add topping WIP
This commit is contained in:
parent
cabfcdee15
commit
16e0e4f9d8
11 changed files with 460 additions and 26 deletions
|
|
@ -141,10 +141,17 @@ const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'materials',
|
path: 'materials',
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import('./features/material-settings/material-settings.component').then(
|
import(
|
||||||
(m) => m.MaterialSettingsComponent
|
'./features/material-settings/material-settings.component'
|
||||||
|
).then((m) => m.MaterialSettingsComponent),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'toppings',
|
||||||
|
loadComponent: () =>
|
||||||
|
import('./features/toppings/toppings.component').then(
|
||||||
|
(t) => t.ToppingsComponent
|
||||||
),
|
),
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -34,15 +34,15 @@ export class LayoutComponent implements OnInit, OnDestroy {
|
||||||
icon_url: 'assets/icons/recipes.svg',
|
icon_url: 'assets/icons/recipes.svg',
|
||||||
link: '/' + this.current_department + '/recipes',
|
link: '/' + this.current_department + '/recipes',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'Log',
|
|
||||||
icon_url: 'assets/icons/logs.svg',
|
|
||||||
link: '/' + this.current_department + '/log',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'Materials',
|
name: 'Materials',
|
||||||
icon_url: '',
|
icon_url: '',
|
||||||
link: '/' + this.current_department + '/materials',
|
link: '/' + this.current_department + '/materials',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Toppings',
|
||||||
|
icon_url: '',
|
||||||
|
link: '/' + this.current_department + '/toppings'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
date = new Date();
|
date = new Date();
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ export interface ToppingGroup {
|
||||||
groupID: string;
|
groupID: string;
|
||||||
idDefault: string;
|
idDefault: string;
|
||||||
idInGroup: string;
|
idInGroup: string;
|
||||||
inUse: string;
|
inUse: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
otherName: string;
|
otherName: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable, count } from 'rxjs';
|
import { Observable, count } from 'rxjs';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
import { Topping, ToppingSet } from '../models/recipe.model';
|
import { Topping, ToppingGroup, ToppingList, ToppingSet } from '../models/recipe.model';
|
||||||
import { RecipeService } from './recipe.service';
|
import { RecipeService } from './recipe.service';
|
||||||
import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe';
|
import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe';
|
||||||
|
|
||||||
|
|
@ -10,13 +10,19 @@ import { getCountryMapSwitcher } from 'src/app/shared/helpers/recipe';
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ToppingService {
|
export class ToppingService {
|
||||||
constructor(private _httpClient: HttpClient, private _recipeService: RecipeService) {}
|
constructor(
|
||||||
|
private _httpClient: HttpClient,
|
||||||
|
private _recipeService: RecipeService
|
||||||
|
) {}
|
||||||
|
|
||||||
async getToppings(country: string, filename: string): Promise<Observable<Topping>> {
|
async getToppings(
|
||||||
console.log("getToppings", country);
|
country: string,
|
||||||
|
filename: string
|
||||||
|
): Promise<Observable<Topping>> {
|
||||||
|
console.log('getToppings', country);
|
||||||
let asyncCountry = await this._recipeService.getCurrentCountry();
|
let asyncCountry = await this._recipeService.getCurrentCountry();
|
||||||
country = getCountryMapSwitcher(asyncCountry);
|
country = getCountryMapSwitcher(asyncCountry);
|
||||||
console.log("getToppingsPreFetch", country, asyncCountry);
|
console.log('getToppingsPreFetch', country, asyncCountry);
|
||||||
return this._httpClient.get<Topping>(
|
return this._httpClient.get<Topping>(
|
||||||
`${environment.api}/recipes/${country}/${filename}/toppings`,
|
`${environment.api}/recipes/${country}/${filename}/toppings`,
|
||||||
{
|
{
|
||||||
|
|
@ -24,16 +30,20 @@ export class ToppingService {
|
||||||
country: country,
|
country: country,
|
||||||
filename: filename,
|
filename: filename,
|
||||||
},
|
},
|
||||||
withCredentials: true
|
withCredentials: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getToppingsOfRecipe(country: string, filename: string, productCode: string): Promise<Observable<ToppingSet[]>> {
|
async getToppingsOfRecipe(
|
||||||
console.log("getToppingsOfRecipe", country);
|
country: string,
|
||||||
|
filename: string,
|
||||||
|
productCode: string
|
||||||
|
): Promise<Observable<ToppingSet[]>> {
|
||||||
|
console.log('getToppingsOfRecipe', country);
|
||||||
let asyncCountry = await this._recipeService.getCurrentCountry();
|
let asyncCountry = await this._recipeService.getCurrentCountry();
|
||||||
country = country || asyncCountry;
|
country = country || asyncCountry;
|
||||||
console.log("getToppingsOfRecipePreFetch", country, asyncCountry);
|
console.log('getToppingsOfRecipePreFetch', country, asyncCountry);
|
||||||
return this._httpClient.get<ToppingSet[]>(
|
return this._httpClient.get<ToppingSet[]>(
|
||||||
`${environment.api}/recipes/${country}/${filename}/${productCode}/toppings`,
|
`${environment.api}/recipes/${country}/${filename}/${productCode}/toppings`,
|
||||||
{
|
{
|
||||||
|
|
@ -41,8 +51,49 @@ export class ToppingService {
|
||||||
country: country,
|
country: country,
|
||||||
filename: filename,
|
filename: filename,
|
||||||
},
|
},
|
||||||
withCredentials: true
|
withCredentials: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getToppingGroups(
|
||||||
|
country: string,
|
||||||
|
filename: string
|
||||||
|
): Promise<Observable<ToppingGroup[]>> {
|
||||||
|
console.log('fetching topping group');
|
||||||
|
let asyncCountry = await this._recipeService.getCurrentCountry();
|
||||||
|
country = getCountryMapSwitcher(asyncCountry);
|
||||||
|
|
||||||
|
return this._httpClient.get<ToppingGroup[]>(
|
||||||
|
`${environment.api}/toppings/groups/${country}/${filename}`,
|
||||||
|
{
|
||||||
|
params:{
|
||||||
|
country: country,
|
||||||
|
filename: filename
|
||||||
|
},
|
||||||
|
withCredentials: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getToppingLists(
|
||||||
|
country: string,
|
||||||
|
filename: string
|
||||||
|
): Promise<Observable<ToppingList[]>> {
|
||||||
|
console.log('fetching topping list');
|
||||||
|
let asyncCountry = await this._recipeService.getCurrentCountry();
|
||||||
|
country = getCountryMapSwitcher(asyncCountry);
|
||||||
|
|
||||||
|
return this._httpClient.get<ToppingList[]>(
|
||||||
|
`${environment.api}/toppings/lists/${country}/${filename}`,
|
||||||
|
{
|
||||||
|
params:{
|
||||||
|
country: country,
|
||||||
|
filename: filename
|
||||||
|
},
|
||||||
|
withCredentials: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
<div class="modal-box max-w-5xl">
|
<div class="modal-box max-w-5xl">
|
||||||
<p>Material Settings</p>
|
<p>Material Settings</p>
|
||||||
|
|
||||||
<input type="checkbox" [value]="currentMaterialSettings.isUse == 'true' ? true : false">
|
<input type="checkbox" value="{{currentMaterialSettings.isUse == 'true' ? true : false}}">
|
||||||
|
|
||||||
|
|
||||||
<p>{{ currentMaterialSettings.materialName }}</p>
|
<p>{{ currentMaterialSettings.materialName }}</p>
|
||||||
|
|
|
||||||
39
client/src/app/features/toppings/toppings.component.html
Normal file
39
client/src/app/features/toppings/toppings.component.html
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
<main class="relative overflow-auto max-h-[80%] h-[88vh]">
|
||||||
|
<table class="table w-full" [formGroup]="toppingGroupForm">
|
||||||
|
<thead class="text-xs sticky top-0">
|
||||||
|
<tr class="bg-primary">
|
||||||
|
<th>Is Use</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Other Name</th>
|
||||||
|
<th>Desciption</th>
|
||||||
|
<!-- <th>Default</th> -->
|
||||||
|
<th>Default</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody formArrayName="toppingGroup" *ngFor="let tpg of toppingGroup.controls; let i = index">
|
||||||
|
<tr formGroupName="{{i}}">
|
||||||
|
<td><input class="toggle" type="checkbox" formControlName="inUse"></td>
|
||||||
|
<td><input class="input input-sm" formControlName="groupID"></td>
|
||||||
|
<td><input class="input input-sm" formControlName="name"></td>
|
||||||
|
<td><input class="input input-sm" formControlName="otherName"></td>
|
||||||
|
<td><input class="input input-sm" formControlName="Desc"></td>
|
||||||
|
<!-- <td>{{tpg.idDefault}}</td> -->
|
||||||
|
<td class=" rounded-md">
|
||||||
|
<div *ngFor="let m of getMemberByGroupId(getAttrFromForm(i, 'groupID'))">
|
||||||
|
<button
|
||||||
|
class="button border-solid border-2 border-black rounded-md p-2 hover:bg-yellow-300"
|
||||||
|
[ngClass]="{ 'button bg-red-200': m == getAttrFromForm(i, 'idDefault') }"
|
||||||
|
>
|
||||||
|
{{ returnThisOrElse(getMemberData(getAttrFromForm(i, 'groupID'), m).name, "") }} ({{
|
||||||
|
m
|
||||||
|
}})
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</main>
|
||||||
168
client/src/app/features/toppings/toppings.component.ts
Normal file
168
client/src/app/features/toppings/toppings.component.ts
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { ToppingService } from 'src/app/core/services/topping.service';
|
||||||
|
import { ToppingGroup, ToppingList } from 'src/app/core/models/recipe.model';
|
||||||
|
import { RecipeService } from 'src/app/core/services/recipe.service';
|
||||||
|
import {
|
||||||
|
FormArray,
|
||||||
|
FormBuilder,
|
||||||
|
FormGroup,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
} from '@angular/forms';
|
||||||
|
import { NgSelectModule } from '@ng-select/ng-select';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-toppings',
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, NgSelectModule,FormsModule, ReactiveFormsModule],
|
||||||
|
templateUrl: './toppings.component.html',
|
||||||
|
})
|
||||||
|
export class ToppingsComponent implements OnInit {
|
||||||
|
// topping group
|
||||||
|
toppingGroupList: ToppingGroup[] = [];
|
||||||
|
toppingLists: ToppingList[] = [];
|
||||||
|
|
||||||
|
groupMemebersMap: { [key: string]: { [key: string]: any } } = {
|
||||||
|
'0': { members: [] },
|
||||||
|
};
|
||||||
|
|
||||||
|
// forms
|
||||||
|
|
||||||
|
toppingGroupForm = this._formBuilder.group(
|
||||||
|
{
|
||||||
|
toppingGroup: this._formBuilder.array([]),
|
||||||
|
},
|
||||||
|
{ updateOn: 'blur' }
|
||||||
|
);
|
||||||
|
|
||||||
|
get toppingGroup(): FormArray {
|
||||||
|
return this.toppingGroupForm.get('toppingGroup') as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _httpClient: HttpClient,
|
||||||
|
private _recipeService: RecipeService,
|
||||||
|
private _toppingService: ToppingService,
|
||||||
|
private _formBuilder: FormBuilder
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async ngOnInit(): Promise<void> {
|
||||||
|
// initialize
|
||||||
|
(
|
||||||
|
await this._toppingService.getToppingGroups(
|
||||||
|
await this._recipeService.getCurrentCountry(),
|
||||||
|
this._recipeService.getCurrentFile()
|
||||||
|
)
|
||||||
|
).subscribe((data) => {
|
||||||
|
// sort by group id
|
||||||
|
data.sort((a, b) => parseInt(a.groupID) - parseInt(b.groupID));
|
||||||
|
|
||||||
|
this.toppingGroupList = data;
|
||||||
|
this.mapMembers();
|
||||||
|
console.log(
|
||||||
|
'topping groups: ',
|
||||||
|
this.toppingGroupList,
|
||||||
|
'mapper:',
|
||||||
|
this.groupMemebersMap,
|
||||||
|
'length',
|
||||||
|
this.toppingGroupList.length
|
||||||
|
);
|
||||||
|
|
||||||
|
// do push to form
|
||||||
|
data.forEach((tg) => {
|
||||||
|
this.toppingGroup.push(
|
||||||
|
this._formBuilder.group({
|
||||||
|
Desc: tg.Desc,
|
||||||
|
name: tg.name,
|
||||||
|
otherName: tg.otherName,
|
||||||
|
groupID: tg.groupID,
|
||||||
|
idInGroup: tg.idInGroup,
|
||||||
|
idDefault: tg.idDefault,
|
||||||
|
inUse: tg.inUse,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('create topping group form', this.toppingGroup);
|
||||||
|
});
|
||||||
|
|
||||||
|
(
|
||||||
|
await this._toppingService.getToppingLists(
|
||||||
|
await this._recipeService.getCurrentCountry(),
|
||||||
|
this._recipeService.getCurrentFile()
|
||||||
|
)
|
||||||
|
).subscribe((data) => {
|
||||||
|
this.toppingLists = data;
|
||||||
|
this.mapNameToMember();
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'get topping list',
|
||||||
|
this.toppingLists,
|
||||||
|
'mapper:',
|
||||||
|
this.groupMemebersMap
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('undefined name of topping list', this.findUndefinedName());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------- Functions -------------------------------------------
|
||||||
|
|
||||||
|
// mapping member to group
|
||||||
|
mapMembers = () => {
|
||||||
|
this.toppingGroupList.forEach((tpg) => {
|
||||||
|
let spl_mem = tpg.idInGroup.split(',');
|
||||||
|
this.groupMemebersMap[tpg.groupID] = { members: spl_mem };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// get members of group id
|
||||||
|
getMemberByGroupId = (id: string) =>
|
||||||
|
this.groupMemebersMap[id]['members'] as string[];
|
||||||
|
|
||||||
|
// match name to member
|
||||||
|
mapNameToMember = () => {
|
||||||
|
if (this.toppingLists.length > 0) {
|
||||||
|
this.toppingGroupList.forEach((tpg) => {
|
||||||
|
let members = this.groupMemebersMap[tpg.groupID]['members'];
|
||||||
|
members.forEach((member_id: string) => {
|
||||||
|
// do get member data from topping list
|
||||||
|
let member_data = this.toppingLists.find(
|
||||||
|
(v) => v.id.toString() == member_id.toString()
|
||||||
|
);
|
||||||
|
// set data to group
|
||||||
|
this.groupMemebersMap[tpg.groupID][member_id] = member_data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// get member data from group
|
||||||
|
getMemberData = (group: string, member_id: string) => {
|
||||||
|
if (this.groupMemebersMap[group][member_id] == undefined) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return this.groupMemebersMap[group][member_id];
|
||||||
|
};
|
||||||
|
|
||||||
|
// check which list does not have name
|
||||||
|
findUndefinedName = () =>
|
||||||
|
this.toppingLists.filter((tl) => tl.name == '' || tl.name == undefined);
|
||||||
|
|
||||||
|
// get with default value
|
||||||
|
returnThisOrElse = (value: any, default_value: any) =>
|
||||||
|
value == undefined || value == '' ? default_value : value;
|
||||||
|
|
||||||
|
// get value from form by given key
|
||||||
|
getAttrFromForm(index: number, key: string){
|
||||||
|
let x = this.toppingGroup.controls.at(index) as any;
|
||||||
|
return x.value[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// diff and find matched
|
||||||
|
comapareFunction = (a: any, b: any) => ( a != undefined && b != undefined)&& (a.toString() === b.toString());
|
||||||
|
}
|
||||||
|
|
@ -267,10 +267,10 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string)
|
||||||
if !strings.Contains(filename, "tmp") {
|
if !strings.Contains(filename, "tmp") {
|
||||||
if filename == "" || filename == d.CurrentFile[countryID] {
|
if filename == "" || filename == d.CurrentFile[countryID] {
|
||||||
// , d.CurrentFile, countryID, "result by country id", len(d.currentRecipe[countryID].Recipe01)
|
// , d.CurrentFile, countryID, "result by country id", len(d.currentRecipe[countryID].Recipe01)
|
||||||
fmt.Println("GetRecipe01ByProductCode.ReadCurrent::filename", filename)
|
// fmt.Println("GetRecipe01ByProductCode.ReadCurrent::filename", filename)
|
||||||
fmt.Println("GetRecipe01ByProductCode.ReadCurrent::countryID", countryID)
|
// fmt.Println("GetRecipe01ByProductCode.ReadCurrent::countryID", countryID)
|
||||||
fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentFile", d.CurrentFile)
|
// fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentFile", d.CurrentFile)
|
||||||
fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentCountryID", d.CurrentCountryID)
|
// fmt.Println("GetRecipe01ByProductCode.ReadCurrent::CurrentCountryID", d.CurrentCountryID)
|
||||||
|
|
||||||
for _, v := range d.currentRecipe[countryID].Recipe01 {
|
for _, v := range d.currentRecipe[countryID].Recipe01 {
|
||||||
if v.ProductCode == productCode {
|
if v.ProductCode == productCode {
|
||||||
|
|
@ -283,9 +283,9 @@ func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("No result in current recipe", countryID)
|
// fmt.Println("No result in current recipe", countryID)
|
||||||
} else if recipe, ok := d.recipeMap[filename]; ok {
|
} else if recipe, ok := d.recipeMap[filename]; ok {
|
||||||
fmt.Println("GetRecipe01ByProductCode.ReadMap", filename, d.CurrentFile, recipe.Recipe[countryID], "countryID=", countryID)
|
// fmt.Println("GetRecipe01ByProductCode.ReadMap", filename, d.CurrentFile, recipe.Recipe[countryID], "countryID=", countryID)
|
||||||
for _, v := range recipe.Recipe[countryID].Recipe01 {
|
for _, v := range recipe.Recipe[countryID].Recipe01 {
|
||||||
if v.ProductCode == productCode {
|
if v.ProductCode == productCode {
|
||||||
d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap))
|
d.taoLogger.Log.Debug("GetRecipe01ByProductCode.getSuccess", zap.Any("fromFile", filename), zap.Any("whereSource", d.recipeMap))
|
||||||
|
|
@ -499,6 +499,100 @@ func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialS
|
||||||
return recipe.MaterialSetting
|
return recipe.MaterialSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Data) GetAllToppingGroups(countryID, filename string) []models.ToppingGroup {
|
||||||
|
if countryID == "" {
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(filename, ".tmp") {
|
||||||
|
if filename == "" || filename == d.CurrentFile[countryID] {
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingGroup
|
||||||
|
}
|
||||||
|
if _, ok := d.recipeMap[countryID]; ok {
|
||||||
|
d.CurrentFile[countryID] = filename
|
||||||
|
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if filename == "default" {
|
||||||
|
filename = d.CurrentFile[countryID]
|
||||||
|
}
|
||||||
|
recipe, err := helpers.ReadRecipeFile(countryID, filename)
|
||||||
|
if err != nil {
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
d.currentRecipe[countryID] = recipe
|
||||||
|
|
||||||
|
if len(d.recipeMap) > 5 { // limit keep in memory 5 version
|
||||||
|
// remove oldest version
|
||||||
|
var oldestVersion string
|
||||||
|
var oldestTime int64
|
||||||
|
for k, v := range d.recipeMap {
|
||||||
|
if oldestTime == 0 || v.TimeStamps < oldestTime {
|
||||||
|
oldestTime = v.TimeStamps
|
||||||
|
oldestVersion = k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete(d.recipeMap, oldestVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.recipeMap[filename] = RecipeWithTimeStamps{
|
||||||
|
Recipe: d.currentRecipe,
|
||||||
|
TimeStamps: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipe.Topping.ToppingGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Data) GetToppingsList(countryID, filename string) []models.ToppingList {
|
||||||
|
// do return default
|
||||||
|
if countryID == "" {
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingList
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle temporary file
|
||||||
|
if !strings.Contains(filename, ".tmp") {
|
||||||
|
if filename == "" || filename == d.CurrentFile[countryID] {
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingList
|
||||||
|
}
|
||||||
|
if _, ok := d.recipeMap[countryID]; ok {
|
||||||
|
d.CurrentFile[countryID] = filename
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if filename == "default" {
|
||||||
|
filename = d.CurrentFile[countryID]
|
||||||
|
}
|
||||||
|
|
||||||
|
recipe, err := helpers.ReadRecipeFile(countryID, filename)
|
||||||
|
if err != nil {
|
||||||
|
return d.currentRecipe[countryID].Topping.ToppingList
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(d.recipeMap) > 5 { // limit keep in memory 5 version
|
||||||
|
// remove oldest version
|
||||||
|
var oldestVersion string
|
||||||
|
var oldestTime int64
|
||||||
|
for k, v := range d.recipeMap {
|
||||||
|
if oldestTime == 0 || v.TimeStamps < oldestTime {
|
||||||
|
oldestTime = v.TimeStamps
|
||||||
|
oldestVersion = k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete(d.recipeMap, oldestVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.recipeMap[filename] = RecipeWithTimeStamps{
|
||||||
|
Recipe: d.currentRecipe,
|
||||||
|
TimeStamps: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipe.Topping.ToppingList
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []models.MaterialCode {
|
func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []models.MaterialCode {
|
||||||
var result []models.MaterialCode
|
var result []models.MaterialCode
|
||||||
|
|
||||||
|
|
|
||||||
69
server/routers/topping.go
Normal file
69
server/routers/topping.go
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
package routers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"recipe-manager/data"
|
||||||
|
"recipe-manager/services/logger"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// this does different from normal topping fetcher in recipe
|
||||||
|
|
||||||
|
type ToppingRouter struct {
|
||||||
|
data *data.Data
|
||||||
|
taoLogger *logger.TaoLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewToppingRouter(data *data.Data, taoLogger *logger.TaoLogger) *ToppingRouter {
|
||||||
|
return &ToppingRouter{
|
||||||
|
data: data,
|
||||||
|
taoLogger: taoLogger,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *ToppingRouter) Route(r chi.Router) {
|
||||||
|
r.Route("/toppings", func(r chi.Router) {
|
||||||
|
r.Get("/groups/{country}/{filename}", tr.GetToppingGroups)
|
||||||
|
r.Get("/lists/{country}/{filename}", tr.GetToppingLists)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all topping group
|
||||||
|
func (tr *ToppingRouter) GetToppingGroups(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
|
||||||
|
// just in case: params country and filename
|
||||||
|
country := chi.URLParam(r, "country")
|
||||||
|
filename := chi.URLParam(r, "filename")
|
||||||
|
|
||||||
|
// get topping groups
|
||||||
|
toppingGroups := tr.data.GetAllToppingGroups(country, filename)
|
||||||
|
|
||||||
|
// send without new mapping
|
||||||
|
|
||||||
|
if err := json.NewEncoder(w).Encode(toppingGroups); err != nil {
|
||||||
|
tr.taoLogger.Log.Error("ToppingRouter.GetToppingGroups", zap.Error(err))
|
||||||
|
http.Error(w, "Internal Error", http.StatusInternalServerError)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *ToppingRouter) GetToppingLists(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
|
||||||
|
country := chi.URLParam(r, "country")
|
||||||
|
filename := chi.URLParam(r, "filename")
|
||||||
|
|
||||||
|
// get toppping list
|
||||||
|
toppingLists := tr.data.GetToppingsList(country, filename)
|
||||||
|
|
||||||
|
if err := json.NewEncoder(w).Encode(toppingLists); err != nil {
|
||||||
|
tr.taoLogger.Log.Debug("ToppingRouter.GetToppingLists", zap.Error(err))
|
||||||
|
http.Error(w, "Internal Error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -151,6 +151,10 @@ func (s *Server) createHandler() {
|
||||||
ur := routers.NewUserRouter(s.taoLogger, userService)
|
ur := routers.NewUserRouter(s.taoLogger, userService)
|
||||||
ur.Route(r)
|
ur.Route(r)
|
||||||
|
|
||||||
|
// Topping Router
|
||||||
|
tr := routers.NewToppingRouter(s.data, s.taoLogger)
|
||||||
|
tr.Route(r)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
|
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,8 @@ func (rs *recipeService) GetRecipeDashboard(request *contracts.RecipeDashboardRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rs.taoLogger.Log.Debug("RecipeDashboard", zap.String("Timestamp", recipe.Timestamp))
|
||||||
|
|
||||||
result := contracts.RecipeDashboardResponse{
|
result := contracts.RecipeDashboardResponse{
|
||||||
ConfigNumber: recipe.MachineSetting.ConfigNumber,
|
ConfigNumber: recipe.MachineSetting.ConfigNumber,
|
||||||
LastUpdated: recipe.Timestamp,
|
LastUpdated: recipe.Timestamp,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue