initial commit

This commit is contained in:
Patrick Nagurny
2018-10-19 11:28:08 -04:00
commit 5ff09d328d
139 changed files with 23448 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
import { Pipe, PipeTransform } from '@angular/core';
import { CurrencyFormatPipe } from './currency-format.pipe';
import { Account } from './account';
@Pipe({name: 'accountBalance'})
export class AccountBalancePipe implements PipeTransform {
constructor(private currencyFormatPipe: CurrencyFormatPipe) {
}
transform(account: Account, balanceType = 'price'): string {
let sign = account.debitBalance ? 1 : -1;
let nativeBalance = 0;
switch(balanceType) {
case 'cost':
nativeBalance = account.totalNativeBalanceCost;
break;
case 'price':
nativeBalance = account.totalNativeBalancePrice;
break;
default:
throw new Error('Invalid balance type ' + balanceType);
}
return this.currencyFormatPipe.transform(sign * nativeBalance, account.orgPrecision, account.orgCurrency);
}
}

View File

@@ -0,0 +1,21 @@
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'accountName'})
export class AccountNamePipe implements PipeTransform {
constructor() {
}
transform(name: string, depth: number): string {
let parts = name.split(':');
let accountString = '';
if(!depth) {
depth = 1;
}
parts = parts.slice(depth - 1, parts.length);
return parts.join(':');
}
}

168
src/app/shared/account.ts Normal file
View File

@@ -0,0 +1,168 @@
export class AccountApi {
id: string;
orgId: string;
inserted: Date;
updated: Date;
name: string;
parent: string;
currency: string;
precision: number;
debitBalance: boolean;
balance: number;
nativeBalance: number;
readOnly: boolean;
recentTxCount: number;
price: number;
constructor(options: any = {}) {
this.id = options.id;
this.orgId = options.orgId;
this.inserted = options.inserted ? new Date(options.inserted): null;
this.updated = options.updated ? new Date(options.updated): null;
this.name = options.name;
this.parent = options.parent ? options.parent : '';
this.currency = options.currency;
this.precision = options.precision ? parseInt(options.precision) : 0;
this.debitBalance = options.debitBalance;
this.balance = options.balance;
this.nativeBalance = options.nativeBalance;
this.readOnly = options.readOnly;
this.recentTxCount = options.recentTxCount ? parseInt(options.recentTxCount) : 0;
this.price = options.price;
}
}
export class Account {
id: string;
orgId: string;
inserted: Date;
updated: Date;
name: string;
fullName: string;
parent: Account;
currency: string;
precision: number;
debitBalance: boolean;
balance: number;
totalBalance: number;
nativeBalanceCost: number;
totalNativeBalanceCost: number;
nativeBalancePrice: number;
totalNativeBalancePrice: number;
price: number;
orgCurrency: string;
orgPrecision: number;
readOnly: boolean;
depth: number;
recentTxCount: number;
children: Account[];
constructor(options: any = {}) {
this.id = options.id;
this.orgId = options.orgId;
this.inserted = options.inserted ? new Date(options.inserted) : null;
this.updated = options.updated ? new Date(options.updated) : null;
this.name = options.name;
this.fullName = options.fullName;
this.parent = options.parent;
this.currency = options.currency;
this.precision = options.precision ? parseInt(options.precision) : 0;
this.debitBalance = options.debitBalance || false;
this.balance = options.balance || 0;
this.totalBalance = options.totalBalance || 0;
this.nativeBalanceCost = options.nativeBalance || 0;
this.totalNativeBalanceCost = options.totalNativeBalanceCost || options.totalNativeBalance || 0;
this.nativeBalancePrice = options.nativeBalancePrice || 0;
this.totalNativeBalancePrice = options.totalNativeBalancePrice || 0;
this.price = options.price || 0;
this.orgCurrency = options.orgCurrency;
this.orgPrecision = options.orgPrecision ? parseInt(options.orgPrecision) : 0;
this.readOnly = options.readOnly;
this.depth = options.depth;
this.recentTxCount = options.recentTxCount || 0;
this.children = options.children || [];
}
}
export class AccountTree {
accountMap: { [accountId: number]: Account; };
rootAccount: Account;
constructor(options: any = {}) {
this.accountMap = options.accountMap;
this.rootAccount = options.rootAccount;
}
getFlattenedAccounts(node?: Account): Account[] {
if(!node) {
node = this.rootAccount;
}
let flattened = [];
for(let account of node.children) {
flattened.push(account);
flattened = flattened.concat(this.getFlattenedAccounts(account));
}
return flattened;
}
getAccountByName (name: string, depth?: number): Account {
for(let id in this.accountMap) {
let account = this.accountMap[id];
if(account.name === name) {
if(!depth || account.depth === depth) {
return account;
}
}
}
return null;
}
accountIsChildOf(account: Account, parent: Account) {
for(let child of parent.children) {
if(child.id === account.id) {
return true;
}
if(this.accountIsChildOf(account, child)) {
return true;
}
}
return false;
}
getAccountAtoms(node?: Account): Account[] {
if(!node) {
node = this.rootAccount;
}
let accounts = [];
for(let i = 0; i < node.children.length; i++) {
let child = node.children[i];
if(!child.children.length) {
accounts.push(child);
} else {
accounts = accounts.concat(this.getAccountAtoms(child));
}
}
return accounts;
}
getAccountLabel(account: Account, depth: number) {
let node = account;
let accountArray = [account.name];
while(node.parent.depth >= depth) {
node = node.parent;
accountArray.unshift(node.name);
}
return accountArray.join(':');
}
}

15
src/app/shared/apikey.ts Normal file
View File

@@ -0,0 +1,15 @@
export class ApiKey {
id: string;
inserted: Date;
updated: Date;
userId: string;
label: string;
constructor(options: any = {}) {
this.id = options.id;
this.inserted = options.inserted ? new Date(options.inserted) : null;
this.updated = options.updated ? new Date(options.updated) : null;
this.userId = options.userId;
this.label = options.label;
}
}

13
src/app/shared/config.ts Normal file
View File

@@ -0,0 +1,13 @@
export class Config {
server: string;
email: string;
password: string; // switch to session based auth
defaultOrg: string;
reportData: any;
constructor(options: any = {}) {
this.server = options.server || 'https://openaccounting.io:8080/api';
this.email = options.email;
this.password = options.password;
this.defaultOrg = options.defaultOrg;
}
}

View File

@@ -0,0 +1,27 @@
import { Pipe, PipeTransform } from '@angular/core';
import { DecimalPipe } from '@angular/common';
@Pipe({name: 'currencyFormat'})
export class CurrencyFormatPipe implements PipeTransform {
constructor(private decimalPipe: DecimalPipe) {
}
transform(amount: number, precision: number, currency = 'USD'): string {
if(amount === null || amount === undefined) {
return '';
}
let prefix = amount < 0 ? '-' : '';
if(currency === 'USD') {
prefix += '$';
}
let minDigits = Math.min(2, precision);
return prefix +
this.decimalPipe.transform(
Math.abs(amount) / Math.pow(10, precision),
'1.' + minDigits + '-' + precision);
}
}

8
src/app/shared/error.ts Normal file
View File

@@ -0,0 +1,8 @@
export class AppError extends Error {
constructor(m: string, public code?: number) {
super(m);
// Set the prototype explicitly.
Object.setPrototypeOf(this, AppError.prototype);
}
}

17
src/app/shared/invite.ts Normal file
View File

@@ -0,0 +1,17 @@
export class Invite {
id: string;
orgId: string;
inserted: Date;
updated: Date;
email: string;
accepted: boolean;
constructor(options: any = {}) {
this.id = options.id;
this.orgId = options.orgId;
this.inserted = options.inserted ? new Date(options.inserted) : null;
this.updated = options.updated ? new Date(options.updated) : null;
this.email = options.email;
this.accepted = options.accepted;
}
}

19
src/app/shared/message.ts Normal file
View File

@@ -0,0 +1,19 @@
export class Message {
version: string;
sequenceNumber: number;
type: string;
action: string;
data: any;
constructor(options: any = {}) {
this.version = options.version;
this.sequenceNumber = options.sequenceNumber;
this.type = options.type;
this.action = options.action;
this.data = options.data;
}
toString(): string {
return JSON.stringify(this);
}
}

16
src/app/shared/org.ts Normal file
View File

@@ -0,0 +1,16 @@
export class Org {
id: string;
inserted: Date;
updated: Date;
name: string;
currency: string;
precision: number;
constructor(options: any = {}) {
this.id = options.id;
this.inserted = options.inserted ? new Date(options.inserted) : null;
this.updated = options.updated ? new Date(options.updated) : null;
this.name = options.name;
this.currency = options.currency;
this.precision = options.precision && parseInt(options.precision);
}
}

17
src/app/shared/price.ts Normal file
View File

@@ -0,0 +1,17 @@
export class Price {
id: string;
currency: string;
date: Date;
inserted: Date;
updated: Date;
price: number;
constructor(options: any = {}) {
this.id = options.id;
this.currency = options.currency;
this.date = options.date ? new Date(options.date) : null;
this.inserted = options.inserted ? new Date(options.inserted) : null;
this.updated = options.updated ? new Date(options.updated) : null;
this.price = options.price;
}
}

View File

@@ -0,0 +1,6 @@
export class SessionOptions {
createDefaultAccounts: boolean;
constructor(options: any = {}) {
this.createDefaultAccounts = options.createDefaultAccounts;
}
};

View File

@@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { DecimalPipe } from '@angular/common';
import { CurrencyFormatPipe } from './currency-format.pipe';
import { AccountNamePipe } from './account-name.pipe';
import { AccountBalancePipe } from './account-balance.pipe';
@NgModule({
imports: [],
declarations: [CurrencyFormatPipe, AccountNamePipe, AccountBalancePipe],
exports: [CurrencyFormatPipe, AccountNamePipe, AccountBalancePipe],
providers: [DecimalPipe, CurrencyFormatPipe]
})
export class SharedModule { }

View File

@@ -0,0 +1,49 @@
export class Transaction {
id: string;
orgId: string;
userId: string;
date: Date;
inserted: Date;
updated: Date;
description: string;
data: any;
deleted: boolean;
splits: Split[];
constructor(options: any = {}) {
this.id = options.id;
this.orgId = options.id;
this.userId = options.id;
this.date = options.date ? new Date(options.date) : null;
this.inserted = options.inserted ? new Date(options.inserted) : null;
this.updated = options.updated ? new Date(options.updated) : null;
this.description = options.description;
this.data = options.data;
this.deleted = options.deleted;
this.splits = options.splits ? options.splits.map(split => new Split(split)) : [];
}
getData(): any {
try {
return JSON.parse(this.data);
} catch(e) {
return {};
}
}
setData(data: any) {
this.data = JSON.stringify(data);
}
// constructor(init?:Partial<Transaction>) {
// Object.assign(this, init);
// }
}
export class Split {
accountId: string;
amount: number;
nativeAmount: number;
constructor(init?:Partial<Split>) {
Object.assign(this, init);
}
}

22
src/app/shared/user.ts Normal file
View File

@@ -0,0 +1,22 @@
export class User {
id: string;
inserted: Date;
updated: Date;
firstName: string;
lastName: string;
email: string;
password: string;
agreeToTerms: boolean;
emailVerified: boolean;
constructor(options: any = {}) {
this.id = options.id || this.id;
this.inserted = options.inserted ? new Date(options.inserted) : null;
this.updated = options.updated ? new Date(options.updated) : null;
this.firstName = options.firstName || this.firstName;
this.lastName = options.lastName || this.lastName;
this.email = options.email || this.email;
this.password = options.password || this.password;
this.agreeToTerms = options.agreeToTerms || false;
this.emailVerified = options.emailVerified || this.emailVerified;
}
}

37
src/app/shared/util.ts Normal file
View File

@@ -0,0 +1,37 @@
export class Util {
static getLocalDateString(input: Date) {
let year = input.getFullYear().toString();
let month = (input.getMonth() + 1).toString();
let date = input.getDate().toString();
if(month.length < 2) {
month = '0' + month;
}
if(date.length < 2) {
date = '0' + date;
}
return year + '-' + month + '-' + date;
}
static getDateFromLocalDateString(input: string) {
let parts = input.split('-');
let date = new Date();
date.setHours(0, 0, 0, 0);
date.setFullYear(parseInt(parts[0]));
date.setMonth(parseInt(parts[1]) - 1);
date.setDate(parseInt(parts[2]));
return date;
}
static newGuid() {
let arr = new Uint8Array(16);
window.crypto.getRandomValues(arr);
return Array.prototype.map.call(arr, val => {
return ('00' + val.toString(16)).slice(-2);
}).join('');
}
}