|
@@ -13,10 +13,11 @@ import { RouterUtils } from "#utils/router-utils.js";
|
|
|
|
|
|
import { Request, Response } from "express";
|
|
import { Request, Response } from "express";
|
|
import sessionService from "#modules/users/auth/services/session-service.js";
|
|
import sessionService from "#modules/users/auth/services/session-service.js";
|
|
-import { CustomFieldWithUserCopyValue } from "#api/v_0.1.0/types/pe-types.js";
|
|
|
|
|
|
+import { CustomFieldWithValue } from "#api/v_0.1.0/types/custom-fields-types.js";
|
|
import { ApiError } from "#exceptions/api-error.js";
|
|
import { ApiError } from "#exceptions/api-error.js";
|
|
import { v4, v7 } from "uuid";
|
|
import { v4, v7 } from "uuid";
|
|
import { cPeService } from "./c-pe-service.js";
|
|
import { cPeService } from "./c-pe-service.js";
|
|
|
|
+import { cCustomFieldsValidateService } from "#modules/client/custom-fields/c-cf-validate-service.js";
|
|
|
|
|
|
class ClientPeController {
|
|
class ClientPeController {
|
|
async getEventPeTypes(
|
|
async getEventPeTypes(
|
|
@@ -60,69 +61,12 @@ class ClientPeController {
|
|
|
|
|
|
const eventId = event.eventId;
|
|
const eventId = event.eventId;
|
|
const userId = user.userId;
|
|
const userId = user.userId;
|
|
- const peType = await selPool.maybeOne(sql.type(
|
|
|
|
- z.object({
|
|
|
|
- peTypeId: DbSchema.act.peTypes.peTypeId,
|
|
|
|
- code: DbSchema.act.peTypes.code,
|
|
|
|
- name: DbSchema.act.peTypes.name,
|
|
|
|
- eventInstId: DbSchema.act.peTypes.eventInstId,
|
|
|
|
- fields: z.array(
|
|
|
|
- CustomFieldWithUserCopyValue.extend({ isCopyUserValue: z.boolean() }),
|
|
|
|
- ),
|
|
|
|
- }),
|
|
|
|
- )`
|
|
|
|
- select
|
|
|
|
- pt.pe_type_id as "peTypeId",
|
|
|
|
- pt.code,
|
|
|
|
- pt.name,
|
|
|
|
- pt.event_inst_id as "eventInstId",
|
|
|
|
- coalesce(jsonb_agg(jsonb_build_object(
|
|
|
|
- 'fieldDefinitionId',
|
|
|
|
- cfwv.field_definition_id,
|
|
|
|
- 'peFfId',
|
|
|
|
- pff.pe_ff_id,
|
|
|
|
- 'isCopyUserValue',
|
|
|
|
- pff.is_copy_user_value,
|
|
|
|
- 'code',
|
|
|
|
- cfwv.code,
|
|
|
|
- 'userCopyValue',
|
|
|
|
- ufwv.value,
|
|
|
|
- 'fieldTypeCode',
|
|
|
|
- cfwv.field_type_code,
|
|
|
|
- 'title',
|
|
|
|
- COALESCE(pff.field_title_override, cfwv.title),
|
|
|
|
- 'mask',
|
|
|
|
- cfwv.mask,
|
|
|
|
- 'options',
|
|
|
|
- cfwv.options,
|
|
|
|
- 'validators',
|
|
|
|
- cfwv.validators)) filter (
|
|
|
|
- where
|
|
|
|
- cfwv.field_definition_id is not null),
|
|
|
|
- '[]'::jsonb) as fields
|
|
|
|
- from
|
|
|
|
- act.pe_types pt
|
|
|
|
- -- необходимые поля
|
|
|
|
- left join act.pe_form_fields pff on
|
|
|
|
- pff.pe_type_id = pt.pe_type_id
|
|
|
|
- -- значение из профиля юзера
|
|
|
|
- left join ev.user_fields_with_values ufwv on
|
|
|
|
- pff.field_definition_id = ufwv.field_definition_id
|
|
|
|
- and ufwv.user_id = ${userId}
|
|
|
|
- and ufwv.event_id = ${eventId}
|
|
|
|
- and ufwv.value is not null
|
|
|
|
- -- только если нужно копировать
|
|
|
|
- and pff.is_copy_user_value = true
|
|
|
|
- left join cf.custom_fields_with_validators cfwv on
|
|
|
|
- pff.field_definition_id = cfwv.field_definition_id
|
|
|
|
- where
|
|
|
|
- pt.code = ${peTypeCode}
|
|
|
|
- group by
|
|
|
|
- pt.pe_type_id,
|
|
|
|
- pt.code,
|
|
|
|
- pt.name,
|
|
|
|
- pt.event_inst_id
|
|
|
|
- `);
|
|
|
|
|
|
+
|
|
|
|
+ const peType = await cPeService.getPeTypeWithFieldsAndUserCopyValues(
|
|
|
|
+ userId,
|
|
|
|
+ peTypeCode,
|
|
|
|
+ eventId,
|
|
|
|
+ );
|
|
|
|
|
|
if (!peType)
|
|
if (!peType)
|
|
throw ApiError.BadRequest(
|
|
throw ApiError.BadRequest(
|
|
@@ -139,33 +83,70 @@ class ClientPeController {
|
|
async createPe(req: Request, res: Response) {
|
|
async createPe(req: Request, res: Response) {
|
|
const event = await sessionService.getCurrentEventFromReq(req);
|
|
const event = await sessionService.getCurrentEventFromReq(req);
|
|
const user = sessionService.getUserFromReq(req);
|
|
const user = sessionService.getUserFromReq(req);
|
|
- const { form, peTypeId, name } = api.client.pe.POST_PartEntity.req.parse(
|
|
|
|
- req.body,
|
|
|
|
- );
|
|
|
|
|
|
+ const { fields, peTypeCode, name } =
|
|
|
|
+ api.client.pe.POST_PartEntity.req.formData.body.parse(
|
|
|
|
+ JSON.parse(req.body.body),
|
|
|
|
+ );
|
|
|
|
|
|
- await updPool.transaction(async (t) => {
|
|
|
|
- const peId = v7();
|
|
|
|
- await t.query(sql.unsafe`
|
|
|
|
- insert into act.part_entities
|
|
|
|
- (pe_id, pe_type_id, event_inst_id, owner_id, name)
|
|
|
|
- values
|
|
|
|
- (${peId}, ${peTypeId}, ${event.eventInstId}, ${user.userId}, ${name})
|
|
|
|
- `);
|
|
|
|
|
|
+ const files = req.files;
|
|
|
|
+
|
|
|
|
+ const peType = await cPeService.getPeTypeWithFields(peTypeCode);
|
|
|
|
+
|
|
|
|
+ if (!peType)
|
|
|
|
+ throw ApiError.BadRequest(
|
|
|
|
+ "peTypeNotFound",
|
|
|
|
+ "Тип сущности участия не найден",
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ const refFields = peType.fields.map((f) => ({
|
|
|
|
+ ...f,
|
|
|
|
+ idKey: "peFfId",
|
|
|
|
+ }));
|
|
|
|
+
|
|
|
|
+ // валидация
|
|
|
|
+ const validationResult =
|
|
|
|
+ await cCustomFieldsValidateService.processAndValidateFields({
|
|
|
|
+ inputFields: fields,
|
|
|
|
+ referenceFields: refFields,
|
|
|
|
+ files,
|
|
|
|
+ idKey: "peFfId",
|
|
|
|
+ addOldValue: false,
|
|
|
|
+ });
|
|
|
|
|
|
- for (const field of form) {
|
|
|
|
- await t.query(sql.unsafe`
|
|
|
|
- insert into act.pe_field_values
|
|
|
|
- (pe_ff_id, pe_id, value)
|
|
|
|
|
|
+ if (!validationResult.isValid)
|
|
|
|
+ throw ApiError.BadRequest(
|
|
|
|
+ "fieldsValidationFailed",
|
|
|
|
+ JSON.stringify(validationResult.messages),
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ const validatedFields = validationResult.checkedfields;
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+ //
|
|
|
|
+ // вставляем в базу и сохраняем файлы
|
|
|
|
+ const peId = v7();
|
|
|
|
+ await updPool.transaction(async (tr) => {
|
|
|
|
+ await tr.query(sql.unsafe`
|
|
|
|
+ insert into act.part_entities
|
|
|
|
+ (pe_id, pe_type_id, event_inst_id, owner_id, name)
|
|
values
|
|
values
|
|
- (${field.peFfId}, ${peId}, ${field.value})
|
|
|
|
|
|
+ (${peId}, ${peType.peTypeId}, ${event.eventInstId}, ${user.userId}, ${name})
|
|
`);
|
|
`);
|
|
- }
|
|
|
|
|
|
|
|
- RouterUtils.validAndSendResponse(api.client.pe.POST_PartEntity.res, res, {
|
|
|
|
- code: "success",
|
|
|
|
- peId,
|
|
|
|
|
|
+ await cCustomFieldsValidateService.saveCustomFieldValuesInTransaction({
|
|
|
|
+ tr,
|
|
|
|
+ parentId: peId,
|
|
|
|
+ action: "peCreate",
|
|
|
|
+ inputFields: validatedFields,
|
|
|
|
+ files,
|
|
|
|
+ isDeleteBefore: false,
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
+
|
|
|
|
+ RouterUtils.validAndSendResponse(api.client.pe.POST_PartEntity.res, res, {
|
|
|
|
+ code: "success",
|
|
|
|
+ peId,
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
async getMyPes(req: Request, res: Response) {
|
|
async getMyPes(req: Request, res: Response) {
|
|
@@ -256,7 +237,7 @@ class ClientPeController {
|
|
|
|
|
|
// валделец
|
|
// валделец
|
|
if (isOwner) {
|
|
if (isOwner) {
|
|
- const pe = await cPeService.getPeWithFieldsAndValues(peId);
|
|
|
|
|
|
+ const pe = await cPeService.getPeWithValues(peId);
|
|
const members = await cPeService.getMembers(peId);
|
|
const members = await cPeService.getMembers(peId);
|
|
const invites = await cPeService.getInvites(peId);
|
|
const invites = await cPeService.getInvites(peId);
|
|
|
|
|
|
@@ -408,7 +389,7 @@ class ClientPeController {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- updPool.transaction(async (t) => {
|
|
|
|
|
|
+ await updPool.transaction(async (t) => {
|
|
t.query(sql.unsafe`
|
|
t.query(sql.unsafe`
|
|
insert into act.pe_members
|
|
insert into act.pe_members
|
|
(pe_member_id, pe_id, user_id)
|
|
(pe_member_id, pe_id, user_id)
|
|
@@ -430,6 +411,86 @@ class ClientPeController {
|
|
peId: invite.peId,
|
|
peId: invite.peId,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ async getMyPesForActivity(req: Request, res: Response) {
|
|
|
|
+ const user = sessionService.getUserFromReq(req);
|
|
|
|
+
|
|
|
|
+ const event = await sessionService.getCurrentEventFromReq(req);
|
|
|
|
+
|
|
|
|
+ const pes = await selPool.any(sql.type(
|
|
|
|
+ z.object({
|
|
|
|
+ peId: DbSchema.act.partEntities.peId,
|
|
|
|
+ peTypeId: DbSchema.act.partEntities.peTypeId,
|
|
|
|
+ peTypeCode: DbSchema.act.peTypes.code,
|
|
|
|
+ peTypeName: DbSchema.act.peTypes.name,
|
|
|
|
+ eventInstId: DbSchema.act.partEntities.eventInstId,
|
|
|
|
+ ownerId: DbSchema.act.partEntities.ownerId,
|
|
|
|
+ name: DbSchema.act.partEntities.name,
|
|
|
|
+ members: z.array(
|
|
|
|
+ z.object({
|
|
|
|
+ peMemberId: DbSchema.act.peMembers.peMemberId,
|
|
|
|
+ userId: DbSchema.usr.users.userId,
|
|
|
|
+ email: DbSchema.usr.users.email,
|
|
|
|
+ fields: z.array(
|
|
|
|
+ CustomFieldWithValue.extend({
|
|
|
|
+ userEfId: z.string().uuid(),
|
|
|
|
+ }),
|
|
|
|
+ ),
|
|
|
|
+ }),
|
|
|
|
+ ),
|
|
|
|
+ fields: z.array(
|
|
|
|
+ CustomFieldWithValue.extend({
|
|
|
|
+ peFfId: z.string().uuid(),
|
|
|
|
+ }),
|
|
|
|
+ ),
|
|
|
|
+ }),
|
|
|
|
+ )`
|
|
|
|
+ select
|
|
|
|
+ pe.pe_id "peId",
|
|
|
|
+ pe.event_inst_id "eventInstId",
|
|
|
|
+ pe.owner_id "ownerId",
|
|
|
|
+ pe.pe_type_id "peTypeId",
|
|
|
|
+ pt.code "peTypeCode",
|
|
|
|
+ pt."name" "peTypeName",
|
|
|
|
+ pe."name",
|
|
|
|
+ coalesce(m.members, '[]'::jsonb) members,
|
|
|
|
+ v.fields
|
|
|
|
+ from
|
|
|
|
+ act.part_entities pe
|
|
|
|
+ join act.pe_types pt on
|
|
|
|
+ pt.pe_type_id = pe.pe_type_id
|
|
|
|
+ -- members
|
|
|
|
+ left join lateral (
|
|
|
|
+ select
|
|
|
|
+ jsonb_agg(jsonb_build_object(
|
|
|
|
+ 'peMemberId', m.pe_member_id,
|
|
|
|
+ 'userId', m.user_id,
|
|
|
|
+ 'email', m.email,
|
|
|
|
+ 'fields', m.fields
|
|
|
|
+ )) as members
|
|
|
|
+ from
|
|
|
|
+ act.pe_members_with_fields_and_values m
|
|
|
|
+ where
|
|
|
|
+ m.pe_id = pe.pe_id
|
|
|
|
+ ) m on
|
|
|
|
+ true
|
|
|
|
+ -- fields
|
|
|
|
+ left join act.pe_with_fields_and_values v on
|
|
|
|
+ v.pe_id = pe.pe_id
|
|
|
|
+ where
|
|
|
|
+ pe.event_inst_id = ${event.eventInstId}
|
|
|
|
+ and pe.owner_id = ${user.userId}
|
|
|
|
+ `);
|
|
|
|
+
|
|
|
|
+ RouterUtils.validAndSendResponse(
|
|
|
|
+ api.client.pe.GET_MyPesForActivity.res,
|
|
|
|
+ res,
|
|
|
|
+ {
|
|
|
|
+ code: "success",
|
|
|
|
+ pes: [...pes],
|
|
|
|
+ },
|
|
|
|
+ );
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
export const clientPeController = new ClientPeController();
|
|
export const clientPeController = new ClientPeController();
|