No automatic signout

Voucher basic working
running tables shifted to cards from buttons, this gives us immense styling oportunities
This commit is contained in:
Amritanshu
2019-07-12 12:36:38 +05:30
parent 4513e8b263
commit bcad4cdae3
31 changed files with 1085 additions and 713 deletions

View File

@ -6,4 +6,5 @@ export class Table {
seats: number;
section: Section;
isActive: boolean;
voucherId?: string;
}

View File

@ -1,37 +1,54 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material';
import { BehaviorSubject } from "rxjs";
import { Product } from '../core/product';
import { ModifiersComponent } from './modifiers/modifiers.component';
import { MatDialog } from '@angular/material';
import { ModifierCategoryService } from '../modifier-categories/modifier-category.service';
import {Subject} from "rxjs";
import {Modifier} from "../core/modifier";
import {ModifierCategory} from "../core/modifier-category";
import {isNotNullOrUndefined} from "codelyzer/util/isNotNullOrUndefined";
import { ModifierCategory } from "../core/modifier-category";
@Injectable()
export class BillService {
public dataObs = new Subject<any[]>();
public data = [];
constructor(
private dialog: MatDialog,
private modifierCategoryService: ModifierCategoryService
) { }
public dataObs;
public data;
addProduct(product: Product) {
let item = {
isKot: false,
product: product,
productId: product.id,
info: `${product.name} (${product.units}) @ ${product.price}`,
quantity: 1,
modifiers: []
};
this.data.push(item);
this.modifierCategoryService.listIsActiveOfProduct(product.id).subscribe(result => {
if (result.reduce((a: any, c: ModifierCategory) => {return a + c.minimum}, 0)) {
this.showModifier(item);
}
});
constructor(
private dialog: MatDialog,
private modifierCategoryService: ModifierCategoryService
) {
this.data = [];
this.dataObs = new BehaviorSubject<any[]>(this.data);
}
loadData(d: any): void {
console.log("data loaded");
this.data = d;
this.data.push({isKot: true, newKot: true, info: "== New Kot =="})
this.dataObs.next(this.data);
}
addProduct(product: Product): void {
let old = this.data.find(x=> !x.isKot && x.productId == product.id && x.isHappyHour == product.hasHappyHour);
if (old !== undefined) {
old.quantity += 1;
} else {
let item = {
isKot: false,
product: product,
productId: product.id,
isHappyHour: product.hasHappyHour,
info: `${product.name} (${product.units}) @ ${product.price}`,
quantity: 1,
modifiers: []
};
this.data.push(item);
this.modifierCategoryService.listIsActiveOfProduct(product.id).subscribe(result => {
if (result.reduce((a: any, c: ModifierCategory) => {
return a + c.minimum
}, 0)) {
this.showModifier(item);
}
});
}
this.dataObs.next(this.data);
}
@ -48,7 +65,7 @@ export class BillService {
});
dialogRef.afterClosed().subscribe(result => {
if (isNotNullOrUndefined(result)) {
if (result !== undefined) {
item.modifiers = result;
}
});

View File

@ -1,19 +1,21 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs/internal/Observable';
import {TableService} from '../../tables/table.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable';
import { VoucherService } from "./voucher.service";
import { Bill } from "./bill";
@Injectable({
providedIn: 'root'
})
export class BillResolver implements Resolve<any[]> {
export class BillResolver implements Resolve<Bill> {
constructor(private ser: TableService, private router: Router) {
constructor(private ser: VoucherService, private router: Router) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any[]> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Bill> {
const tableId = route.queryParamMap.get('table');
const guestId = route.queryParamMap.get('guest');
return this.ser.list();
const voucherId = route.queryParamMap.get('voucher');
return this.ser.getFromTable(tableId, voucherId, guestId);
}
}

View File

@ -15,7 +15,7 @@ export class Inventory {
taxRate: number;
tax: Tax;
discount: number;
modifiers: Modifier;
modifiers: Modifier[];
}
export class Kot {

View File

@ -1,6 +1,11 @@
.kot {
background-color: red;
font-weight: bold;
background-color: hotpink;
}
.printed {
background-color: lightpink;
}
.new-kot {
background-color: lightblue;
}
.square-button {

View File

@ -6,7 +6,7 @@
<mat-table #table [dataSource]="dataSource" aria-label="Elements">
<!-- Info Column -->
<ng-container matColumnDef="info">
<mat-cell *matCellDef="let row" fxLayout="column" fxLayoutAlign="space-around start" [class.kot]="row.isKot">
<mat-cell *matCellDef="let row" fxLayout="column" fxLayoutAlign="start space-between end">
<span>
{{row.info}}
</span>
@ -19,26 +19,27 @@
<ng-container matColumnDef="quantity">
<mat-header-cell *matHeaderCellDef>Quantity</mat-header-cell>
<mat-cell *matCellDef="let row">
<button mat-icon-button (click)="subtractOne(row)">
<button mat-icon-button (click)="subtractOne(row)" [disabled]="row.isPrinted" *ngIf="!row.isKot">
<mat-icon class="del">indeterminate_check_box</mat-icon>
</button>
<button mat-icon-button (click)="quantity(row)">
<button mat-icon-button (click)="quantity(row)" [disabled]="row.isPrinted" *ngIf="!row.isKot">
{{row.quantity}}
</button>
<button mat-icon-button (click)="addOne(row)">
<button mat-icon-button (click)="addOne(row)" [disabled]="row.isPrinted" *ngIf="!row.isKot">
<mat-icon class="del">control_point</mat-icon>
</button>
<button mat-icon-button (click)="removeItem(row)">
<button mat-icon-button (click)="removeItem(row)" [disabled]="row.isPrinted" *ngIf="!row.isKot">
<mat-icon class="del">cancel</mat-icon>
</button>
<button mat-icon-button (click)="modifier(row)">
<button mat-icon-button (click)="modifier(row)" [disabled]="row.isPrinted" *ngIf="!row.isKot">
<mat-icon class="del">assignment</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" [class.kot]="row.isKot" [class.new-kot]="row.newKot"
[class.printed]="row.isPrinted"></mat-row>
</mat-table>
</mat-card-content>
</mat-card>

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import {Bill, Inventory, Kot} from './bill';
import {ModifierCategoryListDatasource} from '../../modifier-categories/modifier-category-list/modifier-category-list-datasource';
import {BillsDataSource} from './bills-datasource';
import {BillService} from "../bill.service";
@ -13,7 +12,6 @@ import {BillService} from "../bill.service";
export class BillsComponent implements OnInit {
dataSource: BillsDataSource;
item: Bill;
view: any[];
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns: string[] = ['info', 'quantity'];
@ -24,18 +22,35 @@ export class BillsComponent implements OnInit {
}
ngOnInit() {
console.log("ds set")
this.dataSource = new BillsDataSource(this.bs.dataObs);
this.route.data
.subscribe((data: { item: Bill }) => {
this.updateView(data.item);
});
this.dataSource = new BillsDataSource(this.bs.dataObs);
}
updateView(item) {
this.item = item;
// this.view = item.kots.reduce((p: Kot, c:Kot) => {
//
// }, [])
let view = item.kots.map(k => {
return [{
isKot: true,
}, ...k.inventories.map(i => {
return {
id: i.id,
isKot: false,
product: i.product,
productId: i.product.id,
isHappyHour: i.isHappyHour,
isPrinted: true,
info: `${i.product.name} (${i.product.units}) @ ${i.price}`,
quantity: 1,
modifiers: i.modifiers
}
})]
});
view = view.reduce((a, c) => {return a.concat(c)} , []);
this.bs.loadData(view);
}
addOne(item: any): void {

View File

@ -0,0 +1,70 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { catchError } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { ErrorLoggerService } from '../../core/error-logger.service';
import {Bill} from "./bill";
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
};
const url = '/v1/vouchers';
const serviceName = 'VoucherService';
@Injectable({providedIn: 'root'})
export class VoucherService {
constructor(private http: HttpClient, private log: ErrorLoggerService) {
}
get(id: string): Observable<Bill> {
return <Observable<Bill>>this.http.get<Bill>(`${url}/${id}`)
.pipe(
catchError(this.log.handleError(serviceName, `get id=${id}`))
);
}
getFromTable(tableId: string, voucherId: string, guestId: string): Observable<Bill> {
let params = new HttpParams();
if (tableId !== null) {
params = params.set('t', tableId);
}
if (voucherId !== null) {
params = params.set('v', voucherId);
}
if (guestId !== null) {
params = params.set('g', guestId);
}
return <Observable<Bill>>this.http.get<Bill>(`${url}/new`, {params: params})
.pipe(
catchError(this.log.handleError(
serviceName,
`getFromTable tableId=${tableId} voucherId=${voucherId} guestId=${guestId}`
))
);
}
save(voucher: Bill): Observable<Bill> {
return <Observable<Bill>>this.http.post<Bill>(`${url}/new`, voucher, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'save'))
);
}
update(voucher: Bill): Observable<Bill> {
return <Observable<Bill>>this.http.put<Bill>(`${url}/${voucher.id}`, voucher, httpOptions)
.pipe(
catchError(this.log.handleError(serviceName, 'update'))
);
}
saveOrUpdate(voucher: Bill): Observable<Bill> {
if (!voucher.id) {
return this.save(voucher);
} else {
return this.update(voucher);
}
}
}

View File

@ -13,6 +13,6 @@ export class RunningTablesResolver implements Resolve<Table[]> {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Table[]> {
return this.ser.list();
return this.ser.running();
}
}

View File

@ -1,5 +1,23 @@
.running {
background-color: green;
}
.printed {
background-color: firebrick;
}
.square-button {
min-width: 150px;
max-width: 150px;
min-height: 150px;
max-height: 150px;
margin: 20px;
}
.item-name {
text-align: center;
padding: 0.5rem;
}
.center {
text-align: center;
}

View File

@ -3,7 +3,13 @@
<mat-card-title>Running Tables</mat-card-title>
</mat-card-title-group>
<mat-card-content fxLayout="row wrap" fxLayoutGap="grid 20px">
<button mat-raised-button class="square-button"
*ngFor="let table of list" [routerLink]="['../bill']" [queryParams]="{table: table.id}" queryParamsHandling="merge">{{table.name}}</button>
<mat-card fxLayout="column" class="square-button"
*ngFor="let table of list" (click)="navigateToBill(table)"
[class.running]="table.status === 'running'" [class.printed]="table.status === 'printed'">
<h3 class="item-name">{{table.name}}</h3>
<span class="center">{{table.pax || 0}} / {{table.seats}} Seats</span>
<span class="center" *ngIf="table.date">{{table.date}}</span>
<span class="center" *ngIf="table.amount">{{table.amount}}</span>
</mat-card>
</mat-card-content>
</mat-card>

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
import { Table } from '../../core/table';
@Component({
@ -10,7 +10,7 @@ import { Table } from '../../core/table';
export class RunningTablesComponent implements OnInit {
list: Table[];
constructor(private route: ActivatedRoute) {
constructor(private router: Router, private route: ActivatedRoute) {
}
ngOnInit() {
@ -19,4 +19,17 @@ export class RunningTablesComponent implements OnInit {
this.list = data.list;
});
}
navigateToBill(table: Table): void {
let qp = {table: table.id};
if (table.voucherId) {
qp["voucher"] = table.voucherId;
}
let navigationExtras: NavigationExtras = {
queryParams: qp,
queryParamsHandling: 'merge',
preserveFragment: true
};
this.router.navigate(['/sales', 'bill'], navigationExtras);
}
}

View File

@ -43,7 +43,7 @@ const routes: Routes = [
permission: 'Guest Book'
},
resolve: {
list: BillResolver
item: BillResolver
},
children: [
{

View File

@ -34,6 +34,14 @@ export class TableService {
);
}
running(): Observable<Table[]> {
const options = {params: new HttpParams().set('a', 'true')};
return <Observable<Table[]>>this.http.get<Table[]>(url, options)
.pipe(
catchError(this.log.handleError(serviceName, 'running'))
);
}
save(tables: Table): Observable<Table> {
return <Observable<Table>>this.http.post<Table>(`${url}/new`, tables, httpOptions)
.pipe(