fds
This commit is contained in:
@@ -13,7 +13,7 @@ import { ProductService } from '../../product/product.service';
|
||||
import { BundleItem } from '../bundle';
|
||||
|
||||
export interface BundleDetailDialogFormData {
|
||||
product: BundleItem | ProductQuery | string;
|
||||
product: ProductQuery | string;
|
||||
quantity: number;
|
||||
salePrice: number;
|
||||
printInBill: boolean;
|
||||
@@ -44,7 +44,7 @@ export class BundleDetailDialogComponent {
|
||||
formModel = linkedSignal<BundleItem, BundleDetailDialogFormData>({
|
||||
source: () => this.data.item,
|
||||
computation: (item) => ({
|
||||
product: item,
|
||||
product: item.sku ?? '',
|
||||
quantity: Number(item.quantity ?? 1),
|
||||
salePrice: Number(item.salePrice ?? 0),
|
||||
printInBill: item.printInBill ?? false,
|
||||
@@ -84,8 +84,7 @@ export class BundleDetailDialogComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data.item.itemId = product.id ?? '';
|
||||
this.data.item.name = product.name ?? '';
|
||||
this.data.item.sku = product;
|
||||
this.data.item.quantity = quantity;
|
||||
this.data.item.salePrice = salePrice;
|
||||
this.data.item.printInBill = formValue.printInBill ?? false;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<mat-label>Menu Category</mat-label>
|
||||
<mat-select [formField]="form.menuCategory">
|
||||
@for (mc of menuCategories(); track mc) {
|
||||
<mat-option [value]="mc.id">
|
||||
<mat-option [value]="mc">
|
||||
{{ mc.name }}
|
||||
</mat-option>
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
<mat-label>Sale Category</mat-label>
|
||||
<mat-select [formField]="form.saleCategory">
|
||||
@for (sc of saleCategories(); track sc) {
|
||||
<mat-option [value]="sc.id">
|
||||
<mat-option [value]="sc">
|
||||
{{ sc.name }}
|
||||
</mat-option>
|
||||
}
|
||||
@@ -61,9 +61,9 @@
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
[formField]="form.addRow.itemId"
|
||||
[formField]="form.addRow.sku"
|
||||
[matAutocomplete]="autoItem"
|
||||
[value]="displayFn(formModel().addRow.itemId)"
|
||||
[value]="displayFn(formModel().addRow.sku)"
|
||||
/>
|
||||
<mat-autocomplete #autoItem="matAutocomplete" [displayWith]="displayFn">
|
||||
@for (p of itemProducts(); track p) {
|
||||
@@ -89,11 +89,11 @@
|
||||
|
||||
<div class="row-container wrapped">
|
||||
<mat-table [dataSource]="formModel().items" aria-label="Bundle Items" class="flex-auto">
|
||||
<!-- Name Column (name is "name (units)") -->
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<mat-header-cell *matHeaderCellDef>Item</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">
|
||||
{{ row.name }}
|
||||
{{ row.sku?.name }}
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export interface BundleDetailFormData {
|
||||
hasHappyHour: boolean;
|
||||
isNotAvailable: boolean;
|
||||
addRow: {
|
||||
itemId: ProductQuery | string;
|
||||
sku: ProductQuery | string;
|
||||
quantity: number;
|
||||
salePrice: number;
|
||||
printInBill: boolean;
|
||||
@@ -89,7 +89,7 @@ export class BundleDetailComponent {
|
||||
isNotAvailable: itemVal.isNotAvailable ?? false,
|
||||
items,
|
||||
addRow: {
|
||||
itemId: '',
|
||||
sku: '',
|
||||
quantity: 1,
|
||||
salePrice: 0,
|
||||
printInBill: true,
|
||||
@@ -101,7 +101,7 @@ export class BundleDetailComponent {
|
||||
form = form(this.formModel);
|
||||
|
||||
private itemProductSearch = computed(() => {
|
||||
const v = this.form.addRow.itemId().value();
|
||||
const v = this.form.addRow.sku().value();
|
||||
return typeof v === 'string' ? v : null;
|
||||
});
|
||||
|
||||
@@ -116,7 +116,7 @@ export class BundleDetailComponent {
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
const v = this.form.addRow.itemId().value();
|
||||
const v = this.form.addRow.sku().value();
|
||||
if (typeof v === 'object' && v !== null) {
|
||||
this.formModel.update((f) => ({
|
||||
...f,
|
||||
@@ -147,7 +147,7 @@ export class BundleDetailComponent {
|
||||
this.formModel.update((f) => ({
|
||||
...f,
|
||||
addRow: {
|
||||
itemId: '',
|
||||
sku: '',
|
||||
quantity: 1,
|
||||
salePrice: 0,
|
||||
printInBill: true,
|
||||
@@ -158,7 +158,7 @@ export class BundleDetailComponent {
|
||||
addRow() {
|
||||
const formValue = this.form().value().addRow;
|
||||
if (!formValue) return;
|
||||
const itemProduct = formValue.itemId as ProductQuery;
|
||||
const itemProduct = formValue.sku as ProductQuery;
|
||||
|
||||
if (!itemProduct || typeof itemProduct === 'string') {
|
||||
this.snackBar.open('Please select a product', 'Error');
|
||||
@@ -178,8 +178,7 @@ export class BundleDetailComponent {
|
||||
}
|
||||
|
||||
const bi = new BundleItem({
|
||||
itemId: itemProduct.id,
|
||||
name: itemProduct.name ?? '',
|
||||
sku: itemProduct,
|
||||
quantity,
|
||||
salePrice,
|
||||
printInBill: formValue.printInBill || false,
|
||||
|
||||
@@ -72,7 +72,9 @@
|
||||
<mat-icon>
|
||||
{{ item.printInBill ? 'visibility' : 'visibility_off' }}
|
||||
</mat-icon>
|
||||
<div class="item-name">{{ item.name }} x {{ item.quantity }} @ {{ item.salePrice | currency: 'INR' }}</div>
|
||||
<div class="item-name">
|
||||
{{ item.sku?.name }} x {{ item.quantity }} @ {{ item.salePrice | currency: 'INR' }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</mat-cell>
|
||||
|
||||
@@ -88,7 +88,7 @@ export class BundleListComponent {
|
||||
...b,
|
||||
menuCategory: b.menuCategory?.name ?? '',
|
||||
items: (b.items ?? [])
|
||||
.map((i) => `${i.name}${i.quantity && i.quantity !== 1 ? ` x${i.quantity}` : ''}`)
|
||||
.map((i) => `${i.sku?.name ?? ''}${i.quantity && i.quantity !== 1 ? ` x${i.quantity}` : ''}`)
|
||||
.join(' | '),
|
||||
}));
|
||||
|
||||
|
||||
@@ -3,14 +3,13 @@ import { ProductQuery } from '../core/product-query';
|
||||
import { SaleCategory } from '../core/sale-category';
|
||||
|
||||
export class BundleItem {
|
||||
sku: ProductQuery | undefined;
|
||||
name: string;
|
||||
id?: string;
|
||||
sku?: ProductQuery;
|
||||
salePrice: number;
|
||||
quantity: number;
|
||||
printInBill: boolean;
|
||||
|
||||
public constructor(init?: Partial<BundleItem>) {
|
||||
this.name = '';
|
||||
this.salePrice = 0;
|
||||
this.quantity = 0;
|
||||
this.printInBill = true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @angular-eslint/no-input-rename */
|
||||
import { PercentPipe } from '@angular/common';
|
||||
import { Component, inject, signal, effect, computed, debounced, afterNextRender, input } from '@angular/core';
|
||||
import { Component, inject, linkedSignal, effect, computed, debounced, afterNextRender, input } from '@angular/core';
|
||||
import { form, FormField } from '@angular/forms/signals';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
@@ -51,8 +51,11 @@ export class CustomerListComponent {
|
||||
sortInput = input<string>('name', { alias: 'f' });
|
||||
direction = input<string>('asc', { alias: 'd' });
|
||||
|
||||
formModel = signal<CustomerListFormData>({
|
||||
filter: this.route.snapshot.queryParamMap.get('q') ?? '',
|
||||
formModel = linkedSignal({
|
||||
source: this.q,
|
||||
computation: (q): CustomerListFormData => ({
|
||||
filter: q,
|
||||
}),
|
||||
});
|
||||
|
||||
form = form(this.formModel);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, inject, computed, effect, signal } from '@angular/core';
|
||||
import { Component, inject, computed, effect, input, linkedSignal } from '@angular/core';
|
||||
import { form, FormField } from '@angular/forms/signals';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
@@ -40,8 +40,21 @@ export class GuestBookListComponent {
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private ser = inject(GuestBookService);
|
||||
|
||||
formModel = signal<GuestBookListFormData>({
|
||||
date: this.initialDate(),
|
||||
date = input(new Date(), {
|
||||
transform: (v: string | null | undefined): Date => {
|
||||
if (v) {
|
||||
const parsed = moment(v, 'DD-MMM-YYYY', true);
|
||||
if (parsed.isValid()) return parsed.toDate();
|
||||
}
|
||||
return new Date();
|
||||
},
|
||||
});
|
||||
|
||||
formModel = linkedSignal({
|
||||
source: this.date,
|
||||
computation: (d): GuestBookListFormData => ({
|
||||
date: d,
|
||||
}),
|
||||
});
|
||||
|
||||
form = form(this.formModel);
|
||||
@@ -65,13 +78,4 @@ export class GuestBookListComponent {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private initialDate(): Date {
|
||||
const qp = this.route.snapshot.queryParamMap.get('date');
|
||||
if (qp) {
|
||||
const parsed = moment(qp, 'DD-MMM-YYYY', true);
|
||||
if (parsed.isValid()) return parsed.toDate();
|
||||
}
|
||||
return new Date();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,7 @@ export class GuestBookService {
|
||||
private http = inject(HttpClient);
|
||||
private log = inject(ErrorLoggerService);
|
||||
|
||||
get(
|
||||
id: Signal<string | null>,
|
||||
type?: Signal<GuestBookType | string>,
|
||||
): HttpResourceRef<GuestBook | undefined> {
|
||||
get(id: Signal<string | null>, type?: Signal<GuestBookType | string>): HttpResourceRef<GuestBook | undefined> {
|
||||
return httpResource<GuestBook>(() => {
|
||||
const idVal = id();
|
||||
const typeVal = type ? type() : '';
|
||||
|
||||
@@ -27,29 +27,27 @@
|
||||
<div class="row-container">
|
||||
<mat-form-field class="flex-auto">
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput [formField]="form.name" />
|
||||
<input matInput [value]="formModel().name" readonly />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row-container">
|
||||
<mat-form-field class="flex-auto">
|
||||
<mat-label>Address</mat-label>
|
||||
<textarea matInput [formField]="form.address"> </textarea>
|
||||
<textarea matInput [value]="formModel().address" readonly> </textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row-container">
|
||||
<mat-checkbox [formField]="form.printInBill">Print in Bill?</mat-checkbox>
|
||||
<mat-checkbox [checked]="formModel().printInBill" [disabled]="true">Print in Bill?</mat-checkbox>
|
||||
</div>
|
||||
<p></p>
|
||||
<div class="discounts">
|
||||
@for (r of item.discounts; track r; let i = $index) {
|
||||
<div class="row-container">
|
||||
<mat-form-field class="flex-auto">
|
||||
<mat-label>Discount on {{ r.name }}</mat-label>
|
||||
<input matInput [formField]="form.discounts[i].discount" />
|
||||
<span matTextSuffix>%</span>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
}
|
||||
<ul>
|
||||
@for (r of formModel().discounts; track r.id) {
|
||||
@if (r.discount > 0) {
|
||||
<li>{{ r.name }} - {{ r.discount | percent: '1.2-2' }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { CdkScrollableModule } from '@angular/cdk/scrolling';
|
||||
import { PercentPipe } from '@angular/common';
|
||||
import { Component, inject, computed, debounced, linkedSignal, signal } from '@angular/core';
|
||||
import { form, FormField } from '@angular/forms/signals';
|
||||
import { MatAutocompleteSelectedEvent, MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
@@ -8,9 +9,9 @@ import { MatOptionModule } from '@angular/material/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { round } from 'mathjs';
|
||||
|
||||
import { Customer } from '../../core/customer';
|
||||
import { CustomerDiscount } from '../../core/customer-discount';
|
||||
import { CustomerService } from '../../customers/customer.service';
|
||||
|
||||
export interface ChooseCustomerFormData {
|
||||
@@ -19,9 +20,7 @@ export interface ChooseCustomerFormData {
|
||||
phone: string;
|
||||
address: string;
|
||||
printInBill: boolean;
|
||||
discounts: {
|
||||
discount: number | null;
|
||||
}[];
|
||||
discounts: CustomerDiscount[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -37,6 +36,7 @@ export interface ChooseCustomerFormData {
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatOptionModule,
|
||||
PercentPipe,
|
||||
FormField,
|
||||
],
|
||||
})
|
||||
@@ -55,9 +55,7 @@ export class ChooseCustomerComponent {
|
||||
phone: data.phone,
|
||||
address: data.address ?? '',
|
||||
printInBill: data.printInBill,
|
||||
discounts: data.discounts.map((x) => ({
|
||||
discount: x.discount ? x.discount * 100 : null,
|
||||
})),
|
||||
discounts: data.discounts ?? [],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -70,7 +68,9 @@ export class ChooseCustomerComponent {
|
||||
debouncedPhone = debounced(this.phoneSignal, 150);
|
||||
|
||||
customersResource = this.ser.autocomplete(this.debouncedPhone.value);
|
||||
customers = computed(() => { return this.customersResource.value() ?? [] });
|
||||
customers = computed(() => {
|
||||
return this.customersResource.value() ?? [];
|
||||
});
|
||||
|
||||
save() {
|
||||
const customer = this.getItem();
|
||||
@@ -92,7 +92,6 @@ export class ChooseCustomerComponent {
|
||||
|
||||
getItem(): Customer {
|
||||
const formModel = this.formModel();
|
||||
const array = formModel.discounts;
|
||||
|
||||
return new Customer({
|
||||
id: formModel.id,
|
||||
@@ -100,14 +99,7 @@ export class ChooseCustomerComponent {
|
||||
phone: formModel.phone ?? '',
|
||||
address: formModel.address ?? '',
|
||||
printInBill: formModel.printInBill ?? false,
|
||||
discounts: formModel.discounts.map((item, index) => {
|
||||
const array_item = array?.[index];
|
||||
return {
|
||||
...this.item().discounts?.[index],
|
||||
discount:
|
||||
array_item && array_item?.discount ? Math.max(Math.min(round(array_item.discount / 100, 5), 100), 0) : 0,
|
||||
};
|
||||
}),
|
||||
discounts: formModel.discounts.map((item) => ({ ...item })),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,15 @@ export class CustomerDiscountsService {
|
||||
private injector = inject(Injector);
|
||||
|
||||
list(id: Signal<string | undefined>): HttpResourceRef<DiscountItem[] | undefined> {
|
||||
return httpResource<DiscountItem[]>(() => {
|
||||
const idVal = id();
|
||||
return idVal === undefined ? url : `${url}/${idVal}`;
|
||||
}, {
|
||||
injector: this.injector,
|
||||
});
|
||||
return httpResource<DiscountItem[]>(
|
||||
() => {
|
||||
const idVal = id();
|
||||
return idVal === undefined ? url : `${url}/${idVal}`;
|
||||
},
|
||||
{
|
||||
injector: this.injector,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
listForDiscount(): HttpResourceRef<{ name: string; discount: number; discountLimit: number }[] | undefined> {
|
||||
|
||||
Reference in New Issue
Block a user