refactor: nestjs

This commit is contained in:
Ahmed Bouhuolia
2025-02-18 19:26:58 +02:00
parent 5c0bb52b59
commit 95bb4fc8e3
30 changed files with 249 additions and 114 deletions

View File

@@ -1,6 +1,7 @@
import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config'; import { ConfigModule, ConfigService } from '@nestjs/config';
import { EventEmitterModule } from '@nestjs/event-emitter'; import { EventEmitterModule } from '@nestjs/event-emitter';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { join } from 'path'; import { join } from 'path';
import { import {
AcceptLanguageResolver, AcceptLanguageResolver,
@@ -25,7 +26,6 @@ import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module';
import { TenancyModelsModule } from '../Tenancy/TenancyModels/Tenancy.module'; import { TenancyModelsModule } from '../Tenancy/TenancyModels/Tenancy.module';
import { LoggerMiddleware } from '@/middleware/logger.middleware'; import { LoggerMiddleware } from '@/middleware/logger.middleware';
import { ExcludeNullInterceptor } from '@/interceptors/ExcludeNull.interceptor'; import { ExcludeNullInterceptor } from '@/interceptors/ExcludeNull.interceptor';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { JwtAuthGuard } from '../Auth/Jwt.guard'; import { JwtAuthGuard } from '../Auth/Jwt.guard';
import { UserIpInterceptor } from '@/interceptors/user-ip.interceptor'; import { UserIpInterceptor } from '@/interceptors/user-ip.interceptor';
import { TenancyGlobalMiddleware } from '../Tenancy/TenancyGlobal.middleware'; import { TenancyGlobalMiddleware } from '../Tenancy/TenancyGlobal.middleware';
@@ -154,13 +154,13 @@ import { StripePaymentModule } from '../StripePayment/StripePayment.module';
BankingTransactionsModule, BankingTransactionsModule,
BankingTransactionsExcludeModule, BankingTransactionsExcludeModule,
BankingTransactionsRegonizeModule, BankingTransactionsRegonizeModule,
// BankingMatchingModule, BankingMatchingModule,
// TransactionsLockingModule, // TransactionsLockingModule,
// SettingsModule, // SettingsModule,
InventoryAdjustmentsModule, InventoryAdjustmentsModule,
PostHogModule, PostHogModule,
EventTrackerModule, EventTrackerModule,
// FinancialStatementsModule, FinancialStatementsModule,
StripePaymentModule, StripePaymentModule,
], ],
controllers: [AppController], controllers: [AppController],

View File

@@ -42,7 +42,7 @@ export class CreateUncategorizedTransactionService {
} as IUncategorizedTransactionCreatingEventPayload, } as IUncategorizedTransactionCreatingEventPayload,
); );
const uncategorizedTransaction = await this.uncategorizedBankTransaction const uncategorizedTransaction = await this.uncategorizedBankTransaction()
.query(trx) .query(trx)
.insertAndFetch({ .insertAndFetch({
...createUncategorizedTransactionDTO, ...createUncategorizedTransactionDTO,

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import { GConstructor } from '@/common/types/Constructor'; import { GConstructor } from '@/common/types/Constructor';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { FinancialSheet } from './FinancialSheet'; import { FinancialSheet } from './FinancialSheet';

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as moment from 'moment'; import * as moment from 'moment';
import { ITableColumn, ITableColumnAccessor } from '../types/Table.types'; import { ITableColumn, ITableColumnAccessor } from '../types/Table.types';
import { IDateRange } from '../types/Report.types'; import { IDateRange } from '../types/Report.types';

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as moment from 'moment'; import * as moment from 'moment';
import { ITableColumn, ITableColumnAccessor } from '../types/Table.types'; import { ITableColumn, ITableColumnAccessor } from '../types/Table.types';
import { IDateRange } from '../types/Report.types'; import { IDateRange } from '../types/Report.types';

View File

@@ -5,13 +5,14 @@ import { Vendor } from '@/modules/Vendors/models/Vendor';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { IAPAgingSummaryQuery } from './APAgingSummary.types'; import { IAPAgingSummaryQuery } from './APAgingSummary.types';
import { ModelObject } from 'objection'; import { ModelObject } from 'objection';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
export class APAgingSummaryRepository { export class APAgingSummaryRepository {
@Inject(Vendor.name) @Inject(Vendor.name)
private readonly vendorModel: typeof Vendor; private readonly vendorModel: TenantModelProxy<typeof Vendor>;
@Inject(Bill.name) @Inject(Bill.name)
private readonly billModel: typeof Bill; private readonly billModel: TenantModelProxy<typeof Bill>;
@Inject(TenancyContext) @Inject(TenancyContext)
private readonly tenancyContext: TenancyContext; private readonly tenancyContext: TenancyContext;
@@ -93,8 +94,8 @@ export class APAgingSummaryRepository {
// Retrieve all vendors from the storage. // Retrieve all vendors from the storage.
const vendors = const vendors =
this.filter.vendorsIds.length > 0 this.filter.vendorsIds.length > 0
? await this.vendorModel.query().whereIn('id', this.filter.vendorsIds) ? await this.vendorModel().query().whereIn('id', this.filter.vendorsIds)
: await this.vendorModel.query(); : await this.vendorModel().query();
this.vendors = vendors; this.vendors = vendors;
} }
@@ -108,7 +109,7 @@ export class APAgingSummaryRepository {
query.modify('filterByBranches', this.filter.branchesIds); query.modify('filterByBranches', this.filter.branchesIds);
} }
}; };
const overdueBills = await this.billModel const overdueBills = await this.billModel()
.query() .query()
.modify('overdueBillsFromDate', this.filter.asDate) .modify('overdueBillsFromDate', this.filter.asDate)
.onBuild(commonQuery); .onBuild(commonQuery);
@@ -127,7 +128,7 @@ export class APAgingSummaryRepository {
} }
}; };
// Retrieve all due vendors bills. // Retrieve all due vendors bills.
const dueBills = await this.billModel const dueBills = await this.billModel()
.query() .query()
.modify('dueBillsFromDate', this.filter.asDate) .modify('dueBillsFromDate', this.filter.asDate)
.onBuild(commonQuery); .onBuild(commonQuery);

View File

@@ -5,16 +5,17 @@ import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
import { ModelObject } from 'objection'; import { ModelObject } from 'objection';
import { IARAgingSummaryQuery } from './ARAgingSummary.types'; import { IARAgingSummaryQuery } from './ARAgingSummary.types';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
export class ARAgingSummaryRepository { export class ARAgingSummaryRepository {
@Inject(TenancyContext) @Inject(TenancyContext)
private tenancyContext: TenancyContext; private tenancyContext: TenancyContext;
@Inject(Customer.name) @Inject(Customer.name)
private customerModel: typeof Customer; private customerModel: TenantModelProxy<typeof Customer>;
@Inject(SaleInvoice.name) @Inject(SaleInvoice.name)
private saleInvoiceModel: typeof SaleInvoice; private saleInvoiceModel: TenantModelProxy<typeof SaleInvoice>;
/** /**
* Filter. * Filter.
@@ -92,10 +93,10 @@ export class ARAgingSummaryRepository {
// Retrieve all customers from the storage. // Retrieve all customers from the storage.
const customers = const customers =
this.filter.customersIds.length > 0 this.filter.customersIds.length > 0
? await this.customerModel ? await this.customerModel()
.query() .query()
.whereIn('id', this.filter.customersIds) .whereIn('id', this.filter.customersIds)
: await this.customerModel.query(); : await this.customerModel().query();
this.customers = customers; this.customers = customers;
} }
@@ -110,7 +111,7 @@ export class ARAgingSummaryRepository {
} }
}; };
// Retrieve all overdue sale invoices. // Retrieve all overdue sale invoices.
const overdueSaleInvoices = await this.saleInvoiceModel const overdueSaleInvoices = await this.saleInvoiceModel()
.query() .query()
.modify('overdueInvoicesFromDate', this.filter.asDate) .modify('overdueInvoicesFromDate', this.filter.asDate)
.onBuild(commonQuery); .onBuild(commonQuery);
@@ -132,7 +133,7 @@ export class ARAgingSummaryRepository {
} }
}; };
// Retrieve all due sale invoices. // Retrieve all due sale invoices.
const currentInvoices = await this.saleInvoiceModel const currentInvoices = await this.saleInvoiceModel()
.query() .query()
.modify('dueInvoicesFromDate', this.filter.asDate) .modify('dueInvoicesFromDate', this.filter.asDate)
.onBuild(commonQuery); .onBuild(commonQuery);

View File

@@ -14,6 +14,7 @@ import { Ledger } from '@/modules/Ledger/Ledger';
import { transformToMapBy } from '@/utils/transform-to-map-by'; import { transformToMapBy } from '@/utils/transform-to-map-by';
import { Account } from '@/modules/Accounts/models/Account.model'; import { Account } from '@/modules/Accounts/models/Account.model';
import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model'; import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT }) @Injectable({ scope: Scope.TRANSIENT })
export class BalanceSheetRepository extends R.compose( export class BalanceSheetRepository extends R.compose(
@@ -24,13 +25,15 @@ export class BalanceSheetRepository extends R.compose(
* Account model. * Account model.
*/ */
@Inject(Account.name) @Inject(Account.name)
public readonly accountModel: typeof Account; public readonly accountModel: TenantModelProxy<typeof Account>;
/** /**
* Account transaction model. * Account transaction model.
*/ */
@Inject(AccountTransaction.name) @Inject(AccountTransaction.name)
public readonly accountTransactionModel: typeof AccountTransaction; public readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>;
/** /**
* @description Balance sheet query. * @description Balance sheet query.
@@ -216,7 +219,7 @@ export class BalanceSheetRepository extends R.compose(
* Initialize accounts graph. * Initialize accounts graph.
*/ */
public initAccountsGraph = async () => { public initAccountsGraph = async () => {
this.accountsGraph = this.accountModel.toDependencyGraph(this.accounts); this.accountsGraph = this.accountModel().toDependencyGraph(this.accounts);
}; };
// ---------------------------- // ----------------------------
@@ -338,7 +341,7 @@ export class BalanceSheetRepository extends R.compose(
* @return {Promise<IAccount[]>} * @return {Promise<IAccount[]>}
*/ */
public getAccounts = () => { public getAccounts = () => {
return this.accountModel.query(); return this.accountModel().query();
}; };
/** /**
@@ -353,18 +356,20 @@ export class BalanceSheetRepository extends R.compose(
toDate: Date, toDate: Date,
datePeriodsType: string, datePeriodsType: string,
) => { ) => {
return this.accountTransactionModel.query().onBuild((query) => { return this.accountTransactionModel()
query.sum('credit as credit'); .query()
query.sum('debit as debit'); .onBuild((query) => {
query.groupBy('accountId'); query.sum('credit as credit');
query.select(['accountId']); query.sum('debit as debit');
query.groupBy('accountId');
query.select(['accountId']);
query.modify('groupByDateFormat', datePeriodsType); query.modify('groupByDateFormat', datePeriodsType);
query.modify('filterDateRange', fromDate, toDate); query.modify('filterDateRange', fromDate, toDate);
query.withGraphFetched('account'); query.withGraphFetched('account');
this.commonFilterBranchesQuery(query); this.commonFilterBranchesQuery(query);
}); });
}; };
/** /**
@@ -372,17 +377,19 @@ export class BalanceSheetRepository extends R.compose(
* @param {Date|string} openingDate - * @param {Date|string} openingDate -
*/ */
public closingAccountsTotal = async (openingDate: Date | string) => { public closingAccountsTotal = async (openingDate: Date | string) => {
return this.accountTransactionModel.query().onBuild((query) => { return this.accountTransactionModel()
query.sum('credit as credit'); .query()
query.sum('debit as debit'); .onBuild((query) => {
query.groupBy('accountId'); query.sum('credit as credit');
query.select(['accountId']); query.sum('debit as debit');
query.groupBy('accountId');
query.select(['accountId']);
query.modify('filterDateRange', null, openingDate); query.modify('filterDateRange', null, openingDate);
query.withGraphFetched('account'); query.withGraphFetched('account');
this.commonFilterBranchesQuery(query); this.commonFilterBranchesQuery(query);
}); });
}; };
/** /**

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as R from 'ramda'; import * as R from 'ramda';
import { defaultTo, set, sumBy, isEmpty, mapValues, get } from 'lodash'; import { defaultTo, set, sumBy, isEmpty, mapValues, get } from 'lodash';
import * as mathjs from 'mathjs'; import * as mathjs from 'mathjs';

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as R from 'ramda'; import * as R from 'ramda';
import { sumBy, mapValues, get } from 'lodash'; import { sumBy, mapValues, get } from 'lodash';
import { ACCOUNT_ROOT_TYPE } from '@/constants/accounts'; import { ACCOUNT_ROOT_TYPE } from '@/constants/accounts';

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import * as moment from 'moment'; import * as moment from 'moment';
import { Knex } from 'knex'; import { Knex } from 'knex';
@@ -11,8 +12,8 @@ import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable() @Injectable()
export class CashFlowRepository { export class CashFlowRepository {
/** /**
* @param {typeof Account} accountModel - Account model. * @param {TenantModelProxy<typeof Account>} accountModel - Account model.
* @param {typeof AccountTransaction} accountTransactionModel - Account transaction model. * @param {TenantModelProxy<typeof AccountTransaction>} accountTransactionModel - Account transaction model.
*/ */
constructor( constructor(
@Inject(Account.name) @Inject(Account.name)

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as R from 'ramda'; import * as R from 'ramda';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import moment from 'moment'; import moment from 'moment';

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as R from 'ramda'; import * as R from 'ramda';
import { map } from 'lodash'; import { map } from 'lodash';
import { Account } from "@/modules/Accounts/models/Account.model"; import { Account } from "@/modules/Accounts/models/Account.model";

View File

@@ -12,6 +12,7 @@ import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { transformToMap } from '@/utils/transform-to-key'; import { transformToMap } from '@/utils/transform-to-key';
import { Ledger } from '@/modules/Ledger/Ledger'; import { Ledger } from '@/modules/Ledger/Ledger';
import { TenantModel } from '@/modules/System/models/TenantModel'; import { TenantModel } from '@/modules/System/models/TenantModel';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT }) @Injectable({ scope: Scope.TRANSIENT })
export class GeneralLedgerRepository { export class GeneralLedgerRepository {
@@ -41,10 +42,12 @@ export class GeneralLedgerRepository {
private readonly accountRepository: AccountRepository; private readonly accountRepository: AccountRepository;
@Inject(AccountTransaction.name) @Inject(AccountTransaction.name)
private readonly accountTransactionModel: typeof AccountTransaction; private readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>;
@Inject(Contact.name) @Inject(Contact.name)
private readonly contactModel: typeof Contact; private readonly contactModel: TenantModelProxy<typeof Contact>;
@Inject(TenancyContext) @Inject(TenancyContext)
private readonly tenancyContext: TenancyContext; private readonly tenancyContext: TenancyContext;
@@ -97,7 +100,7 @@ export class GeneralLedgerRepository {
* Initialize the contacts. * Initialize the contacts.
*/ */
public async initContacts() { public async initContacts() {
this.contacts = await this.contactModel.query(); this.contacts = await this.contactModel().query();
this.contactsById = transformToMap(this.contacts, 'id'); this.contactsById = transformToMap(this.contacts, 'id');
} }
@@ -105,7 +108,7 @@ export class GeneralLedgerRepository {
* Initialize the G/L transactions from/to the given date. * Initialize the G/L transactions from/to the given date.
*/ */
public async initTransactions() { public async initTransactions() {
this.transactions = await this.accountTransactionModel this.transactions = await this.accountTransactionModel()
.query() .query()
.onBuild((query) => { .onBuild((query) => {
query.modify( query.modify(
@@ -132,7 +135,7 @@ export class GeneralLedgerRepository {
*/ */
public async initAccountsOpeningBalance() { public async initAccountsOpeningBalance() {
// Retrieves opening balance credit/debit sumation. // Retrieves opening balance credit/debit sumation.
this.openingBalanceTransactions = await this.accountTransactionModel this.openingBalanceTransactions = await this.accountTransactionModel()
.query() .query()
.onBuild((query) => { .onBuild((query) => {
const toDate = moment(this.filter.fromDate).subtract(1, 'day'); const toDate = moment(this.filter.fromDate).subtract(1, 'day');

View File

@@ -8,14 +8,17 @@ import { Inject, Injectable, Scope } from '@nestjs/common';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { transformToMapKeyValue } from '@/utils/transform-to-map-key-value'; import { transformToMapKeyValue } from '@/utils/transform-to-map-key-value';
import { transformToMapBy } from '@/utils/transform-to-map-by'; import { transformToMapBy } from '@/utils/transform-to-map-by';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT }) @Injectable({ scope: Scope.TRANSIENT })
export class InventoryItemDetailsRepository { export class InventoryItemDetailsRepository {
@Inject(Item.name) @Inject(Item.name)
readonly itemModel: typeof Item; readonly itemModel: TenantModelProxy<typeof Item>;
@Inject(InventoryTransaction.name) @Inject(InventoryTransaction.name)
readonly inventoryTransactionModel: typeof InventoryTransaction; readonly inventoryTransactionModel: TenantModelProxy<
typeof InventoryTransaction
>;
@Inject(TenancyContext) @Inject(TenancyContext)
readonly tenancyContext: TenancyContext; readonly tenancyContext: TenancyContext;
@@ -141,7 +144,7 @@ export class InventoryItemDetailsRepository {
public async getInventoryItems( public async getInventoryItems(
itemsIds?: number[], itemsIds?: number[],
): Promise<ModelObject<Item>[]> { ): Promise<ModelObject<Item>[]> {
return this.itemModel.query().onBuild((q) => { return this.itemModel().query().onBuild((q) => {
q.where('type', 'inventory'); q.where('type', 'inventory');
if (!isEmpty(itemsIds)) { if (!isEmpty(itemsIds)) {
@@ -163,7 +166,7 @@ export class InventoryItemDetailsRepository {
.toDate(); .toDate();
// Opening inventory transactions. // Opening inventory transactions.
const openingTransactions = this.inventoryTransactionModel const openingTransactions = this.inventoryTransactionModel()
.query() .query()
.select('*') .select('*')
.select(raw("IF(`DIRECTION` = 'IN', `QUANTITY`, 0) as 'QUANTITY_IN'")) .select(raw("IF(`DIRECTION` = 'IN', `QUANTITY`, 0) as 'QUANTITY_IN'"))
@@ -188,8 +191,7 @@ export class InventoryItemDetailsRepository {
if (!isEmpty(filter.branchesIds)) { if (!isEmpty(filter.branchesIds)) {
openingTransactions.modify('filterByBranches', filter.branchesIds); openingTransactions.modify('filterByBranches', filter.branchesIds);
} }
const openingBalanceTransactions = await this.inventoryTransactionModel()
const openingBalanceTransactions = await this.inventoryTransactionModel
.query() .query()
.from(openingTransactions) .from(openingTransactions)
.select('itemId') .select('itemId')
@@ -214,7 +216,7 @@ export class InventoryItemDetailsRepository {
public async getItemInventoryTransactions( public async getItemInventoryTransactions(
filter: IInventoryDetailsQuery, filter: IInventoryDetailsQuery,
): Promise<ModelObject<InventoryTransaction>[]> { ): Promise<ModelObject<InventoryTransaction>[]> {
const inventoryTransactions = this.inventoryTransactionModel const inventoryTransactions = this.inventoryTransactionModel()
.query() .query()
.modify('filterDateRange', filter.fromDate, filter.toDate) .modify('filterDateRange', filter.fromDate, filter.toDate)
.orderBy('date', 'ASC') .orderBy('date', 'ASC')

View File

@@ -6,6 +6,7 @@ import { ModelObject } from 'objection';
import { Item } from '@/modules/Items/models/Item'; import { Item } from '@/modules/Items/models/Item';
import { transformToMap } from '@/utils/transform-to-key'; import { transformToMap } from '@/utils/transform-to-key';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT }) @Injectable({ scope: Scope.TRANSIENT })
export class InventoryValuationSheetRepository { export class InventoryValuationSheetRepository {
@@ -13,10 +14,12 @@ export class InventoryValuationSheetRepository {
private readonly tenancyContext: TenancyContext; private readonly tenancyContext: TenancyContext;
@Inject(InventoryCostLotTracker.name) @Inject(InventoryCostLotTracker.name)
private readonly inventoryCostLotTracker: typeof InventoryCostLotTracker; private readonly inventoryCostLotTracker: TenantModelProxy<
typeof InventoryCostLotTracker
>;
@Inject(Item.name) @Inject(Item.name)
private readonly itemModel: typeof Item; private readonly itemModel: TenantModelProxy<typeof Item>;
/** /**
* The filter. * The filter.
@@ -89,8 +92,10 @@ export class InventoryValuationSheetRepository {
* Retrieve the inventory items. * Retrieve the inventory items.
*/ */
async asyncItems() { async asyncItems() {
const inventoryItems = await this.itemModel.query().onBuild((q) => { const inventoryItems = await this.itemModel()
q.where('type', 'inventory'); .query()
.onBuild((q) => {
q.where('type', 'inventory');
if (this.filter.itemsIds.length > 0) { if (this.filter.itemsIds.length > 0) {
q.whereIn('id', this.filter.itemsIds); q.whereIn('id', this.filter.itemsIds);
@@ -121,13 +126,13 @@ export class InventoryValuationSheetRepository {
} }
}; };
// Retrieve the inventory cost `IN` transactions. // Retrieve the inventory cost `IN` transactions.
const INTransactions = await this.inventoryCostLotTracker const INTransactions = await this.inventoryCostLotTracker()
.query() .query()
.onBuild(commonQuery) .onBuild(commonQuery)
.where('direction', 'IN'); .where('direction', 'IN');
// Retrieve the inventory cost `OUT` transactions. // Retrieve the inventory cost `OUT` transactions.
const OUTTransactions = await this.inventoryCostLotTracker const OUTTransactions = await this.inventoryCostLotTracker()
.query() .query()
.onBuild(commonQuery) .onBuild(commonQuery)
.where('direction', 'OUT'); .where('direction', 'OUT');

View File

@@ -2,6 +2,7 @@ import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository'; import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
import { Contact } from '@/modules/Contacts/models/Contact'; import { Contact } from '@/modules/Contacts/models/Contact';
import { Ledger } from '@/modules/Ledger/Ledger'; import { Ledger } from '@/modules/Ledger/Ledger';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { transformToMap } from '@/utils/transform-to-key'; import { transformToMap } from '@/utils/transform-to-key';
import { Inject } from '@nestjs/common'; import { Inject } from '@nestjs/common';
@@ -15,10 +16,10 @@ export class JournalSheetRepository {
private accountRepository: AccountRepository; private accountRepository: AccountRepository;
@Inject(Contact.name) @Inject(Contact.name)
private contactModel: typeof Contact; private contactModel: TenantModelProxy<typeof Contact>;
@Inject(AccountTransaction.name) @Inject(AccountTransaction.name)
private accountTransaction: typeof AccountTransaction; private accountTransaction: TenantModelProxy<typeof AccountTransaction>;
@Inject(AccountTransaction.name) @Inject(AccountTransaction.name)
private accountTransactions: Array<ModelObject<AccountTransaction>>; private accountTransactions: Array<ModelObject<AccountTransaction>>;
@@ -88,7 +89,7 @@ export class JournalSheetRepository {
*/ */
async initAccountTransactions() { async initAccountTransactions() {
// Retrieve all journal transactions based on the given query. // Retrieve all journal transactions based on the given query.
const transactions = await this.accountTransaction const transactions = await this.accountTransaction()
.query() .query()
.onBuild((query) => { .onBuild((query) => {
if (this.filter.fromRange || this.filter.toRange) { if (this.filter.fromRange || this.filter.toRange) {
@@ -119,7 +120,7 @@ export class JournalSheetRepository {
* Initialize contacts. * Initialize contacts.
*/ */
async initContacts() { async initContacts() {
const contacts = await this.contactModel.query(); const contacts = await this.contactModel().query();
this.contacts = contacts; this.contacts = contacts;
this.contactsById = transformToMap(contacts, 'id'); this.contactsById = transformToMap(contacts, 'id');

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as R from 'ramda'; import * as R from 'ramda';
import { TOTAL_NODE_TYPES } from './constants'; import { TOTAL_NODE_TYPES } from './constants';
import { FinancialSheet } from '../../common/FinancialSheet'; import { FinancialSheet } from '../../common/FinancialSheet';

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import * as R from 'ramda'; import * as R from 'ramda';
import { get } from 'lodash'; import { get } from 'lodash';
import { ProfitLossSheetBase } from './ProfitLossSheetBase'; import { ProfitLossSheetBase } from './ProfitLossSheetBase';

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import { merge } from 'lodash'; import { merge } from 'lodash';
import * as R from 'ramda'; import * as R from 'ramda';
import { IProfitLossSheetQuery } from './ProfitLossSheet.types'; import { IProfitLossSheetQuery } from './ProfitLossSheet.types';

View File

@@ -1,9 +1,11 @@
// @ts-nocheck
import { Inject, Injectable, Scope } from '@nestjs/common'; import { Inject, Injectable, Scope } from '@nestjs/common';
import { ModelObject } from 'objection'; import { ModelObject } from 'objection';
import { castArray } from 'lodash'; import { castArray } from 'lodash';
import * as R from 'ramda'; import * as R from 'ramda';
import { Knex } from 'knex'; import { Knex } from 'knex';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import * as moment from 'moment';
import { transformToMapBy } from '@/utils/transform-to-map-by'; import { transformToMapBy } from '@/utils/transform-to-map-by';
import { ProfitLossSheetQuery } from './ProfitLossSheetQuery'; import { ProfitLossSheetQuery } from './ProfitLossSheetQuery';
import { Ledger } from '@/modules/Ledger/Ledger'; import { Ledger } from '@/modules/Ledger/Ledger';
@@ -13,16 +15,17 @@ import { Account } from '@/modules/Accounts/models/Account.model';
import { FinancialDatePeriods } from '../../common/FinancialDatePeriods'; import { FinancialDatePeriods } from '../../common/FinancialDatePeriods';
import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model'; import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT }) @Injectable({ scope: Scope.TRANSIENT })
export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)( export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)(
class {}, class {},
) { ) {
@Inject(Account.name) @Inject(Account.name)
public accountModel: typeof Account; public accountModel: TenantModelProxy<typeof Account>;
@Inject(AccountTransaction.name) @Inject(AccountTransaction.name)
public accountTransactionModel: typeof AccountTransaction; public accountTransactionModel: TenantModelProxy<typeof AccountTransaction>;
@Inject(TenancyContext) @Inject(TenancyContext)
public tenancyContext: TenancyContext; public tenancyContext: TenancyContext;
@@ -206,7 +209,7 @@ export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)(
* Initialize accounts graph. * Initialize accounts graph.
*/ */
private initAccountsGraph = async () => { private initAccountsGraph = async () => {
this.accountsGraph = this.accountModel.toDependencyGraph(this.accounts); this.accountsGraph = this.accountModel().toDependencyGraph(this.accounts);
}; };
// ---------------------------- // ----------------------------
@@ -217,8 +220,8 @@ export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)(
*/ */
private initAccountsTotalLedger = async (): Promise<void> => { private initAccountsTotalLedger = async (): Promise<void> => {
const totalByAccount = await this.accountsTotal( const totalByAccount = await this.accountsTotal(
this.query.fromDate, this.query.query.fromDate,
this.query.toDate, this.query.query.toDate,
); );
// Inject to the repository. // Inject to the repository.
this.totalAccountsLedger = Ledger.fromTransactions(totalByAccount); this.totalAccountsLedger = Ledger.fromTransactions(totalByAccount);
@@ -306,18 +309,23 @@ export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)(
/** /**
* Retrieve the opening balance transactions of the report. * Retrieve the opening balance transactions of the report.
*/ */
public accountsTotal = async (fromDate: Date, toDate: Date) => { public accountsTotal = async (
return this.accountTransactionModel.query().onBuild((query) => { fromDate: moment.MomentInput,
query.sum('credit as credit'); toDate: moment.MomentInput,
query.sum('debit as debit'); ) => {
query.groupBy('accountId'); return this.accountTransactionModel()
query.select(['accountId']); .query()
.onBuild((query) => {
query.sum('credit as credit');
query.sum('debit as debit');
query.groupBy('accountId');
query.select(['accountId']);
query.modify('filterDateRange', fromDate, toDate); query.modify('filterDateRange', fromDate, toDate);
query.withGraphFetched('account'); query.withGraphFetched('account');
this.commonFilterBranchesQuery(query); this.commonFilterBranchesQuery(query);
}); });
}; };
/** /**
@@ -331,18 +339,20 @@ export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)(
toDate: moment.MomentInput, toDate: moment.MomentInput,
datePeriodsType, datePeriodsType,
) => { ) => {
return this.accountTransactionModel.query().onBuild((query) => { return this.accountTransactionModel()
query.sum('credit as credit'); .query()
query.sum('debit as debit'); .onBuild((query) => {
query.groupBy('accountId'); query.sum('credit as credit');
query.select(['accountId']); query.sum('debit as debit');
query.groupBy('accountId');
query.select(['accountId']);
query.modify('groupByDateFormat', datePeriodsType); query.modify('groupByDateFormat', datePeriodsType);
query.modify('filterDateRange', fromDate, toDate); query.modify('filterDateRange', fromDate, toDate);
query.withGraphFetched('account'); query.withGraphFetched('account');
this.commonFilterBranchesQuery(query); this.commonFilterBranchesQuery(query);
}); });
}; };
/** /**
@@ -360,7 +370,7 @@ export class ProfitLossSheetRepository extends R.compose(FinancialDatePeriods)(
* @return {Promise<IAccount[]>} * @return {Promise<IAccount[]>}
*/ */
private getAccounts = () => { private getAccounts = () => {
return this.accountModel.query(); return this.accountModel().query();
}; };
/** /**

View File

@@ -9,17 +9,20 @@ import { Account } from '@/modules/Accounts/models/Account.model';
import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types'; import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types';
import { ModelObject } from 'objection'; import { ModelObject } from 'objection';
import { ACCOUNT_TYPE } from '@/constants/accounts'; import { ACCOUNT_TYPE } from '@/constants/accounts';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT }) @Injectable({ scope: Scope.TRANSIENT })
export class VendorBalanceSummaryRepository { export class VendorBalanceSummaryRepository {
@Inject(AccountTransaction.name) @Inject(AccountTransaction.name)
private readonly accountTransactionModel: typeof AccountTransaction; private readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>;
@Inject(Vendor.name) @Inject(Vendor.name)
private readonly vendorModel: typeof Vendor; private readonly vendorModel: TenantModelProxy<typeof Vendor>;
@Inject(Account.name) @Inject(Account.name)
private readonly accountModel: typeof Account; private readonly accountModel: TenantModelProxy<typeof Account>;
/** /**
* Filter. * Filter.
@@ -99,7 +102,7 @@ export class VendorBalanceSummaryRepository {
public async getVendors( public async getVendors(
vendorsIds?: number[], vendorsIds?: number[],
): Promise<ModelObject<Vendor>[]> { ): Promise<ModelObject<Vendor>[]> {
const vendorQuery = this.vendorModel.query().orderBy('displayName'); const vendorQuery = this.vendorModel().query().orderBy('displayName');
if (!isEmpty(vendorsIds)) { if (!isEmpty(vendorsIds)) {
vendorQuery.whereIn('id', vendorsIds); vendorQuery.whereIn('id', vendorsIds);
@@ -113,7 +116,7 @@ export class VendorBalanceSummaryRepository {
* @returns {Promise<IAccount[]>} * @returns {Promise<IAccount[]>}
*/ */
public async getPayableAccounts(): Promise<ModelObject<Account>[]> { public async getPayableAccounts(): Promise<ModelObject<Account>[]> {
return this.accountModel return this.accountModel()
.query() .query()
.where('accountType', ACCOUNT_TYPE.ACCOUNTS_PAYABLE); .where('accountType', ACCOUNT_TYPE.ACCOUNTS_PAYABLE);
} }
@@ -130,7 +133,7 @@ export class VendorBalanceSummaryRepository {
const payableAccountsIds = map(payableAccounts, 'id'); const payableAccountsIds = map(payableAccounts, 'id');
// Retrieve the customers transactions of A/R accounts. // Retrieve the customers transactions of A/R accounts.
const customersTranasctions = await this.accountTransactionModel const customersTranasctions = await this.accountTransactionModel()
.query() .query()
.onBuild((query) => { .onBuild((query) => {
query.whereIn('accountId', payableAccountsIds); query.whereIn('accountId', payableAccountsIds);

View File

@@ -31,7 +31,6 @@ export class DeleteItemCategoryService {
/** /**
* Deletes the given item category. * Deletes the given item category.
* @param {number} tenantId - Tenant id.
* @param {number} itemCategoryId - Item category id. * @param {number} itemCategoryId - Item category id.
* @return {Promise<void>} * @return {Promise<void>}
*/ */

View File

@@ -31,9 +31,12 @@ import { GetPaymentsReceivedService } from './queries/GetPaymentsReceived.servic
import { MailNotificationModule } from '../MailNotification/MailNotification.module'; import { MailNotificationModule } from '../MailNotification/MailNotification.module';
import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { MailModule } from '../Mail/Mail.module'; import { MailModule } from '../Mail/Mail.module';
import { SendPaymentReceivedMailProcessor } from './processors/PaymentReceivedMailNotification.processor';
import { BullModule } from '@nestjs/bull';
import { SEND_PAYMENT_RECEIVED_MAIL_QUEUE } from './constants';
@Module({ @Module({
controllers: [PaymentReceivesController,], controllers: [PaymentReceivesController],
providers: [ providers: [
PaymentReceivesApplication, PaymentReceivesApplication,
CreatePaymentReceivedService, CreatePaymentReceivedService,
@@ -53,8 +56,9 @@ import { MailModule } from '../Mail/Mail.module';
PaymentReceivedAutoIncrementSubscriber, PaymentReceivedAutoIncrementSubscriber,
PaymentReceivedGLEntriesSubscriber, PaymentReceivedGLEntriesSubscriber,
PaymentReceivedSyncInvoicesSubscriber, PaymentReceivedSyncInvoicesSubscriber,
GetPaymentsReceivedService,
SendPaymentReceiveMailNotification, SendPaymentReceiveMailNotification,
GetPaymentsReceivedService SendPaymentReceivedMailProcessor,
], ],
exports: [PaymentReceivesApplication, CreatePaymentReceivedService], exports: [PaymentReceivesApplication, CreatePaymentReceivedService],
imports: [ imports: [
@@ -68,7 +72,8 @@ import { MailModule } from '../Mail/Mail.module';
AccountsModule, AccountsModule,
MailNotificationModule, MailNotificationModule,
DynamicListModule, DynamicListModule,
MailModule MailModule,
BullModule.registerQueue({ name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE }),
], ],
}) })
export class PaymentsReceivedModule {} export class PaymentsReceivedModule {}

View File

@@ -1,7 +1,11 @@
import { Queue } from 'bullmq';
import { InjectQueue } from '@nestjs/bullmq';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { import {
DEFAULT_PAYMENT_MAIL_CONTENT, DEFAULT_PAYMENT_MAIL_CONTENT,
DEFAULT_PAYMENT_MAIL_SUBJECT, DEFAULT_PAYMENT_MAIL_SUBJECT,
SEND_PAYMENT_RECEIVED_MAIL_JOB,
SEND_PAYMENT_RECEIVED_MAIL_QUEUE,
} from '../constants'; } from '../constants';
import { transformPaymentReceivedToMailDataArgs } from '../utils'; import { transformPaymentReceivedToMailDataArgs } from '../utils';
import { EventEmitter2 } from '@nestjs/event-emitter'; import { EventEmitter2 } from '@nestjs/event-emitter';
@@ -10,13 +14,17 @@ import { ContactMailNotification } from '@/modules/MailNotification/ContactMailN
import { PaymentReceived } from '../models/PaymentReceived'; import { PaymentReceived } from '../models/PaymentReceived';
import { GetPaymentReceivedService } from '../queries/GetPaymentReceived.service'; import { GetPaymentReceivedService } from '../queries/GetPaymentReceived.service';
import { mergeAndValidateMailOptions } from '@/modules/MailNotification/utils'; import { mergeAndValidateMailOptions } from '@/modules/MailNotification/utils';
import { PaymentReceiveMailOptsDTO } from '../types/PaymentReceived.types'; import {
PaymentReceiveMailOptsDTO,
SendPaymentReceivedMailPayload,
} from '../types/PaymentReceived.types';
import { PaymentReceiveMailOpts } from '../types/PaymentReceived.types'; import { PaymentReceiveMailOpts } from '../types/PaymentReceived.types';
import { PaymentReceiveMailPresendEvent } from '../types/PaymentReceived.types'; import { PaymentReceiveMailPresendEvent } from '../types/PaymentReceived.types';
import { SendInvoiceMailDTO } from '@/modules/SaleInvoices/SaleInvoice.types'; import { SendInvoiceMailDTO } from '@/modules/SaleInvoices/SaleInvoice.types';
import { Mail } from '@/modules/Mail/Mail'; import { Mail } from '@/modules/Mail/Mail';
import { MailTransporter } from '@/modules/Mail/MailTransporter.service'; import { MailTransporter } from '@/modules/Mail/MailTransporter.service';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
@Injectable() @Injectable()
export class SendPaymentReceiveMailNotification { export class SendPaymentReceiveMailNotification {
@@ -25,6 +33,10 @@ export class SendPaymentReceiveMailNotification {
private readonly contactMailNotification: ContactMailNotification, private readonly contactMailNotification: ContactMailNotification,
private readonly eventEmitter: EventEmitter2, private readonly eventEmitter: EventEmitter2,
private readonly mailTransport: MailTransporter, private readonly mailTransport: MailTransporter,
private readonly tenancyContext: TenancyContext,
@InjectQueue(SEND_PAYMENT_RECEIVED_MAIL_QUEUE)
private readonly sendPaymentMailQueue: Queue,
@Inject(PaymentReceived.name) @Inject(PaymentReceived.name)
private readonly paymentReceiveModel: TenantModelProxy< private readonly paymentReceiveModel: TenantModelProxy<
@@ -40,19 +52,30 @@ export class SendPaymentReceiveMailNotification {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
public async triggerMail( public async triggerMail(
paymentReceiveId: number, paymentReceivedId: number,
messageDTO: PaymentReceiveMailOptsDTO, messageOptions: PaymentReceiveMailOptsDTO,
): Promise<void> { ): Promise<void> {
const payload = { const tenant = await this.tenancyContext.getTenant();
paymentReceiveId, const user = await this.tenancyContext.getSystemUser();
messageDTO,
};
// await this.agenda.now('payment-receive-mail-send', payload);
const organizationId = tenant.organizationId;
const userId = user.id;
const payload = {
paymentReceivedId,
messageOptions,
userId,
organizationId,
} as SendPaymentReceivedMailPayload;
await this.sendPaymentMailQueue.add(
SEND_PAYMENT_RECEIVED_MAIL_JOB,
payload,
);
// Triggers `onPaymentReceivePreMailSend` event. // Triggers `onPaymentReceivePreMailSend` event.
await this.eventEmitter.emitAsync(events.paymentReceive.onPreMailSend, { await this.eventEmitter.emitAsync(events.paymentReceive.onPreMailSend, {
paymentReceiveId, paymentReceivedId,
messageOptions: messageDTO, messageOptions,
} as PaymentReceiveMailPresendEvent); } as PaymentReceiveMailPresendEvent);
} }

View File

@@ -1,3 +1,7 @@
export const SEND_PAYMENT_RECEIVED_MAIL_QUEUE =
'SEND_PAYMENT_RECEIVED_MAIL_QUEUE';
export const SEND_PAYMENT_RECEIVED_MAIL_JOB = 'SEND_PAYMENT_RECEIVED_MAIL_JOB';
export const DEFAULT_PAYMENT_MAIL_SUBJECT = export const DEFAULT_PAYMENT_MAIL_SUBJECT =
'Payment Received for {Customer Name} from {Company Name}'; 'Payment Received for {Customer Name} from {Company Name}';
export const DEFAULT_PAYMENT_MAIL_CONTENT = ` export const DEFAULT_PAYMENT_MAIL_CONTENT = `

View File

@@ -0,0 +1,43 @@
import { JOB_REF, Process, Processor } from '@nestjs/bull';
import { Job } from 'bull';
import {
SEND_PAYMENT_RECEIVED_MAIL_JOB,
SEND_PAYMENT_RECEIVED_MAIL_QUEUE,
} from '../constants';
import { Inject, Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { ClsService } from 'nestjs-cls';
import { SendPaymentReceiveMailNotification } from '../commands/PaymentReceivedMailNotification';
import { SendPaymentReceivedMailPayload } from '../types/PaymentReceived.types';
@Processor({
name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE,
scope: Scope.REQUEST,
})
export class SendPaymentReceivedMailProcessor {
constructor(
private readonly sendPaymentReceivedMail: SendPaymentReceiveMailNotification,
private readonly clsService: ClsService,
@Inject(JOB_REF)
private readonly jobRef: Job<SendPaymentReceivedMailPayload>,
) {}
@Process(SEND_PAYMENT_RECEIVED_MAIL_JOB)
async handleSendMail() {
const { messageOptions, paymentReceivedId, organizationId, userId } =
this.jobRef.data;
this.clsService.set('organizationId', organizationId);
this.clsService.set('userId', userId);
try {
await this.sendPaymentReceivedMail.sendMail(
paymentReceivedId,
messageOptions,
);
} catch (error) {
console.log(error);
}
}
}

View File

@@ -2,7 +2,11 @@ import { AttachmentLinkDTO } from '@/modules/Attachments/Attachments.types';
import { Knex } from 'knex'; import { Knex } from 'knex';
import { PaymentReceived } from '../models/PaymentReceived'; import { PaymentReceived } from '../models/PaymentReceived';
import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types'; import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types';
import { CommonMailOptions, CommonMailOptionsDTO } from '@/modules/MailNotification/MailNotification.types'; import {
CommonMailOptions,
CommonMailOptionsDTO,
} from '@/modules/MailNotification/MailNotification.types';
import { TenantJobPayload } from '@/interfaces/Tenant';
export interface IPaymentReceivedCreateDTO { export interface IPaymentReceivedCreateDTO {
customerId: number; customerId: number;
@@ -148,7 +152,7 @@ export enum PaymentReceiveAction {
export interface PaymentReceiveMailOpts extends CommonMailOptions {} export interface PaymentReceiveMailOpts extends CommonMailOptions {}
export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {} export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {}
export interface PaymentReceiveMailPresendEvent { export interface PaymentReceiveMailPresendEvent {
paymentReceiveId: number; paymentReceivedId: number;
messageOptions: PaymentReceiveMailOptsDTO; messageOptions: PaymentReceiveMailOptsDTO;
} }
@@ -207,3 +211,8 @@ export interface PaymentReceivedPdfTemplateAttributes {
export interface IPaymentReceivedState { export interface IPaymentReceivedState {
defaultTemplateId: number; defaultTemplateId: number;
} }
export interface SendPaymentReceivedMailPayload extends TenantJobPayload {
paymentReceivedId: number;
messageOptions: PaymentReceiveMailOptsDTO;
}

View File

@@ -71,7 +71,9 @@ export class SaleReceiptMailNotification {
organizationId, organizationId,
} as SaleReceiptSendMailPayload; } as SaleReceiptSendMailPayload;
this.sendSaleReceiptMailProcess.add(SendSaleReceiptMailJob, { ...payload }); await this.sendSaleReceiptMailProcess.add(SendSaleReceiptMailJob, {
...payload,
});
// Triggers the event `onSaleReceiptPreMailSend`. // Triggers the event `onSaleReceiptPreMailSend`.
await this.eventEmitter.emitAsync(events.saleReceipt.onPreMailSend, { await this.eventEmitter.emitAsync(events.saleReceipt.onPreMailSend, {

View File

@@ -2,16 +2,22 @@ import { Process, Processor } from '@nestjs/bull';
import { Job } from 'bull'; import { Job } from 'bull';
import { SendSaleReceiptMailQueue } from '../constants'; import { SendSaleReceiptMailQueue } from '../constants';
import { SaleReceiptMailNotification } from '../commands/SaleReceiptMailNotification'; import { SaleReceiptMailNotification } from '../commands/SaleReceiptMailNotification';
import { SaleReceiptSendMailPayload } from '../types/SaleReceipts.types';
import { ClsService } from 'nestjs-cls';
@Processor(SendSaleReceiptMailQueue) @Processor(SendSaleReceiptMailQueue)
export class SendSaleReceiptMailProcess { export class SendSaleReceiptMailProcess {
constructor( constructor(
private readonly saleReceiptMailNotification: SaleReceiptMailNotification, private readonly saleReceiptMailNotification: SaleReceiptMailNotification,
private readonly clsService: ClsService,
) {} ) {}
@Process(SendSaleReceiptMailQueue) @Process(SendSaleReceiptMailQueue)
async handleSendMailJob(job: Job) { async handleSendMailJob(job: Job<SaleReceiptSendMailPayload>) {
const { messageOpts, saleReceiptId } = job.data; const { messageOpts, saleReceiptId, organizationId, userId } = job.data;
this.clsService.set('organizationId', organizationId);
this.clsService.set('userId', userId);
await this.saleReceiptMailNotification.sendMail(saleReceiptId, messageOpts); await this.saleReceiptMailNotification.sendMail(saleReceiptId, messageOpts);
} }