From 6f7a95bd1819258c3bd653f46f1a470ea743d88a Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Sun, 15 Feb 2026 14:39:02 +0330 Subject: [PATCH] renew dkala subscription --- src/modules/dkala/dkala.controller.ts | 18 +++++----- src/modules/dkala/dkala.module.ts | 6 ++-- .../{shop.service.ts => dkala.service.ts} | 33 +++++++++---------- src/modules/invoices/invoices.module.ts | 2 ++ .../invoices/providers/invoices.service.ts | 29 ++++++++++++++++ 5 files changed, 59 insertions(+), 29 deletions(-) rename src/modules/dkala/providers/{shop.service.ts => dkala.service.ts} (93%) diff --git a/src/modules/dkala/dkala.controller.ts b/src/modules/dkala/dkala.controller.ts index 83b3889..4cfa0ee 100644 --- a/src/modules/dkala/dkala.controller.ts +++ b/src/modules/dkala/dkala.controller.ts @@ -3,7 +3,7 @@ import { ApiBearerAuth, ApiOperation, ApiParam, ApiQuery, ApiTags } from "@nestj import { DContactService } from "./providers/contact.service"; import { DkalaIconsService } from "./providers/icons.service"; -import { ShopService } from "./providers/shop.service"; +import { DkalaService } from "./providers/dkala.service"; import { CreateIconDto } from "./DTO/create-icon.dto"; import { UpdateIconDto } from "./DTO/update-icon.dto"; import { CreateGroupDto } from "./DTO/create-group.dto"; @@ -26,7 +26,7 @@ export class DkalaController { constructor( private readonly iconsService: DkalaIconsService, private readonly contactService: DContactService, - private readonly shopService: ShopService, + private readonly shopService: DkalaService, ) { } // Icon endpoints @@ -145,7 +145,7 @@ export class DkalaController { ) { const parsedPage = page ? parseInt(page.toString(), 10) : 1; const parsedLimit = limit ? parseInt(limit.toString(), 10) : 10; - return await this.shopService.getSmsCountByRestaurant(parsedPage, parsedLimit); + return await this.shopService.getSmsCounts(parsedPage, parsedLimit); } @PermissionsDec(PermissionEnum.DKALA) @@ -153,7 +153,7 @@ export class DkalaController { @ApiOperation({ summary: "Update restaurant" }) @ApiParam({ name: "id", required: true, type: String }) updateRestaurant(@Param("id") id: string, @Body() dto: UpdateShopDto) { - return this.shopService.updateRestaurant(id, dto); + return this.shopService.updateShop(id, dto); } @PermissionsDec(PermissionEnum.DKALA) @@ -176,7 +176,7 @@ export class DkalaController { @ApiOperation({ summary: "Get restaurant admins" }) @ApiParam({ name: "restaurantId", required: true, type: String }) getRestaurantAdmins(@Param("restaurantId") restaurantId: string) { - return this.shopService.getRestaurantAdmins(restaurantId); + return this.shopService.getAdminsByShop(restaurantId); } @PermissionsDec(PermissionEnum.DKALA) @@ -184,7 +184,7 @@ export class DkalaController { @ApiOperation({ summary: "Assign admin to restaurant" }) @ApiParam({ name: "restaurantId", required: true, type: String }) assignRestaurantAdmin(@Param("restaurantId") restaurantId: string, @Body() dto: CreateMyShopAdminDto) { - return this.shopService.assignRestaurantAdmin(restaurantId, dto); + return this.shopService.assignShopAdmin(restaurantId, dto); } @PermissionsDec(PermissionEnum.DKALA) @@ -193,21 +193,21 @@ export class DkalaController { @ApiParam({ name: "restaurantId", required: true, type: String }) @ApiParam({ name: "adminId", required: true, type: String }) revokeRestaurantAdmin(@Param("restaurantId") restaurantId: string, @Param("adminId") adminId: string) { - return this.shopService.revokeRestaurantAdmin(restaurantId, adminId); + return this.shopService.revokeShopAdmin(restaurantId, adminId); } //***User Endpoints*** @Post('dkala/shops') @ApiOperation({ summary: "Create restaurant" }) createRestaurant(@Body() dto: SetupShopDto, @UserDec("id") userId: string) { - return this.shopService.createRestaurant(dto, userId); + return this.shopService.createShop(dto, userId); } @Get('dkala/shops/subscription/:subscriptionId') @ApiOperation({ summary: "Get restaurant subscription by subscription ID" }) @ApiParam({ name: "subscriptionId", required: true, type: String }) getRestaurantSubscription(@Param("subscriptionId") subscriptionId: string) { - return this.shopService.getRestaurantSubscription(subscriptionId); + return this.shopService.getShopBySubscriptionId(subscriptionId); } @Post('dkala/auth/direct-login/:userSubscriptionId') diff --git a/src/modules/dkala/dkala.module.ts b/src/modules/dkala/dkala.module.ts index b63ee73..15ce966 100644 --- a/src/modules/dkala/dkala.module.ts +++ b/src/modules/dkala/dkala.module.ts @@ -4,7 +4,7 @@ import { DKALA_CONFIG } from "./constants"; import { DkalaController } from "./dkala.controller"; import { DContactService } from "./providers/contact.service"; import { DkalaIconsService } from "./providers/icons.service"; -import { ShopService } from "./providers/shop.service"; +import { DkalaService } from "./providers/dkala.service"; import { SubscriptionsModule } from "../subscriptions/subscriptions.module"; import { UsersModule } from "../users/users.module"; import { dkalaConfig } from "../../configs/dkala.config"; @@ -19,13 +19,13 @@ import { dkalaConfig } from "../../configs/dkala.config"; providers: [ DkalaIconsService, DContactService, - ShopService, + DkalaService, { provide: DKALA_CONFIG, useFactory: dkalaConfig().useFactory, inject: dkalaConfig().inject, }, ], - exports: [ShopService], + exports: [DkalaService], }) export class DkalaModule {} diff --git a/src/modules/dkala/providers/shop.service.ts b/src/modules/dkala/providers/dkala.service.ts similarity index 93% rename from src/modules/dkala/providers/shop.service.ts rename to src/modules/dkala/providers/dkala.service.ts index 40490bf..8ab4f5c 100644 --- a/src/modules/dkala/providers/shop.service.ts +++ b/src/modules/dkala/providers/dkala.service.ts @@ -17,8 +17,8 @@ import { IDkalaConfig } from "../../../configs/dkala.config"; @Injectable() -export class ShopService { - private readonly logger = new Logger(ShopService.name); +export class DkalaService { + private readonly logger = new Logger(DkalaService.name); constructor( @Inject(DKALA_CONFIG) private readonly config: IDkalaConfig, @@ -114,7 +114,7 @@ export class ShopService { } } - async createRestaurant(dto: SetupShopDto, userId: string) { + async createShop(dto: SetupShopDto, userId: string) { const { userSubscription } = await this.subscriptionService.getUserSubscriptionById(dto.userSubscriptionId, userId); if (!userSubscription) { throw new BadRequestException(SubscriptionMessage.USER_SUBS_NOT_FOUND); @@ -165,7 +165,7 @@ export class ShopService { } } - async updateRestaurant(id: string, dto: UpdateShopDto) { + async updateShop(id: string, dto: UpdateShopDto) { try { const { data } = await firstValueFrom( this.httpService @@ -194,7 +194,7 @@ export class ShopService { } } - async getRestaurantSubscription(subscriptionId: string) { + async getShopBySubscriptionId(subscriptionId: string) { try { console.log('subscriptionId', subscriptionId) const { data } = await firstValueFrom( @@ -225,13 +225,13 @@ export class ShopService { } } - async getSmsCountByRestaurant(page: number, limit: number) { + async getSmsCounts(page: number, limit: number) { try { const { data } = await firstValueFrom( this.httpService .get(this.config.baseUrl + "/super-admin/notifications/sms-count", { - params: { page, limit}, - headers: this.getHeaders() + params: { page, limit }, + headers: this.getHeaders() }) .pipe( catchError((err: AxiosError) => { @@ -285,11 +285,11 @@ export class ShopService { } } - async getRestaurantAdmins(restaurantId: string) { + async getAdminsByShop(shopId: string) { try { const { data } = await firstValueFrom( this.httpService - .get(`${this.config.baseUrl}/super-admin/shops/${restaurantId}/admins`, { + .get(`${this.config.baseUrl}/super-admin/shops/${shopId}/admins`, { headers: this.getHeaders(), }) .pipe( @@ -314,11 +314,11 @@ export class ShopService { } } - async revokeRestaurantAdmin(restaurantId: string, adminId: string) { + async revokeShopAdmin(shopId: string, adminId: string) { try { const { data } = await firstValueFrom( this.httpService - .delete(`${this.config.baseUrl}/super-admin/shops/${restaurantId}/admins/${adminId}`, { + .delete(`${this.config.baseUrl}/super-admin/shops/${shopId}/admins/${adminId}`, { headers: this.getHeaders(), data: {}, }) @@ -344,12 +344,12 @@ export class ShopService { } } - async assignRestaurantAdmin(restaurantId: string, dto: CreateMyShopAdminDto) { + async assignShopAdmin(shopId: string, dto: CreateMyShopAdminDto) { try { const { data } = await firstValueFrom( this.httpService - .post(`${this.config.baseUrl}/super-admin/shops/${restaurantId}/admins`, dto, { + .post(`${this.config.baseUrl}/super-admin/shops/${shopId}/admins`, dto, { headers: this.getHeaders(), }) .pipe( @@ -377,12 +377,11 @@ export class ShopService { } } - async upgradeSubscription(subscriptionId: string, newPlan: 'base' | 'premium', subscriptionEndDate: Date) { + async upgradeSubscription(subscriptionId: string, subscriptionEndDate: Date) { try { const { data } = await firstValueFrom( this.httpService .patch(`${this.config.baseUrl}/super-admin/shops/subscription/${subscriptionId}/upgrade`, { - newPlan, subscriptionEndDate }, { headers: this.getHeaders(), @@ -454,7 +453,7 @@ export class ShopService { } // 3. Get restaurant by subscription id - const restaurant = await this.getRestaurantSubscription(userSubscriptionId); + const restaurant = await this.getShopBySubscriptionId(userSubscriptionId); // 4. Get slug from restaurant const slug = restaurant.data.slug; diff --git a/src/modules/invoices/invoices.module.ts b/src/modules/invoices/invoices.module.ts index 69f2122..095174f 100755 --- a/src/modules/invoices/invoices.module.ts +++ b/src/modules/invoices/invoices.module.ts @@ -22,6 +22,7 @@ import { PaymentsModule } from "../payments/payments.module"; import { UsersModule } from "../users/users.module"; import { UtilsModule } from "../utils/utils.module"; import { WalletsModule } from "../wallets/wallets.module"; +import { DkalaModule } from "../dkala/dkala.module"; @Module({ imports: [ LoggerModule, @@ -48,6 +49,7 @@ import { WalletsModule } from "../wallets/wallets.module"; PaymentsModule, AccessLogsModule, forwardRef(() => DmenuModule), + forwardRef(() => DkalaModule), ], providers: [InvoicesService, InvoicesRepository, InvoiceItemsRepository, DiscountRepository, UsageDiscountRepository, InvoiceProcessor], controllers: [InvoicesController], diff --git a/src/modules/invoices/providers/invoices.service.ts b/src/modules/invoices/providers/invoices.service.ts index 5490e19..b304934 100755 --- a/src/modules/invoices/providers/invoices.service.ts +++ b/src/modules/invoices/providers/invoices.service.ts @@ -38,6 +38,7 @@ import { InvoiceStatus } from "../enums/invoice-status.enum"; import { IExternalInvoiceJob, InvoicePurpose } from "../interfaces/external-invoice.interface"; import { InvoiceItemsRepository } from "../repositories/invoice-items.repository"; import { InvoicesRepository } from "../repositories/invoices.repository"; +import { DkalaService } from "../../dkala/providers/dkala.service"; @Injectable() export class InvoicesService { private readonly logger = new Logger(InvoicesService.name); @@ -55,6 +56,7 @@ export class InvoicesService { private readonly dataSource: DataSource, private readonly accessLogService: AccessLogService, private readonly restaurantService: RestaurantService, + private readonly dkalaService: DkalaService, ) { } ///********************************** */ @@ -833,6 +835,19 @@ export class InvoicesService { // Don't fail the transaction if external API call fails } } + else if (upgradePlan.service.slug?.toLowerCase().includes('dkala')) { + try { + this.logger.log(`Calling external API for dkala upgrade: subscription ${userSubscription.id}`); + await this.dkalaService.upgradeSubscription( + userSubscription.id, + userSubscription.endDate + ); + this.logger.log(`External API call completed for dkala upgrade: subscription ${userSubscription.id}`); + } catch (error) { + this.logger.error(`Failed to call external API for dkala upgrade: ${error instanceof Error ? error.message : 'Unknown error'}`); + // Don't fail the transaction if external API call fails + } + } } else if (purpose == InvoicePurpose.RENEW) { if (userSubscription.status == SubscriptionStatus.ACTIVE) { @@ -866,6 +881,20 @@ export class InvoicesService { } } + else if (userSubscription.plan.service.slug?.toLowerCase().includes('dkala')) { + try { + this.logger.log(`Calling external API for dkala renew: subscription ${userSubscription.id}`); + await this.dkalaService.upgradeSubscription( + userSubscription.id, + userSubscription.endDate + ); + this.logger.log(`External API call completed for dkala renew: subscription ${userSubscription.id}`); + } catch (error) { + this.logger.error(`Failed to call external API for dkala renew: ${error instanceof Error ? error.message : 'Unknown error'}`); + // Don't fail the transaction if external API call fails + } + } + } else if (purpose == InvoicePurpose.NEW) { userSubscription.status = SubscriptionStatus.ACTIVE; await this.scheduleNextRenewalJob(userSubscription);