From f05ee3e854f169814775da77530b80583998589d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D1=83=D1=80=20=D0=93=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D1=86=D0=BA=D0=B8=D0=B9?= Date: Mon, 19 Oct 2026 16:17:57 +0500 Subject: [PATCH] fix: number a new report after the highest number in the project Counting non-deleted reports reused numbers (and photo folders) after a soft delete. Deleted reports are now included. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../report/dataverseReportRepository.test.ts | 15 +++++++++++---- .../pages/report/dataverseReportRepository.ts | 15 +++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/webparts/stroyBot/pages/report/dataverseReportRepository.test.ts b/src/webparts/stroyBot/pages/report/dataverseReportRepository.test.ts index 786e321..f14e4f3 100644 --- a/src/webparts/stroyBot/pages/report/dataverseReportRepository.test.ts +++ b/src/webparts/stroyBot/pages/report/dataverseReportRepository.test.ts @@ -26,8 +26,8 @@ const bodyOf = (body: string | ArrayBuffer | undefined): unknown => JSON.parse(S describe('адреса Dataverse (1:1 со stroy-bot-report)', () => { it('отчёт, счётчик, строки, факт', () => { expect(DV_PATHS.report('r1')).toEqual('cree9_reports(r1)'); - expect(DV_PATHS.reportCount(5)).toEqual( - 'cree9_reports?$filter=cree9_projectid eq 5 and cree9_deleted ne true&$count=true&$top=1&$select=cree9_number' + expect(DV_PATHS.lastReportNumber(5)).toEqual( + 'cree9_reports?$filter=cree9_projectid eq 5&$orderby=cree9_number desc&$top=1&$select=cree9_number' ); expect(DV_PATHS.reportData('r1')).toEqual('cree9_report_datas?$filter=_cree9_column1_value eq r1'); expect(DV_PATHS.jobTotalFact('j1')).toEqual('cree9_report_datas?$filter=_cree9_jobid_value eq j1&$select=cree9_value'); @@ -165,11 +165,18 @@ describe('saveReportWithData', () => { }); describe('прочие операции', () => { - it('номер нового отчёта = количество неудалённых + 1', async () => { - const client = createFakeHttpClient([{ match: '$count=true', response: { body: { '@odata.count': 7, value: [] } } }]); + it('номер нового отчёта = наибольший номер в проекте (включая удалённые) + 1', async () => { + const client = createFakeHttpClient([ + { match: 'cree9_number desc', response: { body: { value: [{ cree9_number: 7 }] } } } + ]); expect(await createDataverseReportRepository(client, DV).getNextReportNumber(5)).toEqual(8); }); + it('первый отчёт проекта получает номер 1', async () => { + const client = createFakeHttpClient([{ match: 'cree9_number desc', response: { body: { value: [] } } }]); + expect(await createDataverseReportRepository(client, DV).getNextReportNumber(5)).toEqual(1); + }); + it('утверждение — PATCH cree9_aprooved: true', async () => { const client = createFakeHttpClient([{ match: 'cree9_reports(r1)', response: { status: 204 } }]); await createDataverseReportRepository(client, DV).approveReport('r1'); diff --git a/src/webparts/stroyBot/pages/report/dataverseReportRepository.ts b/src/webparts/stroyBot/pages/report/dataverseReportRepository.ts index dd5f292..df7c443 100644 --- a/src/webparts/stroyBot/pages/report/dataverseReportRepository.ts +++ b/src/webparts/stroyBot/pages/report/dataverseReportRepository.ts @@ -50,9 +50,10 @@ export const DV_PATHS = { `?$select=ReferencingAttribute,ReferencingEntityNavigationPropertyName` + `&$filter=ReferencingAttribute eq 'cree9_parentid'`, report: (reportId: string): string => `${DV_TABLES.reports}(${reportId})`, - reportCount: (projectId: number): string => - `${DV_TABLES.reports}?$filter=cree9_projectid eq ${projectId} and cree9_deleted ne true` + - `&$count=true&$top=1&$select=cree9_number`, + // Удалённые отчёты не исключаются: их номера (и папки фото {projectId}_{номер}) повторно не выдаются. + lastReportNumber: (projectId: number): string => + `${DV_TABLES.reports}?$filter=cree9_projectid eq ${projectId}` + + `&$orderby=cree9_number desc&$top=1&$select=cree9_number`, jobTotalFact: (jobId: string): string => `${DV_TABLES.reportData}?$filter=_cree9_jobid_value eq ${jobId}&$select=cree9_value`, reportData: (reportId: string): string => `${DV_TABLES.reportData}?$filter=_cree9_column1_value eq ${reportId}`, @@ -252,9 +253,11 @@ export function createDataverseReportRepository(client: IHttpClient, baseUrl: st getReportById: (reportId) => get(DV_PATHS.report(reportId)), getNextReportNumber: async (projectId) => { - // 🐞 Номер = число неудалённых отчётов + 1: после мягкого удаления номер может повториться. - const result = await get<{ '@odata.count'?: number }>(DV_PATHS.reportCount(projectId)); - return (result['@odata.count'] || 0) + 1; + // В старом коде номер = число неудалённых отчётов + 1, и после мягкого удаления номера повторялись — + // исправлено при проверке T-REP-23: номер = наибольший номер в проекте + 1. + const result = await get<{ value?: Array<{ cree9_number?: number }> }>(DV_PATHS.lastReportNumber(projectId)); + const lastNumber = result.value?.[0]?.cree9_number || 0; + return lastNumber + 1; }, approveReport: (reportId) => patch(DV_PATHS.report(reportId), { cree9_aprooved: true }),