You've already forked openaccounting-web
forked from cybercinch/openaccounting-web
292 lines
7.8 KiB
TypeScript
292 lines
7.8 KiB
TypeScript
|
|
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
|
||
|
|
import { Router } from '@angular/router';
|
||
|
|
import {
|
||
|
|
FormGroup,
|
||
|
|
FormControl,
|
||
|
|
Validators,
|
||
|
|
FormBuilder,
|
||
|
|
AbstractControl,
|
||
|
|
ValidationErrors
|
||
|
|
} from '@angular/forms';
|
||
|
|
import { AccountService } from '../core/account.service';
|
||
|
|
import { OrgService } from '../core/org.service';
|
||
|
|
import { Account, AccountApi, AccountTree } from '../shared/account';
|
||
|
|
import { Util } from '../shared/util';
|
||
|
|
import { AppError } from '../shared/error';
|
||
|
|
|
||
|
|
@Component({
|
||
|
|
selector: 'app-txnew',
|
||
|
|
templateUrl: 'new.html',
|
||
|
|
styleUrls: ['./new.scss'],
|
||
|
|
encapsulation: ViewEncapsulation.None
|
||
|
|
})
|
||
|
|
export class NewTransactionPage {
|
||
|
|
|
||
|
|
public form: FormGroup;
|
||
|
|
public type: string;
|
||
|
|
public typeDescription: string;
|
||
|
|
public secondDescription: string;
|
||
|
|
public firstAccountPrimary: string;
|
||
|
|
public selectAccounts: any[];
|
||
|
|
public error: AppError;
|
||
|
|
public numAccountsShown: number;
|
||
|
|
public expenseAccounts: any[] = [];
|
||
|
|
public incomeAccounts: any[] = [];
|
||
|
|
public paymentAccounts: any[] = [];
|
||
|
|
public assetAccounts: any[] = [];
|
||
|
|
public expenseAccountsAll: any[] = [];
|
||
|
|
public incomeAccountsAll: any[] = [];
|
||
|
|
public paymentAccountsAll: any[] = [];
|
||
|
|
public assetAccountsAll: any[] = [];
|
||
|
|
private accountTree: AccountTree;
|
||
|
|
@ViewChild('acc') acc: any;
|
||
|
|
|
||
|
|
constructor(
|
||
|
|
private router: Router,
|
||
|
|
private accountService: AccountService,
|
||
|
|
private orgService: OrgService,
|
||
|
|
private fb: FormBuilder) {
|
||
|
|
|
||
|
|
this.numAccountsShown = 3;
|
||
|
|
|
||
|
|
let org = this.orgService.getCurrentOrg();
|
||
|
|
|
||
|
|
let dateString = Util.getLocalDateString(new Date());
|
||
|
|
this.form = fb.group({
|
||
|
|
'type': ['', Validators.required],
|
||
|
|
'firstAccountPrimary': [null, Validators.required],
|
||
|
|
'firstAccountSecondary': [null],
|
||
|
|
'secondAccountPrimary': [null, Validators.required],
|
||
|
|
'secondAccountSecondary': [null],
|
||
|
|
'amount': [null, Validators.required],
|
||
|
|
'description': [''],
|
||
|
|
'date': [dateString, Validators.required]
|
||
|
|
});
|
||
|
|
|
||
|
|
this.accountService.getAccountTree().subscribe(tree => {
|
||
|
|
this.accountTree = tree;
|
||
|
|
this.selectAccounts = tree.getFlattenedAccounts().filter(account => {
|
||
|
|
let isAsset = account.fullName.match(/^Assets/);
|
||
|
|
let isLiability = account.fullName.match(/^Liabilities/);
|
||
|
|
return !account.children.length && (isAsset || isLiability);
|
||
|
|
});
|
||
|
|
|
||
|
|
this.getExpenseAccounts();
|
||
|
|
this.getIncomeAccounts();
|
||
|
|
this.getPaymentAccounts();
|
||
|
|
this.getAssetAccounts();
|
||
|
|
});
|
||
|
|
|
||
|
|
this.form.get('type').valueChanges.subscribe(val => {
|
||
|
|
if(val === 'openingBalance') {
|
||
|
|
this.acc.collapse('toggle-1');
|
||
|
|
this.acc.expand('toggle-2');
|
||
|
|
this.form.patchValue({description: 'Opening Balance'});
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
this.form.get('firstAccountPrimary').valueChanges.subscribe(val => {
|
||
|
|
if(val === 'other') {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
this.acc.collapse('toggle-1');
|
||
|
|
this.acc.expand('toggle-2');
|
||
|
|
});
|
||
|
|
|
||
|
|
this.form.get('firstAccountSecondary').valueChanges.subscribe(val => {
|
||
|
|
this.acc.collapse('toggle-1');
|
||
|
|
this.acc.expand('toggle-2');
|
||
|
|
});
|
||
|
|
|
||
|
|
this.form.get('secondAccountPrimary').valueChanges.subscribe(val => {
|
||
|
|
if(val === 'other') {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
this.acc.collapse('toggle-2');
|
||
|
|
this.acc.expand('toggle-3');
|
||
|
|
this.acc.expand('toggle-4');
|
||
|
|
});
|
||
|
|
|
||
|
|
this.form.get('secondAccountSecondary').valueChanges.subscribe(val => {
|
||
|
|
this.acc.collapse('toggle-2');
|
||
|
|
this.acc.expand('toggle-3');
|
||
|
|
this.acc.expand('toggle-4');
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
onSubmit() {
|
||
|
|
let account = new AccountApi(this.form.value);
|
||
|
|
account.id = Util.newGuid();
|
||
|
|
let parentAccount = this.accountTree.accountMap[account.parent];
|
||
|
|
|
||
|
|
if(!parentAccount) {
|
||
|
|
this.error = new AppError('Invalid parent account');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
let org = this.orgService.getCurrentOrg();
|
||
|
|
account.orgId = org.id;
|
||
|
|
account.debitBalance = parentAccount.debitBalance;
|
||
|
|
account.currency = account.currency || parentAccount.currency;
|
||
|
|
account.precision = account.precision !== null ? account.precision : parentAccount.precision;
|
||
|
|
|
||
|
|
this.accountService.newAccount(account)
|
||
|
|
.subscribe(
|
||
|
|
account => {
|
||
|
|
this.router.navigate(['/accounts']);
|
||
|
|
},
|
||
|
|
err => {
|
||
|
|
this.error = err;
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
getExpenseAccounts() {
|
||
|
|
// Get most used expense accounts
|
||
|
|
|
||
|
|
let expenseAccounts = this.accountTree.getAccountAtoms(
|
||
|
|
this.accountTree.getAccountByName('Expenses', 1)
|
||
|
|
);
|
||
|
|
|
||
|
|
this.processAccounts('expenseAccounts', expenseAccounts, 2);
|
||
|
|
}
|
||
|
|
|
||
|
|
getIncomeAccounts() {
|
||
|
|
// Get most used income accounts
|
||
|
|
|
||
|
|
let incomeAccounts = this.accountTree.getAccountAtoms(
|
||
|
|
this.accountTree.getAccountByName('Income', 1)
|
||
|
|
);
|
||
|
|
|
||
|
|
this.processAccounts('incomeAccounts', incomeAccounts, 2);
|
||
|
|
}
|
||
|
|
|
||
|
|
getPaymentAccounts() {
|
||
|
|
// Get most used asset / liability accounts
|
||
|
|
|
||
|
|
let assetAccounts = this.accountTree.getAccountAtoms(
|
||
|
|
this.accountTree.getAccountByName('Assets', 1)
|
||
|
|
);
|
||
|
|
|
||
|
|
let liabilityAccounts = this.accountTree.getAccountAtoms(
|
||
|
|
this.accountTree.getAccountByName('Liabilities', 1)
|
||
|
|
);
|
||
|
|
|
||
|
|
let paymentAccounts = assetAccounts.concat(liabilityAccounts);
|
||
|
|
|
||
|
|
this.processAccounts('paymentAccounts', paymentAccounts, 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
getAssetAccounts() {
|
||
|
|
// Get most used asset accounts
|
||
|
|
|
||
|
|
let assetAccounts = this.accountTree.getAccountAtoms(
|
||
|
|
this.accountTree.getAccountByName('Assets', 1)
|
||
|
|
);
|
||
|
|
|
||
|
|
this.processAccounts('assetAccounts', assetAccounts, 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
processAccounts(variable, data, depth) {
|
||
|
|
data.sort((a, b) => {
|
||
|
|
return b.recentTxCount - a.recentTxCount;
|
||
|
|
});
|
||
|
|
|
||
|
|
let dataWithLabels = data.map((account, i) => {
|
||
|
|
return {
|
||
|
|
id: account.id,
|
||
|
|
name: account.name,
|
||
|
|
label: this.accountTree.getAccountLabel(account, depth),
|
||
|
|
hidden: i < this.numAccountsShown ? false: true
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
let firstAccounts = dataWithLabels.slice(0, this.numAccountsShown);
|
||
|
|
let nextAccounts = dataWithLabels.slice(this.numAccountsShown);
|
||
|
|
|
||
|
|
nextAccounts.sort((a, b) => {
|
||
|
|
let aAlpha = a.label.charCodeAt(0) >= 65 && a.label.charCodeAt(0) <= 122;
|
||
|
|
let bAlpha = b.label.charCodeAt(0) >= 65 && b.label.charCodeAt(0) <= 122;
|
||
|
|
|
||
|
|
if(!aAlpha && bAlpha) {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(aAlpha && !bAlpha) {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(a.label > b.label) {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(a.label < b.label) {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
});
|
||
|
|
|
||
|
|
this[variable] = firstAccounts;
|
||
|
|
this[variable + 'All'] = nextAccounts;
|
||
|
|
}
|
||
|
|
|
||
|
|
getToggle1Title() {
|
||
|
|
let account = this.getFirstAccount();
|
||
|
|
|
||
|
|
let str = 'What type of transaction? ';
|
||
|
|
|
||
|
|
let type = this.form.value.type;
|
||
|
|
|
||
|
|
if(type) {
|
||
|
|
str += type.charAt(0).toUpperCase() + type.substr(1);
|
||
|
|
if(account) {
|
||
|
|
str += ' (' + account.name + ')';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return str;
|
||
|
|
}
|
||
|
|
|
||
|
|
getTitle() {
|
||
|
|
let account = this.getSecondAccount();
|
||
|
|
|
||
|
|
if(this.form.value.type === 'income') {
|
||
|
|
return 'Where was the money sent? ' + (account ? account.name : '');
|
||
|
|
} else if(this.form.value.type === 'openingBalance') {
|
||
|
|
return 'What account? ' + (account ? account.name : '');
|
||
|
|
}
|
||
|
|
|
||
|
|
return 'How did you pay? ' + (account ? account.name : '');
|
||
|
|
}
|
||
|
|
|
||
|
|
getFirstAccount() {
|
||
|
|
if(!this.accountTree) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(this.form.value.firstAccountPrimary && this.form.value.firstAccountPrimary !== 'other') {
|
||
|
|
return this.accountTree.accountMap[this.form.value.firstAccountPrimary];
|
||
|
|
}
|
||
|
|
|
||
|
|
return this.accountTree.accountMap[this.form.value.firstAccountSecondary];
|
||
|
|
}
|
||
|
|
|
||
|
|
getSecondAccount() {
|
||
|
|
if(!this.accountTree) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(this.form.value.secondAccountPrimary && this.form.value.secondAccountPrimary !== 'other') {
|
||
|
|
return this.accountTree.accountMap[this.form.value.secondAccountPrimary];
|
||
|
|
}
|
||
|
|
|
||
|
|
return this.accountTree.accountMap[this.form.value.secondAccountSecondary];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|