feat: enhance order creation validation with additional checks for client, slot, and service

This commit is contained in:
vchikalkin 2025-07-11 13:38:42 +03:00
parent 4ff50e42b9
commit 2686249cc9

View File

@ -2,6 +2,12 @@ const ERR_INVALID_TIME = 'Некорректное время';
const ERR_OVERLAPPING_TIME = 'Время пересекается с другими заказами'; const ERR_OVERLAPPING_TIME = 'Время пересекается с другими заказами';
const ERR_INACTIVE_CLIENT = 'Клиент не активен'; const ERR_INACTIVE_CLIENT = 'Клиент не активен';
const ERR_INACTIVE_MASTER = 'Мастер не активен'; const ERR_INACTIVE_MASTER = 'Мастер не активен';
const ERR_SLOT_CLOSED = 'Слот закрыт';
const ERR_INVALID_CLIENT = 'Некорректный клиент';
const ERR_INVALID_MASTER = 'Некорректный мастер';
const ERR_MISSING_CLIENT = 'Не указан клиент';
const ERR_MISSING_SLOT = 'Не указан слот';
const ERR_MISSING_SERVICE = 'Не указан сервис';
function timeToDate(time: string) { function timeToDate(time: string) {
return new Date(`1970-01-01T${time}Z`); return new Date(`1970-01-01T${time}Z`);
@ -26,47 +32,79 @@ function extractId(input: any): number | null {
export default { export default {
async beforeCreate(event) { async beforeCreate(event) {
const { data } = event.params; const { data } = event.params;
const { time_start, time_end, client } = data; const { time_start, time_end, client, services } = data;
const clientId = extractId(client); const clientId = extractId(client);
const slotId = extractId(data.slot); const slotId = extractId(data.slot);
// Проверка наличия обязательных полей
if (!slotId) throw new Error(ERR_MISSING_SLOT);
if (!clientId) throw new Error(ERR_MISSING_CLIENT);
if (!extractId(services)) throw new Error(ERR_MISSING_SERVICE);
// Проверка корректности времени заказа.
if (!time_start || !time_end) { if (!time_start || !time_end) {
throw new Error(ERR_INVALID_TIME); throw new Error(ERR_INVALID_TIME);
} }
if (timeToDate(time_start) >= timeToDate(time_end)) { if (timeToDate(time_start) >= timeToDate(time_end)) {
throw new Error(ERR_INVALID_TIME); throw new Error(ERR_INVALID_TIME);
} }
const isClientActive = await strapi.db // Получаем слот
const slot = await strapi.db.query('api::slot.slot').findOne({
where: { id: slotId },
populate: ['master'],
});
if (!slot) throw new Error(ERR_MISSING_SLOT);
// 1. Слот не должен быть закрыт
if (slot.state === 'closed') {
throw new Error(ERR_SLOT_CLOSED);
}
// Получаем клиента
const clientEntity = await strapi.db
.query('api::customer.customer') .query('api::customer.customer')
.findOne({ .findOne({
where: { where: { id: clientId },
id: clientId, populate: { masters: true },
active: true,
},
}); });
console.log('🚀 ~ clientEntity ~ clientEntity:', clientEntity);
if (!clientEntity) throw new Error(ERR_MISSING_CLIENT);
if (!isClientActive) { // Проверка активности клиента
if (!clientEntity.active) {
throw new Error(ERR_INACTIVE_CLIENT); throw new Error(ERR_INACTIVE_CLIENT);
} }
const slot = await strapi.db.query('api::slot.slot').findOne({ // Получаем мастера слота
where: { const slotMaster = slot.master;
id: slotId, if (!slotMaster) throw new Error(ERR_INVALID_MASTER);
}, if (!slotMaster.active || slotMaster.role !== 'master') {
populate: ['master'],
});
const master = slot.master;
const isMasterActive = master.active && master.role === 'master';
if (!isMasterActive) {
throw new Error(ERR_INACTIVE_MASTER); throw new Error(ERR_INACTIVE_MASTER);
} }
// 2. Проверка ролей и связей
const isClientMaster = clientEntity.role === 'master';
const slotMasterId = slotMaster.id;
if (!isClientMaster) {
// Клиент не должен быть мастером слота
if (clientEntity.id === slotMasterId) {
throw new Error(ERR_INVALID_CLIENT);
}
// Клиент должен быть в списке клиентов мастера
const masters = clientEntity.masters?.map(m => m.id) || [];
if (!masters.includes(slotMasterId)) {
throw new Error(ERR_INVALID_MASTER);
}
} else {
// Мастер не может записать другого мастера
if (slotMasterId !== clientEntity.id) {
throw new Error(ERR_INVALID_MASTER);
}
}
// Проверка пересечений заказов по времени.
const overlappingEntities = await strapi.db const overlappingEntities = await strapi.db
.query('api::order.order') .query('api::order.order')
.findMany({ .findMany({
@ -83,7 +121,6 @@ export default {
}, },
populate: ['slot'], populate: ['slot'],
}); });
if (overlappingEntities.length > 0) { if (overlappingEntities.length > 0) {
throw new Error(ERR_OVERLAPPING_TIME); throw new Error(ERR_OVERLAPPING_TIME);
} }