Сводная ОСВ: пары участников без встречных записей вместо «сопоставьте все» (#195, AURORA-1746) #196

Merged
aep merged 26 commits from feat/195-counter-pairs into main 2026-10-27 22:09:35 +03:00
2 changed files with 12 additions and 8 deletions
Showing only changes of commit 4942120005 - Show all commits

View File

@ -214,10 +214,17 @@ describe('counterPairsWarning', () => {
expect(w.headline).toBe('Нет встречных записей: 1 пара у 1 участника.');
expect(w.details.endsWith('Ещё 1260 строк без ИНН учтены как внешние.')).toBe(true);
});
it('пять пар у трёх участников', () => {
const ps = [pair('a', 'b'), pair('a', 'c'), pair('a', 'd'), pair('e', 'b'), pair('f', 'c')];
it('пять пар у трёх участников (M — разные missing_id)', () => {
const ps = [pair('a', 'c'), pair('a', 'd'), pair('a', 'e'), pair('b', 'c'), pair('b', 'd')];
expect(counterPairsWarning(ps, 5).headline).toBe('Нет встречных записей: 5 пар у 3 участников.');
});
it('M считает missing_id, а не holder_id', () => {
const ps = [pair('a', 'b'), pair('a', 'c'), pair('d', 'b'), pair('e', 'b'), pair('f', 'b')];
expect(counterPairsWarning(ps, 5).headline).toBe('Нет встречных записей: 5 пар у 2 участников.');
});
it('две пары у двух участников', () => {
expect(counterPairsWarning([pair('a', 'b'), pair('a', 'c')], 1).headline).toBe('Нет встречных записей: 2 пары у 2 участников.');
});
it('без строк без ИНН', () => {
expect(counterPairsWarning([pair('a', 'b')], 0).details).toBe(
'Возможно, контрагент среди строк без ИНН, его ИНН не найден в справочнике или это пропуск в учёте.',

View File

@ -150,13 +150,10 @@ export const rememberCounterPairsShown = (
/** Тексты модалки «Проверьте встречные записи участников». */
export const counterPairsWarning = (pairs: readonly CounterPairOut[], unmappedTotal: number): { headline: string; details: string } => {
const holders = new Set(pairs.map((p) => p.holder_id)).size;
const missing = new Set(pairs.map((p) => p.missing_id)).size;
const base = 'Возможно, контрагент среди строк без ИНН, его ИНН не найден в справочнике или это пропуск в учёте.';
return {
headline: `Нет встречных записей: ${pairs.length} ${pluralRu(pairs.length, ['пара', 'пары', 'пар'])} у ${holders} ${pluralRu(holders, ['участника', 'участников', 'участников'])}.`,
details:
unmappedTotal > 0
? `${base} Ещё ${unmappedTotal} ${pluralRu(unmappedTotal, ['строка', 'строки', 'строк'])} без ИНН учтены как внешние.`
: base,
headline: `Нет встречных записей: ${pairs.length} ${pluralRu(pairs.length, ['пара', 'пары', 'пар'])} у ${missing} ${pluralRu(missing, ['участника', 'участников', 'участников'])}.`,
details: unmappedTotal > 0 ? `${base} Ещё ${unmappedTotal} строк без ИНН учтены как внешние.` : base,
};
};