mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
Debounce scheduling calculating items cost
This commit is contained in:
@@ -139,24 +139,26 @@ export default class InventoryService {
|
||||
) {
|
||||
const agenda = Container.get('agenda');
|
||||
|
||||
const commonJobsQuery = {
|
||||
name: 'compute-item-cost',
|
||||
lastRunAt: { $exists: false },
|
||||
'data.tenantId': tenantId,
|
||||
'data.itemId': itemId,
|
||||
};
|
||||
// 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 },
|
||||
...commonJobsQuery,
|
||||
'data.startingDate': { $lte: startingDate },
|
||||
});
|
||||
// Retrieve any `compute-item-cost` in the queue has lower starting date
|
||||
// with the same given item.
|
||||
const dependsJobs = await agenda.jobs({
|
||||
name: 'compute-item-cost',
|
||||
nextRunAt: { $ne: null },
|
||||
'data.tenantId': tenantId,
|
||||
'data.itemId': itemId,
|
||||
'data.startingDate': { $lte: startingDate },
|
||||
...commonJobsQuery,
|
||||
'data.startingDate': { $gte: startingDate },
|
||||
});
|
||||
|
||||
// If the depends jobs cleared.
|
||||
if (dependsJobs.length === 0) {
|
||||
await agenda.schedule(
|
||||
config.scheduleComputeItemCost,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Mutex } from 'async-mutex';
|
||||
import { Container, Service, Inject } from 'typedi';
|
||||
import { chain } from 'lodash';
|
||||
import moment from 'moment';
|
||||
@@ -34,17 +35,26 @@ export class SaleInvoicesCost {
|
||||
inventoryItemsIds: number[],
|
||||
startingDate: Date
|
||||
): Promise<void> {
|
||||
const asyncOpers: Promise<[]>[] = [];
|
||||
const mutex = new Mutex();
|
||||
|
||||
inventoryItemsIds.forEach((inventoryItemId: number) => {
|
||||
const oper: Promise<[]> = this.inventoryService.scheduleComputeItemCost(
|
||||
tenantId,
|
||||
inventoryItemId,
|
||||
startingDate
|
||||
);
|
||||
asyncOpers.push(oper);
|
||||
});
|
||||
await Promise.all([...asyncOpers]);
|
||||
const asyncOpers = inventoryItemsIds.map(
|
||||
async (inventoryItemId: number) => {
|
||||
// @todo refactor the lock acquire to be distrbuted using Redis
|
||||
// and run the cost schedule job after running invoice transaction.
|
||||
const release = await mutex.acquire();
|
||||
|
||||
try {
|
||||
await this.inventoryService.scheduleComputeItemCost(
|
||||
tenantId,
|
||||
inventoryItemId,
|
||||
startingDate
|
||||
);
|
||||
} finally {
|
||||
release();
|
||||
}
|
||||
}
|
||||
);
|
||||
await Promise.all(asyncOpers);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,17 +96,22 @@ export class SaleInvoicesCost {
|
||||
tenantId: number,
|
||||
inventoryTransactions: IInventoryTransaction[]
|
||||
) {
|
||||
const asyncOpers: Promise<[]>[] = [];
|
||||
const mutex = new Mutex();
|
||||
const reducedTransactions = this.getMaxDateInventoryTransactions(
|
||||
inventoryTransactions
|
||||
);
|
||||
reducedTransactions.forEach((transaction) => {
|
||||
const oper: Promise<[]> = this.inventoryService.scheduleComputeItemCost(
|
||||
tenantId,
|
||||
transaction.itemId,
|
||||
transaction.date
|
||||
);
|
||||
asyncOpers.push(oper);
|
||||
const asyncOpers = reducedTransactions.map(async (transaction) => {
|
||||
const release = await mutex.acquire();
|
||||
|
||||
try {
|
||||
await this.inventoryService.scheduleComputeItemCost(
|
||||
tenantId,
|
||||
transaction.itemId,
|
||||
transaction.date
|
||||
);
|
||||
} finally {
|
||||
release();
|
||||
}
|
||||
});
|
||||
await Promise.all([...asyncOpers]);
|
||||
}
|
||||
|
||||
@@ -86,20 +86,14 @@ export default class InventorySubscriber {
|
||||
private handleScheduleItemsCostOnInventoryTransactionsCreated = async ({
|
||||
tenantId,
|
||||
inventoryTransactions,
|
||||
trx
|
||||
trx,
|
||||
}: IInventoryTransactionsCreatedPayload) => {
|
||||
const inventoryItemsIds = map(inventoryTransactions, 'itemId');
|
||||
|
||||
runAfterTransaction(trx, async () => {
|
||||
try {
|
||||
await this.saleInvoicesCost.computeItemsCostByInventoryTransactions(
|
||||
tenantId,
|
||||
inventoryTransactions
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
await this.saleInvoicesCost.computeItemsCostByInventoryTransactions(
|
||||
tenantId,
|
||||
inventoryTransactions
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
ISaleInvoiceEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import { SaleInvoiceGLEntries } from '@/services/Sales/Invoices/InvoiceGLEntries';
|
||||
import { runAfterTransaction } from '@/services/UnitOfWork/TransactionsHooks';
|
||||
|
||||
@Service()
|
||||
export default class SaleInvoiceWriteGLEntriesSubscriber {
|
||||
|
||||
Reference in New Issue
Block a user