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