package recipe import ( "fmt" "recipe-manager/contracts" "recipe-manager/data" "recipe-manager/models" "recipe-manager/services/logger" "sort" "strings" "go.uber.org/zap" ) type RecipeService interface { GetRecipeDashboard(request *contracts.RecipeDashboardRequest) (contracts.RecipeDashboardResponse, error) GetRecipeOverview(request *contracts.RecipeOverviewRequest) (contracts.RecipeOverviewResponse, error) GetRecipeDetail(request *contracts.RecipeDetailRequest) (contracts.RecipeDetailResponse, error) GetRecipeDetailMat(request *contracts.RecipeDetailRequest) (contracts.RecipeDetailMatListResponse, error) } type recipeService struct { db *data.Data taoLogger *logger.TaoLogger } // GetRecipeDetail implements RecipeService. func (rs *recipeService) GetRecipeDetail(request *contracts.RecipeDetailRequest) (contracts.RecipeDetailResponse, error) { rs.taoLogger.Log.Debug("GetRecipeDetail", zap.Any("request", request)) recipe, err := rs.db.GetRecipe01ByProductCode(request.Filename, request.Country, request.ProductCode) if err != nil { return contracts.RecipeDetailResponse{}, err } // DEBUG: picture rs.taoLogger.Log.Debug("GetRecipeDetail", zap.String("picture", recipe.UriData)) uri_img := recipe.UriData uri_img = strings.TrimPrefix(uri_img, "img=") // if strings.HasPrefix(uri_img, "img=") { // uri_img = uri_img[len("img="):] // } result := contracts.RecipeDetailResponse{ Name: recipe.Name, OtherName: recipe.OtherName, Description: recipe.Description, OtherDescription: recipe.OtherDescription, LastUpdated: recipe.LastChange, Picture: uri_img, // remove "img=" prefix } return result, nil } // GetRecipeDetailMat implements RecipeService. func (rs *recipeService) GetRecipeDetailMat(request *contracts.RecipeDetailRequest) (contracts.RecipeDetailMatListResponse, error) { countryID, err := rs.db.GetCountryIDByName(request.Country) if err != nil { return contracts.RecipeDetailMatListResponse{}, fmt.Errorf("country name: %s not found", request.Country) } // rs.taoLogger.Log.Debug("GetRecipeDetailMat", zap.Any("request", request)) recipe, err := rs.db.GetRecipe01ByProductCode(request.Filename, request.Country, request.ProductCode) if err != nil { return contracts.RecipeDetailMatListResponse{}, err } matIds := []uint64{} for _, v := range recipe.Recipes { if v.IsUse { matIds = append(matIds, uint64(v.MaterialPathId)) } } // rs.taoLogger.Log.Debug("GetRecipeDetailMat", zap.Any("matIds", matIds)) matsCode := rs.db.GetMaterialCode(matIds, countryID, request.Filename) materials := []models.MaterialSetting{} matsSetting := rs.db.GetMaterialSetting(countryID, request.Filename) // rs.taoLogger.Log.Debug("GetRecipeDetailMat", zap.Any("matsSetting", matsSetting)) for _, v := range matsSetting { // rs.taoLogger.Log.Debug("GetRecipeDetailMat,Iterate", zap.Any("mats", v.ID)) for _, mat := range matIds { if v.ID == mat { materials = append(materials, v) break } } } // rs.taoLogger.Log.Debug("GetRecipeDetailMat", zap.Any("matsCode", materials)) result := contracts.RecipeDetailMatListResponse{ Result: []contracts.RecipeDetailMat{}, } for _, v := range recipe.Recipes { for _, mat := range materials { if v.MaterialPathId == int(mat.ID) { mat_name := "" for _, m := range matsCode { if m.MaterialID == mat.ID && mat.MaterialName == "" { mat_name = m.PackageDescription break } else if mat.MaterialName != "" { mat_name = mat.MaterialName // fmt.Println("SetMat", mat_name) break } } result.Result = append(result.Result, contracts.RecipeDetailMat{ StringParam: v.StringParam, IsUse: v.IsUse, MaterialID: mat.ID, Name: mat_name, MixOrder: v.MixOrder, FeedParameter: v.FeedParameter, FeedPattern: v.FeedPattern, MaterialPathId: v.MaterialPathId, PowderGram: v.PowderGram, PowderTime: v.PowderTime, StirTime: v.StirTime, SyrupGram: v.SyrupGram, SyrupTime: v.SyrupTime, WaterCold: v.WaterCold, WaterYield: v.WaterYield, }) break } } } // add padding until full 30 if len(result.Result) < 30 { for i := len(result.Result); i < 30; i++ { result.Result = append(result.Result, contracts.RecipeDetailMat{ StringParam: "", IsUse: false, MaterialID: 0, Name: "", MixOrder: 0, FeedParameter: 0, FeedPattern: 0, MaterialPathId: 0, PowderGram: 0, PowderTime: 0, StirTime: 0, SyrupGram: 0, SyrupTime: 0, WaterCold: 0, WaterYield: 0, }) } } // rs.taoLogger.Log.Debug("GetRecipeDetailMat", zap.Any("result", result)) // sort by id // sort.Slice(result.Result, func(i, j int) bool { // return result.Result[i].MaterialID < result.Result[j].MaterialID // }) return result, nil } func (rs *recipeService) GetRecipeDashboard(request *contracts.RecipeDashboardRequest) (contracts.RecipeDashboardResponse, error) { countryID, err := rs.db.GetCountryIDByName(request.Country) if err != nil { return contracts.RecipeDashboardResponse{}, fmt.Errorf("country name: %s not found", request.Country) } recipe := rs.db.GetRecipe(countryID, request.Filename) result := contracts.RecipeDashboardResponse{ ConfigNumber: recipe.MachineSetting.ConfigNumber, LastUpdated: recipe.Timestamp, Filename: request.Filename, } return result, nil } func (rs *recipeService) GetRecipeOverview(request *contracts.RecipeOverviewRequest) (contracts.RecipeOverviewResponse, error) { countryID, err := rs.db.GetCountryIDByName(request.Country) if err != nil { return contracts.RecipeOverviewResponse{}, fmt.Errorf("country name: %s not found", request.Country) } recipe := rs.db.GetRecipe(countryID, request.Filename) recipeFilter := recipe.Recipe01 result := contracts.RecipeOverviewResponse{} if request.Search != "" { var searchResult []models.Recipe01 for _, v := range recipeFilter { if strings.Contains(strings.ToLower(v.ProductCode), strings.ToLower(request.Search)) || strings.Contains(strings.ToLower(v.Name), strings.ToLower(request.Search)) || strings.Contains(strings.ToLower(v.OtherName), strings.ToLower(request.Search)) { searchResult = append(searchResult, v) } } recipeFilter = searchResult } if len(request.MatIds) > 0 { var matIdsFiltered []models.Recipe01 for _, v := range recipeFilter { for _, matID := range request.MatIds { for _, recipe := range v.Recipes { if recipe.IsUse && recipe.MaterialPathId == matID { matIdsFiltered = append(matIdsFiltered, v) } } } } recipeFilter = matIdsFiltered } // Map to contracts.RecipeOverview for _, v := range recipeFilter { result.Result = append(result.Result, contracts.RecipeOverview{ ID: v.ID, ProductCode: v.ProductCode, Name: v.Name, OtherName: v.OtherName, Description: v.Description, LastUpdated: v.LastChange, }) } result.TotalCount = len(result.Result) result.HasMore = result.TotalCount >= request.Take+request.Skip if result.HasMore { result.Result = result.Result[request.Skip : request.Take+request.Skip] sort.Slice(result.Result, func(i, j int) bool { return result.Result[i].ID < result.Result[j].ID }) } else if result.TotalCount > request.Skip { result.Result = result.Result[request.Skip:] } else { result.Result = []contracts.RecipeOverview{} } return result, nil } func NewRecipeService(db *data.Data, taoLogger *logger.TaoLogger) RecipeService { return &recipeService{ db: db, taoLogger: taoLogger, } }