From 98341d2d80bbc2e27a81f27854b2561eaf11b084 Mon Sep 17 00:00:00 2001 From: "pakintada@gmail.com" Date: Tue, 9 Jan 2024 17:11:15 +0700 Subject: [PATCH] change display, add `StringParam` (WIP) --- .gitignore | 1 + client/src/app/core/models/recipe.model.ts | 4 +- .../recipe-details.component.html | 38 ++-- .../recipe-details.component.ts | 20 +- .../recipe-list/recipe-list.component.html | 128 ++++++++----- .../recipe-list/recipe-list.component.ts | 177 +++++++++++++++--- .../recipe-toppingset.component.ts | 8 +- client/src/app/shared/helpers/mat_type.ts | 45 +++++ server/cofffeemachineConfig | 2 +- server/models/recipe.go | 52 ++--- server/routers/material.go | 2 +- 11 files changed, 352 insertions(+), 125 deletions(-) create mode 100644 client/src/app/shared/helpers/mat_type.ts mode change 120000 => 160000 server/cofffeemachineConfig diff --git a/.gitignore b/.gitignore index 1b38c48..068f6e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ server/services/logger/serverlog.log .idea/ .DS_Store +server/cofffeemachineConfig diff --git a/client/src/app/core/models/recipe.model.ts b/client/src/app/core/models/recipe.model.ts index 0d224cc..3be4b10 100644 --- a/client/src/app/core/models/recipe.model.ts +++ b/client/src/app/core/models/recipe.model.ts @@ -29,6 +29,7 @@ export type RecipeDetail = { }; export type RecipeDetailMat = { + StringParam: string; isUse: boolean; materialID: number; name: string; @@ -75,7 +76,6 @@ export interface Recipe01 { OnTOP: string; LastChange: Date; MenuStatus: string; - RemainingCups: string; StringParam: string; TextForWarningBeforePay: string[]; cashPrice: number; @@ -142,6 +142,7 @@ export interface ToppingList { } export interface MatRecipe { + StringParam: string; MixOrder: number; FeedParameter: number; FeedPattern: number; @@ -164,6 +165,7 @@ export interface ToppingSet { } export interface MaterialSetting { + StringParam: string, AlarmIDWhenOffline: string; BeanChannel: string; CanisterType: string; 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 b7c93e3..c485026 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 @@ -12,6 +12,18 @@
{{ recipeDetailForm.getRawValue().otherName }}
+ + +
+ +
@@ -296,20 +308,20 @@
- - - + + + -

{{ material.name }}

-

{{ material.type }}

+ +
+
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 c684b1c..bbdeac1 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 @@ -22,6 +22,7 @@ import { UserService } from 'src/app/core/services/user.service'; import { Action, ActionRecord } from 'src/app/shared/actionRecord/actionRecord'; import { FormsModule } from '@angular/forms'; import { NgSelectModule } from '@ng-select/ng-select'; +import { getMaterialType, getCategories, isNonMaterial } from 'src/app/shared/helpers/mat_type'; @Component({ selector: 'app-recipe-list', @@ -35,13 +36,17 @@ export class RecipeListComponent implements OnInit { materialList: MaterialCode[] = []; - fullMaterialList: { materialId: number; name: string; type: string; }[] | null = []; + fullMaterialList: + | { materialId: number; name: string; type: string }[] + | null = []; showMaterialSelector: boolean = false; currentSelectRecipeList: number | null = null; isMatLoaded: boolean = false; + categoriedMaterial: { [key: string]: { id: number; name: string }[] } = {}; + constructor( private _recipeService: RecipeService, private _materialService: MaterialService, @@ -67,17 +72,70 @@ export class RecipeListComponent implements OnInit { result.forEach((recipeDetailMat: RecipeDetailMat) => { this.recipeListData.push( this._formBuilder.group({ - isUse: [{ value: recipeDetailMat.isUse, disabled: !this.isEditable()}], - materialPathId: [{value:recipeDetailMat.materialPathId, disabled: !this.isEditable()}], + StringParam: [ + { + value: recipeDetailMat.StringParam, + disabled: !this.isEditable(), + } + ], + isUse: [ + { value: recipeDetailMat.isUse, disabled: !this.isEditable() }, + ], + materialPathId: [ + { + value: recipeDetailMat.materialPathId, + disabled: !this.isEditable(), + }, + ], name: [{ value: recipeDetailMat.name, disabled: true }], - mixOrder: [{ value:recipeDetailMat.mixOrder, disabled: !this.isEditable()}], - stirTime: [{value:recipeDetailMat.stirTime, disabled: !this.isEditable()}], - powderGram: [{value:recipeDetailMat.powderGram, disabled: !this.isEditable()}], - powderTime: [{value:recipeDetailMat.powderTime, disabled: !this.isEditable()}], - syrupGram: [{value:recipeDetailMat.syrupGram, disabled: !this.isEditable()}], - syrupTime: [{value: recipeDetailMat.syrupTime, disabled: !this.isEditable()}], - waterCold: [{value:recipeDetailMat.waterCold, disabled: !this.isEditable()}], - waterYield: [{value:recipeDetailMat.waterYield, disabled: !this.isEditable()}], + mixOrder: [ + { + value: recipeDetailMat.mixOrder, + disabled: !this.isEditable(), + }, + ], + stirTime: [ + { + value: recipeDetailMat.stirTime, + disabled: !this.isEditable(), + }, + ], + powderGram: [ + { + value: recipeDetailMat.powderGram, + disabled: !this.isEditable(), + }, + ], + powderTime: [ + { + value: recipeDetailMat.powderTime, + disabled: !this.isEditable(), + }, + ], + syrupGram: [ + { + value: recipeDetailMat.syrupGram, + disabled: !this.isEditable(), + }, + ], + syrupTime: [ + { + value: recipeDetailMat.syrupTime, + disabled: !this.isEditable(), + }, + ], + waterCold: [ + { + value: recipeDetailMat.waterCold, + disabled: !this.isEditable(), + }, + ], + waterYield: [ + { + value: recipeDetailMat.waterYield, + disabled: !this.isEditable(), + }, + ], }) ); }); @@ -86,29 +144,27 @@ export class RecipeListComponent implements OnInit { this.recipeListForm.valueChanges.subscribe((value) => { // console.log(value.recipeListData); - // console.log(this._recipeListOriginalArray); + // console.log("original recipe detail",this._recipeListOriginalArray); if ( !isEqual( sortBy(value, 'materialID'), sortBy(this._recipeListOriginalArray, 'materialID') ) ) { - - let emitted_res: any[] = [] + let emitted_res: any[] = []; // force type change. temporary solution forEach(value.recipeListData!, (recipeDetailMat: any) => { - recipeDetailMat.materialPathId = parseInt(recipeDetailMat.materialPathId!) - emitted_res.push(recipeDetailMat) - }) + recipeDetailMat.materialPathId = parseInt( + recipeDetailMat.materialPathId! + ); + emitted_res.push(recipeDetailMat); + }); this.recipeListFormChange.emit(emitted_res as unknown[]); } else { this.recipeListFormChange.emit([]); } - - - }); // TODO: make this @@ -118,28 +174,95 @@ export class RecipeListComponent implements OnInit { this._materialService.getFullMaterialDetail().subscribe((materials) => { this.fullMaterialList = materials; - }) + this.categoriedMaterial = this.ListCategory(); + console.log(this.categoriedMaterial); + }); } get recipeListData(): FormArray { return this.recipeListForm.get('recipeListData') as FormArray; } - isEditable(){ - return this._userService.getCurrentUser()!.permissions.includes(UserPermissions.EDITOR); + isEditable() { + return this._userService + .getCurrentUser()! + .permissions.includes(UserPermissions.EDITOR); } - openMaterialList(i: any){ - console.log("open material list for ", i); + openMaterialList(i: any) { + console.log('open material list for ', i); this.showMaterialSelector = true; this.currentSelectRecipeList = i; } - selectMaterial(i: number, material: number){ + selectMaterial(i: number, material: number) { + // 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); + console.log('set mat ', material, 'to slot', i); } + + getTypeForRecipeListAtIndex(i: any){ + let target = this.recipeListData.at(i); + + + // search from full detail + for(const category of Object.keys(this.categoriedMaterial)){ + let finder = this.categoriedMaterial[category].find(mat => mat.id == target.value.materialPathId); + + if (finder != undefined) { + // console.log('found ', finder.name, ' in ', category); + return { + "category": category, + "name": finder.name, + "id": finder.id + }; + } + } + + // console.log("did not find in full detail"); + + return { + "category": "others", + "name": target.value.name, + "id": target.value.materialPathId + }; + } + + // TODO: Filter from full detail by type + ListCategory = () => { + let catMap: { [key: string]: any[] } = { + 'others': [] + }; + + // create category map + getCategories().forEach((category) => { + catMap[category] = []; + }); + + console.log("generated category", catMap); + + this.fullMaterialList!.forEach((mat) => { + let category = getMaterialType(mat.materialId); + + if(Array.isArray(catMap[category])){ + catMap[category].push({ + id: mat.materialId, + name: mat.name, + }); + } + + }); + + + return catMap; + }; + + getCategoriesList = () => Object.keys(this.categoriedMaterial); + + // exposed from mat_type.ts + isEquipment = (materialId: number) => isNonMaterial(materialId); + isNotExistbyCatagories = (materialId : number) => getMaterialType(materialId) == 'others'; } 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 e5e524f..2590fff 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 @@ -99,7 +99,7 @@ export class RecipeToppingsetComponent implements OnInit { ) .subscribe((data) => { this.allToppings = data; - console.log('allToppings', data); + // console.log('allToppings', data); data.ToppingGroup.forEach((group: ToppingGroup) => { if (this.allToppingsDefinitions != null) { @@ -118,8 +118,8 @@ export class RecipeToppingsetComponent implements OnInit { } }); - console.log(this.allToppingsDefinitions); - console.log('allToppingMembersByGroup', this.allToppingMembersByGroup); + // console.log(this.allToppingsDefinitions); + // console.log('allToppingMembersByGroup', this.allToppingMembersByGroup); }); this.toppingForm.valueChanges.subscribe((value) => { @@ -157,7 +157,7 @@ export class RecipeToppingsetComponent implements OnInit { // console.log('newToppingList', newToppingSetList); this.toppingSetChange.emit(newToppingSetList as unknown[]); } else { - console.log('newToppingListNoChange', value.toppingList); + // console.log('newToppingListNoChange', value.toppingList); this.toppingSetChange.emit([]); } }); diff --git a/client/src/app/shared/helpers/mat_type.ts b/client/src/app/shared/helpers/mat_type.ts new file mode 100644 index 0000000..32056aa --- /dev/null +++ b/client/src/app/shared/helpers/mat_type.ts @@ -0,0 +1,45 @@ +var rangeMaterialMapping: { [key: string]: (id: number) => boolean } = { + soda: (id: number) => id == 1031, + water: (id: number) => id == 1, + ice: (id: number) => id == 9100, + whipper: (id: number) => id == 8102, + bean: (id: number) => inRange(1001, 1009, id) || inRange(1100, 1199, id), + leaves: (id: number) => inRange(1600, 1799, id), + syrup: (id: number) => + inRange(1032, 1039, id) || + inRange(1020, 1030, id) || + inRange(1200, 1299, id), + powder: (id: number) => inRange(1040, 1080, id) || inRange(1300, 1399, id), + cup: (id: number) => inRange(9500, 9549, id), + lid: (id: number) => inRange(9600, 9649, id), + straw: (id: number) => inRange(9700, 9749, id), + icecream: (id: number) => inRange(2100, 2200, id), +}; + +export function inRange(min: number, max: number, value: number) { + // console.log(min, max, value, value >= min && value <= max); + return value >= min && value <= max; +} + +export function getCategories() { + return Object.keys(rangeMaterialMapping); +} + +export function getMaterialType(materialId: number) { + for (const key of Object.keys(rangeMaterialMapping)) { + if (rangeMaterialMapping[key](materialId)) { + return key; + } + } + + return 'others'; +} + +export function isNonMaterial(materialId: number) { + // test cup, lid, straw + return ( + rangeMaterialMapping['cup'](materialId) || + rangeMaterialMapping['lid'](materialId) || + rangeMaterialMapping['straw'](materialId) || rangeMaterialMapping['whipper'](materialId) + ); +} diff --git a/server/cofffeemachineConfig b/server/cofffeemachineConfig deleted file mode 120000 index 70f6177..0000000 --- a/server/cofffeemachineConfig +++ /dev/null @@ -1 +0,0 @@ -/Users/wanloprungsiyangkul/project/cofffeemachineConfig \ No newline at end of file diff --git a/server/cofffeemachineConfig b/server/cofffeemachineConfig new file mode 160000 index 0000000..6e0d512 --- /dev/null +++ b/server/cofffeemachineConfig @@ -0,0 +1 @@ +Subproject commit 6e0d512afc4667a2204ff773ad8a3851120cdadd diff --git a/server/models/recipe.go b/server/models/recipe.go index 0a472bf..820855c 100644 --- a/server/models/recipe.go +++ b/server/models/recipe.go @@ -28,31 +28,33 @@ type MaterialCode struct { } type MaterialSetting struct { - AlarmIDWhenOffline int `json:"AlarmIDWhenOffline"` - BeanChannel bool `json:"BeanChannel"` - CanisterType string `json:"CanisterType"` - DrainTimer int `json:"DrainTimer"` - IsEquipment bool `json:"IsEquipment"` - LeavesChannel bool `json:"LeavesChannel"` - LowToOffline int `json:"LowToOffline"` - MaterialStatus int `json:"MaterialStatus"` - PowderChannel bool `json:"PowderChannel"` - RefillUnitGram bool `json:"RefillUnitGram"` - RefillUnitMilliliters bool `json:"RefillUnitMilliliters"` - RefillUnitPCS bool `json:"RefillUnitPCS"` - ScheduleDrainType int `json:"ScheduleDrainType"` - SodaChannel bool `json:"SodaChannel"` - StockAdjust int `json:"StockAdjust"` - SyrupChannel bool `json:"SyrupChannel"` - ID uint64 `json:"id"` - IDAlternate int `json:"idAlternate"` - IsUse bool `json:"isUse"` - PayRettryMaxCount int `json:"pay_rettry_max_count"` - FeedMode string `json:"feed_mode"` - MaterialParameter string `json:"MaterialParameter"` - MaterialName string `json:"materialName"` - MaterialOtherName string `json:"materialOtherName"` - RawMaterialUnit string `json:"RawMaterialUnit"` + StringParam string `json:"StringParam"` + AlarmIDWhenOffline int `json:"AlarmIDWhenOffline"` + BeanChannel bool `json:"BeanChannel"` + CanisterType string `json:"CanisterType"` + DrainTimer int `json:"DrainTimer"` + IceScreamBingsuChannel bool `json:"IceScreamBingsuChannel"` + IsEquipment bool `json:"IsEquipment"` + LeavesChannel bool `json:"LeavesChannel"` + LowToOffline int `json:"LowToOffline"` + MaterialStatus int `json:"MaterialStatus"` + PowderChannel bool `json:"PowderChannel"` + RefillUnitGram bool `json:"RefillUnitGram"` + RefillUnitMilliliters bool `json:"RefillUnitMilliliters"` + RefillUnitPCS bool `json:"RefillUnitPCS"` + ScheduleDrainType int `json:"ScheduleDrainType"` + SodaChannel bool `json:"SodaChannel"` + StockAdjust int `json:"StockAdjust"` + SyrupChannel bool `json:"SyrupChannel"` + ID uint64 `json:"id"` + IDAlternate int `json:"idAlternate"` + IsUse bool `json:"isUse"` + PayRettryMaxCount int `json:"pay_rettry_max_count"` + FeedMode string `json:"feed_mode"` + MaterialParameter string `json:"MaterialParameter"` + MaterialName string `json:"materialName"` + MaterialOtherName string `json:"materialOtherName"` + RawMaterialUnit string `json:"RawMaterialUnit"` } type Recipe01 struct { diff --git a/server/routers/material.go b/server/routers/material.go index 9af8f38..bd4ba48 100644 --- a/server/routers/material.go +++ b/server/routers/material.go @@ -71,7 +71,7 @@ func (mr *MaterialRouter) GetFullMaterialDetail(w http.ResponseWriter, r *http.R materialDetails = append(materialDetails, map[string]interface{}{ "materialId": matSetting.ID, "name": mat_name, - "type": "powder:" + strconv.FormatBool(matSetting.PowderChannel) + ",syrup:" + strconv.FormatBool(matSetting.SyrupChannel) + ",bean:" + strconv.FormatBool(matSetting.BeanChannel) + ",equipment:" + strconv.FormatBool(matSetting.IsEquipment), + "type": "powder:" + strconv.FormatBool(matSetting.PowderChannel) + ",syrup:" + strconv.FormatBool(matSetting.SyrupChannel) + ",bean:" + strconv.FormatBool(matSetting.BeanChannel) + ",equipment:" + strconv.FormatBool(matSetting.IsEquipment) + ",soda:" + strconv.FormatBool(matSetting.SodaChannel) + ",icecream:" + strconv.FormatBool(matSetting.IceScreamBingsuChannel), }) }