mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +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 LedgerStorageService from '@/services/Accounting/LedgerStorageService';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { ExpenseGLEntries } from './ExpenseGLEntries';
|
||||
import { ExpenseGLEntries } from './ExpenseGLEntriesService';
|
||||
|
||||
@Service()
|
||||
export class ExpenseGLEntriesStorage {
|
||||
@@ -12,9 +12,6 @@ export class ExpenseGLEntriesStorage {
|
||||
@Inject()
|
||||
private ledgerStorage: LedgerStorageService;
|
||||
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
* Writes the expense GL entries.
|
||||
* @param {number} tenantId
|
||||
@@ -26,15 +23,12 @@ export class ExpenseGLEntriesStorage {
|
||||
expenseId: number,
|
||||
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.
|
||||
const expenseLedger = this.expenseGLEntries.getExpenseLedger(expense);
|
||||
|
||||
const expenseLedger = await this.expenseGLEntries.getExpenseLedgerById(
|
||||
tenantId,
|
||||
expenseId,
|
||||
trx
|
||||
);
|
||||
// Commits the expense ledger entries.
|
||||
await this.ledgerStorage.commit(tenantId, expenseLedger, trx);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user