import { HttpService } from "@nestjs/axios"; import { BadRequestException, Injectable, Logger } from "@nestjs/common"; import { Inject } from "@nestjs/common"; import { AxiosError } from "axios"; import { catchError, firstValueFrom, throwError } from "rxjs"; import { IDmenuConfig } from "../../../configs/icons.config"; import { DMENU_CONFIG } from "../constants"; import { FindRestaurantsDto } from "../DTO/find-restaurants.dto"; import { SetupRestaurantDto } from "../DTO/create-restaurant.dto"; import { PlanEnum, ISetupRestaurant } from "../interface/plan.interface"; import { SubscriptionsService } from "../../subscriptions/providers/subscriptions.service"; import { SubscriptionMessage } from "../../../common/enums/message.enum"; @Injectable() export class RestaurantService { private readonly logger = new Logger(RestaurantService.name); constructor( @Inject(DMENU_CONFIG) private readonly config: IDmenuConfig, private readonly httpService: HttpService, private readonly subscriptionService: SubscriptionsService, ) { } private getHeaders(): Record { const credentials = Buffer.from(`${this.config.username}:${this.config.password}`).toString("base64"); return { "Content-Type": "application/json", Authorization: `Basic ${credentials}`, }; } async findAll(queryDto: FindRestaurantsDto) { try { const params: Record = { page: queryDto.page || 1, limit: queryDto.limit || 10, orderBy: queryDto.orderBy || 'createdAt', order: queryDto.order || 'desc', }; if (queryDto.search) { params.search = queryDto.search; } if (queryDto.isActive !== undefined) { params.isActive = queryDto.isActive; } if (queryDto.plan) { params.plan = queryDto.plan; } const { data } = await firstValueFrom( this.httpService .get(`${this.config.baseUrl}/super-admin/restaurants`, { params, headers: this.getHeaders(), }) .pipe( catchError((err: AxiosError) => { this.logger.error(`Failed to fetch restaurants: ${err.message}`, err.stack); return throwError(() => err); }), ), ); return data; } catch (error: unknown) { this.logger.error(`Error fetching restaurants: ${error instanceof Error ? error.message : "Unknown error"}`); throw error; } } async createRestaurant(dto: SetupRestaurantDto, userId: string) { const { userSubscription } = await this.subscriptionService.getUserSubscriptionById(dto.userSubscriptionId, userId); if (!userSubscription) { throw new BadRequestException(SubscriptionMessage.USER_SUBS_NOT_FOUND); } const plan = userSubscription.plan.name.includes('دلیوری') ? PlanEnum.Premium : PlanEnum.Base; const setupRestaurantDto: ISetupRestaurant = { name: dto.name, slug: dto.slug, establishedYear: dto.establishedYear, phone: dto.phone, plan, subscriptionId: dto.userSubscriptionId, subscriptionEndDate: userSubscription.endDate.toISOString(), subscriptionStartDate: userSubscription.startDate.toISOString(), }; try { const { data } = await firstValueFrom( this.httpService .post(`${this.config.baseUrl}/super-admin/restaurants`, setupRestaurantDto, { headers: this.getHeaders(), }) .pipe( catchError((err: AxiosError) => { this.logger.error(`Failed to create restaurant: ${err.message}`, err.stack); return throwError(() => err); }), ), ); return data; } catch (error: unknown) { this.logger.error(`Error creating restaurant: ${error instanceof Error ? error.message : "Unknown error"}`); throw error; } } async getRestaurantSubscription(subscriptionId: string) { // TODO: Implement the business logic to get restaurant subscription // This could involve querying the database, making external API calls, etc. this.logger.log(`Getting restaurant subscription for ID: ${subscriptionId}`); // For now, return a placeholder response // You should implement the actual logic based on your business requirements return { subscriptionId, message: "Restaurant subscription endpoint created successfully", // Add actual data structure based on your requirements }; } async getSmsCountByRestaurant(page: number, limit: number) { try { const { data } = await firstValueFrom( this.httpService .get('super-admin/notifications/sms-count', { params: { page, limit }, }) .pipe( catchError((err: AxiosError) => { this.logger.error("error in getting SMS count by restaurant", err); throw new BadRequestException("Failed to fetch SMS count data"); }), ), ); return data; } catch (error) { this.logger.error("error in getSmsCountByRestaurant", error); throw error; } } }