From 7426ff8a3f2ee501ed216690059ba544997f3b55 Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Tue, 2 Sep 2025 21:23:11 +0300 Subject: [PATCH] feat(orders): implement order limit checks for clients and masters - Added order limit validation in the `OrdersService` to check if a master has reached their monthly order limit. - Introduced new error messages for exceeding order limits, enhancing user feedback for both clients and masters. - Integrated `SubscriptionsService` to manage subscription status and remaining order counts effectively. --- packages/graphql/api/orders.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/graphql/api/orders.ts b/packages/graphql/api/orders.ts index 2ecd2e7..e5e41d2 100644 --- a/packages/graphql/api/orders.ts +++ b/packages/graphql/api/orders.ts @@ -7,6 +7,7 @@ import { BaseService } from './base'; import { CustomersService } from './customers'; import { ServicesService } from './services'; import { SlotsService } from './slots'; +import { SubscriptionsService } from './subscriptions'; import { type VariablesOf } from '@graphql-typed-document-node/core'; import { isCustomerMaster } from '@repo/utils/customer'; import { getMinutes, isBeforeNow, isNowOrAfter } from '@repo/utils/datetime-format'; @@ -35,6 +36,10 @@ export const ERRORS = { NOT_FOUND_MASTER: 'Мастер не найден', NOT_FOUND_ORDER: 'Заказ не найден', NOT_FOUND_ORDER_SLOT: 'Слот заказа не найден', + ORDER_LIMIT_EXCEEDED_CLIENT: + 'Достигнут лимит заказов у этого мастера на месяц. Попробуйте записаться позже или к другому мастеру.', + ORDER_LIMIT_EXCEEDED_MASTER: + 'Достигнут лимит заказов на месяц. Оформите Pro подписку для продолжения работы.', OVERLAPPING_TIME: 'Время пересекается с другими заказами', SLOT_CLOSED: 'Слот закрыт', }; @@ -51,6 +56,30 @@ export class OrdersService extends BaseService { if (!variables.input.services?.length) throw new Error(ERRORS.MISSING_SERVICES); if (!variables.input.client) throw new Error(ERRORS.MISSING_CLIENT); + // Проверка лимита заказов мастера слота + const subscriptionsService = new SubscriptionsService(this._user); + + // Получаем информацию о мастере слота для проверки лимита + const slotService = new SlotsService(this._user); + const { slot } = await slotService.getSlot({ documentId: variables.input.slot }); + + if (!slot?.master?.telegramId) { + throw new Error(ERRORS.INVALID_MASTER); + } + + const { remainingOrdersCount, subscription } = await subscriptionsService.getSubscription( + slot.master, + ); + + // Если у мастера слота нет активной подписки и не осталось доступных заказов + if (!subscription?.isActive && remainingOrdersCount <= 0) { + throw new Error( + isCustomerMaster(customer) + ? ERRORS.ORDER_LIMIT_EXCEEDED_MASTER + : ERRORS.ORDER_LIMIT_EXCEEDED_CLIENT, + ); + } + const servicesService = new ServicesService(this._user); // Получаем все услуги по их идентификаторам