diff --git a/barker/models/master.py b/barker/models/master.py index 39e6871..6c509f8 100644 --- a/barker/models/master.py +++ b/barker/models/master.py @@ -89,13 +89,14 @@ class ProductGroup(Base): is_fixture = Column('is_fixture', Boolean, nullable=False) sort_order = Column('sort_order', Numeric, nullable=False) - def __init__(self, name, discount_limit, is_modifier_compulsory, group_type, is_active, sort_order, id=None): + def __init__(self, name, discount_limit, is_modifier_compulsory, group_type, is_active, sort_order, is_fixture=False, id=None): self.name = name self.discount_limit = discount_limit self.is_modifier_compulsory = is_modifier_compulsory self.group_type = group_type self.is_active = is_active self.sort_order = sort_order + self.is_fixture = is_fixture self.id = id diff --git a/barker/routes.py b/barker/routes.py index a1944ff..fefcaf6 100644 --- a/barker/routes.py +++ b/barker/routes.py @@ -53,10 +53,7 @@ def includeme(config): config.add_route("v1_product_groups_new", "/v1/product-groups/new") config.add_route("v1_product_groups_id", "/v1/product-groups/{id}") config.add_route("v1_product_groups_list", "/v1/product-groups") - - config.add_route('product', '/Product.json') - config.add_route('product_list', '/Products.json') - config.add_route('product_id', '/Product/{id}.json') + config.add_route("v1_product_group_types_list", "/v1/product-group-types") config.add_route('product_group', '/ProductGroup.json') config.add_route('product_group_list', '/ProductGroups.json') diff --git a/barker/views/product_group.py b/barker/views/product_group.py index 67bcd89..dc000e1 100644 --- a/barker/views/product_group.py +++ b/barker/views/product_group.py @@ -1,4 +1,5 @@ import uuid +from decimal import Decimal, InvalidOperation import transaction from pyramid.response import Response @@ -6,37 +7,63 @@ from pyramid.view import view_config from barker.exceptions import ValidationFailure from barker.models import Product, ProductGroup +from barker.models.validation_exception import ValidationError -@view_config(request_method='PUT', route_name='product_group', renderer='json', permission='Products', trans=True) +@view_config(request_method='POST', route_name='v1_product_groups_new', renderer='json', permission='Products', trans=True) def save(request): json = request.json_body - item = ProductGroup(json['Name'], json['DiscountLimit'], json['IsModifierCompulsory'], json['GroupType'], - json['IsActive'], json['SortOrder']) + name = json.get("name", "").strip() + if name == "": + raise ValidationError("Name cannot be blank") + try: + discount_limit = Decimal(json["discountLimit"]) / 100 + if discount_limit < 0 or discount_limit > 1: + raise ValidationError("Tax Rate must be a decimal >= 0 and <= 100") + except (ValueError, InvalidOperation): + raise ValidationError("Tax Rate must be a decimal >= 0 and <= 100") + is_modifier_compulsory = json.get("isModifierCompulsory", True) + group_type = json.get("group_type", "").strip() + is_active = json.get("isActive", True) + item = ProductGroup(name, discount_limit, is_modifier_compulsory, group_type, is_active, 0) request.dbsession.add(item) transaction.commit() - item = request.dbsession.query(ProductGroup).filter(ProductGroup.id == item.id).first() - return product_group_info(item) + return product_group_info(item.id, request.dbsession) -@view_config(request_method='POST', route_name='product_group_id', renderer='json', permission='Products', trans=True) +@view_config(request_method='PUT', route_name='v1_product_groups_id', renderer='json', permission='Products', trans=True) def update(request): - item = request.dbsession.query(ProductGroup).filter(ProductGroup.id == uuid.UUID(request.matchdict['id'])).first() json = request.json_body - item.name = json['Name'] - item.discount_limit = json['DiscountLimit'] - item.is_modifier_compulsory = json['IsModifierCompulsory'] - item.group_type = json['GroupType'] - item.is_active = json['IsActive'] - item.sort_order = json['SortOrder'] + item = ( + request.dbsession.query(ProductGroup) + .filter(ProductGroup.id == uuid.UUID(request.matchdict["id"])) + .first() + ) + if item.is_fixture: + raise ValidationError( + "{0} is a fixture and cannot be edited or deleted.".format(item.full_name) + ) + item.name = json['name'].strip() + try: + item.discount_limit = Decimal(json["discountLimit"]) / 100 + if item.discount_limit < 0 or item.discount_limit > 1: + raise ValidationError("Tax Rate must be a decimal >= 0 and <= 100") + except (ValueError, InvalidOperation): + raise ValidationError("Tax Rate must be a decimal >= 0 and <= 100") + item.is_modifier_compulsory = json.get("isModifierCompulsory", True) + item.group_type = json.get("group_type", "").strip() + item.is_active = json.get("isActive", True) transaction.commit() - item = request.dbsession.query(ProductGroup).filter(ProductGroup.id == item.id).first() - return product_group_info(item) + return product_group_info(item.id, request.dbsession) -@view_config(request_method='DELETE', route_name='product_group_id', renderer='json', permission='Products', trans=True) +@view_config(request_method='DELETE', route_name='v1_product_groups_id', renderer='json', permission='Products', trans=True) def delete(request): - item = request.dbsession.query(ProductGroup).filter(ProductGroup.id == uuid.UUID(request.matchdict['id'])).first() + item = ( + request.dbsession.query(ProductGroup) + .filter(ProductGroup.id == uuid.UUID(request.matchdict["id"])) + .first() + ) if item is None: response = Response("Product Group not Found") response.status_int = 500 @@ -50,30 +77,33 @@ def delete(request): return response -@view_config(request_method='GET', route_name='product_group_id', renderer='json', permission='Authenticated') +@view_config(request_method='GET', route_name='v1_product_groups_new', renderer='json', permission='Authenticated') +def show_blank(request): + return product_group_info(None, request.dbsession) + + +@view_config(request_method='GET', route_name='v1_product_groups_id', renderer='json', permission='Authenticated') def show_id(request): - id = uuid.UUID(request.matchdict['id']) - item = request.dbsession.query(ProductGroup).filter(ProductGroup.id == id).first() - return product_group_info(item) + return product_group_info(uuid.UUID(request.matchdict["id"]), request.dbsession) -@view_config(request_method='GET', route_name='product_group_list', renderer='json', permission='Authenticated') +@view_config(request_method='GET', route_name='v1_product_groups_list', renderer='json', permission='Authenticated') def show_list(request): - list = request.dbsession.query(ProductGroup).order_by(ProductGroup.sort_order).order_by(ProductGroup.name).all() + list_ = request.dbsession.query(ProductGroup).order_by(ProductGroup.sort_order).order_by(ProductGroup.name).all() product_groups = [] - for item in list: - product_groups.append(product_group_info(item)) + for item in list_: + product_groups.append(product_group_info(item, request.dbsession)) return product_groups -@view_config(request_method='GET', route_name='product_group_list', renderer='json', request_param='s', +@view_config(request_method='GET', route_name='v1_product_groups_list', renderer='json', request_param='s', permission='Authenticated') def sale_list(request): - list = request.dbsession.query( + list_ = request.dbsession.query( ProductGroup ).filter(ProductGroup.is_active == True).order_by(ProductGroup.sort_order).order_by(ProductGroup.name).all() product_groups = [] - for item in list: + for item in list_: products = request.dbsession.query( Product ).filter( @@ -99,40 +129,52 @@ def sale_list(request): return product_groups -@view_config(request_method='POST', route_name='product_group_list', renderer='json', permission='Products', trans=True) +@view_config(request_method='POST', route_name='v1_product_groups_list', renderer='json', permission='Products', trans=True) def sort_order(request): json = request.json_body for index, item in enumerate(json): request.dbsession.query( ProductGroup ).filter( - ProductGroup.id == uuid.UUID(item['ProductGroupID']) + ProductGroup.id == uuid.UUID(item['id']) ).update( {ProductGroup.sort_order: index} ) return True -@view_config(request_method='GET', route_name='product_group_type_list', renderer='json', permission='Authenticated') +@view_config(request_method='GET', route_name='v1_product_group_types_list', renderer='json', permission='Authenticated') def product_group_type_list(request): - list = request.dbsession.query( + list_ = request.dbsession.query( ProductGroup.group_type ).group_by( ProductGroup.group_type ).order_by( ProductGroup.group_type ).all() - return [item.group_type for item in list] + return [item.group_type for item in list_] -def product_group_info(item): +def product_group_info(item, dbsession): + if item is None: + return { + 'name': "", + 'discountLimit': 0, + 'isModifierCompulsory': False, + 'groupType': "", + 'isActive': True, + 'isFixture': False, + 'sortOrder': 0 + } + if type(item) is uuid.UUID: + item = dbsession.query(ProductGroup).filter(ProductGroup.id == item).first() return { - 'ProductGroupID': item.id, - 'Name': item.name, - 'DiscountLimit': item.discount_limit, - 'IsModifierCompulsory': item.is_modifier_compulsory, - 'GroupType': item.group_type, - - 'IsActive': item.is_active, - 'SortOrder': item.sort_order + 'id': item.id, + 'name': item.name, + 'discountLimit': item.discount_limit, + 'isModifierCompulsory': item.is_modifier_compulsory, + 'groupType': item.group_type, + 'isActive': item.is_active, + 'isFixture': item.is_fixture, + 'sortOrder': item.sort_order } diff --git a/bookie/src/app/app-routing.module.ts b/bookie/src/app/app-routing.module.ts index 518fd3c..cf2f12d 100644 --- a/bookie/src/app/app-routing.module.ts +++ b/bookie/src/app/app-routing.module.ts @@ -15,7 +15,7 @@ const routes: Routes = [ }, { path: 'product-groups', - loadChildren: () => import('./product-group/product-group.module').then(mod => mod.ProductGroupModule) + loadChildren: () => import('./product-group/product-groups.module').then(mod => mod.ProductGroupsModule) }, { path: 'running-tables', diff --git a/bookie/src/app/core/product-group.ts b/bookie/src/app/core/product-group.ts index 51ab0e2..fcca995 100644 --- a/bookie/src/app/core/product-group.ts +++ b/bookie/src/app/core/product-group.ts @@ -3,7 +3,7 @@ export class ProductGroup { name: string; discountLimit: number; isModifierCompulsory: boolean; - groupModifier: string; + groupType: string; isActive: boolean; isFixture: boolean; sortOrder: number; diff --git a/bookie/src/app/home/home.component.html b/bookie/src/app/home/home.component.html index 3a3dda9..ff09da5 100644 --- a/bookie/src/app/home/home.component.html +++ b/bookie/src/app/home/home.component.html @@ -10,6 +10,9 @@ Tables + + Product Groups + Taxes diff --git a/bookie/src/app/product-group/product-group-detail/product-group-detail.component.html b/bookie/src/app/product-group/product-group-detail/product-group-detail.component.html index a8c0167..3423ade 100644 --- a/bookie/src/app/product-group/product-group-detail/product-group-detail.component.html +++ b/bookie/src/app/product-group/product-group-detail/product-group-detail.component.html @@ -9,13 +9,34 @@ fxLayoutGap.lt-md="0px"> Name - + +
+ + Discount Limit + + % + +
+
+ + Group Type + + +
+
+ Is Modifier Compulsory? + Is Active? +
- + + diff --git a/bookie/src/app/product-group/product-group-detail/product-group-detail.component.ts b/bookie/src/app/product-group/product-group-detail/product-group-detail.component.ts index a1b3c28..8134b5d 100644 --- a/bookie/src/app/product-group/product-group-detail/product-group-detail.component.ts +++ b/bookie/src/app/product-group/product-group-detail/product-group-detail.component.ts @@ -1,10 +1,12 @@ -import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; +import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatDialog } from "@angular/material"; -import {ProductGroupService} from '../product-group.service'; -import {ProductGroup} from '../../core/product-group'; -import {ActivatedRoute, Router} from '@angular/router'; -import {ToasterService} from '../../core/toaster.service'; -import {FormBuilder, FormGroup} from '@angular/forms'; +import { ProductGroupService } from '../product-group.service'; +import { ProductGroup } from '../../core/product-group'; +import { ToasterService } from '../../core/toaster.service'; +import { ConfirmDialogComponent } from "../../shared/confirm-dialog/confirm-dialog.component"; @Component({ selector: 'app-product-group-detail', @@ -19,6 +21,7 @@ export class ProductGroupDetailComponent implements OnInit, AfterViewInit { constructor( private route: ActivatedRoute, private router: Router, + private dialog: MatDialog, private fb: FormBuilder, private toaster: ToasterService, private ser: ProductGroupService @@ -28,7 +31,11 @@ export class ProductGroupDetailComponent implements OnInit, AfterViewInit { createForm() { this.form = this.fb.group({ - name: '' + name: '', + discountLimit: '', + isModifierCompulsory: '', + groupType: '', + isActive: '' }); } @@ -43,6 +50,10 @@ export class ProductGroupDetailComponent implements OnInit, AfterViewInit { this.item = item; this.form.setValue({ name: this.item.name, + discountLimit: this.item.discountLimit, + isModifierCompulsory: this.item.isModifierCompulsory, + groupType: this.item.groupType, + isActive: this.item.isActive }); } @@ -65,9 +76,39 @@ export class ProductGroupDetailComponent implements OnInit, AfterViewInit { ); } + delete() { + this.ser.delete(this.item.id) + .subscribe( + (result) => { + this.toaster.show('Success', ''); + this.router.navigateByUrl('/product-groups'); + }, + (error) => { + this.toaster.show('Danger', error.error); + } + ); + } + + confirmDelete(): void { + const dialogRef = this.dialog.open(ConfirmDialogComponent, { + width: '250px', + data: {title: 'Delete Product Group?', content: 'Are you sure? This cannot be undone.'} + }); + + dialogRef.afterClosed().subscribe((result: boolean) => { + if (result) { + this.delete(); + } + }); + } + getItem(): ProductGroup { const formModel = this.form.value; this.item.name = formModel.name; + this.item.discountLimit = +formModel.discountLimit; + this.item.isModifierCompulsory = formModel.isModifierCompulsory; + this.item.groupType = formModel.groupType; + this.item.isActive = formModel.isActive; return this.item; } } diff --git a/bookie/src/app/product-group/product-group-list/product-group-list-datasource.ts b/bookie/src/app/product-group/product-group-list/product-group-list-datasource.ts index 6f81453..8e33b2c 100644 --- a/bookie/src/app/product-group/product-group-list/product-group-list-datasource.ts +++ b/bookie/src/app/product-group/product-group-list/product-group-list-datasource.ts @@ -1,59 +1,17 @@ -import {DataSource} from '@angular/cdk/collections'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import {map} from 'rxjs/operators'; -import {merge, Observable, of as observableOf} from 'rxjs'; -import {ProductGroup} from '../../core/product-group'; +import { DataSource } from '@angular/cdk/collections'; +import { Observable, of as observableOf } from 'rxjs'; +import { ProductGroup } from '../../core/product-group'; export class ProductGroupListDataSource extends DataSource { - constructor(private paginator: MatPaginator, private sort: MatSort, public data: ProductGroup[]) { + constructor(public data: ProductGroup[]) { super(); } connect(): Observable { - const dataMutations = [ - observableOf(this.data), - this.paginator.page, - this.sort.sortChange - ]; - - // Set the paginators length - this.paginator.length = this.data.length; - - return merge(...dataMutations).pipe(map(() => { - return this.getPagedData(this.getSortedData([...this.data])); - })); + return observableOf(this.data); } disconnect() { } - - private getPagedData(data: ProductGroup[]) { - const startIndex = this.paginator.pageIndex * this.paginator.pageSize; - return data.splice(startIndex, this.paginator.pageSize); - } - - private getSortedData(data: ProductGroup[]) { - if (!this.sort.active || this.sort.direction === '') { - return data; - } - - return data.sort((a, b) => { - const isAsc = this.sort.direction === 'asc'; - switch (this.sort.active) { - case 'name': - return compare(a.name, b.name, isAsc); - case 'id': - return compare(+a.id, +b.id, isAsc); - default: - return 0; - } - }); - } -} - -/** Simple sort comparator for example ID/Name columns (for client-side sorting). */ -function compare(a, b, isAsc) { - return (a < b ? -1 : 1) * (isAsc ? 1 : -1); } diff --git a/bookie/src/app/product-group/product-group-list/product-group-list.component.html b/bookie/src/app/product-group/product-group-list/product-group-list.component.html index f62d2f8..ee0c251 100644 --- a/bookie/src/app/product-group/product-group-list/product-group-list.component.html +++ b/bookie/src/app/product-group/product-group-list/product-group-list.component.html @@ -1,35 +1,55 @@ Product Groups + add_box Add - + - Name + Name {{row.name}} + + + Discount Limit + {{row.discountLimit | percent:'1.2-2'}} + + + + + Modifier Compulsory? + {{row.isModifierCompulsory}} + + + + + Group Type + {{row.groupType}} + + + + + Active? + {{row.isActive}} + + - Is Fixture? + Fixture? {{row.isFixture}} - + - - - diff --git a/bookie/src/app/product-group/product-group-list/product-group-list.component.ts b/bookie/src/app/product-group/product-group-list/product-group-list.component.ts index eee7c7a..746ab1d 100644 --- a/bookie/src/app/product-group/product-group-list/product-group-list.component.ts +++ b/bookie/src/app/product-group/product-group-list/product-group-list.component.ts @@ -1,9 +1,11 @@ -import {Component, OnInit, ViewChild} from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import {ProductGroupListDataSource} from './product-group-list-datasource'; -import {ProductGroup} from '../../core/product-group'; -import {ActivatedRoute} from '@angular/router'; +import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; +import { ProductGroupListDataSource } from './product-group-list-datasource'; +import { ProductGroup } from '../../core/product-group'; +import {ActivatedRoute, Router} from '@angular/router'; +import {CdkDragDrop, moveItemInArray} from "@angular/cdk/drag-drop"; +import {MatTable} from "@angular/material"; +import {ToasterService} from "../../core/toaster.service"; +import {ProductGroupService} from "../product-group.service"; @Component({ selector: 'app-product-group-list', @@ -11,21 +13,43 @@ import {ActivatedRoute} from '@angular/router'; styleUrls: ['./product-group-list.component.css'] }) export class ProductGroupListComponent implements OnInit { - @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - @ViewChild(MatSort, { static: true }) sort: MatSort; + @ViewChild('table', { static: true }) table: MatTable; dataSource: ProductGroupListDataSource; list: ProductGroup[]; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ - displayedColumns = ['name', 'isFixture']; + displayedColumns = ['name', 'discountLimit', 'isModifierCompulsory', 'groupType', 'isActive', 'isFixture']; - constructor(private route: ActivatedRoute) { - } + constructor( + private route: ActivatedRoute, + private router: Router, + private toaster: ToasterService, + private ser: ProductGroupService + ) { + } ngOnInit() { this.route.data .subscribe((data: { list: ProductGroup[] }) => { this.list = data.list; }); - this.dataSource = new ProductGroupListDataSource(this.paginator, this.sort, this.list); + this.dataSource = new ProductGroupListDataSource(this.list); + } + + updateSortOrder() { + this.ser.updateSortOrder(this.list) + .subscribe( + (result) => { + this.toaster.show('Success', ''); + this.router.navigateByUrl('/product-groups'); + }, + (error) => { + this.toaster.show('Danger', error.error); + } + ); + } + dropTable(event: CdkDragDrop) { + const prevIndex = this.list.indexOf(event.item.data); + moveItemInArray(this.list, prevIndex, event.currentIndex); + this.table.renderRows(); } } diff --git a/bookie/src/app/product-group/product-group-resolver.service.spec.ts b/bookie/src/app/product-group/product-group-resolver.service.spec.ts index fea6971..0200b56 100644 --- a/bookie/src/app/product-group/product-group-resolver.service.spec.ts +++ b/bookie/src/app/product-group/product-group-resolver.service.spec.ts @@ -1,15 +1,15 @@ import {inject, TestBed} from '@angular/core/testing'; -import {ProductGroupResolverService} from './product-group-resolver.service'; +import {ProductGroupResolver} from './product-group-resolver.service'; -describe('ProductGroupResolverService', () => { +describe('ProductGroupResolver', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [ProductGroupDetailResolverService] + providers: [ProductGroupResolver] }); }); - it('should be created', inject([ProductGroupDetailResolverService], (service: ProductGroupDetailResolverService) => { + it('should be created', inject([ProductGroupResolver], (service: ProductGroupResolver) => { expect(service).toBeTruthy(); })); }); diff --git a/bookie/src/app/product-group/product-group-routing.module.spec.ts b/bookie/src/app/product-group/product-group-routing.module.spec.ts deleted file mode 100644 index 88d6e8f..0000000 --- a/bookie/src/app/product-group/product-group-routing.module.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {ProductGroupRoutingModule} from './product-group-routing.module'; - -describe('ProductGroupRoutingModule', () => { - let productGroupRoutingModule: ProductGroupRoutingModule; - - beforeEach(() => { - productGroupRoutingModule = new ProductGroupRoutingModule(); - }); - - it('should create an instance', () => { - expect(productGroupRoutingModule).toBeTruthy(); - }); -}); diff --git a/bookie/src/app/product-group/product-group.module.spec.ts b/bookie/src/app/product-group/product-group.module.spec.ts deleted file mode 100644 index 40eb41d..0000000 --- a/bookie/src/app/product-group/product-group.module.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {ProductGroupModule} from './product-group.module'; - -describe('ProductGroupModule', () => { - let productGroupModule: ProductGroupModule; - - beforeEach(() => { - productGroupModule = new ProductGroupModule(); - }); - - it('should create an instance', () => { - expect(productGroupModule).toBeTruthy(); - }); -}); diff --git a/bookie/src/app/product-group/product-group.service.ts b/bookie/src/app/product-group/product-group.service.ts index afb00e4..ac5f589 100644 --- a/bookie/src/app/product-group/product-group.service.ts +++ b/bookie/src/app/product-group/product-group.service.ts @@ -8,7 +8,7 @@ import {ProductGroup} from '../core/product-group'; const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) }; -const url = '/api/product-groups'; +const url = '/v1/product-groups'; const serviceName = 'ProductGroupService'; @Injectable({ @@ -48,6 +48,13 @@ export class ProductGroupService { ); } + updateSortOrder(list: ProductGroup[]): Observable { + return >this.http.post(url, list, httpOptions) + .pipe( + catchError(this.log.handleError(serviceName, 'updateSortOrder')) + ); + } + saveOrUpdate(productGroup: ProductGroup): Observable { if (!productGroup.id) { return this.save(productGroup); diff --git a/bookie/src/app/product-group/product-groups-routing.module.spec.ts b/bookie/src/app/product-group/product-groups-routing.module.spec.ts new file mode 100644 index 0000000..56bfefe --- /dev/null +++ b/bookie/src/app/product-group/product-groups-routing.module.spec.ts @@ -0,0 +1,13 @@ +import {ProductGroupsRoutingModule} from './product-groups-routing.module'; + +describe('ProductGroupsRoutingModule', () => { + let productGroupsRoutingModule: ProductGroupsRoutingModule; + + beforeEach(() => { + productGroupsRoutingModule = new ProductGroupsRoutingModule(); + }); + + it('should create an instance', () => { + expect(productGroupsRoutingModule).toBeTruthy(); + }); +}); diff --git a/bookie/src/app/product-group/product-group-routing.module.ts b/bookie/src/app/product-group/product-groups-routing.module.ts similarity index 90% rename from bookie/src/app/product-group/product-group-routing.module.ts rename to bookie/src/app/product-group/product-groups-routing.module.ts index c6d0cdd..189e65c 100644 --- a/bookie/src/app/product-group/product-group-routing.module.ts +++ b/bookie/src/app/product-group/product-groups-routing.module.ts @@ -13,7 +13,7 @@ const productGroupRoutes: Routes = [ component: ProductGroupListComponent, canActivate: [AuthGuard], data: { - permission: 'Cost Centres' + permission: 'Products' }, resolve: { list: ProductGroupListResolver @@ -24,7 +24,7 @@ const productGroupRoutes: Routes = [ component: ProductGroupDetailComponent, canActivate: [AuthGuard], data: { - permission: 'Cost Centres' + permission: 'Products' }, resolve: { item: ProductGroupResolver @@ -35,7 +35,7 @@ const productGroupRoutes: Routes = [ component: ProductGroupDetailComponent, canActivate: [AuthGuard], data: { - permission: 'Cost Centres' + permission: 'Products' }, resolve: { item: ProductGroupResolver @@ -57,5 +57,5 @@ const productGroupRoutes: Routes = [ ProductGroupResolver ] }) -export class ProductGroupRoutingModule { +export class ProductGroupsRoutingModule { } diff --git a/bookie/src/app/product-group/product-groups.module.spec.ts b/bookie/src/app/product-group/product-groups.module.spec.ts new file mode 100644 index 0000000..566075a --- /dev/null +++ b/bookie/src/app/product-group/product-groups.module.spec.ts @@ -0,0 +1,13 @@ +import {ProductGroupsModule} from './product-groups.module'; + +describe('ProductGroupsModule', () => { + let productGroupsModule: ProductGroupsModule; + + beforeEach(() => { + productGroupsModule = new ProductGroupsModule(); + }); + + it('should create an instance', () => { + expect(productGroupsModule).toBeTruthy(); + }); +}); diff --git a/bookie/src/app/product-group/product-group.module.ts b/bookie/src/app/product-group/product-groups.module.ts similarity index 77% rename from bookie/src/app/product-group/product-group.module.ts rename to bookie/src/app/product-group/product-groups.module.ts index f8dbdcb..b9810c3 100644 --- a/bookie/src/app/product-group/product-group.module.ts +++ b/bookie/src/app/product-group/product-groups.module.ts @@ -3,16 +3,18 @@ import {CommonModule} from '@angular/common'; import {ProductGroupListComponent} from './product-group-list/product-group-list.component'; import {ProductGroupDetailComponent} from './product-group-detail/product-group-detail.component'; -import {ProductGroupRoutingModule} from './product-group-routing.module'; +import {ProductGroupsRoutingModule} from './product-groups-routing.module'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; +import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; -import {CdkTableModule} from '@angular/cdk/table'; +import { CdkTableModule } from '@angular/cdk/table'; +import { DragDropModule } from '@angular/cdk/drag-drop'; import {FlexLayoutModule} from '@angular/flex-layout'; import {ReactiveFormsModule} from '@angular/forms'; @@ -20,22 +22,24 @@ import {ReactiveFormsModule} from '@angular/forms'; imports: [ CommonModule, CdkTableModule, + DragDropModule, FlexLayoutModule, MatTableModule, MatPaginatorModule, MatSortModule, MatCardModule, + MatCheckboxModule, MatProgressSpinnerModule, MatInputModule, MatButtonModule, MatIconModule, ReactiveFormsModule, - ProductGroupRoutingModule + ProductGroupsRoutingModule ], declarations: [ ProductGroupListComponent, ProductGroupDetailComponent ] }) -export class ProductGroupModule { +export class ProductGroupsModule { } 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 0a3d6f0..996643d 100644 --- a/bookie/src/app/taxes/tax-detail/tax-detail.component.ts +++ b/bookie/src/app/taxes/tax-detail/tax-detail.component.ts @@ -1,10 +1,12 @@ -import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; +import { AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatDialog} from "@angular/material/dialog"; -import {TaxService} from '../tax.service'; -import {Tax} from '../../core/tax'; -import {ActivatedRoute, Router} from '@angular/router'; -import {ToasterService} from '../../core/toaster.service'; -import {FormBuilder, FormGroup} from '@angular/forms'; +import { TaxService } from '../tax.service'; +import { Tax } from '../../core/tax'; +import { ToasterService } from '../../core/toaster.service'; +import { ConfirmDialogComponent } from "../../shared/confirm-dialog/confirm-dialog.component"; @Component({ selector: 'app-tax-detail', @@ -19,6 +21,7 @@ export class TaxDetailComponent implements OnInit, AfterViewInit { constructor( private route: ActivatedRoute, private router: Router, + private dialog: MatDialog, private fb: FormBuilder, private toaster: ToasterService, private ser: TaxService @@ -67,10 +70,36 @@ export class TaxDetailComponent implements OnInit, AfterViewInit { ); } + delete() { + this.ser.delete(this.item.id) + .subscribe( + (result) => { + this.toaster.show('Success', ''); + this.router.navigateByUrl('/taxes'); + }, + (error) => { + this.toaster.show('Danger', error.error); + } + ); + } + + confirmDelete(): void { + const dialogRef = this.dialog.open(ConfirmDialogComponent, { + width: '250px', + data: {title: 'Delete Tax?', content: 'Are you sure? This cannot be undone.'} + }); + + dialogRef.afterClosed().subscribe((result: boolean) => { + if (result) { + this.delete(); + } + }); + } + getItem(): Tax { const formModel = this.form.value; this.item.name = formModel.name; - this.item.rate = formModel.rate; + this.item.rate = +formModel.rate; return this.item; } }