diff --git a/client/src/app/features/merge/merge.component.ts b/client/src/app/features/merge/merge.component.ts index 17366ee..139ea05 100644 --- a/client/src/app/features/merge/merge.component.ts +++ b/client/src/app/features/merge/merge.component.ts @@ -34,6 +34,7 @@ import { FormsModule } from '@angular/forms'; import { RecipeListComponent } from '../recipes/recipe-details/recipe-list/recipe-list.component'; import { ResizeEvent, ResizableModule } from 'angular-resizable-element'; import { Debugger } from 'src/app/shared/helpers/debugger'; +import { convertFromInterProductCode, inRange } from 'src/app/shared/helpers/recipe'; @Component({ selector: 'app-merge', @@ -442,7 +443,12 @@ export class MergeComponent } } + console.log("fromMachine",this.recipeFromMachine); + if (Object.keys(this.recipeFromMachine).length > 0) { + + // cat master to target + this.concatNoEditKeyToMap(this.recipeFromMachine, this.targetRecipe[this.getCommitAttr(this.selectedCommit, 'contents').productCode]); to_send['appliedMachineRecipe'] = this.recipeFromMachine; } @@ -455,6 +461,8 @@ export class MergeComponent console.log('sending upgrade', to_send); + // alert("sending .. ") + this._recipeService .upgradeRecipe( await this._recipeService.getCurrentCountry(), @@ -508,6 +516,7 @@ export class MergeComponent // get current pd let pd = this.getCommitAttr(this.selectedCommit, 'contents').productCode; + console.log("check content", compare(this.targetRecipe[pd], this.getCommitAttr(this.selectedCommit, 'contents'))); if (base != '') { switch (base) { @@ -523,6 +532,11 @@ export class MergeComponent this.getCommitAttr(this.selectedCommit, 'contents').recipes[idx] = diff_recipe.recipes[idx]; // TODO: add topping sync, if is topping slot, set topping too! + + if(inRange(8111, 8130, convertFromInterProductCode(diff_recipe.recipes[idx].materialPathId))){ + let toppingSlot = convertFromInterProductCode(diff_recipe.recipes[idx].materialPathId )- 8110; + this.getCommitAttr(this.selectedCommit, 'contents').ToppingSet[toppingSlot] = diff_recipe.ToppingSet[toppingSlot]; + } }); } @@ -544,6 +558,10 @@ export class MergeComponent updateIdxList.forEach((idx) => { this.anotherTargetRecipe[pd].recipes[idx] = commit_recipe[idx]; // TODO: add topping sync, if is topping slot, set topping too! + if(inRange(8111, 8130, convertFromInterProductCode(commit_recipe.recipes[idx].materialPathId))){ + let toppingSlot = convertFromInterProductCode(commit_recipe.recipes[idx].materialPathId )- 8110; + this.anotherTargetRecipe[pd].ToppingSet[toppingSlot] = commit_recipe.ToppingSet[toppingSlot]; + } }); } this.recipeFromMachine = this.anotherTargetRecipe[pd]; @@ -663,4 +681,12 @@ export class MergeComponent break; } } + + concatNoEditKeyToMap(source: any, target: any) { + for (const key of Object.keys(source)) { + if (!Object.keys(target).includes(key)) { + target[key] = source[key]; + } + } + } } diff --git a/client/src/app/features/recipes/recipe-details/recipe-details.component.ts b/client/src/app/features/recipes/recipe-details/recipe-details.component.ts index 153dfd0..7cd9a47 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-details.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-details.component.ts @@ -221,6 +221,7 @@ export class RecipeDetailsComponent implements OnInit { SubMenu: [...(this.rawRecipe! as any).SubMenu!], ToppingSet: [...(this.rawRecipe as any).ToppingSet], }; + console.log('pre to_send', to_send); this.concatNoEditKeyToMap(this.rawRecipe, to_send); diff --git a/client/src/app/features/recipes/recipes.component.ts b/client/src/app/features/recipes/recipes.component.ts index 8a4a74a..547b99b 100644 --- a/client/src/app/features/recipes/recipes.component.ts +++ b/client/src/app/features/recipes/recipes.component.ts @@ -539,12 +539,15 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { // end of Recipe Version selection - openJsonTab() { + async openJsonTab() { + + let country = await this._recipeService.getCurrentCountry( + this.department + ); + window.open( environment.api + - `/recipes/${this._recipeService.getCurrentCountry( - this.department - )}/${this._recipeService.getCurrentFile()}/json`, + `/recipes/${country}/${this._recipeService.getCurrentFile()}/json`, '_blank' ); } @@ -669,7 +672,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { next: (data: any) => { if(data.status == 'OK'){ console.log(data.result); - alert("refresh ... "); + // alert("refresh ... "); window.location.reload(); } } diff --git a/server/data/data.go b/server/data/data.go index 8a74a77..dc97f71 100644 --- a/server/data/data.go +++ b/server/data/data.go @@ -438,7 +438,7 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { } // cache to redis - d.redisClient.SetToKey(filename, recipe) + err = d.redisClient.SetToKey(filename, recipe) if err != nil { d.taoLogger.Log.Error("GetRecipe: Error when read recipe file, Return default recipe", zap.Error(err)) @@ -491,6 +491,22 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { // return d.currentRecipe // } +func loopMatchProductCode(recipe01s []models.Recipe01, productCode string) (models.Recipe01, error) { + for _, v := range recipe01s { + if v.ProductCode == productCode { + return v, nil + } else if len(v.SubMenu) > 0 { + for _, subMenu := range v.SubMenu { + if subMenu.ProductCode == productCode { + return subMenu, nil + } + } + } + } + + return models.Recipe01{}, fmt.Errorf("NotFound") +} + func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) (models.Recipe01, error) { // try convert @@ -513,33 +529,96 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) // //fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentFile", d.CurrentFile) // //fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentCountryID", d.CurrentCountryID) - for _, v := range d.CurrentRecipe[countryID].Recipe01 { - if v.ProductCode == productCode { - return v, nil - } else if len(v.SubMenu) > 0 { - for _, subMenu := range v.SubMenu { - if subMenu.ProductCode == productCode { - return subMenu, nil - } - } + // if redis online + if d.redisClient.HealthCheck() == nil { + d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", true)) + recipeFromRedis := d.GetRecipe(countryID, filename) + + // find productCode from this + // for _, v := range recipeFromRedis.Recipe01 { + // if v.ProductCode == productCode { + // return v, nil + // } else if len(v.SubMenu) > 0 { + // for _, subMenu := range v.SubMenu { + // if subMenu.ProductCode == productCode { + // return subMenu, nil + // } + // } + // } + // } + + recipe01, err := loopMatchProductCode(recipeFromRedis.Recipe01, productCode) + if err == nil { + return recipe01, nil + } + + } else { + d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", false)) + // for _, v := range d.CurrentRecipe[countryID].Recipe01 { + // if v.ProductCode == productCode { + // return v, nil + // } else if len(v.SubMenu) > 0 { + // for _, subMenu := range v.SubMenu { + // if subMenu.ProductCode == productCode { + // return subMenu, nil + // } + // } + // } + // } + recipe01, err := loopMatchProductCode(d.CurrentRecipe[countryID].Recipe01, productCode) + if err == nil { + return recipe01, nil } } + // //fmt.Println("No result in current recipe", countryID) } else if recipe, ok := d.recipeMap[filename]; ok { // //fmt.Println("GetRecipe01ByProductCode.ReadMap", filename, d.CurrentFile, recipe.Recipe[countryID], "countryID=", countryID) - for _, v := range recipe.Recipe[countryID].Recipe01 { - if v.ProductCode == productCode { - // d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) - return v, nil - } else if len(v.SubMenu) > 0 { - for _, subMenu := range v.SubMenu { - if subMenu.ProductCode == productCode { - // d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) - return subMenu, nil - } - } + // for _, v := range recipe.Recipe[countryID].Recipe01 { + // if v.ProductCode == productCode { + // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) + // return v, nil + // } else if len(v.SubMenu) > 0 { + // for _, subMenu := range v.SubMenu { + // if subMenu.ProductCode == productCode { + // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) + // return subMenu, nil + // } + // } + // } + // } + + // if redis online + if d.redisClient.HealthCheck() == nil { + d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", true)) + recipeFromRedis := d.GetRecipe(countryID, filename) + + // find productCode from this + // for _, v := range recipeFromRedis.Recipe01 { + // if v.ProductCode == productCode { + // return v, nil + // } else if len(v.SubMenu) > 0 { + // for _, subMenu := range v.SubMenu { + // if subMenu.ProductCode == productCode { + // return subMenu, nil + // } + // } + // } + // } + + recipe01, err := loopMatchProductCode(recipeFromRedis.Recipe01, productCode) + if err == nil { + return recipe01, nil + } + + } else { + d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("useRedis", false)) + recipe01, err := loopMatchProductCode(recipe.Recipe[countryID].Recipe01, productCode) + if err == nil { + return recipe01, nil } } + d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getFail", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) } } @@ -601,18 +680,23 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) TimeStamps: time.Now().Unix(), } - for _, v := range d.CurrentRecipe[countryID].Recipe01 { - if v.ProductCode == productCode { - // d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", v)) - return v, nil - } else if len(v.SubMenu) > 0 { - for _, subMenu := range v.SubMenu { - if subMenu.ProductCode == productCode { - // d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", subMenu)) - return subMenu, nil - } - } - } + // for _, v := range d.CurrentRecipe[countryID].Recipe01 { + // if v.ProductCode == productCode { + // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", v)) + // return v, nil + // } else if len(v.SubMenu) > 0 { + // for _, subMenu := range v.SubMenu { + // if subMenu.ProductCode == productCode { + // // d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("result", subMenu)) + // return subMenu, nil + // } + // } + // } + // } + + recipe01, err := loopMatchProductCode(d.CurrentRecipe[countryID].Recipe01, productCode) + if err == nil { + return recipe01, nil } return models.Recipe01{}, fmt.Errorf("product code: %s not found", productCode) @@ -1281,12 +1365,20 @@ func (d *Data) Merge(country string, filename string, attr string, changeKey str return "UpdatedValueError", fmt.Errorf("updated value is nil") } - // type assertion - updatedModel, ok := updated.(models.Recipe01) - d.taoLogger.Log.Debug("check on update model", zap.Any("appliedFromClient", updatedModel)) - if !ok { - return d.MergeRecipeNoCache(country, filename, updatedModel) - } + var updateRecipe01 models.Recipe01 + updatedRecord, _ := json.Marshal(updated) + json.Unmarshal(updatedRecord, &updateRecipe01) + + return d.MergeRecipeNoCache(country, filename, updateRecipe01) + + // // updatedModel, ok := updateRecipe01.(models.Recipe01) + // // d.taoLogger.Log.Debug("check on update model", zap.Any("ok?", ok), zap.Any("appliedFromClient", updatedModel)) + // if ok { + // return d.MergeRecipeNoCache(country, filename, updatedModel) + // } else { + // d.taoLogger.Log.Debug("Merge", zap.Any("targetAssertionFail", updated)) + // return "Fail to upgrade: NotMatchedByType", nil + // } } @@ -1332,20 +1424,23 @@ func (d *Data) MergeRecipe(country, filename, changeKey string) (string, error) // check address fmt.Println("[Source] source === recipe? ", sourceRecipe == d.GetRecipe(country, filename)) - // apply value to its source - d.SetValuesToRecipe(sourceRecipe.Recipe01, patchValue) + copyOfSourceRecipe := sourceRecipe - return d.finalizedVersion(country, sourceRecipe) + // apply value to its source + d.SetValuesToRecipe(copyOfSourceRecipe.Recipe01, patchValue) + + return d.finalizedVersion(country, copyOfSourceRecipe) } func (d *Data) MergeRecipeNoCache(country string, filename string, updatedRecipe models.Recipe01) (string, error) { // get recipe sourceRecipe := d.GetRecipe(country, filename) + copyOfSourceRecipe := sourceRecipe // apply value to its source - d.SetValuesToRecipe(sourceRecipe.Recipe01, updatedRecipe) + d.SetValuesToRecipe(copyOfSourceRecipe.Recipe01, updatedRecipe) - return d.finalizedVersion(country, sourceRecipe) + return d.finalizedVersion(country, copyOfSourceRecipe) } func (d *Data) finalizedVersion(country string, sourceRecipe *models.Recipe) (string, error) { diff --git a/server/routers/recipe.go b/server/routers/recipe.go index 7211f10..dbe2941 100644 --- a/server/routers/recipe.go +++ b/server/routers/recipe.go @@ -470,7 +470,7 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) { // target saved filename saved_filename := path.Join("./cofffeemachineConfig", countryID, filename) - // store @ temporary file + // store @ temporary filex temp_file_name := helpers.GetTempFile(saved_filename, editor, 0) // push this change, editor, commit_msg into db @@ -492,6 +492,13 @@ func (rr *RecipeRouter) updateRecipe(w http.ResponseWriter, r *http.Request) { // ------------------------ SKIP THIS ------------------------ // save only changes. + // get new change + // newChangeRecipe, err := rr.data.GetRecipe01ByProductCode(filename, countryID, changes.ProductCode) + // if err != nil { + // // error missing + // rr.taoLogger.Log.Debug("RecipeRouter.UpdateRecipe.MissingNewChange", zap.Any("error", err)) + // } + // get new tempfile name if redis is connected; productCodeNoSpl := strings.ReplaceAll(changes.ProductCode, "-", "")