diff --git a/backend/src/admin/admin.module.ts b/backend/src/admin/admin.module.ts index c6262b3d..91560108 100644 --- a/backend/src/admin/admin.module.ts +++ b/backend/src/admin/admin.module.ts @@ -6,9 +6,10 @@ import { AdminService } from './admin.service'; import { AdminController } from './admin.controller'; import { AuthenticationModule } from 'src/authentication/authentication.module'; import { DocumentTemplateModule } from 'src/document_template/document_template.module'; +import { ProvisionModule } from 'src/provision/provision.module'; @Module({ - imports: [HttpModule, AuthenticationModule, DocumentTemplateModule], + imports: [HttpModule, AuthenticationModule, DocumentTemplateModule, ProvisionModule], providers: [AdminGuard, AdminService], exports: [AdminService], controllers: [AdminController], diff --git a/backend/src/app.controller.ts b/backend/src/app.controller.ts index c715d0db..2aa15911 100644 --- a/backend/src/app.controller.ts +++ b/backend/src/app.controller.ts @@ -367,7 +367,7 @@ export class AppController { // const groupMaxJsonArray = await this.reportService.getGroupMaxByVariant('NOTICE OF FINAL REVIEW'); const groupMaxJsonArray = []; try { - const nfrDataObject = await this.reportService.getActiveNfrDataByDtid(dtid); + const nfrDataObject = await this.reportService.getDocumentDataByDocTypeIdAndDtid(1, dtid); nfrData = nfrDataObject.nfrData; const provisionIds = nfrDataObject.provisionIds ? nfrDataObject.provisionIds : []; // const mandatoryProvisionIds = await this.reportService.getMandatoryProvisionsByVariant(variantName); diff --git a/backend/src/document_data/document_data.controller.ts b/backend/src/document_data/document_data.controller.ts index 76d0b1bf..8789d934 100644 --- a/backend/src/document_data/document_data.controller.ts +++ b/backend/src/document_data/document_data.controller.ts @@ -38,9 +38,9 @@ export class DocumentDataController { } } - @Get('dtid/:dtid') - findActiveByDtid(@Param('dtid') dtid: number) { - return this.documentDataService.findActiveByDtid(dtid); + @Get('dtid/:document_type_id/:dtid') + findActiveByDtid(@Param('dtid') dtid: number, @Param('document_type_id') document_type_id: number) { + return this.documentDataService.findDocumentDataByDocTypeIdAndDtid(document_type_id, dtid); } @Get('view/:documentDataId') diff --git a/backend/src/document_data/document_data.service.ts b/backend/src/document_data/document_data.service.ts index 63d7cb65..26bed656 100644 --- a/backend/src/document_data/document_data.service.ts +++ b/backend/src/document_data/document_data.service.ts @@ -43,7 +43,7 @@ export class DocumentDataService { 'document_data_variables', 'document_data_provisions', 'document_data_variables.document_variable', - 'document_data_provisions.provision', + 'document_data_provisions.document_provision', 'document_type', ], }); @@ -210,6 +210,7 @@ export class DocumentDataService { where: { active: true, }, + relations: ['document_type'], }); } @@ -237,39 +238,46 @@ export class DocumentDataService { const variableIds = existingDataVariables.map((dataVariable) => dataVariable.document_variable.id); return { documentData, provisionIds, variableIds }; } catch (err) { + console.log('Error in findByDocumentDataId'); console.log(err); return null; } } - async findActiveByDtid(dtid: number): Promise<{ + async findDocumentDataByDocTypeIdAndDtid( + document_type_id: number, + dtid: number + ): Promise<{ documentData: DocumentData; provisionIds: number[]; variableIds: number[]; }> { try { - const documentData = await this.documentDataRepository.findOne({ - where: { dtid: dtid, active: true }, + const documentData = await this.documentDataRepository.find({ + where: { dtid: dtid }, join: { alias: 'document_data', leftJoinAndSelect: { document_data_provisions: 'document_data.document_data_provisions', - provision: 'document_data_provisions.provision', + document_provision: 'document_data_provisions.document_provision', document_data_variables: 'document_data.document_data_variables', document_variable: 'document_data_variables.document_variable', }, }, }); + const filteredDocumentData = documentData.find((d) => d.document_type.id === document_type_id); + console.log(filteredDocumentData); const provisionIds = - documentData && documentData.document_data_provisions - ? documentData.document_data_provisions.map((dataProvision) => dataProvision.document_provision.id) + filteredDocumentData && filteredDocumentData.document_data_provisions + ? filteredDocumentData.document_data_provisions.map((dataProvision) => dataProvision.document_provision.id) : []; const variableIds = - documentData && documentData.document_data_variables - ? documentData.document_data_variables.map((dataVariable) => dataVariable.document_variable.id) + filteredDocumentData && filteredDocumentData.document_data_variables + ? filteredDocumentData.document_data_variables.map((dataVariable) => dataVariable.document_variable.id) : []; - return { documentData, provisionIds, variableIds }; + return { documentData: filteredDocumentData, provisionIds, variableIds }; } catch (err) { + console.log('Error in findActiveByDtid'); console.log(err); return null; } @@ -282,92 +290,95 @@ export class DocumentDataService { } async getVariablesByDtidAndDocType(dtid: number, document_type_id: number) { - // const documentType: DocumentType = await this.documentTemplateService.getDocumentType(document_type_id); - const documentData: DocumentData = await this.documentDataRepository.findOne({ - where: { dtid: dtid, document_type: { id: document_type_id } }, - join: { - alias: 'document_data', - leftJoinAndSelect: { - document_data_variables: 'document_data.document_data_variables', - document_variable: 'document_data_variables.document_variable', + try { + const documentData: DocumentData = await this.documentDataRepository.findOne({ + where: { dtid: dtid, document_type: { id: document_type_id } }, + join: { + alias: 'document_data', + leftJoinAndSelect: { + document_data_variables: 'document_data.document_data_variables', + document_variable: 'document_data_variables.document_variable', + }, }, - }, - }); - // if the documentData doesn't exist yet, return null. This null value is caught elsewhere. - if (!documentData) { - return null; - } - // saved variables attached to the documentData entry - const existingDataVariables: DocumentDataVariable[] = documentData.document_data_variables; - // all variables associated with the variant - const variables: ProvisionVariable[] = await this.provisionService.getVariablesByDocumentTypeId(document_type_id); - // inserting the existing variable_values to the set of all variables - for (const variable of variables) { - const existingDataVariable = existingDataVariables.find( - (dataVariable) => dataVariable.document_variable.id === variable.id - ); - if (existingDataVariable) { - variable.variable_value = existingDataVariable.data_variable_value; + }); + // if the documentData doesn't exist yet, return null. This null value is caught elsewhere. + if (!documentData) { + return null; } + // saved variables attached to the documentData entry + const existingDataVariables: DocumentDataVariable[] = documentData.document_data_variables; + // all variables associated with the variant + const variables: ProvisionVariable[] = await this.provisionService.getVariablesByDocumentTypeId(document_type_id); + // inserting the existing variable_values to the set of all variables + for (const variable of variables) { + const existingDataVariable = existingDataVariables.find( + (dataVariable) => dataVariable.document_variable.id === variable.id + ); + if (existingDataVariable) { + variable.variable_value = existingDataVariable.data_variable_value; + } + } + const variableIds = existingDataVariables.map((dataVariable) => dataVariable.document_variable.id); + return { variables, variableIds }; + } catch (err) { + console.log('Error in getVariablesByDtidAndDocType'); + console.log(err); + return null; } - const variableIds = existingDataVariables.map((dataVariable) => dataVariable.document_variable.id); - return { variables, variableIds }; } async getProvisionsByDocTypeIdAndDtid(document_type_id: number, dtid: number) { - const documentData: DocumentData = await this.documentDataRepository.findOne({ - where: { dtid: dtid, document_type: { id: document_type_id } }, - join: { - alias: 'document_data', - leftJoinAndSelect: { - document_data_provisions: 'document_data.document_data_provisions', - provision: 'document_data_provisions.provision', - }, - }, - }); - // if the documentData doesn't exist yet, return null. This null value is caught elsewhere. - if (!documentData) { - return null; - } - // documentData for all variants of this dtid - const fullDocumentData: DocumentData[] = await this.documentDataRepository.find({ - where: { dtid: documentData.dtid }, - join: { - alias: 'document_data', - leftJoinAndSelect: { - document_data_provisions: 'document_data.document_data_provisions', - provision: 'document_data_provisions.provision', - }, - }, - }); + try { + const documentData = await this.documentDataRepository + .createQueryBuilder('document_data') + .leftJoinAndSelect('document_data.document_data_provisions', 'document_data_provisions') + .leftJoinAndSelect('document_data_provisions.document_provision', 'provision') + .where('document_data.dtid = :dtid', { dtid }) + .andWhere('document_data."documentTypeId" = :document_type_id', { document_type_id }) + .getOne(); + console.log(documentData); - // saved provisions attached to the dtid - const existingDataProvisions: DocumentDataProvision[] = []; - fullDocumentData.forEach((documentData) => { + // if the documentData doesn't exist yet, return null. This null value is caught elsewhere. + if (!documentData) { + return null; + } + + // saved provisions attached to the dtid + const existingDataProvisions: DocumentDataProvision[] = []; existingDataProvisions.push(...documentData.document_data_provisions); - }); - // all provisions - const provisions: Provision[] = await this.provisionService.getAllProvisions(); - const provisionIds = existingDataProvisions.map((dataProvision) => dataProvision.document_provision.id); - return { provisions, provisionIds }; + // all provisions + const provisions: Provision[] = await this.provisionService.getAllProvisionsByDocTypeId(document_type_id); + const provisionIds = existingDataProvisions.map((dataProvision) => dataProvision.document_provision.id); + return { provisions, provisionIds }; + } catch (err) { + console.log('Error in getProvisionsByDocTypeIdAndDtid'); + console.log(err); + return null; + } } async getEnabledProvisionsByDocTypeIdAndDtid(document_type_id: number, dtid: number) { - const documentData: DocumentData = await this.documentDataRepository.findOne({ - where: { dtid: dtid, document_type: { id: document_type_id } }, - join: { - alias: 'document_data', - leftJoinAndSelect: { - document_data_provisions: 'document_data.document_data_provisions', - provision: 'document_data_provisions.provision', + try { + const documentData: DocumentData = await this.documentDataRepository.findOne({ + where: { dtid: dtid, document_type: { id: document_type_id } }, + join: { + alias: 'document_data', + leftJoinAndSelect: { + document_data_provisions: 'document_data.document_data_provisions', + provision: 'document_data_provisions.provision', + }, }, - }, - }); - const provisionIds = - documentData && documentData.document_data_provisions - ? documentData.document_data_provisions.map((dataProvision) => dataProvision.document_provision.id) - : []; - return provisionIds; + }); + const provisionIds = + documentData && documentData.document_data_provisions + ? documentData.document_data_provisions.map((dataProvision) => dataProvision.document_provision.id) + : []; + return provisionIds; + } catch (err) { + console.log('Error in getEnabledProvisionsByDocTypeIdAndDtid'); + console.log(err); + return null; + } } async remove(dtid: number): Promise<{ deleted: boolean; message?: string }> { diff --git a/backend/src/document_data_log/document_data_log.service.ts b/backend/src/document_data_log/document_data_log.service.ts index f73bb7d1..1ee4f1df 100644 --- a/backend/src/document_data_log/document_data_log.service.ts +++ b/backend/src/document_data_log/document_data_log.service.ts @@ -14,7 +14,6 @@ export class DocumentDataLogService { async create(documentDataLog: CreateDocumentDataLogDto): Promise { const newItem = new DocumentDataLog(); newItem.document_template_id = documentDataLog.document_template_id; - newItem.document_data_id = documentDataLog.document_data_id; newItem.dtid = documentDataLog.dtid; newItem.request_app_user = documentDataLog.request_app_user; newItem.request_json = documentDataLog.request_json; @@ -35,10 +34,11 @@ export class DocumentDataLogService { }); } - async findNextVersion(dtid: number): Promise { + async findNextVersion(dtid: number, document_type_id: number): Promise { const requestLogs = await this.documentDataLogRepository.findAndCount({ where: { dtid: dtid, + document_type_id: document_type_id, }, }); let version = (requestLogs[1] + 1).toString(); diff --git a/backend/src/document_data_log/dto/create-document_data_log.dto.ts b/backend/src/document_data_log/dto/create-document_data_log.dto.ts index 786f4940..dbc58bbc 100644 --- a/backend/src/document_data_log/dto/create-document_data_log.dto.ts +++ b/backend/src/document_data_log/dto/create-document_data_log.dto.ts @@ -3,7 +3,6 @@ import { DocumentDataLogDto } from './document_data_log.dto'; export class CreateDocumentDataLogDto extends PickType(DocumentDataLogDto, [ 'dtid', - 'document_data_id', 'document_type_id', 'document_template_id', 'request_app_user', diff --git a/backend/src/document_data_log/dto/document_data_log.dto.ts b/backend/src/document_data_log/dto/document_data_log.dto.ts index 760cc659..a7dc8de7 100644 --- a/backend/src/document_data_log/dto/document_data_log.dto.ts +++ b/backend/src/document_data_log/dto/document_data_log.dto.ts @@ -1,6 +1,5 @@ export class DocumentDataLogDto { dtid: number; - document_data_id: number; document_type_id: number; document_template_id: number; request_app_user: string; diff --git a/backend/src/document_data_log/dto/update-document_data_log.dto.ts b/backend/src/document_data_log/dto/update-document_data_log.dto.ts index c9cdd8bc..9521ce57 100644 --- a/backend/src/document_data_log/dto/update-document_data_log.dto.ts +++ b/backend/src/document_data_log/dto/update-document_data_log.dto.ts @@ -3,7 +3,6 @@ import { DocumentDataLogDto } from './document_data_log.dto'; export class UpdateDocumentDataLogDto extends PickType(DocumentDataLogDto, [ 'dtid', - 'document_data_id', 'document_type_id', 'document_template_id', 'request_app_user', diff --git a/backend/src/document_data_log/entities/document_data_log.entity.ts b/backend/src/document_data_log/entities/document_data_log.entity.ts index f3ce25e1..d8f1f19b 100644 --- a/backend/src/document_data_log/entities/document_data_log.entity.ts +++ b/backend/src/document_data_log/entities/document_data_log.entity.ts @@ -7,8 +7,6 @@ export class DocumentDataLog { @Column({ nullable: true }) dtid: number; @Column({ nullable: true }) - document_data_id: number; - @Column({ nullable: true }) document_type_id: number; @Column({ nullable: true }) document_template_id: number; @@ -27,7 +25,6 @@ export class DocumentDataLog { constructor( dtid?: number, - document_data_id?: number, document_type_id?: number, document_template_id?: number, request_app_user?: string, @@ -36,7 +33,6 @@ export class DocumentDataLog { update_userid?: string ) { this.dtid = dtid || null; - this.document_data_id = document_data_id || null; this.document_type_id = document_type_id || null; this.document_template_id = document_template_id || null; this.request_app_user = request_app_user || ''; diff --git a/backend/src/document_type/entities/document_type.entity.ts b/backend/src/document_type/entities/document_type.entity.ts index 20e31cd5..ef876212 100644 --- a/backend/src/document_type/entities/document_type.entity.ts +++ b/backend/src/document_type/entities/document_type.entity.ts @@ -10,6 +10,7 @@ import { import { DocumentTemplate } from '../../document_template/entities/document_template.entity'; import { DocumentData } from 'src/document_data/entities/document_data.entity'; import { Provision } from 'src/provision/entities/provision.entity'; +import { ProvisionGroup } from 'src/provision/entities/provision_group.entity'; @Entity() export class DocumentType { @@ -35,6 +36,10 @@ export class DocumentType { document_data: DocumentData[]; @ManyToMany(() => Provision, (provision) => provision.document_types) provisions: Provision[]; + @OneToMany(() => ProvisionGroup, (provisionGroup) => provisionGroup.document_type, { + cascade: true, + }) + provision_groups: ProvisionGroup[]; constructor(name?: string, create_userid?: string, update_userid?: string) { this.name = name || ''; diff --git a/backend/src/main.ts b/backend/src/main.ts index c0dcef8a..8dddd1e6 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -20,7 +20,7 @@ async function bootstrap() { const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api', app, document); const appService = app.get(AppService); - // await appService.initializeDb(); + await appService.initializeDb(); await app.listen(3001); } diff --git a/backend/src/provision/entities/provision.entity.ts b/backend/src/provision/entities/provision.entity.ts index 847ed980..25511a81 100644 --- a/backend/src/provision/entities/provision.entity.ts +++ b/backend/src/provision/entities/provision.entity.ts @@ -52,7 +52,7 @@ export class Provision { document_data_provisions: DocumentDataProvision[]; @ManyToMany(() => DocumentType) @JoinTable({ - name: 'provision_document_type', // Name of the join table + name: 'provision_document_type', joinColumn: { name: 'provision_id', referencedColumnName: 'id', diff --git a/backend/src/provision/entities/provision_group.entity.ts b/backend/src/provision/entities/provision_group.entity.ts index 08acff89..a5c44112 100644 --- a/backend/src/provision/entities/provision_group.entity.ts +++ b/backend/src/provision/entities/provision_group.entity.ts @@ -1,5 +1,6 @@ -import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm'; +import { Entity, Column, PrimaryGeneratedColumn, OneToMany, ManyToMany, ManyToOne } from 'typeorm'; import { Provision } from './provision.entity'; +import { DocumentType } from 'src/document_type/entities/document_type.entity'; /** * This entity holds group descriptions and provision maximums @@ -20,6 +21,9 @@ export class ProvisionGroup { @Column({ nullable: true }) max: number; + @ManyToOne(() => DocumentType, (documentType) => documentType.provision_groups) + document_type: DocumentType; + @OneToMany(() => Provision, (provision) => provision.provision_group, { nullable: true, }) diff --git a/backend/src/provision/provision.service.ts b/backend/src/provision/provision.service.ts index cd77525f..e7c5c3da 100644 --- a/backend/src/provision/provision.service.ts +++ b/backend/src/provision/provision.service.ts @@ -153,7 +153,7 @@ export class ProvisionService { } // querybuilder is more efficient here - async getVariablesByDocumentTypeId(document_type_id: number): Promise { + async getVariablesByDocumentTypeId(document_type_id: number) { const provisions = await this.provisionRepository .createQueryBuilder('provision') .innerJoin('provision.document_types', 'documentType', 'documentType.id = :document_type_id', { @@ -184,13 +184,18 @@ export class ProvisionService { } } - async getAllProvisions(): Promise { + async getAllProvisionsByDocTypeId(document_type_id: number): Promise { try { - const provisions: Provision[] = await this.provisionRepository.find({ - relations: ['provision_group'], - }); + const provisions: Provision[] = await this.provisionRepository + .createQueryBuilder('provision') + .innerJoinAndSelect('provision.provision_group', 'provision_group') + .innerJoin('provision_group.document_type', 'document_type') + .where('document_type.id = :document_type_id', { document_type_id }) + .getMany(); + return provisions; } catch (err) { + console.log('Error in getAllProvisionsByDocTypeId'); console.log(err); return null; } @@ -223,14 +228,9 @@ export class ProvisionService { } async getGroupMaxByDocTypeId(document_type_id: number): Promise { - const provisions = await this.provisionRepository.find({ - relations: ['provision_group'], + const provisionGroups = await this.provisionGroupRepository.find({ + where: { document_type: { id: document_type_id } }, }); - let provisionGroups: ProvisionGroup[] = []; - provisions.forEach((provision) => { - provisionGroups.push(provision.provision_group); - }); - provisionGroups = this.removeDuplicates(provisionGroups, 'provision_group'); return Array.from(provisionGroups).sort((a, b) => a.provision_group - b.provision_group); } diff --git a/backend/src/report/report.controller.ts b/backend/src/report/report.controller.ts index ef1496b6..a6e22c4a 100644 --- a/backend/src/report/report.controller.ts +++ b/backend/src/report/report.controller.ts @@ -38,94 +38,57 @@ export class ReportController { }; } - @Get('get-data/:dtid') - async getData(@Session() session: { data?: SessionData }, @Param('dtid') dtid: number) { - console.log(dtid); - console.log(session); - await this.reportService.getActiveNfrDataByDtid(dtid); - await this.ttlsService.setWebadeToken(); - const response: any = await firstValueFrom(this.ttlsService.callHttp(dtid)) - .then((res) => { - return res; - }) - .catch((err) => { - console.log('callHttp failed'); - console.log(err); - console.log(err.response.data); - }); - return response; - } - - @Get('get-document-data/:dtid') - getNfrData(@Session() session: { data?: SessionData }, @Param('dtid') dtid: number) { - console.log('get-document-data ~ ' + dtid); - return this.reportService.getActiveNfrDataByDtid(dtid); - } - - @Get('get-report-name/:dtid/:tfn/:documentType') - getReportName( - @Param('dtid') dtid: number, - @Param('tfn') tenureFileNumber: string, - @Param('documentType') documentType: string - ): Promise<{ reportName: string }> { - return this.reportService.generateReportName(dtid, tenureFileNumber, documentType); + // @Get('get-data/:dtid') + // async getData(@Session() session: { data?: SessionData }, @Param('dtid') dtid: number) { + // console.log(dtid); + // console.log(session); + // await this.reportService.getTtlsDataByDtid(dtid); + // await this.ttlsService.setWebadeToken(); + // const response: any = await firstValueFrom(this.ttlsService.callHttp(dtid)) + // .then((res) => { + // return res; + // }) + // .catch((err) => { + // console.log('callHttp failed'); + // console.log(err); + // console.log(err.response.data); + // }); + // return response; + // } + + @Get('get-document-data/:document_type_id/:dtid') + getNfrData( + @Session() session: { data?: SessionData }, + @Param('document_type_id') document_type_id: number, + @Param('dtid') dtid: number + ) { + console.log('get-document-data ~ dtid:' + dtid + ', doctypeid: ' + document_type_id); + return this.reportService.getDocumentDataByDocTypeIdAndDtid(document_type_id, dtid); } - @Get('get-nfr-report-name/:dtid/:tfn') - getNFRReportName( + @Get('get-report-name/:dtid/:tfn/:document_type_id') + getReportNameNew( @Param('dtid') dtid: number, - @Param('tfn') tenureFileNumber: string + @Param('tfn') tenure_file_number: string, + @Param('document_type_id') document_type_id: number ): Promise<{ reportName: string }> { - return this.reportService.generateNFRReportName(dtid, tenureFileNumber); + return this.reportService.generateReportName(dtid, tenure_file_number, document_type_id); } + // remember to update @Post('generate-report') @Header('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') - @Header('Content-Disposition', 'attachment; filename=landusereport.docx') + @Header('Content-Disposition', 'attachment; filename=report.docx') async generateReport( - @Session() session: { data: SessionData }, - @Body() data: { prdid: string; document_type: string; dtid: number } - ) { - // this should eventually check permissions and prevent unauthorized users from generating documents - let idir_username = ''; - session = { - data: { - activeAccount: { - idir_username: 'mtennant', - name: '', - full_name: '', - client_roles: [''], - }, - }, - ...session, - }; - if (session.data.activeAccount) { - idir_username = session?.data?.activeAccount.idir_username; - console.log('active account found'); - } else { - console.log('no active account found'); - } - if (data.document_type == 'GL') { - return new StreamableFile(await this.reportService.generateGLReport(+data.dtid, idir_username)); - } else { - return new StreamableFile(await this.reportService.generateLURReport(+data.prdid, idir_username)); - } - } - - @Post('generate-nfr-report') - @Header('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') - @Header('Content-Disposition', 'attachment; filename=nfr-report.docx') - async generateNFRReport( @Session() session: { data: SessionData }, @Body() data: { dtid: number; - variantName: string; + document_type_id: number; variableJson: VariableJSON[]; provisionJson: ProvisionJSON[]; } ) { - // this should eventually check permissions and prevent unauthorized users from generating documents let idir_username = ''; let idir_full_name = ''; if (session?.data?.activeAccount) { @@ -136,9 +99,9 @@ export class ReportController { console.log('no active account found'); } return new StreamableFile( - await this.reportService.generateNFRReport( + await this.reportService.generateReport( data.dtid, - data.variantName, + data.document_type_id, idir_username, idir_full_name, data.variableJson, @@ -147,40 +110,6 @@ export class ReportController { ); } - @Post('generate-report-new') - @Header('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') - @Header('Content-Disposition', 'attachment; filename=report.docx') - async generateReportNew( - @Session() session: { data: SessionData }, - @Body() - data: { - dtid: number; - document_type_id: number; - variableJson: VariableJSON[]; - provisionJson: ProvisionJSON[]; - } - ) { - let idir_username = ''; - let idir_full_name = ''; - if (session?.data?.activeAccount) { - idir_username = session?.data?.activeAccount.idir_username; - idir_full_name = session?.data?.activeAccount.full_name; - console.log('active account found'); - } else { - console.log('no active account found'); - } - // return new StreamableFile( - await this.reportService.generateReportNew( - data.dtid, - data.document_type_id, - idir_username, - idir_full_name, - data.variableJson, - data.provisionJson - ); - // ); - } - @Get('get-group-max/:document_type_id') getGroupMaxByVariant(@Param('document_type_id') document_type_id: number) { return this.reportService.getGroupMaxByDocTypeId(document_type_id); @@ -194,10 +123,12 @@ export class ReportController { return this.reportService.getDocumentProvisionsByDocTypeIdAndDtid(document_type_id, dtid); } - @Get('get-provision-variables/:variantName/:dtid') - async getNFRVariablesByVariant(@Param('variantName') variantName: string, @Param('dtid') dtid: number) { - console.log('getting variables for NFR'); - const variables = await this.reportService.getNFRVariablesByVariantAndDtid(variantName, dtid); + @Get('get-provision-variables/:document_type_id/:dtid') + async getDocumentVariablesByDocumentTypeIdAndDtid( + @Param('document_type_id') document_type_id: number, + @Param('dtid') dtid: number + ) { + const variables = await this.reportService.getDocumentVariablesByDocumentTypeIdAndDtid(document_type_id, dtid); return variables; } @@ -230,35 +161,6 @@ export class ReportController { ); } - @Post('save-nfr') - saveNFR( - @Session() session: { data: SessionData }, - @Body() - data: { - dtid: number; - variant_name: string; - status: string; - provisionArray: ProvisionJSON[]; - variableArray: VariableJSON[]; - } - ) { - let idir_username = ''; - if (session?.data?.activeAccount) { - idir_username = session?.data?.activeAccount.idir_username; - console.log('active account found'); - } else { - console.log('no active account found'); - } - return this.reportService.saveNFR( - data.dtid, - data.variant_name, - data.status, - data.provisionArray, - data.variableArray, - idir_username - ); - } - @Get('enabled-provisions/:document_type_id') getEnabledProvisionsByDocTypeId(@Param('document_type_id') document_type_id: number) { return this.reportService.getEnabledProvisionsByDocTypeId(document_type_id); @@ -274,7 +176,7 @@ export class ReportController { @Get('search-document-data') getNFRData() { - return this.reportService.getNFRData(); + return this.reportService.getDocumentData(); } @Get('get-mandatory-provisions-by-document-type-id/:document_type_id') diff --git a/backend/src/report/report.module.ts b/backend/src/report/report.module.ts index 12f6d6e0..860f6fe2 100644 --- a/backend/src/report/report.module.ts +++ b/backend/src/report/report.module.ts @@ -9,6 +9,7 @@ import { ProvisionModule } from 'src/provision/provision.module'; import { DocumentDataModule } from 'src/document_data/document_data.module'; import { DocumentDataLogModule } from 'src/document_data_log/document_data_log.module'; import { DocumentDataLogService } from 'src/document_data_log/document_data_log.service'; +import { DocumentTypeModule } from 'src/document_type/document_type.module'; @Module({ imports: [ @@ -18,6 +19,7 @@ import { DocumentDataLogService } from 'src/document_data_log/document_data_log. ProvisionModule, DocumentDataModule, DocumentDataLogModule, + DocumentTypeModule, ], providers: [TTLSService, ReportService, DocumentDataLogService], exports: [ReportService], diff --git a/backend/src/report/report.service.ts b/backend/src/report/report.service.ts index ce69e19e..a3a652ce 100644 --- a/backend/src/report/report.service.ts +++ b/backend/src/report/report.service.ts @@ -10,8 +10,11 @@ import { convertToSpecialCamelCase, formatMoney, grazingLeaseVariables, nfrAddre import { DocumentDataService } from 'src/document_data/document_data.service'; import { DocumentTemplate } from 'src/document_template/entities/document_template.entity'; import { DocumentDataLogService } from 'src/document_data_log/document_data_log.service'; +import { DocumentTypeService } from 'src/document_type/document_type.service'; const axios = require('axios'); +// generate report needs to be consolidated which is impossible until we figure out how provisions & variables will be dynamically inserted into the docx files + dotenv.config(); let hostname: string; let port: number; @@ -23,42 +26,77 @@ export class ReportService { private readonly documentTemplateService: DocumentTemplateService, private readonly documentDataLogService: DocumentDataLogService, private readonly provisionService: ProvisionService, - private readonly documentDataService: DocumentDataService + private readonly documentDataService: DocumentDataService, + private readonly documentTypeService: DocumentTypeService ) { hostname = process.env.backend_url ? process.env.backend_url : `http://localhost`; // local development backend port is 3001, docker backend port is 3000 port = process.env.backend_url ? 3000 : 3001; } - /** - * Generates a LUR report name using tenure file number - * and a version number. The version number is incremented - * each time someone generates a LUR report. - * - * @param tenureFileNumber - * @returns - */ - async generateReportName(dtid: number, tenureFileNumber: string, documentType: string) { - const url = `${hostname}:${port}/print-request-log/version/${dtid}/${documentType}`; - // grab the next version string for the dtid - const version = await axios - .get(url, { - headers: { - 'Content-Type': 'application/json', - }, - }) - .then((res) => { - return res.data; - }); + // /** + // * Generates a LUR report name using tenure file number + // * and a version number. The version number is incremented + // * each time someone generates a LUR report. + // * + // * @param tenureFileNumber + // * @returns + // */ + // async generateReportName(dtid: number, tenureFileNumber: string, documentType: string) { + // const url = `${hostname}:${port}/print-request-log/version/${dtid}/${documentType}`; + // // grab the next version string for the dtid + // const version = await axios + // .get(url, { + // headers: { + // 'Content-Type': 'application/json', + // }, + // }) + // .then((res) => { + // return res.data; + // }); + // return { + // reportName: documentType + '_' + tenureFileNumber + '_' + version + '.docx', + // }; + // } + + async generateReportName(dtid: number, tenure_file_number: string, document_type_id: number) { + const version = await this.documentDataLogService.findNextVersion(dtid, document_type_id); + const documentType = await this.documentTypeService.findById(document_type_id); + // probably a better way of doing this + let prefix = 'report'; + if (documentType) { + if (documentType.name.toLowerCase().includes('notice of final review')) { + prefix = 'NFR'; + } else if (documentType.name.toLowerCase().includes('land use report')) { + prefix = 'LUR'; + } else if (documentType.name.toLowerCase().includes('grazing')) { + prefix = 'GL'; + } + } return { - reportName: documentType + '_' + tenureFileNumber + '_' + version + '.docx', + reportName: prefix + '_' + tenure_file_number + '_' + version + '.docx', }; } - async generateReport(dtid: number, username: string, document_type_id: number) { - const documentTemplateObject: { id: number; the_file: string } = - await this.documentTemplateService.findActiveByDocumentType(document_type_id); - const data = await this.documentDataService; + async generateReport( + dtid: number, + document_type_id: number, + idirUsername: string, + idirName: string, + variableJson: VariableJSON[], + provisionJson: ProvisionJSON[] + ) { + // For now, hardcode this to call the different static report routes based on document type + const documentType = await this.documentTypeService.findById(document_type_id); + if (documentType) { + if (documentType.name.toLowerCase().includes('notice of final review')) { + return this.generateNFRReport(dtid, document_type_id, idirUsername, idirName, variableJson, provisionJson); + } else if (documentType.name.toLowerCase().includes('land use report')) { + return this.generateLURReport(dtid, idirUsername); + } else if (documentType.name.toLowerCase().includes('grazing')) { + return this.generateGLReport(dtid, idirUsername); + } + } } /** @@ -68,6 +106,7 @@ export class ReportService { * @param username * @returns */ + // needs a rewrite as prdid is being removed... async generateLURReport(prdid: number, username: string) { prdid = 1; const documentType = LUR_REPORT_TYPE; @@ -304,70 +343,37 @@ export class ReportService { // return response.data; // } - /** - * Generates an NFR report name using tenure file number - * and a version number. The version number is incremented - * each time someone generates a NFR report. - * - * @param tenureFileNumber - * @returns - */ - async generateNFRReportName(dtid: number, tenureFileNumber: string) { - const url = `${hostname}:${port}/document-data-log/version/` + dtid; - // grab the next version string for the dtid - const version = await axios - .get(url, { - headers: { - 'Content-Type': 'application/json', - }, - }) - .then((res) => { - return res.data; - }); - return { reportName: 'NFR_' + tenureFileNumber + '_' + version + '.docx' }; - } - - async generateReportNew( - dtid: number, - document_type_id: number, - idirUsername: string, - idirName: string, - variableJson: VariableJSON[], - provisionJson: ProvisionJSON[] - ) { - console.log('TODO'); - // Get raw data from TTLS - await this.ttlsService.setWebadeToken(); - const rawData: any = await firstValueFrom(this.ttlsService.callHttp(dtid)) - .then((res) => { - return res; - }) - .catch((err) => { - console.log(err); - }); - // Get the active template file for this document type - const documentTemplateObject: DocumentTemplate = await this.documentTemplateService.findActiveByDocumentType( - document_type_id - ); - // format the provisions & variables in a dynamic way - // TODO - // create a log of the transaction - // TODO - // generate and return the document - // TODO - } + // /** + // * Generates an NFR report name using tenure file number + // * and a version number. The version number is incremented + // * each time someone generates a NFR report. + // * + // * @param tenureFileNumber + // * @returns + // */ + // async generateNFRReportName(dtid: number, tenureFileNumber: string) { + // const url = `${hostname}:${port}/document-data-log/version/` + dtid; + // // grab the next version string for the dtid + // const version = await axios + // .get(url, { + // headers: { + // 'Content-Type': 'application/json', + // }, + // }) + // .then((res) => { + // return res.data; + // }); + // return { reportName: 'NFR_' + tenureFileNumber + '_' + version + '.docx' }; + // } async generateNFRReport( dtid: number, - variantName: string, + document_type_id: number, idirUsername: string, idirName: string, variableJson: VariableJSON[], provisionJson: ProvisionJSON[] ) { - const templateUrl = `${hostname}:${port}/document-template/get-active-report/${variantName}`; - const logUrl = `${hostname}:${port}/document-data-log/`; - // get raw ttls data for later await this.ttlsService.setWebadeToken(); const rawData: any = await firstValueFrom(this.ttlsService.callHttp(dtid)) @@ -378,14 +384,7 @@ export class ReportService { console.log(err); }); - // get the document template - const documentTemplateObject: { - id: number; - the_file: string; - document_template: string; - } = await axios.get(templateUrl).then((res) => { - return res.data; - }); + const documentTemplateObject = await this.documentTemplateService.findActiveByDocumentType(document_type_id); // Format variables with names that the document template expects const variables: any = {}; @@ -681,16 +680,17 @@ export class ReportService { const data = Object.assign({}, ttlsData, variables, showProvisionSections); // Log the request - const document_template_id = documentTemplateObject.id; - await axios.post(logUrl, { - document_template_id: document_template_id, + await this.documentDataLogService.create({ dtid: dtid, + document_type_id: document_type_id, + document_template_id: documentTemplateObject?.id, request_app_user: idirUsername, request_json: JSON.stringify(data), + create_userid: idirUsername, }); // Save the NFR Data - await this.saveNFR(dtid, variantName, 'Complete', provisionJson, variableJson, idirUsername); + await this.saveDocument(dtid, document_type_id, 'Complete', provisionJson, variableJson, idirUsername); // Generate the report const cdogsToken = await this.ttlsService.callGetToken(); @@ -796,23 +796,15 @@ export class ReportService { return this.provisionService.getGroupMaxByDocTypeId(document_type_id); } - async getNFRVariablesByVariantAndDtid(variantName: string, dtid: number): Promise { - // if an nfrId is provided, get the variables with any existing user specified values - const url = `${hostname}:${port}/document-data/variables/${variantName}/${dtid}`; - const variables = await axios - .get(url) - .then((res) => { - return res.data.variables; - }) - .catch((err) => console.log(err.response.data)); + async getDocumentVariablesByDocumentTypeIdAndDtid(document_type_id: number, dtid: number): Promise { + // if a dtid & document_type_id are provided, get the variables with any existing user specified values + const variables = await this.documentDataService.getVariablesByDtidAndDocType(dtid, document_type_id); if (variables) { return variables; } else { - // grab the basic variable list corresponding to the variant - const url2 = `${hostname}:${port}/provision/get-provision-variables/variant/${variantName}`; - return axios.get(url2).then((res) => { - return res.data; - }); + // grab the basic variable list corresponding to the document type + const basicVariables = await this.provisionService.getVariablesByDocumentTypeId(document_type_id); + return { variables: basicVariables, variableIds: [] }; } } @@ -824,32 +816,10 @@ export class ReportService { return this.provisionService.getMandatoryProvisionsByDocumentTypeId(document_type_id); } - async getNFRData() { - const nfrDataUrl = `${hostname}:${port}/nfr-data`; - const templateUrl = `${hostname}:${port}/document-template/nfr-template-info`; - - // get NFR data - let nfrData; - try { - const response = await axios.get(nfrDataUrl); - nfrData = response.data; - } catch (err) { - console.log(err.response.data); - return; - } - - // get template IDs from NFR data - const templateIds = nfrData.map((entry) => entry.template_id); - - // get templates using template IDs - let allTemplates; - try { - const response = await axios.post(templateUrl, templateIds); - allTemplates = response.data; - } catch (err) { - console.log(err.response.data); - return; - } + async getDocumentData() { + const documentData = await this.documentDataService.findAll(); + const templateIds = documentData.map((d) => d.template_id); + const allTemplates = await this.documentTemplateService.getTemplatesInfoByIds(templateIds); // filter out deleted templates and create a lookup table const templatesLookup = allTemplates.reduce((acc, template) => { @@ -859,82 +829,84 @@ export class ReportService { return acc; }, {}); - // combine NFR data with their corresponding templates - const combinedArray = nfrData - .filter((nfr) => templatesLookup[nfr.template_id]) - .map((nfr) => ({ - dtid: nfr.dtid, - version: templatesLookup[nfr.template_id].template_version, - file_name: templatesLookup[nfr.template_id].file_name, - updated_date: nfr.update_timestamp.split('T')[0], - status: nfr.status, - active: templatesLookup[nfr.template_id].active_flag, - nfr_id: nfr.id, - variant_name: nfr.variant_name, + // combine Document data with their corresponding templates + const combinedArray = documentData + .filter((document) => templatesLookup[document.template_id]) + .map((document) => ({ + dtid: document.dtid, + version: templatesLookup[document.template_id].template_version, + file_name: templatesLookup[document.template_id].file_name, + updated_date: document.update_timestamp.toString().split('T')[0], + status: document.status, + active: templatesLookup[document.template_id].active_flag, + document_data_id: document.id, + document_type: document.document_type, })); return combinedArray; } - async getActiveNfrDataByDtid(dtid: number): Promise { - const url = `${hostname}:${port}/document-data/dtid/${dtid}`; - const response = await axios - .get(url, { - headers: { - 'Content-Type': 'application/json', - }, - }) - .then((res) => { - return res.data; - }); - // console.log('!!!~~~~~~~~'); - // console.log("this.getGroupMaxByVariant('NOTICE OF FINAL REVIEW')"); - // const groupMax = await this.getGroupMaxByVariant('NOTICE OF FINAL REVIEW'); - // // console.log(groupMax); - // console.log('\ngetActiveNfrDataByDtid'); - // console.log(response); - // console.log('\ndocument_data_provisions'); - // // console.log(response.nfrData.document_data_provisions); - // console.log('\ndocument_data_variables'); - // // console.log(response.nfrData.document_data_variables); - // console.log('\nthis.getMandatoryProvisionsByVariant(NOTICE OF FINAL REVIEW)'); - // const mandatoryProvisions = await this.getMandatoryProvisionsByVariant('NOTICE OF FINAL REVIEW'); - // // console.log(mandatoryProvisions); - // console.log('~~~~~~~~!!!'); - return response; + async getDocumentDataByDocTypeIdAndDtid(document_type_id: number, dtid: number): Promise { + return this.documentDataService.findDocumentDataByDocTypeIdAndDtid(document_type_id, dtid); + // const url = `${hostname}:${port}/document-data/dtid/${dtid}`; + // const response = await axios + // .get(url, { + // headers: { + // 'Content-Type': 'application/json', + // }, + // }) + // .then((res) => { + // return res.data; + // }); + // // const documentData = await this.documentDataService.findActiveByDtid(dtid); + // // console.log('!!!~~~~~~~~'); + // // console.log("this.getGroupMaxByVariant('NOTICE OF FINAL REVIEW')"); + // // const groupMax = await this.getGroupMaxByVariant('NOTICE OF FINAL REVIEW'); + // // // console.log(groupMax); + // // console.log('\ngetActiveNfrDataByDtid'); + // // console.log(response); + // // console.log('\ndocument_data_provisions'); + // // // console.log(response.nfrData.document_data_provisions); + // // console.log('\ndocument_data_variables'); + // // // console.log(response.nfrData.document_data_variables); + // // console.log('\nthis.getMandatoryProvisionsByVariant(NOTICE OF FINAL REVIEW)'); + // // const mandatoryProvisions = await this.getMandatoryProvisionsByVariant('NOTICE OF FINAL REVIEW'); + // // // console.log(mandatoryProvisions); + // // console.log('~~~~~~~~!!!'); + // return response; } - async saveNFR( - dtid: number, - variant_name: string, - status: string, - provisionJsonArray: ProvisionJSON[], - variableJsonArray: VariableJSON[], - idir_username: string - ) { - const templateUrl = `${hostname}:${port}/document-template/get-active-report/${variant_name}`; - const documentTemplate = await axios.get(templateUrl).then((res) => { - return res.data; - }); - const url = `${hostname}:${port}/document-data`; - const data = { - dtid: dtid, - variant_name: variant_name, - template_id: documentTemplate.id, - status: status, - create_userid: idir_username, - ttls_data: [], - provisionJsonArray, - variableJsonArray, - }; - await axios - .post(url, { - body: data, - }) - .then((res) => { - return res.data; - }); - } + // async saveNFR( + // dtid: number, + // variant_name: string, + // status: string, + // provisionJsonArray: ProvisionJSON[], + // variableJsonArray: VariableJSON[], + // idir_username: string + // ) { + // const templateUrl = `${hostname}:${port}/document-template/get-active-report/${variant_name}`; + // const documentTemplate = await axios.get(templateUrl).then((res) => { + // return res.data; + // }); + // const url = `${hostname}:${port}/document-data`; + // const data = { + // dtid: dtid, + // variant_name: variant_name, + // template_id: documentTemplate.id, + // status: status, + // create_userid: idir_username, + // ttls_data: [], + // provisionJsonArray, + // variableJsonArray, + // }; + // await axios + // .post(url, { + // body: data, + // }) + // .then((res) => { + // return res.data; + // }); + // } async saveDocument( dtid: number, @@ -944,7 +916,6 @@ export class ReportService { variableJsonArray: VariableJSON[], idir_username: string ) { - const url = `${hostname}:${port}/document-data`; const documentTemplate = await this.documentTemplateService.findActiveByDocumentType(document_type_id); const data = { dtid: dtid, diff --git a/frontend/src/app/App.tsx b/frontend/src/app/App.tsx index c749195d..28e55e72 100644 --- a/frontend/src/app/App.tsx +++ b/frontend/src/app/App.tsx @@ -3,7 +3,7 @@ import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import Header from './content/display/Header'; import Footer from './content/display/Footer'; import { getDocumentTypes } from './common/report'; -import { DocumentType } from './types/types'; +import { DocType } from './types/types'; import ReportPage from './content/pages/ReportPage'; import SearchPage from './content/pages/SearchPage'; import ManageTemplatesPage from './content/pages/ManageTemplatesPage'; @@ -12,7 +12,7 @@ import ContentWrapper from './content/ContentWrapper'; const App: FC = () => { // used to render report pages - const [documentTypes, setDocumentTypes] = useState([]); + const [documentTypes, setDocumentTypes] = useState([]); useEffect(() => { const getDocTypes = async () => { diff --git a/frontend/src/app/common/admin.ts b/frontend/src/app/common/admin.ts index bd82e9d4..28bef7a0 100644 --- a/frontend/src/app/common/admin.ts +++ b/frontend/src/app/common/admin.ts @@ -2,7 +2,6 @@ import config from '../../config'; import { IdirUserObject } from '../components/modal/admin/AddAdmin'; import { AdminData } from '../components/table/admin/AdminDataTable'; import * as api from './api'; -import fileDownload from 'js-file-download'; /** * Used in report name generation diff --git a/frontend/src/app/common/manage-templates.ts b/frontend/src/app/common/manage-templates.ts index 3c6b977c..fa5b21f3 100644 --- a/frontend/src/app/common/manage-templates.ts +++ b/frontend/src/app/common/manage-templates.ts @@ -61,16 +61,16 @@ export const downloadTemplate = async (id: number, fileName: string): Promise => { - const url = `${config.API_BASE_URL}/admin/remove-template/${id}/${document_template_id}`; +export const removeTemplate = async (id: number, documentTypeId: number): Promise => { + const url = `${config.API_BASE_URL}/admin/remove-template/${id}/${documentTypeId}`; const getParameters = api.generateApiParameters(url); const response = await api.get(getParameters); console.log('removeTemplate response'); console.log(response); }; -export const activateTemplate = async (id: number, document_template_id: string): Promise => { - const url = `${config.API_BASE_URL}/admin/activate-template/${id}/${document_template_id}`; +export const activateTemplate = async (id: number, documentTypeId: string): Promise => { + const url = `${config.API_BASE_URL}/admin/activate-template/${id}/${documentTypeId}`; const getParameters = api.generateApiParameters(url); await api.get(getParameters); }; diff --git a/frontend/src/app/common/report.ts b/frontend/src/app/common/report.ts index 4857b363..319f1947 100644 --- a/frontend/src/app/common/report.ts +++ b/frontend/src/app/common/report.ts @@ -3,51 +3,37 @@ import { ProvisionJson } from '../components/table/reports/SelectedProvisionsTab import { VariableJson } from '../components/table/reports/VariablesTable'; import { ProvisionData } from '../content/display/Provisions'; import { VariableData } from '../content/display/Variables'; -import { DTR, DTRDisplayObject, DocumentType, NfrDataObject, ProvisionGroup } from '../types/types'; +import { DTR, DTRDisplayObject, DocType, DocumentDataObject, ProvisionGroup } from '../types/types'; import { buildDTRDisplayData } from '../util/util'; import * as api from './api'; -/** - * Gets ttls data and parses it for displaying - * - * @param dtid - * @returns - */ -export async function getData(dtid: number): Promise { - const dataUrl = `${config.API_BASE_URL}/report/get-data/${dtid}`; - +// /** +// * Gets ttls data and parses it for displaying +// * +// * @param dtid +// * @returns +// */ +// export async function getData(dtid: number): Promise { +// const dataUrl = `${config.API_BASE_URL}/report/get-data/${dtid}`; + +// const data: DTR = await api.get({ url: dataUrl }); +// const displayData = buildDTRDisplayData(data); +// return displayData; +// } + +export async function getData(document_type_id: number, dtid: number): Promise { + const dataUrl = `${config.API_BASE_URL}/report/get-document-data/${document_type_id}/${dtid}`; const data: DTR = await api.get({ url: dataUrl }); + console.log(data); const displayData = buildDTRDisplayData(data); return displayData; } -/** - * Used to generate reports - * - * @param dtid - * @param fileNum - * @param documentDescription - */ -export async function generateReport(dtid: number, fileNum: string, documentDescription: string): Promise { - const reportNameUrl = `${config.API_BASE_URL}/report/get-report-name/${dtid}/${fileNum}/${documentDescription}`; - const reportUrl = `${config.API_BASE_URL}/report/generate-report`; - - const reportNameResponse: { reportName: string } = await api.get({ url: reportNameUrl }); - const reportName: string = reportNameResponse.reportName; - - const data = { - prdid: null, - dtid: dtid, - document_type: documentDescription, - }; - api.handleFileDownloadPost(reportUrl, data, reportName); -} - /** Section for Notice of Final Review which has lots of custom logic */ -export const getDocumentDataByDtid = async (dtid: number) => { - const url = `${config.API_BASE_URL}/report/get-document-data/${dtid}`; +export const getDocumentDataByDocTypeIdAndDtid = async (document_type_id: number, dtid: number) => { + const url = `${config.API_BASE_URL}/report/get-document-data/${document_type_id}/${dtid}`; const getParameters = api.generateApiParameters(url); - const response: NfrDataObject = await api.get(getParameters); + const response: DocumentDataObject = await api.get(getParameters); return response; }; @@ -59,7 +45,7 @@ export const getGroupMaxByDocTypeId = async (document_type_id: number) => { }; export const getMandatoryProvisionsByDocTypeId = async (document_type_id: number): Promise => { - const url = `${config.API_BASE_URL}/report/get-mandatory-provisions-by-variant/${document_type_id}`; + const url = `${config.API_BASE_URL}/report/get-mandatory-provisions-by-document-type-id/${document_type_id}`; const getParameters = api.generateApiParameters(url); const response: number[] = await api.get(getParameters); return response; @@ -78,23 +64,26 @@ export const getDocumentProvisionsByDocTypeIdDtid = async ( export const getDocumentVariablesByDocTypeIdDtid = async ( document_type_id: number, dtid: number -): Promise => { +): Promise<{ variables: VariableData[]; variableIds: number[] }> => { const url = `${config.API_BASE_URL}/report/get-provision-variables/${document_type_id}/${dtid}`; const getParameters = api.generateApiParameters(url); - const response: VariableData[] = await api.get(getParameters); + const response: { variables: VariableData[]; variableIds: number[] } = await api.get<{ + variables: VariableData[]; + variableIds: number[]; + }>(getParameters); return response; }; export const saveDocument = async ( dtid: number, - variantName: string, + document_type_id: number, provisionArray: { provision_id: number; free_text: string }[], variableArray: { provision_id: number; variable_id: number; variable_value: string }[] ): Promise => { - const url = `${config.API_BASE_URL}/report/save-nfr`; + const url = `${config.API_BASE_URL}/report/save-document`; const data = { dtid: dtid, - variant_name: variantName, + document_type_id: document_type_id, status: 'In Progress', provisionArray: provisionArray, variableArray: variableArray, @@ -103,23 +92,22 @@ export const saveDocument = async ( await api.post(postParameters); }; -// TODO stop using NFR -export const generateNfrReport = async ( +export const generateReport = async ( dtid: number, fileNum: string, - variant: string, + document_type_id: number, provisionJson: ProvisionJson[], variableJson: VariableJson[] ) => { - const url = `${config.API_BASE_URL}/report/generate-nfr-report`; - const reportNameUrl = `${config.API_BASE_URL}/report/get-nfr-report-name/${dtid}/${fileNum}`; + const url = `${config.API_BASE_URL}/report/generate-report`; + const reportNameUrl = `${config.API_BASE_URL}/report/get-report-name/${dtid}/${fileNum}/${document_type_id}`; const reportNameResponse: { reportName: string } = await api.get({ url: reportNameUrl }); const reportName: string = reportNameResponse.reportName; const data = { dtid: dtid, - variantName: variant, + document_type_id: document_type_id, provisionJson: provisionJson, variableJson: variableJson, }; @@ -128,8 +116,8 @@ export const generateNfrReport = async ( }; export const getDocumentTypes = () => { - const url = `${config.API_BASE_URL}/report/get-document-types`; + const url = `${config.API_BASE_URL}/document-type`; console.log(url); const getParameters = api.generateApiParameters(url); - return api.get(getParameters); + return api.get(getParameters); }; diff --git a/frontend/src/app/common/search.ts b/frontend/src/app/common/search.ts index 7f271dab..70ad8975 100644 --- a/frontend/src/app/common/search.ts +++ b/frontend/src/app/common/search.ts @@ -13,6 +13,7 @@ export async function getSearchData(): Promise { const parameters = api.generateApiParameters(url); const response = await api.get(parameters); + console.log(response) if (Array.isArray(response)) { return response; } else { diff --git a/frontend/src/app/components/modal/manage-templates/AddProvisionModal.tsx b/frontend/src/app/components/modal/manage-templates/AddProvisionModal.tsx index aacb1da4..51470fdd 100644 --- a/frontend/src/app/components/modal/manage-templates/AddProvisionModal.tsx +++ b/frontend/src/app/components/modal/manage-templates/AddProvisionModal.tsx @@ -1,10 +1,11 @@ import { useEffect, useState } from 'react'; -import { GroupMax, ProvisionUpload } from '../../../types/types'; +import { DocType, GroupMax, ProvisionUpload } from '../../../types/types'; import { Button, Col, Form, Modal, Row, Spinner } from 'react-bootstrap'; interface AddProvisionModalProps { groupMaxArray: GroupMax[] | undefined; show: boolean; + documentTypes: DocType[] | undefined; addProvisionHandler: (provision: ProvisionUpload) => void; onHide: () => void; refreshTables: () => void; @@ -15,6 +16,7 @@ interface AddProvisionModalProps { const AddProvisionModal: React.FC = ({ groupMaxArray, show, + documentTypes, addProvisionHandler, onHide, refreshTables, @@ -30,7 +32,7 @@ const AddProvisionModal: React.FC = ({ const [freeText, setFreeText] = useState(''); const [helpText, setHelpText] = useState(''); const [category, setCategory] = useState(''); - const [variants, setVariants] = useState([]); + const [documentTypeIds, setDocumentTypeIds] = useState([]); useEffect(() => { setIsMaxUnlimited(max ? max >= 999 : false); @@ -104,12 +106,12 @@ const AddProvisionModal: React.FC = ({ setCategory(e.target.value); }; - const handleVariantIdUpdate = (e: React.ChangeEvent) => { - const variantId: number = parseInt(e.target.value); + const handleDocumentTypeIdUpdate = (e: React.ChangeEvent) => { + const documentTypeId: number = parseInt(e.target.value); if (e.target.checked) { - setVariants((prevVariants) => [...prevVariants, variantId]); + setDocumentTypeIds((prevDocTypeIds) => [...prevDocTypeIds, documentTypeId]); } else { - setVariants(variants.filter((v) => v === variantId)); + setDocumentTypeIds(documentTypeIds.filter((v) => v === documentTypeId)); } }; @@ -127,7 +129,7 @@ const AddProvisionModal: React.FC = ({ free_text: freeText, help_text: helpText, category: category, - variants: variants, + document_type_ids: documentTypeIds, }; addProvisionHandler(provisionUpload); refreshTables(); @@ -256,48 +258,25 @@ const AddProvisionModal: React.FC = ({ - Variants + Document Types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + {documentTypes && + documentTypes.map((docType) => { + return ( + + + + + + + + + ); + })} - + = () => { show={showUploadModal} onHide={() => setShowUploadModal(false)} onUpload={refreshTables} - reportType={currentReportType} + documentTypeId={1} + documentTypeName="placeholder" /> setShowRemoveTemplateModal(false)} onRemove={refreshTables} - reportType={currentReportType} + documentTypeId={1} templateId={currentReportId} /> setShowEditProvisionModal(false)} @@ -189,6 +192,7 @@ const ManageTemplatesPage: FC = () => { /> setShowAddProvisionModal(false)} addProvisionHandler={addProvisionHandler} diff --git a/frontend/src/app/content/pages/ReportPage.tsx b/frontend/src/app/content/pages/ReportPage.tsx index 256ce5fa..1d7bc78f 100644 --- a/frontend/src/app/content/pages/ReportPage.tsx +++ b/frontend/src/app/content/pages/ReportPage.tsx @@ -1,21 +1,20 @@ import { FC, useCallback, useEffect, useState } from 'react'; import Collapsible from '../../../app/components/common/Collapsible'; -import { DTRDisplayObject, DocumentType } from '../../../app/types/types'; +import { DTRDisplayObject, DocType, ProvisionGroup } from '../../../app/types/types'; import TenureDetails from '../display/TenureDetails'; import AreaDetails from '../display/AreaDetails'; import DtidDetails from '../display/DtidDetails'; import { - generateNfrReport, generateReport, getData, getDocumentProvisionsByDocTypeIdDtid, saveDocument, getMandatoryProvisionsByDocTypeId, + getGroupMaxByDocTypeId, } from '../../common/report'; -import VariantDropdown from '../../components/common/VariantDropdown'; -import { CURRENT_REPORT_PAGES, NFR_REPORT_PAGES, NFR_VARIANTS } from '../../util/constants'; +import { CURRENT_REPORT_PAGES } from '../../util/constants'; import InterestedParties from '../display/InterestedParties'; -import { useParams, useNavigate } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import Skeleton from 'react-loading-skeleton'; import Provisions, { ProvisionData } from '../display/Provisions'; import Variables from '../display/Variables'; @@ -24,18 +23,14 @@ import { SaveVariableData, VariableJson } from '../../components/table/reports/V import { Button } from 'react-bootstrap'; export interface ReportPageProps { - documentType: DocumentType; + documentType: DocType; } -// TODO - remove variants, possibly replace with document type dropdown -// remove any mention of nfr - const ReportPage: FC = ({ documentType }) => { const { dtid } = useParams<{ dtid: string }>(); const dtidNumber = dtid ? parseInt(dtid, 10) : null; const [loading, setLoading] = useState(false); const [data, setData] = useState(null); - const [showNfr, setShowNfr] = useState(false); const [allProvisions, setAllProvisions] = useState([]); const [variableArray, setVariableArray] = useState([]); const [provisionArray, setProvisionArray] = useState([]); @@ -43,16 +38,14 @@ const ReportPage: FC = ({ documentType }) => { const [provisionJsonArray, setProvisionJsonArray] = useState([]); const [selectedProvisionIds, setSelectedProvisionIds] = useState([]); const [mandatoryProvisionIds, setMandatoryProvisionIds] = useState([]); - - const navigate = useNavigate(); + const [provisionGroups, setProvisionGroups] = useState([]); useEffect(() => { - setShowNfr(NFR_VARIANTS.includes(documentType.name.toUpperCase())); const fetchData = async () => { if (dtidNumber) { try { setLoading(true); - const fetchedData: DTRDisplayObject = await getData(dtidNumber); + const fetchedData: DTRDisplayObject = await getData(documentType.id, dtidNumber); setData(fetchedData); const fetchProvisions: ProvisionData[] = await getDocumentProvisionsByDocTypeIdDtid( documentType.id, @@ -61,6 +54,8 @@ const ReportPage: FC = ({ documentType }) => { setAllProvisions(fetchProvisions); const mpIds: number[] = await getMandatoryProvisionsByDocTypeId(documentType.id); setMandatoryProvisionIds(mpIds); + const provisionGroupsObject: ProvisionGroup[] = await getGroupMaxByDocTypeId(documentType.id); + setProvisionGroups(provisionGroupsObject); } catch (error) { console.error('Failed to fetch data', error); setData(null); @@ -72,24 +67,12 @@ const ReportPage: FC = ({ documentType }) => { fetchData(); }, [dtidNumber, documentType]); - const generateReportHandler = () => { - if (dtidNumber) { - generateReport(dtidNumber, data!.fileNum, documentType.name); - } - }; - - const handleNfrGenerate = () => { + const handleGenerateReport = () => { if (dtidNumber) { const errorMessage = validateProvisions(); if (!errorMessage) { if (data) { - generateNfrReport( - dtidNumber, - data.fileNum, - documentType.name.toUpperCase(), - provisionJsonArray, - variableJsonArray - ); + generateReport(dtidNumber, data!.fileNum, documentType.id, provisionJsonArray, variableJsonArray); } } else { alert(errorMessage); @@ -110,11 +93,6 @@ const ReportPage: FC = ({ documentType }) => { } }; - const variantChangeHandler = (variant: string) => { - const upperCaseVariant = variant.toUpperCase(); - navigate(`/dtid/${dtid}/${upperCaseVariant}`); - }; - const updateSelectedProvisionIds = useCallback((selectedProvisionIds: number[]) => { setSelectedProvisionIds(selectedProvisionIds); }, []); @@ -145,14 +123,14 @@ const ReportPage: FC = ({ documentType }) => { setProvisionJsonArray(provisionJsonData); }, []); - const handleNfrSave = () => { + const handleDocumentSave = () => { const saveData = async () => { if (dtidNumber) { try { setLoading(true); - await saveDocument(dtidNumber, documentType.name.toUpperCase(), provisionArray, variableArray); + await saveDocument(dtidNumber, documentType.id, provisionArray, variableArray); } catch (err) { - console.log('Error saving NFR Data'); + console.log('Error saving Document Data'); console.log(err); } finally { setLoading(false); @@ -168,16 +146,6 @@ const ReportPage: FC = ({ documentType }) => { <>
Preview - {documentType.name} (Draft)

- {Object.values(NFR_REPORT_PAGES).includes(documentType.name) && ( -
- -
-
- )}
DTID:
@@ -203,42 +171,38 @@ const ReportPage: FC = ({ documentType }) => { ) : ( {data ? : } )} - {showNfr && ( - - - - )} - {showNfr && ( - - - + {provisionGroups && ( + <> + + + + + + + + )}
- {showNfr ? ( - <> - - - - ) : ( - + - )} +
); diff --git a/frontend/src/app/content/pages/SearchPage.tsx b/frontend/src/app/content/pages/SearchPage.tsx index b81d3f67..382edfd0 100644 --- a/frontend/src/app/content/pages/SearchPage.tsx +++ b/frontend/src/app/content/pages/SearchPage.tsx @@ -7,17 +7,18 @@ import { FC, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import SearchDataTable from '../../components/table/search/SearchDataTable'; +import { DocType } from '../../types/types'; // TODO - redo page to include all document types, replace variant with document type const SearchPage: FC = () => { - const [selectedDocument, setSelectedDocument] = useState<{ dtid: number; variant: string } | null>(null); + const [selectedDocument, setSelectedDocument] = useState<{ dtid: number; documentType: DocType } | null>(null); const [searchTerm, setSearchTerm] = useState(''); const navigate = useNavigate(); const handleOpenDocument = async () => { if (selectedDocument) { - navigate(`/dtid/${selectedDocument.dtid}/${selectedDocument.variant}`); + navigate(`/dtid/${selectedDocument.dtid}/${selectedDocument.documentType.name}`); } }; @@ -25,8 +26,8 @@ const SearchPage: FC = () => { setSearchTerm(e.target.value); }; - const handleSelectedDocumentChange = (dtid: number, variant: string) => { - setSelectedDocument({ dtid, variant }); + const handleSelectedDocumentChange = (dtid: number, documentType: DocType) => { + setSelectedDocument({ dtid, documentType }); }; return ( diff --git a/frontend/src/app/content/pages/documentpreview/DocumentPreview.tsx b/frontend/src/app/content/pages/documentpreview/DocumentPreview.tsx index 8788882b..26a2b0a4 100644 --- a/frontend/src/app/content/pages/documentpreview/DocumentPreview.tsx +++ b/frontend/src/app/content/pages/documentpreview/DocumentPreview.tsx @@ -1,5 +1,9 @@ import React, { useState } from 'react'; -import { getData, getNfrProvisionsByVariantDtid, getNfrVariablesByVariantDtid } from '../../../common/report'; +import { + getData, + getDocumentProvisionsByDocTypeIdDtid, + getDocumentVariablesByDocTypeIdDtid, +} from '../../../common/report'; import DocumentPreviewForm from './DocumentPreviewForm'; import ContactInfoDisplay from './ContactInfoDisplay'; import LicenseDetailDisplay from './LicenseDetailDisplay'; @@ -9,7 +13,6 @@ import ProvisionsTable from './ProvisionsTable'; import './DocumentPreview.scss'; import CustomCollapsible from './CustomCollapsible'; - interface DocumentPreviewResponse { dtid: number; fileNum: string; @@ -40,7 +43,6 @@ interface DocumentPreviewResponse { }>; } - interface Provision { type: string; provision: string; @@ -85,8 +87,8 @@ const DocumentPreview: React.FC = () => { const handleClear = () => { setTenureFileNumber(''); setDtid(''); - setIsOpen(false) - setDocumentPreviewResponse(null) + setIsOpen(false); + setDocumentPreviewResponse(null); }; const [provisions, setProvisions] = useState([ @@ -97,25 +99,22 @@ const DocumentPreview: React.FC = () => { const [documentType, setDocumentType] = useState('STANDARD_LICENSE'); - const handleCheckboxChange = (index: number) => { provisions[index].included = !provisions[index].included; }; - - const fetchData = async () => { - const nfrData = await getData(parseInt(dtid)) as DocumentPreviewResponse; + const nfrData = (await getData(1, parseInt(dtid))) as DocumentPreviewResponse; if (nfrData) { - setDocumentPreviewResponse(nfrData) - const dataProvisions = await getNfrProvisionsByVariantDtid("NOTICE OF FINAL REVIEW", 928437); - const dataVariables = await getNfrVariablesByVariantDtid("NOTICE OF FINAL REVIEW", 928437); + setDocumentPreviewResponse(nfrData); + const dataProvisions = await getDocumentProvisionsByDocTypeIdDtid(1, 928437); + const dataVariables = await getDocumentVariablesByDocTypeIdDtid(1, 928437); setIsOpen(true); } }; const handleRetrieve = () => { - if (tenureFileNumber !== "" && dtid !== "") { + if (tenureFileNumber !== '' && dtid !== '') { fetchData(); } }; @@ -123,83 +122,91 @@ const DocumentPreview: React.FC = () => { const toggleCollapsible = () => setIsOpen(!isOpen); - - - - return (
- - - {documentPreviewResponse !== null ? : ""} + isSpanRequired={false} + > + {documentPreviewResponse !== null ? ( + + ) : ( + '' + )} - - - {documentPreviewResponse !== null ? : ""} + isSpanRequired={false} + > + {documentPreviewResponse !== null ? ( + + ) : ( + '' + )} - - - {documentPreviewResponse !== null ? : ""} + isSpanRequired={false} + > + {documentPreviewResponse !== null ? ( + + ) : ( + '' + )}

Create Document


-
- - + { /> - - +
- - + +
); diff --git a/frontend/src/app/types/types.ts b/frontend/src/app/types/types.ts index 27ac130b..bb39f76b 100644 --- a/frontend/src/app/types/types.ts +++ b/frontend/src/app/types/types.ts @@ -112,13 +112,13 @@ export interface InterestedParties { address: string | null; } -export type NfrDataVariableObject = { +export type DocumentDataVariableObject = { data_variable_value: string; id: number; - nfr_variable: NfrVariableObject; + provision_variable: ProvisionVariableObject; }; -export type NfrVariableObject = { +export type ProvisionVariableObject = { id: number; variable_name: string; variable_value: string; @@ -129,13 +129,13 @@ export type NfrVariableObject = { update_timestamp: string; }; -export type NfrDataProvisionObject = { +export type DocumentDataProvisionObject = { provision_free_text: string; id: number; - provision: NfrProvisionObject; + provision: ProvisionObject; }; -export type NfrProvisionObject = { +export type ProvisionObject = { type: string; provision_name: string; free_text: string; @@ -157,10 +157,9 @@ export type ProvisionGroup = { max: number; }; -export type NfrDataObject = { - nfrData: { +export type DocumentDataObject = { + documentData: { dtid: number; - variant_name: string; template_id: number; status: string; create_userid: string; @@ -169,8 +168,9 @@ export type NfrDataObject = { active: boolean; create_timestamp: string; update_timestamp: string; - document_data_provisions: NfrDataProvisionObject; - document_data_variables: NfrDataVariableObject; + document_data_provisions: DocumentDataProvisionObject; + document_data_variables: DocumentDataVariableObject; + document_type: any; // }; provisionIds: number[]; variableIds: number[]; @@ -204,7 +204,7 @@ export type Provision = { edit: any; // remove from route help_text: string; id: number; - variants: any; // seems to be a string array which gets converted to string and saved in the cell + document_type_ids: number[]; // }; export type Variable = { @@ -226,7 +226,7 @@ export type ProvisionUpload = { free_text: string; help_text: string; category: string; - variants: any; + document_type_ids: number[]; // }; export type VariableUpload = { @@ -243,11 +243,11 @@ export type SearchData = { updated_date: string; status: string; active: boolean; - nfr_id: number; - variant_name: string; + document_data_id: number; // + document_type: DocType; // }; -export type DocumentType = { +export type DocType = { id: number; name: string; create_userid: string;