mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 22:30:31 +00:00
refactor: inventory adjustments to GL
This commit is contained in:
@@ -17,21 +17,20 @@ import { Item } from '@/modules/Items/models/Item';
|
||||
import { Account } from '@/modules/Accounts/models/Account.model';
|
||||
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
||||
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||
|
||||
export class CreateQuickInventoryAdjustmentService {
|
||||
constructor(
|
||||
@Inject(InventoryAdjustment.name)
|
||||
private readonly inventoryAdjustmentModel: typeof InventoryAdjustment,
|
||||
|
||||
@Inject(InventoryAdjustmentEntry.name)
|
||||
private readonly inventoryAdjustmentEntryModel: typeof InventoryAdjustmentEntry,
|
||||
|
||||
|
||||
@Inject(Item.name)
|
||||
private readonly itemModel: typeof Item,
|
||||
|
||||
|
||||
@Inject(Account.name)
|
||||
private readonly accountModel: typeof Account,
|
||||
|
||||
|
||||
private readonly tenancyContext: TenancyContext,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly warehouseDTOTransform: WarehouseTransactionDTOTransform,
|
||||
@@ -43,9 +42,10 @@ export class CreateQuickInventoryAdjustmentService {
|
||||
* @param {IQuickInventoryAdjustmentDTO} adjustmentDTO -
|
||||
* @return {IInventoryAdjustment}
|
||||
*/
|
||||
private transformQuickAdjToModel(
|
||||
private async transformQuickAdjToModel(
|
||||
adjustmentDTO: IQuickInventoryAdjustmentDTO,
|
||||
): InventoryAdjustment {
|
||||
): Promise<InventoryAdjustment> {
|
||||
const authorizedUser = await this.tenancyContext.getSystemUser();
|
||||
const entries = [
|
||||
{
|
||||
index: 1,
|
||||
@@ -104,7 +104,8 @@ export class CreateQuickInventoryAdjustmentService {
|
||||
|
||||
// Transform the DTO to inventory adjustment model.
|
||||
const invAdjustmentObject =
|
||||
this.transformQuickAdjToModel(quickAdjustmentDTO);
|
||||
await this.transformQuickAdjToModel(quickAdjustmentDTO);
|
||||
|
||||
// Writes inventory adjustment transaction with associated transactions
|
||||
// under unit-of-work envirment.
|
||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||
|
||||
@@ -18,9 +18,6 @@ export class PublishInventoryAdjustmentService {
|
||||
|
||||
@Inject(InventoryAdjustment.name)
|
||||
private readonly inventoryAdjustmentModel: typeof InventoryAdjustment,
|
||||
|
||||
@Inject(InventoryAdjustmentEntry.name)
|
||||
private readonly inventoryAdjustmentEntryModel: typeof InventoryAdjustmentEntry,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import * as R from 'ramda';
|
||||
import { InventoryAdjustment } from '../../models/InventoryAdjustment';
|
||||
import { InventoryAdjustmentEntry } from '../../models/InventoryAdjustmentEntry';
|
||||
import { ILedgerEntry } from '../../../Ledger/types/Ledger.types';
|
||||
import { AccountNormal } from '@/interfaces/Account';
|
||||
import { Ledger } from '../../../Ledger/Ledger';
|
||||
|
||||
export class InventoryAdjustmentsGL {
|
||||
private inventoryAdjustment: InventoryAdjustment;
|
||||
private baseCurrency: string;
|
||||
|
||||
constructor(inventoryAdjustmentModel: InventoryAdjustment) {
|
||||
this.inventoryAdjustment = inventoryAdjustmentModel;
|
||||
}
|
||||
|
||||
setBaseCurrency(baseCurrency: string) {
|
||||
this.baseCurrency = baseCurrency;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the inventory adjustment common GL entry.
|
||||
* @returns {ILedgerEntry}
|
||||
*/
|
||||
private get adjustmentGLCommonEntry() {
|
||||
return {
|
||||
currencyCode: this.baseCurrency,
|
||||
exchangeRate: 1,
|
||||
|
||||
transactionId: this.inventoryAdjustment.id,
|
||||
transactionType: 'InventoryAdjustment',
|
||||
referenceNumber: this.inventoryAdjustment.referenceNo,
|
||||
|
||||
date: this.inventoryAdjustment.date,
|
||||
|
||||
userId: this.inventoryAdjustment.userId,
|
||||
branchId: this.inventoryAdjustment.branchId,
|
||||
|
||||
createdAt: this.inventoryAdjustment.createdAt,
|
||||
|
||||
credit: 0,
|
||||
debit: 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the inventory adjustment inventory GL entry.
|
||||
* @param {InventoryAdjustmentEntry} entry - Inventory adjustment entry.
|
||||
* @param {number} index - Entry index.
|
||||
* @returns {ILedgerEntry}
|
||||
*/
|
||||
private getAdjustmentGLInventoryEntry = R.curry(
|
||||
(entry: InventoryAdjustmentEntry, index: number): ILedgerEntry => {
|
||||
const commonEntry = this.adjustmentGLCommonEntry;
|
||||
const amount = entry.cost * entry.quantity;
|
||||
|
||||
return {
|
||||
...commonEntry,
|
||||
debit: amount,
|
||||
accountId: entry.item.inventoryAccountId,
|
||||
accountNormal: AccountNormal.DEBIT,
|
||||
index,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieves the inventory adjustment
|
||||
* @param {IInventoryAdjustment} inventoryAdjustment
|
||||
* @param {IInventoryAdjustmentEntry} entry
|
||||
* @returns {ILedgerEntry}
|
||||
*/
|
||||
private getAdjustmentGLCostEntry(
|
||||
entry: InventoryAdjustmentEntry,
|
||||
index: number,
|
||||
): ILedgerEntry {
|
||||
const commonEntry = this.adjustmentGLCommonEntry;
|
||||
const amount = entry.cost * entry.quantity;
|
||||
|
||||
return {
|
||||
...commonEntry,
|
||||
accountId: this.inventoryAdjustment.adjustmentAccountId,
|
||||
accountNormal: AccountNormal.DEBIT,
|
||||
credit: amount,
|
||||
index: index + 2,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the inventory adjustment GL item entry.
|
||||
* @param {InventoryAdjustmentEntry} entry - Inventory adjustment entry.
|
||||
* @param {number} index - Entry index.
|
||||
* @returns {ILedgerEntry[]}
|
||||
*/
|
||||
private getAdjustmentGLItemEntry(
|
||||
entry: InventoryAdjustmentEntry,
|
||||
index: number,
|
||||
): ILedgerEntry[] {
|
||||
const getInventoryEntry = this.getAdjustmentGLInventoryEntry();
|
||||
const inventoryEntry = getInventoryEntry(entry, index);
|
||||
const costEntry = this.getAdjustmentGLCostEntry(entry, index);
|
||||
|
||||
return [inventoryEntry, costEntry];
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes increment inventroy adjustment GL entries.
|
||||
* @param {InventoryAdjustment} inventoryAdjustment -
|
||||
* @param {JournalPoster} jorunal -
|
||||
* @returns {ILedgerEntry[]}
|
||||
*/
|
||||
public getIncrementAdjustmentGLEntries(): ILedgerEntry[] {
|
||||
return this.inventoryAdjustment.entries
|
||||
.map((entry, index) => this.getAdjustmentGLItemEntry(entry, index))
|
||||
.flat();
|
||||
}
|
||||
|
||||
public getAdjustmentGL(): Ledger {
|
||||
const entries = this.getIncrementAdjustmentGLEntries();
|
||||
|
||||
return new Ledger(entries);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { LedgerStorageService } from '../../../Ledger/LedgerStorage.service';
|
||||
import { InventoryAdjustment } from '../../models/InventoryAdjustment';
|
||||
import { TenancyContext } from '../../../Tenancy/TenancyContext.service';
|
||||
import { InventoryAdjustmentsGL } from './InventoryAdjustmentGL';
|
||||
|
||||
export class InventoryAdjustmentsGLEntries {
|
||||
constructor(
|
||||
private readonly ledgerStorage: LedgerStorageService,
|
||||
private readonly tenancyContext: TenancyContext,
|
||||
|
||||
@Inject(InventoryAdjustment.name)
|
||||
private readonly inventoryAdjustment: typeof InventoryAdjustment,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Writes inventory increment adjustment GL entries.
|
||||
* @param {number} inventoryAdjustmentId - Inventory adjustment ID.
|
||||
* @param {Knex.Transaction} trx - Knex transaction.
|
||||
*/
|
||||
public writeAdjustmentGLEntries = async (
|
||||
inventoryAdjustmentId: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> => {
|
||||
// Retrieves the inventory adjustment with associated entries.
|
||||
const adjustment = await this.inventoryAdjustment.query(trx)
|
||||
.findById(inventoryAdjustmentId)
|
||||
.withGraphFetched('entries.item');
|
||||
|
||||
const tenantMeta = await this.tenancyContext.getTenantMetadata();
|
||||
|
||||
// Retrieves the inventory adjustment GL entries.
|
||||
const ledger = new InventoryAdjustmentsGL(adjustment)
|
||||
.setBaseCurrency(tenantMeta.baseCurrency)
|
||||
.getAdjustmentGL();
|
||||
|
||||
// Commits the ledger entries to the storage.
|
||||
await this.ledgerStorage.commit(ledger, trx);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reverts the adjustment transactions GL entries.
|
||||
* @param {number} tenantId
|
||||
* @param {number} inventoryAdjustmentId
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public revertAdjustmentGLEntries = (
|
||||
inventoryAdjustmentId: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<void> => {
|
||||
return this.ledgerStorage.deleteByReference(
|
||||
inventoryAdjustmentId,
|
||||
'InventoryAdjustment',
|
||||
trx,
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Rewrite inventory adjustment GL entries.
|
||||
* @param {number} tenantId
|
||||
* @param {number} inventoryAdjustmentId
|
||||
* @param {Knex.Transaction} trx
|
||||
*/
|
||||
public rewriteAdjustmentGLEntries = async (
|
||||
inventoryAdjustmentId: number,
|
||||
trx?: Knex.Transaction,
|
||||
) => {
|
||||
// Reverts GL entries of the given inventory adjustment.
|
||||
await this.revertAdjustmentGLEntries(inventoryAdjustmentId, trx);
|
||||
|
||||
// Writes GL entries of th egiven inventory adjustment.
|
||||
await this.writeAdjustmentGLEntries(inventoryAdjustmentId, trx);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user