Fully working with the rule no explicit any
This commit is contained in:
@ -2,7 +2,7 @@ import uuid
|
|||||||
|
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from typing import List, Optional
|
from typing import List
|
||||||
|
|
||||||
import barker.schemas.master as schemas
|
import barker.schemas.master as schemas
|
||||||
|
|
||||||
@ -41,9 +41,10 @@ def effective_date(d: str = None) -> date:
|
|||||||
@router.post("", response_model=schemas.ModifierCategory)
|
@router.post("", response_model=schemas.ModifierCategory)
|
||||||
def save(
|
def save(
|
||||||
data: schemas.ModifierCategoryIn,
|
data: schemas.ModifierCategoryIn,
|
||||||
|
date_: date = Depends(effective_date),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
||||||
):
|
) -> schemas.ModifierCategory:
|
||||||
try:
|
try:
|
||||||
item = ModifierCategory(
|
item = ModifierCategory(
|
||||||
name=data.name,
|
name=data.name,
|
||||||
@ -54,7 +55,7 @@ def save(
|
|||||||
db.add(item)
|
db.add(item)
|
||||||
add_products(item, data.menu_categories, db)
|
add_products(item, data.menu_categories, db)
|
||||||
db.commit()
|
db.commit()
|
||||||
return modifier_category_info(item, db=db)
|
return modifier_category_info(item, date_, db=db)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@ -73,7 +74,7 @@ def update(
|
|||||||
date_: date = Depends(effective_date),
|
date_: date = Depends(effective_date),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
||||||
):
|
) -> schemas.ModifierCategory:
|
||||||
try:
|
try:
|
||||||
item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first()
|
item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first()
|
||||||
item.name = data.name
|
item.name = data.name
|
||||||
@ -94,17 +95,18 @@ def update(
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/{id_}")
|
@router.delete("/{id_}", response_model=schemas.ModifierCategoryIn)
|
||||||
def delete(
|
def delete(
|
||||||
id_: uuid.UUID,
|
id_: uuid.UUID,
|
||||||
|
date_: date = Depends(effective_date),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
||||||
):
|
) -> schemas.ModifierCategoryIn:
|
||||||
try:
|
try:
|
||||||
item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first()
|
item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first()
|
||||||
db.delete(item)
|
db.delete(item)
|
||||||
db.commit()
|
db.commit()
|
||||||
return modifier_category_info(None, db=db)
|
return modifier_category_blank(date_, db=db)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@ -116,12 +118,13 @@ def delete(
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@router.get("")
|
@router.get("", response_model=schemas.ModifierCategoryIn)
|
||||||
def show_blank(
|
def show_blank(
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
|
date_: date = Depends(effective_date),
|
||||||
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
||||||
):
|
) -> schemas.ModifierCategoryIn:
|
||||||
return modifier_category_info(None, db=db)
|
return modifier_category_info(date_, db=db)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/list")
|
@router.get("/list")
|
||||||
@ -178,6 +181,7 @@ def show_list(
|
|||||||
@router.get("/for-product/{id_}")
|
@router.get("/for-product/{id_}")
|
||||||
def for_product(
|
def for_product(
|
||||||
id_: uuid.UUID,
|
id_: uuid.UUID,
|
||||||
|
date_: date = Depends(effective_date),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: UserToken = Security(get_user),
|
user: UserToken = Security(get_user),
|
||||||
):
|
):
|
||||||
@ -201,18 +205,18 @@ def for_product(
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{id_}")
|
@router.get("/{id_}", response_model=schemas.ModifierCategory)
|
||||||
def show_id(
|
def show_id(
|
||||||
id_: uuid.UUID,
|
id_: uuid.UUID,
|
||||||
date_: date = Depends(effective_date),
|
date_: date = Depends(effective_date),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
user: UserToken = Security(get_user, scopes=["modifiers"]),
|
||||||
):
|
) -> schemas.ModifierCategory:
|
||||||
item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first()
|
item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first()
|
||||||
return modifier_category_info(item, date_, db=db)
|
return modifier_category_info(item, date_, db=db)
|
||||||
|
|
||||||
|
|
||||||
def modifier_category_info(item: Optional[ModifierCategory], date_: date, db: Session):
|
def modifier_category_info(item: ModifierCategory, date_: date, db: Session) -> schemas.ModifierCategory:
|
||||||
menu_categories = (
|
menu_categories = (
|
||||||
db.query(MenuCategory)
|
db.query(MenuCategory)
|
||||||
.join(MenuCategory.products)
|
.join(MenuCategory.products)
|
||||||
@ -235,48 +239,71 @@ def modifier_category_info(item: Optional[ModifierCategory], date_: date, db: Se
|
|||||||
)
|
)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
if item is None:
|
|
||||||
return {
|
|
||||||
"name": "",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 0,
|
|
||||||
"isActive": True,
|
|
||||||
"menuCategories": [
|
|
||||||
{
|
|
||||||
"id": mc.id,
|
|
||||||
"name": mc.name,
|
|
||||||
"enabled": False,
|
|
||||||
"products": [{"id": p.id, "name": p.name, "enabled": False} for p in mc.products],
|
|
||||||
}
|
|
||||||
for mc in menu_categories
|
|
||||||
],
|
|
||||||
"sortOrder": item.sort_order,
|
|
||||||
}
|
|
||||||
products = [p.id for p in item.products]
|
products = [p.id for p in item.products]
|
||||||
return {
|
return schemas.ModifierCategory(
|
||||||
"id": item.id,
|
id=item.id,
|
||||||
"name": item.name,
|
name=item.name,
|
||||||
"minimum": item.minimum,
|
minimum=item.minimum,
|
||||||
"maximum": item.maximum,
|
maximum=item.maximum,
|
||||||
"isActive": item.is_active,
|
isActive=item.is_active,
|
||||||
"menuCategories": [
|
menuCategories=[
|
||||||
{
|
schemas.MenuCategoryLink(
|
||||||
"id": mc.id,
|
id=mc.id,
|
||||||
"name": mc.name,
|
name=mc.name,
|
||||||
"enabled": False,
|
enabled=False,
|
||||||
"products": [
|
products=[
|
||||||
{
|
schemas.ProductLink(
|
||||||
"id": p.id,
|
id=p.id,
|
||||||
"name": p.name,
|
name=p.name,
|
||||||
"enabled": True if p.product_id in products else False,
|
enabled=True if p.product_id in products else False,
|
||||||
}
|
)
|
||||||
for p in mc.products
|
for p in mc.products
|
||||||
],
|
],
|
||||||
}
|
)
|
||||||
for mc in menu_categories
|
for mc in menu_categories
|
||||||
],
|
],
|
||||||
"sortOrder": item.sort_order,
|
sortOrder=item.sort_order,
|
||||||
}
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def modifier_category_blank(date_: date, db: Session) -> schemas.ModifierCategoryIn:
|
||||||
|
menu_categories = (
|
||||||
|
db.query(MenuCategory)
|
||||||
|
.join(MenuCategory.products)
|
||||||
|
.filter(
|
||||||
|
and_(
|
||||||
|
or_(
|
||||||
|
ProductVersion.valid_from == None, # noqa: E711
|
||||||
|
ProductVersion.valid_from <= date_,
|
||||||
|
),
|
||||||
|
or_(
|
||||||
|
ProductVersion.valid_till == None, # noqa: E711
|
||||||
|
ProductVersion.valid_till >= date_,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.order_by(MenuCategory.sort_order, ProductVersion.sort_order, ProductVersion.name)
|
||||||
|
.options(
|
||||||
|
joinedload(MenuCategory.products, innerjoin=True),
|
||||||
|
contains_eager(MenuCategory.products),
|
||||||
|
)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
return schemas.ModifierCategoryIn(
|
||||||
|
name="",
|
||||||
|
minimum=0,
|
||||||
|
maximum=0,
|
||||||
|
isActive=True,
|
||||||
|
menuCategories=[
|
||||||
|
schemas.MenuCategoryLink(
|
||||||
|
id=mc.id,
|
||||||
|
name=mc.name,
|
||||||
|
enabled=False,
|
||||||
|
products=[schemas.ProductLink(id=p.id, name=p.name, enabled=False) for p in mc.products],
|
||||||
|
)
|
||||||
|
for mc in menu_categories
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def add_products(modifier_category: ModifierCategory, menu_categories: List[schemas.MenuCategoryLink], db: Session):
|
def add_products(modifier_category: ModifierCategory, menu_categories: List[schemas.MenuCategoryLink], db: Session):
|
||||||
|
|||||||
@ -38,6 +38,6 @@ module.exports = {
|
|||||||
"@typescript-eslint/lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }],
|
"@typescript-eslint/lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }],
|
||||||
"class-methods-use-this": ["error", {"exceptMethods": ["disconnect", "displayFn", "transform"]}],
|
"class-methods-use-this": ["error", {"exceptMethods": ["disconnect", "displayFn", "transform"]}],
|
||||||
"import/order": ["error", {"alphabetize": {"order": "asc", "caseInsensitive": true}, "newlines-between": "always"}],
|
"import/order": ["error", {"alphabetize": {"order": "asc", "caseInsensitive": true}, "newlines-between": "always"}],
|
||||||
"@typescript-eslint/no-explicit-any": "off", // Disabled for now, but needed to transition to strict compiling
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -89,7 +89,7 @@ export class AuthService {
|
|||||||
formData.append('otp', otp);
|
formData.append('otp', otp);
|
||||||
formData.append('grant_type', 'password');
|
formData.append('grant_type', 'password');
|
||||||
return this.http
|
return this.http
|
||||||
.post<any>(loginUrl, formData)
|
.post<{ access_token: string; token_type: string }>(loginUrl, formData)
|
||||||
.pipe(map((u) => u.access_token))
|
.pipe(map((u) => u.access_token))
|
||||||
.pipe(map((u) => AuthService.parseJwt(u)))
|
.pipe(map((u) => AuthService.parseJwt(u)))
|
||||||
.pipe(
|
.pipe(
|
||||||
@ -118,7 +118,7 @@ export class AuthService {
|
|||||||
|
|
||||||
refreshToken() {
|
refreshToken() {
|
||||||
return this.http
|
return this.http
|
||||||
.post<any>(refreshUrl, {})
|
.post<{ access_token: string; token_type: string }>(refreshUrl, {})
|
||||||
.pipe(map((u) => u.access_token))
|
.pipe(map((u) => u.access_token))
|
||||||
.pipe(map((u) => AuthService.parseJwt(u)))
|
.pipe(map((u) => AuthService.parseJwt(u)))
|
||||||
.pipe(
|
.pipe(
|
||||||
|
|||||||
@ -70,14 +70,16 @@ export class CashierReportComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print() {
|
print() {
|
||||||
this.ser.print(this.info.cashier.id as string, this.info.startDate, this.info.finishDate).subscribe(
|
this.ser
|
||||||
() => {
|
.print(this.info.cashier.id as string, this.info.startDate, this.info.finishDate)
|
||||||
this.toaster.show('', 'Successfully Printed');
|
.subscribe(
|
||||||
},
|
() => {
|
||||||
(error) => {
|
this.toaster.show('', 'Successfully Printed');
|
||||||
this.toaster.show('Error', error.error);
|
},
|
||||||
},
|
(error) => {
|
||||||
);
|
this.toaster.show('Error', error.error);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getInfo(): CashierReport {
|
getInfo(): CashierReport {
|
||||||
|
|||||||
@ -3,9 +3,8 @@ import { Product } from './product';
|
|||||||
import { Tax } from './tax';
|
import { Tax } from './tax';
|
||||||
|
|
||||||
export class BillViewItem {
|
export class BillViewItem {
|
||||||
id: string;
|
id: string | undefined;
|
||||||
isKot: boolean;
|
isKot: boolean;
|
||||||
oldKot: boolean;
|
|
||||||
info: string;
|
info: string;
|
||||||
|
|
||||||
kotId: string;
|
kotId: string;
|
||||||
@ -20,10 +19,16 @@ export class BillViewItem {
|
|||||||
tax: Tax;
|
tax: Tax;
|
||||||
modifiers: Modifier[];
|
modifiers: Modifier[];
|
||||||
|
|
||||||
|
public get isOldKot(): boolean {
|
||||||
|
return this.isKot && this.id !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isNewKot(): boolean {
|
||||||
|
return this.isKot && this.id === undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public constructor(init?: Partial<BillViewItem>) {
|
public constructor(init?: Partial<BillViewItem>) {
|
||||||
this.id = '';
|
|
||||||
this.isKot = true;
|
this.isKot = true;
|
||||||
this.oldKot = false;
|
|
||||||
this.info = '';
|
this.info = '';
|
||||||
this.kotId = '';
|
this.kotId = '';
|
||||||
this.product = new Product();
|
this.product = new Product();
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export class ErrorLoggerService {
|
|||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, class-methods-use-this
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars, class-methods-use-this
|
||||||
public handleError<T>(serviceName = 'error-logger', operation = 'operation', result?: T) {
|
public handleError<T>(serviceName = 'error-logger', operation = 'operation', result?: T) {
|
||||||
return (error: any): Observable<T> => {
|
return (error: unknown): Observable<T> => {
|
||||||
ErrorLoggerService.log(serviceName, `${operation} failed: ${error}`);
|
ErrorLoggerService.log(serviceName, `${operation} failed: ${error}`);
|
||||||
return throwError(error);
|
return throwError(error);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export class ErrorInterceptor implements HttpInterceptor {
|
|||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||||
return next.handle(request).pipe(
|
return next.handle(request).pipe(
|
||||||
catchError((err) => {
|
catchError((err) => {
|
||||||
// We don't want to refresh token for some requests like login or refresh token itself
|
// We don't want to refresh token for some requests like login or refresh token itself
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export class JwtInterceptor implements HttpInterceptor {
|
|||||||
|
|
||||||
constructor(private authService: AuthService) {}
|
constructor(private authService: AuthService) {}
|
||||||
|
|
||||||
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||||
// add authorization header with jwt token if available
|
// add authorization header with jwt token if available
|
||||||
|
|
||||||
// We use this line to debug token refreshing
|
// We use this line to debug token refreshing
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { MatSelectChange } from '@angular/material/select';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ export class HeaderFooterComponent implements OnInit {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
show(val: any) {
|
show(val: MatSelectChange) {
|
||||||
this.router.navigate(['/header-footer', val.value]);
|
this.router.navigate(['/header-footer', val.value]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
|||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatTreeNestedDataSource } from '@angular/material/tree';
|
import { MatTreeNestedDataSource } from '@angular/material/tree';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
import { MenuCategory } from '../../core/menu-category';
|
import { MenuCategory } from '../../core/menu-category';
|
||||||
import { ModifierCategory } from '../../core/modifier-category';
|
import { ModifierCategory } from '../../core/modifier-category';
|
||||||
@ -11,6 +12,7 @@ import { Product } from '../../core/product';
|
|||||||
import { ToasterService } from '../../core/toaster.service';
|
import { ToasterService } from '../../core/toaster.service';
|
||||||
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
|
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
|
||||||
import { ModifierCategoryService } from '../modifier-category.service';
|
import { ModifierCategoryService } from '../modifier-category.service';
|
||||||
|
import { NodeItem } from '../node-item';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-role-detail',
|
selector: 'app-role-detail',
|
||||||
@ -21,8 +23,8 @@ export class ModifierCategoryDetailComponent implements OnInit, AfterViewInit {
|
|||||||
@ViewChild('nameElement', { static: true }) nameElement?: ElementRef;
|
@ViewChild('nameElement', { static: true }) nameElement?: ElementRef;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
item: ModifierCategory = new ModifierCategory();
|
item: ModifierCategory = new ModifierCategory();
|
||||||
treeControl = new NestedTreeControl<any>((node) => node.products);
|
treeControl = new NestedTreeControl<NodeItem>((node: NodeItem) => node.children);
|
||||||
dataSource = new MatTreeNestedDataSource<any>();
|
dataSource = new MatTreeNestedDataSource<NodeItem>();
|
||||||
products: Map<string, Product> = new Map<string, Product>();
|
products: Map<string, Product> = new Map<string, Product>();
|
||||||
productsOfMenuCategory: Map<string, Product[]> = new Map<string, Product[]>();
|
productsOfMenuCategory: Map<string, Product[]> = new Map<string, Product[]>();
|
||||||
|
|
||||||
@ -45,15 +47,26 @@ export class ModifierCategoryDetailComponent implements OnInit, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.route.data.subscribe((value) => {
|
this.route.data
|
||||||
const data = value as { item: ModifierCategory };
|
.pipe(
|
||||||
this.showItem(data.item);
|
map((value) => {
|
||||||
});
|
const data = value as { item: ModifierCategory };
|
||||||
|
const tree: NodeItem[] = data.item.menuCategories.map((x: MenuCategory) => ({
|
||||||
|
id: x.id as string,
|
||||||
|
name: x.name,
|
||||||
|
children: x.products.map((y: Product) => ({ id: y.id as string, name: y.name })),
|
||||||
|
}));
|
||||||
|
return { item: data.item, tree };
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.subscribe((data) => {
|
||||||
|
this.showItem(data.item, data.tree);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showItem(item: ModifierCategory) {
|
showItem(item: ModifierCategory, tree: NodeItem[]) {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.dataSource.data = item.menuCategories;
|
this.dataSource.data = tree;
|
||||||
this.form.patchValue({
|
this.form.patchValue({
|
||||||
name: this.item.name || '',
|
name: this.item.name || '',
|
||||||
minimum: `${this.item.minimum}`,
|
minimum: `${this.item.minimum}`,
|
||||||
@ -133,22 +146,22 @@ export class ModifierCategoryDetailComponent implements OnInit, AfterViewInit {
|
|||||||
return this.item;
|
return this.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasChild = (_: number, node: any) => !!node.products && node.products.length > 0;
|
hasChild = (_: number, node: NodeItem) => !!node.children && node.children.length > 0;
|
||||||
|
|
||||||
isProductSelected(node: Product) {
|
isProductSelected(node: NodeItem) {
|
||||||
return (this.products.get(node.id as string) as Product).enabled;
|
return (this.products.get(node.id) as Product).enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
isMenuCategorySelected(node: MenuCategory) {
|
isMenuCategorySelected(node: NodeItem) {
|
||||||
return (this.productsOfMenuCategory.get(node.id as string) as Product[]).reduce(
|
return (this.productsOfMenuCategory.get(node.id) as Product[]).reduce(
|
||||||
(acc: boolean, current: Product) => acc && current.enabled,
|
(acc: boolean, current: Product) => acc && current.enabled,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isMenuCategoryPartiallySelected(node: MenuCategory) {
|
isMenuCategoryPartiallySelected(node: NodeItem) {
|
||||||
const total = (this.productsOfMenuCategory.get(node.id as string) as Product[]).length;
|
const total = (this.productsOfMenuCategory.get(node.id) as Product[]).length;
|
||||||
const ticked = (this.productsOfMenuCategory.get(node.id as string) as Product[]).reduce(
|
const ticked = (this.productsOfMenuCategory.get(node.id) as Product[]).reduce(
|
||||||
(acc, current) => {
|
(acc, current) => {
|
||||||
if (current.enabled) {
|
if (current.enabled) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
@ -161,12 +174,12 @@ export class ModifierCategoryDetailComponent implements OnInit, AfterViewInit {
|
|||||||
return ticked > 0 && ticked < total;
|
return ticked > 0 && ticked < total;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleProductSelection(node: Product) {
|
toggleProductSelection(node: NodeItem) {
|
||||||
(this.products.get(node.id as string) as Product).enabled = !(this.products.get(node.id as string) as Product)
|
(this.products.get(node.id) as Product).enabled = !(this.products.get(node.id) as Product)
|
||||||
.enabled;
|
.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMenuCategorySelection(node: MenuCategory) {
|
toggleMenuCategorySelection(node: NodeItem) {
|
||||||
const sel = !this.isMenuCategorySelected(node);
|
const sel = !this.isMenuCategorySelected(node);
|
||||||
(this.productsOfMenuCategory.get(node.id as string) as Product[]).forEach((p) => {
|
(this.productsOfMenuCategory.get(node.id as string) as Product[]).forEach((p) => {
|
||||||
p.enabled = sel;
|
p.enabled = sel;
|
||||||
|
|||||||
5
bookie/src/app/modifier-categories/node-item.ts
Normal file
5
bookie/src/app/modifier-categories/node-item.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface NodeItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
children?: NodeItem[];
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
import { MatSelectChange } from '@angular/material/select';
|
||||||
import { MatTable } from '@angular/material/table';
|
import { MatTable } from '@angular/material/table';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
@ -34,7 +35,7 @@ export class ModifierListComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
filterOn(val: any) {
|
filterOn(val: MatSelectChange) {
|
||||||
this.filter.next(val.value);
|
this.filter.next(val.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,9 +20,9 @@ export class BillTypeComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
accept(): void {
|
accept(): void {
|
||||||
if (this.selected === 'REGULAR_BILL') this.dialogRef.close(VoucherType.Bill)
|
if (this.selected === 'REGULAR_BILL') this.dialogRef.close(VoucherType.Bill);
|
||||||
else if (this.selected === 'STAFF') this.dialogRef.close(VoucherType.Staff)
|
else if (this.selected === 'STAFF') this.dialogRef.close(VoucherType.Staff);
|
||||||
else if (this.selected === 'NO_CHARGE') this.dialogRef.close(VoucherType.NoCharge)
|
else if (this.selected === 'NO_CHARGE') this.dialogRef.close(VoucherType.NoCharge);
|
||||||
else this.dialogRef.close();
|
else this.dialogRef.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,14 +21,14 @@ import { ModifiersComponent } from './modifiers/modifiers.component';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BillService {
|
export class BillService {
|
||||||
public dataObs;
|
public dataObs: BehaviorSubject<BillViewItem[]>;
|
||||||
public data: any[];
|
public data: BillViewItem[];
|
||||||
public bill: Bill = new Bill();
|
public bill: Bill = new Bill();
|
||||||
public netAmount: BehaviorSubject<number>;
|
public netAmount: BehaviorSubject<number>;
|
||||||
public discountAmount: BehaviorSubject<number>;
|
public discountAmount: BehaviorSubject<number>;
|
||||||
public taxAmount: BehaviorSubject<number>;
|
public taxAmount: BehaviorSubject<number>;
|
||||||
public amount: BehaviorSubject<number>;
|
public amount: BehaviorSubject<number>;
|
||||||
public selection = new SelectionModel<any>(true, []);
|
public selection = new SelectionModel<BillViewItem>(true, []);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
@ -37,7 +37,7 @@ export class BillService {
|
|||||||
private modifierCategoryService: ModifierCategoryService,
|
private modifierCategoryService: ModifierCategoryService,
|
||||||
) {
|
) {
|
||||||
this.data = [];
|
this.data = [];
|
||||||
this.dataObs = new BehaviorSubject<any[]>(this.data);
|
this.dataObs = new BehaviorSubject<BillViewItem[]>(this.data);
|
||||||
this.netAmount = new BehaviorSubject(0);
|
this.netAmount = new BehaviorSubject(0);
|
||||||
this.discountAmount = new BehaviorSubject(0);
|
this.discountAmount = new BehaviorSubject(0);
|
||||||
this.taxAmount = new BehaviorSubject(0);
|
this.taxAmount = new BehaviorSubject(0);
|
||||||
@ -50,7 +50,6 @@ export class BillService {
|
|||||||
new BillViewItem({
|
new BillViewItem({
|
||||||
id: k.id,
|
id: k.id,
|
||||||
isKot: true,
|
isKot: true,
|
||||||
oldKot: true,
|
|
||||||
info: `Kot: ${k.code} / ${k.date} (${k.user.name}) `,
|
info: `Kot: ${k.code} / ${k.date} (${k.user.name}) `,
|
||||||
}),
|
}),
|
||||||
...k.inventories.map(
|
...k.inventories.map(
|
||||||
@ -74,7 +73,7 @@ export class BillService {
|
|||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
this.data = view.reduce((a, c) => a.concat(c), []);
|
this.data = view.reduce((a, c) => a.concat(c), []);
|
||||||
this.data.push({ isKot: true, newKot: true, info: '== New Kot ==' });
|
this.data.push(new BillViewItem({ isKot: true, info: '== New Kot ==' }));
|
||||||
this.dataObs.next(this.data);
|
this.dataObs.next(this.data);
|
||||||
this.updateAmounts();
|
this.updateAmounts();
|
||||||
}
|
}
|
||||||
@ -101,7 +100,7 @@ export class BillService {
|
|||||||
if (old !== undefined) {
|
if (old !== undefined) {
|
||||||
old.quantity += quantity;
|
old.quantity += quantity;
|
||||||
} else {
|
} else {
|
||||||
const item = {
|
const item = new BillViewItem({
|
||||||
isKot: false,
|
isKot: false,
|
||||||
product,
|
product,
|
||||||
productId: product.id,
|
productId: product.id,
|
||||||
@ -113,11 +112,11 @@ export class BillService {
|
|||||||
taxRate: product.tax.rate,
|
taxRate: product.tax.rate,
|
||||||
tax: product.tax,
|
tax: product.tax,
|
||||||
modifiers: [],
|
modifiers: [],
|
||||||
};
|
});
|
||||||
this.data.push(item);
|
this.data.push(item);
|
||||||
this.modifierCategoryService.listForProduct(product.id as string).subscribe((result) => {
|
this.modifierCategoryService.listForProduct(product.id as string).subscribe((result) => {
|
||||||
if (
|
if (
|
||||||
result.reduce((a: any, c: ModifierCategory) => {
|
result.reduce((a: number, c: ModifierCategory) => {
|
||||||
return a + c.minimum;
|
return a + c.minimum;
|
||||||
}, 0)
|
}, 0)
|
||||||
) {
|
) {
|
||||||
@ -129,14 +128,14 @@ export class BillService {
|
|||||||
this.updateAmounts();
|
this.updateAmounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
showModifier(item: any): void {
|
showModifier(item: BillViewItem): void {
|
||||||
// [routerLink]="['/sales', 'modifiers', item.id]"
|
// [routerLink]="['/sales', 'modifiers', item.id]"
|
||||||
const dialogRef = this.dialog.open(ModifiersComponent, {
|
const dialogRef = this.dialog.open(ModifiersComponent, {
|
||||||
position: {
|
position: {
|
||||||
top: '10vh',
|
top: '10vh',
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
list: this.modifierCategoryService.listForProduct(item.productId),
|
list: this.modifierCategoryService.listForProduct(item.productId as string),
|
||||||
selected: item.modifiers,
|
selected: item.modifiers,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -148,20 +147,23 @@ export class BillService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addOne(item: any): void {
|
addOne(item: BillViewItem): void {
|
||||||
item.quantity += 1;
|
item.quantity += 1;
|
||||||
this.dataObs.next(this.data);
|
this.dataObs.next(this.data);
|
||||||
this.updateAmounts();
|
this.updateAmounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
quantity(item: any, quantity: number): void {
|
quantity(item: BillViewItem, quantity: number): void {
|
||||||
item.quantity = quantity;
|
item.quantity = quantity;
|
||||||
this.dataObs.next(this.data);
|
this.dataObs.next(this.data);
|
||||||
this.updateAmounts();
|
this.updateAmounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
subtractOne(item: any, canEdit: boolean): void {
|
subtractOne(item: BillViewItem, canEdit: boolean): void {
|
||||||
if (item.quantity > 1 || (canEdit && this.minimum(item.productId, item.isHappyHour) >= 1)) {
|
if (
|
||||||
|
item.quantity > 1 ||
|
||||||
|
(canEdit && this.minimum(item.productId as string, item.isHappyHour) >= 1)
|
||||||
|
) {
|
||||||
item.quantity -= 1;
|
item.quantity -= 1;
|
||||||
this.dataObs.next(this.data);
|
this.dataObs.next(this.data);
|
||||||
this.updateAmounts();
|
this.updateAmounts();
|
||||||
@ -170,13 +172,13 @@ export class BillService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeItem(item: any): void {
|
removeItem(item: BillViewItem): void {
|
||||||
this.data.splice(this.data.indexOf(item), 1);
|
this.data.splice(this.data.indexOf(item), 1);
|
||||||
this.dataObs.next(this.data);
|
this.dataObs.next(this.data);
|
||||||
this.updateAmounts();
|
this.updateAmounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier(item: any): void {
|
modifier(item: BillViewItem): void {
|
||||||
this.showModifier(item);
|
this.showModifier(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +232,7 @@ export class BillService {
|
|||||||
const item = JSON.parse(JSON.stringify(this.bill));
|
const item = JSON.parse(JSON.stringify(this.bill));
|
||||||
item.kots.forEach((k: Kot) => {
|
item.kots.forEach((k: Kot) => {
|
||||||
k.inventories.forEach((i: Inventory) => {
|
k.inventories.forEach((i: Inventory) => {
|
||||||
i.discount = this.data.find((x) => !x.isKot && x.id === i.id).discount;
|
i.discount = (this.data.find((x) => !x.isKot && x.id === i.id) as BillViewItem).discount;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
item.kots.push(this.getKot());
|
item.kots.push(this.getKot());
|
||||||
@ -273,7 +275,10 @@ export class BillService {
|
|||||||
math.round(
|
math.round(
|
||||||
this.data
|
this.data
|
||||||
.filter((x) => !x.isKot)
|
.filter((x) => !x.isKot)
|
||||||
.reduce((ca: number, c: any) => ca + (c.isHappyHour ? 0 : c.price) * c.quantity, 0),
|
.reduce(
|
||||||
|
(ca: number, c: BillViewItem) => ca + (c.isHappyHour ? 0 : c.price) * c.quantity,
|
||||||
|
0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
this.discountAmount.next(
|
this.discountAmount.next(
|
||||||
@ -281,7 +286,7 @@ export class BillService {
|
|||||||
this.data
|
this.data
|
||||||
.filter((x) => !x.isKot)
|
.filter((x) => !x.isKot)
|
||||||
.reduce(
|
.reduce(
|
||||||
(ca: number, c: Inventory) =>
|
(ca: number, c: BillViewItem) =>
|
||||||
ca + (c.isHappyHour ? 0 : c.price) * c.quantity * c.discount,
|
ca + (c.isHappyHour ? 0 : c.price) * c.quantity * c.discount,
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
@ -292,7 +297,7 @@ export class BillService {
|
|||||||
this.data
|
this.data
|
||||||
.filter((x) => !x.isKot)
|
.filter((x) => !x.isKot)
|
||||||
.reduce(
|
.reduce(
|
||||||
(ca: number, c: Inventory) =>
|
(ca: number, c: BillViewItem) =>
|
||||||
ca + (c.isHappyHour ? 0 : c.price) * c.quantity * (1 - c.discount) * c.taxRate,
|
ca + (c.isHappyHour ? 0 : c.price) * c.quantity * (1 - c.discount) * c.taxRate,
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
@ -303,7 +308,7 @@ export class BillService {
|
|||||||
this.data
|
this.data
|
||||||
.filter((x) => !x.isKot)
|
.filter((x) => !x.isKot)
|
||||||
.reduce(
|
.reduce(
|
||||||
(ca: number, c: Inventory) =>
|
(ca: number, c: BillViewItem) =>
|
||||||
ca + (c.isHappyHour ? 0 : c.price) * c.quantity * (1 - c.discount) * (1 + c.taxRate),
|
ca + (c.isHappyHour ? 0 : c.price) * c.quantity * (1 - c.discount) * (1 + c.taxRate),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
@ -327,7 +332,9 @@ export class BillService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
splitBill(table: Table): Observable<boolean> {
|
splitBill(table: Table): Observable<boolean> {
|
||||||
const inventoriesToMove: string[] = this.selection.selected.map((x: any) => x.id);
|
const inventoriesToMove: string[] = this.selection.selected.map(
|
||||||
|
(x: BillViewItem) => x.id as string,
|
||||||
|
);
|
||||||
return this.ser.splitBill(this.bill.id as string, inventoriesToMove, table);
|
return this.ser.splitBill(this.bill.id as string, inventoriesToMove, table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,12 +16,12 @@ export class Bill {
|
|||||||
kotId: string;
|
kotId: string;
|
||||||
table: Table;
|
table: Table;
|
||||||
guest: GuestBook;
|
guest: GuestBook;
|
||||||
settlements: any[];
|
// settlements: any[];
|
||||||
voidReason: string;
|
voidReason: string;
|
||||||
voucherType: string;
|
voucherType: string;
|
||||||
serial: number;
|
serial: number;
|
||||||
kots: Kot[];
|
kots: Kot[];
|
||||||
reprints: any[];
|
// reprints: any[];
|
||||||
|
|
||||||
get dateTip(): string {
|
get dateTip(): string {
|
||||||
return this.date;
|
return this.date;
|
||||||
@ -46,12 +46,12 @@ export class Bill {
|
|||||||
this.kotId = '';
|
this.kotId = '';
|
||||||
this.table = new Table();
|
this.table = new Table();
|
||||||
this.guest = new GuestBook();
|
this.guest = new GuestBook();
|
||||||
this.settlements = [];
|
// this.settlements = [];
|
||||||
this.voidReason = '';
|
this.voidReason = '';
|
||||||
this.voucherType = '';
|
this.voucherType = '';
|
||||||
this.serial = 0;
|
this.serial = 0;
|
||||||
this.kots = [];
|
this.kots = [];
|
||||||
this.reprints = [];
|
// this.reprints = [];
|
||||||
Object.assign(this, init);
|
Object.assign(this, init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import { DataSource } from '@angular/cdk/collections';
|
import { DataSource } from '@angular/cdk/collections';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
export class BillsDataSource extends DataSource<any> {
|
import { BillViewItem } from '../../core/bill-view-item';
|
||||||
constructor(private data: Observable<any[]>) {
|
|
||||||
|
export class BillsDataSource extends DataSource<BillViewItem> {
|
||||||
|
constructor(private data: Observable<BillViewItem[]>) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(): Observable<any[]> {
|
connect(): Observable<BillViewItem[]> {
|
||||||
return this.data;
|
return this.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@
|
|||||||
<ng-container matColumnDef="select">
|
<ng-container matColumnDef="select">
|
||||||
<mat-cell *matCellDef="let row">
|
<mat-cell *matCellDef="let row">
|
||||||
<mat-checkbox
|
<mat-checkbox
|
||||||
*ngIf="row.oldKot"
|
*ngIf="row.isOldKot"
|
||||||
(change)="$event ? masterToggle(row) : null"
|
(change)="$event ? masterToggle(row) : null"
|
||||||
[checked]="bs.selection.hasValue() && isAllSelected(row)"
|
[checked]="bs.selection.hasValue() && isAllSelected(row)"
|
||||||
[indeterminate]="isAnySelected(row)"
|
[indeterminate]="isAnySelected(row)"
|
||||||
@ -70,7 +70,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
<!-- Info Column -->
|
<!-- Info Column -->
|
||||||
<ng-container matColumnDef="info">
|
<ng-container matColumnDef="info">
|
||||||
<mat-cell *matCellDef="let row" [class.blue800]="row.newKot">
|
<mat-cell *matCellDef="let row" [class.blue800]="row.isNewKot">
|
||||||
<span>
|
<span>
|
||||||
{{ row.info }}
|
{{ row.info }}
|
||||||
</span>
|
</span>
|
||||||
@ -123,7 +123,12 @@
|
|||||||
>
|
>
|
||||||
<mat-icon class="del">assignment</mat-icon>
|
<mat-icon class="del">assignment</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button (click)="moveKot(row)" [disabled]="row.newKot" *ngIf="row.isKot">
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
(click)="moveKot(row)"
|
||||||
|
[disabled]="row.isKot && !row.id"
|
||||||
|
*ngIf="row.isKot"
|
||||||
|
>
|
||||||
<mat-icon class="del">open_in_new</mat-icon>
|
<mat-icon class="del">open_in_new</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
@ -166,8 +171,8 @@
|
|||||||
<mat-header-row *matHeaderRowDef="['table-title', 'table-details']"></mat-header-row>
|
<mat-header-row *matHeaderRowDef="['table-title', 'table-details']"></mat-header-row>
|
||||||
<mat-row
|
<mat-row
|
||||||
*matRowDef="let row; columns: displayedColumns"
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
[class.blue400]="row.oldKot"
|
[class.blue400]="row.isOldKot"
|
||||||
[class.blue800]="row.newKot"
|
[class.blue800]="row.isNewKot"
|
||||||
[class.red100]="row.isPrinted"
|
[class.red100]="row.isPrinted"
|
||||||
></mat-row>
|
></mat-row>
|
||||||
<mat-footer-row *matFooterRowDef="['net-title', 'net-amount']"></mat-footer-row>
|
<mat-footer-row *matFooterRowDef="['net-title', 'net-amount']"></mat-footer-row>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { Observable } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { AuthService } from '../../auth/auth.service';
|
import { AuthService } from '../../auth/auth.service';
|
||||||
|
import { BillViewItem } from '../../core/bill-view-item';
|
||||||
import { Table } from '../../core/table';
|
import { Table } from '../../core/table';
|
||||||
import { ToasterService } from '../../core/toaster.service';
|
import { ToasterService } from '../../core/toaster.service';
|
||||||
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
|
import { ConfirmDialogComponent } from '../../shared/confirm-dialog/confirm-dialog.component';
|
||||||
@ -68,7 +69,7 @@ export class BillsComponent implements OnInit {
|
|||||||
isAllSelected(kot: Kot) {
|
isAllSelected(kot: Kot) {
|
||||||
return this.bs.data
|
return this.bs.data
|
||||||
.filter((x) => x.kotId === kot.id)
|
.filter((x) => x.kotId === kot.id)
|
||||||
.reduce((p: boolean, c: any) => p && this.bs.selection.isSelected(c), true);
|
.reduce((p: boolean, c: BillViewItem) => p && this.bs.selection.isSelected(c), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
isAnySelected(kot: Kot) {
|
isAnySelected(kot: Kot) {
|
||||||
@ -76,7 +77,7 @@ export class BillsComponent implements OnInit {
|
|||||||
let found = 0;
|
let found = 0;
|
||||||
this.bs.data
|
this.bs.data
|
||||||
.filter((x) => x.kotId === kot.id)
|
.filter((x) => x.kotId === kot.id)
|
||||||
.forEach((c: any) => {
|
.forEach((c: BillViewItem) => {
|
||||||
total += 1;
|
total += 1;
|
||||||
if (this.bs.selection.isSelected(c)) {
|
if (this.bs.selection.isSelected(c)) {
|
||||||
found += 1;
|
found += 1;
|
||||||
@ -94,11 +95,11 @@ export class BillsComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
addOne(item: any): void {
|
addOne(item: BillViewItem): void {
|
||||||
this.bs.addOne(item);
|
this.bs.addOne(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
quantity(item: any): void {
|
quantity(item: BillViewItem): void {
|
||||||
const dialogRef = this.dialog.open(QuantityComponent, {
|
const dialogRef = this.dialog.open(QuantityComponent, {
|
||||||
// width: '750px',
|
// width: '750px',
|
||||||
data: item.quantity,
|
data: item.quantity,
|
||||||
@ -123,16 +124,16 @@ export class BillsComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
subtractOne(item: any): void {
|
subtractOne(item: BillViewItem): void {
|
||||||
const canEdit = this.auth.allowed('edit-printed-product');
|
const canEdit = this.auth.allowed('edit-printed-product');
|
||||||
this.bs.subtractOne(item, canEdit);
|
this.bs.subtractOne(item, canEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeItem(item: any): void {
|
removeItem(item: BillViewItem): void {
|
||||||
this.bs.removeItem(item);
|
this.bs.removeItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier(item: any): void {
|
modifier(item: BillViewItem): void {
|
||||||
this.bs.modifier(item);
|
this.bs.modifier(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +203,7 @@ export class BillsComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
rowQuantityDisabled(row: any) {
|
rowQuantityDisabled(row: BillViewItem) {
|
||||||
if (!row.isPrinted) {
|
if (!row.isPrinted) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { DiscountDataSource } from './discount-datasource';
|
|||||||
styleUrls: ['./discount.component.css'],
|
styleUrls: ['./discount.component.css'],
|
||||||
})
|
})
|
||||||
export class DiscountComponent {
|
export class DiscountComponent {
|
||||||
list: any[] = [];
|
list: { name: string; discount: number }[] = [];
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
dataSource: DiscountDataSource = new DiscountDataSource([]);
|
dataSource: DiscountDataSource = new DiscountDataSource([]);
|
||||||
|
|
||||||
@ -20,12 +20,12 @@ export class DiscountComponent {
|
|||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<DiscountComponent>,
|
public dialogRef: MatDialogRef<DiscountComponent>,
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: Observable<any[]>,
|
@Inject(MAT_DIALOG_DATA) public data: Observable<{ name: string; discount: number }[]>,
|
||||||
) {
|
) {
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
discounts: '',
|
discounts: '',
|
||||||
});
|
});
|
||||||
this.data.subscribe((list: any[]) => {
|
this.data.subscribe((list: { name: string; discount: number }[]) => {
|
||||||
this.list = list;
|
this.list = list;
|
||||||
this.form.setControl(
|
this.form.setControl(
|
||||||
'discounts',
|
'discounts',
|
||||||
|
|||||||
@ -249,7 +249,7 @@ export class SalesHomeComponent {
|
|||||||
}
|
}
|
||||||
const amount = this.bs.amountVal();
|
const amount = this.bs.amountVal();
|
||||||
const type = this.bs.type();
|
const type = this.bs.type();
|
||||||
let obs: any;
|
let obs: Observable<boolean>;
|
||||||
if (type === 'NO_CHARGE' || type === 'STAFF') {
|
if (type === 'NO_CHARGE' || type === 'STAFF') {
|
||||||
obs = this.receivePaymentWithReason(type, amount);
|
obs = this.receivePaymentWithReason(type, amount);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||||
import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms';
|
import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { MatSelectChange } from '@angular/material/select';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
@ -127,7 +128,7 @@ export class SectionPrinterComponent implements OnInit {
|
|||||||
return this.list;
|
return this.list;
|
||||||
}
|
}
|
||||||
|
|
||||||
show(val: any) {
|
show(val: MatSelectChange) {
|
||||||
this.router.navigate(['/section-printers', val.value]);
|
this.router.navigate(['/section-printers', val.value]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,8 @@ import { Pipe, PipeTransform } from '@angular/core';
|
|||||||
name: 'clear',
|
name: 'clear',
|
||||||
})
|
})
|
||||||
export class ClearPipe implements PipeTransform {
|
export class ClearPipe implements PipeTransform {
|
||||||
transform(value: any): any {
|
transform(value: string | null): string {
|
||||||
|
if (value === null) return '';
|
||||||
return value === '₹ 0.00' || value === '0.00' ? '' : value;
|
return value === '₹ 0.00' || value === '0.00' ? '' : value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,6 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|||||||
export class ConfirmDialogComponent {
|
export class ConfirmDialogComponent {
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<ConfirmDialogComponent>,
|
public dialogRef: MatDialogRef<ConfirmDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
@Inject(MAT_DIALOG_DATA) public data: { title: string; content: string },
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|||||||
export class ImageDialogComponent {
|
export class ImageDialogComponent {
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<ImageDialogComponent>,
|
public dialogRef: MatDialogRef<ImageDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
@Inject(MAT_DIALOG_DATA) public data: string,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
close(): void {
|
close(): void {
|
||||||
|
|||||||
@ -5,16 +5,6 @@ import { evaluate, round } from 'mathjs';
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class MathService {
|
export class MathService {
|
||||||
// eslint-disable-next-line class-methods-use-this
|
|
||||||
journalAmount(amount: string = '', debit: number): any {
|
|
||||||
const val = this.parseAmount(amount, 2);
|
|
||||||
let newDebit = debit;
|
|
||||||
if (val < 0) {
|
|
||||||
newDebit *= -1;
|
|
||||||
}
|
|
||||||
return { debit: newDebit, amount: Math.abs(val) };
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
parseAmount(amount: string = '', rounding: number = 2): number {
|
parseAmount(amount: string = '', rounding: number = 2): number {
|
||||||
const cleaned = `${amount}`.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
const cleaned = `${amount}`.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||||
|
|||||||
3
bookie/src/app/shared/to-csv-type.ts
Normal file
3
bookie/src/app/shared/to-csv-type.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface ToCsvType {
|
||||||
|
[column: string]: string | number | boolean | null;
|
||||||
|
}
|
||||||
@ -1,15 +1,19 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { ToCsvType } from './to-csv-type';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ToCsvService {
|
export class ToCsvService {
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
toCsv(headers: any, data: any[]): string {
|
toCsv(headers: { [display: string]: string }, data: unknown[]): string {
|
||||||
const header = Object.keys(headers);
|
const header = Object.keys(headers);
|
||||||
const replacer = (key: string, value: string | number | null) => (value === null ? '' : value);
|
const replacer = (key: string, value: string | number | null) => (value === null ? '' : value);
|
||||||
const csv = data.map((row) =>
|
const csv = data.map((row) =>
|
||||||
header.map((fieldName) => JSON.stringify(row[headers[fieldName]], replacer)).join(','),
|
header
|
||||||
|
.map((fieldName) => JSON.stringify((row as ToCsvType)[headers[fieldName]], replacer))
|
||||||
|
.join(','),
|
||||||
);
|
);
|
||||||
csv.unshift(header.join(','));
|
csv.unshift(header.join(','));
|
||||||
return csv.join('\r\n');
|
return csv.join('\r\n');
|
||||||
|
|||||||
Reference in New Issue
Block a user