Updated to angular 11

Now compiling with strict mode in typescript
Need to error checking now
This commit is contained in:
2020-11-22 10:13:37 +05:30
parent cabd6f2ea1
commit 6567f560ab
187 changed files with 1709 additions and 1184 deletions

View File

@ -3,8 +3,8 @@
fxLayout="column"
class="square-button"
matRipple
(click)="select('REGULAR_BILL')"
[class.selected]="selected == 'REGULAR_BILL'"
(click)="selectRegularBill()"
[class.selected]="selectRegularBill()"
>
<h3 class="item-name">Regular</h3>
</mat-card>
@ -12,8 +12,8 @@
fxLayout="column"
class="square-button"
matRipple
(click)="select('STAFF')"
[class.selected]="selected == 'STAFF'"
(click)="selectStaff()"
[class.selected]="selectedStaff()"
>
<h3 class="item-name">Staff</h3>
</mat-card>
@ -21,8 +21,8 @@
fxLayout="column"
class="square-button"
matRipple
(click)="select('NO_CHARGE')"
[class.selected]="selected == 'NO_CHARGE'"
(click)="selectNoCharge()"
[class.selected]="selectedNoCharge()"
>
<h3 class="item-name">No Charge</h3>
</mat-card>

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { BillTypeComponent } from './bill-type.component';
@ -6,11 +6,13 @@ describe('BillTypeComponent', () => {
let component: BillTypeComponent;
let fixture: ComponentFixture<BillTypeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [BillTypeComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [BillTypeComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(BillTypeComponent);

View File

@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { PrintType } from '../bills/print-type';
import { VoucherType } from '../bills/voucher-type';
@Component({
selector: 'app-bill-type',
@ -9,17 +9,38 @@ import { PrintType } from '../bills/print-type';
styleUrls: ['./bill-type.component.css'],
})
export class BillTypeComponent {
selected: string;
selected: VoucherType | null;
constructor(public dialogRef: MatDialogRef<BillTypeComponent>) {
this.selected = null;
}
select(s: string) {
this.selected = s;
selectRegularBill() {
this.selected = VoucherType.Bill;
}
selectedRegularBill() {
return this.selected === VoucherType.Bill;
}
selectStaff() {
this.selected = VoucherType.Staff;
}
selectedStaff() {
return this.selected === VoucherType.Staff;
}
selectNoCharge() {
this.selected = VoucherType.NoCharge;
}
selectedNoCharge() {
return this.selected === VoucherType.NoCharge;
}
accept(): void {
this.dialogRef.close(PrintType[this.selected]);
if (this.selected === null) this.dialogRef.close();
else this.dialogRef.close(this.selected);
}
}

View File

@ -5,6 +5,7 @@ import * as math from 'mathjs';
import { BehaviorSubject } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { BillViewItem } from '../core/bill-view-item';
import { ModifierCategory } from '../core/modifier-category';
import { Product } from '../core/product';
import { Table } from '../core/table';
@ -14,7 +15,7 @@ import { ModifierCategoryService } from '../modifier-categories/modifier-categor
import { Bill } from './bills/bill';
import { Inventory } from './bills/inventory';
import { Kot } from './bills/kot';
import { PrintType } from './bills/print-type';
import { VoucherType } from './bills/voucher-type';
import { VoucherService } from './bills/voucher.service';
import { ModifiersComponent } from './modifiers/modifiers.component';
@ -22,7 +23,7 @@ import { ModifiersComponent } from './modifiers/modifiers.component';
export class BillService {
public dataObs;
public data: any[];
public bill;
public bill: Bill = new Bill();
public netAmount: BehaviorSubject<number>;
public discountAmount: BehaviorSubject<number>;
public taxAmount: BehaviorSubject<number>;
@ -45,16 +46,16 @@ export class BillService {
loadData(bill: Bill): void {
this.bill = bill;
const view = this.bill.kots.map((k) => {
return [
{
id: k.id,
isKot: true,
oldKot: true,
info: `Kot: ${k.code} / ${k.date} (${k.user.name}) `,
},
...k.inventories.map((i) => {
return {
const view: BillViewItem[][] = this.bill.kots.map((k: Kot) => [
new BillViewItem({
id: k.id,
isKot: true,
oldKot: true,
info: `Kot: ${k.code} / ${k.date} (${k.user.name}) `,
}),
...k.inventories.map(
(i) =>
new BillViewItem({
id: i.id,
kotId: k.id,
isKot: false,
@ -69,10 +70,9 @@ export class BillService {
taxRate: i.taxRate,
tax: i.tax,
modifiers: i.modifiers,
};
}),
];
});
}),
),
]);
this.data = view.reduce((a, c) => a.concat(c), []);
this.data.push({ isKot: true, newKot: true, info: '== New Kot ==' });
this.dataObs.next(this.data);
@ -92,7 +92,7 @@ export class BillService {
!x.isKot && !x.id && x.productId === product.id && x.isHappyHour === product.hasHappyHour,
);
if (quantity < 0) {
const minimum = this.minimum(product.id, product.hasHappyHour) + quantity;
const minimum = this.minimum(product.id as string, product.hasHappyHour) + quantity;
if (minimum + quantity < 0) {
this.toaster.show('Error', 'Total quantity cannot be negative!');
return;
@ -115,7 +115,7 @@ export class BillService {
modifiers: [],
};
this.data.push(item);
this.modifierCategoryService.listForProduct(product.id).subscribe((result) => {
this.modifierCategoryService.listForProduct(product.id as string).subscribe((result) => {
if (
result.reduce((a: any, c: ModifierCategory) => {
return a + c.minimum;
@ -183,7 +183,12 @@ export class BillService {
discount(discounts: { id: string; name: string; discount: number }[]): void {
this.data.forEach((x) => {
if (!x.isKot) {
x.discount = discounts.find((d) => d.id === x.product.saleCategory.id).discount / 100;
x.discount =
(discounts.find((d) => d.id === x.product.saleCategory.id) as {
id: string;
name: string;
discount: number;
}).discount / 100;
x.info = `${x.product.name} @ ${x.price} - ${math.round(x.discount * 100, 2)}%`;
}
});
@ -211,25 +216,25 @@ export class BillService {
});
}
printKot(guest_book_id: string): Observable<boolean> {
printKot(guestBookId: string | null): Observable<boolean> {
const item = JSON.parse(JSON.stringify(this.bill));
const newKot = this.getKot();
if (newKot.inventories.length === 0) {
this.toaster.show('Error', 'Cannot print a blank KOT\nPlease add some products!');
}
item.kots.push(newKot);
return this.ser.saveOrUpdate(item, PrintType.Kot, guest_book_id, true);
return this.ser.saveOrUpdate(item, VoucherType.Kot, guestBookId, true);
}
printBill(guest_book_id: string, printType: PrintType): Observable<boolean> {
printBill(guest_book_id: string | null, voucherType: VoucherType): Observable<boolean> {
const item = JSON.parse(JSON.stringify(this.bill));
item.kots.forEach((k) => {
k.inventories.forEach((i) => {
item.kots.forEach((k: Kot) => {
k.inventories.forEach((i: Inventory) => {
i.discount = this.data.find((x) => !x.isKot && x.id === i.id).discount;
});
});
item.kots.push(this.getKot());
return this.ser.saveOrUpdate(item, printType, guest_book_id, true);
return this.ser.saveOrUpdate(item, voucherType, guest_book_id, true);
}
type() {
@ -240,27 +245,27 @@ export class BillService {
amounts: { id: number; name: string; amount: number }[],
name: string,
): Observable<boolean> {
return this.ser.receivePayment(this.bill.id, amounts, name, true);
return this.ser.receivePayment(this.bill.id as string, amounts, name, true);
}
moveTable(table: Table): Observable<boolean> {
return this.ser.moveTable(this.bill.id, table);
return this.ser.moveTable(this.bill.id as string, table);
}
mergeTable(table: Table): Observable<boolean> {
return this.ser.mergeTable(this.bill.id, table);
return this.ser.mergeTable(this.bill.id as string, table);
}
moveKot(kotId: string, table: Table): Observable<boolean> {
return this.ser.moveKotToNewTable(this.bill.id, kotId, table);
return this.ser.moveKotToNewTable(this.bill.id as string, kotId, table);
}
mergeKot(kotId: string, table: Table): Observable<boolean> {
return this.ser.mergeKotWithOldBill(this.bill.id, kotId, table);
return this.ser.mergeKotWithOldBill(this.bill.id as string, kotId, table);
}
voidBill(reason: string): Observable<boolean> {
return this.ser.voidBill(this.bill.id, reason, true);
return this.ser.voidBill(this.bill.id as string, reason, true);
}
updateAmounts() {
@ -323,6 +328,6 @@ export class BillService {
splitBill(table: Table): Observable<boolean> {
const inventoriesToMove: string[] = this.selection.selected.map((x: any) => x.id);
return this.ser.splitBill(this.bill.id, inventoriesToMove, table);
return this.ser.splitBill(this.bill.id as string, inventoriesToMove, table);
}
}

View File

@ -12,7 +12,7 @@ export class BillResolver implements Resolve<Bill> {
constructor(private ser: VoucherService) {}
resolve(route: ActivatedRouteSnapshot): Observable<Bill> {
const tableId = route.queryParamMap.get('table');
const tableId = route.queryParamMap.get('table') as string;
const guestId = route.queryParamMap.get('guest');
const voucherId = route.queryParamMap.get('voucher');
return this.ser.getFromTable(tableId, voucherId, guestId);

View File

@ -5,7 +5,7 @@ import { GuestBook } from '../../guest-book/guest-book';
import { Kot } from './kot';
export class Bill {
id: string;
id: string | undefined;
date: string;
pax: number;
customer?: { id: string; name: string };
@ -13,17 +13,45 @@ export class Bill {
creationDate: string;
lastEditDate: string;
billId: string;
kotId: string;
table: Table;
guest: GuestBook;
settlements: any[];
void: boolean;
voidReason: string;
voucherType: string;
serial: number;
kots: Kot[];
reprints: any[];
get dateTip(): string {
return this.date;
}
get creationDateTip(): string {
return this.date;
}
get lastEditDateTip(): string {
return this.date;
}
public constructor(init?: Partial<Bill>) {
this.id = undefined;
this.date = '';
this.pax = 0;
this.user = new User();
this.creationDate = '';
this.lastEditDate = '';
this.billId = '';
this.kotId = '';
this.table = new Table();
this.guest = new GuestBook();
this.settlements = [];
this.voidReason = '';
this.voucherType = '';
this.serial = 0;
this.kots = [];
this.reprints = [];
Object.assign(this, init);
}
}

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { BillsComponent } from './bills.component';
@ -6,11 +6,13 @@ describe('BillsComponent', () => {
let component: BillsComponent;
let fixture: ComponentFixture<BillsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [BillsComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [BillsComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(BillsComponent);

View File

@ -1,7 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable, throwError } from 'rxjs';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { AuthService } from '../../auth/auth.service';
@ -17,6 +17,7 @@ import { TablesDialogComponent } from '../tables-dialog/tables-dialog.component'
import { Bill } from './bill';
import { BillsDataSource } from './bills-datasource';
import { Kot } from './kot';
import { VoucherType } from './voucher-type';
@Component({
selector: 'app-bills',
@ -24,7 +25,7 @@ import { Kot } from './kot';
styleUrls: ['./bills.component.css'],
})
export class BillsComponent implements OnInit {
dataSource: BillsDataSource;
dataSource: BillsDataSource = new BillsDataSource(this.bs.dataObs);
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns: string[] = ['select', 'info', 'quantity'];
@ -39,7 +40,8 @@ export class BillsComponent implements OnInit {
) {}
ngOnInit() {
this.route.data.subscribe((data: { item: Bill }) => {
this.route.data.subscribe((value) => {
const data = value as { item: Bill };
this.bs.loadData(data.item);
});
this.getPax();
@ -122,7 +124,7 @@ export class BillsComponent implements OnInit {
}
subtractOne(item: any): void {
const canEdit = this.auth.user.perms.indexOf('edit-printed-product') !== -1;
const canEdit = this.auth.allowed('edit-printed-product');
this.bs.subtractOne(item, canEdit);
}
@ -134,14 +136,21 @@ export class BillsComponent implements OnInit {
this.bs.modifier(item);
}
confirmMoveKotDialog(table: Table): Observable<Table | Observable<never>> {
confirmMoveKotDialog(table: Table): Observable<Table> {
return this.dialog
.open(ConfirmDialogComponent, {
width: '250px',
data: { title: 'Move KOT?', content: 'Are you sure?' },
})
.afterClosed()
.pipe(map((x: boolean) => (x ? table : throwError('Please confirm move'))));
.pipe(
map((x: boolean) => {
if (!x) {
throw new Error('Please confirm move');
}
return table;
}),
);
}
chooseTable(allowMerge: boolean): Observable<Table> {
@ -154,11 +163,18 @@ export class BillsComponent implements OnInit {
},
})
.afterClosed()
.pipe(map((x) => x || throwError('Please choose a table')));
.pipe(
map((x: Table) => {
if (!x) {
throw new Error('Please choose a table');
}
return x;
}),
);
}
moveKot(kot: Kot) {
const canMergeTables = this.auth.user.perms.indexOf('merge-tables') !== -1;
const canMergeTables = this.auth.allowed('merge-tables');
this.chooseTable(canMergeTables)
.pipe(
switchMap((table: Table) => this.confirmMoveKotDialog(table)),
@ -170,9 +186,9 @@ export class BillsComponent implements OnInit {
return this.bs.moveTable(table);
}
if (table.status) {
return this.bs.mergeKot(kot.id, table);
return this.bs.mergeKot(kot.id as string, table);
}
return this.bs.moveKot(kot.id, table);
return this.bs.moveKot(kot.id as string, table);
}),
)
.subscribe(
@ -190,10 +206,10 @@ export class BillsComponent implements OnInit {
if (!row.isPrinted) {
return false;
}
if (this.bs.bill.isVoid) {
if (this.bs.bill.voucherType === VoucherType.Void) {
return true;
}
if (this.auth.user.perms.indexOf('edit-printed-product') === -1) {
if (!this.auth.allowed('edit-printed-product')) {
return true;
}
return false;

View File

@ -3,7 +3,7 @@ import { Product } from '../../core/product';
import { Tax } from '../../core/tax';
export class Inventory {
id: string;
id: string | undefined;
product: Product;
quantity: number;
price: number;
@ -15,6 +15,16 @@ export class Inventory {
sortOrder: number;
public constructor(init?: Partial<Inventory>) {
this.id = undefined;
this.product = new Product();
this.quantity = 0;
this.price = 0;
this.isHappyHour = false;
this.taxRate = 0;
this.tax = new Tax();
this.discount = 0;
this.modifiers = [];
this.sortOrder = 0;
Object.assign(this, init);
}
}

View File

@ -3,13 +3,18 @@ import { User } from '../../core/user';
import { Inventory } from './inventory';
export class Kot {
id: string;
id: string | undefined;
code: number;
date: string;
user: User;
inventories: Inventory[];
public constructor(init?: Partial<Kot>) {
this.id = undefined;
this.code = 0;
this.date = '';
this.user = new User();
this.inventories = [];
Object.assign(this, init);
}
}

View File

@ -1,6 +1,7 @@
export enum PrintType {
export enum VoucherType {
Kot = 'KOT',
Bill = 'REGULAR_BILL',
NoCharge = 'NO_CHARGE',
Staff = 'STAFF',
Void = 'VOID',
}

View File

@ -7,7 +7,7 @@ import { ErrorLoggerService } from '../../core/error-logger.service';
import { Table } from '../../core/table';
import { Bill } from './bill';
import { PrintType } from './print-type';
import { VoucherType } from './voucher-type';
const url = '/api/voucher';
const urlMoveTable = '/api/move-table';
@ -27,7 +27,11 @@ export class VoucherService {
);
}
getFromTable(tableId: string, voucherId: string, guestId: string): Observable<Bill> {
getFromTable(
tableId: string,
voucherId: string | null,
guestId: string | null,
): Observable<Bill> {
let params = new HttpParams();
if (voucherId !== null) {
params = params.set('v', voucherId);
@ -50,15 +54,15 @@ export class VoucherService {
save(
voucher: Bill,
printType: PrintType,
guest_book_id: string,
voucherType: VoucherType,
guestBookId: string | null,
updateTable: boolean,
): Observable<boolean> {
const options = {
params: new HttpParams().set('p', printType).set('u', updateTable.toString()),
params: new HttpParams().set('p', voucherType).set('u', updateTable.toString()),
};
if (guest_book_id !== null) {
options.params = options.params.set('g', guest_book_id);
if (guestBookId !== null) {
options.params = options.params.set('g', guestBookId);
}
return <Observable<boolean>>(
this.http
@ -69,15 +73,15 @@ export class VoucherService {
update(
voucher: Bill,
printType: PrintType,
guest_book_id: string,
voucherType: VoucherType,
guestBookId: string | null,
updateTable: boolean,
): Observable<boolean> {
const options = {
params: new HttpParams().set('p', printType).set('u', updateTable.toString()),
params: new HttpParams().set('p', voucherType).set('u', updateTable.toString()),
};
if (guest_book_id !== null) {
options.params = options.params.set('g', guest_book_id);
if (guestBookId !== null) {
options.params = options.params.set('g', guestBookId);
}
return <Observable<boolean>>(
this.http
@ -88,13 +92,13 @@ export class VoucherService {
change(
voucher: Bill,
printType: PrintType,
guest_book_id: string,
voucherType: VoucherType,
guestBookId: string | null,
updateTable: boolean,
): Observable<boolean> {
const options = { params: new HttpParams().set('u', updateTable.toString()) };
if (guest_book_id !== null) {
options.params = options.params.set('g', guest_book_id);
if (guestBookId !== null) {
options.params = options.params.set('g', guestBookId);
}
return <Observable<boolean>>(
this.http
@ -105,17 +109,17 @@ export class VoucherService {
saveOrUpdate(
voucher: Bill,
printType: PrintType,
guest_book_id: string,
voucherType: VoucherType,
guestBookId: string | null,
updateTable: boolean,
): Observable<boolean> {
if (!voucher.id) {
return this.save(voucher, printType, guest_book_id, updateTable);
return this.save(voucher, voucherType, guestBookId, updateTable);
}
if (voucher.voucherType === PrintType.Kot) {
return this.update(voucher, printType, guest_book_id, updateTable);
if (voucher.voucherType === VoucherType.Kot) {
return this.update(voucher, voucherType, guestBookId, updateTable);
}
return this.change(voucher, printType, guest_book_id, updateTable);
return this.change(voucher, voucherType, guestBookId, updateTable);
}
receivePayment(

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { DiscountComponent } from './discount.component';
@ -6,11 +6,13 @@ describe('DiscountComponent', () => {
let component: DiscountComponent;
let fixture: ComponentFixture<DiscountComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DiscountComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [DiscountComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(DiscountComponent);

View File

@ -11,9 +11,9 @@ import { DiscountDataSource } from './discount-datasource';
styleUrls: ['./discount.component.css'],
})
export class DiscountComponent {
list: any[];
list: any[] = [];
form: FormGroup;
dataSource: DiscountDataSource;
dataSource: DiscountDataSource = new DiscountDataSource([]);
displayedColumns = ['name', 'discount'];
@ -22,7 +22,9 @@ export class DiscountComponent {
private fb: FormBuilder,
@Inject(MAT_DIALOG_DATA) public data: Observable<any[]>,
) {
this.createForm();
this.form = this.fb.group({
discounts: '',
});
this.data.subscribe((list: any[]) => {
this.list = list;
this.form.setControl(
@ -40,12 +42,6 @@ export class DiscountComponent {
});
}
createForm() {
this.form = this.fb.group({
discounts: '',
});
}
accept(): void {
const array = this.form.get('discounts') as FormArray;
this.list.forEach((item, index) => {

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { SalesHomeComponent } from './sales-home.component';
@ -6,11 +6,13 @@ describe('SalesHomeComponent', () => {
let component: SalesHomeComponent;
let fixture: ComponentFixture<SalesHomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SalesHomeComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [SalesHomeComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(SalesHomeComponent);

View File

@ -5,6 +5,7 @@ import { Observable, of as observableOf, throwError } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';
import { AuthService } from '../../auth/auth.service';
import { ReceivePaymentList } from '../../core/receive-payment-list';
import { Table } from '../../core/table';
import { ToasterService } from '../../core/toaster.service';
import { SaleCategoryService } from '../../sale-category/sale-category.service';
@ -12,7 +13,7 @@ import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dial
import { TableService } from '../../tables/table.service';
import { BillTypeComponent } from '../bill-type/bill-type.component';
import { BillService } from '../bill.service';
import { PrintType } from '../bills/print-type';
import { VoucherType } from '../bills/voucher-type';
import { DiscountComponent } from '../discount/discount.component';
import { ReasonComponent } from '../reason/reason.component';
import { ReceivePaymentComponent } from '../receive-payment/receive-payment.component';
@ -36,16 +37,13 @@ export class SalesHomeComponent {
) {}
printKotAllowed(): boolean {
if (this.auth.user && this.auth.user.perms.indexOf('print-kot') === -1) {
if (!this.auth.allowed('print-kot')) {
return false;
}
if (!this.bs.bill.id) {
return true;
}
if (this.bs.bill.voucherType !== PrintType.Kot) {
return false;
}
if (this.bs.bill.isVoid) {
if (this.bs.bill.voucherType !== VoucherType.Kot) {
return false;
}
return true;
@ -71,7 +69,7 @@ export class SalesHomeComponent {
}
discountAllowed(): boolean {
return this.auth.user && this.auth.user.perms.indexOf('discount') !== -1;
return this.auth.allowed('discount');
}
showDiscount(): Observable<boolean | { id: string; name: string; discount: number }[]> {
@ -96,7 +94,7 @@ export class SalesHomeComponent {
}
billTypeDialog() {
if (this.bs.bill.voucherType !== PrintType.Kot) {
if (this.bs.bill.voucherType !== VoucherType.Kot) {
return observableOf(this.bs.bill.voucherType);
}
return this.dialog.open(BillTypeComponent).afterClosed();
@ -123,19 +121,16 @@ export class SalesHomeComponent {
}
printBillAllowed(): boolean {
if (this.auth.user && this.auth.user.perms.indexOf('print-bill') === -1) {
if (!this.auth.allowed('print-bill')) {
return false;
}
if (!this.bs.bill.id) {
return true;
}
if (
this.bs.bill.voucherType !== PrintType.Kot &&
this.auth.user.perms.indexOf('edit-printed-bill') === -1
) {
if (this.bs.bill.voucherType !== VoucherType.Kot && !this.auth.allowed('edit-printed-bill')) {
return false;
}
if (this.bs.bill.isVoid) {
if (this.bs.bill.voucherType === VoucherType.Void) {
return false;
}
return true;
@ -145,7 +140,7 @@ export class SalesHomeComponent {
if (!this.printBillAllowed()) {
return;
}
let guestBookId = null;
let guestBookId: string | null = null;
if (this.route.snapshot.queryParamMap.has('guest')) {
guestBookId = this.route.snapshot.queryParamMap.get('guest');
}
@ -163,7 +158,7 @@ export class SalesHomeComponent {
}
return throwError('No Bill Type Chosen');
}),
switchMap((x: PrintType) => this.bs.printBill(guestBookId, x as PrintType)),
switchMap((x: VoucherType) => this.bs.printBill(guestBookId, x as VoucherType)),
)
.subscribe(
() => {
@ -177,23 +172,23 @@ export class SalesHomeComponent {
}
receivePaymentAllowed(): boolean {
if (this.auth.user && this.auth.user.perms.indexOf('settle-bill') === -1) {
if (!this.auth.allowed('settle-bill')) {
return false;
}
if (!this.bs.bill.id) {
return false;
}
if (this.bs.bill.voucherType === PrintType.Kot) {
if (this.bs.bill.voucherType === VoucherType.Kot) {
return false;
}
if (this.bs.bill.isVoid) {
if (this.bs.bill.voucherType === VoucherType.Void) {
return false;
}
return true;
}
receivePaymentWithReason(type: string, amount: number): Observable<boolean> {
const types = {
const types: ReceivePaymentList = {
NO_CHARGE: [
{
id: 4,
@ -267,12 +262,7 @@ export class SalesHomeComponent {
}
moveTableAllowed(): boolean {
// TODO: Check if this condition should be "and" or "or"
if (
this.auth.user &&
this.auth.user.perms.indexOf('move-table') === -1 &&
this.auth.user.perms.indexOf('merge-tables') === -1
) {
if (!this.auth.allowed('move-table') && !this.auth.allowed('merge-tables')) {
return false;
}
if (!this.bs.bill.id) {
@ -285,7 +275,7 @@ export class SalesHomeComponent {
if (!this.moveTableAllowed()) {
return;
}
const canMergeTables = this.auth.user.perms.indexOf('merge-tables') !== -1;
const canMergeTables = this.auth.allowed('merge-tables');
this.dialog
.open(TablesDialogComponent, {
// width: '750px',
@ -325,7 +315,7 @@ export class SalesHomeComponent {
}
voidBillAllowed(): boolean {
if (this.auth.user && this.auth.user.perms.indexOf('void-bill') === -1) {
if (!this.auth.allowed('void-bill')) {
return false;
}
if (!this.bs.bill.id) {
@ -381,7 +371,7 @@ export class SalesHomeComponent {
}
splitBillAllowed(): boolean {
if (this.auth.user && this.auth.user.perms.indexOf('split-bill') === -1) {
if (!this.auth.allowed('split-bill')) {
return false;
}
if (!this.bs.bill.id) {

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MenuCategoriesComponent } from './menu-categories.component';
@ -6,11 +6,13 @@ describe('MenuCategoriesComponent', () => {
let component: MenuCategoriesComponent;
let fixture: ComponentFixture<MenuCategoriesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MenuCategoriesComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [MenuCategoriesComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(MenuCategoriesComponent);

View File

@ -9,12 +9,13 @@ import { MenuCategory } from '../../core/menu-category';
styleUrls: ['./menu-categories.component.css'],
})
export class MenuCategoriesComponent implements OnInit {
list: MenuCategory[];
list: MenuCategory[] = [];
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.data.subscribe((data: { list: MenuCategory[] }) => {
this.route.data.subscribe((value) => {
const data = value as { list: MenuCategory[] };
this.list = data.list;
});
}

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ModifiersComponent } from './modifiers.component';
@ -6,11 +6,13 @@ describe('ModifiersComponent', () => {
let component: ModifiersComponent;
let fixture: ComponentFixture<ModifiersComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ModifiersComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ModifiersComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(ModifiersComponent);

View File

@ -11,9 +11,9 @@ import { ModifierCategory } from '../../core/modifier-category';
styleUrls: ['./modifiers.component.css'],
})
export class ModifiersComponent {
list: ModifierCategory[];
list: ModifierCategory[] = [];
selected: Modifier[];
selectedIds: string[];
selectedIds: (string | undefined)[];
constructor(
@Inject(MAT_DIALOG_DATA)

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { PaxComponent } from './pax.component';
@ -6,11 +6,13 @@ describe('PaxComponent', () => {
let component: PaxComponent;
let fixture: ComponentFixture<PaxComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [PaxComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [PaxComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(PaxComponent);

View File

@ -15,7 +15,10 @@ export class PaxComponent implements OnInit {
@Inject(MAT_DIALOG_DATA) public data: number,
private fb: FormBuilder,
) {
this.createForm();
// Create form
this.form = this.fb.group({
pax: '',
});
}
ngOnInit() {
@ -24,12 +27,6 @@ export class PaxComponent implements OnInit {
});
}
createForm() {
this.form = this.fb.group({
pax: '',
});
}
accept(): void {
const { pax } = this.form.value;
this.dialogRef.close(pax);

View File

@ -12,7 +12,7 @@ export class ProductsResolver implements Resolve<Product[]> {
constructor(private ser: ProductService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot): Observable<Product[]> {
const id = route.paramMap.get('id');
const id = route.paramMap.get('id') as string;
return this.ser.listIsActiveOfCategory(id);
}
}

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ProductsComponent } from './products.component';
@ -6,11 +6,13 @@ describe('ProductsComponent', () => {
let component: ProductsComponent;
let fixture: ComponentFixture<ProductsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ProductsComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ProductsComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(ProductsComponent);

View File

@ -10,12 +10,13 @@ import { BillService } from '../bill.service';
styleUrls: ['./products.component.css'],
})
export class ProductsComponent implements OnInit {
list: Product[];
list: Product[] = [];
constructor(private route: ActivatedRoute, private bs: BillService) {}
ngOnInit() {
this.route.data.subscribe((data: { list: Product[] }) => {
this.route.data.subscribe((value) => {
const data = value as { list: Product[] };
this.list = data.list;
});
}

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { QuantityComponent } from './quantity.component';
@ -6,11 +6,13 @@ describe('QuantityComponent', () => {
let component: QuantityComponent;
let fixture: ComponentFixture<QuantityComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [QuantityComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [QuantityComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(QuantityComponent);

View File

@ -18,7 +18,10 @@ export class QuantityComponent implements OnInit {
private fb: FormBuilder,
private math: MathService,
) {
this.createForm();
// Create form
this.form = this.fb.group({
quantity: '',
});
}
ngOnInit() {
@ -27,12 +30,6 @@ export class QuantityComponent implements OnInit {
});
}
createForm() {
this.form = this.fb.group({
quantity: '',
});
}
accept(): void {
const quantity = this.math.parseAmount(this.form.value.quantity);
this.dialogRef.close(quantity);

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ReasonComponent } from './reason.component';
@ -6,11 +6,13 @@ describe('VoidReasonComponent', () => {
let component: ReasonComponent;
let fixture: ComponentFixture<ReasonComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ReasonComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ReasonComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(ReasonComponent);

View File

@ -10,11 +10,11 @@ import { ReasonDatasource } from './reason-datasource';
styleUrls: ['./reason.component.css'],
})
export class ReasonComponent {
@ViewChild('son', { static: true }) son: ElementRef;
@ViewChild('son', { static: true }) son?: ElementRef;
form: FormGroup;
dataSource: ReasonDatasource;
title: string;
selected: string;
selected = '';
reasons: string[];
displayedColumns = ['reason'];

View File

@ -1,12 +1,14 @@
import { DataSource } from '@angular/cdk/collections';
import { Observable, of as observableOf } from 'rxjs';
export class ReceivePaymentDatasource extends DataSource<{ name: string; discount: number }> {
constructor(private data: { name: string; discount: number }[]) {
import { ReceivePaymentItem } from '../../core/receive-payment-item';
export class ReceivePaymentDatasource extends DataSource<ReceivePaymentItem> {
constructor(private data: ReceivePaymentItem[]) {
super();
}
connect(): Observable<{ name: string; discount: number }[]> {
connect(): Observable<ReceivePaymentItem[]> {
return observableOf(this.data);
}

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ReceivePaymentComponent } from './receive-payment.component';
@ -6,11 +6,13 @@ describe('ReceivePaymentComponent', () => {
let component: ReceivePaymentComponent;
let fixture: ComponentFixture<ReceivePaymentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ReceivePaymentComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ReceivePaymentComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(ReceivePaymentComponent);

View File

@ -3,7 +3,9 @@ import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { distinctUntilChanged } from 'rxjs/operators';
import { PrintType } from '../bills/print-type';
import { ReceivePaymentItem } from '../../core/receive-payment-item';
import { ReceivePaymentList } from '../../core/receive-payment-list';
import { VoucherType } from '../bills/voucher-type';
import { ReceivePaymentDatasource } from './receive-payment-datasource';
@ -13,7 +15,7 @@ import { ReceivePaymentDatasource } from './receive-payment-datasource';
styleUrls: ['./receive-payment.component.css'],
})
export class ReceivePaymentComponent {
choices = {
choices: ReceivePaymentList = {
REGULAR_BILL: [
{
id: 2,
@ -52,7 +54,7 @@ export class ReceivePaymentComponent {
],
};
type: PrintType;
type: VoucherType;
amount: number;
balance: number;
form: FormGroup;
@ -63,16 +65,18 @@ export class ReceivePaymentComponent {
constructor(
public dialogRef: MatDialogRef<ReceivePaymentComponent>,
private fb: FormBuilder,
@Inject(MAT_DIALOG_DATA) public data: { type: PrintType; amount: number },
@Inject(MAT_DIALOG_DATA) public data: { type: VoucherType; amount: number },
) {
this.createForm();
this.form = this.fb.group({
amounts: '',
});
this.type = data.type;
this.amount = data.amount;
this.balance = data.amount;
this.form.setControl(
'amounts',
this.fb.array(
this.choices[this.type].map((x) =>
this.choices[this.type].map((x: ReceivePaymentItem) =>
this.fb.group({
name: [x.name],
amount: [''],
@ -84,17 +88,11 @@ export class ReceivePaymentComponent {
this.listenToAmountChange();
}
createForm() {
this.form = this.fb.group({
amounts: '',
});
}
listenToAmountChange() {
const array = this.form.get('amounts') as FormArray;
this.choices[this.type].forEach((z, i) =>
array.controls[i].valueChanges.pipe(distinctUntilChanged()).subscribe((x) => {
this.choices[this.type].find((s) => s.name === x.name).amount =
(this.choices[this.type].find((s) => s.name === x.name) as ReceivePaymentItem).amount =
x.amount === '' ? 0 : parseInt(x.amount, 10);
this.balance = this.amount - this.choices[this.type].reduce((a, c) => a + c.amount, 0);
}),

View File

@ -1,13 +1,11 @@
.running {
/* Red 900 */
background-color: #b71c1c;
color: #ffffff;
background-color: #f8cbad;
color: #000000;
}
.printed {
/* Green 900 */
background-color: #1b5e20;
color: #ffffff;
background-color: #c6e0b4;
color: #000000;
}
.square-button {

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RunningTablesComponent } from './running-tables.component';
@ -6,11 +6,13 @@ describe('RunningTablesComponent', () => {
let component: RunningTablesComponent;
let fixture: ComponentFixture<RunningTablesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [RunningTablesComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [RunningTablesComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(RunningTablesComponent);

View File

@ -9,12 +9,13 @@ import { Table } from '../../core/table';
styleUrls: ['./running-tables.component.css'],
})
export class RunningTablesComponent implements OnInit {
list: Table[];
list: Table[] = [];
constructor(private router: Router, private route: ActivatedRoute) {}
ngOnInit() {
this.route.data.subscribe((data: { list: Table[] }) => {
this.route.data.subscribe((value) => {
const data = value as { list: Table[] };
this.list = data.list;
});
}
@ -23,7 +24,7 @@ export class RunningTablesComponent implements OnInit {
const qp = { table: table.id };
if (table.voucherId) {
// eslint-disable-next-line @typescript-eslint/dot-notation
qp['voucher'] = table.voucherId;
Object.assign(qp, { voucher: table.voucherId });
}
const navigationExtras: NavigationExtras = {
queryParams: qp,

View File

@ -1,4 +1,4 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TablesDialogComponent } from './tables-dialog.component';
@ -6,11 +6,13 @@ describe('TablesDialogComponent', () => {
let component: TablesDialogComponent;
let fixture: ComponentFixture<TablesDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TablesDialogComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [TablesDialogComponent],
}).compileComponents();
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(TablesDialogComponent);

View File

@ -10,9 +10,9 @@ import { Table } from '../../core/table';
styleUrls: ['./tables-dialog.component.css'],
})
export class TablesDialogComponent {
list: Table[];
list: Table[] = [];
canChooseRunning: boolean;
selected: Table;
selected: Table | null;
constructor(
public dialogRef: MatDialogRef<TablesDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { list: Observable<Table[]>; canChooseRunning: boolean },