mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 23:00:34 +00:00
refactor: nestjs
This commit is contained in:
@@ -41,6 +41,8 @@ services:
|
|||||||
context: ./docker/redis
|
context: ./docker/redis
|
||||||
expose:
|
expose:
|
||||||
- "6379"
|
- "6379"
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
volumes:
|
volumes:
|
||||||
- redis:/data
|
- redis:/data
|
||||||
deploy:
|
deploy:
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"@bigcapital/pdf-templates": "*",
|
"@bigcapital/pdf-templates": "*",
|
||||||
"@bigcapital/utils": "*",
|
"@bigcapital/utils": "*",
|
||||||
"@nestjs/bull": "^10.2.1",
|
"@nestjs/bull": "^10.2.1",
|
||||||
"@nestjs/bullmq": "^10.2.1",
|
"@nestjs/bullmq": "^10.2.2",
|
||||||
"@nestjs/cache-manager": "^2.2.2",
|
"@nestjs/cache-manager": "^2.2.2",
|
||||||
"@nestjs/common": "^10.0.0",
|
"@nestjs/common": "^10.0.0",
|
||||||
"@nestjs/config": "^3.2.3",
|
"@nestjs/config": "^3.2.3",
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
"bluebird": "^3.7.2",
|
"bluebird": "^3.7.2",
|
||||||
"bull": "^4.16.3",
|
"bull": "^4.16.3",
|
||||||
"bullmq": "^5.21.1",
|
"bullmq": "^5.25.6",
|
||||||
"cache-manager": "^6.1.1",
|
"cache-manager": "^6.1.1",
|
||||||
"cache-manager-redis-store": "^3.0.1",
|
"cache-manager-redis-store": "^3.0.1",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
@@ -58,6 +58,7 @@
|
|||||||
"knex": "^3.1.0",
|
"knex": "^3.1.0",
|
||||||
"lamda": "^0.4.1",
|
"lamda": "^0.4.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"mathjs": "^9.4.0",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"mysql2": "^3.11.3",
|
"mysql2": "^3.11.3",
|
||||||
@@ -85,8 +86,7 @@
|
|||||||
"uuid": "^10.0.0",
|
"uuid": "^10.0.0",
|
||||||
"xlsx": "^0.18.5",
|
"xlsx": "^0.18.5",
|
||||||
"yup": "^0.28.1",
|
"yup": "^0.28.1",
|
||||||
"zod": "^3.23.8",
|
"zod": "^3.23.8"
|
||||||
"mathjs": "^9.4.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "^10.0.0",
|
"@nestjs/cli": "^10.0.0",
|
||||||
@@ -94,10 +94,10 @@
|
|||||||
"@nestjs/testing": "^10.0.0",
|
"@nestjs/testing": "^10.0.0",
|
||||||
"@types/express": "^5.0.0",
|
"@types/express": "^5.0.0",
|
||||||
"@types/jest": "^29.5.2",
|
"@types/jest": "^29.5.2",
|
||||||
|
"@types/mathjs": "^6.0.12",
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.3.1",
|
||||||
"@types/supertest": "^6.0.0",
|
"@types/supertest": "^6.0.0",
|
||||||
"@types/yup": "^0.29.13",
|
"@types/yup": "^0.29.13",
|
||||||
"@types/mathjs": "^6.0.12",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||||
"@typescript-eslint/parser": "^8.0.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"eslint": "^9.0.0",
|
"eslint": "^9.0.0",
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { ValidateDeleteBankAccountTransactions } from './commands/ValidateDelete
|
|||||||
import { BankTransactionGLEntriesService } from './commands/BankTransactionGLEntries';
|
import { BankTransactionGLEntriesService } from './commands/BankTransactionGLEntries';
|
||||||
import { BankingTransactionsApplication } from './BankingTransactionsApplication.service';
|
import { BankingTransactionsApplication } from './BankingTransactionsApplication.service';
|
||||||
import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementOrders.module';
|
import { AutoIncrementOrdersModule } from '../AutoIncrementOrders/AutoIncrementOrders.module';
|
||||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
|
||||||
import { DeleteCashflowTransaction } from './commands/DeleteCashflowTransaction.service';
|
import { DeleteCashflowTransaction } from './commands/DeleteCashflowTransaction.service';
|
||||||
import { CreateBankTransactionService } from './commands/CreateBankTransaction.service';
|
import { CreateBankTransactionService } from './commands/CreateBankTransaction.service';
|
||||||
import { GetBankTransactionService } from './queries/GetBankTransaction.service';
|
import { GetBankTransactionService } from './queries/GetBankTransaction.service';
|
||||||
@@ -24,6 +23,7 @@ import { BankingTransactionsController } from './BankingTransactions.controller'
|
|||||||
import { GetBankAccountsService } from './queries/GetBankAccounts.service';
|
import { GetBankAccountsService } from './queries/GetBankAccounts.service';
|
||||||
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
||||||
import { BankAccount } from './models/BankAccount';
|
import { BankAccount } from './models/BankAccount';
|
||||||
|
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||||
|
|
||||||
const models = [
|
const models = [
|
||||||
RegisterTenancyModel(UncategorizedBankTransaction),
|
RegisterTenancyModel(UncategorizedBankTransaction),
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { Controller, Get } from '@nestjs/common';
|
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||||
import { Headers, Query, Res } from '@nestjs/common';
|
import { Response } from 'express';
|
||||||
|
import { Controller, Get, Headers, Query, Res } from '@nestjs/common';
|
||||||
import { IGeneralLedgerSheetQuery } from './GeneralLedger.types';
|
import { IGeneralLedgerSheetQuery } from './GeneralLedger.types';
|
||||||
import { GeneralLedgerApplication } from './GeneralLedgerApplication';
|
import { GeneralLedgerApplication } from './GeneralLedgerApplication';
|
||||||
import { AcceptType } from '@/constants/accept-type';
|
import { AcceptType } from '@/constants/accept-type';
|
||||||
import { Response } from 'express';
|
import { PublicRoute } from '@/modules/Auth/Jwt.guard';
|
||||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
|
||||||
|
|
||||||
@Controller('/reports/general-ledger')
|
@Controller('/reports/general-ledger')
|
||||||
@ApiTags('reports')
|
@ApiTags('reports')
|
||||||
|
@PublicRoute()
|
||||||
export class GeneralLedgerController {
|
export class GeneralLedgerController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly generalLedgerApplication: GeneralLedgerApplication,
|
private readonly generalLedgerApplication: GeneralLedgerApplication,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export class GeneralLedgerSheet extends R.compose(FinancialSheetStructure)(
|
|||||||
constructor(
|
constructor(
|
||||||
query: IGeneralLedgerSheetQuery,
|
query: IGeneralLedgerSheetQuery,
|
||||||
repository: GeneralLedgerRepository,
|
repository: GeneralLedgerRepository,
|
||||||
i18n,
|
i18n: I18nService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import {
|
import { IGeneralLedgerSheetQuery } from './GeneralLedger.types';
|
||||||
IGeneralLedgerSheetQuery,
|
|
||||||
|
|
||||||
} from './GeneralLedger.types';
|
|
||||||
import { flatten, isEmpty, uniq } from 'lodash';
|
import { flatten, isEmpty, uniq } from 'lodash';
|
||||||
import { ModelObject } from 'objection';
|
import { ModelObject } from 'objection';
|
||||||
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 { Contact } from '@/modules/Contacts/models/Contact';
|
import { Contact } from '@/modules/Contacts/models/Contact';
|
||||||
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
|
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
|
||||||
import { Inject } from '@nestjs/common';
|
import { Inject, Injectable, Scope } from '@nestjs/common';
|
||||||
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 { 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';
|
||||||
|
|
||||||
|
@Injectable({ scope: Scope.TRANSIENT })
|
||||||
export class GeneralLedgerRepository {
|
export class GeneralLedgerRepository {
|
||||||
public filter: IGeneralLedgerSheetQuery;
|
public filter: IGeneralLedgerSheetQuery;
|
||||||
public accounts: Account[];
|
public accounts: Account[];
|
||||||
@@ -42,6 +40,12 @@ export class GeneralLedgerRepository {
|
|||||||
@Inject(AccountRepository)
|
@Inject(AccountRepository)
|
||||||
private readonly accountRepository: AccountRepository;
|
private readonly accountRepository: AccountRepository;
|
||||||
|
|
||||||
|
@Inject(AccountTransaction.name)
|
||||||
|
private readonly accountTransactionModel: typeof AccountTransaction;
|
||||||
|
|
||||||
|
@Inject(Contact.name)
|
||||||
|
private readonly contactModel: typeof Contact;
|
||||||
|
|
||||||
@Inject(TenancyContext)
|
@Inject(TenancyContext)
|
||||||
private readonly tenancyContext: TenancyContext;
|
private readonly tenancyContext: TenancyContext;
|
||||||
|
|
||||||
@@ -79,24 +83,21 @@ export class GeneralLedgerRepository {
|
|||||||
*/
|
*/
|
||||||
public async initAccounts() {
|
public async initAccounts() {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.accounts = await this.accountRepository
|
this.accounts = await this.accountRepository.all().orderBy('name', 'ASC');
|
||||||
.all()
|
|
||||||
.orderBy('name', 'ASC');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the accounts graph.
|
* Initialize the accounts graph.
|
||||||
*/
|
*/
|
||||||
public async initAccountsGraph() {
|
public async initAccountsGraph() {
|
||||||
this.accountsGraph =
|
this.accountsGraph = await this.accountRepository.getDependencyGraph();
|
||||||
await this.repositories.accountRepository.getDependencyGraph();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the contacts.
|
* Initialize the contacts.
|
||||||
*/
|
*/
|
||||||
public async initContacts() {
|
public async initContacts() {
|
||||||
this.contacts = await this.repositories.contactRepository.all();
|
this.contacts = await this.contactModel.query();
|
||||||
this.contactsById = transformToMap(this.contacts, 'id');
|
this.contactsById = transformToMap(this.contacts, 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,17 +105,23 @@ 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.repositories.transactionsRepository
|
this.transactions = await this.accountTransactionModel
|
||||||
.journal({
|
.query()
|
||||||
fromDate: this.filter.fromDate,
|
|
||||||
toDate: this.filter.toDate,
|
|
||||||
branchesIds: this.filter.branchesIds,
|
|
||||||
})
|
|
||||||
.orderBy('date', 'ASC')
|
|
||||||
.onBuild((query) => {
|
.onBuild((query) => {
|
||||||
|
query.modify(
|
||||||
|
'filterDateRange',
|
||||||
|
this.filter.fromDate,
|
||||||
|
this.filter.toDate,
|
||||||
|
);
|
||||||
|
if (!isEmpty(this.filter.branchesIds)) {
|
||||||
|
query.modify('filterByBranches', this.filter.branchesIds);
|
||||||
|
}
|
||||||
|
query.orderBy('date', 'ASC');
|
||||||
|
|
||||||
if (this.filter.accountsIds?.length > 0) {
|
if (this.filter.accountsIds?.length > 0) {
|
||||||
query.whereIn('accountId', this.accountNodesIncludeTransactions);
|
query.whereIn('accountId', this.accountNodesIncludeTransactions);
|
||||||
}
|
}
|
||||||
|
query.withGraphFetched('account');
|
||||||
});
|
});
|
||||||
// Transform array transactions to journal collection.
|
// Transform array transactions to journal collection.
|
||||||
this.transactionsLedger = Ledger.fromTransactions(this.transactions);
|
this.transactionsLedger = Ledger.fromTransactions(this.transactions);
|
||||||
@@ -124,17 +131,23 @@ export class GeneralLedgerRepository {
|
|||||||
* Initialize the G/L accounts opening balance.
|
* Initialize the G/L accounts opening balance.
|
||||||
*/
|
*/
|
||||||
public async initAccountsOpeningBalance() {
|
public async initAccountsOpeningBalance() {
|
||||||
// Retreive opening balance credit/debit sumation.
|
// Retrieves opening balance credit/debit sumation.
|
||||||
this.openingBalanceTransactions =
|
this.openingBalanceTransactions = await this.accountTransactionModel
|
||||||
await this.repositories.transactionsRepository.journal({
|
.query()
|
||||||
toDate: moment(this.filter.fromDate).subtract(1, 'day'),
|
.onBuild((query) => {
|
||||||
sumationCreditDebit: true,
|
const toDate = moment(this.filter.fromDate).subtract(1, 'day');
|
||||||
branchesIds: this.filter.branchesIds,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
query.modify('sumationCreditDebit');
|
||||||
|
query.modify('filterDateRange', null, toDate);
|
||||||
|
|
||||||
|
if (!isEmpty(this.filter.branchesIds)) {
|
||||||
|
query.modify('filterByBranches', this.filter.branchesIds);
|
||||||
|
}
|
||||||
|
query.withGraphFetched('account');
|
||||||
|
});
|
||||||
// Accounts opening transactions.
|
// Accounts opening transactions.
|
||||||
this.openingBalanceTransactionsLedger = Ledger.fromTransactions(
|
this.openingBalanceTransactionsLedger = Ledger.fromTransactions(
|
||||||
this.openingBalanceTransactions
|
this.openingBalanceTransactions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +162,7 @@ export class GeneralLedgerRepository {
|
|||||||
const childrenNodeIds = this.filter.accountsIds?.map(
|
const childrenNodeIds = this.filter.accountsIds?.map(
|
||||||
(accountId: number) => {
|
(accountId: number) => {
|
||||||
return this.accountsGraph.dependenciesOf(accountId);
|
return this.accountsGraph.dependenciesOf(accountId);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
const nodeIds = R.concat(this.filter.accountsIds, childrenNodeIds);
|
const nodeIds = R.concat(this.filter.accountsIds, childrenNodeIds);
|
||||||
|
|
||||||
@@ -175,7 +188,7 @@ export class GeneralLedgerRepository {
|
|||||||
this.accountNodeInclude = R.compose(
|
this.accountNodeInclude = R.compose(
|
||||||
R.uniq,
|
R.uniq,
|
||||||
R.flatten,
|
R.flatten,
|
||||||
R.concat(this.filter.accountsIds)
|
R.concat(this.filter.accountsIds),
|
||||||
)(nodeIds);
|
)(nodeIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as moment from 'moment';
|
import { I18nService } from 'nestjs-i18n';
|
||||||
import { GeneralLedgerMeta } from './GeneralLedgerMeta';
|
import { GeneralLedgerMeta } from './GeneralLedgerMeta';
|
||||||
import { GeneralLedgerRepository } from './GeneralLedgerRepository';
|
import { GeneralLedgerRepository } from './GeneralLedgerRepository';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
@@ -10,8 +10,6 @@ import {
|
|||||||
IGeneralLedgerMeta,
|
IGeneralLedgerMeta,
|
||||||
IGeneralLedgerSheetQuery,
|
IGeneralLedgerSheetQuery,
|
||||||
} from './GeneralLedger.types';
|
} from './GeneralLedger.types';
|
||||||
import { I18nService } from 'nestjs-i18n';
|
|
||||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GeneralLedgerService {
|
export class GeneralLedgerService {
|
||||||
@@ -52,8 +50,7 @@ export class GeneralLedgerService {
|
|||||||
const meta = await this.generalLedgerMeta.meta(filter);
|
const meta = await this.generalLedgerMeta.meta(filter);
|
||||||
|
|
||||||
// Triggers `onGeneralLedgerViewed` event.
|
// Triggers `onGeneralLedgerViewed` event.
|
||||||
await this.eventEmitter.emitAsync(events.reports.onGeneralLedgerViewed, {
|
await this.eventEmitter.emitAsync(events.reports.onGeneralLedgerViewed, {});
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: reportData,
|
data: reportData,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import * as moment from 'moment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the running balance.
|
* Calculate the running balance.
|
||||||
* @param {number} amount - Transaction amount.
|
* @param {number} amount - Transaction amount.
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export class SaleEstimatesApplication {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Deliver the given sale estimate.
|
* Deliver the given sale estimate.
|
||||||
* @param {number} saleEstimateId
|
* @param {number} saleEstimateId - Sale estimate id.
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public deliverSaleEstimate(saleEstimateId: number) {
|
public deliverSaleEstimate(saleEstimateId: number) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||||
import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module';
|
import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module';
|
||||||
import { TransformerInjectable } from '../Transformer/TransformerInjectable.service';
|
import { TransformerInjectable } from '../Transformer/TransformerInjectable.service';
|
||||||
@@ -33,7 +34,7 @@ import { ChromiumlyTenancyModule } from '../ChromiumlyTenancy/ChromiumlyTenancy.
|
|||||||
import { TemplateInjectableModule } from '../TemplateInjectable/TemplateInjectable.module';
|
import { TemplateInjectableModule } from '../TemplateInjectable/TemplateInjectable.module';
|
||||||
import { SaleEstimatePdfTemplate } from '../SaleInvoices/queries/SaleEstimatePdfTemplate.service';
|
import { SaleEstimatePdfTemplate } from '../SaleInvoices/queries/SaleEstimatePdfTemplate.service';
|
||||||
import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module';
|
import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module';
|
||||||
// import { SaleEstimateNotifyBySms } from './commands/SaleEstimateSmsNotify';
|
import { SendSaleEstimateMailQueue } from './types/SaleEstimates.types';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -43,7 +44,8 @@ import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module';
|
|||||||
MailModule,
|
MailModule,
|
||||||
ChromiumlyTenancyModule,
|
ChromiumlyTenancyModule,
|
||||||
TemplateInjectableModule,
|
TemplateInjectableModule,
|
||||||
PdfTemplatesModule
|
PdfTemplatesModule,
|
||||||
|
BullModule.registerQueue({ name: SendSaleEstimateMailQueue }),
|
||||||
],
|
],
|
||||||
controllers: [SaleEstimatesController],
|
controllers: [SaleEstimatesController],
|
||||||
providers: [
|
providers: [
|
||||||
@@ -73,7 +75,6 @@ import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module';
|
|||||||
SendSaleEstimateMail,
|
SendSaleEstimateMail,
|
||||||
GetSaleEstimatePdf,
|
GetSaleEstimatePdf,
|
||||||
SaleEstimatePdfTemplate
|
SaleEstimatePdfTemplate
|
||||||
// SaleEstimateNotifyBySms,
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class SaleEstimatesModule {}
|
export class SaleEstimatesModule {}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { InjectQueue } from '@nestjs/bullmq';
|
||||||
|
import { Queue } from 'bull';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { ContactMailNotification } from '@/modules/MailNotification/ContactMailNotification';
|
import { ContactMailNotification } from '@/modules/MailNotification/ContactMailNotification';
|
||||||
@@ -14,6 +16,8 @@ import { mergeAndValidateMailOptions } from '@/modules/MailNotification/utils';
|
|||||||
import {
|
import {
|
||||||
ISaleEstimateMailPresendEvent,
|
ISaleEstimateMailPresendEvent,
|
||||||
SaleEstimateMailOptionsDTO,
|
SaleEstimateMailOptionsDTO,
|
||||||
|
SendSaleEstimateMailJob,
|
||||||
|
SendSaleEstimateMailQueue,
|
||||||
} from '../types/SaleEstimates.types';
|
} from '../types/SaleEstimates.types';
|
||||||
import { SaleEstimateMailOptions } from '../types/SaleEstimates.types';
|
import { SaleEstimateMailOptions } from '../types/SaleEstimates.types';
|
||||||
import { Mail } from '@/modules/Mail/Mail';
|
import { Mail } from '@/modules/Mail/Mail';
|
||||||
@@ -38,6 +42,8 @@ export class SendSaleEstimateMail {
|
|||||||
|
|
||||||
@Inject(SaleEstimate.name)
|
@Inject(SaleEstimate.name)
|
||||||
private readonly saleEstimateModel: typeof SaleEstimate,
|
private readonly saleEstimateModel: typeof SaleEstimate,
|
||||||
|
@InjectQueue(SendSaleEstimateMailQueue)
|
||||||
|
private readonly sendEstimateMailQueue: Queue,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,7 +60,7 @@ export class SendSaleEstimateMail {
|
|||||||
saleEstimateId,
|
saleEstimateId,
|
||||||
messageOptions,
|
messageOptions,
|
||||||
};
|
};
|
||||||
// await this.agenda.now('sale-estimate-mail-send', payload);
|
await this.sendEstimateMailQueue.add(SendSaleEstimateMailJob, payload);
|
||||||
|
|
||||||
// Triggers `onSaleEstimatePreMailSend` event.
|
// Triggers `onSaleEstimatePreMailSend` event.
|
||||||
await this.eventPublisher.emitAsync(events.saleEstimate.onPreMailSend, {
|
await this.eventPublisher.emitAsync(events.saleEstimate.onPreMailSend, {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Process, Processor } from '@nestjs/bull';
|
||||||
|
import { Job } from 'bull';
|
||||||
|
import {
|
||||||
|
SendSaleEstimateMailJob,
|
||||||
|
SendSaleEstimateMailQueue,
|
||||||
|
} from '../types/SaleEstimates.types';
|
||||||
|
import { SendSaleEstimateMail } from '../commands/SendSaleEstimateMail';
|
||||||
|
|
||||||
|
@Processor(SendSaleEstimateMailQueue)
|
||||||
|
export class SendSaleEstimateMailProcess {
|
||||||
|
constructor(private readonly sendEstimateMailService: SendSaleEstimateMail) {}
|
||||||
|
|
||||||
|
@Process(SendSaleEstimateMailJob)
|
||||||
|
async handleSendMail(job: Job) {
|
||||||
|
const { saleEstimateId, messageOptions } = job.data;
|
||||||
|
|
||||||
|
await this.sendEstimateMailService.sendMail(saleEstimateId, messageOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,9 @@ import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/Dynam
|
|||||||
import { CommonMailOptionsDTO } from '@/modules/MailNotification/MailNotification.types';
|
import { CommonMailOptionsDTO } from '@/modules/MailNotification/MailNotification.types';
|
||||||
import { CommonMailOptions } from '@/modules/MailNotification/MailNotification.types';
|
import { CommonMailOptions } from '@/modules/MailNotification/MailNotification.types';
|
||||||
|
|
||||||
|
export const SendSaleEstimateMailQueue = 'SendSaleEstimateMailProcessor';
|
||||||
|
export const SendSaleEstimateMailJob = 'SendSaleEstimateMailProcess';
|
||||||
|
|
||||||
export interface ISaleEstimateDTO {
|
export interface ISaleEstimateDTO {
|
||||||
customerId: number;
|
customerId: number;
|
||||||
exchangeRate?: number;
|
exchangeRate?: number;
|
||||||
@@ -122,3 +125,8 @@ export interface ISaleEstimateMailPresendEvent {
|
|||||||
export interface ISaleEstimateState {
|
export interface ISaleEstimateState {
|
||||||
defaultTemplateId: number;
|
defaultTemplateId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISendSaleEstimateMailProcessData {
|
||||||
|
saleEstimateId: number;
|
||||||
|
messageOptions: SaleEstimateMailOptionsDTO;
|
||||||
|
}
|
||||||
|
|||||||
@@ -322,3 +322,9 @@ export interface InvoicePdfTemplateAttributes {
|
|||||||
export interface ISaleInvocieState {
|
export interface ISaleInvocieState {
|
||||||
defaultTemplateId: number;
|
defaultTemplateId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface SaleInvoiceSendMailData {
|
||||||
|
saleInvoiceId: number;
|
||||||
|
messageOptions: SendInvoiceMailDTO;
|
||||||
|
}
|
||||||
@@ -8,8 +8,6 @@ import { GetSaleInvoicesPayable } from './queries/GetSaleInvoicesPayable.service
|
|||||||
import { WriteoffSaleInvoice } from './commands/WriteoffSaleInvoice.service';
|
import { WriteoffSaleInvoice } from './commands/WriteoffSaleInvoice.service';
|
||||||
import { SaleInvoicePdf } from './queries/SaleInvoicePdf.service';
|
import { SaleInvoicePdf } from './queries/SaleInvoicePdf.service';
|
||||||
import { GetInvoicePaymentsService } from './queries/GetInvoicePayments.service';
|
import { GetInvoicePaymentsService } from './queries/GetInvoicePayments.service';
|
||||||
// import { SaleInvoiceNotifyBySms } from './SaleInvoiceNotifyBySms';
|
|
||||||
// import { SendInvoiceMailReminder } from './commands/SendSaleInvoiceMailReminder';
|
|
||||||
import { GetSaleInvoiceState } from './queries/GetSaleInvoiceState.service';
|
import { GetSaleInvoiceState } from './queries/GetSaleInvoiceState.service';
|
||||||
import { GetSaleInvoiceMailState } from './queries/GetSaleInvoiceMailState.service';
|
import { GetSaleInvoiceMailState } from './queries/GetSaleInvoiceMailState.service';
|
||||||
import {
|
import {
|
||||||
@@ -39,7 +37,6 @@ export class SaleInvoiceApplication {
|
|||||||
private getSaleInvoiceStateService: GetSaleInvoiceState,
|
private getSaleInvoiceStateService: GetSaleInvoiceState,
|
||||||
private sendSaleInvoiceMailService: SendSaleInvoiceMail,
|
private sendSaleInvoiceMailService: SendSaleInvoiceMail,
|
||||||
private getSaleInvoiceMailStateService: GetSaleInvoiceMailState,
|
private getSaleInvoiceMailStateService: GetSaleInvoiceMailState,
|
||||||
// private invoiceSms: SaleInvoiceNotifyBySms,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -191,57 +188,9 @@ export class SaleInvoiceApplication {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {number} saleInvoiceId
|
|
||||||
* @param {InvoiceNotificationType} invoiceNotificationType
|
|
||||||
*/
|
|
||||||
// public notifySaleInvoiceBySms = async (
|
|
||||||
// tenantId: number,
|
|
||||||
// saleInvoiceId: number,
|
|
||||||
// invoiceNotificationType: InvoiceNotificationType,
|
|
||||||
// ) => {
|
|
||||||
// return this.invoiceSms.notifyBySms(
|
|
||||||
// tenantId,
|
|
||||||
// saleInvoiceId,
|
|
||||||
// invoiceNotificationType,
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the SMS details of the given invoice.
|
|
||||||
* @param {number} tenantId - Tenant id.
|
|
||||||
* @param {number} saleInvoiceId - Sale invoice id.
|
|
||||||
*/
|
|
||||||
// public getSaleInvoiceSmsDetails = async (
|
|
||||||
// tenantId: number,
|
|
||||||
// saleInvoiceId: number,
|
|
||||||
// invoiceSmsDetailsDTO: ISaleInvoiceSmsDetailsDTO,
|
|
||||||
// ): Promise<ISaleInvoiceSmsDetails> => {
|
|
||||||
// return this.invoiceSms.smsDetails(
|
|
||||||
// tenantId,
|
|
||||||
// saleInvoiceId,
|
|
||||||
// invoiceSmsDetailsDTO,
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the metadata of invoice mail reminder.
|
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {number} saleInvoiceId
|
|
||||||
* @returns {}
|
|
||||||
*/
|
|
||||||
// public getSaleInvoiceMailReminder(tenantId: number, saleInvoiceId: number) {
|
|
||||||
// return this.sendInvoiceReminderService.getMailOption(
|
|
||||||
// tenantId,
|
|
||||||
// saleInvoiceId,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the default mail options of the given sale invoice.
|
* Retrieves the default mail options of the given sale invoice.
|
||||||
* @param {number} saleInvoiceid
|
* @param {number} saleInvoiceid - Sale invoice id.
|
||||||
* @returns {Promise<SaleInvoiceMailState>}
|
* @returns {Promise<SaleInvoiceMailState>}
|
||||||
*/
|
*/
|
||||||
public getSaleInvoiceMailState(
|
public getSaleInvoiceMailState(
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ import { InventoryCostModule } from '../InventoryCost/InventoryCost.module';
|
|||||||
import { SendSaleInvoiceMailCommon } from './commands/SendInvoiceInvoiceMailCommon.service';
|
import { SendSaleInvoiceMailCommon } from './commands/SendInvoiceInvoiceMailCommon.service';
|
||||||
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
||||||
import { MailNotificationModule } from '../MailNotification/MailNotification.module';
|
import { MailNotificationModule } from '../MailNotification/MailNotification.module';
|
||||||
|
import { SendSaleInvoiceMailProcessor } from './processors/SendSaleInvoiceMail.processor';
|
||||||
|
import { BullModule } from '@nestjs/bull';
|
||||||
|
import { SendSaleInvoiceQueue } from './constants';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -60,6 +63,7 @@ import { MailNotificationModule } from '../MailNotification/MailNotification.mod
|
|||||||
MailNotificationModule,
|
MailNotificationModule,
|
||||||
InventoryCostModule,
|
InventoryCostModule,
|
||||||
DynamicListModule,
|
DynamicListModule,
|
||||||
|
BullModule.registerQueue({ name: SendSaleInvoiceQueue }),
|
||||||
],
|
],
|
||||||
controllers: [SaleInvoicesController],
|
controllers: [SaleInvoicesController],
|
||||||
providers: [
|
providers: [
|
||||||
@@ -95,6 +99,7 @@ import { MailNotificationModule } from '../MailNotification/MailNotification.mod
|
|||||||
GetSaleInvoicesService,
|
GetSaleInvoicesService,
|
||||||
GetSaleInvoiceMailState,
|
GetSaleInvoiceMailState,
|
||||||
SendSaleInvoiceMailCommon,
|
SendSaleInvoiceMailCommon,
|
||||||
|
SendSaleInvoiceMailProcessor
|
||||||
],
|
],
|
||||||
exports: [GetSaleInvoice],
|
exports: [GetSaleInvoice],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -115,19 +115,16 @@ export class CreateSaleInvoice {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Transformes create DTO to model.
|
* Transformes create DTO to model.
|
||||||
* @param {number} tenantId -
|
|
||||||
* @param {ICustomer} customer -
|
* @param {ICustomer} customer -
|
||||||
* @param {ISaleInvoiceCreateDTO} saleInvoiceDTO -
|
* @param {ISaleInvoiceCreateDTO} saleInvoiceDTO -
|
||||||
*/
|
*/
|
||||||
private transformCreateDTOToModel = async (
|
private transformCreateDTOToModel = async (
|
||||||
customer: Customer,
|
customer: Customer,
|
||||||
saleInvoiceDTO: ISaleInvoiceCreateDTO,
|
saleInvoiceDTO: ISaleInvoiceCreateDTO,
|
||||||
// authorizedUser: SystemUser,
|
|
||||||
) => {
|
) => {
|
||||||
return this.transformerDTO.transformDTOToModel(
|
return this.transformerDTO.transformDTOToModel(
|
||||||
customer,
|
customer,
|
||||||
saleInvoiceDTO,
|
saleInvoiceDTO,
|
||||||
// authorizedUser,
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { Queue } from 'bullmq';
|
||||||
|
import { InjectQueue } from '@nestjs/bullmq';
|
||||||
import { SaleInvoicePdf } from '../queries/SaleInvoicePdf.service';
|
import { SaleInvoicePdf } from '../queries/SaleInvoicePdf.service';
|
||||||
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon.service';
|
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon.service';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { events } from '@/common/events/events';
|
import { events } from '@/common/events/events';
|
||||||
import { mergeAndValidateMailOptions } from '@/modules/MailNotification/utils';
|
import { mergeAndValidateMailOptions } from '@/modules/MailNotification/utils';
|
||||||
import { SaleInvoiceMailOptions, SendInvoiceMailDTO } from '../SaleInvoice.types';
|
import {
|
||||||
|
SaleInvoiceMailOptions,
|
||||||
|
SendInvoiceMailDTO,
|
||||||
|
} from '../SaleInvoice.types';
|
||||||
import { ISaleInvoiceMailSend } from '../SaleInvoice.types';
|
import { ISaleInvoiceMailSend } from '../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 { SendSaleInvoiceMailJob, SendSaleInvoiceQueue } from '../constants';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SendSaleInvoiceMail {
|
export class SendSaleInvoiceMail {
|
||||||
@@ -22,13 +28,13 @@ export class SendSaleInvoiceMail {
|
|||||||
private readonly invoiceMail: SendSaleInvoiceMailCommon,
|
private readonly invoiceMail: SendSaleInvoiceMailCommon,
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
private readonly mailTransporter: MailTransporter,
|
private readonly mailTransporter: MailTransporter,
|
||||||
|
@InjectQueue(SendSaleInvoiceQueue) private readonly sendInvoiceQueue: Queue,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the invoice mail of the given sale invoice.
|
* Sends the invoice mail of the given sale invoice.
|
||||||
* @param {number} tenantId
|
* @param {number} saleInvoiceId - Sale invoice id.
|
||||||
* @param {number} saleInvoiceId
|
* @param {SendInvoiceMailDTO} messageDTO - Message DTO.
|
||||||
* @param {SendInvoiceMailDTO} messageDTO
|
|
||||||
*/
|
*/
|
||||||
public async triggerMail(
|
public async triggerMail(
|
||||||
saleInvoiceId: number,
|
saleInvoiceId: number,
|
||||||
@@ -38,8 +44,7 @@ export class SendSaleInvoiceMail {
|
|||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
messageOptions,
|
messageOptions,
|
||||||
};
|
};
|
||||||
// await this.agenda.now('sale-invoice-mail-send', payload);
|
await this.sendInvoiceQueue.add(SendSaleInvoiceMailJob, payload);
|
||||||
|
|
||||||
// Triggers the event `onSaleInvoicePreMailSend`.
|
// Triggers the event `onSaleInvoicePreMailSend`.
|
||||||
await this.eventEmitter.emitAsync(events.saleInvoice.onPreMailSend, {
|
await this.eventEmitter.emitAsync(events.saleInvoice.onPreMailSend, {
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
// import config from '@/config';
|
// import config from '@/config';
|
||||||
|
|
||||||
|
export const SendSaleInvoiceQueue = 'SendSaleInvoiceQueue';
|
||||||
|
export const SendSaleInvoiceMailJob = 'SendSaleInvoiceMailJob';
|
||||||
|
|
||||||
const BASE_URL = 'http://localhost:3000';
|
const BASE_URL = 'http://localhost:3000';
|
||||||
|
|
||||||
export const DEFAULT_INVOICE_MAIL_SUBJECT =
|
export const DEFAULT_INVOICE_MAIL_SUBJECT =
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { JOB_REF, Process, Processor } from '@nestjs/bull';
|
||||||
|
import { Job } from 'bull';
|
||||||
|
import { SendSaleInvoiceMailJob, SendSaleInvoiceQueue } from '../constants';
|
||||||
|
import { SendSaleInvoiceMail } from '../commands/SendSaleInvoiceMail';
|
||||||
|
import { Inject, Scope } from '@nestjs/common';
|
||||||
|
import { REQUEST } from '@nestjs/core';
|
||||||
|
import { UseCls } from 'nestjs-cls';
|
||||||
|
|
||||||
|
@Processor({
|
||||||
|
name: SendSaleInvoiceQueue,
|
||||||
|
scope: Scope.REQUEST,
|
||||||
|
})
|
||||||
|
export class SendSaleInvoiceMailProcessor {
|
||||||
|
constructor(
|
||||||
|
private readonly sendSaleInvoiceMail: SendSaleInvoiceMail,
|
||||||
|
@Inject(REQUEST) private readonly request: Request,
|
||||||
|
@Inject(JOB_REF) private readonly jobRef: Job,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Process(SendSaleInvoiceMailJob)
|
||||||
|
async handleSendInvoice() {
|
||||||
|
const { messageOptions, saleInvoiceId } = this.jobRef.data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.sendSaleInvoiceMail.sendMail(saleInvoiceId, messageOptions);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
ISaleReceiptState,
|
ISaleReceiptState,
|
||||||
ISalesReceiptsFilter,
|
ISalesReceiptsFilter,
|
||||||
SaleReceiptMailOpts,
|
SaleReceiptMailOpts,
|
||||||
|
SaleReceiptMailOptsDTO,
|
||||||
} from './types/SaleReceipts.types';
|
} from './types/SaleReceipts.types';
|
||||||
import { GetSaleReceiptsService } from './queries/GetSaleReceipts.service';
|
import { GetSaleReceiptsService } from './queries/GetSaleReceipts.service';
|
||||||
import { SaleReceipt } from './models/SaleReceipt';
|
import { SaleReceipt } from './models/SaleReceipt';
|
||||||
@@ -29,7 +30,6 @@ export class SaleReceiptApplication {
|
|||||||
private getSaleReceiptsService: GetSaleReceiptsService,
|
private getSaleReceiptsService: GetSaleReceiptsService,
|
||||||
private closeSaleReceiptService: CloseSaleReceipt,
|
private closeSaleReceiptService: CloseSaleReceipt,
|
||||||
private getSaleReceiptPdfService: SaleReceiptsPdfService,
|
private getSaleReceiptPdfService: SaleReceiptsPdfService,
|
||||||
// private saleReceiptNotifyBySmsService: SaleReceiptNotifyBySms,
|
|
||||||
private getSaleReceiptStateService: GetSaleReceiptState,
|
private getSaleReceiptStateService: GetSaleReceiptState,
|
||||||
private saleReceiptNotifyByMailService: SaleReceiptMailNotification,
|
private saleReceiptNotifyByMailService: SaleReceiptMailNotification,
|
||||||
) {}
|
) {}
|
||||||
@@ -147,16 +147,15 @@ export class SaleReceiptApplication {
|
|||||||
* @param {SaleReceiptMailOptsDTO} messageOpts
|
* @param {SaleReceiptMailOptsDTO} messageOpts
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
// public sendSaleReceiptMail(
|
public sendSaleReceiptMail(
|
||||||
// saleReceiptId: number,
|
saleReceiptId: number,
|
||||||
// messageOpts: SaleReceiptMailOptsDTO,
|
messageOpts: SaleReceiptMailOptsDTO,
|
||||||
// ): Promise<void> {
|
): Promise<void> {
|
||||||
// return this.saleReceiptNotifyByMailService.triggerMail(
|
return this.saleReceiptNotifyByMailService.triggerMail(
|
||||||
// tenantId,
|
saleReceiptId,
|
||||||
// saleReceiptId,
|
messageOpts,
|
||||||
// messageOpts,
|
);
|
||||||
// );
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the default mail options of the given sale receipt.
|
* Retrieves the default mail options of the given sale receipt.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
import { BullModule } from '@nestjs/bull';
|
||||||
import { SaleReceiptApplication } from './SaleReceiptApplication.service';
|
import { SaleReceiptApplication } from './SaleReceiptApplication.service';
|
||||||
import { CreateSaleReceipt } from './commands/CreateSaleReceipt.service';
|
import { CreateSaleReceipt } from './commands/CreateSaleReceipt.service';
|
||||||
import { EditSaleReceipt } from './commands/EditSaleReceipt.service';
|
import { EditSaleReceipt } from './commands/EditSaleReceipt.service';
|
||||||
@@ -30,8 +31,10 @@ import { SaleReceiptMailNotification } from './commands/SaleReceiptMailNotificat
|
|||||||
import { SaleReceiptInventoryTransactions } from './inventory/SaleReceiptInventoryTransactions';
|
import { SaleReceiptInventoryTransactions } from './inventory/SaleReceiptInventoryTransactions';
|
||||||
import { InventoryCostModule } from '../InventoryCost/InventoryCost.module';
|
import { InventoryCostModule } from '../InventoryCost/InventoryCost.module';
|
||||||
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
import { DynamicListModule } from '../DynamicListing/DynamicList.module';
|
||||||
import { MailModule } from '../Mail/Mail.module';
|
|
||||||
import { MailNotificationModule } from '../MailNotification/MailNotification.module';
|
import { MailNotificationModule } from '../MailNotification/MailNotification.module';
|
||||||
|
import { SendSaleReceiptMailProcess } from './processes/SendSaleReceiptMail.process';
|
||||||
|
import { MailModule } from '../Mail/Mail.module';
|
||||||
|
import { SendSaleReceiptMailQueue } from './constants';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
controllers: [SaleReceiptsController],
|
controllers: [SaleReceiptsController],
|
||||||
@@ -48,7 +51,8 @@ import { MailNotificationModule } from '../MailNotification/MailNotification.mod
|
|||||||
InventoryCostModule,
|
InventoryCostModule,
|
||||||
DynamicListModule,
|
DynamicListModule,
|
||||||
MailModule,
|
MailModule,
|
||||||
MailNotificationModule
|
MailNotificationModule,
|
||||||
|
BullModule.registerQueue({ name: SendSaleReceiptMailQueue }),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
TenancyContext,
|
TenancyContext,
|
||||||
@@ -70,6 +74,7 @@ import { MailNotificationModule } from '../MailNotification/MailNotification.mod
|
|||||||
SaleReceiptMailNotification,
|
SaleReceiptMailNotification,
|
||||||
SaleReceiptInventoryTransactions,
|
SaleReceiptInventoryTransactions,
|
||||||
SaleReceiptInventoryTransactionsSubscriber,
|
SaleReceiptInventoryTransactionsSubscriber,
|
||||||
|
SendSaleReceiptMailProcess,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class SaleReceiptsModule {}
|
export class SaleReceiptsModule {}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
import { InjectQueue } from '@nestjs/bull';
|
||||||
|
import { Queue } from 'bullmq';
|
||||||
import {
|
import {
|
||||||
DEFAULT_RECEIPT_MAIL_CONTENT,
|
DEFAULT_RECEIPT_MAIL_CONTENT,
|
||||||
DEFAULT_RECEIPT_MAIL_SUBJECT,
|
DEFAULT_RECEIPT_MAIL_SUBJECT,
|
||||||
|
SendSaleReceiptMailJob,
|
||||||
|
SendSaleReceiptMailQueue,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { mergeAndValidateMailOptions } from '@/modules/MailNotification/utils';
|
import { mergeAndValidateMailOptions } from '@/modules/MailNotification/utils';
|
||||||
import { transformReceiptToMailDataArgs } from '../utils';
|
import { transformReceiptToMailDataArgs } from '../utils';
|
||||||
@@ -36,14 +40,16 @@ export class SaleReceiptMailNotification {
|
|||||||
private readonly mailTransporter: MailTransporter,
|
private readonly mailTransporter: MailTransporter,
|
||||||
|
|
||||||
@Inject(SaleReceipt.name)
|
@Inject(SaleReceipt.name)
|
||||||
private readonly saleReceiptModel: typeof SaleReceipt
|
private readonly saleReceiptModel: typeof SaleReceipt,
|
||||||
|
|
||||||
|
@InjectQueue(SendSaleReceiptMailQueue)
|
||||||
|
private readonly sendSaleReceiptMailProcess: Queue,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the receipt mail of the given sale receipt.
|
* Sends the receipt mail of the given sale receipt.
|
||||||
* @param {number} tenantId
|
* @param {number} saleReceiptId - Sale receipt id.
|
||||||
* @param {number} saleReceiptId
|
* @param {SaleReceiptMailOptsDTO} messageDTO - Message DTOs.
|
||||||
* @param {SaleReceiptMailOptsDTO} messageDTO
|
|
||||||
*/
|
*/
|
||||||
public async triggerMail(
|
public async triggerMail(
|
||||||
saleReceiptId: number,
|
saleReceiptId: number,
|
||||||
@@ -53,7 +59,7 @@ export class SaleReceiptMailNotification {
|
|||||||
saleReceiptId,
|
saleReceiptId,
|
||||||
messageOpts: messageOptions,
|
messageOpts: messageOptions,
|
||||||
};
|
};
|
||||||
// await this.agenda.now('sale-receipt-mail-send', payload);
|
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, {
|
||||||
@@ -70,7 +76,8 @@ export class SaleReceiptMailNotification {
|
|||||||
public async getMailOptions(
|
public async getMailOptions(
|
||||||
saleReceiptId: number,
|
saleReceiptId: number,
|
||||||
): Promise<SaleReceiptMailOpts> {
|
): Promise<SaleReceiptMailOpts> {
|
||||||
const saleReceipt = await this.saleReceiptModel.query()
|
const saleReceipt = await this.saleReceiptModel
|
||||||
|
.query()
|
||||||
.findById(saleReceiptId)
|
.findById(saleReceiptId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ Amount : <strong>{Receipt Amount}</strong></br />
|
|||||||
</p>
|
</p>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const SendSaleReceiptMailQueue = 'SendSaleReceiptMailQueue';
|
||||||
|
export const SendSaleReceiptMailJob = 'SendSaleReceiptMailJob';
|
||||||
|
|
||||||
export const ERRORS = {
|
export const ERRORS = {
|
||||||
SALE_RECEIPT_NOT_FOUND: 'SALE_RECEIPT_NOT_FOUND',
|
SALE_RECEIPT_NOT_FOUND: 'SALE_RECEIPT_NOT_FOUND',
|
||||||
DEPOSIT_ACCOUNT_NOT_FOUND: 'DEPOSIT_ACCOUNT_NOT_FOUND',
|
DEPOSIT_ACCOUNT_NOT_FOUND: 'DEPOSIT_ACCOUNT_NOT_FOUND',
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Process, Processor } from '@nestjs/bull';
|
||||||
|
import { Job } from 'bull';
|
||||||
|
import { SendSaleReceiptMailQueue } from '../constants';
|
||||||
|
import { SaleReceiptMailNotification } from '../commands/SaleReceiptMailNotification';
|
||||||
|
|
||||||
|
@Processor(SendSaleReceiptMailQueue)
|
||||||
|
export class SendSaleReceiptMailProcess {
|
||||||
|
constructor(
|
||||||
|
private readonly saleReceiptMailNotification: SaleReceiptMailNotification,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Process(SendSaleReceiptMailQueue)
|
||||||
|
async handleSendMailJob(job: Job) {
|
||||||
|
const { messageOpts, saleReceiptId } = job.data;
|
||||||
|
|
||||||
|
await this.saleReceiptMailNotification.sendMail(saleReceiptId, messageOpts);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
pnpm-lock.yaml
generated
4
pnpm-lock.yaml
generated
@@ -497,7 +497,7 @@ importers:
|
|||||||
specifier: ^10.2.1
|
specifier: ^10.2.1
|
||||||
version: 10.2.2(@nestjs/common@10.4.7)(@nestjs/core@10.4.7)(bull@4.16.4)
|
version: 10.2.2(@nestjs/common@10.4.7)(@nestjs/core@10.4.7)(bull@4.16.4)
|
||||||
'@nestjs/bullmq':
|
'@nestjs/bullmq':
|
||||||
specifier: ^10.2.1
|
specifier: ^10.2.2
|
||||||
version: 10.2.2(@nestjs/common@10.4.7)(@nestjs/core@10.4.7)(bullmq@5.25.6)
|
version: 10.2.2(@nestjs/common@10.4.7)(@nestjs/core@10.4.7)(bullmq@5.25.6)
|
||||||
'@nestjs/cache-manager':
|
'@nestjs/cache-manager':
|
||||||
specifier: ^2.2.2
|
specifier: ^2.2.2
|
||||||
@@ -557,7 +557,7 @@ importers:
|
|||||||
specifier: ^4.16.3
|
specifier: ^4.16.3
|
||||||
version: 4.16.4
|
version: 4.16.4
|
||||||
bullmq:
|
bullmq:
|
||||||
specifier: ^5.21.1
|
specifier: ^5.25.6
|
||||||
version: 5.25.6
|
version: 5.25.6
|
||||||
cache-manager:
|
cache-manager:
|
||||||
specifier: ^6.1.1
|
specifier: ^6.1.1
|
||||||
|
|||||||
Reference in New Issue
Block a user