From 6014da7e7312aa028c81b83a37af59b48e8800c4 Mon Sep 17 00:00:00 2001 From: mahyargdz Date: Mon, 17 Feb 2025 16:23:08 +0330 Subject: [PATCH] chore: add service to approve a invoice by user --- src/common/enums/message.enum.ts | 5 +++++ .../invoices/enums/invoice-status.enum.ts | 1 + src/modules/invoices/invoices.controller.ts | 9 +++++++- .../invoices/providers/invoices.service.ts | 21 +++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index 20e9ab2..46a0365 100644 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -335,6 +335,11 @@ export const enum InvoiceMessage { CREATED = "فاکتور با موفقیت ایجاد شد", SEARCH_QUERY_MUST_BE_A_STRING = "رشته جستجو باید یک رشته باشد", NOT_FOUND_BY_ID = "فاکتوری با این شناسه یافت نشد", + APPROVED = "فاکتور با موفقیت تایید شد", + ALREADY_APPROVED = "فاکتور قبلا تایید شده است", + INVOICE_CAN_NOT_APPROVED = "فاکتور قابل تایید نیست", + INVOICE_ALREADY_PAID = "فاکتور قبلا پرداخت شده است", + INVOICE_IS_OVERDUE = "فاکتور منقضی شده است", } export const enum LearningMessage { diff --git a/src/modules/invoices/enums/invoice-status.enum.ts b/src/modules/invoices/enums/invoice-status.enum.ts index 7e071ee..d60074a 100644 --- a/src/modules/invoices/enums/invoice-status.enum.ts +++ b/src/modules/invoices/enums/invoice-status.enum.ts @@ -1,4 +1,5 @@ export enum InvoiceStatus { + APPROVED = "APPROVED", PENDING = "PENDING", PAID = "PAID", EXPIRED = "EXPIRED", diff --git a/src/modules/invoices/invoices.controller.ts b/src/modules/invoices/invoices.controller.ts index 3e76be0..386bd8a 100644 --- a/src/modules/invoices/invoices.controller.ts +++ b/src/modules/invoices/invoices.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Get, Param, Post, Query } from "@nestjs/common"; +import { Body, Controller, Get, Param, Patch, Post, Query } from "@nestjs/common"; import { ApiOperation } from "@nestjs/swagger"; import { ApplyDiscountDto } from "./DTO/apply-discount-invoice.dto"; @@ -48,6 +48,13 @@ export class InvoicesController { return this.invoiceService.getInvoiceById(paramDto.id, isAdmin, userId); } + @ApiOperation({ summary: "approve invoice by user" }) + @AuthGuards() + @Patch(":id/approve") + approveInvoiceByUser(@Param() paramDto: ParamDto, @UserDec("id") userId: string) { + return this.invoiceService.approveInvoiceByUser(paramDto.id, userId); + } + @Post(":id/apply-discount") async applyDiscount(@Param() paramDto: ParamDto, @Body() applyDiscountDto: ApplyDiscountDto) { return this.invoiceService.applyDiscount(paramDto.id, applyDiscountDto); diff --git a/src/modules/invoices/providers/invoices.service.ts b/src/modules/invoices/providers/invoices.service.ts index 6b476c9..4dc9db8 100644 --- a/src/modules/invoices/providers/invoices.service.ts +++ b/src/modules/invoices/providers/invoices.service.ts @@ -1,5 +1,6 @@ import { BadRequestException, Injectable } from "@nestjs/common"; // eslint-disable-next-line import/no-named-as-default +import dayjs from "dayjs"; import Decimal from "decimal.js"; import { QueryRunner } from "typeorm"; @@ -59,7 +60,27 @@ export class InvoicesService { invoice, }; } + ///********************************** */ + async approveInvoiceByUser(invoiceId: string, userId: string) { + const invoice = await this.invoiceRepository.findOneBy({ id: invoiceId, user: { id: userId } }); + if (!invoice) throw new BadRequestException(InvoiceMessage.NOT_FOUND_BY_ID); + + if (invoice.status === InvoiceStatus.APPROVED) 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 (invoice.status !== InvoiceStatus.PENDING) throw new BadRequestException(InvoiceMessage.INVOICE_CAN_NOT_APPROVED); + + invoice.status = InvoiceStatus.APPROVED; + + await this.invoiceRepository.save(invoice); + + return { + message: InvoiceMessage.APPROVED, + invoice, + }; + } ///********************************** */ async createInvoiceForSubscription(userId: string, plan: SubscriptionPlan, dueDate: Date, queryRunner: QueryRunner) {