mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 07:10:33 +00:00
refactor: The expense G/L writer
This commit is contained in:
113
packages/server/src/services/Expenses/ExpenseGL.ts
Normal file
113
packages/server/src/services/Expenses/ExpenseGL.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import * as R from 'ramda';
|
||||||
|
import {
|
||||||
|
AccountNormal,
|
||||||
|
IExpenseCategory,
|
||||||
|
ILedger,
|
||||||
|
ILedgerEntry,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import Ledger from '../Accounting/Ledger';
|
||||||
|
|
||||||
|
export class ExpenseGL {
|
||||||
|
private expense: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor method.
|
||||||
|
*/
|
||||||
|
constructor(expense: any) {
|
||||||
|
this.expense = expense;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL common entry.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {Partial<ILedgerEntry>}
|
||||||
|
*/
|
||||||
|
private getExpenseGLCommonEntry = (): Partial<ILedgerEntry> => {
|
||||||
|
return {
|
||||||
|
currencyCode: this.expense.currencyCode,
|
||||||
|
exchangeRate: this.expense.exchangeRate,
|
||||||
|
|
||||||
|
transactionType: 'Expense',
|
||||||
|
transactionId: this.expense.id,
|
||||||
|
|
||||||
|
date: this.expense.paymentDate,
|
||||||
|
userId: this.expense.userId,
|
||||||
|
|
||||||
|
debit: 0,
|
||||||
|
credit: 0,
|
||||||
|
|
||||||
|
branchId: this.expense.branchId,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL payment entry.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedgerEntry}
|
||||||
|
*/
|
||||||
|
private getExpenseGLPaymentEntry = (): ILedgerEntry => {
|
||||||
|
const commonEntry = this.getExpenseGLCommonEntry();
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonEntry,
|
||||||
|
credit: this.expense.localAmount,
|
||||||
|
accountId: this.expense.paymentAccountId,
|
||||||
|
accountNormal:
|
||||||
|
this.expense?.paymentAccount?.accountNormal === 'debit'
|
||||||
|
? AccountNormal.DEBIT
|
||||||
|
: AccountNormal.CREDIT,
|
||||||
|
index: 1,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL category entry.
|
||||||
|
* @param {IExpense} expense -
|
||||||
|
* @param {IExpenseCategory} expenseCategory -
|
||||||
|
* @param {number} index
|
||||||
|
* @returns {ILedgerEntry}
|
||||||
|
*/
|
||||||
|
private getExpenseGLCategoryEntry = R.curry(
|
||||||
|
(category: IExpenseCategory, index: number): ILedgerEntry => {
|
||||||
|
const commonEntry = this.getExpenseGLCommonEntry();
|
||||||
|
const localAmount = category.amount * this.expense.exchangeRate;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonEntry,
|
||||||
|
accountId: category.expenseAccountId,
|
||||||
|
accountNormal: AccountNormal.DEBIT,
|
||||||
|
debit: localAmount,
|
||||||
|
note: category.description,
|
||||||
|
index: index + 2,
|
||||||
|
projectId: category.projectId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense GL entries.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedgerEntry[]}
|
||||||
|
*/
|
||||||
|
public getExpenseGLEntries = (): ILedgerEntry[] => {
|
||||||
|
const getCategoryEntry = this.getExpenseGLCategoryEntry();
|
||||||
|
|
||||||
|
const paymentEntry = this.getExpenseGLPaymentEntry();
|
||||||
|
const categoryEntries = this.expense.categories.map(getCategoryEntry);
|
||||||
|
|
||||||
|
return [paymentEntry, ...categoryEntries];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the given expense ledger.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedger}
|
||||||
|
*/
|
||||||
|
public getExpenseLedger = (): ILedger => {
|
||||||
|
const entries = this.getExpenseGLEntries();
|
||||||
|
|
||||||
|
console.log(entries, 'entries');
|
||||||
|
|
||||||
|
return new Ledger(entries);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import * as R from 'ramda';
|
|
||||||
import { Service } from 'typedi';
|
|
||||||
import {
|
|
||||||
AccountNormal,
|
|
||||||
IExpense,
|
|
||||||
IExpenseCategory,
|
|
||||||
ILedger,
|
|
||||||
ILedgerEntry,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import Ledger from '@/services/Accounting/Ledger';
|
|
||||||
|
|
||||||
@Service()
|
|
||||||
export class ExpenseGLEntries {
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL common entry.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
private getExpenseGLCommonEntry = (expense: IExpense) => {
|
|
||||||
return {
|
|
||||||
currencyCode: expense.currencyCode,
|
|
||||||
exchangeRate: expense.exchangeRate,
|
|
||||||
|
|
||||||
transactionType: 'Expense',
|
|
||||||
transactionId: expense.id,
|
|
||||||
|
|
||||||
date: expense.paymentDate,
|
|
||||||
userId: expense.userId,
|
|
||||||
|
|
||||||
debit: 0,
|
|
||||||
credit: 0,
|
|
||||||
|
|
||||||
branchId: expense.branchId,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL payment entry.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns {ILedgerEntry}
|
|
||||||
*/
|
|
||||||
private getExpenseGLPaymentEntry = (expense: IExpense): ILedgerEntry => {
|
|
||||||
const commonEntry = this.getExpenseGLCommonEntry(expense);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...commonEntry,
|
|
||||||
credit: expense.localAmount,
|
|
||||||
accountId: expense.paymentAccountId,
|
|
||||||
accountNormal: AccountNormal.DEBIT,
|
|
||||||
index: 1,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL category entry.
|
|
||||||
* @param {IExpense} expense -
|
|
||||||
* @param {IExpenseCategory} expenseCategory -
|
|
||||||
* @param {number} index
|
|
||||||
* @returns {ILedgerEntry}
|
|
||||||
*/
|
|
||||||
private getExpenseGLCategoryEntry = R.curry(
|
|
||||||
(
|
|
||||||
expense: IExpense,
|
|
||||||
category: IExpenseCategory,
|
|
||||||
index: number
|
|
||||||
): ILedgerEntry => {
|
|
||||||
const commonEntry = this.getExpenseGLCommonEntry(expense);
|
|
||||||
const localAmount = category.amount * expense.exchangeRate;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...commonEntry,
|
|
||||||
accountId: category.expenseAccountId,
|
|
||||||
accountNormal: AccountNormal.DEBIT,
|
|
||||||
debit: localAmount,
|
|
||||||
note: category.description,
|
|
||||||
index: index + 2,
|
|
||||||
projectId: category.projectId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the expense GL entries.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns {ILedgerEntry[]}
|
|
||||||
*/
|
|
||||||
public getExpenseGLEntries = (expense: IExpense): ILedgerEntry[] => {
|
|
||||||
const getCategoryEntry = this.getExpenseGLCategoryEntry(expense);
|
|
||||||
|
|
||||||
const paymentEntry = this.getExpenseGLPaymentEntry(expense);
|
|
||||||
const categoryEntries = expense.categories.map(getCategoryEntry);
|
|
||||||
|
|
||||||
return [paymentEntry, ...categoryEntries];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the given expense ledger.
|
|
||||||
* @param {IExpense} expense
|
|
||||||
* @returns {ILedger}
|
|
||||||
*/
|
|
||||||
public getExpenseLedger = (expense: IExpense): ILedger => {
|
|
||||||
const entries = this.getExpenseGLEntries(expense);
|
|
||||||
|
|
||||||
return new Ledger(entries);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { Knex } from 'knex';
|
||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { IExpense, ILedger } from '@/interfaces';
|
||||||
|
import { ExpenseGL } from './ExpenseGL';
|
||||||
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class ExpenseGLEntries {
|
||||||
|
@Inject()
|
||||||
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the expense G/L of the given id.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} expenseId
|
||||||
|
* @param {Knex.Transaction} trx
|
||||||
|
* @returns {Promise<ILedger>}
|
||||||
|
*/
|
||||||
|
public getExpenseLedgerById = async (
|
||||||
|
tenantId: number,
|
||||||
|
expenseId: number,
|
||||||
|
trx?: Knex.Transaction
|
||||||
|
): Promise<ILedger> => {
|
||||||
|
const { Expense } = await this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const expense = await Expense.query(trx)
|
||||||
|
.findById(expenseId)
|
||||||
|
.withGraphFetched('categories')
|
||||||
|
.withGraphFetched('paymentAccount')
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
return this.getExpenseLedger(expense);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the given expense ledger.
|
||||||
|
* @param {IExpense} expense
|
||||||
|
* @returns {ILedger}
|
||||||
|
*/
|
||||||
|
public getExpenseLedger = (expense: IExpense): ILedger => {
|
||||||
|
const expenseGL = new ExpenseGL(expense);
|
||||||
|
|
||||||
|
return expenseGL.getExpenseLedger();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import { Knex } from 'knex';
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
|
import LedgerStorageService from '@/services/Accounting/LedgerStorageService';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
import { ExpenseGLEntries } from './ExpenseGLEntries';
|
import { ExpenseGLEntries } from './ExpenseGLEntriesService';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class ExpenseGLEntriesStorage {
|
export class ExpenseGLEntriesStorage {
|
||||||
@@ -12,9 +12,6 @@ export class ExpenseGLEntriesStorage {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private ledgerStorage: LedgerStorageService;
|
private ledgerStorage: LedgerStorageService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private tenancy: HasTenancyService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the expense GL entries.
|
* Writes the expense GL entries.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -26,15 +23,12 @@ export class ExpenseGLEntriesStorage {
|
|||||||
expenseId: number,
|
expenseId: number,
|
||||||
trx?: Knex.Transaction
|
trx?: Knex.Transaction
|
||||||
) => {
|
) => {
|
||||||
const { Expense } = await this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const expense = await Expense.query(trx)
|
|
||||||
.findById(expenseId)
|
|
||||||
.withGraphFetched('categories');
|
|
||||||
|
|
||||||
// Retrieves the given expense ledger.
|
// Retrieves the given expense ledger.
|
||||||
const expenseLedger = this.expenseGLEntries.getExpenseLedger(expense);
|
const expenseLedger = await this.expenseGLEntries.getExpenseLedgerById(
|
||||||
|
tenantId,
|
||||||
|
expenseId,
|
||||||
|
trx
|
||||||
|
);
|
||||||
// Commits the expense ledger entries.
|
// Commits the expense ledger entries.
|
||||||
await this.ledgerStorage.commit(tenantId, expenseLedger, trx);
|
await this.ledgerStorage.commit(tenantId, expenseLedger, trx);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user