mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 22:00:31 +00:00
refactoring: balance sheet report.
refactoring: trial balance sheet report. refactoring: general ledger report. refactoring: journal report. refactoring: P&L report.
This commit is contained in:
@@ -1,25 +1,7 @@
|
||||
import TenantRepository from 'repositories/TenantRepository';
|
||||
import { IAccount } from 'interfaces';
|
||||
import { Account } from 'models';
|
||||
|
||||
export default class AccountRepository extends TenantRepository {
|
||||
models: any;
|
||||
repositories: any;
|
||||
cache: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId - The given tenant id.
|
||||
*/
|
||||
constructor(
|
||||
tenantId: number,
|
||||
) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve accounts dependency graph.
|
||||
* @returns {}
|
||||
@@ -27,8 +9,9 @@ export default class AccountRepository extends TenantRepository {
|
||||
async getDependencyGraph() {
|
||||
const { Account } = this.models;
|
||||
const accounts = await this.allAccounts();
|
||||
const cacheKey = this.getCacheKey('accounts.depGraph');
|
||||
|
||||
return this.cache.get('accounts.depGraph', async () => {
|
||||
return this.cache.get(cacheKey, async () => {
|
||||
return Account.toDependencyGraph(accounts);
|
||||
});
|
||||
}
|
||||
@@ -37,10 +20,13 @@ export default class AccountRepository extends TenantRepository {
|
||||
* Retrieve all accounts on the storage.
|
||||
* @return {IAccount[]}
|
||||
*/
|
||||
allAccounts(): IAccount[] {
|
||||
allAccounts(withRelations?: string|string[]): IAccount[] {
|
||||
const { Account } = this.models;
|
||||
return this.cache.get('accounts', async () => {
|
||||
return Account.query();
|
||||
const cacheKey = this.getCacheKey('accounts.depGraph', withRelations);
|
||||
|
||||
return this.cache.get(cacheKey, async () => {
|
||||
return Account.query()
|
||||
.withGraphFetched(withRelations);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -51,7 +37,9 @@ export default class AccountRepository extends TenantRepository {
|
||||
*/
|
||||
getBySlug(slug: string): IAccount {
|
||||
const { Account } = this.models;
|
||||
return this.cache.get(`accounts.slug.${slug}`, () => {
|
||||
const cacheKey = this.getCacheKey('accounts.slug', slug);
|
||||
|
||||
return this.cache.get(cacheKey, () => {
|
||||
return Account.query().findOne('slug', slug);
|
||||
});
|
||||
}
|
||||
@@ -63,7 +51,9 @@ export default class AccountRepository extends TenantRepository {
|
||||
*/
|
||||
findById(id: number): IAccount {
|
||||
const { Account } = this.models;
|
||||
return this.cache.get(`accounts.id.${id}`, () => {
|
||||
const cacheKey = this.getCacheKey('accounts.id', id);
|
||||
|
||||
return this.cache.get(cacheKey, () => {
|
||||
return Account.query().findById(id);
|
||||
});
|
||||
}
|
||||
@@ -75,7 +65,11 @@ export default class AccountRepository extends TenantRepository {
|
||||
*/
|
||||
findByIds(accountsIds: number[]) {
|
||||
const { Account } = this.models;
|
||||
return Account.query().whereIn('id', accountsIds);
|
||||
const cacheKey = this.getCacheKey('accounts.id', accountsIds);
|
||||
|
||||
return this.cache.get(cacheKey, () => {
|
||||
return Account.query().whereIn('id', accountsIds);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,6 +137,6 @@ export default class AccountRepository extends TenantRepository {
|
||||
* Flush repository cache.
|
||||
*/
|
||||
flushCache(): void {
|
||||
this.cache.delStartWith('accounts');
|
||||
this.cache.delStartWith(this.repositoryName);
|
||||
}
|
||||
}
|
||||
60
server/src/repositories/AccountTransactionRepository.ts
Normal file
60
server/src/repositories/AccountTransactionRepository.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
import { QueryBuilder } from 'knex';
|
||||
import { AccountTransaction } from 'models';
|
||||
import hashObject from 'object-hash';
|
||||
import TenantRepository from 'repositories/TenantRepository';
|
||||
|
||||
|
||||
interface IJournalTransactionsFilter {
|
||||
fromDate: string | Date,
|
||||
toDate: string | Date,
|
||||
accountsIds: number[],
|
||||
sumationCreditDebit: boolean,
|
||||
fromAmount: number,
|
||||
toAmount: number,
|
||||
contactsIds?: number[],
|
||||
contactType?: string,
|
||||
};
|
||||
|
||||
export default class AccountTransactionsRepository extends TenantRepository {
|
||||
|
||||
journal(filter: IJournalTransactionsFilter) {
|
||||
const { AccountTransaction } = this.models;
|
||||
const cacheKey = this.getCacheKey('transactions.journal', filter);
|
||||
|
||||
return this.cache.get(cacheKey, () => {
|
||||
return AccountTransaction.query()
|
||||
.modify('filterAccounts', filter.accountsIds)
|
||||
.modify('filterDateRange', filter.fromDate, filter.toDate)
|
||||
.withGraphFetched('account.type')
|
||||
.onBuild((query) => {
|
||||
if (filter.sumationCreditDebit) {
|
||||
query.modify('sumationCreditDebit');
|
||||
}
|
||||
if (filter.fromAmount || filter.toAmount) {
|
||||
query.modify('filterAmountRange', filter.fromAmount, filter.toAmount);
|
||||
}
|
||||
if (filter.contactsIds) {
|
||||
query.modify('filterContactIds', filter.contactsIds);
|
||||
}
|
||||
if (filter.contactType) {
|
||||
query.where('contact_type', filter.contactType);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
openingBalance(fromDate) {
|
||||
return this.cache.get('transaction.openingBalance', () => {
|
||||
return AccountTransaction.query()
|
||||
.modify('openingBalance', fromDate);
|
||||
})
|
||||
}
|
||||
|
||||
closingOpening(toDate) {
|
||||
return this.cache.get('transaction.closingBalance', () => {
|
||||
return AccountTransaction.query()
|
||||
.modify('closingBalance', toDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,6 @@ import TenantRepository from 'repositories/TenantRepository';
|
||||
import { IAccountType } from 'interfaces';
|
||||
|
||||
export default class AccountTypeRepository extends TenantRepository {
|
||||
cache: any;
|
||||
models: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId - The given tenant id.
|
||||
*/
|
||||
constructor(
|
||||
tenantId: number,
|
||||
) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all accounts types.
|
||||
* @return {IAccountType[]}
|
||||
|
||||
19
server/src/repositories/CachableRepository.ts
Normal file
19
server/src/repositories/CachableRepository.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import hashObject from 'object-hash';
|
||||
|
||||
|
||||
export default class CachableRepository {
|
||||
repositoryName: string;
|
||||
|
||||
/**
|
||||
* Retrieve the cache key of the method name and arguments.
|
||||
* @param {string} method
|
||||
* @param {...any} args
|
||||
* @return {string}
|
||||
*/
|
||||
getCacheKey(method, ...args) {
|
||||
const hashArgs = hashObject({ ...args });
|
||||
const repositoryName = this.repositoryName;
|
||||
|
||||
return `${repositoryName}-${method}-${hashArgs}`;
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,6 @@ import TenantRepository from 'repositories/TenantRepository';
|
||||
import { IContact } from 'interfaces';
|
||||
|
||||
export default class ContactRepository extends TenantRepository {
|
||||
cache: any;
|
||||
models: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId - The given tenant id.
|
||||
*/
|
||||
constructor(
|
||||
tenantId: number,
|
||||
) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given contact model.
|
||||
* @param {number} contactId
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import TenantRepository from "./TenantRepository";
|
||||
|
||||
export default class CustomerRepository extends TenantRepository {
|
||||
models: any;
|
||||
cache: any;
|
||||
all() {
|
||||
const { Contact } = this.models;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId
|
||||
*/
|
||||
constructor(tenantId: number) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
return this.cache.get('customers', () => {
|
||||
return Contact.query().modify('customer');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,21 +3,6 @@ import { IExpense } from 'interfaces';
|
||||
import moment from "moment";
|
||||
|
||||
export default class ExpenseRepository extends TenantRepository {
|
||||
models: any;
|
||||
repositories: any;
|
||||
cache: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId
|
||||
*/
|
||||
constructor(tenantId: number) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given expense by id.
|
||||
* @param {number} expenseId
|
||||
|
||||
18
server/src/repositories/JournalRepository.ts
Normal file
18
server/src/repositories/JournalRepository.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { IBalanceSheetQuery } from 'interfaces';
|
||||
import TenantRepository from 'repositories/TenantRepository';
|
||||
|
||||
|
||||
export default class JournalRepository extends TenantRepository {
|
||||
|
||||
balanceSheet(query: IBalanceSheetQuery) {
|
||||
|
||||
// Accounts dependency graph.
|
||||
const accountsGraph = Account.toDependencyGraph(balanceSheetAccounts);
|
||||
|
||||
// Load all entries that associated to the given accounts.
|
||||
const journalEntriesCollected = Account.collectJournalEntries(balanceSheetAccounts);
|
||||
|
||||
const journalEntries = new JournalPoster(accountsGraph);
|
||||
journalEntries.loadEntries(journalEntriesCollected);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,45 @@
|
||||
import { Container } from 'typedi';
|
||||
import TenancyService from 'services/Tenancy/TenancyService';
|
||||
import CachableRepository from './CachableRepository';
|
||||
|
||||
export default class TenantRepository {
|
||||
export default class TenantRepository extends CachableRepository {
|
||||
repositoryName: string;
|
||||
tenantId: number;
|
||||
tenancy: TenancyService;
|
||||
|
||||
modelsInstance: any;
|
||||
repositoriesInstance: any;
|
||||
cacheInstance: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId
|
||||
*/
|
||||
constructor(tenantId: number) {
|
||||
super();
|
||||
|
||||
this.tenantId = tenantId;
|
||||
this.tenancy = Container.get(TenancyService);
|
||||
this.repositoryName = this.constructor.name;
|
||||
}
|
||||
|
||||
get models() {
|
||||
if (!this.modelsInstance) {
|
||||
this.modelsInstance = this.tenancy.models(this.tenantId);
|
||||
}
|
||||
return this.modelsInstance;
|
||||
}
|
||||
|
||||
get repositories() {
|
||||
if (!this.repositoriesInstance) {
|
||||
this.repositoriesInstance = this.tenancy.repositories(this.tenantId);
|
||||
}
|
||||
return this.repositoriesInstance;
|
||||
}
|
||||
|
||||
get cache() {
|
||||
if (!this.cacheInstance) {
|
||||
this.cacheInstance = this.tenancy.cache(this.tenantId);
|
||||
}
|
||||
return this.cacheInstance;
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,6 @@ import TenantRepository from "./TenantRepository";
|
||||
|
||||
|
||||
export default class VendorRepository extends TenantRepository {
|
||||
models: any;
|
||||
cache: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId
|
||||
*/
|
||||
constructor(tenantId: number) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve vendor details of the given id.
|
||||
@@ -68,7 +55,6 @@ export default class VendorRepository extends TenantRepository {
|
||||
[changeMethod]('balance', Math.abs(amount));
|
||||
}
|
||||
|
||||
|
||||
async changeDiffBalance(
|
||||
vendorId: number,
|
||||
amount: number,
|
||||
|
||||
@@ -2,22 +2,6 @@ import { IView } from 'interfaces';
|
||||
import TenantRepository from 'repositories/TenantRepository';
|
||||
|
||||
export default class ViewRepository extends TenantRepository {
|
||||
models: any;
|
||||
cache: any;
|
||||
repositories: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId - The given tenant id.
|
||||
*/
|
||||
constructor(
|
||||
tenantId: number,
|
||||
) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve view model by the given id.
|
||||
|
||||
@@ -2,23 +2,6 @@ import { omit } from 'lodash';
|
||||
import TenantRepository from 'repositories/TenantRepository';
|
||||
|
||||
export default class ViewRoleRepository extends TenantRepository {
|
||||
models: any;
|
||||
cache: any;
|
||||
repositories: any;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {number} tenantId - The given tenant id.
|
||||
*/
|
||||
constructor(
|
||||
tenantId: number,
|
||||
) {
|
||||
super(tenantId);
|
||||
|
||||
this.models = this.tenancy.models(tenantId);
|
||||
this.cache = this.tenancy.cache(tenantId);
|
||||
this.repositories = this.tenancy.cache(tenantId);
|
||||
}
|
||||
|
||||
allByView(viewId: number) {
|
||||
const { ViewRole } = this.models;
|
||||
|
||||
Reference in New Issue
Block a user