diff --git a/src/app/accounting/accounting-routing.module.ts b/src/app/accounting/accounting-routing.module.ts
index a9c4bce58..efa8d5f0d 100644
--- a/src/app/accounting/accounting-routing.module.ts
+++ b/src/app/accounting/accounting-routing.module.ts
@@ -26,6 +26,7 @@ import { CreateClosureComponent } from './closing-entries/create-closure/create-
import { ViewClosureComponent } from './closing-entries/view-closure/view-closure.component';
import { EditClosureComponent } from './closing-entries/edit-closure/edit-closure.component';
import { AccountingRulesComponent } from './accounting-rules/accounting-rules.component';
+import { CreateRuleComponent } from './accounting-rules/create-rule/create-rule.component';
const routes: Routes = [
Route.withShell([
@@ -165,8 +166,18 @@ const routes: Routes = [
},
{
path: 'accounting-rules',
- component: AccountingRulesComponent,
data: { title: extract('Accounting Rules'), breadcrumb: 'Rules' },
+ children: [
+ {
+ path: '',
+ component: AccountingRulesComponent
+ },
+ {
+ path: 'create',
+ component: CreateRuleComponent,
+ data: { title: extract('Create Accounting Rule'), breadcrumb: 'Create' }
+ }
+ ]
}
]
}
diff --git a/src/app/accounting/accounting-rules/create-rule/create-rule.component.html b/src/app/accounting/accounting-rules/create-rule/create-rule.component.html
new file mode 100644
index 000000000..e92880aeb
--- /dev/null
+++ b/src/app/accounting/accounting-rules/create-rule/create-rule.component.html
@@ -0,0 +1,104 @@
+
diff --git a/src/app/accounting/accounting-rules/create-rule/create-rule.component.scss b/src/app/accounting/accounting-rules/create-rule/create-rule.component.scss
new file mode 100644
index 000000000..47139b9fc
--- /dev/null
+++ b/src/app/accounting/accounting-rules/create-rule/create-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/create-rule/create-rule.component.spec.ts b/src/app/accounting/accounting-rules/create-rule/create-rule.component.spec.ts
new file mode 100644
index 000000000..6ed4a6a38
--- /dev/null
+++ b/src/app/accounting/accounting-rules/create-rule/create-rule.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CreateRuleComponent } from './create-rule.component';
+
+describe('CreateRuleComponent', () => {
+ let component: CreateRuleComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ CreateRuleComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CreateRuleComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/accounting/accounting-rules/create-rule/create-rule.component.ts b/src/app/accounting/accounting-rules/create-rule/create-rule.component.ts
new file mode 100644
index 000000000..66617d138
--- /dev/null
+++ b/src/app/accounting/accounting-rules/create-rule/create-rule.component.ts
@@ -0,0 +1,89 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators, ValidatorFn, ValidationErrors } from '@angular/forms';
+
+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-create-rule',
+ templateUrl: './create-rule.component.html',
+ styleUrls: ['./create-rule.component.scss']
+})
+export class CreateRuleComponent implements OnInit {
+
+ accountingRuleForm: FormGroup;
+ officeData: any;
+ glAccountData: any;
+ debitTagData: any;
+ creditTagData: any;
+
+ constructor(private formBuilder: FormBuilder,
+ private accountingService: AccountingService) { }
+
+ ngOnInit() {
+ this.createAccountingRulesForm();
+ this.getAccountingRulesTemplate();
+ this.setAccountingRulesForm();
+ }
+
+ createAccountingRulesForm() {
+ this.accountingRuleForm = this.formBuilder.group({
+ 'name': ['', Validators.required],
+ 'officeId': ['', Validators.required],
+ 'debitRuleType': ['fixedAccount'],
+ 'accountToDebit': [''],
+ 'debitTags': [''],
+ 'allowMultipleDebitEntries': [''],
+ 'creditRuleType': ['fixedAccount'],
+ 'accountToCredit': [''],
+ 'creditTags': [''],
+ 'allowMultipleCreditEntries': [''],
+ '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);
+ }
+ });
+ }
+
+ 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.createAccountingRule(accountingRule).subscribe((response: any) => {
+ console.log(response);
+ });
+ }
+
+}
diff --git a/src/app/accounting/accounting.module.ts b/src/app/accounting/accounting.module.ts
index cc62f5e07..6d47fb7f8 100644
--- a/src/app/accounting/accounting.module.ts
+++ b/src/app/accounting/accounting.module.ts
@@ -25,6 +25,7 @@ import { CreateClosureComponent } from './closing-entries/create-closure/create-
import { ViewClosureComponent } from './closing-entries/view-closure/view-closure.component';
import { EditClosureComponent } from './closing-entries/edit-closure/edit-closure.component';
import { AccountingRulesComponent } from './accounting-rules/accounting-rules.component';
+import { CreateRuleComponent } from './accounting-rules/create-rule/create-rule.component';
@NgModule({
imports: [
@@ -54,7 +55,8 @@ import { AccountingRulesComponent } from './accounting-rules/accounting-rules.co
CreateClosureComponent,
ViewClosureComponent,
EditClosureComponent,
- AccountingRulesComponent
+ AccountingRulesComponent,
+ CreateRuleComponent
],
entryComponents: [
RevertTransactionComponent,
diff --git a/src/app/accounting/accounting.service.ts b/src/app/accounting/accounting.service.ts
index a6b039c2f..ae5f30cb9 100644
--- a/src/app/accounting/accounting.service.ts
+++ b/src/app/accounting/accounting.service.ts
@@ -145,4 +145,12 @@ export class AccountingService {
return this.http.put(`/glclosures/${accountingClosureId}`, accountingClosure);
}
+ getAccountingRulesTemplate() {
+ return this.http.get('/accountingrules/template');
+ }
+
+ createAccountingRule(accountingRule: any) {
+ return this.http.post('/accountingrules', accountingRule);
+ }
+
}