From db131d10c02708266bfaef71b4668697e2740466 Mon Sep 17 00:00:00 2001 From: "pakintada@gmail.com" Date: Wed, 17 Jan 2024 17:38:23 +0700 Subject: [PATCH 1/5] fix default file reader bug --- .../src/app/core/services/material.service.ts | 34 ++- .../src/app/core/services/recipe.service.ts | 34 ++- .../recipe-details.component.html | 93 ++++---- .../recipe-details.component.ts | 4 +- .../recipe-list/recipe-list.component.html | 180 ++++++++------- .../recipe-list/recipe-list.component.ts | 46 +++- .../recipe-topping.component.html | 27 +++ .../recipe-topping.component.ts | 91 ++++++++ .../features/recipes/recipes.component.html | 2 +- .../app/features/recipes/recipes.component.ts | 107 ++++++--- client/src/app/shared/helpers/recipe.ts | 21 ++ client/src/app/shared/helpers/tuple.ts | 15 ++ server/data/data.go | 212 +++++++++++++----- server/data/sqlite.go | 12 + server/routers/material.go | 12 +- 15 files changed, 636 insertions(+), 254 deletions(-) create mode 100644 client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html create mode 100644 client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts create mode 100644 client/src/app/shared/helpers/tuple.ts diff --git a/client/src/app/core/services/material.service.ts b/client/src/app/core/services/material.service.ts index a9f9b51..1e22d77 100644 --- a/client/src/app/core/services/material.service.ts +++ b/client/src/app/core/services/material.service.ts @@ -3,10 +3,15 @@ import { Injectable } from '@angular/core'; import { MaterialCode, MaterialSetting } from '../models/recipe.model'; import { environment } from 'src/environments/environment'; import { Observable } from 'rxjs'; +import { ActivatedRoute } from '@angular/router'; +import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; @Injectable({ providedIn: 'root' }) export class MaterialService { - constructor(private _httpClient: HttpClient) {} + + private department = this._route.snapshot.paramMap.get('department') + + constructor(private _httpClient: HttpClient, private _route: ActivatedRoute) {} getMaterialCodes( matIds?: number[], @@ -17,7 +22,7 @@ export class MaterialService { `${environment.api}/materials/code`, { params: { - country: country || this.getCurrentCountry(), + country: country || this.getCurrentCountry(this.department!), filename: filename || this.getCurrentFile(), mat_ids: matIds?.join(',') || '', }, @@ -36,9 +41,12 @@ export class MaterialService { }[] | null>{ console.log("getFullMaterialDetail", country, filename); - country = country || this.getCurrentCountry(); + country = country || this.getCurrentCountry(this.department!); filename = filename || this.getCurrentFile(); + // finalize fetch from what? + console.log("country, filename", country, filename); + return this._httpClient.get<{ "materialId": number, "name": string, @@ -57,7 +65,7 @@ export class MaterialService { `${environment.api}/materials/setting/${id}`, { params: { - country: country || this.getCurrentCountry(), + country: country || this.getCurrentCountry(this.department!), filename: filename || this.getCurrentFile(), }, withCredentials: true, @@ -71,10 +79,24 @@ export class MaterialService { return currentRecipeFile; } - return 'coffeethai02_580.json'; + return 'default'; } - getCurrentCountry(): string { + getCurrentCountry(department? : string): string { + + // fetch by using department + if(department){ + + // translate back to full name + let fullname = getCountryMapSwitcher(department); + + console.log('Material.service::fullname: ', fullname); + + // localStorage.setItem('currentRecipeCountry', fullname); + return fullname; + } + + const currentRecipeCountry = localStorage.getItem('currentRecipeCountry'); if (currentRecipeCountry) { return currentRecipeCountry; diff --git a/client/src/app/core/services/recipe.service.ts b/client/src/app/core/services/recipe.service.ts index b183d01..4118993 100644 --- a/client/src/app/core/services/recipe.service.ts +++ b/client/src/app/core/services/recipe.service.ts @@ -12,6 +12,8 @@ import { } from '../models/recipe.model'; import { environment } from 'src/environments/environment'; import { RecipeMetaData } from 'src/app/shared/types/recipe'; +import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; +import { ActivatedRoute } from '@angular/router'; type RecipeOverviewParams = { filename: string; @@ -38,15 +40,17 @@ export class RecipeService { private tmp_files: string[] = []; + private department = this._route.snapshot.paramMap.get('department'); + private get tmpfiles(): string[] { return this.tmp_files; } - constructor(private _httpClient: HttpClient) {} + constructor(private _httpClient: HttpClient, private _route: ActivatedRoute) {} getRecipesDashboard( params: RecipeDashboardParams = { - country: this.getCurrentCountry(), + country: this.getCurrentCountry(this.department!), filename: this.getCurrentFile(), } ): Observable { @@ -65,7 +69,7 @@ export class RecipeService { getRecipeOverview( params: RecipeOverviewParams = { - country: this.getCurrentCountry(), + country: this.getCurrentCountry(this.department!), filename: this.getCurrentFile(), materialIds: [], offset: 0, @@ -96,7 +100,7 @@ export class RecipeService { { params: { filename: this.getCurrentFile(), - country: this.getCurrentCountry(), + country: this.getCurrentCountry(this.department!), }, withCredentials: true, responseType: 'json', @@ -112,7 +116,7 @@ export class RecipeService { { params: { filename: this.getCurrentFile(), - country: this.getCurrentCountry(), + country: this.getCurrentCountry(this.department!), }, withCredentials: true, responseType: 'json', @@ -121,19 +125,35 @@ export class RecipeService { } getCurrentFile(): string { + + // TODO: get default from server + + const currentRecipeFile = localStorage.getItem('currentRecipeFile'); if (currentRecipeFile) { return currentRecipeFile; } - return 'coffeethai02_580.json'; + return 'default'; } setCurrentFile(filename: string) { localStorage.setItem('currentRecipeFile', filename); } - getCurrentCountry(): string { + getCurrentCountry(department?: string): string { + + if(department){ + + // translate back to full name + let fullname = getCountryMapSwitcher(department); + + console.log('fullname: ', fullname); + + // localStorage.setItem('currentRecipeCountry', fullname); + return fullname; + } + const currentRecipeCountry = localStorage.getItem('currentRecipeCountry'); if (currentRecipeCountry) { return currentRecipeCountry; diff --git a/client/src/app/features/recipes/recipe-details/recipe-details.component.html b/client/src/app/features/recipes/recipe-details/recipe-details.component.html index 1d31cf1..ed0ff21 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-details.component.html +++ b/client/src/app/features/recipes/recipe-details/recipe-details.component.html @@ -7,19 +7,17 @@ class="block p-6 bg-white border border-gray-200 rounded-lg shadow w-full" >
- - - -
- -
+ +
+ +
@@ -29,7 +27,6 @@
{{ recipeDetailForm.getRawValue().otherName }}
-
@@ -110,7 +107,12 @@
- +
@@ -118,45 +120,52 @@
- - +
-
- -
- 1 - 2 - 3 -
+
+ 1 + 2 + 3 +
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 29f41ca..c03772f 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 @@ -109,7 +109,7 @@ export class RecipeDetailsComponent implements OnInit { this.recipeOriginalDetail = { ...this.recipeDetailForm.getRawValue() }; }); - this._recipeService.getSubMenus(this._recipeService.getCurrentCountry(), this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => { + this._recipeService.getSubMenus(this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => { console.log('Submenus', data); this.submenus = data; }); @@ -177,7 +177,7 @@ export class RecipeDetailsComponent implements OnInit { // TODO: update value in targeted recipe console.log('to_send', to_send); this._recipeService.editChanges( - this._recipeService.getCurrentCountry(), + this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile(), { ...to_send, diff --git a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html index 2222c72..373da4e 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html +++ b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html @@ -4,7 +4,8 @@ Is Use Material ID Material Name - Settings + Volume + Settings - + - + - + - - -
+

Volume

gram

- -
-
-
- -

tail

- -

- mA -

+ +
+
+
+
+ +

tail

+ +

mA

+
-
-
-

Hot

- -

ml

-
-
-

Cold

- -

ml

-
-
-

- Grinder -

-

- Mix -

-

- Clean -

- -

sec

+

Hot

+ + +

ml

+
+
+

Cold

+ +

ml

+
+
+

{{getTooltipForStirTime(getTypeForRecipeListAtIndex(i))}}

+ +

sec

+
+
+
+
Topping Settings
+
+ +
@@ -291,7 +299,11 @@ Water

Hot (waterYield)

- +

ml

diff --git a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts index aefd18d..85f5975 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts @@ -32,11 +32,13 @@ import { inRange } from 'src/app/shared/helpers/recipe'; +import { RecipeToppingComponent } from '../recipe-topping/recipe-topping.component'; + @Component({ - selector: 'app-recipe-list', - templateUrl: './recipe-list.component.html', - standalone: true, - imports: [NgIf, NgFor, ReactiveFormsModule, FormsModule], + selector: 'app-recipe-list', + templateUrl: './recipe-list.component.html', + standalone: true, + imports: [NgIf, NgFor, ReactiveFormsModule, FormsModule, RecipeToppingComponent] }) export class RecipeListComponent implements OnInit { @Input({ required: true }) productCode!: string; @@ -324,9 +326,17 @@ export class RecipeListComponent implements OnInit { // console.log("make material list by category", this.makeListCategory()); this.showMaterialSelector = false; - this.recipeListData.at(i).get('materialPathId')?.setValue(material); - console.log('set mat ', material, 'to slot', i); + // query material for its name + let materialName = this.fullMaterialList!.find( + (mat) => mat.materialId == material + )!.name; + + this.recipeListData.at(i).get('name')?.setValue( + materialName + ); + + console.log('set mat ', material, materialName,'to slot', i); } getTypeForRecipeListAtIndex(i: any) { @@ -501,4 +511,28 @@ export class RecipeListComponent implements OnInit { this.recipeListData.value[i][key] ); } + + getTooltipForStirTime = (cat: { + category: string; + name: any; + id: any; +}) => { + switch (cat.category) { + case 'whipper': + return 'Mix'; + case 'bean': + return 'Grinder'; + case 'others': + + if(inRange(8001, 8002, cat.id)){ + return 'Clean'; + } + + break; + default: + break; + } + + return ''; + }; } diff --git a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html new file mode 100644 index 0000000..6db76f8 --- /dev/null +++ b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html @@ -0,0 +1,27 @@ +
+ + + + +
{{ item.name }} ({{ item.groupId }})
+
+
+ + + + +
diff --git a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts new file mode 100644 index 0000000..9f1c3c0 --- /dev/null +++ b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts @@ -0,0 +1,91 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NgSelectModule } from '@ng-select/ng-select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { RecipeService } from 'src/app/core/services/recipe.service'; +import { ToppingService } from 'src/app/core/services/topping.service'; +import { Topping, ToppingGroup, ToppingSet } from 'src/app/core/models/recipe.model'; + +@Component({ + selector: 'app-recipe-topping', + standalone: true, + imports: [CommonModule, NgSelectModule, FormsModule, ReactiveFormsModule], + templateUrl: './recipe-topping.component.html', +}) +export class RecipeToppingComponent implements OnInit { + @Input() index: number = 0; + @Input() toppingSet!: ToppingSet; + @Output() toppingSetChange = new EventEmitter(); + + allToppings: Topping | undefined = undefined; + + allToppingsDefinitions: + | { groupId: string; name: string; members: string; default: string }[] + | null = [{ groupId: '0', name: 'none', members: '0', default: '0' }]; + + allToppingMembersByGroup: { + id: string; + members: { id: string; name: string }[]; + }[] = []; + + constructor( + private _recipeService: RecipeService, + private _toppingService: ToppingService + ) {} + ngOnInit(): void { + this._toppingService + .getToppings( + this._recipeService.getCurrentCountry(), + this._recipeService.getCurrentFile() + ) + .subscribe((data) => { + this.allToppings = data; + // console.log('allToppings', data); + + data.ToppingGroup.forEach((group: ToppingGroup) => { + if (this.allToppingsDefinitions != null) { + // this.allToppingsDefinitions = {}; + this.allToppingsDefinitions.push({ + groupId: group.groupID, + name: group.name, + members: group.idInGroup, + default: group.idDefault, + }); + + this.allToppingMembersByGroup.push({ + id: group.groupID, + members: this.mapToppingListToMember(group.idInGroup.split(',')), + }); + } + }); + + // console.log(this.allToppingsDefinitions); + // console.log('allToppingMembersByGroup', this.allToppingMembersByGroup); + }); + } + + compareFunc = (a: any, b: any) => a.toString() === b.toString(); + + mapToppingListToMember = (mm: string[]) => + mm.map((m) => { + // find actual topping from toppingList + let actualTopping = this.allToppings!.ToppingList.find((t) => t.id == m); + + return { + id: actualTopping!.id, + name: actualTopping?.name == null ? m : actualTopping!.name, + }; + }); + + getMembersByGroupId(groupID: string) { + return this.allToppingMembersByGroup.find((x) => x.id == groupID)?.members; + } + + getGroupIdByIndex(i: number) { + // console.log("getGroupId",this.toppingList.value![i]) + // return (this.toppingList.value![i] as any).groupID as string; + } + + // services +} + diff --git a/client/src/app/features/recipes/recipes.component.html b/client/src/app/features/recipes/recipes.component.html index 6c532c0..5e71b4b 100644 --- a/client/src/app/features/recipes/recipes.component.html +++ b/client/src/app/features/recipes/recipes.component.html @@ -11,7 +11,7 @@
Recipe Version {{ recipesDashboard.configNumber }} | + >Recipe Version {{ currentVersion }} | {{ recipesDashboard.filename }}
diff --git a/client/src/app/features/recipes/recipes.component.ts b/client/src/app/features/recipes/recipes.component.ts index 7d19b07..1c6b4e4 100644 --- a/client/src/app/features/recipes/recipes.component.ts +++ b/client/src/app/features/recipes/recipes.component.ts @@ -1,4 +1,5 @@ import { + AfterViewInit, Component, ElementRef, OnDestroy, @@ -24,7 +25,7 @@ import { tap, } from 'rxjs'; import * as lodash from 'lodash'; -import { ActivatedRoute, RouterLink } from '@angular/router'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { NgSelectModule } from '@ng-select/ng-select'; import { FormsModule } from '@angular/forms'; import { MaterialService } from 'src/app/core/services/material.service'; @@ -32,6 +33,7 @@ import { UserService } from 'src/app/core/services/user.service'; import { UserPermissions } from 'src/app/core/auth/userPermissions'; import { ToppingService } from 'src/app/core/services/topping.service'; import { copy, transformToTSV } from 'src/app/shared/helpers/copy'; +import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; @Component({ selector: 'app-recipes', @@ -46,7 +48,7 @@ import { copy, transformToTSV } from 'src/app/shared/helpers/copy'; ], templateUrl: './recipes.component.html', }) -export class RecipesComponent implements OnInit, OnDestroy { +export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { recipesDashboard$!: Observable; recipeOverviewList!: RecipeOverview[]; selectMaterialFilter: number[] | null = null; @@ -89,9 +91,9 @@ export class RecipesComponent implements OnInit, OnDestroy { department: string = this.route.parent!.snapshot.params['department']; copyList: any[] = []; - @ViewChild('table', { static: false }) set content(table: ElementRef) { - // expose element ref for other fn + currentVersion: number | undefined = undefined; + @ViewChild('table', { static: false }) set content(table: ElementRef) { table.nativeElement.addEventListener( 'scroll', () => { @@ -109,7 +111,7 @@ export class RecipesComponent implements OnInit, OnDestroy { take: this.take, search: this.oldSearchStr, filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(), + country: this._recipeService.getCurrentCountry(this.department), materialIds: this.selectMaterialFilter || [], }) .subscribe(({ result, hasMore, totalCount }) => { @@ -134,14 +136,16 @@ export class RecipesComponent implements OnInit, OnDestroy { private _materialService: MaterialService, private _toppingService: ToppingService, private route: ActivatedRoute, - private _userService: UserService + private _userService: UserService, + private _router: Router ) {} ngOnInit(): void { + console.log('Trigger onInit where department = ', this.department); this.recipesDashboard$ = this._recipeService .getRecipesDashboard({ filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(), + country: this._recipeService.getCurrentCountry(this.department!), }) .pipe( finalize(() => { @@ -151,7 +155,7 @@ export class RecipesComponent implements OnInit, OnDestroy { take: this.take, search: this.oldSearchStr, filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(), + country: this._recipeService.getCurrentCountry(this.department!), materialIds: this.selectMaterialFilter || [], }) .subscribe(({ result, hasMore, totalCount }) => { @@ -163,9 +167,34 @@ export class RecipesComponent implements OnInit, OnDestroy { }) ); + // FIXME: Lag assigned + + this.recipesDashboard$.subscribe((data) => { + this.currentVersion = data.configNumber; + console.log('current version', this.currentVersion); + }); + + console.log('ngAfterViewInit::department', this.department); + console.log('::CurrentFile', this._recipeService.getCurrentFile()); + + this._materialService + .getFullMaterialDetail( + this.department, + this._recipeService.getCurrentFile() + ) + .subscribe((mat) => { + this.materialDetail = mat; + console.log(this.materialDetail?.length); + + // check material detail + console.log('first material', this.materialDetail![0]); + }); + + // end of FIXME + this._recipeService .getSavedTmp( - this._recipeService.getCurrentCountry(), + this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile() ) .subscribe({ @@ -209,16 +238,6 @@ export class RecipesComponent implements OnInit, OnDestroy { this.materialList = materials; }); - this._materialService - .getFullMaterialDetail( - this.department, - this._recipeService.getCurrentFile() - ) - .subscribe((mat) => { - this.materialDetail = mat; - console.log(this.materialDetail?.length); - }); - this._toppingService .getToppings(this.department, this._recipeService.getCurrentFile()) .subscribe((tp) => { @@ -232,6 +251,10 @@ export class RecipesComponent implements OnInit, OnDestroy { this.initRecipeSelection(); } + ngAfterViewInit(): void { + console.log('After view on init trigger'); + } + setSearch(event: Event) { console.log((event.target as HTMLInputElement).value); this.searchStr = (event.target as HTMLInputElement).value; @@ -247,7 +270,7 @@ export class RecipesComponent implements OnInit, OnDestroy { take: this.take, search: this.oldSearchStr, filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(), + country: this._recipeService.getCurrentCountry(this.department), materialIds: this.selectMaterialFilter || [], }) .subscribe(({ result, hasMore, totalCount }) => { @@ -400,7 +423,14 @@ export class RecipesComponent implements OnInit, OnDestroy { countrySelected(country: string) { this.selectedCountry = country; this.isCountrySelected = true; - localStorage.setItem('currentRecipeCountry', country); + // localStorage.setItem('currentRecipeCountry', country); + + // force reload, will fix this later + void this._router + .navigate([`/${getCountryMapSwitcher(country)}/recipes`]) + .then(() => { + window.location.reload(); + }); } loadRecipe(recipeFileName: string) { @@ -409,11 +439,18 @@ export class RecipesComponent implements OnInit, OnDestroy { this.isHasMore = true; this.isLoadMore = true; this.oldSearchStr = ''; - localStorage.setItem('currentRecipeFile', recipeFileName); + // localStorage.setItem('currentRecipeFile', recipeFileName); + + console.log('loadRecipe', recipeFileName, "currentCountry", this.department); this.recipesDashboard$ = this._recipeService.getRecipesDashboard({ filename: recipeFileName, - country: this.selectedCountry!, + country: this.department!, + }); + + this.recipesDashboard$.subscribe((data) => { + this.currentVersion = data.configNumber; + console.log('current version', this.currentVersion); }); this._recipeService @@ -438,7 +475,9 @@ export class RecipesComponent implements OnInit, OnDestroy { openJsonTab() { window.open( environment.api + - `/recipes/${this._recipeService.getCurrentCountry()}/${this._recipeService.getCurrentFile()}/json`, + `/recipes/${this._recipeService.getCurrentCountry( + this.department + )}/${this._recipeService.getCurrentFile()}/json`, '_blank' ); } @@ -503,26 +542,22 @@ export class RecipesComponent implements OnInit, OnDestroy { item.name.toLowerCase().includes(term.toLowerCase()) || item.materialId.toString().includes(term); - - addToCopyList(data: any){ - - if(this.copyList.includes(data)){ - + addToCopyList(data: any) { + if (this.copyList.includes(data)) { let index = this.copyList.indexOf(data); this.copyList.splice(index, 1); } else { this.copyList = [...this.copyList, data]; } - } - - async copyToTsv(data: any){ - - await copy(transformToTSV(data)).then( (value) => { + async copyToTsv(data: any) { + await copy(transformToTSV(data)) + .then((value) => { console.log('copyToTsv', value); - }).catch( (err) => { + }) + .catch((err) => { console.log('copyToTsvErr', err); }); - } + } } diff --git a/client/src/app/shared/helpers/recipe.ts b/client/src/app/shared/helpers/recipe.ts index c42d251..4ab1bad 100644 --- a/client/src/app/shared/helpers/recipe.ts +++ b/client/src/app/shared/helpers/recipe.ts @@ -1,3 +1,5 @@ +import { Tuple } from "./tuple"; + var rangeMaterialMapping: { [key: string]: (id: number) => boolean } = { soda: (id: number) => id == 1031, water: (id: number) => id == 1, @@ -92,5 +94,24 @@ export var stringParamsDefinition: { [key: string]: string } = { export var conditionTests: { [key: string]: (arg: any) => boolean } = { 'not-zero': (arg: any) => arg != 0, + 'zero': (arg: any) => arg == 0, 'false-if-another-exist': (arg: any) => arg[1] != undefined } + + +export var countryMap: Tuple[] = [ + new Tuple('tha', 'Thailand'), + new Tuple('mys', 'Malaysia'), + new Tuple('aus', 'Australia'), +]; + +export function getCountryMapSwitcher(param: string) { + + console.log("param = ", param); + + for (const country of countryMap) { + if(country.first == param || country.second == param){ + return country.switchGet(param); + } + } +} diff --git a/client/src/app/shared/helpers/tuple.ts b/client/src/app/shared/helpers/tuple.ts new file mode 100644 index 0000000..541a250 --- /dev/null +++ b/client/src/app/shared/helpers/tuple.ts @@ -0,0 +1,15 @@ +export class Tuple { + constructor(public first: T, public second: U) {} + + public get(): [T, U] { + return [this.first, this.second]; + } + + public switchGet(elem: any): any{ + if(elem == this.first){ + return this.second; + } else { + return this.first; + } + } +} diff --git a/server/data/data.go b/server/data/data.go index d37d53b..018dd97 100644 --- a/server/data/data.go +++ b/server/data/data.go @@ -23,13 +23,20 @@ type RecipeWithTimeStamps struct { } 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 + CurrentFile map[string]string + CurrentCountryID map[string]string + DefaultCountryMap []DefaultByCountry + AllRecipeFiles map[string][]helpers.RecipePath + currentRecipe *models.Recipe + recipeMap map[string]RecipeWithTimeStamps + Countries []helpers.CountryName + taoLogger *logger.TaoLogger +} + +type DefaultByCountry struct { + CountryShortName string + CountryLongName string + DefaultFileVersion int } var ( @@ -53,46 +60,95 @@ func NewData(taoLogger *logger.TaoLogger) *Data { defaultFile := "coffeethai02_600.json" defaultCountry := "tha" - // TODO: read 'version' file - versionPath := path.Join("cofffeemachineConfig", defaultCountry, "version") - taoLogger.Log.Debug("version", zap.Any("version path", versionPath)) + // TODO: read 'version' file by country - // versionFile, err := os.Open(versionPath) - content, err := os.ReadFile(versionPath) + // versionPath := path.Join("cofffeemachineConfig", defaultCountry, "version") + // taoLogger.Log.Debug("version", zap.Any("version path", versionPath)) - if err != nil { - taoLogger.Log.Debug("Error when open version file", zap.Error(err)) - } + // // versionFile, err := os.Open(versionPath) + // content, err := os.ReadFile(versionPath) - initVersion := string(content) + // if err != nil { + // taoLogger.Log.Debug("Error when open version file", zap.Error(err)) + // } - // read latest version - // set latest to default version - latest_version, err := strconv.Atoi(initVersion) + // initVersion := string(content) - if err != nil { - latest_version = 600 - } + // // read latest version + // // set latest to default version + // latest_version, err := strconv.Atoi(initVersion) - for _, v := range allRecipeFiles[defaultCountry] { + // if err != nil { + // latest_version = 600 + // } - // extract filename as version - current_version_iter, err := strconv.Atoi(strings.Split(strings.Split(v.Name, "_")[1], ".")[0]) + defaultForEachCountry := []DefaultByCountry{} + for _, elem := range countries { + // generate default of all countries + currentVersionPath := path.Join("cofffeemachineConfig", elem.CountryID, "version") + // this is default version for each country + content, err := os.ReadFile(currentVersionPath) if err != nil { - continue + taoLogger.Log.Debug("Error when open version file", zap.Error(err)) } - if current_version_iter == latest_version { - // taoLogger.Log.Debug("current_version_iter", zap.Any("current_version_iter", current_version_iter)) - // set latest - latest_version = current_version_iter - defaultFile = v.Name - break + initVersion := string(content) + + // read latest version + latest_version, _ := strconv.Atoi(initVersion) + defaultForEachCountry = append(defaultForEachCountry, DefaultByCountry{CountryShortName: elem.CountryID, CountryLongName: elem.CountryName, DefaultFileVersion: latest_version}) + } + + currentFileMap := make(map[string]string) + CurrentCountryIDMap := make(map[string]string) + + // all default versions as string + versionsString := "" + + // loop default for each country + + for _, v := range defaultForEachCountry { + + for _, v2 := range allRecipeFiles[v.CountryShortName] { + + // extract filename as version + current_version_iter, err := strconv.Atoi(strings.Split(strings.Split(v2.Name, "_")[1], ".")[0]) + + if err != nil { + continue + } + + if current_version_iter == v.DefaultFileVersion { + currentFileMap[v.CountryShortName] = v2.Name + CurrentCountryIDMap[v.CountryShortName] = v.CountryLongName + + versionsString = versionsString + v.CountryShortName + ":" + strconv.Itoa(current_version_iter) + "," + + break + } } } - taoLogger.Log.Debug("defaultFile", zap.Any("defaultFile", defaultFile), zap.Any("latest_version", latest_version)) + // for _, v := range allRecipeFiles[defaultCountry] { + + // // extract filename as version + // current_version_iter, err := strconv.Atoi(strings.Split(strings.Split(v.Name, "_")[1], ".")[0]) + + // if err != nil { + // continue + // } + + // if current_version_iter == latest_version { + // // taoLogger.Log.Debug("current_version_iter", zap.Any("current_version_iter", current_version_iter)) + // // set latest + // latest_version = current_version_iter + // defaultFile = v.Name + // break + // } + // } + + taoLogger.Log.Debug("defaultFile", zap.Any("defaultFile", defaultFile), zap.Any("latest_version", versionsString)) defaultRecipe, err := helpers.ReadRecipeFile(defaultCountry, defaultFile) @@ -101,8 +157,8 @@ func NewData(taoLogger *logger.TaoLogger) *Data { } return &Data{ - CurrentFile: defaultFile, - CurrentCountryID: defaultCountry, + CurrentFile: currentFileMap, + CurrentCountryID: CurrentCountryIDMap, AllRecipeFiles: allRecipeFiles, currentRecipe: defaultRecipe, recipeMap: map[string]RecipeWithTimeStamps{ @@ -111,8 +167,9 @@ func NewData(taoLogger *logger.TaoLogger) *Data { TimeStamps: time.Now().Unix(), }, }, - Countries: countries, - taoLogger: taoLogger, + Countries: countries, + taoLogger: taoLogger, + DefaultCountryMap: defaultForEachCountry, } } @@ -122,20 +179,25 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { return d.currentRecipe } - if filename == "" || filename == d.CurrentFile { + if filename == "" || filename == d.CurrentFile[countryID] { return d.currentRecipe } if recipe, ok := d.recipeMap[filename]; ok { - d.CurrentFile = filename - d.CurrentCountryID = countryID + d.CurrentFile[countryID] = filename + d.CurrentCountryID[countryID] = countryID return &recipe.Recipe } // change current version and read new recipe - d.CurrentFile = filename + + if filename == "default" { + filename = d.CurrentFile[countryID] + } + + d.CurrentFile[countryID] = filename d.taoLogger.Log.Debug("GetRecipe", zap.String("filename", filename), zap.String("countryID", countryID)) - d.CurrentCountryID = countryID + d.CurrentCountryID[countryID] = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { @@ -178,7 +240,7 @@ func (d *Data) GetCurrentRecipe() *models.Recipe { func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) (models.Recipe01, error) { if !strings.Contains(filename, "tmp") { - if filename == "" || filename == d.CurrentFile { + if filename == "" || filename == d.CurrentFile[countryID] { fmt.Println("GetRecipe01ByProductCode.ReadCurrent", filename, d.CurrentFile) for _, v := range d.currentRecipe.Recipe01 { if v.ProductCode == productCode { @@ -195,12 +257,18 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) } } - d.CurrentFile = filename - d.CurrentCountryID = countryID + d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("filename", filename), zap.Any("countryID", countryID), zap.Any("productCode", productCode)) + + if filename == "default" { + filename = d.CurrentFile[countryID] + } + + d.CurrentFile[countryID] = filename + d.CurrentCountryID[countryID] = countryID for _, v := range countries { if v.CountryName == countryID { - d.CurrentCountryID = v.CountryID + d.CurrentCountryID[countryID] = v.CountryID countryID = v.CountryID break } @@ -295,7 +363,7 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS } if !strings.Contains(filename, "tmp") { - if filename == "" || filename == d.CurrentFile { + if filename == "" || filename == d.CurrentFile[countryID] { copy(result, d.currentRecipe.MaterialSetting) d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("result", result)) return d.currentRecipe.MaterialSetting @@ -303,14 +371,20 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS if recipe, ok := d.recipeMap[filename]; ok { copy(result, recipe.Recipe.MaterialSetting) - d.CurrentFile = filename - d.CurrentCountryID = countryID + d.CurrentFile[countryID] = filename + d.CurrentCountryID[countryID] = countryID return d.currentRecipe.MaterialSetting } } - d.CurrentFile = filename - d.CurrentCountryID = countryID + if filename == "default" { + filename = d.CurrentFile[countryID] + } + + d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("filename", filename), zap.Any("countryID", countryID)) + + d.CurrentFile[countryID] = filename + d.CurrentCountryID[countryID] = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { @@ -349,14 +423,19 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []models.MaterialCode { var result []models.MaterialCode - if filename == "" || filename == d.CurrentFile { + if filename == "" || filename == d.CurrentFile[countryID] { result = d.currentRecipe.MaterialCode } else if recipe, ok := d.recipeMap[filename]; ok { - d.CurrentFile = filename + d.CurrentFile[countryID] = filename return recipe.Recipe.MaterialCode } else { - d.CurrentFile = filename - d.CurrentCountryID = countryID + + if filename == "default" { + filename = d.CurrentFile[countryID] + } + + d.CurrentFile[countryID] = filename + d.CurrentCountryID[countryID] = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { @@ -411,14 +490,19 @@ func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []model func (d *Data) GetToppings(countryID, filename string) models.Topping { - if filename == "" || filename == d.CurrentFile { + if filename == "" || filename == d.CurrentFile[countryID] { return d.currentRecipe.Topping } else if recipe, ok := d.recipeMap[filename]; ok { - d.CurrentFile = filename + d.CurrentFile[countryID] = filename return recipe.Recipe.Topping } - d.CurrentFile = filename - d.CurrentCountryID = countryID + + if filename == "default" { + filename = d.CurrentFile[countryID] + } + + d.CurrentFile[countryID] = filename + d.CurrentCountryID[countryID] = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { @@ -432,6 +516,11 @@ func (d *Data) GetToppings(countryID, filename string) models.Topping { } func (d *Data) GetToppingsOfRecipe(countryID, filename string, productCode string) ([]models.ToppingSet, error) { + + if filename == "default" { + filename = d.CurrentFile[countryID] + } + recipe, err := d.GetRecipe01ByProductCode(filename, countryID, productCode) if err != nil { @@ -443,6 +532,11 @@ func (d *Data) GetToppingsOfRecipe(countryID, filename string, productCode strin } func (d *Data) GetSubmenusOfRecipe(countryID, filename, productCode string) ([]models.Recipe01, error) { + + if filename == "default" { + filename = d.CurrentFile[countryID] + } + recipe, err := d.GetRecipe01ByProductCode(filename, countryID, productCode) if err != nil { diff --git a/server/data/sqlite.go b/server/data/sqlite.go index 2124f42..2007dee 100644 --- a/server/data/sqlite.go +++ b/server/data/sqlite.go @@ -1,11 +1,23 @@ package data import ( + "fmt" + "os" + "github.com/jmoiron/sqlx" _ "github.com/mattn/go-sqlite3" ) func NewSqliteDatabase() *sqlx.DB { + + // ensure that database exists + info, err := os.Stat("./data/database.db") + if os.IsNotExist(err) { + fmt.Println("No database found. Check path: ", err) + } else { + fmt.Println("Database existed. ", info) + } + db := sqlx.MustConnect("sqlite3", "./data/database.db") return db } diff --git a/server/routers/material.go b/server/routers/material.go index bd4ba48..cc68f1b 100644 --- a/server/routers/material.go +++ b/server/routers/material.go @@ -75,17 +75,7 @@ func (mr *MaterialRouter) GetFullMaterialDetail(w http.ResponseWriter, r *http.R }) } - // for _, matCode := range matCodes { - // for index, matDetail := range materialDetails { - // if matCode.MaterialID == matDetail["materialId"] { - // materialDetails[index]["name"] = matCode.PackageDescription - // } else if matDetail["materialId"].(uint64) > 8110 && matDetail["materialId"].(uint64) <= 8130 { - // slotNum := matDetail["materialId"].(uint64) - 8110 - // // mr.taoLogger.Log.Debug("GetFullMaterialDetail", zap.Any("slotNum", matDetail["materialId"]), zap.Any("slotNum", slotNum)) - // materialDetails[index]["name"] = "Topping" + strconv.Itoa(int(slotNum)) - // } - // } - // } + // mr.taoLogger.Log.Debug("GetFullMaterialDetail", zap.Any("materialDetails", materialDetails)) // send result if err := json.NewEncoder(w).Encode(materialDetails); err != nil { From 4ece2cf30ce21fac1a732d5230ad390508cda592 Mon Sep 17 00:00:00 2001 From: "pakintada@gmail.com" Date: Thu, 18 Jan 2024 16:59:06 +0700 Subject: [PATCH 2/5] fix delay material fetching --- .../src/app/core/services/material.service.ts | 39 ++++-- .../src/app/core/services/recipe.service.ts | 28 ++-- .../recipe-details.component.ts | 12 +- .../recipe-list/recipe-list.component.ts | 12 +- .../recipe-topping.component.ts | 4 +- .../recipe-toppingset.component.ts | 6 +- .../features/recipes/recipes.component.html | 2 +- .../app/features/recipes/recipes.component.ts | 125 ++++++++++-------- client/src/app/shared/helpers/asyncStorage.ts | 14 ++ server/data/data.go | 105 ++++++++------- server/routers/material.go | 2 +- server/routers/recipe.go | 4 + server/services/recipe/recipe.go | 10 ++ 13 files changed, 220 insertions(+), 143 deletions(-) create mode 100644 client/src/app/shared/helpers/asyncStorage.ts diff --git a/client/src/app/core/services/material.service.ts b/client/src/app/core/services/material.service.ts index 1e22d77..52edb32 100644 --- a/client/src/app/core/services/material.service.ts +++ b/client/src/app/core/services/material.service.ts @@ -5,6 +5,7 @@ import { environment } from 'src/environments/environment'; import { Observable } from 'rxjs'; import { ActivatedRoute } from '@angular/router'; import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; +import { AsyncStorage } from 'src/app/shared/helpers/asyncStorage'; @Injectable({ providedIn: 'root' }) export class MaterialService { @@ -13,16 +14,20 @@ export class MaterialService { constructor(private _httpClient: HttpClient, private _route: ActivatedRoute) {} - getMaterialCodes( + async getMaterialCodes( matIds?: number[], country?: string, filename?: string - ): Observable { + ): Promise> { + + // async country + let asyncCountry = await AsyncStorage.getItem('currentRecipeCountry'); + return this._httpClient.get( `${environment.api}/materials/code`, { params: { - country: country || this.getCurrentCountry(this.department!), + country: country || asyncCountry, filename: filename || this.getCurrentFile(), mat_ids: matIds?.join(',') || '', }, @@ -31,17 +36,19 @@ export class MaterialService { ); } - getFullMaterialDetail( + async getFullMaterialDetail( country?: string, filename?: string - ): Observable<{ + ): Promise{ - console.log("getFullMaterialDetail", country, filename); + }[] | null>>{ + console.log("getFullMaterialDetail", country, filename, country || this.getCurrentCountry(this.department!)); - country = country || this.getCurrentCountry(this.department!); + let asyncCountry = await AsyncStorage.getItem('currentRecipeCountry'); + + country = country || asyncCountry; filename = filename || this.getCurrentFile(); // finalize fetch from what? @@ -56,16 +63,19 @@ export class MaterialService { }); } - getMaterialSettingById( + async getMaterialSettingById( id: number, country?: string, filename?: string - ): Observable { + ): Promise> { + + let asyncCountry = await AsyncStorage.getItem('currentRecipeCountry'); + return this._httpClient.get( `${environment.api}/materials/setting/${id}`, { params: { - country: country || this.getCurrentCountry(this.department!), + country: country || asyncCountry, filename: filename || this.getCurrentFile(), }, withCredentials: true, @@ -82,7 +92,7 @@ export class MaterialService { return 'default'; } - getCurrentCountry(department? : string): string { + async getCurrentCountry(department? : string): Promise { // fetch by using department if(department){ @@ -97,7 +107,10 @@ export class MaterialService { } - const currentRecipeCountry = localStorage.getItem('currentRecipeCountry'); + // const currentRecipeCountry = localStorage.getItem('currentRecipeCountry'); + + const currentRecipeCountry = await AsyncStorage.getItem('currentRecipeCountry'); + if (currentRecipeCountry) { return currentRecipeCountry; } diff --git a/client/src/app/core/services/recipe.service.ts b/client/src/app/core/services/recipe.service.ts index 4118993..780d403 100644 --- a/client/src/app/core/services/recipe.service.ts +++ b/client/src/app/core/services/recipe.service.ts @@ -14,6 +14,7 @@ import { environment } from 'src/environments/environment'; import { RecipeMetaData } from 'src/app/shared/types/recipe'; import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; import { ActivatedRoute } from '@angular/router'; +import { AsyncStorage } from 'src/app/shared/helpers/asyncStorage'; type RecipeOverviewParams = { filename: string; @@ -49,7 +50,7 @@ export class RecipeService { constructor(private _httpClient: HttpClient, private _route: ActivatedRoute) {} getRecipesDashboard( - params: RecipeDashboardParams = { + params: any = { country: this.getCurrentCountry(this.department!), filename: this.getCurrentFile(), } @@ -67,8 +68,8 @@ export class RecipeService { ); } - getRecipeOverview( - params: RecipeOverviewParams = { + async getRecipeOverview( + params: any = { country: this.getCurrentCountry(this.department!), filename: this.getCurrentFile(), materialIds: [], @@ -76,7 +77,7 @@ export class RecipeService { take: 20, search: '', } - ): Observable { + ): Promise> { return this._httpClient.get( environment.api + '/recipes/overview', { @@ -94,13 +95,13 @@ export class RecipeService { ); } - getRecipeDetail(productCode: string): Observable { + async getRecipeDetail(productCode: string): Promise> { return this._httpClient.get( environment.api + '/recipes/' + productCode, { params: { filename: this.getCurrentFile(), - country: this.getCurrentCountry(this.department!), + country: await this.getCurrentCountry(this.department!), }, withCredentials: true, responseType: 'json', @@ -108,15 +109,15 @@ export class RecipeService { ); } - getRecipeDetailMat( + async getRecipeDetailMat( productCode: string - ): Observable<{ result: RecipeDetailMat[] }> { + ): Promise> { return this._httpClient.get<{ result: RecipeDetailMat[] }>( environment.api + '/recipes/' + productCode + '/mat', { params: { filename: this.getCurrentFile(), - country: this.getCurrentCountry(this.department!), + country: await this.getCurrentCountry(this.department!), }, withCredentials: true, responseType: 'json', @@ -141,7 +142,7 @@ export class RecipeService { localStorage.setItem('currentRecipeFile', filename); } - getCurrentCountry(department?: string): string { + async getCurrentCountry(department?: string): Promise { if(department){ @@ -151,10 +152,15 @@ export class RecipeService { console.log('fullname: ', fullname); // localStorage.setItem('currentRecipeCountry', fullname); + + await AsyncStorage.setItem('currentRecipeCountry', fullname); + return fullname; } - const currentRecipeCountry = localStorage.getItem('currentRecipeCountry'); + // const currentRecipeCountry = localStorage.getItem('currentRecipeCountry'); + + const currentRecipeCountry = await AsyncStorage.getItem('currentRecipeCountry'); if (currentRecipeCountry) { return currentRecipeCountry; } 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 c03772f..38f1fe4 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 @@ -94,11 +94,11 @@ export class RecipeDetailsComponent implements OnInit { toppingSet: ToppingSet[] | null = null; submenus: Recipe01[] | null = null; - ngOnInit() { + async ngOnInit() { this.productCode = this._route.snapshot.params['productCode']; - this.recipeDetail$ = this._recipeService - .getRecipeDetail(this.productCode) + this.recipeDetail$ = (await this._recipeService + .getRecipeDetail(this.productCode)) .pipe(first()); this.recipeDetail$.subscribe((detail) => { @@ -109,7 +109,7 @@ export class RecipeDetailsComponent implements OnInit { this.recipeOriginalDetail = { ...this.recipeDetailForm.getRawValue() }; }); - this._recipeService.getSubMenus(this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => { + this._recipeService.getSubMenus(await this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => { console.log('Submenus', data); this.submenus = data; }); @@ -143,7 +143,7 @@ export class RecipeDetailsComponent implements OnInit { confirmSave = { title: 'The changes detected!', message: 'Do you want to save changes?', - confirmCallBack: () => { + confirmCallBack: async () => { console.log('confirm save'); // get username @@ -177,7 +177,7 @@ export class RecipeDetailsComponent implements OnInit { // TODO: update value in targeted recipe console.log('to_send', to_send); this._recipeService.editChanges( - this._recipeService.getCurrentCountry(this.department), + await this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile(), { ...to_send, diff --git a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts index 85f5975..9ad52e0 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts @@ -96,9 +96,9 @@ export class RecipeListComponent implements OnInit { private _recipeListOriginalArray!: RecipeDetailMat[]; - ngOnInit(): void { - this._recipeService - .getRecipeDetailMat(this.productCode) + async ngOnInit(): Promise { + (await this._recipeService + .getRecipeDetailMat(this.productCode)) .pipe(first()) .subscribe(({ result }) => { this._recipeListOriginalArray = result; @@ -287,11 +287,13 @@ export class RecipeListComponent implements OnInit { }); // TODO: embed this to recipelist - this._materialService.getMaterialCodes().subscribe((materials) => { + (await + // TODO: embed this to recipelist + this._materialService.getMaterialCodes()).subscribe((materials) => { this.materialList = materials; }); - this._materialService.getFullMaterialDetail().subscribe((materials) => { + (await this._materialService.getFullMaterialDetail()).subscribe((materials) => { this.fullMaterialList = materials; this.categoriedMaterial = this.ListCategory(); console.log(this.categoriedMaterial); diff --git a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts index 9f1c3c0..aeb3e70 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts @@ -32,10 +32,10 @@ export class RecipeToppingComponent implements OnInit { private _recipeService: RecipeService, private _toppingService: ToppingService ) {} - ngOnInit(): void { + async ngOnInit(): Promise { this._toppingService .getToppings( - this._recipeService.getCurrentCountry(), + await this._recipeService.getCurrentCountry(), this._recipeService.getCurrentFile() ) .subscribe((data) => { diff --git a/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts b/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts index 2590fff..b7946be 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts @@ -64,10 +64,10 @@ export class RecipeToppingsetComponent implements OnInit { return this.toppingForm.get('toppingList') as FormArray; } - ngOnInit(): void { + async ngOnInit(): Promise { this._toppingService .getToppingsOfRecipe( - this._recipeService.getCurrentCountry(), + await this._recipeService.getCurrentCountry(), this._recipeService.getCurrentFile(), this.productCode ) @@ -94,7 +94,7 @@ export class RecipeToppingsetComponent implements OnInit { // fetch all toppings : group and list this._toppingService .getToppings( - this._recipeService.getCurrentCountry(), + await this._recipeService.getCurrentCountry(), this._recipeService.getCurrentFile() ) .subscribe((data) => { diff --git a/client/src/app/features/recipes/recipes.component.html b/client/src/app/features/recipes/recipes.component.html index 5e71b4b..6c532c0 100644 --- a/client/src/app/features/recipes/recipes.component.html +++ b/client/src/app/features/recipes/recipes.component.html @@ -11,7 +11,7 @@
Recipe Version {{ currentVersion }} | + >Recipe Version {{ recipesDashboard.configNumber }} | {{ recipesDashboard.filename }}
diff --git a/client/src/app/features/recipes/recipes.component.ts b/client/src/app/features/recipes/recipes.component.ts index 1c6b4e4..9c70660 100644 --- a/client/src/app/features/recipes/recipes.component.ts +++ b/client/src/app/features/recipes/recipes.component.ts @@ -34,6 +34,7 @@ import { UserPermissions } from 'src/app/core/auth/userPermissions'; import { ToppingService } from 'src/app/core/services/topping.service'; import { copy, transformToTSV } from 'src/app/shared/helpers/copy'; import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; +import { AsyncStorage } from 'src/app/shared/helpers/asyncStorage'; @Component({ selector: 'app-recipes', @@ -96,7 +97,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { @ViewChild('table', { static: false }) set content(table: ElementRef) { table.nativeElement.addEventListener( 'scroll', - () => { + async () => { if (this.isHasMore === false) { return; } @@ -105,15 +106,15 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { const isBottom = scrollTop + clientHeight >= scrollHeight - 10; if (isBottom && !this.isLoadMore) { this.isLoadMore = true; - this._recipeService + (await this._recipeService .getRecipeOverview({ offset: this.offset, take: this.take, search: this.oldSearchStr, filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(this.department), + country: await this._recipeService.getCurrentCountry(this.department), materialIds: this.selectMaterialFilter || [], - }) + })) .subscribe(({ result, hasMore, totalCount }) => { if (this.recipeOverviewList) { this.recipeOverviewList = @@ -140,24 +141,24 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { private _router: Router ) {} - ngOnInit(): void { + async ngOnInit(): Promise { console.log('Trigger onInit where department = ', this.department); this.recipesDashboard$ = this._recipeService .getRecipesDashboard({ filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(this.department!), + country: await this._recipeService.getCurrentCountry(this.department!), }) .pipe( - finalize(() => { - this._recipeService + finalize(async () => { + (await this._recipeService .getRecipeOverview({ offset: this.offset, take: this.take, search: this.oldSearchStr, filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(this.department!), + country: await this._recipeService.getCurrentCountry(this.department!), materialIds: this.selectMaterialFilter || [], - }) + })) .subscribe(({ result, hasMore, totalCount }) => { this.recipeOverviewList = result; this.offset += 10; @@ -177,14 +178,14 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { console.log('ngAfterViewInit::department', this.department); console.log('::CurrentFile', this._recipeService.getCurrentFile()); - this._materialService + (await this._materialService .getFullMaterialDetail( this.department, this._recipeService.getCurrentFile() - ) + )) .subscribe((mat) => { this.materialDetail = mat; - console.log(this.materialDetail?.length); + console.log(this.materialDetail?.length, "[0]=", mat?.at(0), "current country", this._recipeService.getCurrentCountry(), "currentFile", this._recipeService.getCurrentFile()); // check material detail console.log('first material', this.materialDetail![0]); @@ -194,7 +195,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { this._recipeService .getSavedTmp( - this._recipeService.getCurrentCountry(this.department), + await this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile() ) .subscribe({ @@ -224,8 +225,10 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { }); // TODO: get all materials; MaterialSetting + MaterialCode - this._materialService - .getMaterialCodes() + (await + // TODO: get all materials; MaterialSetting + MaterialCode + this._materialService + .getMaterialCodes()) .pipe( map((mat) => mat.map((m) => ({ @@ -260,19 +263,26 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { this.searchStr = (event.target as HTMLInputElement).value; } - search(event: Event) { + async search(event: Event) { + + // country + let country = await this._recipeService.getCurrentCountry(this.department).then( + (country) => country + ); + + this.offset = 0; this.isLoadMore = true; this.oldSearchStr = this.searchStr; - this._recipeService + (await this._recipeService .getRecipeOverview({ offset: this.offset, take: this.take, search: this.oldSearchStr, filename: this._recipeService.getCurrentFile(), - country: this._recipeService.getCurrentCountry(this.department), + country: country, materialIds: this.selectMaterialFilter || [], - }) + })) .subscribe(({ result, hasMore, totalCount }) => { this.recipeOverviewList = result; this.offset += 10; @@ -420,20 +430,19 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { ); } - countrySelected(country: string) { + async countrySelected(country: string) { this.selectedCountry = country; this.isCountrySelected = true; // localStorage.setItem('currentRecipeCountry', country); + await AsyncStorage.setItem('currentRecipeCountry', country); + // force reload, will fix this later void this._router - .navigate([`/${getCountryMapSwitcher(country)}/recipes`]) - .then(() => { - window.location.reload(); - }); + .navigate([`/${getCountryMapSwitcher(country)}/recipes`]); } - loadRecipe(recipeFileName: string) { + async loadRecipe(recipeFileName: string) { // clear all recipes this.offset = 0; this.isHasMore = true; @@ -441,33 +450,43 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { this.oldSearchStr = ''; // localStorage.setItem('currentRecipeFile', recipeFileName); - console.log('loadRecipe', recipeFileName, "currentCountry", this.department); + await AsyncStorage.setItem('currentRecipeFile', recipeFileName); - this.recipesDashboard$ = this._recipeService.getRecipesDashboard({ - filename: recipeFileName, - country: this.department!, - }); - this.recipesDashboard$.subscribe((data) => { - this.currentVersion = data.configNumber; - console.log('current version', this.currentVersion); - }); - this._recipeService - .getRecipeOverview({ - offset: this.offset, - take: this.take, - search: this.oldSearchStr, - filename: recipeFileName, - country: this.selectedCountry!, - materialIds: this.selectMaterialFilter || [], - }) - .subscribe(({ result, hasMore, totalCount }) => { - this.recipeOverviewList = result; - this.offset += 10; - this.isHasMore = hasMore; - this.isLoadMore = false; - }); + + console.log('loadRecipe', recipeFileName, "currentCountry", this.department, "selectedCountry", this.selectedCountry); + + // clear all menus + this.recipeOverviewList = []; + + // this.recipesDashboard$ = this._recipeService.getRecipesDashboard({ + // filename: recipeFileName, + // country: this.selectedCountry!, + // }); + + // this.recipesDashboard$.subscribe((data) => { + // this.currentVersion = data.configNumber; + // console.log('current version', this.currentVersion); + // }); + + // this._recipeService + // .getRecipeOverview({ + // offset: this.offset, + // take: this.take, + // search: this.oldSearchStr, + // filename: recipeFileName, + // country: this.selectedCountry!, + // materialIds: this.selectMaterialFilter || [], + // }) + // .subscribe(({ result, hasMore, totalCount }) => { + // this.recipeOverviewList = result; + // this.offset += 10; + // this.isHasMore = hasMore; + // this.isLoadMore = false; + // }); + + window.location.reload(); } // end of Recipe Version selection @@ -487,7 +506,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { this.saveTab = true; } - loadSavedFile(file_commit: any) { + async loadSavedFile(file_commit: any) { this.showSaveNoti = false; this.saveTab = false; console.log('loadSavedFile', file_commit, this.department); @@ -511,7 +530,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { console.log(file_commit.Change_file.split('/')[2]); - this._recipeService + (await this._recipeService .getRecipeOverview({ offset: this.offset, take: this.take, @@ -519,7 +538,7 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { filename: file_commit.Change_file.split('/')[2], country: country, materialIds: this.selectMaterialFilter || [], - }) + })) .subscribe(({ result, hasMore, totalCount }) => { console.log('loadSavedFile', result); this._recipeService.setCurrentFile( diff --git a/client/src/app/shared/helpers/asyncStorage.ts b/client/src/app/shared/helpers/asyncStorage.ts new file mode 100644 index 0000000..6b3e304 --- /dev/null +++ b/client/src/app/shared/helpers/asyncStorage.ts @@ -0,0 +1,14 @@ +export class AsyncStorage { + static async getItem(key: string) { + return new Promise((resolve) => { + resolve(localStorage.getItem(key) as T); + }); + } + + static async setItem(key: string, value: string) { + return new Promise((resolve) => { + localStorage.setItem(key, value); + resolve(); + }); + } +} diff --git a/server/data/data.go b/server/data/data.go index 018dd97..4b1b505 100644 --- a/server/data/data.go +++ b/server/data/data.go @@ -18,7 +18,7 @@ import ( ) type RecipeWithTimeStamps struct { - Recipe models.Recipe + Recipe map[string]*models.Recipe TimeStamps int64 } @@ -27,7 +27,7 @@ type Data struct { CurrentCountryID map[string]string DefaultCountryMap []DefaultByCountry AllRecipeFiles map[string][]helpers.RecipePath - currentRecipe *models.Recipe + currentRecipe map[string]*models.Recipe recipeMap map[string]RecipeWithTimeStamps Countries []helpers.CountryName taoLogger *logger.TaoLogger @@ -58,7 +58,6 @@ func NewData(taoLogger *logger.TaoLogger) *Data { allRecipeFiles := helpers.ScanRecipeFiles(countries) defaultFile := "coffeethai02_600.json" - defaultCountry := "tha" // TODO: read 'version' file by country @@ -102,6 +101,7 @@ func NewData(taoLogger *logger.TaoLogger) *Data { currentFileMap := make(map[string]string) CurrentCountryIDMap := make(map[string]string) + currentDefaultFileForEachCountry := make(map[string]*models.Recipe) // all default versions as string versionsString := "" @@ -125,6 +125,13 @@ func NewData(taoLogger *logger.TaoLogger) *Data { versionsString = versionsString + v.CountryShortName + ":" + strconv.Itoa(current_version_iter) + "," + // do read default + defaultRecipe, err := helpers.ReadRecipeFile(v.CountryShortName, v2.Name) + if err != nil { + log.Panic("Error when read default recipe file for each country:", v.CountryShortName, err) + } + + currentDefaultFileForEachCountry[v.CountryShortName] = defaultRecipe break } } @@ -148,22 +155,24 @@ func NewData(taoLogger *logger.TaoLogger) *Data { // } // } - taoLogger.Log.Debug("defaultFile", zap.Any("defaultFile", defaultFile), zap.Any("latest_version", versionsString)) + // FIXME: default file bug. do assign each default recipe model to each country - defaultRecipe, err := helpers.ReadRecipeFile(defaultCountry, defaultFile) + // taoLogger.Log.Debug("defaultFile", zap.Any("defaultFile", defaultFile), zap.Any("latest_version", versionsString)) - if err != nil { - log.Panic("Error when read default recipe file:", err) - } + // defaultRecipe, err := helpers.ReadRecipeFile(defaultCountry, defaultFile) + + // if err != nil { + // log.Panic("Error when read default recipe file:", err) + // } return &Data{ CurrentFile: currentFileMap, CurrentCountryID: CurrentCountryIDMap, AllRecipeFiles: allRecipeFiles, - currentRecipe: defaultRecipe, + currentRecipe: currentDefaultFileForEachCountry, recipeMap: map[string]RecipeWithTimeStamps{ defaultFile: { - Recipe: *defaultRecipe, + Recipe: currentDefaultFileForEachCountry, TimeStamps: time.Now().Unix(), }, }, @@ -176,17 +185,17 @@ func NewData(taoLogger *logger.TaoLogger) *Data { func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { if countryID == "" { - return d.currentRecipe + return d.currentRecipe["tha"] } if filename == "" || filename == d.CurrentFile[countryID] { - return d.currentRecipe + return d.currentRecipe[countryID] } if recipe, ok := d.recipeMap[filename]; ok { d.CurrentFile[countryID] = filename d.CurrentCountryID[countryID] = countryID - return &recipe.Recipe + return recipe.Recipe[countryID] } // change current version and read new recipe @@ -202,10 +211,10 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) - return d.currentRecipe + return d.currentRecipe[countryID] } - d.currentRecipe = recipe + d.currentRecipe[countryID] = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version @@ -222,34 +231,34 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { } d.recipeMap[filename] = RecipeWithTimeStamps{ - Recipe: *d.currentRecipe, + Recipe: d.currentRecipe, TimeStamps: time.Now().Unix(), } - return d.currentRecipe + return d.currentRecipe[countryID] } -func (d *Data) GetRecipe01() []models.Recipe01 { - return d.currentRecipe.Recipe01 -} +// func (d *Data) GetRecipe01() []models.Recipe01 { +// return d.currentRecipe.Recipe01 +// } -func (d *Data) GetCurrentRecipe() *models.Recipe { - return d.currentRecipe -} +// func (d *Data) GetCurrentRecipe() *models.Recipe { +// return d.currentRecipe +// } func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) (models.Recipe01, error) { if !strings.Contains(filename, "tmp") { if filename == "" || filename == d.CurrentFile[countryID] { fmt.Println("GetRecipe01ByProductCode.ReadCurrent", filename, d.CurrentFile) - for _, v := range d.currentRecipe.Recipe01 { + for _, v := range d.currentRecipe[countryID].Recipe01 { if v.ProductCode == productCode { return v, nil } } } else if recipe, ok := d.recipeMap[filename]; ok { fmt.Println("GetRecipe01ByProductCode.ReadMap", filename, d.CurrentFile) - for _, v := range recipe.Recipe.Recipe01 { + for _, v := range recipe.Recipe[countryID].Recipe01 { if v.ProductCode == productCode { return v, nil } @@ -278,7 +287,7 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) - for _, v := range d.currentRecipe.Recipe01 { + for _, v := range d.currentRecipe[countryID].Recipe01 { if v.ProductCode == productCode { return v, nil } @@ -287,7 +296,7 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) d.taoLogger.Log.Debug("GetRecipe01ByProductCode", zap.Any("productCode", productCode), zap.Any("version", recipe.MachineSetting.ConfigNumber)) - d.currentRecipe = recipe + d.currentRecipe[countryID] = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version @@ -304,11 +313,11 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) } d.recipeMap[filename] = RecipeWithTimeStamps{ - Recipe: *d.currentRecipe, + Recipe: d.currentRecipe, TimeStamps: time.Now().Unix(), } - for _, v := range d.currentRecipe.Recipe01 { + 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 @@ -358,22 +367,22 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS result := make([]models.MaterialSetting, 0) if countryID == "" { - copy(result, d.currentRecipe.MaterialSetting) + copy(result, d.currentRecipe[countryID].MaterialSetting) return result } if !strings.Contains(filename, "tmp") { if filename == "" || filename == d.CurrentFile[countryID] { - copy(result, d.currentRecipe.MaterialSetting) + copy(result, d.currentRecipe[countryID].MaterialSetting) d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("result", result)) - return d.currentRecipe.MaterialSetting + return d.currentRecipe[countryID].MaterialSetting } if recipe, ok := d.recipeMap[filename]; ok { - copy(result, recipe.Recipe.MaterialSetting) + copy(result, recipe.Recipe[countryID].MaterialSetting) d.CurrentFile[countryID] = filename d.CurrentCountryID[countryID] = countryID - return d.currentRecipe.MaterialSetting + return d.currentRecipe[countryID].MaterialSetting } } @@ -389,13 +398,13 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) - copy(result, d.currentRecipe.MaterialSetting) - return d.currentRecipe.MaterialSetting + copy(result, d.currentRecipe[countryID].MaterialSetting) + return d.currentRecipe[countryID].MaterialSetting } d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("recipe", recipe.MaterialSetting)) - d.currentRecipe = recipe + d.currentRecipe[countryID] = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version @@ -412,7 +421,7 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS } d.recipeMap[filename] = RecipeWithTimeStamps{ - Recipe: *d.currentRecipe, + Recipe: d.currentRecipe, TimeStamps: time.Now().Unix(), } @@ -424,10 +433,10 @@ func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []model var result []models.MaterialCode if filename == "" || filename == d.CurrentFile[countryID] { - result = d.currentRecipe.MaterialCode + result = d.currentRecipe[countryID].MaterialCode } else if recipe, ok := d.recipeMap[filename]; ok { d.CurrentFile[countryID] = filename - return recipe.Recipe.MaterialCode + return recipe.Recipe[countryID].MaterialCode } else { if filename == "default" { @@ -440,10 +449,10 @@ func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []model if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) - return d.currentRecipe.MaterialCode + return d.currentRecipe[countryID].MaterialCode } - d.currentRecipe = recipe + d.currentRecipe[countryID] = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version @@ -460,11 +469,11 @@ func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []model } d.recipeMap[filename] = RecipeWithTimeStamps{ - Recipe: *d.currentRecipe, + Recipe: d.currentRecipe, TimeStamps: time.Now().Unix(), } - result = d.currentRecipe.MaterialCode + result = d.currentRecipe[countryID].MaterialCode } if len(ids) == 0 { @@ -491,10 +500,10 @@ func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []model func (d *Data) GetToppings(countryID, filename string) models.Topping { if filename == "" || filename == d.CurrentFile[countryID] { - return d.currentRecipe.Topping + return d.currentRecipe[countryID].Topping } else if recipe, ok := d.recipeMap[filename]; ok { d.CurrentFile[countryID] = filename - return recipe.Recipe.Topping + return recipe.Recipe[countryID].Topping } if filename == "default" { @@ -507,10 +516,10 @@ func (d *Data) GetToppings(countryID, filename string) models.Topping { if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) - return d.currentRecipe.Topping + return d.currentRecipe[countryID].Topping } - d.currentRecipe = recipe + d.currentRecipe[countryID] = recipe return recipe.Topping } diff --git a/server/routers/material.go b/server/routers/material.go index cc68f1b..ff19f29 100644 --- a/server/routers/material.go +++ b/server/routers/material.go @@ -75,7 +75,7 @@ func (mr *MaterialRouter) GetFullMaterialDetail(w http.ResponseWriter, r *http.R }) } - // mr.taoLogger.Log.Debug("GetFullMaterialDetail", zap.Any("materialDetails", materialDetails)) + mr.taoLogger.Log.Debug("GetFullMaterialDetail", zap.Any("materialDetails", materialDetails[0])) // send result if err := json.NewEncoder(w).Encode(materialDetails); err != nil { diff --git a/server/routers/recipe.go b/server/routers/recipe.go index f1a6aae..f0a5886 100644 --- a/server/routers/recipe.go +++ b/server/routers/recipe.go @@ -173,6 +173,8 @@ func (rr *RecipeRouter) dashBoard(w http.ResponseWriter, r *http.Request) { country := r.URL.Query().Get("country") filename := r.URL.Query().Get("filename") + rr.taoLogger.Log.Debug("RecipeRouter.Dashboard", zap.Any("country", country), zap.Any("filename", filename)) + result, err := rr.recipeService.GetRecipeDashboard(&contracts.RecipeDashboardRequest{ Country: country, Filename: filename, @@ -205,6 +207,8 @@ func (rr *RecipeRouter) overview(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") materialIds := r.URL.Query().Get("materialIds") + rr.taoLogger.Log.Debug("RecipeRouter.Overview", zap.Any("take", take), zap.Any("offset", offset), zap.Any("country", country), zap.Any("filename", filename), zap.Any("materialIds", materialIds)) + var materialIdsUint []int for _, v := range strings.Split(materialIds, ",") { materialIdUint, err := strconv.ParseUint(v, 10, 64) diff --git a/server/services/recipe/recipe.go b/server/services/recipe/recipe.go index ef70f73..6fa84de 100644 --- a/server/services/recipe/recipe.go +++ b/server/services/recipe/recipe.go @@ -186,6 +186,16 @@ func (rs *recipeService) GetRecipeDashboard(request *contracts.RecipeDashboardRe recipe := rs.db.GetRecipe(countryID, request.Filename) + // recheck if filename is `default` + + if request.Filename == "default" { + for _, v := range rs.db.DefaultCountryMap { + if v.CountryShortName == request.Country || v.CountryLongName == request.Country { + request.Filename = rs.db.CurrentFile[v.CountryShortName] + } + } + } + result := contracts.RecipeDashboardResponse{ ConfigNumber: recipe.MachineSetting.ConfigNumber, LastUpdated: recipe.Timestamp, From 09d71ac61e8bfcbdf6a1332b2233e8dabef32bf2 Mon Sep 17 00:00:00 2001 From: "pakintada@gmail.com" Date: Fri, 19 Jan 2024 14:59:21 +0700 Subject: [PATCH 3/5] fix country params --- .../src/app/core/services/material.service.ts | 12 +- .../src/app/core/services/recipe.service.ts | 12 +- .../src/app/core/services/topping.service.ts | 18 +- .../recipe-details.component.html | 4 +- .../recipe-details.component.ts | 6 +- .../recipe-list/recipe-list.component.ts | 14 +- .../recipe-topping.component.ts | 11 +- .../recipe-toppingset.component.html | 4 +- .../recipe-toppingset.component.ts | 374 +++++++++--------- .../app/features/recipes/recipes.component.ts | 4 +- server/data/data.go | 74 ++-- server/routers/material.go | 6 +- server/services/recipe/recipe.go | 2 +- 13 files changed, 299 insertions(+), 242 deletions(-) diff --git a/client/src/app/core/services/material.service.ts b/client/src/app/core/services/material.service.ts index 52edb32..4f3019f 100644 --- a/client/src/app/core/services/material.service.ts +++ b/client/src/app/core/services/material.service.ts @@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { MaterialCode, MaterialSetting } from '../models/recipe.model'; import { environment } from 'src/environments/environment'; -import { Observable } from 'rxjs'; +import { Observable, count } from 'rxjs'; import { ActivatedRoute } from '@angular/router'; import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; import { AsyncStorage } from 'src/app/shared/helpers/asyncStorage'; @@ -44,11 +44,13 @@ export class MaterialService { "name": string, "type": string }[] | null>>{ - console.log("getFullMaterialDetail", country, filename, country || this.getCurrentCountry(this.department!)); + console.log("getFullMaterialDetail", country, "where filename = ",filename, "department.short = ", this.department!); - let asyncCountry = await AsyncStorage.getItem('currentRecipeCountry'); + let currentCountryWithoutDepartment = await this.getCurrentCountry(); + let asyncCountry = await this.getCurrentCountry(this.department!); - country = country || asyncCountry; + console.log("[FullMatFetchService] get current country = ", currentCountryWithoutDepartment, " do switch tuple = ", getCountryMapSwitcher(currentCountryWithoutDepartment)); + country = getCountryMapSwitcher(currentCountryWithoutDepartment); filename = filename || this.getCurrentFile(); // finalize fetch from what? @@ -102,6 +104,8 @@ export class MaterialService { console.log('Material.service::fullname: ', fullname); + await AsyncStorage.setItem('currentRecipeCountry', fullname); + // localStorage.setItem('currentRecipeCountry', fullname); return fullname; } diff --git a/client/src/app/core/services/recipe.service.ts b/client/src/app/core/services/recipe.service.ts index 780d403..730d7b5 100644 --- a/client/src/app/core/services/recipe.service.ts +++ b/client/src/app/core/services/recipe.service.ts @@ -96,12 +96,16 @@ export class RecipeService { } async getRecipeDetail(productCode: string): Promise> { + + let asyncCountry = await this.getCurrentCountry(this.department!); + console.log('get detail by asyncCountry', asyncCountry); + return this._httpClient.get( environment.api + '/recipes/' + productCode, { params: { filename: this.getCurrentFile(), - country: await this.getCurrentCountry(this.department!), + country: asyncCountry, }, withCredentials: true, responseType: 'json', @@ -112,12 +116,15 @@ export class RecipeService { async getRecipeDetailMat( productCode: string ): Promise> { + + let asyncCountry = await this.getCurrentCountry(this.department!); + return this._httpClient.get<{ result: RecipeDetailMat[] }>( environment.api + '/recipes/' + productCode + '/mat', { params: { filename: this.getCurrentFile(), - country: await this.getCurrentCountry(this.department!), + country: asyncCountry, }, withCredentials: true, responseType: 'json', @@ -251,6 +258,7 @@ export class RecipeService { } getSubMenus(country: string, filename: string, productCode: string) { + console.log('getSubMenus', country, filename, productCode); return this._httpClient.get( environment.api + '/recipes/' + diff --git a/client/src/app/core/services/topping.service.ts b/client/src/app/core/services/topping.service.ts index 0f282d3..22d1ca5 100644 --- a/client/src/app/core/services/topping.service.ts +++ b/client/src/app/core/services/topping.service.ts @@ -1,16 +1,22 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Observable, count } from 'rxjs'; import { environment } from 'src/environments/environment'; import { Topping, ToppingSet } from '../models/recipe.model'; +import { RecipeService } from './recipe.service'; +import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe'; @Injectable({ providedIn: 'root', }) export class ToppingService { - constructor(private _httpClient: HttpClient) {} + constructor(private _httpClient: HttpClient, private _recipeService: RecipeService) {} - getToppings(country: string, filename: string): Observable { + async getToppings(country: string, filename: string): Promise> { + console.log("getToppings", country); + let asyncCountry = await this._recipeService.getCurrentCountry(); + country = getCountryMapSwitcher(asyncCountry); + console.log("getToppingsPreFetch", country, asyncCountry); return this._httpClient.get( `${environment.api}/recipes/${country}/${filename}/toppings`, { @@ -23,7 +29,11 @@ export class ToppingService { ); } - getToppingsOfRecipe(country: string, filename: string, productCode: string): Observable { + async getToppingsOfRecipe(country: string, filename: string, productCode: string): Promise> { + console.log("getToppingsOfRecipe", country); + let asyncCountry = await this._recipeService.getCurrentCountry(); + country = country || asyncCountry; + console.log("getToppingsOfRecipePreFetch", country, asyncCountry); return this._httpClient.get( `${environment.api}/recipes/${country}/${filename}/${productCode}/toppings`, { diff --git a/client/src/app/features/recipes/recipe-details/recipe-details.component.html b/client/src/app/features/recipes/recipe-details/recipe-details.component.html index ed0ff21..9969e91 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-details.component.html +++ b/client/src/app/features/recipes/recipe-details/recipe-details.component.html @@ -130,7 +130,7 @@
- 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 38f1fe4..f08f879 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 @@ -20,7 +20,6 @@ import { UserPermissions } from 'src/app/core/auth/userPermissions'; import { ToppingService } from 'src/app/core/services/topping.service'; import { copy, transformToTSV } from 'src/app/shared/helpers/copy'; -import { RecipeToppingsetComponent } from "./recipe-toppingset/recipe-toppingset.component"; @Component({ selector: 'app-recipe-details', @@ -41,7 +40,6 @@ import { RecipeToppingsetComponent } from "./recipe-toppingset/recipe-toppingset ConfirmModal, DatePipe, RecipeListComponent, - RecipeToppingsetComponent, FormsModule ] }) @@ -109,7 +107,7 @@ export class RecipeDetailsComponent implements OnInit { this.recipeOriginalDetail = { ...this.recipeDetailForm.getRawValue() }; }); - this._recipeService.getSubMenus(await this._recipeService.getCurrentCountry(this.department), this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => { + this._recipeService.getSubMenus(await this._recipeService.getCurrentCountry(), this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => { console.log('Submenus', data); this.submenus = data; }); @@ -117,7 +115,7 @@ export class RecipeDetailsComponent implements OnInit { this.recipeDetailForm.valueChanges.subscribe(this.onRecipeDetailFormChange); - this._toppingService.getToppingsOfRecipe(this.department, this._recipeService.getCurrentFile(), this.productCode).subscribe((data) => { + (await this._toppingService.getToppingsOfRecipe(this.department, this._recipeService.getCurrentFile(), this.productCode)).subscribe((data) => { this.toppingSet = data; // console.log('Toppings', data); }) diff --git a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts index 9ad52e0..25273d5 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts @@ -1,5 +1,5 @@ import { NgFor, NgIf } from '@angular/common'; -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnInit, Output, ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR } from '@angular/core'; import { FormArray, FormBuilder, @@ -291,6 +291,7 @@ export class RecipeListComponent implements OnInit { // TODO: embed this to recipelist this._materialService.getMaterialCodes()).subscribe((materials) => { this.materialList = materials; + console.log("[MatService] get materials", materials.length); }); (await this._materialService.getFullMaterialDetail()).subscribe((materials) => { @@ -384,6 +385,17 @@ export class RecipeListComponent implements OnInit { this.fullMaterialList!.forEach((mat) => { let category = getMaterialType(mat.materialId); + // try again + if(category == 'others'){ + // find min + // console.log(Math.floor(mat.materialId / 1000) ); + let interCode = Math.floor(mat.materialId / 10000) * 10000; + let originalCode = mat.materialId - (interCode); + + console.log("from",mat.materialId,"interCode", interCode, "originalCode", originalCode); + category = getMaterialType(originalCode); + console.log("get original category of inter", category); + } if (Array.isArray(catMap[category])) { catMap[category].push({ diff --git a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts index aeb3e70..2d0a79a 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts @@ -5,6 +5,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RecipeService } from 'src/app/core/services/recipe.service'; import { ToppingService } from 'src/app/core/services/topping.service'; import { Topping, ToppingGroup, ToppingSet } from 'src/app/core/models/recipe.model'; +import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-recipe-topping', @@ -27,17 +28,19 @@ export class RecipeToppingComponent implements OnInit { id: string; members: { id: string; name: string }[]; }[] = []; + department = this._route.snapshot.paramMap.get('department'); constructor( private _recipeService: RecipeService, - private _toppingService: ToppingService + private _toppingService: ToppingService, + private _route: ActivatedRoute ) {} async ngOnInit(): Promise { - this._toppingService + (await this._toppingService .getToppings( - await this._recipeService.getCurrentCountry(), + this.department!, this._recipeService.getCurrentFile() - ) + )) .subscribe((data) => { this.allToppings = data; // console.log('allToppings', data); diff --git a/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.html b/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.html index edd4336..215a0f7 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.html +++ b/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.html @@ -1,4 +1,4 @@ - + -
+ --> diff --git a/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts b/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts index b7946be..26a3757 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-toppingset/recipe-toppingset.component.ts @@ -1,220 +1,220 @@ -import { NgFor } from '@angular/common'; -import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core'; -import { - FormArray, - FormBuilder, - FormsModule, - ReactiveFormsModule, -} from '@angular/forms'; -import { forEach, isEqual } from 'lodash'; -import { - Topping, - ToppingGroup, - ToppingList, - ToppingSet, -} from 'src/app/core/models/recipe.model'; -import { RecipeService } from 'src/app/core/services/recipe.service'; -import { ToppingService } from 'src/app/core/services/topping.service'; -import { NgSelectModule } from '@ng-select/ng-select'; -import { CommonModule } from '@angular/common'; +// import { NgFor } from '@angular/common'; +// import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core'; +// import { +// FormArray, +// FormBuilder, +// FormsModule, +// ReactiveFormsModule, +// } from '@angular/forms'; +// import { forEach, isEqual } from 'lodash'; +// import { +// Topping, +// ToppingGroup, +// ToppingList, +// ToppingSet, +// } from 'src/app/core/models/recipe.model'; +// import { RecipeService } from 'src/app/core/services/recipe.service'; +// import { ToppingService } from 'src/app/core/services/topping.service'; +// import { NgSelectModule } from '@ng-select/ng-select'; +// import { CommonModule } from '@angular/common'; -@Component({ - selector: 'app-recipe-toppingset', - templateUrl: './recipe-toppingset.component.html', - standalone: true, - imports: [ - NgFor, - FormsModule, - ReactiveFormsModule, - CommonModule, - NgSelectModule, - ], -}) -export class RecipeToppingsetComponent implements OnInit { - @Input() productCode!: string; - @Output() toppingSetChange = new EventEmitter(); +// @Component({ +// selector: 'app-recipe-toppingset', +// templateUrl: './recipe-toppingset.component.html', +// standalone: true, +// imports: [ +// NgFor, +// FormsModule, +// ReactiveFormsModule, +// CommonModule, +// NgSelectModule, +// ], +// }) +// export class RecipeToppingsetComponent implements OnInit { +// @Input() productCode!: string; +// @Output() toppingSetChange = new EventEmitter(); - allToppings: Topping | undefined = undefined; +// allToppings: Topping | undefined = undefined; - allToppingsDefinitions: - | { groupId: string; name: string; members: string; default: string }[] - | null = [{ groupId: '0', name: 'none', members: '0', default: '0' }]; +// allToppingsDefinitions: +// | { groupId: string; name: string; members: string; default: string }[] +// | null = [{ groupId: '0', name: 'none', members: '0', default: '0' }]; - allToppingMembersByGroup: { - id: string; - members: { id: string; name: string }[]; - }[] = []; +// allToppingMembersByGroup: { +// id: string; +// members: { id: string; name: string }[]; +// }[] = []; - private _toppingSetOriginalArray!: ToppingSet[]; +// private _toppingSetOriginalArray!: ToppingSet[]; - constructor( - private _recipeService: RecipeService, - private _toppingService: ToppingService, - private _formBuilder: FormBuilder - ) {} +// constructor( +// private _recipeService: RecipeService, +// private _toppingService: ToppingService, +// private _formBuilder: FormBuilder +// ) {} - toppingForm = this._formBuilder.group( - { - toppingList: this._formBuilder.array([]), - }, - { updateOn: 'blur' } - ); +// toppingForm = this._formBuilder.group( +// { +// toppingList: this._formBuilder.array([]), +// }, +// { updateOn: 'blur' } +// ); - get toppingList(): FormArray { - return this.toppingForm.get('toppingList') as FormArray; - } +// get toppingList(): FormArray { +// return this.toppingForm.get('toppingList') as FormArray; +// } - async ngOnInit(): Promise { - this._toppingService - .getToppingsOfRecipe( - await this._recipeService.getCurrentCountry(), - this._recipeService.getCurrentFile(), - this.productCode - ) - .subscribe((data) => { - // this.toppingForm.patchValue({toppingList: data}); - this._toppingSetOriginalArray = data; +// async ngOnInit(): Promise { +// this._toppingService +// .getToppingsOfRecipe( +// await this._recipeService.getCurrentCountry(), +// this._recipeService.getCurrentFile(), +// this.productCode +// ) +// .subscribe((data) => { +// // this.toppingForm.patchValue({toppingList: data}); +// this._toppingSetOriginalArray = data; - data.forEach((toppingSet: ToppingSet) => { - this.toppingList.push( - this._formBuilder.group({ - isUse: toppingSet.isUse, - groupID: toppingSet.groupID, - defaultIDSelect: toppingSet.defaultIDSelect, - ListGroupID: toppingSet.ListGroupID, - }) - ); - }); +// data.forEach((toppingSet: ToppingSet) => { +// this.toppingList.push( +// this._formBuilder.group({ +// isUse: toppingSet.isUse, +// groupID: toppingSet.groupID, +// defaultIDSelect: toppingSet.defaultIDSelect, +// ListGroupID: toppingSet.ListGroupID, +// }) +// ); +// }); - // console.log('controls', this.toppingList.controls); +// // console.log('controls', this.toppingList.controls); - // this.toppingSetChange.emit(this.toppingSetList); - }); +// // this.toppingSetChange.emit(this.toppingSetList); +// }); - // fetch all toppings : group and list - this._toppingService - .getToppings( - await this._recipeService.getCurrentCountry(), - this._recipeService.getCurrentFile() - ) - .subscribe((data) => { - this.allToppings = data; - // console.log('allToppings', data); +// // fetch all toppings : group and list +// this._toppingService +// .getToppings( +// await this._recipeService.getCurrentCountry(), +// this._recipeService.getCurrentFile() +// ) +// .subscribe((data) => { +// this.allToppings = data; +// // console.log('allToppings', data); - data.ToppingGroup.forEach((group: ToppingGroup) => { - if (this.allToppingsDefinitions != null) { - // this.allToppingsDefinitions = {}; - this.allToppingsDefinitions.push({ - groupId: group.groupID, - name: group.name, - members: group.idInGroup, - default: group.idDefault, - }); +// data.ToppingGroup.forEach((group: ToppingGroup) => { +// if (this.allToppingsDefinitions != null) { +// // this.allToppingsDefinitions = {}; +// this.allToppingsDefinitions.push({ +// groupId: group.groupID, +// name: group.name, +// members: group.idInGroup, +// default: group.idDefault, +// }); - this.allToppingMembersByGroup.push({ - id: group.groupID, - members: this.mapToppingListToMember(group.idInGroup.split(',')), - }); - } - }); +// this.allToppingMembersByGroup.push({ +// id: group.groupID, +// members: this.mapToppingListToMember(group.idInGroup.split(',')), +// }); +// } +// }); - // console.log(this.allToppingsDefinitions); - // console.log('allToppingMembersByGroup', this.allToppingMembersByGroup); - }); +// // console.log(this.allToppingsDefinitions); +// // console.log('allToppingMembersByGroup', this.allToppingMembersByGroup); +// }); - this.toppingForm.valueChanges.subscribe((value) => { - //validator - for (let i = 0; i < value.toppingList!.length; i++) { - let toppingSet = value.toppingList![i] as any; +// this.toppingForm.valueChanges.subscribe((value) => { +// //validator +// for (let i = 0; i < value.toppingList!.length; i++) { +// let toppingSet = value.toppingList![i] as any; - // handle null case - if (toppingSet.defaultIDSelect == null) { - toppingSet.defaultIDSelect = 0; - } +// // handle null case +// if (toppingSet.defaultIDSelect == null) { +// toppingSet.defaultIDSelect = 0; +// } - // handle null case - if (toppingSet.groupID == null) { - toppingSet.groupID = '0'; - } +// // handle null case +// if (toppingSet.groupID == null) { +// toppingSet.groupID = '0'; +// } - // handle null case - if (!Array.isArray(toppingSet.ListGroupID)) { - toppingSet.ListGroupID = [parseInt(toppingSet.groupID), 0, 0, 0]; - } - } - let isDiff = !isEqual(this._toppingSetOriginalArray, value.toppingList!); +// // handle null case +// if (!Array.isArray(toppingSet.ListGroupID)) { +// toppingSet.ListGroupID = [parseInt(toppingSet.groupID), 0, 0, 0]; +// } +// } +// let isDiff = !isEqual(this._toppingSetOriginalArray, value.toppingList!); - if (isDiff) { - let newToppingSetList: any[] = []; +// if (isDiff) { +// let newToppingSetList: any[] = []; - forEach(value.toppingList!, (toppingSet: any) => { - // transform value - toppingSet.defaultIDSelect = parseInt(toppingSet.defaultIDSelect); +// forEach(value.toppingList!, (toppingSet: any) => { +// // transform value +// toppingSet.defaultIDSelect = parseInt(toppingSet.defaultIDSelect); - newToppingSetList.push(toppingSet); - }); +// newToppingSetList.push(toppingSet); +// }); - // console.log('newToppingList', newToppingSetList); - this.toppingSetChange.emit(newToppingSetList as unknown[]); - } else { - // console.log('newToppingListNoChange', value.toppingList); - this.toppingSetChange.emit([]); - } - }); - } +// // console.log('newToppingList', newToppingSetList); +// this.toppingSetChange.emit(newToppingSetList as unknown[]); +// } else { +// // console.log('newToppingListNoChange', value.toppingList); +// this.toppingSetChange.emit([]); +// } +// }); +// } - // match group id to its name - getGroupName(groupID: string) { - // check if array - if (Array.isArray(this.allToppings!.ToppingGroup)) { - return (this.allToppings!.ToppingGroup as ToppingGroup[]).find( - (group) => group.groupID == groupID - )?.name; - } else { - return undefined; - } - } +// // match group id to its name +// getGroupName(groupID: string) { +// // check if array +// if (Array.isArray(this.allToppings!.ToppingGroup)) { +// return (this.allToppings!.ToppingGroup as ToppingGroup[]).find( +// (group) => group.groupID == groupID +// )?.name; +// } else { +// return undefined; +// } +// } - openToppingList(i: any) { - console.log('select', i); - } +// openToppingList(i: any) { +// console.log('select', i); +// } - currentGroupId(i: any) { - console.log('currentGroupId', i); - return (this.toppingForm.value.toppingList![i] as any).groupID as string; - } +// currentGroupId(i: any) { +// console.log('currentGroupId', i); +// return (this.toppingForm.value.toppingList![i] as any).groupID as string; +// } - getMembersByGroupId(groupID: string) { - return this.allToppingMembersByGroup.find((x) => x.id == groupID)?.members; - } +// getMembersByGroupId(groupID: string) { +// return this.allToppingMembersByGroup.find((x) => x.id == groupID)?.members; +// } - getGroupIdByIndex(i: number) { - // console.log("getGroupId",this.toppingList.value![i]) - return (this.toppingList.value![i] as any).groupID as string; - } +// getGroupIdByIndex(i: number) { +// // console.log("getGroupId",this.toppingList.value![i]) +// return (this.toppingList.value![i] as any).groupID as string; +// } - mapToppingListToMember = (mm: string[]) => - mm.map((m) => { - // find actual topping from toppingList - let actualTopping = this.allToppings!.ToppingList.find((t) => t.id == m); +// mapToppingListToMember = (mm: string[]) => +// mm.map((m) => { +// // find actual topping from toppingList +// let actualTopping = this.allToppings!.ToppingList.find((t) => t.id == m); - return { - id: actualTopping!.id, - name: actualTopping?.name == null ? m : actualTopping!.name, - }; - }); +// return { +// id: actualTopping!.id, +// name: actualTopping?.name == null ? m : actualTopping!.name, +// }; +// }); - getDefaultOfGroup(groupID: any) { - this.toppingList.controls.forEach((control) => { - if ((control.value as any).groupID == groupID) { - let newDefault = this.allToppingsDefinitions!.find( - (x) => x.groupId == groupID - )!.default; - // set new defaultid - control.get('defaultIDSelect')?.setValue(newDefault); - } - }); - } +// getDefaultOfGroup(groupID: any) { +// this.toppingList.controls.forEach((control) => { +// if ((control.value as any).groupID == groupID) { +// let newDefault = this.allToppingsDefinitions!.find( +// (x) => x.groupId == groupID +// )!.default; +// // set new defaultid +// control.get('defaultIDSelect')?.setValue(newDefault); +// } +// }); +// } - compareFunc = (a: any, b: any) => a.toString() === b.toString(); -} +// compareFunc = (a: any, b: any) => a.toString() === b.toString(); +// } diff --git a/client/src/app/features/recipes/recipes.component.ts b/client/src/app/features/recipes/recipes.component.ts index 9c70660..d079bf9 100644 --- a/client/src/app/features/recipes/recipes.component.ts +++ b/client/src/app/features/recipes/recipes.component.ts @@ -241,8 +241,8 @@ export class RecipesComponent implements OnInit, OnDestroy, AfterViewInit { this.materialList = materials; }); - this._toppingService - .getToppings(this.department, this._recipeService.getCurrentFile()) + (await this._toppingService + .getToppings(this.department, this._recipeService.getCurrentFile())) .subscribe((tp) => { this.toppings = { toppingGroup: tp.ToppingGroup, diff --git a/server/data/data.go b/server/data/data.go index 4b1b505..a74285e 100644 --- a/server/data/data.go +++ b/server/data/data.go @@ -184,6 +184,8 @@ func NewData(taoLogger *logger.TaoLogger) *Data { func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { + d.taoLogger.Log.Debug("invoke GetRecipe", zap.String("countryID", countryID), zap.String("filename", filename)) + if countryID == "" { return d.currentRecipe["tha"] } @@ -194,7 +196,7 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { if recipe, ok := d.recipeMap[filename]; ok { d.CurrentFile[countryID] = filename - d.CurrentCountryID[countryID] = countryID + // d.CurrentCountryID[countryID] = countryID return recipe.Recipe[countryID] } @@ -204,13 +206,13 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { filename = d.CurrentFile[countryID] } - d.CurrentFile[countryID] = filename + // d.CurrentFile[countryID] = filename d.taoLogger.Log.Debug("GetRecipe", zap.String("filename", filename), zap.String("countryID", countryID)) - d.CurrentCountryID[countryID] = countryID + // d.CurrentCountryID[countryID] = 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)) + d.taoLogger.Log.Error("GetRecipe: Error when read recipe file, Return default recipe", zap.Error(err)) return d.currentRecipe[countryID] } @@ -248,21 +250,41 @@ func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) (models.Recipe01, error) { + // try convert + if len(countryID) != 3 { + for k, v := range d.CurrentCountryID { + fmt.Println("GetRecipe01ByProductCode.Iterate", k, v, v == countryID) + if v == countryID { + countryID = k + break + } + } + } + fmt.Println("GetRecipe01ByProductCode", filename, countryID, productCode) + if !strings.Contains(filename, "tmp") { if filename == "" || filename == d.CurrentFile[countryID] { - fmt.Println("GetRecipe01ByProductCode.ReadCurrent", filename, d.CurrentFile) + // , d.CurrentFile, countryID, "result by country id", len(d.currentRecipe[countryID].Recipe01) + fmt.Println("GetRecipe01ByProductCode.ReadCurrent::filename", filename) + fmt.Println("GetRecipe01ByProductCode.ReadCurrent::countryID", countryID) + 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 } } + fmt.Println("No result in current recipe", countryID) } else if recipe, ok := d.recipeMap[filename]; ok { - fmt.Println("GetRecipe01ByProductCode.ReadMap", filename, d.CurrentFile) + 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 } } + d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getFail", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap)) } } @@ -272,12 +294,12 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) filename = d.CurrentFile[countryID] } - d.CurrentFile[countryID] = filename - d.CurrentCountryID[countryID] = countryID + // d.CurrentFile[countryID] = filename + // d.CurrentCountryID[countryID] = countryID for _, v := range countries { if v.CountryName == countryID { - d.CurrentCountryID[countryID] = v.CountryID + // d.CurrentCountryID[countryID] = v.CountryID countryID = v.CountryID break } @@ -286,7 +308,7 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { - d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) + d.taoLogger.Log.Error("GetRecipe01ByProductCode: Error when read recipe file, Return default recipe", zap.Error(err)) for _, v := range d.currentRecipe[countryID].Recipe01 { if v.ProductCode == productCode { return v, nil @@ -373,15 +395,15 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS if !strings.Contains(filename, "tmp") { if filename == "" || filename == d.CurrentFile[countryID] { - copy(result, d.currentRecipe[countryID].MaterialSetting) - d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("result", result)) + // copy(result, d.currentRecipe[countryID].MaterialSetting) + // d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("result", result)) return d.currentRecipe[countryID].MaterialSetting } if recipe, ok := d.recipeMap[filename]; ok { copy(result, recipe.Recipe[countryID].MaterialSetting) d.CurrentFile[countryID] = filename - d.CurrentCountryID[countryID] = countryID + // d.CurrentCountryID[countryID] = countryID return d.currentRecipe[countryID].MaterialSetting } } @@ -390,19 +412,19 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS filename = d.CurrentFile[countryID] } - d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("filename", filename), zap.Any("countryID", countryID)) + // d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("filename", filename), zap.Any("countryID", countryID)) - d.CurrentFile[countryID] = filename - d.CurrentCountryID[countryID] = countryID + // d.CurrentFile[countryID] = filename + // d.CurrentCountryID[countryID] = 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)) + d.taoLogger.Log.Error("GetMaterialSetting: Error when read recipe file, Return default recipe", zap.Error(err)) copy(result, d.currentRecipe[countryID].MaterialSetting) return d.currentRecipe[countryID].MaterialSetting } - d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("recipe", recipe.MaterialSetting)) + // d.taoLogger.Log.Debug("GetMaterialSetting", zap.Any("recipe", recipe.MaterialSetting)) d.currentRecipe[countryID] = recipe @@ -443,12 +465,12 @@ func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []model filename = d.CurrentFile[countryID] } - d.CurrentFile[countryID] = filename - d.CurrentCountryID[countryID] = countryID + // d.CurrentFile[countryID] = filename + // d.CurrentCountryID[countryID] = 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)) + d.taoLogger.Log.Error("GetMaterialCode: Error when read recipe file, Return default recipe", zap.Error(err)) return d.currentRecipe[countryID].MaterialCode } @@ -510,12 +532,12 @@ func (d *Data) GetToppings(countryID, filename string) models.Topping { filename = d.CurrentFile[countryID] } - d.CurrentFile[countryID] = filename - d.CurrentCountryID[countryID] = countryID + // d.CurrentFile[countryID] = filename + // d.CurrentCountryID[countryID] = 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)) + d.taoLogger.Log.Error("GetToppings: Error when read recipe file, Return default recipe", zap.Error(err)) return d.currentRecipe[countryID].Topping } @@ -533,7 +555,7 @@ func (d *Data) GetToppingsOfRecipe(countryID, filename string, productCode strin recipe, err := d.GetRecipe01ByProductCode(filename, countryID, productCode) if err != nil { - d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) + d.taoLogger.Log.Error("GetToppingOfRecipe: Error when read recipe file, Return default recipe", zap.Error(err)) return []models.ToppingSet{}, err } @@ -549,7 +571,7 @@ func (d *Data) GetSubmenusOfRecipe(countryID, filename, productCode string) ([]m recipe, err := d.GetRecipe01ByProductCode(filename, countryID, productCode) if err != nil { - d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) + d.taoLogger.Log.Error("GetSubmenusOfRecipe: Error when read recipe file, Return default recipe", zap.Error(err)) return []models.Recipe01{}, err } diff --git a/server/routers/material.go b/server/routers/material.go index ff19f29..c5ce714 100644 --- a/server/routers/material.go +++ b/server/routers/material.go @@ -131,7 +131,7 @@ func (mr *MaterialRouter) getMaterialSettingByMatID(w http.ResponseWriter, r *ht countryID, err := mr.data.GetCountryIDByName(country) if err != nil { - mr.taoLogger.Log.Error("MaterialRouter.GetMaterialSettingByMatID", zap.Error(err)) + // mr.taoLogger.Log.Error("MaterialRouter.GetMaterialSettingByMatID", zap.Error(err)) http.Error(w, "Country not found", http.StatusNotFound) return } @@ -142,7 +142,7 @@ func (mr *MaterialRouter) getMaterialSettingByMatID(w http.ResponseWriter, r *ht matIDuint, err := strconv.ParseUint(matID, 10, 64) if err != nil { - mr.taoLogger.Log.Error("MaterialRouter.GetMaterialSettingByMatID", zap.Error(err)) + // mr.taoLogger.Log.Error("MaterialRouter.GetMaterialSettingByMatID", zap.Error(err)) http.Error(w, "Invalid material id", http.StatusBadRequest) return } @@ -157,7 +157,7 @@ func (mr *MaterialRouter) getMaterialSettingByMatID(w http.ResponseWriter, r *ht } if err := json.NewEncoder(w).Encode(matSetting); err != nil { - mr.taoLogger.Log.Error("MaterialRouter.GetMaterialSettingByMatID", zap.Error(err)) + // mr.taoLogger.Log.Error("MaterialRouter.GetMaterialSettingByMatID", zap.Error(err)) http.Error(w, "Internal Error", http.StatusInternalServerError) return } diff --git a/server/services/recipe/recipe.go b/server/services/recipe/recipe.go index 6fa84de..675d6ca 100644 --- a/server/services/recipe/recipe.go +++ b/server/services/recipe/recipe.go @@ -67,7 +67,7 @@ func (rs *recipeService) GetRecipeDetailMat(request *contracts.RecipeDetailReque return contracts.RecipeDetailMatListResponse{}, fmt.Errorf("country name: %s not found", request.Country) } - // rs.taoLogger.Log.Debug("GetRecipeDetailMat", zap.Any("request", request)) + rs.taoLogger.Log.Debug("GetRecipeDetailMat", zap.Any("request", request)) recipe, err := rs.db.GetRecipe01ByProductCode(request.Filename, request.Country, request.ProductCode) From 6b37c73aea3382e3a1bea6fc1b1b383cf04516c1 Mon Sep 17 00:00:00 2001 From: "pakintada@gmail.com" Date: Fri, 19 Jan 2024 15:01:43 +0700 Subject: [PATCH 4/5] increase timeout --- .../recipes/recipe-details/recipe-list/recipe-list.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts index 25273d5..02aafda 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts @@ -505,7 +505,7 @@ export class RecipeListComponent implements OnInit { if(this.timeoutHandler){ console.log("timeout get", this.timeout); - if(this.timeout >= 5){ + if(this.timeout >= 20){ this.showDetailRecipeList = true; } From ddfbeb4ac668aaef640d038474894d7bca482246 Mon Sep 17 00:00:00 2001 From: "pakintada@gmail.com" Date: Fri, 19 Jan 2024 17:13:04 +0700 Subject: [PATCH 5/5] add topping edit to recipelist `WIP` --- .../recipe-details.component.ts | 5 +- .../recipe-list/recipe-list.component.html | 14 +- .../recipe-list/recipe-list.component.ts | 26 +++- .../recipe-topping.component.html | 59 +++++--- .../recipe-topping.component.ts | 141 +++++++++++++----- client/src/app/shared/helpers/recipe.ts | 8 + 6 files changed, 180 insertions(+), 73 deletions(-) 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 f08f879..8f3e030 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 @@ -225,8 +225,9 @@ export class RecipeDetailsComponent implements OnInit { } onRecipeListFormChange(repl: unknown[]) { - // console.log('Recipe List Form Changed', repl); - this.repl = repl as never[]; + console.log('Recipe List Form Changed', repl); + this.repl = repl[1] as never[]; + this.tpl = repl[0] as never[]; this.isValueChanged ||= repl != undefined; } diff --git a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html index 373da4e..660051a 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html +++ b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.html @@ -40,10 +40,10 @@ " >

Volume

- +

gram

@@ -53,14 +53,14 @@ *ngIf="displayByCond(i, 'powderGram', 'zero', { compare: undefined })" >

Volume

- +

gram

@@ -141,7 +141,11 @@
Topping Settings
- +
diff --git a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts index 02aafda..821fadf 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-list/recipe-list.component.ts @@ -29,7 +29,8 @@ import { StringParam, stringParamsDefinition, conditionTests, - inRange + inRange, + convertFromInterProductCode } from 'src/app/shared/helpers/recipe'; import { RecipeToppingComponent } from '../recipe-topping/recipe-topping.component'; @@ -80,6 +81,9 @@ export class RecipeListComponent implements OnInit { // detailed recipe list showDetailRecipeList: boolean = false; + // topping list + public toppingList: any[] = []; + constructor( private _recipeService: RecipeService, private _materialService: MaterialService, @@ -280,7 +284,9 @@ export class RecipeListComponent implements OnInit { emitted_res.push(recipeDetailMat); }); - this.recipeListFormChange.emit(emitted_res as unknown[]); + // do another emit + + this.recipeListFormChange.emit([this.toppingList, emitted_res] as unknown[]); } else { this.recipeListFormChange.emit([]); } @@ -392,9 +398,9 @@ export class RecipeListComponent implements OnInit { let interCode = Math.floor(mat.materialId / 10000) * 10000; let originalCode = mat.materialId - (interCode); - console.log("from",mat.materialId,"interCode", interCode, "originalCode", originalCode); + // console.log("from",mat.materialId,"interCode", interCode, "originalCode", originalCode); category = getMaterialType(originalCode); - console.log("get original category of inter", category); + // console.log("get original category of inter", category); } if (Array.isArray(catMap[category])) { @@ -415,7 +421,11 @@ export class RecipeListComponent implements OnInit { isNotExistbyCatagories = (materialId: number) => getMaterialType(materialId) == 'others'; - isTopping = (materialId: number) => { return inRange(8111, 8130, materialId); }; + isTopping = (materialId: number) => { + return inRange(8111, 8130, convertFromInterProductCode(materialId)); + }; + + getToppingSlotNumber = (mat: number) => convertFromInterProductCode(mat) - 8110; isStringParamExist = (i: number) => { let rawStringParam = this.recipeListData.at(i).get('StringParam')?.value; @@ -549,4 +559,10 @@ export class RecipeListComponent implements OnInit { return ''; }; + + onToppingSetChange = (event: any, index: number) => { + // console.log('onToppingSetChange at index', index, "get event", event); + this.toppingList[event[0]] = event[1]; + // console.log('onToppingSetChange', this.toppingList); + } } diff --git a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html index 6db76f8..8da2488 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html +++ b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.html @@ -1,27 +1,38 @@ -
- - - - +
+
+ + + + -
{{ item.name }} ({{ item.groupId }})
+ +
{{ item.name }} ({{ item.groupId }})
+
+
+ + + +
{{ item.name }} ({{ item.id }})
-
- - - - + +
+
+
diff --git a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts index 2d0a79a..7fd4e4a 100644 --- a/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts +++ b/client/src/app/features/recipes/recipe-details/recipe-topping/recipe-topping.component.ts @@ -1,10 +1,19 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { CommonModule } from '@angular/common'; import { NgSelectModule } from '@ng-select/ng-select'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { + FormArray, + FormBuilder, + FormsModule, + ReactiveFormsModule, +} from '@angular/forms'; import { RecipeService } from 'src/app/core/services/recipe.service'; import { ToppingService } from 'src/app/core/services/topping.service'; -import { Topping, ToppingGroup, ToppingSet } from 'src/app/core/models/recipe.model'; +import { + Topping, + ToppingGroup, + ToppingSet, +} from 'src/app/core/models/recipe.model'; import { ActivatedRoute } from '@angular/router'; @Component({ @@ -14,8 +23,8 @@ import { ActivatedRoute } from '@angular/router'; templateUrl: './recipe-topping.component.html', }) export class RecipeToppingComponent implements OnInit { - @Input() index: number = 0; - @Input() toppingSet!: ToppingSet; + @Input() productCode: string = ''; + @Input() index: number | undefined = undefined; @Output() toppingSetChange = new EventEmitter(); allToppings: Topping | undefined = undefined; @@ -30,41 +39,90 @@ export class RecipeToppingComponent implements OnInit { }[] = []; department = this._route.snapshot.paramMap.get('department'); + private _toppingSetOriginalArray!: ToppingSet[]; + + // form + toppingForm = this._formBuilder.group( + { + toppingList: this._formBuilder.array([]), + }, + { + updateOn: 'blur', + } + ); + + get toppingList(): FormArray { + return this.toppingForm.get('toppingList') as FormArray; + } + constructor( + private _formBuilder: FormBuilder, private _recipeService: RecipeService, private _toppingService: ToppingService, private _route: ActivatedRoute ) {} async ngOnInit(): Promise { - (await this._toppingService - .getToppings( + // get topping of this recipe + + // initialize toppinglist form + + ( + await this._toppingService.getToppingsOfRecipe( + await this._recipeService.getCurrentCountry(), + this._recipeService.getCurrentFile(), + this.productCode + ) + ).subscribe((data) => { + this._toppingSetOriginalArray = data; + // console.log('ToppingSet', data); + + // check length of toppingList if in range with given index + if(this.index && data.length >= this.index!){ + this.toppingList.push( + this._formBuilder.group({ + isUse: data[this.index!].isUse, + groupID: data[this.index!].groupID, + defaultIDSelect: data[this.index!].defaultIDSelect, + ListGroupID: data[this.index!].ListGroupID, + }) + ); + } + }); + + // get all topping + ( + await this._toppingService.getToppings( this.department!, this._recipeService.getCurrentFile() - )) - .subscribe((data) => { - this.allToppings = data; - // console.log('allToppings', data); + ) + ).subscribe((data) => { + this.allToppings = data; + // console.log('allToppings', data); - data.ToppingGroup.forEach((group: ToppingGroup) => { - if (this.allToppingsDefinitions != null) { - // this.allToppingsDefinitions = {}; - this.allToppingsDefinitions.push({ - groupId: group.groupID, - name: group.name, - members: group.idInGroup, - default: group.idDefault, - }); + data.ToppingGroup.forEach((group: ToppingGroup) => { + if (this.allToppingsDefinitions != null) { + // this.allToppingsDefinitions = {}; + this.allToppingsDefinitions.push({ + groupId: group.groupID, + name: group.name, + members: group.idInGroup, + default: group.idDefault, + }); - this.allToppingMembersByGroup.push({ - id: group.groupID, - members: this.mapToppingListToMember(group.idInGroup.split(',')), - }); - } - }); - - // console.log(this.allToppingsDefinitions); - // console.log('allToppingMembersByGroup', this.allToppingMembersByGroup); + this.allToppingMembersByGroup.push({ + id: group.groupID, + members: this.mapToppingListToMember(group.idInGroup.split(',')), + }); + } }); + }); + + + // emit value changes + this.toppingForm.valueChanges.subscribe((value) => { + console.log('emit value', value); + this.toppingSetChange.emit([this.index, this.toppingList.value]); + }); } compareFunc = (a: any, b: any) => a.toString() === b.toString(); @@ -80,15 +138,24 @@ export class RecipeToppingComponent implements OnInit { }; }); - getMembersByGroupId(groupID: string) { - return this.allToppingMembersByGroup.find((x) => x.id == groupID)?.members; - } + getMembersByGroupId(groupID: string) { + return this.allToppingMembersByGroup.find((x) => x.id == groupID)?.members; + } - getGroupIdByIndex(i: number) { - // console.log("getGroupId",this.toppingList.value![i]) - // return (this.toppingList.value![i] as any).groupID as string; - } + getGroupIdByIndex(i: number) { + return (this.toppingList.value![0] as any).groupID as string; + } - // services + getDefaultOfGroup(groupID: any) { + this.toppingList.controls.forEach((control) => { + if ((control.value as any).groupID == groupID) { + + let newDefault = (this.allToppingsDefinitions as any).find( + (x: any) => x.groupId == groupID + )!.default; + + control.get('defaultIDSelect')?.setValue(newDefault); + } + }) + } } - diff --git a/client/src/app/shared/helpers/recipe.ts b/client/src/app/shared/helpers/recipe.ts index 4ab1bad..baa004b 100644 --- a/client/src/app/shared/helpers/recipe.ts +++ b/client/src/app/shared/helpers/recipe.ts @@ -48,6 +48,14 @@ export function isNonMaterial(materialId: number) { ); } +// Inter mode checker +export function convertFromInterProductCode(materialId: number) { + let interPrefix = Math.floor(materialId / 10000) * 10000; + let interId = materialId - interPrefix; + + return interId; +} + // StringParam export class StringParam {