diff --git a/barker/barker/routers/auth/role.py b/barker/barker/routers/auth/role.py index ad1b37f..def4cab 100644 --- a/barker/barker/routers/auth/role.py +++ b/barker/barker/routers/auth/role.py @@ -1,6 +1,6 @@ import uuid -from typing import List, Optional +from typing import List import barker.schemas.auth as schemas @@ -31,7 +31,7 @@ def save( data: schemas.RoleIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), -): +) -> schemas.Role: try: item = Role(data.name) db.add(item) @@ -55,7 +55,7 @@ def update( data: schemas.RoleIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), -): +) -> schemas.Role: try: item: Role = db.query(Role).filter(Role.id == id_).first() item.name = data.name @@ -83,12 +83,12 @@ def add_permissions(role: Role, permissions: List[schemas.PermissionItem], db): role.permissions.remove(gp) -@router.delete("/{id_}") +@router.delete("/{id_}", response_model=schemas.RoleIn) def delete( id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), -): +) -> schemas.RoleIn: try: item: Role = db.query(Role).filter(Role.id == id_).first() if item is None: @@ -96,35 +96,34 @@ def delete( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Role not found", ) - else: - raise HTTPException( - status_code=status.HTTP_501_NOT_IMPLEMENTED, - detail="Role deletion not implemented", - ) + raise HTTPException( + status_code=status.HTTP_501_NOT_IMPLEMENTED, + detail="Role deletion not implemented", + ) except Exception: db.rollback() raise -@router.get("") +@router.get("", response_model=schemas.RoleIn) def show_blank( db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), -): - return role_info(None, db) +) -> schemas.RoleIn: + return blank_role_info(db) @router.get("/list", response_model=List[schemas.RoleList]) async def show_list( db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), -): +) -> List[schemas.RoleList]: return [ - { - "id": item.id, - "name": item.name, - "permissions": [p.name for p in sorted(item.permissions, key=lambda p: p.name)], - } + schemas.RoleList( + id=item.id, + name=item.name, + permissions=[p.name for p in sorted(item.permissions, key=lambda p: p.name)], + ) for item in db.query(Role).order_by(Role.name).all() ] @@ -134,30 +133,31 @@ def show_id( id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), -): +) -> schemas.Role: item: Role = db.query(Role).filter(Role.id == id_).first() return role_info(item, db) -def role_info(item: Optional[Role], db): - if item is None: - return { - "name": "", - "permissions": [ - {"id": p.id, "name": p.name, "enabled": False} - for p in db.query(Permission).order_by(Permission.name).all() - ], - } - else: - return { - "id": item.id, - "name": item.name, - "permissions": [ - { - "id": p.id, - "name": p.name, - "enabled": True if p in item.permissions else False, - } - for p in db.query(Permission).order_by(Permission.name).all() - ], - } +def role_info(item: Role, db: Session) -> schemas.Role: + return schemas.Role( + id=item.id, + name=item.name, + permissions=[ + schemas.PermissionItem( + id=p.id, + name=p.name, + enabled=True if p in item.permissions else False, + ) + for p in db.query(Permission).order_by(Permission.name).all() + ], + ) + + +def blank_role_info(db: Session) -> schemas.RoleIn: + return schemas.RoleIn( + name="", + permissions=[ + schemas.PermissionItem(id=p.id, name=p.name, enabled=False) + for p in db.query(Permission).order_by(Permission.name).all() + ], + ) diff --git a/barker/barker/routers/auth/user.py b/barker/barker/routers/auth/user.py index 0749e24..2184d73 100644 --- a/barker/barker/routers/auth/user.py +++ b/barker/barker/routers/auth/user.py @@ -1,6 +1,6 @@ import uuid -from typing import List, Optional +from typing import List import barker.schemas.auth as schemas @@ -145,12 +145,12 @@ def delete( raise -@router.get("") +@router.get("", response_model=schemas.UserIn) def show_blank( db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["users"]), -): - return user_info(None, db, user) +) -> schemas.UserIn: + return blank_user_info(db) @router.get("/list", response_model=List[schemas.UserList]) @@ -171,14 +171,6 @@ async def show_list( ] -@router.get("/active") -async def show_active(db: Session = Depends(get_db), user: UserToken = Depends(get_user)): - return [ - {"name": item.name} - for item in db.query(User).filter(User.locked_out == False).order_by(User.name) # noqa: E712 - ] - - @router.get("/{id_}", response_model=schemas.User) def show_id( id_: uuid.UUID, @@ -189,27 +181,29 @@ def show_id( return user_info(item, db, user) -def user_info(item: Optional[User], db: Session, user: UserToken) -> schemas.User: - if item is None: - return schemas.User( - name="", - lockedOut=False, - roles=[{"id": r.id, "name": r.name, "enabled": False} for r in db.query(Role).order_by(Role.name).all()], - ) - else: - return schemas.User( - id=item.id, - name=item.name, - password="", - lockedOut=item.locked_out, - roles=[ - { - "id": r.id, - "name": r.name, - "enabled": True if r in item.roles else False, - } - for r in db.query(Role).order_by(Role.name).all() - ] - if "users" in user.permissions - else [], - ) +def user_info(item: User, db: Session, user: UserToken) -> schemas.User: + return schemas.User( + id=item.id, + name=item.name, + password="", + lockedOut=item.locked_out, + roles=[ + { + "id": r.id, + "name": r.name, + "enabled": True if r in item.roles else False, + } + for r in db.query(Role).order_by(Role.name).all() + ] + if "users" in user.permissions + else [], + ) + + +def blank_user_info(db: Session) -> schemas.UserIn: + return schemas.UserIn( + name="", + password="", + lockedOut=False, + roles=[{"id": r.id, "name": r.name, "enabled": False} for r in db.query(Role).order_by(Role.name).all()], + ) diff --git a/barker/barker/routers/customer.py b/barker/barker/routers/customer.py index e7427a1..45939ff 100644 --- a/barker/barker/routers/customer.py +++ b/barker/barker/routers/customer.py @@ -1,6 +1,6 @@ import uuid -from typing import Optional +from typing import List import barker.schemas.master as schemas @@ -31,7 +31,7 @@ def save( data: schemas.CustomerIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["customers"]), -): +) -> schemas.Customer: try: item = Customer(name=data.name, phone=data.phone, address=data.address) db.add(item) @@ -54,7 +54,7 @@ def update( data: schemas.CustomerIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["customers"]), -): +) -> schemas.Customer: try: item: Customer = db.query(Customer).filter(Customer.id == id_).first() item.name = data.name @@ -93,35 +93,37 @@ def delete( raise -@router.get("") +@router.get("", response_model=schemas.CustomerIn) def show_blank( db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["customers"]), -): - return customer_info(None) +) -> schemas.CustomerIn: + return blank_customer_info() -@router.get("/list") -def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get_user)): +@router.get("/list", response_model=List[schemas.Customer]) +def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get_user)) -> List[schemas.Customer]: return [customer_info(item) for item in db.query(Customer).order_by(Customer.name).all()] -@router.get("/{id_}") +@router.get("/{id_}", response_model=schemas.Customer) def show_id( id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["customers"]), -): +) -> schemas.Customer: item: Customer = db.query(Customer).filter(Customer.id == id_).first() return customer_info(item) -def customer_info(item: Optional[Customer]): - if item is None: - return {"name": "", "address": "", "phone": ""} - return { - "id": item.id, - "name": item.name, - "address": item.address, - "phone": item.phone, - } +def customer_info(item: Customer) -> schemas.Customer: + return schemas.Customer( + id=item.id, + name=item.name, + address=item.address, + phone=item.phone, + ) + + +def blank_customer_info() -> schemas.CustomerIn: + return schemas.CustomerIn(name="", address="", phone="") diff --git a/barker/barker/routers/reports/cashier_report.py b/barker/barker/routers/reports/cashier_report.py index 2ba6d25..376572e 100644 --- a/barker/barker/routers/reports/cashier_report.py +++ b/barker/barker/routers/reports/cashier_report.py @@ -34,13 +34,13 @@ def get_db() -> Session: db.close() -@router.get("/active") +@router.get("/active", response_model=List[UserLink]) def active_cashiers( start_date: date = Depends(report_start_date), finish_date: date = Depends(report_finish_date), db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["cashier-report"]), -): +) -> List[UserLink]: if (date.today() - start_date).days > 5 and "audit" not in user.permissions: raise HTTPException( diff --git a/barker/barker/routers/voucher/merge_move.py b/barker/barker/routers/voucher/merge_move.py index 6f64da4..2c08554 100644 --- a/barker/barker/routers/voucher/merge_move.py +++ b/barker/barker/routers/voucher/merge_move.py @@ -12,7 +12,7 @@ from sqlalchemy.orm import Session from ...core.security import get_current_active_user as get_user from ...db.session import SessionLocal -from ...models import Kot, Overview, Settlement, Voucher +from ...models import Kot, Overview, Settlement, Voucher, VoucherType from ...routers.voucher import do_update_settlements, do_update_table, get_bill_id from ...schemas.auth import UserToken @@ -36,12 +36,15 @@ def merge_kot( user: UserToken = Security(get_user, scopes=["merge-kots"]), ): try: + check_if_voucher_is_unprinted(data.voucher_id, db) kots: int = db.query(func.count(Kot.id)).filter(Kot.voucher_id == data.voucher_id).scalar() if kots <= 1: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Single kot cannot be used, move table instead. This error should not show up in frontend", ) + check_if_voucher_is_unprinted(data.new_voucher_id, db) + db.query(Kot).filter(Kot.id == data.kot_id, Kot.voucher_id == data.voucher_id).update( {Kot.voucher_id: data.new_voucher_id} ) @@ -65,8 +68,8 @@ def move_kot( user: UserToken = Security(get_user, scopes=["move-kot-to-new-table"]), ): try: - # TODO: Check if this is the only kot, then move table instead of move kot. now = datetime.now() + check_if_voucher_is_unprinted(data.voucher_id, db) kots: int = db.query(func.count(Kot.id)).filter(Kot.voucher_id == data.voucher_id).scalar() if kots <= 1: raise HTTPException( @@ -134,6 +137,8 @@ def merge_table( user: UserToken = Security(get_user, scopes=["merge-tables"]), ): try: + check_if_voucher_is_unprinted(data.voucher_id, db) + check_if_voucher_is_unprinted(data.new_voucher_id, db) db.query(Kot).filter(Kot.voucher_id == data.voucher_id).update({Kot.voucher_id: data.new_voucher_id}) db.query(Overview).filter(Overview.voucher_id == data.voucher_id).delete() db.query(Settlement).filter(Settlement.voucher_id == data.voucher_id).delete() @@ -155,3 +160,17 @@ def update_settlements(vouchers: List[uuid.UUID], db: Session): for v in vouchers: voucher: Voucher = db.query(Voucher).filter(Voucher.id == v).first() do_update_settlements(voucher, [], db) + + +def check_if_voucher_is_unprinted(voucher_id: uuid.UUID, db: Session) -> None: + voucher_type: VoucherType = db.query(Voucher.voucher_type).filter(Voucher.id == voucher_id).scalar() + if not voucher_type: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Original bill not found", + ) + if voucher_type != VoucherType.KOT: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Bill is printed or void.", + ) diff --git a/bookie/.gitignore b/bookie/.gitignore index ee5c9d8..86d943a 100644 --- a/bookie/.gitignore +++ b/bookie/.gitignore @@ -4,10 +4,16 @@ /dist /tmp /out-tsc +# Only exists if Bazel was run +/bazel-out # dependencies /node_modules +# profiling files +chrome-profiler-events*.json +speed-measure-plugin*.json + # IDEs and editors /.idea .project @@ -23,6 +29,7 @@ !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +.history/* # misc /.sass-cache diff --git a/bookie/angular.json b/bookie/angular.json index 078f670..4d181a2 100644 --- a/bookie/angular.json +++ b/bookie/angular.json @@ -44,7 +44,6 @@ "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "extractLicenses": true, "vendorChunk": false, @@ -52,8 +51,8 @@ "budgets": [ { "type": "initial", - "maximumWarning": "1mb", - "maximumError": "2mb" + "maximumWarning": "500kb", + "maximumError": "1mb" }, { "type": "anyComponentStyle", @@ -89,15 +88,15 @@ "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", + "assets": [ + "src/favicon.ico", + "src/assets" + ], "styles": [ "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "src/styles.css" ], - "scripts": [], - "assets": [ - "src/favicon.ico", - "src/assets" - ] + "scripts": [] } }, "lint": { diff --git a/bookie/package.json b/bookie/package.json index 77e1c16..124b8dd 100644 --- a/bookie/package.json +++ b/bookie/package.json @@ -14,60 +14,58 @@ }, "private": true, "dependencies": { - "@angular/animations": "^10.1.4", - "@angular/cdk": "^10.2.4", - "@angular/common": "^10.1.4", - "@angular/compiler": "^10.1.4", - "@angular/core": "^10.1.4", - "@angular/flex-layout": "^10.0.0-beta.32", - "@angular/forms": "^10.1.4", - "@angular/material": "^10.2.4", - "@angular/material-moment-adapter": "^10.2.4", - "@angular/platform-browser": "^10.1.4", - "@angular/platform-browser-dynamic": "^10.1.4", - "@angular/router": "^10.1.4", - "core-js": "^3.6.5", - "mathjs": "^7.4.0", + "@angular/animations": "^11.0.0", + "@angular/cdk": "^11.0.0", + "@angular/common": "^11.0.0", + "@angular/compiler": "^11.0.0", + "@angular/core": "^11.0.0", + "@angular/flex-layout": "^11.0.0-beta.33", + "@angular/forms": "^11.0.0", + "@angular/material": "^11.0.0", + "@angular/material-moment-adapter": "^11.0.0", + "@angular/platform-browser": "^11.0.0", + "@angular/platform-browser-dynamic": "^11.0.0", + "@angular/router": "^11.0.0", + "mathjs": "^8.0.1", "moment": "^2.29.1", "rxjs": "^6.6.3", - "tslib": "^2.0.2", - "zone.js": "^0.10.3" + "tslib": "^2.0.0", + "zone.js": "^0.11.3" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.1001.4", - "@angular-eslint/builder": "^0.5.0-beta.2", - "@angular-eslint/eslint-plugin": "^0.5.0-beta.2", - "@angular-eslint/eslint-plugin-template": "^0.5.0-beta.2", - "@angular-eslint/schematics": "^0.5.0-beta.2", - "@angular-eslint/template-parser": "^0.5.0-beta.2", - "@angular/cli": "^10.1.4", - "@angular/compiler-cli": "^10.1.4", - "@angular/language-service": "^10.1.4", - "@types/jasmine": "^3.5.14", - "@types/jasminewd2": "^2.0.3", - "@types/node": "^14.11.5", - "@typescript-eslint/eslint-plugin": "^4.4.0", - "@typescript-eslint/parser": "^4.3.0", - "codelyzer": "^6.0.1", - "eslint": "^7.10.0", - "eslint-config-airbnb-typescript": "^11.0.0", - "eslint-config-prettier": "^6.12.0", + "@angular-devkit/build-angular": "~0.1100.1", + "@angular-eslint/builder": "^0.8.0-beta.0", + "@angular-eslint/eslint-plugin": "^0.8.0-beta.0", + "@angular-eslint/eslint-plugin-template": "^0.8.0-beta.0", + "@angular-eslint/schematics": "^0.8.0-beta.0", + "@angular-eslint/template-parser": "^0.8.0-beta.0", + "@angular/cli": "^11.0.1", + "@angular/compiler-cli": "^11.0.0", + "@angular/language-service": "^11.0.0", + "@types/jasmine": "~3.6.0", + "@types/mathjs": "^6.0.7", + "@types/node": "^14.14.7", + "@typescript-eslint/eslint-plugin": "^4.8.0", + "@typescript-eslint/parser": "^4.8.0", + "eslint": "^7.13.0", + "eslint-config-airbnb-typescript": "^12.0.0", + "eslint-config-prettier": "^6.15.0", "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jsdoc": "^30.6.3", + "eslint-plugin-jsdoc": "^30.7.8", "husky": "^4.3.0", "jasmine-core": "^3.6.0", "jasmine-spec-reporter": "^6.0.0", "karma": "^5.2.3", "karma-chrome-launcher": "~3.1.0", - "karma-coverage-istanbul-reporter": "~3.0.2", - "karma-jasmine": "^4.0.1", + "karma-coverage": "~2.0.3", + "karma-jasmine": "^4.0.0", "karma-jasmine-html-reporter": "^1.5.0", - "lint-staged": "^10.4.0", + "lint-staged": "^10.5.1", "prettier": "^2.1.2", "protractor": "~7.0.0", "standard-version": "^9.0.0", "ts-node": "^9.0.0", - "typescript": "^4.0.3" + "typescript": "^4.0.5" }, "husky": { "hooks": { diff --git a/bookie/src/app/app-routing.module.ts b/bookie/src/app/app-routing.module.ts index 28faeef..b68f66c 100644 --- a/bookie/src/app/app-routing.module.ts +++ b/bookie/src/app/app-routing.module.ts @@ -137,6 +137,7 @@ const routes: Routes = [ imports: [ RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload', + relativeLinkResolution: 'legacy', }), ], exports: [RouterModule], diff --git a/bookie/src/app/app.module.ts b/bookie/src/app/app.module.ts index 0682ebb..6983993 100644 --- a/bookie/src/app/app.module.ts +++ b/bookie/src/app/app.module.ts @@ -14,7 +14,10 @@ import { MatGridListModule } from '@angular/material/grid-list'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatMenuModule } from '@angular/material/menu'; +import { MatPaginatorModule } from '@angular/material/paginator'; import { MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -53,6 +56,9 @@ registerLocaleData(enIN); ReactiveFormsModule, CoreModule, SharedModule, + MatTableModule, + MatPaginatorModule, + MatSortModule, ], providers: [{ provide: LOCALE_ID, useValue: 'en-IN' }], bootstrap: [AppComponent], diff --git a/bookie/src/app/auth/auth-guard.service.ts b/bookie/src/app/auth/auth-guard.service.ts index 7df8c60..23d6d75 100644 --- a/bookie/src/app/auth/auth-guard.service.ts +++ b/bookie/src/app/auth/auth-guard.service.ts @@ -24,7 +24,7 @@ export class AuthGuard implements CanActivate { this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); return false; } - if (permission !== undefined && user.perms.indexOf(permission) === -1) { + if (permission !== undefined && !this.authService.allowed(permission)) { this.toaster.show('Danger', 'You do not have the permission to access this area.'); return false; } diff --git a/bookie/src/app/auth/auth.service.ts b/bookie/src/app/auth/auth.service.ts index 57ae7ac..87347ca 100644 --- a/bookie/src/app/auth/auth.service.ts +++ b/bookie/src/app/auth/auth.service.ts @@ -14,8 +14,8 @@ const JWT_USER = 'JWT_USER'; @Injectable({ providedIn: 'root' }) export class AuthService { - private currentUserSubject: BehaviorSubject; - public currentUser: Observable; + private currentUserSubject: BehaviorSubject = new BehaviorSubject(null); + public currentUser: Observable; public device: Device; constructor(private http: HttpClient, private cs: CookieService) { @@ -26,7 +26,7 @@ export class AuthService { this.device = new Device({ id: deviceId, name: device }); } - static parseJwt(token): User { + static parseJwt(token: string): User { const base64Url = token.split('.')[1]; const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); const jsonPayload = decodeURIComponent( @@ -48,18 +48,22 @@ export class AuthService { }); } - checkStorage(): User { - const existingToken: User = JSON.parse(localStorage.getItem(JWT_USER)); + checkStorage(): User | null { + const storageToken = localStorage.getItem(JWT_USER); + let existingToken: User | null = null; + if (storageToken !== null) { + existingToken = JSON.parse(storageToken); + } if (existingToken === null || Date.now() > existingToken.exp * 1000) { localStorage.removeItem(JWT_USER); - this.currentUserSubject = new BehaviorSubject(null); + this.currentUserSubject.next(null); return null; } - this.currentUserSubject = new BehaviorSubject(existingToken); + this.currentUserSubject.next(existingToken); return existingToken; } - public get user(): User { + public get user(): User | null { let val = this.currentUserSubject.value; if (val == null) { return val; @@ -69,7 +73,7 @@ export class AuthService { val = this.checkStorage(); } if (val == null) { - return null; + return new User(); } expired = Date.now() > val.exp * 1000; if (expired) { @@ -99,7 +103,11 @@ export class AuthService { } needsRefreshing(): boolean { - return Date.now() > (this.user.exp - environment.ACCESS_TOKEN_REFRESH_MINUTES * 60) * 1000; + const { user } = this; + if (user === null) { + return true; + } + return Date.now() > (user.exp - environment.ACCESS_TOKEN_REFRESH_MINUTES * 60) * 1000; } logout() { @@ -122,4 +130,12 @@ export class AuthService { }), ); } + + allowed(permission: string): boolean { + const { user } = this; + if (user == null || user.perms.indexOf(permission) === -1) { + return false; + } + return true; + } } diff --git a/bookie/src/app/auth/login/login.component.ts b/bookie/src/app/auth/login/login.component.ts index 06ed34c..80fea2c 100644 --- a/bookie/src/app/auth/login/login.component.ts +++ b/bookie/src/app/auth/login/login.component.ts @@ -12,7 +12,7 @@ import { AuthService } from '../auth.service'; styleUrls: ['./login.component.css'], }) export class LoginComponent implements OnInit, AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement: ElementRef; + @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; form: FormGroup; hide: boolean; showOtp: boolean; @@ -29,10 +29,10 @@ export class LoginComponent implements OnInit, AfterViewInit { ) { this.hide = true; this.showOtp = false; - this.createForm(); - } + this.clientId = ''; + this.returnUrl = ''; - createForm() { + // Create form this.form = this.fb.group({ username: '', password: '', @@ -46,7 +46,9 @@ export class LoginComponent implements OnInit, AfterViewInit { ngAfterViewInit() { setTimeout(() => { - this.nameElement.nativeElement.focus(); + if (this.nameElement !== undefined) { + this.nameElement.nativeElement.focus(); + } }, 0); } diff --git a/bookie/src/app/beer-sale-report/beer-sale-export-header-interface.ts b/bookie/src/app/beer-sale-report/beer-sale-export-header-interface.ts new file mode 100644 index 0000000..16572e3 --- /dev/null +++ b/bookie/src/app/beer-sale-report/beer-sale-export-header-interface.ts @@ -0,0 +1,3 @@ +export interface BeerSaleExportHeaderInterface { + [header: string]: string; +} diff --git a/bookie/src/app/beer-sale-report/beer-sale-report-item.ts b/bookie/src/app/beer-sale-report/beer-sale-report-item.ts index 25fd5fd..4af9ff2 100644 --- a/bookie/src/app/beer-sale-report/beer-sale-report-item.ts +++ b/bookie/src/app/beer-sale-report/beer-sale-report-item.ts @@ -2,4 +2,11 @@ export class BeerSaleReportItem { date: string; name: string; quantity: number; + + public constructor(init?: Partial) { + this.date = ''; + this.name = ''; + this.quantity = 0; + Object.assign(this, init); + } } diff --git a/bookie/src/app/beer-sale-report/beer-sale-report.component.spec.ts b/bookie/src/app/beer-sale-report/beer-sale-report.component.spec.ts index 8598e9b..8f37366 100644 --- a/bookie/src/app/beer-sale-report/beer-sale-report.component.spec.ts +++ b/bookie/src/app/beer-sale-report/beer-sale-report.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { BeerSaleReportComponent } from './beer-sale-report.component'; @@ -6,11 +6,13 @@ describe('BeerSaleReportComponent', () => { let component: BeerSaleReportComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [BeerSaleReportComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [BeerSaleReportComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(BeerSaleReportComponent); diff --git a/bookie/src/app/beer-sale-report/beer-sale-report.component.ts b/bookie/src/app/beer-sale-report/beer-sale-report.component.ts index 23752db..784b4dc 100644 --- a/bookie/src/app/beer-sale-report/beer-sale-report.component.ts +++ b/bookie/src/app/beer-sale-report/beer-sale-report.component.ts @@ -5,6 +5,7 @@ import * as moment from 'moment'; import { ToCsvService } from '../shared/to-csv.service'; +import { BeerSaleExportHeaderInterface } from './beer-sale-export-header-interface'; import { BeerSaleReport } from './beer-sale-report'; import { BeerSaleReportDataSource } from './beer-sale-report-datasource'; @@ -14,9 +15,9 @@ import { BeerSaleReportDataSource } from './beer-sale-report-datasource'; styleUrls: ['./beer-sale-report.component.css'], }) export class BeerSaleReportComponent implements OnInit { - dataSource: BeerSaleReportDataSource; + info: BeerSaleReport = new BeerSaleReport(); + dataSource: BeerSaleReportDataSource = new BeerSaleReportDataSource(this.info.data); form: FormGroup; - info: BeerSaleReport; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns: string[] = ['date']; @@ -27,11 +28,16 @@ export class BeerSaleReportComponent implements OnInit { private fb: FormBuilder, private toCsv: ToCsvService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + startDate: '', + finishDate: '', + }); } ngOnInit() { - this.route.data.subscribe((data: { info: BeerSaleReport }) => { + this.route.data.subscribe((value) => { + const data = value as { info: BeerSaleReport }; this.info = data.info; this.displayedColumns = ['date'].concat(this.info.headers); this.form.setValue({ @@ -52,32 +58,21 @@ export class BeerSaleReportComponent implements OnInit { }); } - createForm() { - this.form = this.fb.group({ - startDate: '', - finishDate: '', - }); - } - getInfo(): BeerSaleReport { const formModel = this.form.value; - return { + return new BeerSaleReport({ startDate: moment(formModel.startDate).format('DD-MMM-YYYY'), finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'), - }; + }); } exportCsv() { - const headers = this.info.headers.reduce( - (a, c) => { - a[c] = c; - return a; - }, - { - Date: 'date', - }, - ); + const init: BeerSaleExportHeaderInterface = { Date: 'date' }; + const headers = this.info.headers.reduce((a, c) => { + a[c] = c; + return a; + }, init); const csvData = new Blob([this.toCsv.toCsv(headers, this.info.data)], { type: 'text/csv;charset=utf-8;', }); diff --git a/bookie/src/app/beer-sale-report/beer-sale-report.service.ts b/bookie/src/app/beer-sale-report/beer-sale-report.service.ts index e094d86..2713230 100644 --- a/bookie/src/app/beer-sale-report/beer-sale-report.service.ts +++ b/bookie/src/app/beer-sale-report/beer-sale-report.service.ts @@ -16,7 +16,7 @@ const serviceName = 'BeerSaleReportService'; export class BeerSaleReportService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(startDate: string, finishDate): Observable { + get(startDate: string | null, finishDate: string | null): Observable { const options = { params: new HttpParams() }; if (startDate !== null) { options.params = options.params.set('s', startDate); diff --git a/bookie/src/app/beer-sale-report/beer-sale-report.ts b/bookie/src/app/beer-sale-report/beer-sale-report.ts index 283977f..7dc99bf 100644 --- a/bookie/src/app/beer-sale-report/beer-sale-report.ts +++ b/bookie/src/app/beer-sale-report/beer-sale-report.ts @@ -3,6 +3,14 @@ import { BeerSaleReportItem } from './beer-sale-report-item'; export class BeerSaleReport { startDate: string; finishDate: string; - headers?: string[]; - data?: BeerSaleReportItem[]; + headers: string[]; + data: BeerSaleReportItem[]; + + public constructor(init?: Partial) { + this.startDate = ''; + this.finishDate = ''; + this.data = []; + this.headers = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/bill-settlement-report/bill-settlement-report-item.ts b/bookie/src/app/bill-settlement-report/bill-settlement-report-item.ts index e3180f7..7e6f3a5 100644 --- a/bookie/src/app/bill-settlement-report/bill-settlement-report-item.ts +++ b/bookie/src/app/bill-settlement-report/bill-settlement-report-item.ts @@ -3,4 +3,12 @@ export class BillSettlementReportItem { billId: string; amount: number; settlement: string; + + public constructor(init?: Partial) { + this.date = ''; + this.billId = ''; + this.amount = 0; + this.settlement = ''; + Object.assign(this, init); + } } diff --git a/bookie/src/app/bill-settlement-report/bill-settlement-report.component.spec.ts b/bookie/src/app/bill-settlement-report/bill-settlement-report.component.spec.ts index 95afcd3..48758bd 100644 --- a/bookie/src/app/bill-settlement-report/bill-settlement-report.component.spec.ts +++ b/bookie/src/app/bill-settlement-report/bill-settlement-report.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { BillSettlementReportComponent } from './bill-settlement-report.component'; @@ -6,11 +6,13 @@ describe('BillSettlementReportComponent', () => { let component: BillSettlementReportComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [BillSettlementReportComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [BillSettlementReportComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(BillSettlementReportComponent); diff --git a/bookie/src/app/bill-settlement-report/bill-settlement-report.component.ts b/bookie/src/app/bill-settlement-report/bill-settlement-report.component.ts index 262fb71..a3ed2b1 100644 --- a/bookie/src/app/bill-settlement-report/bill-settlement-report.component.ts +++ b/bookie/src/app/bill-settlement-report/bill-settlement-report.component.ts @@ -14,9 +14,12 @@ import { BillSettlementReportDataSource } from './bill-settlement-report-datasou styleUrls: ['./bill-settlement-report.component.css'], }) export class BillSettlementReportComponent implements OnInit { - dataSource: BillSettlementReportDataSource; + info: BillSettlementReport = new BillSettlementReport(); + dataSource: BillSettlementReportDataSource = new BillSettlementReportDataSource( + this.info.amounts, + ); + form: FormGroup; - info: BillSettlementReport; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['date', 'billId', 'amount', 'settlement']; @@ -27,11 +30,16 @@ export class BillSettlementReportComponent implements OnInit { private fb: FormBuilder, private toCsv: ToCsvService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + startDate: '', + finishDate: '', + }); } ngOnInit() { - this.route.data.subscribe((data: { info: BillSettlementReport }) => { + this.route.data.subscribe((value) => { + const data = value as { info: BillSettlementReport }; this.info = data.info; this.form.setValue({ startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(), @@ -51,20 +59,13 @@ export class BillSettlementReportComponent implements OnInit { }); } - createForm() { - this.form = this.fb.group({ - startDate: '', - finishDate: '', - }); - } - getInfo(): BillSettlementReport { const formModel = this.form.value; - return { + return new BillSettlementReport({ startDate: moment(formModel.startDate).format('DD-MMM-YYYY'), finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'), - }; + }); } exportCsv() { diff --git a/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts b/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts index 5a5484e..cb2b82c 100644 --- a/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts +++ b/bookie/src/app/bill-settlement-report/bill-settlement-report.service.ts @@ -16,7 +16,7 @@ const serviceName = 'BillSettlementReportService'; export class BillSettlementReportService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(startDate: string, finishDate): Observable { + get(startDate: string | null, finishDate: string | null): Observable { const options = { params: new HttpParams() }; if (startDate !== null) { options.params = options.params.set('s', startDate); diff --git a/bookie/src/app/bill-settlement-report/bill-settlement-report.ts b/bookie/src/app/bill-settlement-report/bill-settlement-report.ts index 68fe42f..9052e50 100644 --- a/bookie/src/app/bill-settlement-report/bill-settlement-report.ts +++ b/bookie/src/app/bill-settlement-report/bill-settlement-report.ts @@ -3,5 +3,12 @@ import { BillSettlementReportItem } from './bill-settlement-report-item'; export class BillSettlementReport { startDate: string; finishDate: string; - amounts?: BillSettlementReportItem[]; + amounts: BillSettlementReportItem[]; + + public constructor(init?: Partial) { + this.startDate = ''; + this.finishDate = ''; + this.amounts = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/cashier-report/cashier-report-display-item.ts b/bookie/src/app/cashier-report/cashier-report-display-item.ts index c318683..d001af6 100644 --- a/bookie/src/app/cashier-report/cashier-report-display-item.ts +++ b/bookie/src/app/cashier-report/cashier-report-display-item.ts @@ -1,4 +1,10 @@ export class CashierReportDisplayItem { name: string; amount: number; + + public constructor(init?: Partial) { + this.name = ''; + this.amount = 0; + Object.assign(this, init); + } } diff --git a/bookie/src/app/cashier-report/cashier-report-print-item.ts b/bookie/src/app/cashier-report/cashier-report-print-item.ts index d11cae6..face423 100644 --- a/bookie/src/app/cashier-report/cashier-report-print-item.ts +++ b/bookie/src/app/cashier-report/cashier-report-print-item.ts @@ -3,4 +3,12 @@ export class CashierReportPrintItem { billId: string; customer: string; amount: number; + + public constructor(init?: Partial) { + this.date = ''; + this.billId = ''; + this.customer = ''; + this.amount = 0; + Object.assign(this, init); + } } diff --git a/bookie/src/app/cashier-report/cashier-report.component.spec.ts b/bookie/src/app/cashier-report/cashier-report.component.spec.ts index f413626..5c4ceb4 100644 --- a/bookie/src/app/cashier-report/cashier-report.component.spec.ts +++ b/bookie/src/app/cashier-report/cashier-report.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { CashierReportComponent } from './cashier-report.component'; @@ -6,11 +6,13 @@ describe('CashierReportComponent', () => { let component: CashierReportComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [CashierReportComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [CashierReportComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(CashierReportComponent); diff --git a/bookie/src/app/cashier-report/cashier-report.component.ts b/bookie/src/app/cashier-report/cashier-report.component.ts index e95910c..ddb110c 100644 --- a/bookie/src/app/cashier-report/cashier-report.component.ts +++ b/bookie/src/app/cashier-report/cashier-report.component.ts @@ -17,10 +17,10 @@ import { CashierReportService } from './cashier-report.service'; styleUrls: ['./cashier-report.component.css'], }) export class CashierReportComponent implements OnInit { - dataSource: CashierReportDataSource; + activeCashiers: User[] = []; + info: CashierReport = new CashierReport(); + dataSource: CashierReportDataSource = new CashierReportDataSource(this.info.amounts); form: FormGroup; - activeCashiers: User[]; - info: CashierReport; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'amount']; @@ -33,11 +33,17 @@ export class CashierReportComponent implements OnInit { private toaster: ToasterService, private ser: CashierReportService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + startDate: '', + finishDate: '', + cashier: '', + }); } ngOnInit() { - this.route.data.subscribe((data: { cashiers: User[]; info: CashierReport }) => { + this.route.data.subscribe((value) => { + const data = value as { cashiers: User[]; info: CashierReport }; this.activeCashiers = data.cashiers; this.info = data.info; this.form.setValue({ @@ -64,7 +70,7 @@ export class CashierReportComponent implements OnInit { } print() { - this.ser.print(this.info.cashier.id, this.info.startDate, this.info.finishDate).subscribe( + this.ser.print(this.info.cashier.id as string, this.info.startDate, this.info.finishDate).subscribe( () => { this.toaster.show('', 'Successfully Printed'); }, @@ -74,23 +80,15 @@ export class CashierReportComponent implements OnInit { ); } - createForm() { - this.form = this.fb.group({ - startDate: '', - finishDate: '', - cashier: '', - }); - } - getInfo(): CashierReport { const formModel = this.form.value; - return { + return new CashierReport({ cashier: new User({ id: formModel.cashier }), cashiers: this.info.cashiers, startDate: moment(formModel.startDate).format('DD-MMM-YYYY'), finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'), - }; + }); } exportCsv() { diff --git a/bookie/src/app/cashier-report/cashier-report.service.ts b/bookie/src/app/cashier-report/cashier-report.service.ts index 3de203d..aadd889 100644 --- a/bookie/src/app/cashier-report/cashier-report.service.ts +++ b/bookie/src/app/cashier-report/cashier-report.service.ts @@ -17,7 +17,11 @@ const serviceName = 'CashierReportService'; export class CashierReportService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - list(id: string, startDate: string, finishDate): Observable { + list( + id: string | null, + startDate: string | null, + finishDate: string | null, + ): Observable { const listUrl = id === null ? url : `${url}/${id}`; const options = { params: new HttpParams() }; if (startDate !== null) { @@ -33,7 +37,7 @@ export class CashierReportService { ); } - activeCashiers(startDate: string, finishDate): Observable { + activeCashiers(startDate: string | null, finishDate: string | null): Observable { const options = { params: new HttpParams() }; if (startDate !== null) { options.params = options.params.set('s', startDate); @@ -47,7 +51,7 @@ export class CashierReportService { .pipe(catchError(this.log.handleError(serviceName, 'activeCashiers'))); } - print(id: string, startDate: string, finishDate): Observable { + print(id: string, startDate: string | null, finishDate: string | null): Observable { const printUrl = `${url}/print/${id}`; const options = { params: new HttpParams() }; if (startDate !== null) { diff --git a/bookie/src/app/cashier-report/cashier-report.ts b/bookie/src/app/cashier-report/cashier-report.ts index f8f32b7..dc61bf1 100644 --- a/bookie/src/app/cashier-report/cashier-report.ts +++ b/bookie/src/app/cashier-report/cashier-report.ts @@ -8,6 +8,16 @@ export class CashierReport { finishDate: string; cashier: User; cashiers: string; - amounts?: CashierReportDisplayItem[]; - info?: CashierReportPrintItem[]; + amounts: CashierReportDisplayItem[]; + info: CashierReportPrintItem[]; + + public constructor(init?: Partial) { + this.startDate = ''; + this.finishDate = '0'; + this.cashier = new User(); + this.cashiers = ''; + this.amounts = []; + this.info = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/bill-view-item.ts b/bookie/src/app/core/bill-view-item.ts new file mode 100644 index 0000000..dc3bb0d --- /dev/null +++ b/bookie/src/app/core/bill-view-item.ts @@ -0,0 +1,41 @@ +import { Modifier } from './modifier'; +import { Product } from './product'; +import { Tax } from './tax'; + +export class BillViewItem { + id: string; + isKot: boolean; + oldKot: boolean; + info: string; + + kotId: string; + product: Product; + productId: string | undefined; + isHappyHour: boolean; + isPrinted: boolean; + price: number; + quantity: number; + discount: number; + taxRate: number; + tax: Tax; + modifiers: Modifier[]; + + public constructor(init?: Partial) { + this.id = ''; + this.isKot = true; + this.oldKot = false; + this.info = ''; + this.kotId = ''; + this.product = new Product(); + this.productId = this.product.id; + this.isHappyHour = false; + this.isPrinted = false; + this.price = 0; + this.quantity = 0; + this.discount = 0; + this.taxRate = 0; + this.tax = new Tax(); + this.modifiers = []; + Object.assign(this, init); + } +} diff --git a/bookie/src/app/core/device.ts b/bookie/src/app/core/device.ts index 8e93ca5..2adfecf 100644 --- a/bookie/src/app/core/device.ts +++ b/bookie/src/app/core/device.ts @@ -1,7 +1,7 @@ import { Section } from './section'; export class Device { - id: string; + id: string | undefined; name: string; enabled: boolean; section: Section; @@ -10,6 +10,12 @@ export class Device { lastDate?: string; public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.enabled = false; + this.section = new Section(); + this.creationDate = ''; + this.lastUser = ''; Object.assign(this, init); } } diff --git a/bookie/src/app/core/menu-category.ts b/bookie/src/app/core/menu-category.ts index b502dbb..10bc902 100644 --- a/bookie/src/app/core/menu-category.ts +++ b/bookie/src/app/core/menu-category.ts @@ -2,7 +2,7 @@ import { Product } from './product'; export class MenuCategory { - id: string; + id: string | undefined; name: string; discountLimit: number; isActive: boolean; @@ -12,6 +12,13 @@ export class MenuCategory { enabled?: boolean; public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.discountLimit = 0; + this.isActive = true; + this.isFixture = false; + this.sortOrder = 0; + this.products = []; Object.assign(this, init); } } diff --git a/bookie/src/app/core/modifier-category.ts b/bookie/src/app/core/modifier-category.ts index 0d6a06d..c4c57a8 100644 --- a/bookie/src/app/core/modifier-category.ts +++ b/bookie/src/app/core/modifier-category.ts @@ -3,11 +3,22 @@ import { MenuCategory } from './menu-category'; import { Modifier } from './modifier'; export class ModifierCategory { - id: string; + id: string | undefined; name: string; minimum: number; maximum: number; isActive: boolean; - menuCategories?: MenuCategory[]; - modifiers?: Modifier[]; + menuCategories: MenuCategory[]; + modifiers: Modifier[]; + + public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.minimum = 0; + this.maximum = 0; + this.isActive = true; + this.menuCategories = []; + this.modifiers = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/modifier.ts b/bookie/src/app/core/modifier.ts index 1e0334a..b9807fe 100644 --- a/bookie/src/app/core/modifier.ts +++ b/bookie/src/app/core/modifier.ts @@ -2,11 +2,21 @@ import { ModifierCategory } from './modifier-category'; export class Modifier { - id: string; + id: string | undefined; name: string; showInBill: boolean; price: number; modifierCategory: ModifierCategory; isActive: boolean; billPrice?: number; + + public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.showInBill = true; + this.price = 0; + this.modifierCategory = new ModifierCategory(); + this.isActive = true; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/printer.ts b/bookie/src/app/core/printer.ts index 8406b7d..6de2873 100644 --- a/bookie/src/app/core/printer.ts +++ b/bookie/src/app/core/printer.ts @@ -1,6 +1,11 @@ export class Printer { - id: string; + id: string | undefined; name?: string; address?: string; cutCode?: string; + + public constructor(init?: Partial) { + this.id = undefined; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/product.ts b/bookie/src/app/core/product.ts index bb3e54a..f70572d 100644 --- a/bookie/src/app/core/product.ts +++ b/bookie/src/app/core/product.ts @@ -4,7 +4,7 @@ import { SaleCategory } from './sale-category'; import { Tax } from './tax'; export class Product { - id: string; + id: string | undefined; code: number; name: string; units: string; @@ -17,6 +17,24 @@ export class Product { isActive: boolean; sortOrder: number; - enabled?: boolean; - tax?: Tax; + enabled: boolean; + tax: Tax; + + public constructor(init?: Partial) { + this.id = undefined; + this.code = 0; + this.name = ''; + this.units = ''; + this.menuCategory = new MenuCategory(); + this.saleCategory = new SaleCategory(); + this.price = 0; + this.hasHappyHour = false; + this.isNotAvailable = false; + this.quantity = 0; + this.isActive = true; + this.sortOrder = 0; + this.enabled = true; + this.tax = new Tax(); + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/receive-payment-item.ts b/bookie/src/app/core/receive-payment-item.ts new file mode 100644 index 0000000..f63c38f --- /dev/null +++ b/bookie/src/app/core/receive-payment-item.ts @@ -0,0 +1,5 @@ +export interface ReceivePaymentItem { + id: number; + name: string; + amount: number; +} diff --git a/bookie/src/app/core/receive-payment-list.ts b/bookie/src/app/core/receive-payment-list.ts new file mode 100644 index 0000000..955b60b --- /dev/null +++ b/bookie/src/app/core/receive-payment-list.ts @@ -0,0 +1,5 @@ +import { ReceivePaymentItem } from './receive-payment-item'; + +export interface ReceivePaymentList { + [billType: string]: ReceivePaymentItem[]; +} diff --git a/bookie/src/app/core/sale-category.ts b/bookie/src/app/core/sale-category.ts index a0be996..ba3cf3d 100644 --- a/bookie/src/app/core/sale-category.ts +++ b/bookie/src/app/core/sale-category.ts @@ -1,7 +1,14 @@ import { Tax } from './tax'; export class SaleCategory { - id: string; + id: string | undefined; name: string; tax: Tax; + + public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.tax = new Tax(); + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/section-printer.ts b/bookie/src/app/core/section-printer.ts index 909ec30..850c0f7 100644 --- a/bookie/src/app/core/section-printer.ts +++ b/bookie/src/app/core/section-printer.ts @@ -5,4 +5,11 @@ export class SectionPrinter { menuCategory: MenuCategory; printer: Printer; copies: number; + + public constructor(init?: Partial) { + this.menuCategory = new MenuCategory(); + this.printer = new Printer(); + this.copies = 0; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/section.ts b/bookie/src/app/core/section.ts index 04127d9..0707314 100644 --- a/bookie/src/app/core/section.ts +++ b/bookie/src/app/core/section.ts @@ -1,4 +1,10 @@ export class Section { - id: string; + id: string | undefined; name: string; + + public constructor(init?: Partial
) { + this.id = undefined; + this.name = ''; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/table.ts b/bookie/src/app/core/table.ts index 4f1caa0..da252f2 100644 --- a/bookie/src/app/core/table.ts +++ b/bookie/src/app/core/table.ts @@ -1,7 +1,7 @@ import { Section } from './section'; export class Table { - id: string; + id: string | undefined; name: string; seats: number; section: Section; @@ -12,4 +12,13 @@ export class Table { guest?: string; date?: string; amount?: number; + + public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.seats = 0; + this.section = new Section(); + this.isActive = true; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/tax.ts b/bookie/src/app/core/tax.ts index a286cfb..31e0b8b 100644 --- a/bookie/src/app/core/tax.ts +++ b/bookie/src/app/core/tax.ts @@ -1,6 +1,14 @@ export class Tax { - id: string; + id: string | undefined; name: string; rate: number; isFixture: boolean; + + public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.rate = 0; + this.isFixture = false; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/user-group.ts b/bookie/src/app/core/user-group.ts index ce7f90a..d2774a0 100644 --- a/bookie/src/app/core/user-group.ts +++ b/bookie/src/app/core/user-group.ts @@ -1,5 +1,12 @@ export class UserGroup { - id: string; + id: string | undefined; name: string; enabled: boolean; + + public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.enabled = false; + Object.assign(this, init); + } } diff --git a/bookie/src/app/core/user.ts b/bookie/src/app/core/user.ts index 78ec38a..f807afd 100644 --- a/bookie/src/app/core/user.ts +++ b/bookie/src/app/core/user.ts @@ -1,20 +1,28 @@ import { UserGroup } from './user-group'; export class User { - id: string; + id: string | undefined; name: string; password: string; lockedOut: boolean; - roles?: UserGroup[]; + roles: UserGroup[]; perms: string[]; - isAuthenticated: boolean; access_token?: string; - exp?: number; + exp: number; ver: string; lastDevice: string; lastDate?: string; public constructor(init?: Partial) { + this.id = undefined; + this.name = ''; + this.password = ''; + this.lockedOut = true; + this.roles = []; + this.perms = []; + this.exp = 0; + this.ver = ''; + this.lastDevice = ''; Object.assign(this, init); } } diff --git a/bookie/src/app/devices/device-detail/device-detail.component.spec.ts b/bookie/src/app/devices/device-detail/device-detail.component.spec.ts index 05f066b..7169488 100644 --- a/bookie/src/app/devices/device-detail/device-detail.component.spec.ts +++ b/bookie/src/app/devices/device-detail/device-detail.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { DeviceDetailComponent } from './device-detail.component'; @@ -6,11 +6,13 @@ describe('DeviceDetailComponent', () => { let component: DeviceDetailComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [DeviceDetailComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DeviceDetailComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(DeviceDetailComponent); diff --git a/bookie/src/app/devices/device-detail/device-detail.component.ts b/bookie/src/app/devices/device-detail/device-detail.component.ts index 7b560e3..f89a919 100644 --- a/bookie/src/app/devices/device-detail/device-detail.component.ts +++ b/bookie/src/app/devices/device-detail/device-detail.component.ts @@ -15,10 +15,10 @@ import { DeviceService } from '../device.service'; styleUrls: ['./device-detail.component.css'], }) export class DeviceDetailComponent implements OnInit, AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement: ElementRef; + @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; form: FormGroup; - sections: Section[]; - item: Device; + sections: Section[] = []; + item: Device = new Device(); constructor( private route: ActivatedRoute, @@ -28,10 +28,7 @@ export class DeviceDetailComponent implements OnInit, AfterViewInit { private toaster: ToasterService, private ser: DeviceService, ) { - this.createForm(); - } - - createForm() { + // Create form this.form = this.fb.group({ name: '', section: '', @@ -40,7 +37,8 @@ export class DeviceDetailComponent implements OnInit, AfterViewInit { } ngOnInit() { - this.route.data.subscribe((data: { item: Device; sections: Section[] }) => { + this.route.data.subscribe((value) => { + const data = value as { item: Device; sections: Section[] }; this.showItem(data.item); this.sections = data.sections; }); @@ -57,7 +55,9 @@ export class DeviceDetailComponent implements OnInit, AfterViewInit { ngAfterViewInit() { setTimeout(() => { - this.nameElement.nativeElement.focus(); + if (this.nameElement !== undefined) { + this.nameElement.nativeElement.focus(); + } }, 0); } @@ -74,7 +74,7 @@ export class DeviceDetailComponent implements OnInit, AfterViewInit { } delete() { - this.ser.delete(this.item.id).subscribe( + this.ser.delete(this.item.id as string).subscribe( () => { this.toaster.show('Success', ''); this.router.navigateByUrl('/devices'); diff --git a/bookie/src/app/devices/device-list/device-list.component.ts b/bookie/src/app/devices/device-list/device-list.component.ts index b888090..2fbfedc 100644 --- a/bookie/src/app/devices/device-list/device-list.component.ts +++ b/bookie/src/app/devices/device-list/device-list.component.ts @@ -11,15 +11,16 @@ import { DeviceListDataSource } from './device-list-datasource'; styleUrls: ['./device-list.component.css'], }) export class DeviceListComponent implements OnInit { - dataSource: DeviceListDataSource; - list: Device[]; + list: Device[] = []; + dataSource: DeviceListDataSource = new DeviceListDataSource(this.list); /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'section', 'enabled', 'creationDate', 'last']; constructor(private route: ActivatedRoute) {} ngOnInit() { - this.route.data.subscribe((data: { list: Device[] }) => { + this.route.data.subscribe((value) => { + const data = value as { list: Device[] }; this.list = data.list; }); this.dataSource = new DeviceListDataSource(this.list); diff --git a/bookie/src/app/devices/device.service.ts b/bookie/src/app/devices/device.service.ts index d697d2e..687bd3f 100644 --- a/bookie/src/app/devices/device.service.ts +++ b/bookie/src/app/devices/device.service.ts @@ -15,7 +15,7 @@ const serviceName = 'DeviceService'; export class DeviceService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string): Observable { + get(id: string | null): Observable { const getUrl: string = id === null ? `${url}` : `${url}/${id}`; return >( this.http diff --git a/bookie/src/app/discount-report/discount-report-item.ts b/bookie/src/app/discount-report/discount-report-item.ts index 4d03c72..78ad6af 100644 --- a/bookie/src/app/discount-report/discount-report-item.ts +++ b/bookie/src/app/discount-report/discount-report-item.ts @@ -1,4 +1,10 @@ export class DiscountReportItem { name: string; amount: number; + + public constructor(init?: Partial) { + this.name = ''; + this.amount = 0; + Object.assign(this, init); + } } diff --git a/bookie/src/app/discount-report/discount-report.component.spec.ts b/bookie/src/app/discount-report/discount-report.component.spec.ts index 33d74f5..80a32ec 100644 --- a/bookie/src/app/discount-report/discount-report.component.spec.ts +++ b/bookie/src/app/discount-report/discount-report.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { DiscountReportComponent } from './discount-report.component'; @@ -6,11 +6,13 @@ describe('DiscountReportComponent', () => { let component: DiscountReportComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [DiscountReportComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DiscountReportComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(DiscountReportComponent); diff --git a/bookie/src/app/discount-report/discount-report.component.ts b/bookie/src/app/discount-report/discount-report.component.ts index e2eeb56..7ea7b5f 100644 --- a/bookie/src/app/discount-report/discount-report.component.ts +++ b/bookie/src/app/discount-report/discount-report.component.ts @@ -16,9 +16,9 @@ import { DiscountReportService } from './discount-report.service'; styleUrls: ['./discount-report.component.css'], }) export class DiscountReportComponent implements OnInit { - dataSource: DiscountReportDataSource; + info: DiscountReport = new DiscountReport(); + dataSource: DiscountReportDataSource = new DiscountReportDataSource(this.info.amounts); form: FormGroup; - info: DiscountReport; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'amount']; @@ -31,11 +31,16 @@ export class DiscountReportComponent implements OnInit { private toaster: ToasterService, private ser: DiscountReportService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + startDate: '', + finishDate: '', + }); } ngOnInit() { - this.route.data.subscribe((data: { info: DiscountReport }) => { + this.route.data.subscribe((value) => { + const data = value as { info: DiscountReport }; this.info = data.info; this.form.setValue({ startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(), @@ -55,20 +60,13 @@ export class DiscountReportComponent implements OnInit { }); } - createForm() { - this.form = this.fb.group({ - startDate: '', - finishDate: '', - }); - } - getInfo(): DiscountReport { const formModel = this.form.value; - return { + return new DiscountReport({ startDate: moment(formModel.startDate).format('DD-MMM-YYYY'), finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'), - }; + }); } print() { diff --git a/bookie/src/app/discount-report/discount-report.service.ts b/bookie/src/app/discount-report/discount-report.service.ts index 4d8b10b..20322aa 100644 --- a/bookie/src/app/discount-report/discount-report.service.ts +++ b/bookie/src/app/discount-report/discount-report.service.ts @@ -16,7 +16,7 @@ const serviceName = 'DiscountReportService'; export class DiscountReportService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(startDate: string, finishDate): Observable { + get(startDate: string | null, finishDate: string | null): Observable { const options = { params: new HttpParams() }; if (startDate !== null) { options.params = options.params.set('s', startDate); @@ -31,7 +31,7 @@ export class DiscountReportService { ); } - print(startDate: string, finishDate): Observable { + print(startDate: string | null, finishDate: string | null): Observable { const printUrl = `${url}/print`; const options = { params: new HttpParams() }; if (startDate !== null) { diff --git a/bookie/src/app/discount-report/discount-report.ts b/bookie/src/app/discount-report/discount-report.ts index f41baf4..3fb25be 100644 --- a/bookie/src/app/discount-report/discount-report.ts +++ b/bookie/src/app/discount-report/discount-report.ts @@ -3,5 +3,12 @@ import { DiscountReportItem } from './discount-report-item'; export class DiscountReport { startDate: string; finishDate: string; - amounts?: DiscountReportItem[]; + amounts: DiscountReportItem[]; + + public constructor(init?: Partial) { + this.startDate = ''; + this.finishDate = ''; + this.amounts = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts b/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts index 4291c60..6ec0f53 100644 --- a/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts +++ b/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts @@ -12,9 +12,9 @@ import { GuestBookService } from '../guest-book.service'; styleUrls: ['./guest-book-detail.component.css'], }) export class GuestBookDetailComponent implements OnInit, AfterViewInit { - @ViewChild('name', { static: true }) nameElement: ElementRef; + @ViewChild('name', { static: true }) nameElement?: ElementRef; form: FormGroup; - item: GuestBook; + item: GuestBook = new GuestBook(); constructor( private fb: FormBuilder, @@ -23,10 +23,7 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit { private toaster: ToasterService, private ser: GuestBookService, ) { - this.createForm(); - } - - createForm() { + // Create form this.form = this.fb.group({ name: [null, Validators.required], phone: [null, Validators.required], @@ -36,14 +33,17 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit { } ngOnInit() { - this.route.data.subscribe((data: { item: GuestBook }) => { + this.route.data.subscribe((value) => { + const data = value as { item: GuestBook }; this.showItem(data.item); }); } ngAfterViewInit() { setTimeout(() => { - this.nameElement.nativeElement.focus(); + if (this.nameElement !== undefined) { + this.nameElement.nativeElement.focus(); + } }, 0); } @@ -52,7 +52,7 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit { this.form.setValue({ name: item.name, phone: item.phone, - pax: `${item.pax}`, + pax: item.pax, address: item.address, }); } diff --git a/bookie/src/app/guest-book/guest-book-list.ts b/bookie/src/app/guest-book/guest-book-list.ts index 1b056aa..b500cba 100644 --- a/bookie/src/app/guest-book/guest-book-list.ts +++ b/bookie/src/app/guest-book/guest-book-list.ts @@ -3,4 +3,10 @@ import { GuestBook } from './guest-book'; export class GuestBookList { date: string; list: GuestBook[]; + + public constructor(init?: Partial) { + this.date = ''; + this.list = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.css b/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.css index c2e5ab1..d78addf 100644 --- a/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.css +++ b/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.css @@ -3,13 +3,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; } diff --git a/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.ts b/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.ts index f218a72..4994091 100644 --- a/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.ts +++ b/bookie/src/app/guest-book/guest-book-list/guest-book-list.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import * as moment from 'moment'; @@ -20,9 +20,9 @@ import { GuestBookListDataSource } from './guest-book-list-datasource'; styleUrls: ['./guest-book-list.component.css'], }) export class GuestBookListComponent implements OnInit { - dataSource: GuestBookListDataSource; + data: BehaviorSubject = new BehaviorSubject([]); + dataSource: GuestBookListDataSource = new GuestBookListDataSource(this.data); form: FormGroup; - data: BehaviorSubject; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['sno', 'name', 'phone', 'pax', 'date', 'action']; @@ -34,21 +34,16 @@ export class GuestBookListComponent implements OnInit { private toaster: ToasterService, private ser: GuestBookService, ) { - this.createForm(); - this.data = new BehaviorSubject([]); - this.listenToDateChange(); - } - - createForm() { + // Create form this.form = this.fb.group({ date: '', }); + this.listenToDateChange(); } listenToDateChange(): void { - this.form - .get('date') - .valueChanges.pipe(map((x) => moment(x).format('DD-MMM-YYYY'))) + (this.form.get('date') as FormControl).valueChanges + .pipe(map((x) => moment(x).format('DD-MMM-YYYY'))) .subscribe((x) => { return this.ser.list(x).subscribe((list: GuestBookList) => { this.data.next(list.list); @@ -57,7 +52,8 @@ export class GuestBookListComponent implements OnInit { } ngOnInit() { - this.route.data.subscribe((data: { list: GuestBookList }) => { + this.route.data.subscribe((value) => { + const data = value as { list: GuestBookList }; this.data.next(data.list.list); this.form.setValue({ date: moment(data.list.date, 'DD-MMM-YYYY').toDate() }); }); diff --git a/bookie/src/app/guest-book/guest-book.service.ts b/bookie/src/app/guest-book/guest-book.service.ts index 697ee3d..60a5eb2 100644 --- a/bookie/src/app/guest-book/guest-book.service.ts +++ b/bookie/src/app/guest-book/guest-book.service.ts @@ -19,7 +19,7 @@ const serviceName = 'GuestBookService'; export class GuestBookService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string): Observable { + get(id: string | null): Observable { const getUrl: string = id === null ? url : `${url}/${id}`; return >( this.http @@ -28,7 +28,7 @@ export class GuestBookService { ); } - list(date: string): Observable { + list(date: string | null): Observable { const options = { params: new HttpParams().set('q', date === null ? '' : date) }; return >( this.http diff --git a/bookie/src/app/guest-book/guest-book.ts b/bookie/src/app/guest-book/guest-book.ts index 5c18ebb..c88c6b7 100644 --- a/bookie/src/app/guest-book/guest-book.ts +++ b/bookie/src/app/guest-book/guest-book.ts @@ -1,5 +1,5 @@ export class GuestBook { - id: string; + id: string | undefined; serial: number; name: string; phone: string; @@ -12,6 +12,13 @@ export class GuestBook { tableName?: string; public constructor(init?: Partial) { + this.id = undefined; + this.serial = 0; + this.name = ''; + this.phone = ''; + this.pax = 0; + this.address = ''; + this.date = ''; Object.assign(this, init); } } diff --git a/bookie/src/app/header-footer/header-footer.component.spec.ts b/bookie/src/app/header-footer/header-footer.component.spec.ts index 9b68747..9ee5a7c 100644 --- a/bookie/src/app/header-footer/header-footer.component.spec.ts +++ b/bookie/src/app/header-footer/header-footer.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { HeaderFooterComponent } from './header-footer.component'; @@ -6,11 +6,13 @@ describe('HeaderFooterComponent', () => { let component: HeaderFooterComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [HeaderFooterComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HeaderFooterComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(HeaderFooterComponent); diff --git a/bookie/src/app/header-footer/header-footer.component.ts b/bookie/src/app/header-footer/header-footer.component.ts index 53c5027..e92b93c 100644 --- a/bookie/src/app/header-footer/header-footer.component.ts +++ b/bookie/src/app/header-footer/header-footer.component.ts @@ -15,10 +15,10 @@ import { HeaderFooterService } from './header-footer.service'; styleUrls: ['./header-footer.component.css'], }) export class HeaderFooterComponent implements OnInit { - @ViewChild('section', { static: true }) sectionElement: ElementRef; + @ViewChild('section', { static: true }) sectionElement?: ElementRef; form: FormGroup; - list: HeaderFooter[]; - id: string; + list: HeaderFooter[] = []; + id = ''; constructor( private route: ActivatedRoute, @@ -28,30 +28,29 @@ export class HeaderFooterComponent implements OnInit { private dialog: MatDialog, private ser: HeaderFooterService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + id: '', + text: '', + }); route.params.pipe(map((p) => p.id)).subscribe((x) => { this.id = x; }); } - createForm() { - this.form = this.fb.group({ - id: '', - text: '', - }); - } - ngOnInit() { - this.route.data.subscribe((data: { list: HeaderFooter[] }) => { + this.route.data.subscribe((value) => { + const data = value as { list: HeaderFooter[] }; this.showItem(data.list); }); } showItem(list: HeaderFooter[]) { this.list = list; + const val = this.list.find((v) => v.id === this.id) as HeaderFooter; this.form.setValue({ id: this.id, - text: this.list.find((v) => v.id === this.id).text, + text: val.text, }); } @@ -70,6 +69,7 @@ export class HeaderFooterComponent implements OnInit { getItem(): HeaderFooter { const formModel = this.form.value; const item = this.list.find((v) => v.id === this.id); + if (item === undefined) return new HeaderFooter(); item.text = formModel.text; return item; } diff --git a/bookie/src/app/header-footer/header-footer.ts b/bookie/src/app/header-footer/header-footer.ts index f2d639a..9ce380f 100644 --- a/bookie/src/app/header-footer/header-footer.ts +++ b/bookie/src/app/header-footer/header-footer.ts @@ -1,5 +1,12 @@ export class HeaderFooter { id: string; name: string; - text?: string; + text: string; + + public constructor(init?: Partial) { + this.id = ''; + this.name = ''; + this.text = ''; + Object.assign(this, init); + } } diff --git a/bookie/src/app/home/home.component.html b/bookie/src/app/home/home.component.html index 96a2ff8..67f78bc 100644 --- a/bookie/src/app/home/home.component.html +++ b/bookie/src/app/home/home.component.html @@ -3,7 +3,7 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('customers') !== -1" + *ngIf="auth.allowed('customers')" [routerLink]="['/', 'guest-book']" >

Guest Book

@@ -12,16 +12,18 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('sales') !== -1" + *ngIf="auth.allowed('sales')" [routerLink]="['/', 'sales']" >

Sales

+ +

Cashier Report

@@ -30,7 +32,7 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('sale-report') !== -1" + *ngIf="auth.allowed('sale-report')" [routerLink]="['/', 'sale-report']" >

Sale Report

@@ -39,7 +41,7 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('tax-report') !== -1" + *ngIf="auth.allowed('tax-report')" [routerLink]="['/', 'tax-report']" >

Tax Report

@@ -48,7 +50,7 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('product-sale-report') !== -1" + *ngIf="auth.allowed('product-sale-report')" [routerLink]="['/', 'product-sale-report']" >

Product Sale Report

@@ -57,7 +59,7 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('bill-settlement-report') !== -1" + *ngIf="auth.allowed('bill-settlement-report')" [routerLink]="['/', 'bill-settlement-report']" >

Bill Settlement Report

@@ -66,7 +68,7 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('beer-sale-report') !== -1" + *ngIf="auth.allowed('beer-sale-report')" [routerLink]="['/', 'beer-sale-report']" >

Beer Sale Report

@@ -75,52 +77,18 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('discount-report') !== -1" + *ngIf="auth.allowed('discount-report')" [routerLink]="['/', 'discount-report']" >

Discount Report

+
+
-

Tables

-
- -

Sections

-
- -

Menu Categories

-
- -

Sale Categories

-
-

Products

@@ -129,88 +97,16 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('modifiers') !== -1" - [routerLink]="['/', 'modifier-categories']" + *ngIf="auth.allowed('products')" + [routerLink]="['/', 'update-product-prices']" > -

Modifier Categories

+

Update Product Prices

-

Modifiers

-
- -

Taxes

-
- -

Devices

-
- -

Section Printers

-
- -

Printers

-
- -

Roles

-
- -

Users

-
- -

Header / Footer

-
-

Product Updates Report

@@ -219,10 +115,122 @@ fxLayout="column" class="square-button" matRipple - *ngIf="auth.user && auth.user.perms.indexOf('products') !== -1" - [routerLink]="['/', 'update-product-prices']" + *ngIf="auth.allowed('modifiers')" + [routerLink]="['/', 'modifiers']" > -

Update Product Prices

+

Modifiers

+
+ +

Modifier Categories

+
+
+
+ +

Tables

+
+ +

Sections

+
+ +

Menu Categories

+
+ +

Sale Categories

+
+ +

Taxes

+
+ +

Devices

+
+ +

Section Printers

+
+ +

Printers

+
+
+
+ +

Roles

+
+ +

Users

+
+ +

Header / Footer

> { + confirmMoveKotDialog(table: Table): Observable
{ 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
{ @@ -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; diff --git a/bookie/src/app/sales/bills/inventory.ts b/bookie/src/app/sales/bills/inventory.ts index 1f1f055..5104ebf 100644 --- a/bookie/src/app/sales/bills/inventory.ts +++ b/bookie/src/app/sales/bills/inventory.ts @@ -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) { + 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); } } diff --git a/bookie/src/app/sales/bills/kot.ts b/bookie/src/app/sales/bills/kot.ts index c9dbf78..f41804a 100644 --- a/bookie/src/app/sales/bills/kot.ts +++ b/bookie/src/app/sales/bills/kot.ts @@ -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) { + this.id = undefined; + this.code = 0; + this.date = ''; + this.user = new User(); + this.inventories = []; Object.assign(this, init); } } diff --git a/bookie/src/app/sales/bills/print-type.ts b/bookie/src/app/sales/bills/voucher-type.ts similarity index 66% rename from bookie/src/app/sales/bills/print-type.ts rename to bookie/src/app/sales/bills/voucher-type.ts index 78af97a..eff7888 100644 --- a/bookie/src/app/sales/bills/print-type.ts +++ b/bookie/src/app/sales/bills/voucher-type.ts @@ -1,6 +1,7 @@ -export enum PrintType { +export enum VoucherType { Kot = 'KOT', Bill = 'REGULAR_BILL', NoCharge = 'NO_CHARGE', Staff = 'STAFF', + Void = 'VOID', } diff --git a/bookie/src/app/sales/bills/voucher.service.ts b/bookie/src/app/sales/bills/voucher.service.ts index 2307af7..604bc21 100644 --- a/bookie/src/app/sales/bills/voucher.service.ts +++ b/bookie/src/app/sales/bills/voucher.service.ts @@ -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 { + getFromTable( + tableId: string, + voucherId: string | null, + guestId: string | null, + ): Observable { 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 { 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 >( 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 { 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 >( 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 { 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 >( 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 { 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( diff --git a/bookie/src/app/sales/discount/discount.component.spec.ts b/bookie/src/app/sales/discount/discount.component.spec.ts index a520637..15460a9 100644 --- a/bookie/src/app/sales/discount/discount.component.spec.ts +++ b/bookie/src/app/sales/discount/discount.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [DiscountComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [DiscountComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(DiscountComponent); diff --git a/bookie/src/app/sales/discount/discount.component.ts b/bookie/src/app/sales/discount/discount.component.ts index 24c4bb8..8b672ac 100644 --- a/bookie/src/app/sales/discount/discount.component.ts +++ b/bookie/src/app/sales/discount/discount.component.ts @@ -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, ) { - 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) => { diff --git a/bookie/src/app/sales/home/sales-home.component.spec.ts b/bookie/src/app/sales/home/sales-home.component.spec.ts index 2e69b46..62f6419 100644 --- a/bookie/src/app/sales/home/sales-home.component.spec.ts +++ b/bookie/src/app/sales/home/sales-home.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [SalesHomeComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [SalesHomeComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(SalesHomeComponent); diff --git a/bookie/src/app/sales/home/sales-home.component.ts b/bookie/src/app/sales/home/sales-home.component.ts index c7b7bff..5043fc1 100644 --- a/bookie/src/app/sales/home/sales-home.component.ts +++ b/bookie/src/app/sales/home/sales-home.component.ts @@ -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 { @@ -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 { - 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) { diff --git a/bookie/src/app/sales/menu-categories/menu-categories.component.spec.ts b/bookie/src/app/sales/menu-categories/menu-categories.component.spec.ts index 45505ff..6434f7d 100644 --- a/bookie/src/app/sales/menu-categories/menu-categories.component.spec.ts +++ b/bookie/src/app/sales/menu-categories/menu-categories.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [MenuCategoriesComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [MenuCategoriesComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(MenuCategoriesComponent); diff --git a/bookie/src/app/sales/menu-categories/menu-categories.component.ts b/bookie/src/app/sales/menu-categories/menu-categories.component.ts index c247959..32ed99d 100644 --- a/bookie/src/app/sales/menu-categories/menu-categories.component.ts +++ b/bookie/src/app/sales/menu-categories/menu-categories.component.ts @@ -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; }); } diff --git a/bookie/src/app/sales/modifiers/modifiers.component.spec.ts b/bookie/src/app/sales/modifiers/modifiers.component.spec.ts index 6512712..a757d1e 100644 --- a/bookie/src/app/sales/modifiers/modifiers.component.spec.ts +++ b/bookie/src/app/sales/modifiers/modifiers.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ModifiersComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ModifiersComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(ModifiersComponent); diff --git a/bookie/src/app/sales/modifiers/modifiers.component.ts b/bookie/src/app/sales/modifiers/modifiers.component.ts index 87e70f5..73ee8b1 100644 --- a/bookie/src/app/sales/modifiers/modifiers.component.ts +++ b/bookie/src/app/sales/modifiers/modifiers.component.ts @@ -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) diff --git a/bookie/src/app/sales/pax/pax.component.spec.ts b/bookie/src/app/sales/pax/pax.component.spec.ts index 3c5e187..bc89230 100644 --- a/bookie/src/app/sales/pax/pax.component.spec.ts +++ b/bookie/src/app/sales/pax/pax.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [PaxComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PaxComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(PaxComponent); diff --git a/bookie/src/app/sales/pax/pax.component.ts b/bookie/src/app/sales/pax/pax.component.ts index a204dec..c5e345a 100644 --- a/bookie/src/app/sales/pax/pax.component.ts +++ b/bookie/src/app/sales/pax/pax.component.ts @@ -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); diff --git a/bookie/src/app/sales/products/products-resolver.service.ts b/bookie/src/app/sales/products/products-resolver.service.ts index bb497f7..e61ccdd 100644 --- a/bookie/src/app/sales/products/products-resolver.service.ts +++ b/bookie/src/app/sales/products/products-resolver.service.ts @@ -12,7 +12,7 @@ export class ProductsResolver implements Resolve { constructor(private ser: ProductService, private router: Router) {} resolve(route: ActivatedRouteSnapshot): Observable { - const id = route.paramMap.get('id'); + const id = route.paramMap.get('id') as string; return this.ser.listIsActiveOfCategory(id); } } diff --git a/bookie/src/app/sales/products/products.component.spec.ts b/bookie/src/app/sales/products/products.component.spec.ts index b1c717a..0b841b9 100644 --- a/bookie/src/app/sales/products/products.component.spec.ts +++ b/bookie/src/app/sales/products/products.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ProductsComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ProductsComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(ProductsComponent); diff --git a/bookie/src/app/sales/products/products.component.ts b/bookie/src/app/sales/products/products.component.ts index 27a5877..b54b4cd 100644 --- a/bookie/src/app/sales/products/products.component.ts +++ b/bookie/src/app/sales/products/products.component.ts @@ -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; }); } diff --git a/bookie/src/app/sales/quantity/quantity.component.spec.ts b/bookie/src/app/sales/quantity/quantity.component.spec.ts index b7e581f..de8101e 100644 --- a/bookie/src/app/sales/quantity/quantity.component.spec.ts +++ b/bookie/src/app/sales/quantity/quantity.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [QuantityComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [QuantityComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(QuantityComponent); diff --git a/bookie/src/app/sales/quantity/quantity.component.ts b/bookie/src/app/sales/quantity/quantity.component.ts index 2200cc5..41e12a4 100644 --- a/bookie/src/app/sales/quantity/quantity.component.ts +++ b/bookie/src/app/sales/quantity/quantity.component.ts @@ -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); diff --git a/bookie/src/app/sales/reason/reason.component.spec.ts b/bookie/src/app/sales/reason/reason.component.spec.ts index 4caf60e..fcd97ff 100644 --- a/bookie/src/app/sales/reason/reason.component.spec.ts +++ b/bookie/src/app/sales/reason/reason.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ReasonComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ReasonComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(ReasonComponent); diff --git a/bookie/src/app/sales/reason/reason.component.ts b/bookie/src/app/sales/reason/reason.component.ts index 7adf4ab..2d70e1a 100644 --- a/bookie/src/app/sales/reason/reason.component.ts +++ b/bookie/src/app/sales/reason/reason.component.ts @@ -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']; diff --git a/bookie/src/app/sales/receive-payment/receive-payment-datasource.ts b/bookie/src/app/sales/receive-payment/receive-payment-datasource.ts index c4dd696..11a7ba4 100644 --- a/bookie/src/app/sales/receive-payment/receive-payment-datasource.ts +++ b/bookie/src/app/sales/receive-payment/receive-payment-datasource.ts @@ -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 { + constructor(private data: ReceivePaymentItem[]) { super(); } - connect(): Observable<{ name: string; discount: number }[]> { + connect(): Observable { return observableOf(this.data); } diff --git a/bookie/src/app/sales/receive-payment/receive-payment.component.spec.ts b/bookie/src/app/sales/receive-payment/receive-payment.component.spec.ts index 4af31cf..1f2c4dc 100644 --- a/bookie/src/app/sales/receive-payment/receive-payment.component.spec.ts +++ b/bookie/src/app/sales/receive-payment/receive-payment.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ReceivePaymentComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ReceivePaymentComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(ReceivePaymentComponent); diff --git a/bookie/src/app/sales/receive-payment/receive-payment.component.ts b/bookie/src/app/sales/receive-payment/receive-payment.component.ts index 7d99bea..cee1a23 100644 --- a/bookie/src/app/sales/receive-payment/receive-payment.component.ts +++ b/bookie/src/app/sales/receive-payment/receive-payment.component.ts @@ -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, 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); }), diff --git a/bookie/src/app/sales/running-tables/running-tables.component.css b/bookie/src/app/sales/running-tables/running-tables.component.css index b46ac09..9310616 100644 --- a/bookie/src/app/sales/running-tables/running-tables.component.css +++ b/bookie/src/app/sales/running-tables/running-tables.component.css @@ -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 { diff --git a/bookie/src/app/sales/running-tables/running-tables.component.spec.ts b/bookie/src/app/sales/running-tables/running-tables.component.spec.ts index 0331997..14ced34 100644 --- a/bookie/src/app/sales/running-tables/running-tables.component.spec.ts +++ b/bookie/src/app/sales/running-tables/running-tables.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [RunningTablesComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [RunningTablesComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(RunningTablesComponent); diff --git a/bookie/src/app/sales/running-tables/running-tables.component.ts b/bookie/src/app/sales/running-tables/running-tables.component.ts index 0e1e124..1572942 100644 --- a/bookie/src/app/sales/running-tables/running-tables.component.ts +++ b/bookie/src/app/sales/running-tables/running-tables.component.ts @@ -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, diff --git a/bookie/src/app/sales/tables-dialog/tables-dialog.component.spec.ts b/bookie/src/app/sales/tables-dialog/tables-dialog.component.spec.ts index 30b7c00..89f70da 100644 --- a/bookie/src/app/sales/tables-dialog/tables-dialog.component.spec.ts +++ b/bookie/src/app/sales/tables-dialog/tables-dialog.component.spec.ts @@ -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; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [TablesDialogComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [TablesDialogComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(TablesDialogComponent); diff --git a/bookie/src/app/sales/tables-dialog/tables-dialog.component.ts b/bookie/src/app/sales/tables-dialog/tables-dialog.component.ts index 496caf5..7ebeae5 100644 --- a/bookie/src/app/sales/tables-dialog/tables-dialog.component.ts +++ b/bookie/src/app/sales/tables-dialog/tables-dialog.component.ts @@ -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, @Inject(MAT_DIALOG_DATA) public data: { list: Observable; canChooseRunning: boolean }, diff --git a/bookie/src/app/section-printers/section-printer.component.spec.ts b/bookie/src/app/section-printers/section-printer.component.spec.ts index 3886a13..d61561a 100644 --- a/bookie/src/app/section-printers/section-printer.component.spec.ts +++ b/bookie/src/app/section-printers/section-printer.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { SectionPrinterComponent } from './section-printer.component'; @@ -6,11 +6,13 @@ describe('SectionPrinterComponent', () => { let component: SectionPrinterComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [SectionPrinterComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [SectionPrinterComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(SectionPrinterComponent); diff --git a/bookie/src/app/section-printers/section-printer.component.ts b/bookie/src/app/section-printers/section-printer.component.ts index 88ea8e9..51d48a4 100644 --- a/bookie/src/app/section-printers/section-printer.component.ts +++ b/bookie/src/app/section-printers/section-printer.component.ts @@ -1,5 +1,5 @@ import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; -import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; +import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import { BehaviorSubject } from 'rxjs'; @@ -20,14 +20,14 @@ import { SectionPrinterService } from './section-printer.service'; styleUrls: ['./section-printer.component.css'], }) export class SectionPrinterComponent implements OnInit { - @ViewChild('section', { static: true }) sectionElement: ElementRef; + @ViewChild('section', { static: true }) sectionElement?: ElementRef; form: FormGroup; - dataSource: SectionPrinterDataSource; public listObservable = new BehaviorSubject([]); - list: SectionPrinter[]; - sections: Section[]; - printers: Printer[]; - sectionId: string; + dataSource: SectionPrinterDataSource = new SectionPrinterDataSource(this.listObservable); + list: SectionPrinter[] = []; + sections: Section[] = []; + printers: Printer[] = []; + sectionId = ''; displayedColumns = ['menuCategory', 'printer', 'copies']; constructor( @@ -38,34 +38,30 @@ export class SectionPrinterComponent implements OnInit { private dialog: MatDialog, private ser: SectionPrinterService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + section: '', + menuCategories: this.fb.array([]), + }); route.params.pipe(map((p) => p.id)).subscribe((x) => { this.sectionId = x; }); } - createForm() { - this.form = this.fb.group({ - section: '', - menuCategories: this.fb.array([]), - }); - } - ngOnInit() { - this.route.data.subscribe( - (data: { list: SectionPrinter[]; sections: Section[]; printers: Printer[] }) => { - this.sections = data.sections; - this.printers = data.printers; - this.showItem(data.list); - this.dataSource = new SectionPrinterDataSource(this.listObservable); - this.listObservable.next(this.list); - }, - ); + this.route.data.subscribe((value) => { + const data = value as { list: SectionPrinter[]; sections: Section[]; printers: Printer[] }; + this.sections = data.sections; + this.printers = data.printers; + this.showItem(data.list); + this.dataSource = new SectionPrinterDataSource(this.listObservable); + this.listObservable.next(this.list); + }); } showItem(list: SectionPrinter[]) { this.list = list; - this.form.get('section').setValue(this.sectionId); + (this.form.get('section') as AbstractControl).setValue(this.sectionId); this.form.setControl( 'menuCategories', this.fb.array( diff --git a/bookie/src/app/section-printers/section-printer.service.ts b/bookie/src/app/section-printers/section-printer.service.ts index 43c34ed..6f20ef7 100644 --- a/bookie/src/app/section-printers/section-printer.service.ts +++ b/bookie/src/app/section-printers/section-printer.service.ts @@ -18,7 +18,7 @@ const serviceName = 'SectionPrinterService'; export class SectionPrinterService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string): Observable { + get(id: string | null): Observable { const getUrl: string = id === null ? `${url}` : `${url}/${id}`; return >( this.http diff --git a/bookie/src/app/sections/section-detail/section-detail.component.spec.ts b/bookie/src/app/sections/section-detail/section-detail.component.spec.ts index 488d8bf..64adbb6 100644 --- a/bookie/src/app/sections/section-detail/section-detail.component.spec.ts +++ b/bookie/src/app/sections/section-detail/section-detail.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { SectionDetailComponent } from './section-detail.component'; @@ -6,11 +6,13 @@ describe('SectionDetailComponent', () => { let component: SectionDetailComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [SectionDetailComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [SectionDetailComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(SectionDetailComponent); diff --git a/bookie/src/app/sections/section-detail/section-detail.component.ts b/bookie/src/app/sections/section-detail/section-detail.component.ts index 5b0482e..32f2f35 100644 --- a/bookie/src/app/sections/section-detail/section-detail.component.ts +++ b/bookie/src/app/sections/section-detail/section-detail.component.ts @@ -14,9 +14,9 @@ import { SectionService } from '../section.service'; styleUrls: ['./section-detail.component.css'], }) export class SectionDetailComponent implements OnInit, AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement: ElementRef; + @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; form: FormGroup; - item: Section; + item: Section = new Section(); constructor( private route: ActivatedRoute, @@ -26,17 +26,15 @@ export class SectionDetailComponent implements OnInit, AfterViewInit { private toaster: ToasterService, private ser: SectionService, ) { - this.createForm(); - } - - createForm() { + // Create form this.form = this.fb.group({ name: '', }); } ngOnInit() { - this.route.data.subscribe((data: { item: Section }) => { + this.route.data.subscribe((value) => { + const data = value as { item: Section }; this.showItem(data.item); }); } @@ -50,7 +48,9 @@ export class SectionDetailComponent implements OnInit, AfterViewInit { ngAfterViewInit() { setTimeout(() => { - this.nameElement.nativeElement.focus(); + if (this.nameElement !== undefined) { + this.nameElement.nativeElement.focus(); + } }, 0); } @@ -67,7 +67,7 @@ export class SectionDetailComponent implements OnInit, AfterViewInit { } delete() { - this.ser.delete(this.item.id).subscribe( + this.ser.delete(this.item.id as string).subscribe( () => { this.toaster.show('Success', ''); this.router.navigateByUrl('/sections'); diff --git a/bookie/src/app/sections/section-list/section-list.component.ts b/bookie/src/app/sections/section-list/section-list.component.ts index acbf939..01b22ed 100644 --- a/bookie/src/app/sections/section-list/section-list.component.ts +++ b/bookie/src/app/sections/section-list/section-list.component.ts @@ -11,15 +11,16 @@ import { SectionListDataSource } from './section-list-datasource'; styleUrls: ['./section-list.component.css'], }) export class SectionListComponent implements OnInit { - dataSource: SectionListDataSource; - list: Section[]; + list: Section[] = []; + dataSource: SectionListDataSource = new SectionListDataSource(this.list); /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name']; constructor(private route: ActivatedRoute) {} ngOnInit() { - this.route.data.subscribe((data: { list: Section[] }) => { + this.route.data.subscribe((value) => { + const data = value as { list: Section[] }; this.list = data.list; }); this.dataSource = new SectionListDataSource(this.list); diff --git a/bookie/src/app/sections/section.service.ts b/bookie/src/app/sections/section.service.ts index 65f3309..f16d786 100644 --- a/bookie/src/app/sections/section.service.ts +++ b/bookie/src/app/sections/section.service.ts @@ -18,7 +18,7 @@ const serviceName = 'SectionService'; export class SectionService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string): Observable
{ + get(id: string | null): Observable
{ const getUrl: string = id === null ? url : `${url}/${id}`; return >( this.http diff --git a/bookie/src/app/shared/cookie.service.ts b/bookie/src/app/shared/cookie.service.ts index 44fb306..8faac0d 100644 --- a/bookie/src/app/shared/cookie.service.ts +++ b/bookie/src/app/shared/cookie.service.ts @@ -20,7 +20,7 @@ export class CookieService { return ''; } - public deleteCookie(name) { + public deleteCookie(name: string) { this.setCookie(name, '', -1); } diff --git a/bookie/src/app/shared/to-csv.service.ts b/bookie/src/app/shared/to-csv.service.ts index 5d080fd..3fcfe65 100644 --- a/bookie/src/app/shared/to-csv.service.ts +++ b/bookie/src/app/shared/to-csv.service.ts @@ -7,7 +7,7 @@ export class ToCsvService { // eslint-disable-next-line class-methods-use-this toCsv(headers: any, data: any[]): string { const header = Object.keys(headers); - const replacer = (key, value) => (value === null ? '' : value); + const replacer = (key: string, value: string | number | null) => (value === null ? '' : value); const csv = data.map((row) => header.map((fieldName) => JSON.stringify(row[headers[fieldName]], replacer)).join(','), ); diff --git a/bookie/src/app/tables/table-detail/table-detail.component.spec.ts b/bookie/src/app/tables/table-detail/table-detail.component.spec.ts index 2897402..b1d6f2f 100644 --- a/bookie/src/app/tables/table-detail/table-detail.component.spec.ts +++ b/bookie/src/app/tables/table-detail/table-detail.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { TableDetailComponent } from './tables-detail.component'; @@ -6,11 +6,13 @@ describe('TableDetailComponent', () => { let component: TableDetailComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [TableDetailComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [TableDetailComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(TableDetailComponent); diff --git a/bookie/src/app/tables/table-detail/table-detail.component.ts b/bookie/src/app/tables/table-detail/table-detail.component.ts index 4bb5206..ef5e9a1 100644 --- a/bookie/src/app/tables/table-detail/table-detail.component.ts +++ b/bookie/src/app/tables/table-detail/table-detail.component.ts @@ -15,10 +15,10 @@ import { TableService } from '../table.service'; styleUrls: ['./table-detail.component.css'], }) export class TableDetailComponent implements OnInit, AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement: ElementRef; + @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; form: FormGroup; - sections: Section[]; - item: Table; + sections: Section[] = []; + item: Table = new Table(); constructor( private route: ActivatedRoute, @@ -28,10 +28,7 @@ export class TableDetailComponent implements OnInit, AfterViewInit { private toaster: ToasterService, private ser: TableService, ) { - this.createForm(); - } - - createForm() { + // Create form this.form = this.fb.group({ name: '', seats: '', @@ -41,7 +38,8 @@ export class TableDetailComponent implements OnInit, AfterViewInit { } ngOnInit() { - this.route.data.subscribe((data: { item: Table; sections: Section[] }) => { + this.route.data.subscribe((value) => { + const data = value as { item: Table; sections: Section[] }; this.showItem(data.item); this.sections = data.sections; }); @@ -59,7 +57,9 @@ export class TableDetailComponent implements OnInit, AfterViewInit { ngAfterViewInit() { setTimeout(() => { - this.nameElement.nativeElement.focus(); + if (this.nameElement !== undefined) { + this.nameElement.nativeElement.focus(); + } }, 0); } @@ -76,7 +76,7 @@ export class TableDetailComponent implements OnInit, AfterViewInit { } delete() { - this.ser.delete(this.item.id).subscribe( + this.ser.delete(this.item.id as string).subscribe( () => { this.toaster.show('Success', ''); this.router.navigateByUrl('/tables'); diff --git a/bookie/src/app/tables/table-list/table-list-datasource.ts b/bookie/src/app/tables/table-list/table-list-datasource.ts index 099057a..4b50cd8 100644 --- a/bookie/src/app/tables/table-list/table-list-datasource.ts +++ b/bookie/src/app/tables/table-list/table-list-datasource.ts @@ -5,7 +5,7 @@ import { tap } from 'rxjs/operators'; import { Table } from '../../core/table'; export class TableListDataSource extends DataSource
{ - private data: Table[]; + private data: Table[] = []; constructor(private readonly dataObs: Observable) { super(); diff --git a/bookie/src/app/tables/table-list/table-list.component.ts b/bookie/src/app/tables/table-list/table-list.component.ts index 4e48dbf..0de575c 100644 --- a/bookie/src/app/tables/table-list/table-list.component.ts +++ b/bookie/src/app/tables/table-list/table-list.component.ts @@ -17,10 +17,10 @@ import { TableListDataSource } from './table-list-datasource'; styleUrls: ['./table-list.component.css'], }) export class TableListComponent implements OnInit { - @ViewChild('table', { static: true }) table: MatTable; - dataSource: TableListDataSource; - list: Table[]; - data: BehaviorSubject; + @ViewChild('table', { static: true }) table?: MatTable; + data: BehaviorSubject = new BehaviorSubject([]); + dataSource: TableListDataSource = new TableListDataSource(this.data); + list: Table[] = []; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'seats', 'section', 'isActive']; @@ -30,14 +30,14 @@ export class TableListComponent implements OnInit { private toaster: ToasterService, private ser: TableService, ) { - this.data = new BehaviorSubject([]); this.data.subscribe((data: Table[]) => { this.list = data; }); } ngOnInit() { - this.route.data.subscribe((data: { list: Table[] }) => { + this.route.data.subscribe((value) => { + const data = value as { list: Table[] }; this.data.next(data.list); }); this.dataSource = new TableListDataSource(this.data); diff --git a/bookie/src/app/tables/table.service.ts b/bookie/src/app/tables/table.service.ts index 98d3d49..c278156 100644 --- a/bookie/src/app/tables/table.service.ts +++ b/bookie/src/app/tables/table.service.ts @@ -18,7 +18,7 @@ const serviceName = 'TableService'; export class TableService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string): Observable
{ + get(id: string | null): Observable
{ const getUrl: string = id === null ? url : `${url}/${id}`; return >( this.http diff --git a/bookie/src/app/tax-report/tax-report-item.ts b/bookie/src/app/tax-report/tax-report-item.ts index c090543..6c86773 100644 --- a/bookie/src/app/tax-report/tax-report-item.ts +++ b/bookie/src/app/tax-report/tax-report-item.ts @@ -3,4 +3,12 @@ export class TaxReportItem { taxRate: number; saleAmount: number; amount: number; + + public constructor(init?: Partial) { + this.name = ''; + this.taxRate = 0; + this.saleAmount = 0; + this.amount = 0; + Object.assign(this, init); + } } diff --git a/bookie/src/app/tax-report/tax-report.component.spec.ts b/bookie/src/app/tax-report/tax-report.component.spec.ts index 0ac9d78..adbbb75 100644 --- a/bookie/src/app/tax-report/tax-report.component.spec.ts +++ b/bookie/src/app/tax-report/tax-report.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { TaxReportComponent } from './tax-report.component'; @@ -6,11 +6,13 @@ describe('TaxReportComponent', () => { let component: TaxReportComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [TaxReportComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [TaxReportComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(TaxReportComponent); diff --git a/bookie/src/app/tax-report/tax-report.component.ts b/bookie/src/app/tax-report/tax-report.component.ts index c96be48..d96db40 100644 --- a/bookie/src/app/tax-report/tax-report.component.ts +++ b/bookie/src/app/tax-report/tax-report.component.ts @@ -14,9 +14,9 @@ import { TaxReportDatasource } from './tax-report-datasource'; styleUrls: ['./tax-report.component.css'], }) export class TaxReportComponent implements OnInit { - dataSource: TaxReportDatasource; + info: TaxReport = new TaxReport(); + dataSource: TaxReportDatasource = new TaxReportDatasource(this.info.amounts); form: FormGroup; - info: TaxReport; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'taxRate', 'saleAmount', 'taxAmount']; @@ -27,11 +27,16 @@ export class TaxReportComponent implements OnInit { private fb: FormBuilder, private toCsv: ToCsvService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + startDate: '', + finishDate: '', + }); } ngOnInit() { - this.route.data.subscribe((data: { info: TaxReport }) => { + this.route.data.subscribe((value) => { + const data = value as { info: TaxReport }; this.info = data.info; this.form.setValue({ startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(), @@ -51,20 +56,13 @@ export class TaxReportComponent implements OnInit { }); } - createForm() { - this.form = this.fb.group({ - startDate: '', - finishDate: '', - }); - } - getInfo(): TaxReport { const formModel = this.form.value; - return { + return new TaxReport({ startDate: moment(formModel.startDate).format('DD-MMM-YYYY'), finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'), - }; + }); } exportCsv() { diff --git a/bookie/src/app/tax-report/tax-report.service.ts b/bookie/src/app/tax-report/tax-report.service.ts index 5e5ea7e..f379d27 100644 --- a/bookie/src/app/tax-report/tax-report.service.ts +++ b/bookie/src/app/tax-report/tax-report.service.ts @@ -16,7 +16,7 @@ const serviceName = 'TaxReportService'; export class TaxReportService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(startDate: string, finishDate): Observable { + get(startDate: string | null, finishDate: string | null): Observable { const options = { params: new HttpParams() }; if (startDate !== null) { options.params = options.params.set('s', startDate); diff --git a/bookie/src/app/tax-report/tax-report.ts b/bookie/src/app/tax-report/tax-report.ts index cbbc92b..a6624dd 100644 --- a/bookie/src/app/tax-report/tax-report.ts +++ b/bookie/src/app/tax-report/tax-report.ts @@ -3,5 +3,12 @@ import { TaxReportItem } from './tax-report-item'; export class TaxReport { startDate: string; finishDate: string; - amounts?: TaxReportItem[]; + amounts: TaxReportItem[]; + + public constructor(init?: Partial) { + this.startDate = ''; + this.finishDate = ''; + this.amounts = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/taxes/tax-detail/tax-detail.component.spec.ts b/bookie/src/app/taxes/tax-detail/tax-detail.component.spec.ts index 8ff524f..973f489 100644 --- a/bookie/src/app/taxes/tax-detail/tax-detail.component.spec.ts +++ b/bookie/src/app/taxes/tax-detail/tax-detail.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { TaxDetailComponent } from './tax-detail.component'; @@ -6,11 +6,13 @@ describe('TaxDetailComponent', () => { let component: TaxDetailComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [TaxDetailComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [TaxDetailComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(TaxDetailComponent); diff --git a/bookie/src/app/taxes/tax-detail/tax-detail.component.ts b/bookie/src/app/taxes/tax-detail/tax-detail.component.ts index 8f651c5..1c7dbf9 100644 --- a/bookie/src/app/taxes/tax-detail/tax-detail.component.ts +++ b/bookie/src/app/taxes/tax-detail/tax-detail.component.ts @@ -14,9 +14,9 @@ import { TaxService } from '../tax.service'; styleUrls: ['./tax-detail.component.css'], }) export class TaxDetailComponent implements OnInit, AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement: ElementRef; + @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; form: FormGroup; - item: Tax; + item: Tax = new Tax(); constructor( private route: ActivatedRoute, @@ -26,10 +26,7 @@ export class TaxDetailComponent implements OnInit, AfterViewInit { private toaster: ToasterService, private ser: TaxService, ) { - this.createForm(); - } - - createForm() { + // Create form this.form = this.fb.group({ name: '', rate: '', @@ -37,7 +34,8 @@ export class TaxDetailComponent implements OnInit, AfterViewInit { } ngOnInit() { - this.route.data.subscribe((data: { item: Tax }) => { + this.route.data.subscribe((value) => { + const data = value as { item: Tax }; this.showItem(data.item); }); } @@ -52,7 +50,9 @@ export class TaxDetailComponent implements OnInit, AfterViewInit { ngAfterViewInit() { setTimeout(() => { - this.nameElement.nativeElement.focus(); + if (this.nameElement !== undefined) { + this.nameElement.nativeElement.focus(); + } }, 0); } @@ -69,7 +69,7 @@ export class TaxDetailComponent implements OnInit, AfterViewInit { } delete() { - this.ser.delete(this.item.id).subscribe( + this.ser.delete(this.item.id as string).subscribe( () => { this.toaster.show('Success', ''); this.router.navigateByUrl('/taxes'); diff --git a/bookie/src/app/taxes/tax-list/tax-list.component.ts b/bookie/src/app/taxes/tax-list/tax-list.component.ts index 4b2c279..9deed7d 100644 --- a/bookie/src/app/taxes/tax-list/tax-list.component.ts +++ b/bookie/src/app/taxes/tax-list/tax-list.component.ts @@ -11,15 +11,16 @@ import { TaxListDataSource } from './tax-list-datasource'; styleUrls: ['./tax-list.component.css'], }) export class TaxListComponent implements OnInit { - dataSource: TaxListDataSource; - list: Tax[]; + list: Tax[] = []; + dataSource: TaxListDataSource = new TaxListDataSource(this.list); /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'rate', 'isFixture']; constructor(private route: ActivatedRoute) {} ngOnInit() { - this.route.data.subscribe((data: { list: Tax[] }) => { + this.route.data.subscribe((value) => { + const data = value as { list: Tax[] }; this.list = data.list; }); this.dataSource = new TaxListDataSource(this.list); diff --git a/bookie/src/app/taxes/tax.service.ts b/bookie/src/app/taxes/tax.service.ts index da47d41..2260466 100644 --- a/bookie/src/app/taxes/tax.service.ts +++ b/bookie/src/app/taxes/tax.service.ts @@ -18,7 +18,7 @@ const serviceName = 'TaxService'; export class TaxService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string): Observable { + get(id: string | null): Observable { const getUrl: string = id === null ? url : `${url}/${id}`; return >( this.http.get(getUrl).pipe(catchError(this.log.handleError(serviceName, `get id=${id}`))) diff --git a/bookie/src/app/update-product-prices/update-product-prices-item.ts b/bookie/src/app/update-product-prices/update-product-prices-item.ts index 95321c3..c2afcd8 100644 --- a/bookie/src/app/update-product-prices/update-product-prices-item.ts +++ b/bookie/src/app/update-product-prices/update-product-prices-item.ts @@ -3,4 +3,12 @@ export class UpdateProductPricesItem { name: string; oldPrice: number; newPrice: number; + + public constructor(init?: Partial) { + this.id = ''; + this.name = ''; + this.oldPrice = 0; + this.newPrice = 0; + Object.assign(this, init); + } } diff --git a/bookie/src/app/update-product-prices/update-product-prices.component.spec.ts b/bookie/src/app/update-product-prices/update-product-prices.component.spec.ts index cfb6ca7..c081481 100644 --- a/bookie/src/app/update-product-prices/update-product-prices.component.spec.ts +++ b/bookie/src/app/update-product-prices/update-product-prices.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UpdateProductPricesComponent } from './update-product-prices.component'; @@ -6,11 +6,13 @@ describe('UpdateProductPricesComponent', () => { let component: UpdateProductPricesComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [UpdateProductPricesComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UpdateProductPricesComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(UpdateProductPricesComponent); diff --git a/bookie/src/app/update-product-prices/update-product-prices.component.ts b/bookie/src/app/update-product-prices/update-product-prices.component.ts index 85f6817..05c8db4 100644 --- a/bookie/src/app/update-product-prices/update-product-prices.component.ts +++ b/bookie/src/app/update-product-prices/update-product-prices.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; +import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import * as moment from 'moment'; import { map } from 'rxjs/operators'; @@ -18,10 +18,10 @@ import { UpdateProductPricesService } from './update-product-prices.service'; styleUrls: ['./update-product-prices.component.css'], }) export class UpdateProductPricesComponent implements OnInit { - dataSource: UpdateProductPricesDataSource; + info: UpdateProductPrices = new UpdateProductPrices(); + dataSource: UpdateProductPricesDataSource = new UpdateProductPricesDataSource(this.info.items); form: FormGroup; - menuCategories: MenuCategory[]; - info: UpdateProductPrices; + menuCategories: MenuCategory[] = []; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'oldPrice', 'newPrice']; @@ -34,14 +34,22 @@ export class UpdateProductPricesComponent implements OnInit { private toaster: ToasterService, private ser: UpdateProductPricesService, ) { - this.createForm(); + // Create form + this.form = this.fb.group({ + date: '', + menuCategory: '', + prices: this.fb.array([]), + }); } ngOnInit() { this.route.data .pipe( - map((data: { menuCategories: MenuCategory[]; info: UpdateProductPrices }) => { - data.menuCategories.unshift(new MenuCategory({ id: null, name: '-- All Categories --' })); + map((value) => { + const data = value as { menuCategories: MenuCategory[]; info: UpdateProductPrices }; + data.menuCategories.unshift( + new MenuCategory({ id: undefined, name: '-- All Categories --' }), + ); return data; }), ) @@ -53,10 +61,12 @@ export class UpdateProductPricesComponent implements OnInit { loadData(info: UpdateProductPrices) { this.info = info; - this.form.get('date').setValue(moment(this.info.date, 'DD-MMM-YYYY').toDate()); - this.form - .get('menuCategory') - .setValue(this.info.menuCategoryId !== undefined ? this.info.menuCategoryId : ''); + (this.form.get('date') as AbstractControl).setValue( + moment(this.info.date, 'DD-MMM-YYYY').toDate(), + ); + (this.form.get('menuCategory') as AbstractControl).setValue( + this.info.menuCategoryId !== undefined ? this.info.menuCategoryId : '', + ); this.form.setControl( 'prices', this.fb.array( @@ -73,7 +83,7 @@ export class UpdateProductPricesComponent implements OnInit { show() { const info = this.getInfo(); const route = ['update-product-prices']; - if (info.menuCategoryId !== null) route.push(info.menuCategoryId); + if (info.menuCategoryId !== null) route.push(info.menuCategoryId as string); this.router.navigate(route, { queryParams: { date: info.date, @@ -81,14 +91,6 @@ export class UpdateProductPricesComponent implements OnInit { }); } - createForm() { - this.form = this.fb.group({ - date: '', - menuCategory: '', - prices: this.fb.array([]), - }); - } - getInfo(): UpdateProductPrices { const formModel = this.form.value; const array = this.form.get('prices') as FormArray; diff --git a/bookie/src/app/update-product-prices/update-product-prices.service.ts b/bookie/src/app/update-product-prices/update-product-prices.service.ts index 3f3cc6c..4056040 100644 --- a/bookie/src/app/update-product-prices/update-product-prices.service.ts +++ b/bookie/src/app/update-product-prices/update-product-prices.service.ts @@ -17,7 +17,7 @@ const serviceName = 'UpdateProductPricesService'; export class UpdateProductPricesService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string, date: string): Observable { + get(id: string | null, date: string | null): Observable { const getUrl: string = id === null ? url : `${url}/${id}`; const options = { params: new HttpParams() }; if (date !== null) { diff --git a/bookie/src/app/update-product-prices/update-product-prices.ts b/bookie/src/app/update-product-prices/update-product-prices.ts index 3f43c3d..11a10fd 100644 --- a/bookie/src/app/update-product-prices/update-product-prices.ts +++ b/bookie/src/app/update-product-prices/update-product-prices.ts @@ -4,4 +4,10 @@ export class UpdateProductPrices { date: string; menuCategoryId?: string; items: UpdateProductPricesItem[]; + + public constructor(init?: Partial) { + this.date = ''; + this.items = []; + Object.assign(this, init); + } } diff --git a/bookie/src/app/users/user-detail/user-detail.component.spec.ts b/bookie/src/app/users/user-detail/user-detail.component.spec.ts index edfa2f5..8bb5bc3 100644 --- a/bookie/src/app/users/user-detail/user-detail.component.spec.ts +++ b/bookie/src/app/users/user-detail/user-detail.component.spec.ts @@ -1,4 +1,4 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UserDetailComponent } from './user-detail.component'; @@ -6,11 +6,13 @@ describe('UserDetailComponent', () => { let component: UserDetailComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [UserDetailComponent], - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UserDetailComponent], + }).compileComponents(); + }), + ); beforeEach(() => { fixture = TestBed.createComponent(UserDetailComponent); diff --git a/bookie/src/app/users/user-detail/user-detail.component.ts b/bookie/src/app/users/user-detail/user-detail.component.ts index 875812b..5622064 100644 --- a/bookie/src/app/users/user-detail/user-detail.component.ts +++ b/bookie/src/app/users/user-detail/user-detail.component.ts @@ -1,5 +1,5 @@ import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; -import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; +import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; @@ -14,9 +14,9 @@ import { UserService } from '../user.service'; styleUrls: ['./user-detail.component.css'], }) export class UserDetailComponent implements OnInit, AfterViewInit { - @ViewChild('nameElement', { static: true }) nameElement: ElementRef; + @ViewChild('nameElement', { static: true }) nameElement?: ElementRef; form: FormGroup; - item: User; + item: User = new User(); hide: boolean; constructor( @@ -28,10 +28,7 @@ export class UserDetailComponent implements OnInit, AfterViewInit { private ser: UserService, ) { this.hide = true; - this.createForm(); - } - - createForm() { + // Create form this.form = this.fb.group({ name: '', password: '', @@ -41,16 +38,17 @@ export class UserDetailComponent implements OnInit, AfterViewInit { } ngOnInit() { - this.route.data.subscribe((data: { item: User }) => { + this.route.data.subscribe((value) => { + const data = value as { item: User }; this.showItem(data.item); }); } showItem(item: User) { this.item = item; - this.form.get('name').setValue(item.name); - this.form.get('password').setValue(''); - this.form.get('lockedOut').setValue(item.lockedOut); + (this.form.get('name') as AbstractControl).setValue(item.name); + (this.form.get('password') as AbstractControl).setValue(''); + (this.form.get('lockedOut') as AbstractControl).setValue(item.lockedOut); this.form.setControl( 'roles', this.fb.array( @@ -65,7 +63,11 @@ export class UserDetailComponent implements OnInit, AfterViewInit { ngAfterViewInit() { setTimeout(() => { - this.nameElement.nativeElement.focus(); + if (this.nameElement !== undefined) { + if (this.nameElement !== undefined) { + this.nameElement.nativeElement.focus(); + } + } }, 0); } @@ -82,7 +84,7 @@ export class UserDetailComponent implements OnInit, AfterViewInit { } delete() { - this.ser.delete(this.item.id).subscribe( + this.ser.delete(this.item.id as string).subscribe( () => { this.toaster.show('Success', ''); this.router.navigateByUrl('/users'); @@ -112,9 +114,11 @@ export class UserDetailComponent implements OnInit, AfterViewInit { this.item.password = formModel.password; this.item.lockedOut = formModel.lockedOut; const array = this.form.get('roles') as FormArray; - this.item.roles.forEach((item, index) => { - item.enabled = array.controls[index].value.role; - }); + if (this.item.roles !== undefined) { + this.item.roles.forEach((item, index) => { + item.enabled = array.controls[index].value.role; + }); + } return this.item; } } diff --git a/bookie/src/app/users/user-list/user-list.component.ts b/bookie/src/app/users/user-list/user-list.component.ts index b8e747f..3fbcd8b 100644 --- a/bookie/src/app/users/user-list/user-list.component.ts +++ b/bookie/src/app/users/user-list/user-list.component.ts @@ -11,15 +11,16 @@ import { UserListDataSource } from './user-list-datasource'; styleUrls: ['./user-list.component.css'], }) export class UserListComponent implements OnInit { - dataSource: UserListDataSource; - list: User[]; + dataSource: UserListDataSource = new UserListDataSource([]); + list: User[] = []; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'lockedOut', 'roles', 'last']; constructor(private route: ActivatedRoute) {} ngOnInit() { - this.route.data.subscribe((data: { list: User[] }) => { + this.route.data.subscribe((value) => { + const data = value as { list: User[] }; this.list = data.list; }); this.dataSource = new UserListDataSource(this.list); diff --git a/bookie/src/app/users/user.service.ts b/bookie/src/app/users/user.service.ts index 0988756..918c2b5 100644 --- a/bookie/src/app/users/user.service.ts +++ b/bookie/src/app/users/user.service.ts @@ -18,7 +18,7 @@ const serviceName = 'UserService'; export class UserService { constructor(private http: HttpClient, private log: ErrorLoggerService) {} - get(id: string): Observable { + get(id: string | null): Observable { const getUrl: string = id === null ? `${url}` : `${url}/${id}`; return >( this.http @@ -35,14 +35,6 @@ export class UserService { ); } - listOfNames(): Observable { - return >( - this.http - .get(`${url}/active`) - .pipe(catchError(this.log.handleError(serviceName, 'list'))) - ); - } - save(user: User): Observable { return >( this.http diff --git a/bookie/src/test.ts b/bookie/src/test.ts index e94b4bd..e103ada 100644 --- a/bookie/src/test.ts +++ b/bookie/src/test.ts @@ -7,7 +7,16 @@ import { platformBrowserDynamicTesting, } from '@angular/platform-browser-dynamic/testing'; -declare const require: any; +declare const require: { + context( + path: string, + deep?: boolean, + filter?: RegExp, + ): { + keys(): string[]; + (id: string): T; + }; +}; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); diff --git a/bookie/tsconfig.app.json b/bookie/tsconfig.app.json index d0a39d8..3178957 100644 --- a/bookie/tsconfig.app.json +++ b/bookie/tsconfig.app.json @@ -1,3 +1,4 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ { "extends": "./tsconfig.json", "compilerOptions": { diff --git a/bookie/tsconfig.json b/bookie/tsconfig.json index 7f7e937..1561830 100644 --- a/bookie/tsconfig.json +++ b/bookie/tsconfig.json @@ -1,10 +1,11 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ { "compileOnSave": false, "compilerOptions": { "baseUrl": "./", "outDir": "../frontend", "forceConsistentCasingInFileNames": true, -// "strict": true, + "strict": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "sourceMap": true,