mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 13:20:31 +00:00
fix: design flow of writing invoice journal entries.
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
import { Container, Service, Inject } from 'typedi';
|
||||
import { pick } from 'lodash';
|
||||
import config from 'config';
|
||||
import {
|
||||
EventDispatcher,
|
||||
EventDispatcherInterface,
|
||||
} from 'decorators/eventDispatcher';
|
||||
import { IInventoryLotCost, IInventoryTransaction, IItem, IItemEntry } from 'interfaces'
|
||||
import {
|
||||
IInventoryLotCost,
|
||||
IInventoryTransaction,
|
||||
IItem,
|
||||
IItemEntry,
|
||||
} from 'interfaces';
|
||||
import InventoryAverageCost from 'services/Inventory/InventoryAverageCost';
|
||||
import InventoryCostLotTracker from 'services/Inventory/InventoryCostLotTracker';
|
||||
import TenancyService from 'services/Tenancy/TenancyService';
|
||||
@@ -27,9 +33,9 @@ export default class InventoryService {
|
||||
itemEntries: IItemEntry[],
|
||||
transactionType: string,
|
||||
transactionId: number,
|
||||
direction: 'IN'|'OUT',
|
||||
date: Date|string,
|
||||
lotNumber: number,
|
||||
direction: 'IN' | 'OUT',
|
||||
date: Date | string,
|
||||
lotNumber: number
|
||||
) {
|
||||
return itemEntries.map((entry: IItemEntry) => ({
|
||||
...pick(entry, ['itemId', 'quantity', 'rate']),
|
||||
@@ -62,13 +68,21 @@ export default class InventoryService {
|
||||
let costMethodComputer: IInventoryCostMethod;
|
||||
|
||||
// Switch between methods based on the item cost method.
|
||||
switch('AVG') {
|
||||
switch ('AVG') {
|
||||
case 'FIFO':
|
||||
case 'LIFO':
|
||||
costMethodComputer = new InventoryCostLotTracker(tenantId, fromDate, itemId);
|
||||
costMethodComputer = new InventoryCostLotTracker(
|
||||
tenantId,
|
||||
fromDate,
|
||||
itemId
|
||||
);
|
||||
break;
|
||||
case 'AVG':
|
||||
costMethodComputer = new InventoryAverageCost(tenantId, fromDate, itemId);
|
||||
costMethodComputer = new InventoryAverageCost(
|
||||
tenantId,
|
||||
fromDate,
|
||||
itemId
|
||||
);
|
||||
break;
|
||||
}
|
||||
return costMethodComputer.computeItemCost();
|
||||
@@ -77,20 +91,24 @@ export default class InventoryService {
|
||||
/**
|
||||
* Schedule item cost compute job.
|
||||
* @param {number} tenantId
|
||||
* @param {number} itemId
|
||||
* @param {Date} startingDate
|
||||
* @param {number} itemId
|
||||
* @param {Date} startingDate
|
||||
*/
|
||||
async scheduleComputeItemCost(tenantId: number, itemId: number, startingDate: Date|string) {
|
||||
async scheduleComputeItemCost(
|
||||
tenantId: number,
|
||||
itemId: number,
|
||||
startingDate: Date | string
|
||||
) {
|
||||
const agenda = Container.get('agenda');
|
||||
|
||||
// Cancel any `compute-item-cost` in the queue has upper starting date
|
||||
// Cancel any `compute-item-cost` in the queue has upper starting date
|
||||
// with the same given item.
|
||||
await agenda.cancel({
|
||||
name: 'compute-item-cost',
|
||||
nextRunAt: { $ne: null },
|
||||
'data.tenantId': tenantId,
|
||||
'data.itemId': itemId,
|
||||
'data.startingDate': { "$gt": startingDate }
|
||||
'data.startingDate': { $gt: startingDate },
|
||||
});
|
||||
|
||||
// Retrieve any `compute-item-cost` in the queue has lower starting date
|
||||
@@ -100,23 +118,29 @@ export default class InventoryService {
|
||||
nextRunAt: { $ne: null },
|
||||
'data.tenantId': tenantId,
|
||||
'data.itemId': itemId,
|
||||
'data.startingDate': { "$lte": startingDate }
|
||||
'data.startingDate': { $lte: startingDate },
|
||||
});
|
||||
if (dependsJobs.length === 0) {
|
||||
await agenda.schedule('in 30 seconds', 'compute-item-cost', {
|
||||
startingDate, itemId, tenantId,
|
||||
});
|
||||
await agenda.schedule(
|
||||
config.scheduleComputeItemCost,
|
||||
'compute-item-cost',
|
||||
{
|
||||
startingDate,
|
||||
itemId,
|
||||
tenantId,
|
||||
}
|
||||
);
|
||||
|
||||
// Triggers `onComputeItemCostJobScheduled` event.
|
||||
await this.eventDispatcher.dispatch(
|
||||
events.inventory.onComputeItemCostJobScheduled,
|
||||
{ startingDate, itemId, tenantId },
|
||||
{ startingDate, itemId, tenantId }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records the inventory transactions.
|
||||
* Records the inventory transactions.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {Bill} bill - Bill model object.
|
||||
* @param {number} billId - Bill id.
|
||||
@@ -125,27 +149,23 @@ export default class InventoryService {
|
||||
async recordInventoryTransactions(
|
||||
tenantId: number,
|
||||
inventoryEntries: IInventoryTransaction[],
|
||||
deleteOld: boolean,
|
||||
deleteOld: boolean
|
||||
): Promise<void> {
|
||||
inventoryEntries.forEach(async (entry: IInventoryTransaction) => {
|
||||
await this.recordInventoryTransaction(
|
||||
tenantId,
|
||||
entry,
|
||||
deleteOld,
|
||||
);
|
||||
await this.recordInventoryTransaction(tenantId, entry, deleteOld);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {IInventoryTransaction} inventoryEntry
|
||||
* @param {boolean} deleteOld
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {IInventoryTransaction} inventoryEntry
|
||||
* @param {boolean} deleteOld
|
||||
*/
|
||||
async recordInventoryTransaction(
|
||||
tenantId: number,
|
||||
inventoryEntry: IInventoryTransaction,
|
||||
deleteOld: boolean = false,
|
||||
deleteOld: boolean = false
|
||||
): Promise<IInventoryTransaction> {
|
||||
const { InventoryTransaction, Item } = this.tenancy.models(tenantId);
|
||||
|
||||
@@ -153,7 +173,7 @@ export default class InventoryService {
|
||||
await this.deleteInventoryTransactions(
|
||||
tenantId,
|
||||
inventoryEntry.transactionId,
|
||||
inventoryEntry.transactionType,
|
||||
inventoryEntry.transactionType
|
||||
);
|
||||
}
|
||||
return InventoryTransaction.query().insert({
|
||||
@@ -165,14 +185,14 @@ export default class InventoryService {
|
||||
/**
|
||||
* Deletes the given inventory transactions.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {string} transactionType
|
||||
* @param {number} transactionId
|
||||
* @param {string} transactionType
|
||||
* @param {number} transactionId
|
||||
* @return {Promise}
|
||||
*/
|
||||
async deleteInventoryTransactions(
|
||||
tenantId: number,
|
||||
transactionId: number,
|
||||
transactionType: string,
|
||||
transactionType: string
|
||||
): Promise<void> {
|
||||
const { InventoryTransaction } = this.tenancy.models(tenantId);
|
||||
|
||||
@@ -184,16 +204,16 @@ export default class InventoryService {
|
||||
|
||||
/**
|
||||
* Records the inventory cost lot transaction.
|
||||
* @param {number} tenantId
|
||||
* @param {IInventoryLotCost} inventoryLotEntry
|
||||
* @param {number} tenantId
|
||||
* @param {IInventoryLotCost} inventoryLotEntry
|
||||
* @return {Promise<IInventoryLotCost>}
|
||||
*/
|
||||
async recordInventoryCostLotTransaction(
|
||||
tenantId: number,
|
||||
inventoryLotEntry: IInventoryLotCost,
|
||||
inventoryLotEntry: IInventoryLotCost
|
||||
): Promise<void> {
|
||||
const { InventoryCostLotTracker } = this.tenancy.models(tenantId);
|
||||
|
||||
|
||||
return InventoryCostLotTracker.query().insert({
|
||||
...inventoryLotEntry,
|
||||
});
|
||||
@@ -209,13 +229,14 @@ export default class InventoryService {
|
||||
const LOT_NUMBER_KEY = 'lot_number_increment';
|
||||
const storedLotNumber = settings.find({ key: LOT_NUMBER_KEY });
|
||||
|
||||
return (storedLotNumber && storedLotNumber.value) ?
|
||||
parseInt(storedLotNumber.value, 10) : 1;
|
||||
return storedLotNumber && storedLotNumber.value
|
||||
? parseInt(storedLotNumber.value, 10)
|
||||
: 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the next inventory LOT number.
|
||||
* @param {number} tenantId
|
||||
* @param {number} tenantId
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
async incrementNextLotNumber(tenantId: number) {
|
||||
@@ -236,4 +257,4 @@ export default class InventoryService {
|
||||
|
||||
return lotNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user