refactor: the invoice and subscription flow of user
This commit is contained in:
@@ -5,7 +5,7 @@ import { Column, Entity, ManyToOne } from "typeorm";
|
|||||||
import { Invoice } from "./invoice.entity";
|
import { Invoice } from "./invoice.entity";
|
||||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||||
import { DecimalTransformer } from "../../../common/transformers/decimal.transformer";
|
import { DecimalTransformer } from "../../../common/transformers/decimal.transformer";
|
||||||
import { SubscriptionPlan } from "../../subscriptions/entities/subscription.entity";
|
import { UserSubscription } from "../../subscriptions/entities/user-subscription.entity";
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class InvoiceItem extends BaseEntity {
|
export class InvoiceItem extends BaseEntity {
|
||||||
@@ -27,6 +27,6 @@ export class InvoiceItem extends BaseEntity {
|
|||||||
@Column({ type: "decimal", precision: 16, scale: 2, nullable: false, transformer: new DecimalTransformer() })
|
@Column({ type: "decimal", precision: 16, scale: 2, nullable: false, transformer: new DecimalTransformer() })
|
||||||
totalPrice: Decimal;
|
totalPrice: Decimal;
|
||||||
|
|
||||||
@ManyToOne(() => SubscriptionPlan, { nullable: true, onDelete: "RESTRICT" })
|
@ManyToOne(() => UserSubscription, { nullable: true, onDelete: "RESTRICT" })
|
||||||
subscriptionPlan: SubscriptionPlan | null;
|
subscriptionPlan: UserSubscription | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
export enum InvoiceStatus {
|
export enum InvoiceStatus {
|
||||||
PENDING = "PENDING",
|
PENDING = "PENDING",
|
||||||
APPROVED = "APPROVED",
|
|
||||||
REJECTED = "REJECTED",
|
|
||||||
WAIT_PAYMENT = "WAIT_PAYMENT",
|
WAIT_PAYMENT = "WAIT_PAYMENT",
|
||||||
PAID = "PAID",
|
PAID = "PAID",
|
||||||
EXPIRED = "EXPIRED",
|
EXPIRED = "EXPIRED",
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import { DiscountRepository } from "../../discounts/repositories/discount.reposi
|
|||||||
import { UsageDiscountRepository } from "../../discounts/repositories/usage-discount.repository";
|
import { UsageDiscountRepository } from "../../discounts/repositories/usage-discount.repository";
|
||||||
import { NotificationsService } from "../../notifications/providers/notifications.service";
|
import { NotificationsService } from "../../notifications/providers/notifications.service";
|
||||||
import { SubscriptionPlan } from "../../subscriptions/entities/subscription.entity";
|
import { SubscriptionPlan } from "../../subscriptions/entities/subscription.entity";
|
||||||
|
import { UserSubscription } from "../../subscriptions/entities/user-subscription.entity";
|
||||||
|
import { SubscriptionStatus } from "../../subscriptions/enums/subscription-status.enum";
|
||||||
import { UsersService } from "../../users/providers/users.service";
|
import { UsersService } from "../../users/providers/users.service";
|
||||||
import { OTPService } from "../../utils/providers/otp.service";
|
import { OTPService } from "../../utils/providers/otp.service";
|
||||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||||
@@ -110,9 +112,13 @@ export class InvoicesService {
|
|||||||
const invoice = await this.invoiceRepository.findOne({ where: { id: invoiceId, user: { id: userId } }, relations: { items: true } });
|
const invoice = await this.invoiceRepository.findOne({ where: { id: invoiceId, user: { id: userId } }, relations: { items: true } });
|
||||||
if (!invoice) throw new BadRequestException(InvoiceMessage.NOT_FOUND_BY_ID);
|
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.WAIT_PAYMENT) throw new BadRequestException(InvoiceMessage.ALREADY_APPROVED);
|
||||||
if (invoice.status === InvoiceStatus.PAID) throw new BadRequestException(InvoiceMessage.INVOICE_ALREADY_PAID);
|
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(invoice.dueDate)) {
|
||||||
|
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);
|
if (invoice.status !== InvoiceStatus.PENDING) throw new BadRequestException(InvoiceMessage.INVOICE_CAN_NOT_APPROVED);
|
||||||
|
|
||||||
@@ -149,14 +155,13 @@ export class InvoicesService {
|
|||||||
const isValid = await this.otpService.verifyOtp(user.phone, code, "INVOICE_VERIFY");
|
const isValid = await this.otpService.verifyOtp(user.phone, code, "INVOICE_VERIFY");
|
||||||
if (!isValid) throw new BadRequestException(AuthMessage.INVALID_OTP);
|
if (!isValid) throw new BadRequestException(AuthMessage.INVALID_OTP);
|
||||||
|
|
||||||
if (invoice.status === InvoiceStatus.REJECTED) throw new BadRequestException(InvoiceMessage.INVOICE_IS_REJECTED);
|
if (invoice.status === InvoiceStatus.WAIT_PAYMENT) throw new BadRequestException(InvoiceMessage.ALREADY_APPROVED);
|
||||||
if (invoice.status === InvoiceStatus.APPROVED) throw new BadRequestException(InvoiceMessage.ALREADY_APPROVED);
|
|
||||||
if (invoice.status === InvoiceStatus.PAID) throw new BadRequestException(InvoiceMessage.INVOICE_ALREADY_PAID);
|
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(invoice.dueDate)) throw new BadRequestException(InvoiceMessage.INVOICE_IS_OVERDUE);
|
||||||
|
|
||||||
if (invoice.status !== InvoiceStatus.PENDING) throw new BadRequestException(InvoiceMessage.INVOICE_CAN_NOT_APPROVED);
|
if (invoice.status !== InvoiceStatus.PENDING) throw new BadRequestException(InvoiceMessage.INVOICE_CAN_NOT_APPROVED);
|
||||||
|
|
||||||
invoice.status = InvoiceStatus.APPROVED;
|
invoice.status = InvoiceStatus.WAIT_PAYMENT;
|
||||||
|
|
||||||
await this.invoiceRepository.save(invoice);
|
await this.invoiceRepository.save(invoice);
|
||||||
|
|
||||||
@@ -167,14 +172,27 @@ export class InvoicesService {
|
|||||||
}
|
}
|
||||||
///********************************** */
|
///********************************** */
|
||||||
|
|
||||||
async createInvoiceForSubscription(userId: string, plan: SubscriptionPlan, dueDate: Date, queryRunner: QueryRunner) {
|
async createInvoiceForSubscription(
|
||||||
|
userId: string,
|
||||||
|
plan: SubscriptionPlan,
|
||||||
|
userSub: UserSubscription,
|
||||||
|
dueDate: Date,
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
) {
|
||||||
const invoiceItems = [
|
const invoiceItems = [
|
||||||
{ name: plan.service.name, count: 1, unitPrice: plan.price, discount: 0, subscriptionPlan: plan, totalPrice: plan.price },
|
{
|
||||||
|
name: plan.service.name,
|
||||||
|
count: 1,
|
||||||
|
unitPrice: plan.price,
|
||||||
|
discount: 0,
|
||||||
|
subscriptionPlan: userSub,
|
||||||
|
totalPrice: plan.price,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const invoice = queryRunner.manager.create(Invoice, {
|
const invoice = queryRunner.manager.create(Invoice, {
|
||||||
totalPrice: plan.price,
|
totalPrice: plan.price,
|
||||||
user: { id: userId },
|
user: { id: userId },
|
||||||
status: InvoiceStatus.PAID,
|
status: InvoiceStatus.PENDING,
|
||||||
paidAt: new Date(),
|
paidAt: new Date(),
|
||||||
dueDate,
|
dueDate,
|
||||||
items: invoiceItems,
|
items: invoiceItems,
|
||||||
@@ -238,7 +256,9 @@ export class InvoicesService {
|
|||||||
.andWhere("invoice.user.id = :userId", { userId: userId })
|
.andWhere("invoice.user.id = :userId", { userId: userId })
|
||||||
.leftJoinAndSelect("invoice.items", "items")
|
.leftJoinAndSelect("invoice.items", "items")
|
||||||
.leftJoinAndSelect("items.subscriptionPlan", "subscriptionPlan", "subscriptionPlan.id IS NOT NULL")
|
.leftJoinAndSelect("items.subscriptionPlan", "subscriptionPlan", "subscriptionPlan.id IS NOT NULL")
|
||||||
.leftJoinAndSelect("subscriptionPlan.service", "service", "subscriptionPlan.id IS NOT NULL");
|
.leftJoinAndSelect("subscriptionPlan.plan", "plan", "subscriptionPlan.id IS NOT NULL")
|
||||||
|
.leftJoin("plan.service", "service", "subscriptionPlan.id IS NOT NULL")
|
||||||
|
.addSelect(["service.name", "service.id"]);
|
||||||
|
|
||||||
if (queryDto.status) {
|
if (queryDto.status) {
|
||||||
queryBuilder.andWhere("invoice.status = :status", { status: queryDto.status });
|
queryBuilder.andWhere("invoice.status = :status", { status: queryDto.status });
|
||||||
@@ -265,27 +285,33 @@ export class InvoicesService {
|
|||||||
const user = await this.usersService.findOneByIdWithQueryRunner(userId, queryRunner);
|
const user = await this.usersService.findOneByIdWithQueryRunner(userId, queryRunner);
|
||||||
|
|
||||||
const invoice = await this.getPendingInvoiceByIdWithQueryRunner(invoiceId, user.id, queryRunner);
|
const invoice = await this.getPendingInvoiceByIdWithQueryRunner(invoiceId, user.id, queryRunner);
|
||||||
|
console.log(invoice);
|
||||||
|
|
||||||
if (invoice.status === InvoiceStatus.REJECTED) throw new BadRequestException(InvoiceMessage.INVOICE_IS_REJECTED);
|
if (invoice.status !== InvoiceStatus.WAIT_PAYMENT) throw new BadRequestException(InvoiceMessage.INVOICE_CAN_NOT_PAID);
|
||||||
if (invoice.status === InvoiceStatus.EXPIRED) throw new BadRequestException(InvoiceMessage.INVOICE_IS_OVERDUE);
|
|
||||||
if (invoice.status === InvoiceStatus.PAID) throw new BadRequestException(InvoiceMessage.INVOICE_ALREADY_PAID);
|
|
||||||
if (invoice.status !== InvoiceStatus.APPROVED) throw new BadRequestException(InvoiceMessage.INVOICE_CAN_NOT_PAID);
|
|
||||||
|
|
||||||
const userWallet = await this.walletsService.getWalletByUserId(user.id, queryRunner);
|
const userWallet = await this.walletsService.getWalletByUserId(user.id, queryRunner);
|
||||||
|
|
||||||
if (new Decimal(userWallet.balance).lessThan(invoice.totalPrice)) throw new BadRequestException(WalletMessage.INSUFFICIENT_BALANCE);
|
if (userWallet.balance < invoice.totalPrice) throw new BadRequestException(WalletMessage.INSUFFICIENT_BALANCE);
|
||||||
|
|
||||||
userWallet.balance = new Decimal(userWallet.balance).sub(invoice.totalPrice);
|
userWallet.balance = new Decimal(userWallet.balance).sub(invoice.totalPrice);
|
||||||
|
|
||||||
await queryRunner.manager.save(Wallet, userWallet);
|
await queryRunner.manager.save(Wallet, userWallet);
|
||||||
|
|
||||||
await this.walletsService.createInvoiceTransaction(invoice.totalPrice, userWallet.id, queryRunner);
|
if (invoice.items[0]?.subscriptionPlan) {
|
||||||
|
const userSubscription = invoice.items[0].subscriptionPlan;
|
||||||
|
userSubscription.status = SubscriptionStatus.ACTIVE;
|
||||||
|
|
||||||
|
//
|
||||||
|
await queryRunner.manager.save(UserSubscription, userSubscription);
|
||||||
|
await this.walletsService.createSubscriptionTransaction(invoice.totalPrice, userWallet.id, queryRunner);
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
await this.walletsService.createInvoiceTransaction(invoice.totalPrice, userWallet.id, queryRunner);
|
||||||
|
}
|
||||||
invoice.status = InvoiceStatus.PAID;
|
invoice.status = InvoiceStatus.PAID;
|
||||||
invoice.paidAt = new Date();
|
invoice.paidAt = dayjs().toDate();
|
||||||
|
|
||||||
await queryRunner.manager.save(Invoice, invoice);
|
await queryRunner.manager.save(Invoice, invoice);
|
||||||
console.log(invoice);
|
|
||||||
await queryRunner.commitTransaction();
|
await queryRunner.commitTransaction();
|
||||||
return {
|
return {
|
||||||
message: InvoiceMessage.INVOICE_PAID,
|
message: InvoiceMessage.INVOICE_PAID,
|
||||||
@@ -302,7 +328,20 @@ export class InvoicesService {
|
|||||||
//*********************************** */
|
//*********************************** */
|
||||||
|
|
||||||
async getPendingInvoiceByIdWithQueryRunner(invoiceId: string, userId: string, queryRunner: QueryRunner) {
|
async getPendingInvoiceByIdWithQueryRunner(invoiceId: string, userId: string, queryRunner: QueryRunner) {
|
||||||
const invoice = await queryRunner.manager.findOneBy(Invoice, { user: { id: userId }, status: InvoiceStatus.PENDING, id: invoiceId });
|
const invoice = await queryRunner.manager.findOne(Invoice, {
|
||||||
|
where: {
|
||||||
|
user: { id: userId },
|
||||||
|
status: InvoiceStatus.WAIT_PAYMENT,
|
||||||
|
id: invoiceId,
|
||||||
|
},
|
||||||
|
relations: {
|
||||||
|
items: {
|
||||||
|
subscriptionPlan: {
|
||||||
|
plan: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
if (!invoice) throw new BadRequestException(InvoiceMessage.NOT_FOUND_BY_ID);
|
if (!invoice) throw new BadRequestException(InvoiceMessage.NOT_FOUND_BY_ID);
|
||||||
return invoice;
|
return invoice;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export class NotificationsService {
|
|||||||
//************************ */
|
//************************ */
|
||||||
|
|
||||||
async markAllAsRead(userId: string) {
|
async markAllAsRead(userId: string) {
|
||||||
await this.notificationRepository.delete({ recipient: { id: userId } });
|
await this.notificationRepository.update({ recipient: { id: userId } }, { isRead: true });
|
||||||
return {
|
return {
|
||||||
message: CommonMessage.UPDATE_SUCCESS,
|
message: CommonMessage.UPDATE_SUCCESS,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,12 +28,6 @@ export class UserSubscription extends BaseEntity {
|
|||||||
@Column({ type: "text", nullable: false })
|
@Column({ type: "text", nullable: false })
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
@Column({ type: "enum", enum: SubscriptionStatus, default: SubscriptionStatus.PENDING })
|
@Column({ type: "enum", enum: SubscriptionStatus, default: SubscriptionStatus.INACTIVE })
|
||||||
status: SubscriptionStatus;
|
status: SubscriptionStatus;
|
||||||
|
|
||||||
@Column({ type: "boolean", default: false })
|
|
||||||
isCanceled: boolean;
|
|
||||||
|
|
||||||
// @OneToMany(() => UserQuickAccess, (quickAccess) => quickAccess.userSubscription)
|
|
||||||
// quickAccess: UserQuickAccess[];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export enum SubscriptionStatus {
|
export enum SubscriptionStatus {
|
||||||
ACTIVE = "ACTIVE",
|
ACTIVE = "ACTIVE",
|
||||||
INACTIVE = "INACTIVE",
|
INACTIVE = "INACTIVE",
|
||||||
PENDING = "PENDING",
|
// PENDING = "PENDING",
|
||||||
CANCELED = "CANCELED",
|
CANCELED = "CANCELED",
|
||||||
EXPIRED = "EXPIRED",
|
EXPIRED = "EXPIRED",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ import dayjs from "dayjs";
|
|||||||
import Decimal from "decimal.js";
|
import Decimal from "decimal.js";
|
||||||
import { DataSource, In } from "typeorm";
|
import { DataSource, In } from "typeorm";
|
||||||
|
|
||||||
import { ServiceMessage, SubscriptionMessage, WalletMessage } from "../../../common/enums/message.enum";
|
import { ServiceMessage, SubscriptionMessage } from "../../../common/enums/message.enum";
|
||||||
import { DanakServicesService } from "../../danak-services/providers/danak-services.service";
|
import { DanakServicesService } from "../../danak-services/providers/danak-services.service";
|
||||||
import { DiscountCalculationType } from "../../discounts/enums/discount-type.enum";
|
import { DiscountCalculationType } from "../../discounts/enums/discount-type.enum";
|
||||||
import { InvoicesService } from "../../invoices/providers/invoices.service";
|
import { InvoicesService } from "../../invoices/providers/invoices.service";
|
||||||
import { UsersService } from "../../users/providers/users.service";
|
import { UsersService } from "../../users/providers/users.service";
|
||||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||||
import { Wallet } from "../../wallets/entities/wallet.entity";
|
// import { Wallet } from "../../wallets/entities/wallet.entity";
|
||||||
import { WalletsService } from "../../wallets/providers/wallets.service";
|
// import { WalletsService } from "../../wallets/providers/wallets.service";
|
||||||
import { AddSubscriptionsToServiceDto } from "../DTO/create-subscription.dto";
|
import { AddSubscriptionsToServiceDto } from "../DTO/create-subscription.dto";
|
||||||
import { SearchUserSubsQueryDto } from "../DTO/search-user-subs-query.dto";
|
import { SearchUserSubsQueryDto } from "../DTO/search-user-subs-query.dto";
|
||||||
import { ServiceSubsQueryDto } from "../DTO/service-subs-query.dto";
|
import { ServiceSubsQueryDto } from "../DTO/service-subs-query.dto";
|
||||||
@@ -30,7 +30,7 @@ export class SubscriptionsService {
|
|||||||
private readonly userSubscriptionsRepository: UserSubscriptionsRepository,
|
private readonly userSubscriptionsRepository: UserSubscriptionsRepository,
|
||||||
private readonly invoicesService: InvoicesService,
|
private readonly invoicesService: InvoicesService,
|
||||||
private readonly usersService: UsersService,
|
private readonly usersService: UsersService,
|
||||||
private readonly walletsService: WalletsService,
|
// private readonly walletsService: WalletsService,
|
||||||
private readonly danakServices: DanakServicesService,
|
private readonly danakServices: DanakServicesService,
|
||||||
private readonly dataSource: DataSource,
|
private readonly dataSource: DataSource,
|
||||||
) {}
|
) {}
|
||||||
@@ -227,47 +227,18 @@ export class SubscriptionsService {
|
|||||||
|
|
||||||
const startDate = dayjs().toDate();
|
const startDate = dayjs().toDate();
|
||||||
const endDate = dayjs().add(plan.duration, "day").toDate();
|
const endDate = dayjs().add(plan.duration, "day").toDate();
|
||||||
// const startDate = new Date();
|
|
||||||
// const endDate = new Date();
|
|
||||||
// endDate.setDate(startDate.getDate() + plan.duration);
|
|
||||||
//
|
//
|
||||||
const userSubscription = queryRunner.manager.create(UserSubscription, { ...subscribeDto, user, plan, startDate, endDate });
|
const userSubscription = queryRunner.manager.create(UserSubscription, { ...subscribeDto, user, plan, startDate, endDate });
|
||||||
|
|
||||||
await queryRunner.manager.save(UserSubscription, userSubscription);
|
await queryRunner.manager.save(UserSubscription, userSubscription);
|
||||||
|
|
||||||
const userWallet = await this.walletsService.getWalletByUserId(user.id, queryRunner);
|
|
||||||
|
|
||||||
let finalPrice = new Decimal(plan.price);
|
|
||||||
|
|
||||||
const activeDiscounts =
|
|
||||||
plan.discounts?.filter((discount) => discount.isActive && new Date() >= discount.startDate && new Date() <= discount.endDate) || [];
|
|
||||||
|
|
||||||
activeDiscounts.forEach((discount) => {
|
|
||||||
if (discount.calculationType === DiscountCalculationType.PERCENTAGE) {
|
|
||||||
finalPrice = finalPrice.sub(finalPrice.mul(discount.amount).div(100));
|
|
||||||
} else if (discount.calculationType === DiscountCalculationType.FIXED) {
|
|
||||||
finalPrice = finalPrice.sub(discount.amount);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
plan.price = finalPrice;
|
|
||||||
|
|
||||||
if (new Decimal(userWallet.balance).lessThan(finalPrice)) throw new BadRequestException(WalletMessage.INSUFFICIENT_BALANCE);
|
|
||||||
|
|
||||||
// if (userWallet.balance < plan.price) throw new BadRequestException(WalletMessage.INSUFFICIENT_BALANCE);
|
|
||||||
|
|
||||||
//
|
|
||||||
userWallet.balance = new Decimal(userWallet.balance).sub(finalPrice);
|
|
||||||
|
|
||||||
await queryRunner.manager.save(Wallet, userWallet);
|
|
||||||
//
|
//
|
||||||
|
|
||||||
await this.walletsService.createSubscriptionTransaction(finalPrice, userWallet.id, queryRunner);
|
|
||||||
//TODO: need queue handling for notification
|
//TODO: need queue handling for notification
|
||||||
const invoiceDueDate = dayjs(userSubscription.endDate).subtract(3, "day").toDate();
|
const invoiceDueDate = dayjs(userSubscription.startDate).add(5, "day").toDate();
|
||||||
|
|
||||||
const invoice = await this.invoicesService.createInvoiceForSubscription(userId, plan, invoiceDueDate, queryRunner);
|
const invoice = await this.invoicesService.createInvoiceForSubscription(userId, plan, userSubscription, invoiceDueDate, queryRunner);
|
||||||
userSubscription.status = SubscriptionStatus.ACTIVE;
|
userSubscription.status = SubscriptionStatus.INACTIVE;
|
||||||
|
|
||||||
await queryRunner.manager.save(UserSubscription, userSubscription);
|
await queryRunner.manager.save(UserSubscription, userSubscription);
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,8 @@ export class Ticket extends BaseEntity {
|
|||||||
@Column({ type: "enum", enum: TicketPriority, nullable: false })
|
@Column({ type: "enum", enum: TicketPriority, nullable: false })
|
||||||
priority: TicketPriority;
|
priority: TicketPriority;
|
||||||
|
|
||||||
//TODO:set this to not nullable
|
|
||||||
@ManyToOne(() => DanakService, (danakService) => danakService.tickets, { onDelete: "RESTRICT", nullable: true })
|
@ManyToOne(() => DanakService, (danakService) => danakService.tickets, { onDelete: "RESTRICT", nullable: true })
|
||||||
danakService: DanakService;
|
danakService: DanakService | null;
|
||||||
|
|
||||||
@ManyToOne(() => User, (user) => user.tickets, { nullable: true })
|
@ManyToOne(() => User, (user) => user.tickets, { nullable: true })
|
||||||
assignedTo: User;
|
assignedTo: User;
|
||||||
|
|||||||
@@ -92,6 +92,21 @@ export class WalletsService {
|
|||||||
|
|
||||||
return transaction;
|
return transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*********************************** */
|
||||||
|
|
||||||
|
async createInvoiceTransaction(amount: Decimal, walletId: string, queryRunner: QueryRunner) {
|
||||||
|
const transaction = queryRunner.manager.create(WalletTransaction, {
|
||||||
|
amount,
|
||||||
|
wallet: { id: walletId },
|
||||||
|
type: TransactionType.DEBIT,
|
||||||
|
description: WalletMessage.INVOICE_WALLET_TRANSFER,
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryRunner.manager.save(WalletTransaction, transaction);
|
||||||
|
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
//*********************************** */
|
//*********************************** */
|
||||||
|
|
||||||
async getTransaction(userId: string, paginationDto: PaginationDto) {
|
async getTransaction(userId: string, paginationDto: PaginationDto) {
|
||||||
@@ -189,19 +204,4 @@ export class WalletsService {
|
|||||||
if (!wallet) throw new BadRequestException(WalletMessage.WALLET_NOT_FOUND);
|
if (!wallet) throw new BadRequestException(WalletMessage.WALLET_NOT_FOUND);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
//*********************************** */
|
|
||||||
|
|
||||||
async createInvoiceTransaction(amount: Decimal, walletId: string, queryRunner: QueryRunner) {
|
|
||||||
const transaction = queryRunner.manager.create(WalletTransaction, {
|
|
||||||
amount,
|
|
||||||
wallet: { id: walletId },
|
|
||||||
type: TransactionType.DEBIT,
|
|
||||||
description: WalletMessage.INVOICE_WALLET_TRANSFER,
|
|
||||||
});
|
|
||||||
|
|
||||||
await queryRunner.manager.save(WalletTransaction, transaction);
|
|
||||||
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user