- number-поля теперь рендерятся как text + inputMode=numeric, чтобы браузер не округлял значения через input type=number - пробелы при вставке в number-поля удаляются - бэкенд нормализует значения number-полей в строку перед сохранением - добавлен хелпер normalizeFieldValueForStorage Closes: искажение расчётного счёта и других длинных числовых полей
77 lines
2.6 KiB
SQL
77 lines
2.6 KiB
SQL
UPDATE "automations"
|
||
SET "code" = $CODE$
|
||
const RENTAL_FORM_ID = 15;
|
||
const MACHINE_FIELD_CODE = 'field_3';
|
||
const RENTAL_STATUS_NAME = 'В аренде';
|
||
|
||
const task = ctx.triggerData?.task;
|
||
if (!task || task.formId !== RENTAL_FORM_ID) {
|
||
ctx.result = { allow: true };
|
||
return;
|
||
}
|
||
|
||
const statuses = await ctx.forms.getStatuses(RENTAL_FORM_ID);
|
||
const rentalStatus = statuses.find(s => s.name.trim().toLowerCase() === RENTAL_STATUS_NAME.toLowerCase());
|
||
if (!rentalStatus) {
|
||
ctx.log('Статус "В аренде" не найден');
|
||
ctx.result = { allow: true };
|
||
return;
|
||
}
|
||
|
||
const formFields = await ctx.forms.getFields(RENTAL_FORM_ID);
|
||
const machineField = formFields.find(f => f.code === MACHINE_FIELD_CODE);
|
||
if (!machineField) {
|
||
ctx.log('Поле Машина не найдено');
|
||
ctx.result = { allow: true };
|
||
return;
|
||
}
|
||
|
||
const machineValue = task.customFields?.[`customField_${machineField.id}`] ?? task.customFields?.[MACHINE_FIELD_CODE];
|
||
if (!machineValue) {
|
||
ctx.result = { allow: true };
|
||
return;
|
||
}
|
||
|
||
const machineTaskId = parseInt(machineValue, 10);
|
||
if (!machineTaskId) {
|
||
ctx.result = { allow: true };
|
||
return;
|
||
}
|
||
|
||
const machineTask = await ctx.tasks.get(machineTaskId);
|
||
const machineName = machineTask?.title || `Машина #${machineTaskId}`;
|
||
|
||
const existingTasks = await ctx.tasks.list(RENTAL_FORM_ID);
|
||
for (const t of existingTasks) {
|
||
if (t.currentStatusId !== rentalStatus.id) continue;
|
||
const values = await ctx.tasks.getFieldValues(t.id);
|
||
const existingMachine = values.find(v => v.fieldId === machineField.id)?.value;
|
||
if (String(existingMachine) === String(machineValue)) {
|
||
const [assignees, author] = await Promise.all([
|
||
ctx.tasks.getAssignees(t.id),
|
||
t.createdBy ? ctx.users.get(t.createdBy) : null,
|
||
]);
|
||
const assigneeNames = assignees.map(a =>
|
||
`${a.user.firstName || ''} ${a.user.middleName || ''} ${a.user.lastName || ''}`.trim() || a.user.email
|
||
).join(', ') || null;
|
||
const authorName = author
|
||
? `${author.firstName || ''} ${author.middleName || ''} ${author.lastName || ''}`.trim() || author.email
|
||
: null;
|
||
|
||
const renterName = assigneeNames || authorName || 'неизвестен';
|
||
|
||
ctx.result = {
|
||
allow: false,
|
||
error: `${machineName} уже в аренде. Арендатор: ${renterName}. Активная аренда: #${t.id}`,
|
||
activeRentalTaskId: t.id,
|
||
assignedToName: renterName,
|
||
};
|
||
return;
|
||
}
|
||
}
|
||
|
||
ctx.result = { allow: true };
|
||
$CODE$,
|
||
"updated_at" = now()
|
||
WHERE "organization_id" = 1 AND "name" = 'Контроль дублирования аренды машин';
|