update: invoice processor and fix bug
This commit is contained in:
@@ -11,5 +11,5 @@ export const INVOICE = Object.freeze({
|
||||
FINE_PERCENTAGE: 0.01, // 1% of the total price
|
||||
MAX_DAYS_AFTER_OVERDUE: 10,
|
||||
DUEDATE: 7,
|
||||
DAYS_BEFORE_OVERDUE: 6,
|
||||
DAYS_BEFORE_OVERDUE: 3,
|
||||
});
|
||||
|
||||
@@ -62,7 +62,8 @@ export class InvoicesService {
|
||||
const totalPrice = invoiceItems.reduce((sum, item) => new Decimal(item.totalPrice).add(sum), new Decimal(0));
|
||||
const tax = totalPrice.mul(0.1);
|
||||
|
||||
const dueDate = dayjs().add(INVOICE.DUEDATE, "day").toDate();
|
||||
// const dueDate = dayjs().add(INVOICE.DUEDATE, "day").toDate();
|
||||
const dueDate = dayjs().add(1, "minute").toDate();
|
||||
|
||||
const invoice = queryRunner.manager.create(Invoice, {
|
||||
user: { id: createDto.userId },
|
||||
@@ -90,13 +91,12 @@ export class InvoicesService {
|
||||
},
|
||||
queryRunner,
|
||||
);
|
||||
//TODO:remove the test delay
|
||||
await this.invoiceQueue.add(
|
||||
INVOICE.INVOICE_REMINDER_JOB_NAME,
|
||||
{ invoiceId: invoice.id },
|
||||
{
|
||||
// delay: dayjs(invoice.dueDate).subtract(INVOICE.DAYS_BEFORE_OVERDUE, "day").diff(dayjs()),
|
||||
delay: 900000, // 15 minutes in milliseconds
|
||||
delay: dayjs(invoice.dueDate).subtract(INVOICE.DAYS_BEFORE_OVERDUE, "day").diff(dayjs()),
|
||||
// delay: 1.5 * 60 * 1000, // 5 minutes in milliseconds
|
||||
attempts: INVOICE.INVOICE_REMINDER_JOB_ATTEMPTS,
|
||||
backoff: INVOICE.INVOICE_REMINDER_JOB_BACKOFF,
|
||||
},
|
||||
@@ -126,7 +126,7 @@ export class InvoicesService {
|
||||
|
||||
if (invoice.status === InvoiceStatus.WAIT_PAYMENT) throw new BadRequestException(InvoiceMessage.ALREADY_APPROVED);
|
||||
if (invoice.status === InvoiceStatus.PAID) throw new BadRequestException(InvoiceMessage.INVOICE_ALREADY_PAID);
|
||||
if (dayjs().isAfter(invoice.dueDate)) {
|
||||
if (dayjs().isAfter(dayjs(invoice.dueDate).add(INVOICE.MAX_DAYS_AFTER_OVERDUE, "day"))) {
|
||||
invoice.status = InvoiceStatus.EXPIRED;
|
||||
await this.invoiceRepository.save(invoice);
|
||||
throw new BadRequestException(InvoiceMessage.INVOICE_IS_OVERDUE);
|
||||
@@ -177,7 +177,13 @@ export class InvoicesService {
|
||||
|
||||
if (invoice.status === InvoiceStatus.WAIT_PAYMENT) throw new BadRequestException(InvoiceMessage.ALREADY_APPROVED);
|
||||
if (invoice.status === InvoiceStatus.PAID) throw new BadRequestException(InvoiceMessage.INVOICE_ALREADY_PAID);
|
||||
if (dayjs().isAfter(invoice.dueDate)) throw new BadRequestException(InvoiceMessage.INVOICE_IS_OVERDUE);
|
||||
//
|
||||
if (dayjs().isAfter(dayjs(invoice.dueDate).add(INVOICE.MAX_DAYS_AFTER_OVERDUE, "day"))) {
|
||||
invoice.status = InvoiceStatus.EXPIRED;
|
||||
await this.invoiceRepository.save(invoice);
|
||||
throw new BadRequestException(InvoiceMessage.INVOICE_IS_OVERDUE);
|
||||
}
|
||||
//
|
||||
if (invoice.status !== InvoiceStatus.PENDING) throw new BadRequestException(InvoiceMessage.INVOICE_CAN_NOT_APPROVED);
|
||||
|
||||
invoice.status = InvoiceStatus.WAIT_PAYMENT;
|
||||
@@ -256,8 +262,7 @@ export class InvoicesService {
|
||||
INVOICE.INVOICE_REMINDER_JOB_NAME,
|
||||
{ invoiceId: invoice.id },
|
||||
{
|
||||
// delay: dayjs(invoice.dueDate).subtract(INVOICE.DAYS_BEFORE_OVERDUE, "day").diff(dayjs()),
|
||||
delay: 900000, // 15 minutes in milliseconds
|
||||
delay: dayjs(invoice.dueDate).subtract(INVOICE.DAYS_BEFORE_OVERDUE, "day").diff(dayjs()),
|
||||
attempts: INVOICE.INVOICE_REMINDER_JOB_ATTEMPTS,
|
||||
backoff: INVOICE.INVOICE_REMINDER_JOB_BACKOFF,
|
||||
repeat: { every: 300000 },
|
||||
|
||||
@@ -8,6 +8,7 @@ import { DataSource, QueryRunner } from "typeorm";
|
||||
|
||||
import { WorkerProcessor } from "../../../common/queues/worker.processor";
|
||||
import { NotificationsService } from "../../notifications/providers/notifications.service";
|
||||
import { SubscriptionStatus } from "../../subscriptions/enums/subscription-status.enum";
|
||||
import { INVOICE } from "../constants";
|
||||
import { Invoice } from "../entities/invoice.entity";
|
||||
import { InvoiceStatus } from "../enums/invoice-status.enum";
|
||||
@@ -77,7 +78,7 @@ export class InvoiceProcessor extends WorkerProcessor {
|
||||
private async fetchInvoice(invoiceId: string, queryRunner: QueryRunner) {
|
||||
const invoice = await queryRunner.manager.findOne(Invoice, {
|
||||
where: { id: invoiceId },
|
||||
relations: { user: true },
|
||||
relations: { user: true, items: { subscriptionPlan: true } },
|
||||
});
|
||||
|
||||
if (!invoice) throw new Error(`Invoice not found: ${invoiceId}`);
|
||||
@@ -86,15 +87,34 @@ export class InvoiceProcessor extends WorkerProcessor {
|
||||
//********************************** */
|
||||
|
||||
private isInvoiceOverdueForCancellation(invoice: Invoice): boolean {
|
||||
const fiveDaysAfterDueDate = dayjs(invoice.dueDate).add(INVOICE.MAX_DAYS_AFTER_OVERDUE, "day");
|
||||
return dayjs().isAfter(fiveDaysAfterDueDate);
|
||||
const tenDaysAfterDueDate = dayjs(invoice.dueDate).add(INVOICE.MAX_DAYS_AFTER_OVERDUE, "day");
|
||||
return dayjs().isAfter(tenDaysAfterDueDate);
|
||||
}
|
||||
//********************************** */
|
||||
|
||||
private async cancelOverdueInvoice(invoice: Invoice, queryRunner: QueryRunner) {
|
||||
invoice.status = InvoiceStatus.CANCELLED;
|
||||
await queryRunner.manager.save(Invoice, invoice);
|
||||
this.logger.log(`Invoice ${invoice.id} has been cancelled as it is more than 7 days overdue.`);
|
||||
if (invoice.items[0]?.subscriptionPlan) {
|
||||
this.logger.log(
|
||||
`Invoice ${invoice.id} has been cancelled as it is more than 10 days overdue. Subscription Plan ${invoice.items[0].subscriptionPlan.id} has been cancelled.`,
|
||||
);
|
||||
const userSubscription = invoice.items[0].subscriptionPlan;
|
||||
userSubscription.status = SubscriptionStatus.INACTIVE;
|
||||
|
||||
await queryRunner.manager.save(userSubscription);
|
||||
|
||||
// await this.notificationService.createSubscriptionPlanCancelledNotification(
|
||||
// invoice.user.id,
|
||||
// {
|
||||
// userPhone: invoice.user.phone,
|
||||
// userEmail: invoice.user.email,
|
||||
// subscriptionPlanId: invoice.items[0].subscriptionPlan.id,
|
||||
// },
|
||||
// queryRunner,
|
||||
// );
|
||||
}
|
||||
this.logger.log(`Invoice ${invoice.id} has been cancelled as it is more than 10 days overdue.`);
|
||||
}
|
||||
//********************************** */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user