This commit is contained in:
2026-08-27 12:08:58 +00:00
parent 612426b92f
commit af07bb5043
7 changed files with 90 additions and 68 deletions
+21 -12
View File
@@ -1,5 +1,5 @@
import { HttpClient, HttpHeaders, httpResource, HttpResourceRef } from '@angular/common/http'; import { HttpClient, HttpHeaders, httpResource, HttpResourceRef } from '@angular/common/http';
import { Injectable, Signal, inject } from '@angular/core'; import { Injectable, Signal, inject, signal } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
@@ -27,17 +27,26 @@ export class CustomerService {
}); });
} }
list(q: string | null, page = 0, size = 50, field = 'name', direction = 'asc'): Observable<PagedResult<Customer>> { list(
const params = { q: Signal<string | null>,
...(q ? { q } : {}), page: Signal<number> = signal(0),
p: page, size: Signal<number> = signal(50),
s: size, field: Signal<string> = signal('name'),
f: field, direction: Signal<string> = signal('asc'),
d: direction, ): HttpResourceRef<PagedResult<Customer> | undefined> {
}; return httpResource<PagedResult<Customer>>(() => {
return this.http const qVal = q();
.get<PagedResult<Customer>>(`${url}/list`, { params }) return {
.pipe(catchError(this.log.handleError(serviceName, 'list'))) as Observable<PagedResult<Customer>>; url: `${url}/list`,
params: {
...(qVal ? { q: qVal } : {}),
p: page(),
s: size(),
f: field(),
d: direction(),
},
};
});
} }
query( query(
@@ -1,5 +1,5 @@
import { HttpClient, HttpHeaders, httpResource, HttpResourceRef } from '@angular/common/http'; import { HttpClient, HttpHeaders, httpResource, HttpResourceRef } from '@angular/common/http';
import { Injectable, Signal, inject } from '@angular/core'; import { Injectable, Injector, Signal, inject } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
@@ -18,22 +18,30 @@ const serviceName = 'ModifierCategoryService';
export class ModifierCategoryService { export class ModifierCategoryService {
private http = inject(HttpClient); private http = inject(HttpClient);
private log = inject(ErrorLoggerService); private log = inject(ErrorLoggerService);
private injector = inject(Injector);
get(id: Signal<string | null>): HttpResourceRef<ModifierCategory | undefined> { get(id: Signal<string | null>): HttpResourceRef<ModifierCategory | undefined> {
return httpResource<ModifierCategory>(() => { return httpResource<ModifierCategory>(
const idVal = id(); () => {
return idVal === null || idVal === undefined ? url : `${url}/${idVal}`; const idVal = id();
}); return idVal === null || idVal === undefined ? { url } : { url: `${url}/${idVal}` };
},
{ injector: this.injector },
);
} }
list(): HttpResourceRef<ModifierCategory[] | undefined> { list(): HttpResourceRef<ModifierCategory[] | undefined> {
return httpResource<ModifierCategory[]>(() => `${url}/list`); return httpResource<ModifierCategory[]>(() => ({ url: `${url}/list` }), { injector: this.injector });
} }
listForSku(sku_id: string): Observable<ModifierCategory[]> { listForSku(skuId: Signal<string | null>): HttpResourceRef<ModifierCategory[] | undefined> {
return this.http return httpResource<ModifierCategory[]>(
.get<ModifierCategory[]>(`${url}/for-sku/${sku_id}`) () => {
.pipe(catchError(this.log.handleError(serviceName, 'listForSku'))) as Observable<ModifierCategory[]>; const idVal = skuId();
return idVal ? { url: `${url}/for-sku/${idVal}` } : undefined;
},
{ injector: this.injector },
);
} }
save(modifierCategory: ModifierCategory): Observable<ModifierCategory> { save(modifierCategory: ModifierCategory): Observable<ModifierCategory> {
@@ -1,6 +1,6 @@
import { CurrencyPipe } from '@angular/common'; import { CurrencyPipe } from '@angular/common';
import { Component, inject, computed, linkedSignal, input } from '@angular/core'; import { Component, computed, inject, input, linkedSignal } from '@angular/core';
import { form, FormField } from '@angular/forms/signals'; import { FormField, form } from '@angular/forms/signals';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatOptionModule } from '@angular/material/core'; import { MatOptionModule } from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatDatepickerModule } from '@angular/material/datepicker';
+17 -9
View File
@@ -1,9 +1,10 @@
import { SelectionModel } from '@angular/cdk/collections'; import { SelectionModel } from '@angular/cdk/collections';
import { Injectable, inject, signal, computed } from '@angular/core'; import { Injectable, Injector, computed, inject, signal } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { throwError, Observable } from 'rxjs'; import { Observable, throwError } from 'rxjs';
import { tap } from 'rxjs/operators'; import { filter, take, tap } from 'rxjs/operators';
import { ModifierCategory } from '../core/modifier-category'; import { ModifierCategory } from '../core/modifier-category';
import { ProductQuery } from '../core/product-query'; import { ProductQuery } from '../core/product-query';
@@ -29,6 +30,7 @@ export class BillService {
private math = inject(MathService); private math = inject(MathService);
private ser = inject(VoucherService); private ser = inject(VoucherService);
private modifierCategoryService = inject(ModifierCategoryService); private modifierCategoryService = inject(ModifierCategoryService);
private injector = inject(Injector);
public data = signal<Kot[]>([]); public data = signal<Kot[]>([]);
public bill: Bill = new Bill(); public bill: Bill = new Bill();
@@ -152,11 +154,17 @@ export class BillService {
} }
} }
newKot.inventories.push(item); newKot.inventories.push(item);
this.modifierCategoryService.listForSku(sku.id as string).subscribe((result) => { const modRes = this.modifierCategoryService.listForSku(signal(sku.id as string));
if (result.reduce((a: number, c: ModifierCategory) => a + c.minimum, 0)) { toObservable(modRes.value, { injector: this.injector })
this.showModifier(item); .pipe(
} filter((result): result is ModifierCategory[] => !!result),
}); take(1),
)
.subscribe((result) => {
if (result.reduce((a: number, c: ModifierCategory) => a + c.minimum, 0)) {
this.showModifier(item);
}
});
} }
this.displayBill(); this.displayBill();
} }
@@ -171,7 +179,7 @@ export class BillService {
maxWidth: 'none', maxWidth: 'none',
maxHeight: 'none', maxHeight: 'none',
data: { data: {
list: this.modifierCategoryService.listForSku(item.sku.id as string), list: this.modifierCategoryService.listForSku(signal(item.sku.id as string)),
selected: Object.assign([], item.modifiers), selected: Object.assign([], item.modifiers),
}, },
}); });
@@ -1,6 +1,6 @@
import { CdkScrollable } from '@angular/cdk/scrolling'; import { CdkScrollable } from '@angular/cdk/scrolling';
import { Component, inject, signal, computed } from '@angular/core'; import { HttpResourceRef } from '@angular/common/http';
import { toSignal } from '@angular/core/rxjs-interop'; import { Component, computed, inject, signal } from '@angular/core';
import { MatBadgeModule } from '@angular/material/badge'; import { MatBadgeModule } from '@angular/material/badge';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
@@ -8,7 +8,6 @@ import { MatChipsModule } from '@angular/material/chips';
import { MatRippleModule } from '@angular/material/core'; import { MatRippleModule } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { MatTabsModule } from '@angular/material/tabs'; import { MatTabsModule } from '@angular/material/tabs';
import { Observable } from 'rxjs';
import { Modifier } from '../../core/modifier'; import { Modifier } from '../../core/modifier';
import { ModifierCategory } from '../../core/modifier-category'; import { ModifierCategory } from '../../core/modifier-category';
@@ -30,11 +29,11 @@ import { ModifierCategory } from '../../core/modifier-category';
}) })
export class ModifiersComponent { export class ModifiersComponent {
data = inject<{ data = inject<{
list: Observable<ModifierCategory[]>; list: HttpResourceRef<ModifierCategory[] | undefined>;
selected: Modifier[]; selected: Modifier[];
}>(MAT_DIALOG_DATA); }>(MAT_DIALOG_DATA);
list = toSignal(this.data.list, { initialValue: [] }); list = computed(() => this.data.list.value() ?? []);
selected = signal<Modifier[]>(this.data.selected ? [...this.data.selected] : []); selected = signal<Modifier[]>(this.data.selected ? [...this.data.selected] : []);
selectedIds = computed(() => this.selected().map((e) => e.id)); selectedIds = computed(() => this.selected().map((e) => e.id));
@@ -1,16 +1,14 @@
import { CdkScrollableModule } from '@angular/cdk/scrolling'; import { CdkScrollableModule } from '@angular/cdk/scrolling';
import { CurrencyPipe } from '@angular/common'; import { CurrencyPipe } from '@angular/common';
import { Component, inject, signal, computed } from '@angular/core'; import { Component, computed, effect, inject, signal } from '@angular/core';
import { form, FormField } from '@angular/forms/signals'; import { FormField, form } from '@angular/forms/signals';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input'; import { MatInputModule } from '@angular/material/input';
import { MatTableModule } from '@angular/material/table'; import { MatTableModule } from '@angular/material/table';
import { map, tap } from 'rxjs/operators';
import { ReceivePaymentItem } from '../../core/receive-payment-item'; import { ReceivePaymentItem } from '../../core/receive-payment-item';
import { SettleOption } from '../../core/settle-option';
import { SettleOptionService } from '../../settle-option/settle-option.service'; import { SettleOptionService } from '../../settle-option/settle-option.service';
import { VoucherType } from '../bills/voucher-type'; import { VoucherType } from '../bills/voucher-type';
@@ -45,6 +43,9 @@ export class ReceivePaymentComponent {
amount: number; amount: number;
}>(MAT_DIALOG_DATA); }>(MAT_DIALOG_DATA);
typeSignal = signal<VoucherType | undefined>(this.data.type);
settleOptionsResource = this.ser.listForType(this.typeSignal);
choices = signal<ReceivePaymentItem[]>([]); choices = signal<ReceivePaymentItem[]>([]);
choicesWithAmount = computed(() => { choicesWithAmount = computed(() => {
const amounts = this.formModel().amounts; const amounts = this.formModel().amounts;
@@ -77,25 +78,23 @@ export class ReceivePaymentComponent {
this.amount = data.amount; this.amount = data.amount;
this.displayReason.set(false); this.displayReason.set(false);
this.displayTable.set(false); this.displayTable.set(false);
this.ser
.listForType(data.type) effect(() => {
.pipe( const x = this.settleOptionsResource.value();
tap((x: SettleOption[]) => this.displayReason.set(x.reduce((o, n) => o || n.hasReason, this.displayReason()))), if (!x) return;
tap((x: SettleOption[]) => this.displayTable.set(x.length > 1)), this.displayReason.set(x.reduce((o, n) => o || n.hasReason, false));
map((x: SettleOption[]) => this.displayTable.set(x.length > 1);
x.map((y) => ({ ...y, amount: !this.displayTable() ? this.amount : 0 }) as ReceivePaymentItem), const isTable = x.length > 1;
), const choices = x.map((y) => ({ ...y, amount: !isTable ? this.amount : 0 }) as ReceivePaymentItem);
) this.choices.set(choices);
.subscribe((x) => { this.formModel.update((f) => ({
this.choices.set(x); ...f,
this.formModel.update((f) => ({ amounts: x.map((y) => ({
...f, name: y.name,
amounts: x.map((y) => ({ amount: !isTable ? this.amount : 0,
name: y.name, })),
amount: y.amount === 0 ? 0 : this.amount, }));
})), });
}));
});
} }
select(reason: string) { select(reason: string) {
@@ -31,12 +31,11 @@ export class SettleOptionService {
return httpResource<SettleOption[]>(() => `${url}/list`); return httpResource<SettleOption[]>(() => `${url}/list`);
} }
listForType(voucherType: VoucherType): Observable<SettleOption[]> { listForType(voucherType: Signal<VoucherType | undefined>): HttpResourceRef<SettleOption[] | undefined> {
return this.http return httpResource<SettleOption[]>(() => {
.get<SettleOption[]>(`${url}/for-type/${voucherType}`) const typeVal = voucherType();
.pipe(catchError(this.log.handleError(serviceName, `listForType voucherType=${voucherType}`))) as Observable< return typeVal !== undefined && typeVal !== null ? `${url}/for-type/${typeVal}` : undefined;
SettleOption[] });
>;
} }
save(settleOption: SettleOption): Observable<SettleOption> { save(settleOption: SettleOption): Observable<SettleOption> {