Skip to content

Commit

Permalink
Merge pull request #662 from bigcapitalhq/refactor-expense-gl
Browse files Browse the repository at this point in the history
refactor: The expense G/L writer
  • Loading branch information
abouolia authored Sep 4, 2024
2 parents 3795322 + d3d2112 commit 9f21f64
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 118 deletions.
113 changes: 113 additions & 0 deletions packages/server/src/services/Expenses/ExpenseGL.ts
Original file line number Diff line number Diff line change
@@ -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);
};
}
106 changes: 0 additions & 106 deletions packages/server/src/services/Expenses/ExpenseGLEntries.ts

This file was deleted.

45 changes: 45 additions & 0 deletions packages/server/src/services/Expenses/ExpenseGLEntriesService.ts
Original file line number Diff line number Diff line change
@@ -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();
};
}
18 changes: 6 additions & 12 deletions packages/server/src/services/Expenses/ExpenseGLEntriesStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -12,9 +12,6 @@ export class ExpenseGLEntriesStorage {
@Inject()
private ledgerStorage: LedgerStorageService;

@Inject()
private tenancy: HasTenancyService;

/**
* Writes the expense GL entries.
* @param {number} tenantId
Expand All @@ -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);
};
Expand Down

0 comments on commit 9f21f64

Please sign in to comment.