Отпуск: зелёное сообщение об отправке в ЭДО без подробностей — ответ 200 значит принято
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -46,8 +46,8 @@
|
|||||||
имени физического лица; БИН нужны ЭДО только чтобы выбрать сертификат Sigex (mTLS) нужной компании.
|
имени физического лица; БИН нужны ЭДО только чтобы выбрать сертификат Sigex (mTLS) нужной компании.
|
||||||
Запрос один на все файлы: ЭДО принимает его целиком или отклоняет целиком (например, если у какой-то
|
Запрос один на все файлы: ЭДО принимает его целиком или отклоняет целиком (например, если у какой-то
|
||||||
компании не распознан), поэтому повтор безопасен. Если у компании нет сертификата Sigex, ЭДО всё равно
|
компании не распознан), поэтому повтор безопасен. Если у компании нет сертификата Sigex, ЭДО всё равно
|
||||||
сохраняет её документ (`awaiting_certificate: true`), но подписать его нельзя, пока администратор не
|
сохраняет её документ, но подписать его нельзя, пока администратор не загрузит сертификат. Ответ 200
|
||||||
загрузит сертификат — тогда подписание откроется само. В зелёном сообщении такие компании названы отдельно.
|
значит «принято»: в зелёном сообщении просто «Документы отправлены на подписание в ЭДО».
|
||||||
- **ИИН** берётся из `GET /Employee/ByEmail` (поле `Iin`), **БИН компаний** — из `GET /Dictionary/Companies`
|
- **ИИН** берётся из `GET /Employee/ByEmail` (поле `Iin`), **БИН компаний** — из `GET /Dictionary/Companies`
|
||||||
по `CompanyId` каждой записи сотрудника (`shared/edo/signingTarget.ts`). Компания без БИН в справочнике
|
по `CompanyId` каждой записи сотрудника (`shared/edo/signingTarget.ts`). Компания без БИН в справочнике
|
||||||
пропускается и показывается в сообщении; остальные уходят.
|
пропускается и показывается в сообщении; остальные уходят.
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import { FORM_ID, IFormData, EMPTY_DATA, SetField } from './model';
|
|||||||
import { loadVacationRequest } from './load';
|
import { loadVacationRequest } from './load';
|
||||||
import { vacationApprovalService } from './submit';
|
import { vacationApprovalService } from './submit';
|
||||||
import { IVacationSigningResult, sendVacationForSigning } from './sendToSign';
|
import { IVacationSigningResult, sendVacationForSigning } from './sendToSign';
|
||||||
import { describeSigning } from './signingMessage';
|
|
||||||
import { RequestSection } from './sections/RequestSection';
|
import { RequestSection } from './sections/RequestSection';
|
||||||
import { useStableCallback } from '../../shared/useStableCallback';
|
import { useStableCallback } from '../../shared/useStableCallback';
|
||||||
|
|
||||||
@@ -162,7 +161,7 @@ const VacationView: React.FC<IVacationViewProps> = ({ context, itemId, formKey,
|
|||||||
.then((initiatorEmail) => sendVacationForSigning(context, { data, employeeName, itemId, code, initiatorEmail }))
|
.then((initiatorEmail) => sendVacationForSigning(context, { data, employeeName, itemId, code, initiatorEmail }))
|
||||||
.then((result): string | undefined => {
|
.then((result): string | undefined => {
|
||||||
setSigningResult(result);
|
setSigningResult(result);
|
||||||
return describeSigning(result, data.Employee);
|
return 'Документы отправлены на подписание в ЭДО.';
|
||||||
})
|
})
|
||||||
.catch((e): string | undefined => {
|
.catch((e): string | undefined => {
|
||||||
setSigningError(
|
setSigningError(
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ export interface IVacationToSign {
|
|||||||
export interface IVacationSigningResult {
|
export interface IVacationSigningResult {
|
||||||
/** Названия компаний, по которым заявление отправлено на подпись. */
|
/** Названия компаний, по которым заявление отправлено на подпись. */
|
||||||
sent: string[];
|
sent: string[];
|
||||||
/**
|
|
||||||
* Компании, у которых в ЭДО нет сертификата Sigex: заявление там сохранено, но подписать его нельзя,
|
|
||||||
* пока администратор не загрузит сертификат. Подписание откроется само — это подмножество `sent`.
|
|
||||||
*/
|
|
||||||
awaitingCertificate: string[];
|
|
||||||
/** Компании сотрудника, по которым документ не собрать (нет БИН в справочнике), и почему. */
|
/** Компании сотрудника, по которым документ не собрать (нет БИН в справочнике), и почему. */
|
||||||
skipped: ISkippedCompany[];
|
skipped: ISkippedCompany[];
|
||||||
}
|
}
|
||||||
@@ -110,17 +105,14 @@ export async function sendVacationForSigning(
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
const accepted = await submitSigningRequest(context, {
|
await submitSigningRequest(context, {
|
||||||
recipient: { iin: targets.iin, email: data.Employee, name: targets.name },
|
recipient: { iin: targets.iin, email: data.Employee, name: targets.name },
|
||||||
initiatorEmail: vacation.initiatorEmail || data.Employee,
|
initiatorEmail: vacation.initiatorEmail || data.Employee,
|
||||||
files
|
files
|
||||||
});
|
});
|
||||||
|
|
||||||
const waitingBins = accepted.documents.filter((d) => d.awaitingCertificate).map((d) => d.companyBin);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sent: targets.companies.map((c) => c.name),
|
sent: targets.companies.map((c) => c.name),
|
||||||
awaitingCertificate: targets.companies.filter((c) => waitingBins.indexOf(c.bin) >= 0).map((c) => c.name),
|
|
||||||
skipped: targets.skipped
|
skipped: targets.skipped
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
import type { IVacationSigningResult } from './sendToSign';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Фраза для зелёного сообщения «Решение сохранено…»: что ушло на подпись, а что сохранено и ждёт
|
|
||||||
* сертификата Sigex своей компании (подписание откроется после его загрузки).
|
|
||||||
*/
|
|
||||||
export function describeSigning(result: IVacationSigningResult, employeeEmail: string): string {
|
|
||||||
const ready = result.sent.filter((name) => result.awaitingCertificate.indexOf(name) < 0);
|
|
||||||
const parts: string[] = [];
|
|
||||||
|
|
||||||
if (ready.length > 0) {
|
|
||||||
parts.push(`Документы отправлены на подписание в ЭДО (${ready.join(', ')}): ссылка для подписания ушла на ${employeeEmail}.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.awaitingCertificate.length > 0) {
|
|
||||||
parts.push(
|
|
||||||
`Документы сохранены в ЭДО, но ждут загрузки сертификата Sigex по компаниям: ${result.awaitingCertificate.join(', ')}. ` +
|
|
||||||
`Подписание откроется само, когда администратор загрузит сертификат; ссылка придёт на ${employeeEmail}.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts.join(' ');
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@ import { IEmployeeOrganization } from '../dictionary/models/IEmployeeOrganizatio
|
|||||||
import { describeEdoError } from './edoErrors';
|
import { describeEdoError } from './edoErrors';
|
||||||
import { splitFio } from './fio';
|
import { splitFio } from './fio';
|
||||||
import { resolveSigningTargets } from './signingTarget';
|
import { resolveSigningTargets } from './signingTarget';
|
||||||
import { describeSigning } from '../../forms/Vacation/signingMessage';
|
|
||||||
|
|
||||||
const TANSU_ID = '9de064a4-44c8-88ef-11ec-8284930fad96';
|
const TANSU_ID = '9de064a4-44c8-88ef-11ec-8284930fad96';
|
||||||
|
|
||||||
@@ -151,26 +150,3 @@ describe('текст ошибки ЭДО', () => {
|
|||||||
expect(describeEdoError(403, '')).toContain('403');
|
expect(describeEdoError(403, '')).toContain('403');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('сообщение об отправке в ЭДО', () => {
|
|
||||||
it('всё ушло на подпись', () => {
|
|
||||||
const text = describeSigning({ sent: ['ТОО А', 'ТОО Б'], awaitingCertificate: [], skipped: [] }, 'a@b.kz');
|
|
||||||
|
|
||||||
expect(text).toContain('отправлены на подписание в ЭДО (ТОО А, ТОО Б)');
|
|
||||||
expect(text).not.toContain('сертификат');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('у части компаний нет сертификата — документы сохранены и ждут', () => {
|
|
||||||
const text = describeSigning({ sent: ['ТОО А', 'ТОО Б'], awaitingCertificate: ['ТОО Б'], skipped: [] }, 'a@b.kz');
|
|
||||||
|
|
||||||
expect(text).toContain('отправлены на подписание в ЭДО (ТОО А)');
|
|
||||||
expect(text).toContain('ждут загрузки сертификата Sigex по компаниям: ТОО Б');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('сертификата нет ни у кого', () => {
|
|
||||||
const text = describeSigning({ sent: ['ТОО А'], awaitingCertificate: ['ТОО А'], skipped: [] }, 'a@b.kz');
|
|
||||||
|
|
||||||
expect(text).not.toContain('отправлены на подписание');
|
|
||||||
expect(text).toContain('ждут загрузки сертификата Sigex');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user