From ca80e5eff477d0a22a0c8c8dc6564c9874310814 Mon Sep 17 00:00:00 2001 From: Abhay Chawla Date: Mon, 6 Aug 2018 00:41:53 +0530 Subject: [PATCH] feat(accounting-rules): edit and delete rule Add edit accounting rule component and ability to delete accounting rule. --- .../accounting/accounting-routing.module.ts | 16 ++- .../edit-rule/edit-rule.component.html | 105 ++++++++++++++++ .../edit-rule/edit-rule.component.scss | 19 +++ .../edit-rule/edit-rule.component.spec.ts | 25 ++++ .../edit-rule/edit-rule.component.ts | 115 ++++++++++++++++++ .../view-rule/view-rule.component.ts | 25 +++- src/app/accounting/accounting.module.ts | 4 +- src/app/accounting/accounting.service.ts | 8 ++ 8 files changed, 312 insertions(+), 5 deletions(-) create mode 100644 src/app/accounting/accounting-rules/edit-rule/edit-rule.component.html create mode 100644 src/app/accounting/accounting-rules/edit-rule/edit-rule.component.scss create mode 100644 src/app/accounting/accounting-rules/edit-rule/edit-rule.component.spec.ts create mode 100644 src/app/accounting/accounting-rules/edit-rule/edit-rule.component.ts diff --git a/src/app/accounting/accounting-routing.module.ts b/src/app/accounting/accounting-routing.module.ts index 46065b4b5..db6f3e96c 100644 --- a/src/app/accounting/accounting-routing.module.ts +++ b/src/app/accounting/accounting-routing.module.ts @@ -29,6 +29,7 @@ import { AccountingRulesComponent } from './accounting-rules/accounting-rules.co import { CreateRuleComponent } from './accounting-rules/create-rule/create-rule.component'; import { ViewRuleComponent } from './accounting-rules/view-rule/view-rule.component'; import { ViewAccountingRuleResolver } from './accounting-rules/view-rule/view-rule.resolver'; +import { EditRuleComponent } from './accounting-rules/edit-rule/edit-rule.component'; const routes: Routes = [ Route.withShell([ @@ -181,11 +182,22 @@ const routes: Routes = [ }, { path: 'view/:id', - component: ViewRuleComponent, data: { title: extract('View Accounting Rule'), routeResolveBreadcrumb: ['accountingRule', 'name'] }, resolve: { accountingRule: ViewAccountingRuleResolver - } + }, + runGuardsAndResolvers: 'always', + children: [ + { + path: '', + component: ViewRuleComponent + }, + { + path: 'edit', + component: EditRuleComponent, + data: { title: extract('Edit Accounting Rules'), breadcrumb: 'Edit', routeResolveBreadcrumb: false } + } + ] } ] } diff --git a/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.html b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.html new file mode 100644 index 000000000..c13907d9e --- /dev/null +++ b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.html @@ -0,0 +1,105 @@ +
+ + + +
+ + + +
+ + + + + + + + + {{ office.name }} + + + + +
+ + + Fixed Account + List of Accounts + +
+ + + + + {{ glAccount.name }} + + + + +
+ + + + {{ debitTag.name }} + + + + +
+ + Multiple Debit Entries Allowed + +
+
+ +
+ + + Fixed Account + List of Accounts + +
+ + + + + {{ glAccount.name }} + + + + +
+ + + + {{ creditTag.name }} + + + + +
+ + Multiple Credit Entries Allowed + +
+
+ + + + + +
+ +
+ + + + + + +
+ +
+ +
+ diff --git a/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.scss b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.scss new file mode 100644 index 000000000..47139b9fc --- /dev/null +++ b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.scss @@ -0,0 +1,19 @@ +.rule-wrapper { + margin: 17.5px 0 0 0; +} + +.additional-selection { + opacity: 0.75; + font-size: 0.75em; +} + +.entries-wrapper { + position: relative; + + .entries { + padding: 0 0 17.5px 0; + position: absolute; + bottom: 0; + right: 0; + } +} diff --git a/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.spec.ts b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.spec.ts new file mode 100644 index 000000000..97e4412f2 --- /dev/null +++ b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditRuleComponent } from './edit-rule.component'; + +describe('EditRuleComponent', () => { + let component: EditRuleComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EditRuleComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditRuleComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.ts b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.ts new file mode 100644 index 000000000..d64f5a4a5 --- /dev/null +++ b/src/app/accounting/accounting-rules/edit-rule/edit-rule.component.ts @@ -0,0 +1,115 @@ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, Validators, ValidatorFn, ValidationErrors } from '@angular/forms'; +import { Router, ActivatedRoute } from '@angular/router'; + +import { AccountingService } from '../../accounting.service'; + +const oneOfTheFieldsIsRequiredValidator: ValidatorFn = (accountingRuleForm: FormGroup): ValidationErrors | null => { + const accountToDebit = accountingRuleForm.controls.accountToDebit.value; + const debitTags = accountingRuleForm.controls.debitTags.value; + const accountToCredit = accountingRuleForm.controls.accountToCredit.value; + const creditTags = accountingRuleForm.controls.creditTags.value; + return ((accountToDebit || debitTags) && (accountToCredit || creditTags)) ? null : { 'error': true }; +}; + +@Component({ + selector: 'mifosx-edit-rule', + templateUrl: './edit-rule.component.html', + styleUrls: ['./edit-rule.component.scss'] +}) +export class EditRuleComponent implements OnInit { + + accountingRuleForm: FormGroup; + accountingRule: any; + officeData: any; + glAccountData: any; + debitTagData: any; + creditTagData: any; + + constructor(private route: ActivatedRoute, + private formBuilder: FormBuilder, + private accountingService: AccountingService, + private router: Router) { + this.route.data.subscribe((data: { accountingRule: any }) => { + this.accountingRule = data.accountingRule; + }); + } + + ngOnInit() { + this.createAccountingRulesForm(); + this.getAccountingRulesTemplate(); + this.setAccountingRulesForm(); + } + + createAccountingRulesForm() { + this.accountingRuleForm = this.formBuilder.group({ + 'name': [this.accountingRule.name, Validators.required], + 'officeId': [this.accountingRule.officeId, Validators.required], + 'debitRuleType': [''], + 'accountToDebit': [''], + 'debitTags': [''], + 'allowMultipleDebitEntries': [''], + 'creditRuleType': [''], + 'accountToCredit': [''], + 'creditTags': [''], + 'allowMultipleCreditEntries': [''], + 'description': [this.accountingRule.description] + }, { validator: oneOfTheFieldsIsRequiredValidator }); + } + + setAccountingRulesForm() { + this.accountingRuleForm.get('debitRuleType').valueChanges.subscribe(debitRuleType => { + if (debitRuleType === 'fixedAccount') { + this.accountingRuleForm.get('debitTags').reset(); + this.accountingRuleForm.get('allowMultipleDebitEntries').reset(); + } else { + this.accountingRuleForm.get('allowMultipleDebitEntries').setValue(false); + } + }); + this.accountingRuleForm.get('creditRuleType').valueChanges.subscribe(creditRuleType => { + if (creditRuleType === 'fixedAccount') { + this.accountingRuleForm.get('creditTags').reset(); + this.accountingRuleForm.get('allowMultipleCreditEntries').reset(); + } else { + this.accountingRuleForm.get('allowMultipleCreditEntries').setValue(false); + } + }); + + if (this.accountingRule.debitAccounts) { + this.accountingRuleForm.get('debitRuleType').setValue('fixedAccount'); + this.accountingRuleForm.get('accountToDebit').setValue(this.accountingRule.debitAccounts[0].id); + } else { + this.accountingRuleForm.get('debitRuleType').setValue('listOfAccounts'); + this.accountingRuleForm.get('debitTags').setValue(this.accountingRule.debitTags.map((debitTag: any) => debitTag.tag.id)); + this.accountingRuleForm.get('allowMultipleDebitEntries').setValue(this.accountingRule.allowMultipleDebitEntries); + } + + if (this.accountingRule.creditAccounts) { + this.accountingRuleForm.get('creditRuleType').setValue('fixedAccount'); + this.accountingRuleForm.get('accountToCredit').setValue(this.accountingRule.creditAccounts[0].id); + } else { + this.accountingRuleForm.get('creditRuleType').setValue('listOfAccounts'); + this.accountingRuleForm.get('creditTags').setValue(this.accountingRule.creditTags.map((creditTag: any) => creditTag.tag.id)); + this.accountingRuleForm.get('allowMultipleCreditEntries').setValue(this.accountingRule.allowMultipleCreditEntries); + } + } + + getAccountingRulesTemplate() { + this.accountingService.getAccountingRulesTemplate().subscribe((accountingRulesData: any) => { + this.officeData = accountingRulesData.allowedOffices; + this.glAccountData = accountingRulesData.allowedAccounts; + this.debitTagData = accountingRulesData.allowedDebitTagOptions; + this.creditTagData = accountingRulesData.allowedCreditTagOptions; + }); + } + + submit() { + const accountingRule = this.accountingRuleForm.value; + delete accountingRule.debitRuleType; + delete accountingRule.creditRuleType; + this.accountingService.updateAccountingRule(this.accountingRule.id, accountingRule).subscribe((response: any) => { + this.router.navigate(['/accounting/accounting-rules/view', response.resourceId]); + }); + } + +} diff --git a/src/app/accounting/accounting-rules/view-rule/view-rule.component.ts b/src/app/accounting/accounting-rules/view-rule/view-rule.component.ts index 6ee4bf069..2969a141e 100644 --- a/src/app/accounting/accounting-rules/view-rule/view-rule.component.ts +++ b/src/app/accounting/accounting-rules/view-rule/view-rule.component.ts @@ -1,5 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatDialog } from '@angular/material'; + +import { AccountingService } from '../../accounting.service'; +import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dialog.component'; @Component({ selector: 'mifosx-view-rule', @@ -10,7 +14,10 @@ export class ViewRuleComponent implements OnInit { accountingRule: any; - constructor(private route: ActivatedRoute) { + constructor(private route: ActivatedRoute, + private router: Router, + private accountingService: AccountingService, + public dialog: MatDialog) { this.route.data.subscribe((data: { accountingRule: any }) => { this.accountingRule = data.accountingRule; }); @@ -19,4 +26,18 @@ export class ViewRuleComponent implements OnInit { ngOnInit() { } + deleteAccountingRule() { + const deleteAccountingRuleDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `accounting rule ${this.accountingRule.id}` } + }); + deleteAccountingRuleDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.accountingService.deleteAccountingRule(this.accountingRule.id) + .subscribe(() => { + this.router.navigate(['/accounting/accounting-rules']); + }); + } + }); + } + } diff --git a/src/app/accounting/accounting.module.ts b/src/app/accounting/accounting.module.ts index 5b8465ecb..0a5853ea6 100644 --- a/src/app/accounting/accounting.module.ts +++ b/src/app/accounting/accounting.module.ts @@ -27,6 +27,7 @@ import { EditClosureComponent } from './closing-entries/edit-closure/edit-closur import { AccountingRulesComponent } from './accounting-rules/accounting-rules.component'; import { CreateRuleComponent } from './accounting-rules/create-rule/create-rule.component'; import { ViewRuleComponent } from './accounting-rules/view-rule/view-rule.component'; +import { EditRuleComponent } from './accounting-rules/edit-rule/edit-rule.component'; @NgModule({ imports: [ @@ -58,7 +59,8 @@ import { ViewRuleComponent } from './accounting-rules/view-rule/view-rule.compon EditClosureComponent, AccountingRulesComponent, CreateRuleComponent, - ViewRuleComponent + ViewRuleComponent, + EditRuleComponent ], entryComponents: [ RevertTransactionComponent, diff --git a/src/app/accounting/accounting.service.ts b/src/app/accounting/accounting.service.ts index c65b32932..53f7757de 100644 --- a/src/app/accounting/accounting.service.ts +++ b/src/app/accounting/accounting.service.ts @@ -157,4 +157,12 @@ export class AccountingService { return this.http.get(`/accountingrules/${accountingRuleId}`); } + deleteAccountingRule(accountingRuleId: number) { + return this.http.delete(`/accountingrules/${accountingRuleId}`); + } + + updateAccountingRule(accoutingRuleId: number, accountingRule: any) { + return this.http.put(`/accountingrules/${accoutingRuleId}`, accountingRule); + } + }