Mostly working with Product + Version and Sku + Version.
There will still be many errors. But this is working somewhat
This commit is contained in:
@@ -7,7 +7,7 @@ import { tap } from 'rxjs/operators';
|
||||
|
||||
import { BillViewItem } from '../core/bill-view-item';
|
||||
import { ModifierCategory } from '../core/modifier-category';
|
||||
import { Product } from '../core/product';
|
||||
import { StockKeepingUnit } from '../core/stock-keeping-unit';
|
||||
import { ReceivePaymentItem } from '../core/receive-payment-item';
|
||||
import { SaleCategory } from '../core/sale-category';
|
||||
import { Table } from '../core/table';
|
||||
@@ -80,10 +80,10 @@ export class BillService {
|
||||
id: i.id,
|
||||
kotId: k.id,
|
||||
isKot: false,
|
||||
productId: i.product.id,
|
||||
skuId: i.sku.id,
|
||||
isHappyHour: i.isHappyHour,
|
||||
isPrinted: !!k.id,
|
||||
info: `${i.product.name} @ ${i.price} - ${this.math.halfRoundEven(i.discount * 100, 2)}%`,
|
||||
info: `${i.sku.name} @ ${i.price} - ${this.math.halfRoundEven(i.discount * 100, 2)}%`,
|
||||
quantity: i.quantity,
|
||||
modifiers: i.modifiers,
|
||||
}),
|
||||
@@ -101,22 +101,22 @@ export class BillService {
|
||||
this.displayBill();
|
||||
}
|
||||
|
||||
minimum(productId: string, happyHour: boolean): number {
|
||||
minimum(skuId: string, happyHour: boolean): number {
|
||||
return this.bill.kots.reduce(
|
||||
(t, k) =>
|
||||
k.inventories.reduce(
|
||||
(a, c) => (c.product.id === productId && c.isHappyHour === happyHour ? a + c.quantity : a),
|
||||
(a, c) => (c.sku.id === skuId && c.isHappyHour === happyHour ? a + c.quantity : a),
|
||||
0,
|
||||
) + t,
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
addProduct(product: Product, quantity: number, discount: number): void {
|
||||
addSku(sku: StockKeepingUnit, quantity: number, discount: number): void {
|
||||
const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot;
|
||||
const old = newKot.inventories.find((x) => x.product.id === product.id && x.isHappyHour === product.hasHappyHour);
|
||||
const old = newKot.inventories.find((x) => x.sku.id === sku.id && x.isHappyHour === sku.hasHappyHour);
|
||||
if (quantity < 0) {
|
||||
const minimum = this.minimum(product.id as string, product.hasHappyHour) + quantity;
|
||||
const minimum = this.minimum(sku.id as string, sku.hasHappyHour) + quantity;
|
||||
if (minimum + quantity < 0) {
|
||||
this.snackBar.open('Total quantity cannot be negative!', 'Error');
|
||||
return;
|
||||
@@ -126,17 +126,17 @@ export class BillService {
|
||||
old.quantity += quantity;
|
||||
} else {
|
||||
const item = new Inventory({
|
||||
product,
|
||||
sku,
|
||||
quantity,
|
||||
price: product.price,
|
||||
isHappyHour: product.hasHappyHour,
|
||||
taxRate: product.tax.rate,
|
||||
tax: product.tax,
|
||||
price: sku.price,
|
||||
isHappyHour: sku.hasHappyHour,
|
||||
taxRate: sku.tax.rate,
|
||||
tax: sku.tax,
|
||||
discount,
|
||||
modifiers: [],
|
||||
});
|
||||
newKot.inventories.push(item);
|
||||
this.modifierCategoryService.listForProduct(product.id as string).subscribe((result) => {
|
||||
this.modifierCategoryService.listForSku(sku.id as string).subscribe((result) => {
|
||||
if (result.reduce((a: number, c: ModifierCategory) => a + c.minimum, 0)) {
|
||||
this.showModifier(item);
|
||||
}
|
||||
@@ -155,7 +155,7 @@ export class BillService {
|
||||
maxWidth: 'none',
|
||||
maxHeight: 'none',
|
||||
data: {
|
||||
list: this.modifierCategoryService.listForProduct(item.product.id as string),
|
||||
list: this.modifierCategoryService.listForSku(item.sku.id as string),
|
||||
selected: Object.assign([], item.modifiers),
|
||||
},
|
||||
});
|
||||
@@ -171,7 +171,7 @@ export class BillService {
|
||||
addOne(item: BillViewItem): void {
|
||||
const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot;
|
||||
const old = newKot.inventories.find(
|
||||
(x) => x.product.id === item.productId && x.isHappyHour === item.isHappyHour,
|
||||
(x) => x.sku.id === item.skuId && x.isHappyHour === item.isHappyHour,
|
||||
) as Inventory;
|
||||
old.quantity += 1;
|
||||
this.displayBill();
|
||||
@@ -180,7 +180,7 @@ export class BillService {
|
||||
quantity(item: BillViewItem, quantity: number): void {
|
||||
const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot;
|
||||
const old = newKot.inventories.find(
|
||||
(x) => x.product.id === item.productId && x.isHappyHour === item.isHappyHour,
|
||||
(x) => x.sku.id === item.skuId && x.isHappyHour === item.isHappyHour,
|
||||
) as Inventory;
|
||||
old.quantity = quantity;
|
||||
this.displayBill();
|
||||
@@ -189,9 +189,9 @@ export class BillService {
|
||||
subtractOne(item: BillViewItem, canEdit: boolean): void {
|
||||
const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot;
|
||||
const old = newKot.inventories.find(
|
||||
(x) => x.product.id === item.productId && x.isHappyHour === item.isHappyHour,
|
||||
(x) => x.sku.id === item.skuId && x.isHappyHour === item.isHappyHour,
|
||||
) as Inventory;
|
||||
if (item.quantity >= 1 || (canEdit && this.minimum(item.productId as string, item.isHappyHour) >= 1)) {
|
||||
if (item.quantity >= 1 || (canEdit && this.minimum(item.skuId as string, item.isHappyHour) >= 1)) {
|
||||
old.quantity -= 1;
|
||||
} else if (item.quantity === 0) {
|
||||
newKot.inventories.splice(newKot.inventories.indexOf(old), 1);
|
||||
@@ -202,7 +202,7 @@ export class BillService {
|
||||
removeItem(item: BillViewItem): void {
|
||||
const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot;
|
||||
const old = newKot.inventories.find(
|
||||
(x) => x.product.id === item.productId && x.isHappyHour === item.isHappyHour,
|
||||
(x) => x.sku.id === item.skuId && x.isHappyHour === item.isHappyHour,
|
||||
) as Inventory;
|
||||
newKot.inventories.splice(newKot.inventories.indexOf(old), 1);
|
||||
this.displayBill();
|
||||
@@ -211,17 +211,17 @@ export class BillService {
|
||||
modifier(item: BillViewItem): void {
|
||||
const newKot = this.bill.kots.find((k) => k.id === undefined) as Kot;
|
||||
const old = newKot.inventories.find(
|
||||
(x) => x.product.id === item.productId && x.isHappyHour === item.isHappyHour,
|
||||
(x) => x.sku.id === item.skuId && x.isHappyHour === item.isHappyHour,
|
||||
) as Inventory;
|
||||
this.showModifier(old);
|
||||
}
|
||||
|
||||
discount(discounts: { id: string; name: string; discount: number }[]): void {
|
||||
for (const kot of this.bill.kots) {
|
||||
const noDiscount = kot.inventories.filter((x) => x.isHappyHour).map((x) => x.product.id as string);
|
||||
const noDiscount = kot.inventories.filter((x) => x.isHappyHour).map((x) => x.sku.id as string);
|
||||
for (const inventory of kot.inventories) {
|
||||
const e = discounts.find((d) => d.id === (inventory.product.saleCategory as SaleCategory).id);
|
||||
if (e === undefined || noDiscount.indexOf(inventory.product.id as string) !== -1) {
|
||||
const e = discounts.find((d) => d.id === (inventory.sku.saleCategory as SaleCategory).id);
|
||||
if (e === undefined || noDiscount.indexOf(inventory.sku.id as string) !== -1) {
|
||||
continue;
|
||||
}
|
||||
inventory.discount = e.discount;
|
||||
@@ -264,11 +264,11 @@ export class BillService {
|
||||
|
||||
printBill(guestBookId: string | null, voucherType: VoucherType): Observable<boolean> {
|
||||
const item = JSON.parse(JSON.stringify(this.bill));
|
||||
const products = item.kots.reduce(
|
||||
const skus = item.kots.reduce(
|
||||
(p: number, k: Kot) => p + k.inventories.filter((i) => i.quantity !== 0).length,
|
||||
0,
|
||||
);
|
||||
if (products === 0) {
|
||||
if (skus === 0) {
|
||||
return throwError(() => Error('Cannot print a blank Bill\nPlease add some products!'));
|
||||
}
|
||||
if (!this.happyHourItemsBalanced() || this.happyHourItemsMoreThanRegular()) {
|
||||
@@ -364,7 +364,7 @@ export class BillService {
|
||||
const data: { move: string[]; keep: string[] } = { move: [], keep: [] };
|
||||
for (const kot of this.bill.kots) {
|
||||
for (const inv of kot.inventories) {
|
||||
if (saleCategories.indexOf(inv.product.saleCategory?.id as string) === -1) {
|
||||
if (saleCategories.indexOf(inv.sku.saleCategory?.id as string) === -1) {
|
||||
data.keep.push(inv.id as string);
|
||||
} else {
|
||||
data.move.push(inv.id as string);
|
||||
@@ -378,10 +378,10 @@ export class BillService {
|
||||
for (const kot of this.bill.kots) {
|
||||
const happyHourItems = kot.inventories
|
||||
.filter((x) => x.isHappyHour)
|
||||
.map((x) => ({ id: x.product.id as string, quantity: x.quantity }));
|
||||
.map((x) => ({ id: x.sku.id as string, quantity: x.quantity }));
|
||||
for (const item of happyHourItems) {
|
||||
const q = kot.inventories.find(
|
||||
(x) => !x.isHappyHour && x.product.id === item.id && x.quantity === item.quantity,
|
||||
(x) => !x.isHappyHour && x.sku.id === item.id && x.quantity === item.quantity,
|
||||
);
|
||||
if (q === undefined) {
|
||||
return false;
|
||||
@@ -397,7 +397,7 @@ export class BillService {
|
||||
const invs: Record<string, { normal: number; happy: number }> = {};
|
||||
for (const kot of this.bill.kots) {
|
||||
for (const inventory of kot.inventories) {
|
||||
const pid = inventory.product.id as string;
|
||||
const pid = inventory.sku.id as string;
|
||||
if (invs[pid] === undefined) {
|
||||
invs[pid] = { normal: 0, happy: 0 };
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
export class BillSelectionItem {
|
||||
kotId?: string;
|
||||
inventoryId?: string;
|
||||
productId: string;
|
||||
skuId: string;
|
||||
isHappyHour: boolean;
|
||||
|
||||
public constructor(init?: Partial<BillSelectionItem>) {
|
||||
this.kotId = undefined;
|
||||
this.inventoryId = undefined;
|
||||
this.productId = '';
|
||||
this.skuId = '';
|
||||
this.isHappyHour = false;
|
||||
Object.assign(this, init);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<h2>Bill</h2>
|
||||
|
||||
<table mat-table #table [dataSource]="dataSource" class="mat-elevation-z8" [trackBy]="trackByKotProductId">
|
||||
<table mat-table #table [dataSource]="dataSource" class="mat-elevation-z8" [trackBy]="trackByKotskuId">
|
||||
<ng-container matColumnDef="bill-no-title">
|
||||
<mat-header-cell *matHeaderCellDef class="deep-purple-200 bold">Bill / KOT number</mat-header-cell>
|
||||
</ng-container>
|
||||
|
||||
@@ -112,7 +112,7 @@ export class BillsComponent implements OnInit {
|
||||
new BillSelectionItem({
|
||||
kotId: kot.id,
|
||||
inventoryId: c.id,
|
||||
productId: c.product.id,
|
||||
skuId: c.sku.id,
|
||||
isHappyHour: c.isHappyHour,
|
||||
}),
|
||||
),
|
||||
@@ -126,7 +126,7 @@ export class BillsComponent implements OnInit {
|
||||
new BillSelectionItem({
|
||||
kotId: invView.kotId,
|
||||
inventoryId: invView.id,
|
||||
productId: invView.productId,
|
||||
skuId: invView.skuId,
|
||||
isHappyHour: invView.isHappyHour,
|
||||
}),
|
||||
);
|
||||
@@ -138,7 +138,7 @@ export class BillsComponent implements OnInit {
|
||||
new BillSelectionItem({
|
||||
kotId: invView.kotId,
|
||||
inventoryId: invView.id,
|
||||
productId: invView.productId,
|
||||
skuId: invView.skuId,
|
||||
isHappyHour: invView.isHappyHour,
|
||||
}),
|
||||
);
|
||||
@@ -154,7 +154,7 @@ export class BillsComponent implements OnInit {
|
||||
new BillSelectionItem({
|
||||
kotId: kot.id,
|
||||
inventoryId: item.id,
|
||||
productId: item.product.id,
|
||||
skuId: item.sku.id,
|
||||
isHappyHour: item.isHappyHour,
|
||||
}),
|
||||
);
|
||||
@@ -174,7 +174,7 @@ export class BillsComponent implements OnInit {
|
||||
new BillSelectionItem({
|
||||
kotId: kot.id,
|
||||
inventoryId: item.id,
|
||||
productId: item.product.id,
|
||||
skuId: item.sku.id,
|
||||
isHappyHour: item.isHappyHour,
|
||||
}),
|
||||
);
|
||||
@@ -186,11 +186,11 @@ export class BillsComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
trackByKotProductId(index: number, row: BillViewItem): string {
|
||||
trackByKotskuId(index: number, row: BillViewItem): string {
|
||||
// Fallbacks in case fields are undefined/null
|
||||
const kotId = row.kotId ?? '';
|
||||
const productId = row.productId ?? '';
|
||||
return `${kotId}_${productId}`;
|
||||
const skuId = row.skuId ?? '';
|
||||
return `${kotId}_${skuId}`;
|
||||
}
|
||||
|
||||
addOne(item: BillViewItem): void {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Modifier } from '../../core/modifier';
|
||||
import { Product } from '../../core/product';
|
||||
import { StockKeepingUnit as Product } from '../../core/stock-keeping-unit';
|
||||
import { Tax } from '../../core/tax';
|
||||
|
||||
export class Inventory {
|
||||
id: string | undefined;
|
||||
product: Product;
|
||||
sku: Product;
|
||||
quantity: number;
|
||||
price: number;
|
||||
isHappyHour: boolean;
|
||||
@@ -16,7 +16,7 @@ export class Inventory {
|
||||
|
||||
public constructor(init?: Partial<Inventory>) {
|
||||
this.id = undefined;
|
||||
this.product = new Product();
|
||||
this.sku = new Product();
|
||||
this.quantity = 0;
|
||||
this.price = 0;
|
||||
this.isHappyHour = false;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { MenuCategory } from './menu-category';
|
||||
import { SaleCategory } from './sale-category';
|
||||
import { Tax } from './tax';
|
||||
|
||||
export class Product {
|
||||
id: string | undefined;
|
||||
versionId?: string;
|
||||
name: string;
|
||||
units: string;
|
||||
menuCategory?: MenuCategory;
|
||||
saleCategory?: SaleCategory;
|
||||
price: number;
|
||||
hasHappyHour: boolean;
|
||||
isNotAvailable: boolean;
|
||||
quantity: number;
|
||||
isActive: boolean;
|
||||
sortOrder: number;
|
||||
|
||||
enabled: boolean;
|
||||
tax: Tax;
|
||||
|
||||
validFrom: string | null;
|
||||
validTill: string | null;
|
||||
|
||||
public constructor(init?: Partial<Product>) {
|
||||
this.id = undefined;
|
||||
this.name = '';
|
||||
this.units = '';
|
||||
this.price = 0;
|
||||
this.hasHappyHour = false;
|
||||
this.isNotAvailable = false;
|
||||
this.quantity = 0;
|
||||
this.isActive = true;
|
||||
this.sortOrder = 0;
|
||||
this.enabled = true;
|
||||
this.validFrom = null;
|
||||
this.validTill = null;
|
||||
this.tax = new Tax();
|
||||
Object.assign(this, init);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
<mat-card
|
||||
class="flex-col square-button"
|
||||
matRipple
|
||||
(click)="addProduct(item)"
|
||||
(click)="addSku(item)"
|
||||
[class.accent]="item.hasHappyHour"
|
||||
[class.disabled]="item.isNotAvailable"
|
||||
[class.primary]="!item.hasHappyHour && !item.isNotAvailable"
|
||||
|
||||
@@ -4,7 +4,7 @@ import { MatCardModule } from '@angular/material/card';
|
||||
import { MatRippleModule } from '@angular/material/core';
|
||||
import { ActivatedRoute, RouterLink } from '@angular/router';
|
||||
|
||||
import { Product } from '../../core/product';
|
||||
import { StockKeepingUnit as Product } from '../../core/stock-keeping-unit';
|
||||
import { BillService } from '../bill.service';
|
||||
|
||||
@Component({
|
||||
@@ -26,10 +26,10 @@ export class ProductsComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
addProduct(product: Product): void {
|
||||
addSku(product: Product): void {
|
||||
if (product.isNotAvailable) {
|
||||
return;
|
||||
}
|
||||
this.bs.addProduct(product, 1, 0);
|
||||
this.bs.addSku(product, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { ResolveFn } from '@angular/router';
|
||||
|
||||
import { Product } from '../../core/product';
|
||||
import { StockKeepingUnit as Product } from '../../core/stock-keeping-unit';
|
||||
import { ProductService } from '../../product/product.service';
|
||||
|
||||
export const productsResolver: ResolveFn<Product[]> = (route) => {
|
||||
|
||||
Reference in New Issue
Block a user