169 lines
5.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* eslint-disable canonical/id-match */
import { getClientWithToken } from '../apollo/client';
import * as GQL from '../types';
import { Enum_Slot_State } from '../types';
import { BaseService } from './base';
import { CustomersService } from './customers';
import { NotifyService } from './notify';
import { ServicesService } from './services';
import { SlotsService } from './slots';
import { type VariablesOf } from '@graphql-typed-document-node/core';
import { isCustomerMaster } from '@repo/utils/customer';
import { formatTime, sumTime } from '@repo/utils/datetime-format';
const ERRORS = {
INVALID_CLIENT: 'Invalid client',
INVALID_MASTER: 'Invalid master',
INVALID_SERVICE_DURATION: 'Invalid service duration',
MISSING_CLIENT: 'Missing client id',
MISSING_ORDER: 'Order not found',
MISSING_SERVICE_ID: 'Missing service id',
MISSING_SERVICES: 'Missing services',
MISSING_SLOT: 'Missing slot id',
MISSING_START_TIME: 'Missing time start',
MISSING_USER: 'User not found',
NO_PERMISSION: 'No permission',
SLOT_CLOSED: 'Slot is closed',
};
export class OrdersService extends BaseService {
async createOrder(variables: {
input: Omit<VariablesOf<typeof GQL.CreateOrderDocument>['input'], 'time_end'>;
}) {
if (!variables.input.slot) throw new Error(ERRORS.MISSING_SLOT);
if (!variables.input.client) throw new Error(ERRORS.MISSING_CLIENT);
if (!variables.input.services?.length) throw new Error(ERRORS.MISSING_SERVICES);
if (!variables.input.services[0]) throw new Error(ERRORS.MISSING_SERVICE_ID);
if (!variables.input.time_start) throw new Error(ERRORS.MISSING_START_TIME);
const customersService = new CustomersService(this.customer);
const slotsService = new SlotsService(this.customer);
const servicesService = new ServicesService(this.customer);
const { customer } = await customersService.getCustomer(this.customer);
if (!customer) throw new Error(ERRORS.MISSING_USER);
const { slot } = await slotsService.getSlot({ documentId: variables.input.slot });
if (slot?.state === Enum_Slot_State.Closed) {
throw new Error(ERRORS.SLOT_CLOSED);
}
const isMaster = isCustomerMaster(customer);
if (!isMaster) {
if (customer.documentId !== variables.input.client) {
throw new Error(ERRORS.INVALID_CLIENT);
}
const { customers } = await customersService.getMasters(this.customer);
const masters = customers.at(0)?.masters;
const masterId = slot?.master?.documentId;
if (!masters?.some((master) => master?.documentId === masterId)) {
throw new Error(ERRORS.INVALID_MASTER);
}
}
if (isMaster && slot?.master?.documentId !== customer.documentId) {
throw new Error(ERRORS.INVALID_MASTER);
}
const { service } = await servicesService.getService({
documentId: variables.input.services[0],
});
if (!service?.duration) throw new Error(ERRORS.INVALID_SERVICE_DURATION);
const endTime = sumTime(variables.input.time_start, service?.duration);
const { mutate } = await getClientWithToken();
const mutationResult = await mutate({
mutation: GQL.CreateOrderDocument,
variables: {
...variables,
input: {
...variables.input,
state: isMaster ? GQL.Enum_Order_State.Approved : GQL.Enum_Order_State.Created,
time_end: formatTime(endTime).db(),
},
},
});
const error = mutationResult.errors?.at(0);
if (error) throw new Error(error.message);
// Уведомление об создании заказа
const notifyService = new NotifyService(this.customer);
notifyService.orderCreated(variables);
return mutationResult.data;
}
async getOrder(variables: VariablesOf<typeof GQL.GetOrderDocument>) {
const { query } = await getClientWithToken();
const result = await query({
query: GQL.GetOrderDocument,
variables,
});
return result.data;
}
async getOrders(variables: VariablesOf<typeof GQL.GetOrdersDocument>) {
const { query } = await getClientWithToken();
const result = await query({
query: GQL.GetOrdersDocument,
variables,
});
return result.data;
}
async updateOrder(variables: VariablesOf<typeof GQL.UpdateOrderDocument>) {
const customersService = new CustomersService(this.customer);
const { customer } = await customersService.getCustomer(this.customer);
if (!customer) throw new Error(ERRORS.MISSING_USER);
const { query } = await getClientWithToken();
const {
data: { order },
} = await query({
query: GQL.GetOrderDocument,
variables: { documentId: variables.documentId },
});
if (!order) throw new Error(ERRORS.MISSING_ORDER);
const isMaster = isCustomerMaster(customer);
const hasPermission =
(isMaster && order.slot?.master?.documentId === customer.documentId) ||
(!isMaster && order.client?.documentId === customer.documentId);
if (!hasPermission) throw new Error(ERRORS.NO_PERMISSION);
const { mutate } = await getClientWithToken();
const mutationResult = await mutate({
mutation: GQL.UpdateOrderDocument,
variables,
});
const error = mutationResult.errors?.at(0);
if (error) throw new Error(error.message);
// Уведомление об изменении заказа
const notifyService = new NotifyService(this.customer);
notifyService.orderUpdated(variables);
return mutationResult.data;
}
}