Add material code and settings

This commit is contained in:
Kenta420 2023-10-06 15:33:10 +07:00
parent 36be0426f6
commit 498bcf1c24
9 changed files with 279 additions and 60 deletions

View file

@ -3,7 +3,8 @@ export interface Recipe {
MachineSetting: MachineSetting;
Recipe01: Recipe01[];
Topping: Topping;
MaterailCode: MaterailCode[];
MaterialCode: MaterialCode[];
MaterialSetting: MaterialSetting[];
}
export interface MachineSetting {
@ -14,10 +15,10 @@ export interface MachineSetting {
temperatureMin: string;
}
export interface MaterailCode {
export interface MaterialCode {
PackageDescription: string;
RefillValuePerStep: string;
materialID: string;
materialID: number;
materialCode: string;
}
@ -25,7 +26,7 @@ export interface Recipe01 {
Description: string;
ExtendID: string;
OnTOP: string;
LastChange: string;
LastChange: Date;
MenuStatus: string;
RemainingCups: string;
StringParam: string;
@ -97,8 +98,8 @@ export interface MatRecipe {
MixOrder: string;
FeedParameter: string;
FeedPattern: string;
isUse: string;
materialPathId: string;
isUse: boolean;
materialPathId: number;
powderGram: string;
powderTime: string;
stirTime: string;

View file

@ -0,0 +1,41 @@
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';
@Injectable({ providedIn: 'root' })
export class MaterialService {
constructor(private _httpClient: HttpClient) {}
getMaterialCodes(
matIds?: number[],
version?: string
): Observable<MaterialCode[]> {
return this._httpClient.get<MaterialCode[]>(
`${environment.api}/materials/code`,
{
params: {
version: version || '',
mat_ids: matIds?.join(',') || '',
},
withCredentials: true,
}
);
}
getMaterialSettingById(
id: number,
version?: string
): Observable<MaterialSetting> {
return this._httpClient.get<MaterialSetting>(
`${environment.api}/materials/setting/${id}`,
{
params: {
version: version || '',
},
withCredentials: true,
}
);
}
}

View file

@ -4,20 +4,23 @@
class="block col-span-1 p-6 bg-white border border-gray-200 rounded-lg shadow"
>
<div *ngIf="isLoaded; else indicator" [@inOutAnimation]>
<h5 class="mb-2 text-xl font-bold text-gray-900">
{{ originalRecipeDetail?.name }} |
{{ originalRecipeDetail?.productCode }}
</h5>
<div class="flex flex-wrap">
<h5 class="mb-2 text-xl font-bold text-gray-900">
{{ originalRecipeDetail.name }}
</h5>
<h5 class="mb-2 px-3 text-xl font-bold text-gray-900">|</h5>
<h5 class="mb-2 text-xl font-bold text-gray-900">
{{ originalRecipeDetail.productCode }}
</h5>
</div>
<div class="flex items-center mb-2">
<div class="flex items-center mr-4">
<p class="text-sm text-gray-500">สูตร</p>
<p class="ml-2 text-sm text-gray-900">
{{ originalRecipeDetail?.name }}
</p>
</div>
<div class="flex items-center">
<p class="text-sm text-gray-500">ประเภท</p>
<p class="ml-2 text-sm text-gray-900">เครื่องดื่ม</p>
<p class="text-sm text-gray-500">Last Modify</p>
<p class="ml-2 text-sm text-gray-900">
{{
originalRecipeDetail.lastModified | date : "dd/MM/yyyy HH:mm:ss"
}}
</p>
</div>
</div>
<div class="flex p-3 items-center justify-center w-full">
@ -103,26 +106,38 @@
</div>
</ng-template>
</div>
<div
class="flex items-center justify-center h-48 mb-4 rounded bg-gray-50 dark:bg-gray-800"
>
<p class="text-2xl text-gray-400 dark:text-gray-500">
<svg
class="w-3.5 h-3.5"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 18 18"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 1v16M1 9h16"
/>
</svg>
</p>
<div class="col-span-3 max-h-[300px] overflow-auto mb-4 rounded">
<table class="table">
<thead>
<tr class="bg-gray-200">
<th class="px-6 py-3">Enable</th>
<th class="px-6 py-3">Material ID</th>
<th class="px-6 py-3">Material Name</th>
</tr>
</thead>
<tbody *ngIf="isMatLoaded; else indicator">
<tr
*ngFor="let mat of originalRecipeDetail?.matData"
class="bg-white la border-b hover:bg-secondary"
>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
<label>
<input
type="checkbox"
class="toggle toggle-sm"
[checked]="mat.enable"
/>
</label>
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
{{ mat.id }}
</td>
<td class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap">
{{ mat.name }}
</td>
</tr>
</tbody>
</table>
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div
@ -318,7 +333,7 @@
</div>
</div>
<div
class="sticky bottom-0 col-span-3 flex justify-end bg-white rounded-full shadow-xl p-3"
class="sticky bottom-0 col-span-3 flex justify-end bg-white rounded-full drop-shadow-2xl p-3"
>
<button
(click)="onPressConfirmClose()"

View file

@ -1,15 +1,18 @@
import { NgIf } from '@angular/common';
import { DatePipe, NgFor, NgIf } from '@angular/common';
import { Component, EventEmitter, OnInit } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { isEqual } from 'lodash';
import { delay } from 'rxjs';
import { delay, finalize } from 'rxjs';
import { RecipeService } from 'src/app/core/services/recipe.service';
import { ConfirmModal } from 'src/app/shared/modal/confirm/confirm-modal.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { animate, style, transition, trigger } from '@angular/animations';
import { MatRecipe } from 'src/app/core/models/recipe.model';
import { MaterialService } from 'src/app/core/services/material.service';
interface RecipeDetail {
lastModified: Date;
productCode: string;
name: string;
otherName: string;
@ -19,6 +22,14 @@ interface RecipeDetail {
isUse: boolean;
isShow: boolean;
disable: boolean;
recipes: MatRecipe[];
matData?: MaterialData[];
}
interface MaterialData {
id: number;
name: string;
enable: boolean;
}
interface RecipeMetaData {
@ -34,7 +45,14 @@ interface RecipeMetaData {
selector: 'app-recipe-details',
templateUrl: './recipe-details.component.html',
standalone: true,
imports: [NgIf, RouterLink, ReactiveFormsModule, ConfirmModal],
imports: [
NgIf,
NgFor,
RouterLink,
ReactiveFormsModule,
ConfirmModal,
DatePipe,
],
animations: [
trigger('inOutAnimation', [
transition(':enter', [
@ -48,14 +66,16 @@ export class RecipeDetailsComponent implements OnInit {
title: string = 'Recipe Detail';
recipeMetaData: RecipeMetaData | null = null;
originalRecipeDetail: RecipeDetail | null = null;
originalRecipeDetail!: RecipeDetail;
isLoaded: boolean = false;
isMatLoaded: boolean = false;
constructor(
private _route: ActivatedRoute,
private _router: Router,
private _recipeService: RecipeService
private _recipeService: RecipeService,
private _materialService: MaterialService
) {}
recipeDetail = new FormGroup({
@ -73,6 +93,7 @@ export class RecipeDetailsComponent implements OnInit {
ngOnInit() {
this._recipeService
.getRecipesById(this._route.snapshot.params['productCode'])
.pipe(finalize(() => {}))
.subscribe(({ recipe, recipeMetaData }) => {
this.title = recipe.name + ' | ' + recipe.productCode;
this.recipeDetail.patchValue({
@ -87,6 +108,7 @@ export class RecipeDetailsComponent implements OnInit {
disable: recipe.disable,
});
this.originalRecipeDetail = {
lastModified: recipe.LastChange,
productCode: recipe.productCode,
name: recipe.name,
otherName: recipe.otherName,
@ -96,9 +118,27 @@ export class RecipeDetailsComponent implements OnInit {
isUse: recipe.isUse,
isShow: recipe.isShow,
disable: recipe.disable,
recipes: recipe.recipes,
};
this.recipeMetaData = recipeMetaData;
this.isLoaded = true;
const ids = this.originalRecipeDetail.recipes.map(
(recipe) => recipe.materialPathId
);
this._materialService.getMaterialCodes(ids).subscribe((data) => {
this.originalRecipeDetail.matData = data
.map((item) => {
return {
id: item.materialID,
name: item.PackageDescription,
enable: false,
};
})
.sort((a, b) => (a.id > b.id ? -1 : -1));
this.isMatLoaded = true;
});
});
}

View file

@ -84,12 +84,7 @@ export class DashboardComponent implements OnInit {
);
}
constructor(
private _route: ActivatedRoute,
private _router: Router,
private _userService: UserService,
private _recipeService: RecipeService
) {}
constructor(private _recipeService: RecipeService) {}
ngOnInit(): void {
this._recipeService

View file

@ -89,3 +89,49 @@ func (d *Data) GetRecipe(version string) models.Recipe {
func (d *Data) GetRecipe01() []models.Recipe01 {
return d.recipe.Recipe01
}
func (d *Data) GetMaterialSetting(version string) []models.MaterialSetting {
result := make([]models.MaterialSetting, 0)
if version == "" || version == d.CurrentVersion {
copy(result, d.recipe.MaterialSetting)
return result
}
d.CurrentVersion = version
d.recipe = readFile(version)
copy(result, d.recipe.MaterialSetting)
return result
}
func (d *Data) GetMaterialCode(ids []uint64, version string) []models.MaterialCode {
var result []models.MaterialCode
if version == "" || version == d.CurrentVersion {
result = d.recipe.MaterialCode
} else {
d.CurrentVersion = version
d.recipe = readFile(version)
result = d.recipe.MaterialCode
}
if len(ids) == 0 {
return result
}
resultFilter := make([]models.MaterialCode, len(ids))
for _, id := range ids {
if id == 0 {
continue
}
for _, m := range result {
if m.MaterialID == id {
resultFilter = append(resultFilter, m)
break
}
}
}
return resultFilter
}

View file

@ -1,14 +1,15 @@
package models
type Recipe struct {
Timestamp string `json:"Timestamp"`
MachineSetting MatchineSetting `json:"MachineSetting"`
Recipe01 []Recipe01 `json:"Recipe01"`
Topping Topping `json:"Topping"`
MaterailCode []MaterailCode `json:"MaterailCode"`
Timestamp string `json:"Timestamp"`
MachineSetting MachineSetting `json:"MachineSetting"`
Recipe01 []Recipe01 `json:"Recipe01"`
Topping Topping `json:"Topping"`
MaterialCode []MaterialCode `json:"MaterialCode"`
MaterialSetting []MaterialSetting `json:"MaterialSetting"`
}
type MatchineSetting struct {
type MachineSetting struct {
RecipeTag string `json:"RecipeTag"`
StrTextShowError []string `json:"strTextShowError"`
ConfigNumber int `json:"configNumber"`
@ -16,10 +17,10 @@ type MatchineSetting struct {
TemperatureMin int `json:"temperatureMin"`
}
type MaterailCode struct {
type MaterialCode struct {
PackageDescription string `json:"PackageDescription"`
RefillValuePerStep int `json:"RefillValuePerStep"`
MaterialID int `json:"materialID"`
MaterialID uint64 `json:"materialID"`
MaterialCode string `json:"materialCode"`
}
@ -40,7 +41,7 @@ type MaterialSetting struct {
SodaChannel bool `json:"SodaChannel"`
StockAdjust int `json:"StockAdjust"`
SyrupChannel bool `json:"SyrupChannel"`
ID int `json:"id"`
ID uint64 `json:"id"`
IDAlternate int `json:"idAlternate"`
IsUse bool `json:"isUse"`
PayRettryMaxCount int `json:"pay_rettry_max_count"`

View file

@ -0,0 +1,76 @@
package routers
import (
"encoding/json"
"net/http"
"recipe-manager/data"
"recipe-manager/models"
"strconv"
"strings"
"github.com/go-chi/chi/v5"
)
type MaterialRouter struct {
data *data.Data
}
func NewMaterialRouter(data *data.Data) *MaterialRouter {
return &MaterialRouter{
data: data,
}
}
func (mr *MaterialRouter) Route(r chi.Router) {
r.Route("/materials", func(r chi.Router) {
r.Get("/code", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
version := r.URL.Query().Get("version")
matIDs := r.URL.Query().Get("mat_ids")
var matIDsUint []uint64
for _, v := range strings.Split(matIDs, ",") {
matIDUint, err := strconv.ParseUint(v, 10, 64)
if err != nil || matIDUint == 0 {
continue
}
matIDsUint = append(matIDsUint, matIDUint)
}
material := mr.data.GetMaterialCode(matIDsUint, version)
json.NewEncoder(w).Encode(material)
})
r.Get("/setting/{mat_id}", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
version := r.URL.Query().Get("version")
material := mr.data.GetMaterialSetting(version)
matID := chi.URLParam(r, "mat_id")
matIDuint, err := strconv.ParseUint(matID, 10, 64)
if err != nil {
http.Error(w, "Invalid material id", http.StatusBadRequest)
return
}
var matSetting models.MaterialSetting
for _, mat := range material {
if mat.ID == matIDuint {
matSetting = mat
break
}
}
json.NewEncoder(w).Encode(matSetting)
})
})
}

View file

@ -437,7 +437,6 @@ func (s *Server) createHandler() {
Log.Debug("Scan dir completed < ", zap.String("path", r.RequestURI))
})
// Recipe Router
sheetService, err := sheet.NewSheetService(context.Background(), s.cfg)
if err != nil {
@ -445,9 +444,14 @@ func (s *Server) createHandler() {
return
}
// Recipe Router
rr := routers.NewRecipeRouter(database, sheetService)
rr.Route(r)
// Material Router
mr := routers.NewMaterialRouter(database)
mr.Route(r)
})
r.NotFound(func(w http.ResponseWriter, r *http.Request) {