From 6d6924b92a951f5432fe859a96662bec2605a86b Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Mon, 6 May 2024 12:40:45 -0700 Subject: [PATCH 01/16] Changes to ignore duplicates for summary generation. --- web/src/components/FOI/Home/Redlining.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index a1553dd27..056d1c08f 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -3340,7 +3340,9 @@ const Redlining = React.forwardRef( // sort based on sortorder as the sortorder added based on the LastModified let sorteddocs = sortBySortOrder(alldocuments) for (const sorteddoc of sorteddocs) { - sorteddocids.push(sorteddoc['documentid']); + if (sorteddocids.includes(sorteddoc['documentid']) == false) { + sorteddocids.push(sorteddoc['documentid']); + } } return {"sorteddocuments": sorteddocids, "pkgdocuments": summarylist} @@ -3978,7 +3980,10 @@ const Redlining = React.forwardRef( // sort based on sortorder as the sortorder added based on the LastModified let sorteddocs = sortBySortOrder(alldocuments) for (const sorteddoc of sorteddocs) { - sorteddocids.push(sorteddoc['documentid']); + if (sorteddocids.includes(sorteddoc['documentid']) == false) { + sorteddocids.push(sorteddoc['documentid']); + } + } return {"sorteddocuments": sorteddocids, "pkgdocuments": summarylist} } From f24ba073a9909be70285a23df8df9a9c6b2ec125 Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Mon, 6 May 2024 12:45:58 -0700 Subject: [PATCH 02/16] Changes to ignore duplicates for summary generation. --- web/src/components/FOI/Home/Redlining.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index 056d1c08f..d3ce2854e 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -3340,7 +3340,7 @@ const Redlining = React.forwardRef( // sort based on sortorder as the sortorder added based on the LastModified let sorteddocs = sortBySortOrder(alldocuments) for (const sorteddoc of sorteddocs) { - if (sorteddocids.includes(sorteddoc['documentid']) == false) { + if (!sorteddocids.includes(sorteddoc['documentid'])) { sorteddocids.push(sorteddoc['documentid']); } } @@ -3980,7 +3980,7 @@ const Redlining = React.forwardRef( // sort based on sortorder as the sortorder added based on the LastModified let sorteddocs = sortBySortOrder(alldocuments) for (const sorteddoc of sorteddocs) { - if (sorteddocids.includes(sorteddoc['documentid']) == false) { + if (!sorteddocids.includes(sorteddoc['documentid'])) { sorteddocids.push(sorteddoc['documentid']); } From dc5070d674542660a76f46c87b70d01312731332 Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Mon, 6 May 2024 17:48:11 -0400 Subject: [PATCH 03/16] NR/Duplicate not selected issue fixed --- web/src/components/FOI/Home/Redlining.js | 89 ++++++++++++++++-------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index a1553dd27..8735294d9 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -241,6 +241,24 @@ const Redlining = React.forwardRef( return !stopLoop; }; + const skipDocument = (documentPageFlags, pagecount) => { + let pageFlagArray = []; + let skipdocument = false; + if (documentPageFlags?.length > 0) { + pageFlagArray = documentPageFlags?.filter((flag) => + [ + pageFlagTypes["Duplicate"], + pageFlagTypes["Not Responsive"], + ].includes(flag.flagid)); + + if (pageFlagArray.length == pagecount) { + skipdocument = true; + } + + } + return skipdocument; + } + const isValidRedlineDownload = () => { let isvalid = false; let pageFlagArray = []; @@ -3361,6 +3379,8 @@ const Redlining = React.forwardRef( for (const [key, value] of Object.entries(stitchlist)) { divCount++; let docCount = 0; + // added this vopy variable for validating the first document of a division with NR/Duplicate + let docCountCopy = 0; let division = key; let documentlist = stitchlist[key]; if (redlineSinglePkg == "N") { @@ -3375,33 +3395,43 @@ const Redlining = React.forwardRef( }); } if(documentlist.length > 0) { - for (let doc of documentlist) { - await _instance.Core.createDocument(doc.s3path_load, { - loadAsPDF: true, - useDownloader: false, // Added to fix BLANK page issue - }).then(async (docObj) => { - //if (isIgnoredDocument(doc, docObj.getPageCount(), divisionDocuments) == false) { - docCount++; - if (docCount == 1) { - // Delete pages from the first document - const deletedPages = getDeletedPagesBeforeStitching(doc.documentid); - if (deletedPages.length > 0) { - docObj.removePages(deletedPages); - } - stitchedDocObj = docObj; - } else { - let pageIndexToInsert = stitchedDocObj?.getPageCount() + 1; - await stitchedDocObj.insertPages( - docObj, - doc.pages, - pageIndexToInsert - ); - } - //} - }); - if (docCount == documentlist.length && redlineSinglePkg == "N" ) { - requestStitchObject[division] = stitchedDocObj; - } + for (let doc of documentlist) { + await _instance.Core.createDocument(doc.s3path_load, { + loadAsPDF: true, + useDownloader: false, // Added to fix BLANK page issue + }).then(async (docObj) => { + //if (isIgnoredDocument(doc, docObj.getPageCount(), divisionDocuments) == false) { + docCountCopy++; + docCount++; + if (docCountCopy == 1) { + // Delete pages from the first document + const deletedPages = getDeletedPagesBeforeStitching(doc.documentid); + if (deletedPages.length > 0) { + docObj.removePages(deletedPages); + } + if (!skipDocument(doc.pageFlag, doc.pagecount)) { + stitchedDocObj = docObj; + } + else { + docCountCopy--; + } + + } else { + if (stitchedDocObj && !skipDocument(doc.pageFlag, doc.pagecount)) { + let pageIndexToInsert = stitchedDocObj?.getPageCount() + 1; + await stitchedDocObj.insertPages( + docObj, + doc.pages, + pageIndexToInsert + ); + } + } + //} + }); + if (docCount == documentlist.length && redlineSinglePkg == "N" ) { + requestStitchObject[division] = stitchedDocObj; + } + } } else { if (incompatableList[division]["incompatibleFiles"].length > 0) { @@ -3613,7 +3643,7 @@ const Redlining = React.forwardRef( if (stitchObject == null) { triggerRedlineZipper( redlineIncompatabileMappings[divisionid], - redlineStitchInfo[divisionid]["s3path"], + null, // stitchObject == null then no stichedDocPath available divisionCountForToast, redlineSinglePackage ); @@ -3633,7 +3663,8 @@ const Redlining = React.forwardRef( } if ( redlinepageMappings["pagestoremove"][divisionid] && - redlinepageMappings["pagestoremove"][divisionid].length > 0 + redlinepageMappings["pagestoremove"][divisionid].length > 0 && + stitchObject?.getPageCount() > redlinepageMappings["pagestoremove"][divisionid].length ) { await stitchObject.removePages( redlinepageMappings["pagestoremove"][divisionid] From d80494b022751ea363ec23c113a1dd56b658f15b Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Mon, 6 May 2024 15:10:21 -0700 Subject: [PATCH 04/16] Chnages to redline name . --- .../DocumentServices/services/redactionsummaryservice.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/computingservices/DocumentServices/services/redactionsummaryservice.py b/computingservices/DocumentServices/services/redactionsummaryservice.py index 447b6a924..5c0bc53b3 100644 --- a/computingservices/DocumentServices/services/redactionsummaryservice.py +++ b/computingservices/DocumentServices/services/redactionsummaryservice.py @@ -41,7 +41,7 @@ def processmessage(self,incomingmessage): stitcheddocfilename = filesobj['filename'] s3uricategoryfolder= "oipcreview" if category == 'oipcreviewredline' else category s3uri = stitcheddocs3uri.split(s3uricategoryfolder+"/")[0] + s3uricategoryfolder+"/" - filename = stitcheddocfilename.replace(".pdf","- summary.pdf") + filename = self.__get_filename(message.requestnumber, category) uploadobj= uploadbytes(filename,redaction_summary.content, s3uri) upload_responses.append(uploadobj) if uploadobj["uploadresponse"].status_code == 200: @@ -57,6 +57,11 @@ def processmessage(self,incomingmessage): print('error occured in redaction summary service: ', error) pdfstitchjobactivity().recordjobstatus(message,4,"redactionsummaryfailed",str(error),"summary generation failed") return summaryfilestozip + + def __get_filename(self, requestnumber, category): + if category == 'responsepackage': + return requestnumber+" - summary.pdf" + return requestnumber+" - "+category+" - summary.pdf" def __get_pageflags(self, category): From 8a79a6c3d87485529d0f91c8aeeb5f1b7959bfc0 Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Mon, 6 May 2024 15:11:00 -0700 Subject: [PATCH 05/16] Chnages to redline name . --- .../DocumentServices/services/redactionsummaryservice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/computingservices/DocumentServices/services/redactionsummaryservice.py b/computingservices/DocumentServices/services/redactionsummaryservice.py index 5c0bc53b3..0cdf17371 100644 --- a/computingservices/DocumentServices/services/redactionsummaryservice.py +++ b/computingservices/DocumentServices/services/redactionsummaryservice.py @@ -38,7 +38,7 @@ def processmessage(self,incomingmessage): else: filesobj= messageattributes[0]['files'][0] stitcheddocs3uri = filesobj['s3uripath'] - stitcheddocfilename = filesobj['filename'] + #stitcheddocfilename = filesobj['filename'] s3uricategoryfolder= "oipcreview" if category == 'oipcreviewredline' else category s3uri = stitcheddocs3uri.split(s3uricategoryfolder+"/")[0] + s3uricategoryfolder+"/" filename = self.__get_filename(message.requestnumber, category) From 77dc06c3cfd2cfa438669b104202537de1364c35 Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Mon, 6 May 2024 16:15:01 -0700 Subject: [PATCH 06/16] Chnages to redline name . --- .../services/redactionsummaryservice.py | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/computingservices/DocumentServices/services/redactionsummaryservice.py b/computingservices/DocumentServices/services/redactionsummaryservice.py index 0cdf17371..872b1563e 100644 --- a/computingservices/DocumentServices/services/redactionsummaryservice.py +++ b/computingservices/DocumentServices/services/redactionsummaryservice.py @@ -33,16 +33,19 @@ def processmessage(self,incomingmessage): template_path='templates/'+documenttypename+'.docx' redaction_summary= documentgenerationservice().generate_pdf(formattedsummary, documenttypename,template_path) messageattributes= json.loads(message.attributes) + divisioname = None if len(messageattributes)>1: filesobj=(next(item for item in messageattributes if item['divisionid'] == divisionid))['files'][0] + divisioname=(next(item for item in messageattributes if item['divisionid'] == divisionid))['divisionname'] else: filesobj= messageattributes[0]['files'][0] + divisioname = messageattributes[0]['divisionname'] stitcheddocs3uri = filesobj['s3uripath'] - #stitcheddocfilename = filesobj['filename'] + stitcheddocfilename = filesobj['filename'] s3uricategoryfolder= "oipcreview" if category == 'oipcreviewredline' else category s3uri = stitcheddocs3uri.split(s3uricategoryfolder+"/")[0] + s3uricategoryfolder+"/" - filename = self.__get_filename(message.requestnumber, category) - uploadobj= uploadbytes(filename,redaction_summary.content, s3uri) + filename =self.__get_summaryfilename(message.requestnumber, category, divisioname, stitcheddocfilename) + uploadobj= uploadbytes(filename,redaction_summary.content,s3uri) upload_responses.append(uploadobj) if uploadobj["uploadresponse"].status_code == 200: summaryuploaderror= False @@ -58,12 +61,18 @@ def processmessage(self,incomingmessage): pdfstitchjobactivity().recordjobstatus(message,4,"redactionsummaryfailed",str(error),"summary generation failed") return summaryfilestozip - def __get_filename(self, requestnumber, category): + def __get_summaryfilename(self, requestnumber, category, divisionname, stitcheddocfilename): + stitchedfilepath = stitcheddocfilename[:stitcheddocfilename.rfind( '/')+1] if category == 'responsepackage': - return requestnumber+" - summary.pdf" - return requestnumber+" - "+category+" - summary.pdf" - - + _filename = requestnumber + elif category == 'oipcreviewredline': + _filename = requestnumber+ ' - Redline' + else: + _filename = requestnumber+" - "+category + if divisionname not in (None, ''): + _filename = _filename+" - "+divisionname + return stitchedfilepath+_filename+" - summary.pdf" + def __get_pageflags(self, category): if category == "responsepackage": return documentpageflag().get_all_pageflags(['Consult', 'Not Responsive', 'Duplicate']) From d2d21d9d1a7e78b95651bf2e703b259ef6b2909e Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Mon, 6 May 2024 16:22:12 -0700 Subject: [PATCH 07/16] Chnages to redline name . --- .../DocumentServices/services/redactionsummaryservice.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/computingservices/DocumentServices/services/redactionsummaryservice.py b/computingservices/DocumentServices/services/redactionsummaryservice.py index 872b1563e..fb21e91b4 100644 --- a/computingservices/DocumentServices/services/redactionsummaryservice.py +++ b/computingservices/DocumentServices/services/redactionsummaryservice.py @@ -36,10 +36,12 @@ def processmessage(self,incomingmessage): divisioname = None if len(messageattributes)>1: filesobj=(next(item for item in messageattributes if item['divisionid'] == divisionid))['files'][0] - divisioname=(next(item for item in messageattributes if item['divisionid'] == divisionid))['divisionname'] + divisioname=(next(item for item in messageattributes if item['divisionid'] == divisionid))['divisionname'] if category not in ('responsepackage','oipcreviewredline') else None + else: filesobj= messageattributes[0]['files'][0] - divisioname = messageattributes[0]['divisionname'] + divisioname = messageattributes[0]['divisionname'] if category not in ('responsepackage','oipcreviewredline') else None + stitcheddocs3uri = filesobj['s3uripath'] stitcheddocfilename = filesobj['filename'] s3uricategoryfolder= "oipcreview" if category == 'oipcreviewredline' else category From 3ddcf3edd66c1495d8f6ce1a8bacbcc4252cdf5c Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 7 May 2024 13:12:36 -0400 Subject: [PATCH 08/16] NR/Duplicate issue fix --- web/src/components/FOI/Home/Redlining.js | 116 +++++++++++++++-------- web/src/components/FOI/Home/utils.js | 53 +++++++++++ 2 files changed, 127 insertions(+), 42 deletions(-) diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index 83a3a835f..366f9ffd2 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -71,7 +71,10 @@ import { getJoinedSections, isObjectNotEmpty, getValidObject, - constructPageFlags + constructPageFlags, + skipDocument, + skipDuplicateDocument, + skipNRDocument } from "./utils"; import { Edit, MultiSelectEdit } from "./Edit"; import _ from "lodash"; @@ -210,7 +213,7 @@ const Redlining = React.forwardRef( stopLoop = true; return false; //stop loop } else { - // artial Disclosure, Full Disclosure, Withheld in Full, Duplicate, Not Responsive + // partial Disclosure, Full Disclosure, Withheld in Full, Duplicate, Not Responsive pageFlagArray = pageFlagInfo.pageflag?.filter((flag) => [ pageFlagTypes["Partial Disclosure"], @@ -241,24 +244,6 @@ const Redlining = React.forwardRef( return !stopLoop; }; - const skipDocument = (documentPageFlags, pagecount) => { - let pageFlagArray = []; - let skipdocument = false; - if (documentPageFlags?.length > 0) { - pageFlagArray = documentPageFlags?.filter((flag) => - [ - pageFlagTypes["Duplicate"], - pageFlagTypes["Not Responsive"], - ].includes(flag.flagid)); - - if (pageFlagArray.length == pagecount) { - skipdocument = true; - } - - } - return skipdocument; - } - const isValidRedlineDownload = () => { let isvalid = false; let pageFlagArray = []; @@ -2766,6 +2751,18 @@ const Redlining = React.forwardRef( let pageIndex = 1; //gather pages that need to be removed doc.pageFlag.sort((a, b) => a.page - b.page); //sort pageflag by page # + let skipDocumentPages = false; + let skipOnlyDuplicateDocument = false; + let skipOnlyNRDocument = false; + if (!includeDuplicatePages && !includeNRPages) { + skipDocumentPages = skipDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } + else if (!includeDuplicatePages) { + skipOnlyDuplicateDocument = skipDuplicateDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } + else if (!includeNRPages) { + skipOnlyNRDocument = skipNRDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } //if(isIgnoredDocument(doc, doc['pagecount'], divisionDocuments) == false) { for (const flagInfo of doc.pageFlag) { if (flagInfo.flagid !== pageFlagTypes["Consult"]) { // ignore consult flag to fix bug FOIMOD-3062 @@ -2779,11 +2776,13 @@ const Redlining = React.forwardRef( pagesToRemoveEachDoc.length; } else { pagesToRemoveEachDoc.push(flagInfo.page); - - pagesToRemove.push( - pageIndex + totalPageCountIncludeRemoved - ); + if (!skipDocumentPages && !skipOnlyDuplicateDocument) { + pagesToRemove.push( + pageIndex + totalPageCountIncludeRemoved + ); + } } + } else if (flagInfo.flagid == pageFlagTypes["Not Responsive"]) { if(includeNRPages) { NRWatermarksPagesEachDiv.push(pageIndex + totalPageCountIncludeRemoved - pagesToRemove.length); @@ -2794,10 +2793,11 @@ const Redlining = React.forwardRef( pagesToRemoveEachDoc.length; } else { pagesToRemoveEachDoc.push(flagInfo.page); - - pagesToRemove.push( - pageIndex + totalPageCountIncludeRemoved - ); + if (!skipDocumentPages && !skipOnlyNRDocument) { + pagesToRemove.push( + pageIndex + totalPageCountIncludeRemoved + ); + } } } else { if (flagInfo.flagid !== pageFlagTypes["Consult"]) { @@ -2816,7 +2816,9 @@ const Redlining = React.forwardRef( totalPageCount += Object.keys( pageMappings[doc.documentid] ).length; - totalPageCountIncludeRemoved += doc.pagecount; + if (!skipDocumentPages) { + totalPageCountIncludeRemoved += doc.pagecount; + } //} } @@ -3228,17 +3230,32 @@ const Redlining = React.forwardRef( for (let doc of div.documentlist) { docCount++; documentsObjArr.push(doc); - if (docCount == div.documentlist.length) { - if (pageMappedDocs != undefined) { - let divisionsdocpages = Object.values( - pageMappedDocs.redlineDocIdLookup - ) - .filter((obj) => { - return obj.division.includes(div.divisionid); - }) - .map((obj) => { + let skipDocumentPages = false; + let skipOnlyDuplicateDocument = false; + let skipOnlyNRDocument = false; + if (!includeDuplicatePages && !includeNRPages) { + skipDocumentPages = skipDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } + else if (!includeDuplicatePages) { + skipOnlyDuplicateDocument = skipDuplicateDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } + else if (!includeNRPages) { + skipOnlyNRDocument = skipNRDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } + if (pageMappedDocs != undefined) { + let divisionsdocpages = Object.values( + pageMappedDocs.redlineDocIdLookup + ) + .filter((obj) => { + return obj.division.includes(div.divisionid) && obj.docId == doc.documentid; + }) + .map((obj) => { + if (!skipDocumentPages && !skipOnlyDuplicateDocument && !skipOnlyNRDocument) { return obj.pageMappings; - }); + } + // return {}; + }); + if (divisionsdocpages[0]) { divisionsdocpages.forEach(function (_arr) { _arr.forEach(function (value) { divisionstitchpages.push(value); @@ -3253,6 +3270,9 @@ const Redlining = React.forwardRef( ); } } + // if (docCount == div.documentlist.length) { + + // } } } if ( @@ -3397,7 +3417,19 @@ const Redlining = React.forwardRef( }); } if(documentlist.length > 0) { - for (let doc of documentlist) { + for (let doc of documentlist) { + let skipDocumentPages = false; + let skipOnlyDuplicateDocument = false; + let skipOnlyNRDocument = false; + if (!includeDuplicatePages && !includeNRPages) { + skipDocumentPages = skipDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } + else if (!includeDuplicatePages) { + skipOnlyDuplicateDocument = skipDuplicateDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } + else if (!includeNRPages) { + skipOnlyNRDocument = skipNRDocument(doc.pageFlag, doc.pagecount, pageFlagTypes); + } await _instance.Core.createDocument(doc.s3path_load, { loadAsPDF: true, useDownloader: false, // Added to fix BLANK page issue @@ -3411,7 +3443,7 @@ const Redlining = React.forwardRef( if (deletedPages.length > 0) { docObj.removePages(deletedPages); } - if (!skipDocument(doc.pageFlag, doc.pagecount)) { + if (!skipDocumentPages && !skipOnlyDuplicateDocument && !skipOnlyNRDocument) { stitchedDocObj = docObj; } else { @@ -3419,7 +3451,7 @@ const Redlining = React.forwardRef( } } else { - if (stitchedDocObj && !skipDocument(doc.pageFlag, doc.pagecount)) { + if (stitchedDocObj && (!skipDocumentPages && !skipOnlyDuplicateDocument && !skipOnlyNRDocument)) { let pageIndexToInsert = stitchedDocObj?.getPageCount() + 1; await stitchedDocObj.insertPages( docObj, diff --git a/web/src/components/FOI/Home/utils.js b/web/src/components/FOI/Home/utils.js index 7d1c0c728..89afd78dc 100644 --- a/web/src/components/FOI/Home/utils.js +++ b/web/src/components/FOI/Home/utils.js @@ -536,4 +536,57 @@ const getRedactionType = (sectionValue, isFullPage, RedactionTypes) => { else if (["", " "].includes(sectionValue)) { return RedactionTypes["blank"]; // in progress } +} + + +export const skipDocument = (documentPageFlags, pagecount, pageFlagTypes) => { + let pageFlagArray = []; + let skipdocument = false; + if (documentPageFlags?.length > 0) { + pageFlagArray = documentPageFlags?.filter((flag) => + [ + pageFlagTypes["Duplicate"], + pageFlagTypes["Not Responsive"], + ].includes(flag.flagid)); + + if (pageFlagArray.length == pagecount) { + skipdocument = true; + } + + } + return skipdocument; +} + +export const skipDuplicateDocument = (documentPageFlags, pagecount, pageFlagTypes) => { + let pageFlagArray = []; + let skipdocument = false; + if (documentPageFlags?.length > 0) { + pageFlagArray = documentPageFlags?.filter((flag) => + [ + pageFlagTypes["Duplicate"], + ].includes(flag.flagid)); + + if (pageFlagArray.length == pagecount) { + skipdocument = true; + } + + } + return skipdocument; +} + +export const skipNRDocument = (documentPageFlags, pagecount, pageFlagTypes) => { + let pageFlagArray = []; + let skipdocument = false; + if (documentPageFlags?.length > 0) { + pageFlagArray = documentPageFlags?.filter((flag) => + [ + pageFlagTypes["Not Responsive"], + ].includes(flag.flagid)); + + if (pageFlagArray.length == pagecount) { + skipdocument = true; + } + + } + return skipdocument; } \ No newline at end of file From 95d4b734e6f4a395068e791dbda0f7bb410029e7 Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 7 May 2024 16:03:43 -0400 Subject: [PATCH 09/16] fixed page stamping issue --- web/src/components/FOI/Home/Redlining.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index 366f9ffd2..b731fab88 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -3250,10 +3250,9 @@ const Redlining = React.forwardRef( return obj.division.includes(div.divisionid) && obj.docId == doc.documentid; }) .map((obj) => { - if (!skipDocumentPages && !skipOnlyDuplicateDocument && !skipOnlyNRDocument) { + if (res.issingleredlinepackage == "Y" || (!skipDocumentPages && !skipOnlyDuplicateDocument && !skipOnlyNRDocument)) { return obj.pageMappings; } - // return {}; }); if (divisionsdocpages[0]) { divisionsdocpages.forEach(function (_arr) { From 8fcb8a32bac6bd4f67180f378e7b78d074dad513 Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Tue, 7 May 2024 14:57:33 -0700 Subject: [PATCH 10/16] Changes to fix the bug and generate package on category "responsepackage." --- .../DocumentServices/services/dts/redactionsummary.py | 4 ++-- web/src/components/FOI/Home/Redlining.js | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/computingservices/DocumentServices/services/dts/redactionsummary.py b/computingservices/DocumentServices/services/dts/redactionsummary.py index ff1b45fb8..fd4afdce6 100644 --- a/computingservices/DocumentServices/services/dts/redactionsummary.py +++ b/computingservices/DocumentServices/services/dts/redactionsummary.py @@ -20,7 +20,7 @@ def __getrangenumber(self, rangeval): def __packaggesummary(self, message, documentids, pageflags, programareas): try: - redactionlayerid = message.redactionlayerid + redactionlayerid = message.redactionlayerid if message.category != "responsepackage" else 1 summarymsg = message.summarydocuments summaryobject = get_in_summary_object(summarymsg) ordereddocids = summaryobject.sorteddocuments @@ -48,7 +48,7 @@ def __packaggesummary(self, message, documentids, pageflags, programareas): pageflag['docpageflags'] = pageflag['docpageflags'] + self.__get_pagesection_mapping(filteredpages, docpagesections, docpageconsults) skippages = self.__get_skippagenos(docpageflag['pageflag'], message.category) pagecount = (pagecount+stitchedpagedata[docid]["pagecount"])-len(skippages) - + for pageflag in _pageflags: _data = {} if len(pageflag['docpageflags']) > 0: diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index 83a3a835f..b6458990e 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -3900,7 +3900,9 @@ const Redlining = React.forwardRef( let doc = documentViewer.getDocument(); await annotationManager.applyRedactions(); /**must apply redactions before removing pages*/ - await doc.removePages(pagesToRemove); + if (pagesToRemove.length > 0) { + await doc.removePages(pagesToRemove); + } const { PDFNet } = _instance.Core; PDFNet.initialize(); From 49e52459aa79be7e21a1c28ecdc0063ca8f256ae Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Tue, 7 May 2024 15:59:10 -0700 Subject: [PATCH 11/16] Changes to get the layerid based on recent event. --- .../services/dal/documentpageflag.py | 23 +++++++++++++++++++ .../services/dts/redactionsummary.py | 7 +++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/computingservices/DocumentServices/services/dal/documentpageflag.py b/computingservices/DocumentServices/services/dal/documentpageflag.py index 67062bc9a..f492d1038 100644 --- a/computingservices/DocumentServices/services/dal/documentpageflag.py +++ b/computingservices/DocumentServices/services/dal/documentpageflag.py @@ -214,3 +214,26 @@ def getdeletedpages(cls, ministryrequestid, docids): finally: if conn is not None: conn.close() + + @classmethod + def getrecentredactionlayerid(cls, ministryrequestid): + conn = getdbconnection() + layerid = 1 + try: + cursor = conn.cursor() + query = ''' + select redactionlayerid + from "DocumentPageflags" + where foiministryrequestid = %s::integer + order by created_at desc limit 1; + ''' + cursor.execute(query, (ministryrequestid,)) + layerid = cursor.fetchone() + return layerid + except Exception as error: + logging.error("Error in getting recentredactionlayerid for requestid") + logging.error(error) + finally: + cursor.close() + if conn is not None: + conn.close() diff --git a/computingservices/DocumentServices/services/dts/redactionsummary.py b/computingservices/DocumentServices/services/dts/redactionsummary.py index fd4afdce6..4459a5c23 100644 --- a/computingservices/DocumentServices/services/dts/redactionsummary.py +++ b/computingservices/DocumentServices/services/dts/redactionsummary.py @@ -20,7 +20,7 @@ def __getrangenumber(self, rangeval): def __packaggesummary(self, message, documentids, pageflags, programareas): try: - redactionlayerid = message.redactionlayerid if message.category != "responsepackage" else 1 + redactionlayerid = self.__getredactionlayerid(message) summarymsg = message.summarydocuments summaryobject = get_in_summary_object(summarymsg) ordereddocids = summaryobject.sorteddocuments @@ -61,6 +61,11 @@ def __packaggesummary(self, message, documentids, pageflags, programareas): except (Exception) as error: print('error occured in redaction dts service: ', error) + def __getredactionlayerid(self, message): + if message.category == "responsepackage": + return documentpageflag().getrecentredactionlayerid(message.ministryrequestid) + return message.redactionlayerid + def __getdeletedpages(self, ministryid, ordereddocids): deletedpages = documentpageflag().getdeletedpages(ministryid, ordereddocids) documentpages = {} From 1a3975ea6848b0ac244dfe0a1297e4c184d46d9e Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Thu, 9 May 2024 15:41:11 -0400 Subject: [PATCH 12/16] NR/Duplicate checkbox after cancel --- web/src/components/FOI/Home/Redlining.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index b731fab88..6808b906b 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -314,10 +314,8 @@ const Redlining = React.forwardRef( } } setIsDisableNRDuplicate(isDisabled); - if (isDisabled) { - setIncludeNRPages(isDisabled) - setIncludeDuplicatePages(isDisabled); - } + setIncludeNRPages(isDisabled) + setIncludeDuplicatePages(isDisabled); } const [enableSavingRedline, setEnableSavingRedline] = useState(false); @@ -3149,8 +3147,7 @@ const Redlining = React.forwardRef( } const cancelSaveRedlineDoc = () => { - setIncludeDuplicatePages(false); - setIncludeNRPages(false); + disableNRDuplicate(); setRedlineModalOpen(false); }; From aa9a5461df614be65e172e164cbf42b8266ade67 Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Fri, 17 May 2024 11:21:03 -0700 Subject: [PATCH 13/16] Changes to close the session. --- api/reviewer_api/models/DocumentPageflagHistory.py | 3 +++ api/reviewer_api/models/Keywords.py | 14 +++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/api/reviewer_api/models/DocumentPageflagHistory.py b/api/reviewer_api/models/DocumentPageflagHistory.py index 04e97ebae..7c7e312ce 100644 --- a/api/reviewer_api/models/DocumentPageflagHistory.py +++ b/api/reviewer_api/models/DocumentPageflagHistory.py @@ -33,7 +33,10 @@ def createpageflag(cls, documentpageflaghistory)->DefaultMethodResult: # no db close or commit because this function is called in a loop try: db.session.add(documentpageflaghistory) + db.session.commit() return DefaultMethodResult(True, 'Page Flag history is saved', documentpageflaghistory.id) except Exception as ex: logging.error(ex) return DefaultMethodResult(False, 'Page Flag history is not saved', documentpageflaghistory.id) + finally: + db.session.close() \ No newline at end of file diff --git a/api/reviewer_api/models/Keywords.py b/api/reviewer_api/models/Keywords.py index 3b88c57e6..f2646a8b3 100644 --- a/api/reviewer_api/models/Keywords.py +++ b/api/reviewer_api/models/Keywords.py @@ -3,7 +3,7 @@ from sqlalchemy import or_ from datetime import datetime as datetime2 from sqlalchemy import or_, and_ - +import logging class Keyword(db.Model): __tablename__ = 'Keywords' # Defining the columns @@ -19,10 +19,14 @@ class Keyword(db.Model): @classmethod def getall(cls): - keyword_schema = KeywordSchema(many=True) - query = db.session.query(Keyword).filter_by(isactive=True).all() - return keyword_schema.dump(query) - + try: + keyword_schema = KeywordSchema(many=True) + query = db.session.query(Keyword).filter_by(isactive=True).all() + return keyword_schema.dump(query) + except Exception as ex: + logging.error(ex) + finally: + db.session.close() class KeywordSchema(ma.Schema): class Meta: From 48d857befa3dd5009b58e5cbd76e0d6012bbaecc Mon Sep 17 00:00:00 2001 From: nkan-aot2 <156717133+nkan-aot2@users.noreply.github.com> Date: Thu, 30 May 2024 10:10:19 -0700 Subject: [PATCH 14/16] fix newRedaction not being cleared after canceling redaction --- web/src/components/FOI/Home/Redlining.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index 18c607020..fff6658b5 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -2270,6 +2270,7 @@ const Redlining = React.forwardRef( } ); } + setNewRedaction(null) } setEditAnnot(null); }; From a9de02d19a731d09d19c859061c62667583f7507 Mon Sep 17 00:00:00 2001 From: Aparna Date: Mon, 10 Jun 2024 13:25:20 -0700 Subject: [PATCH 15/16] FOIMOD-3073 - Fees - Remaining Balance Check Added new table - PDFStitchJobAttributes Updates in notification manager Added new frontend modal before response package download --- api/migrations/versions/9d45ce57481e_.py | 35 ++++ .../models/PDFStitchJobAttributes.py | 66 +++++++ api/reviewer_api/resources/document.py | 7 +- api/reviewer_api/schemas/finalpackage.py | 5 +- api/reviewer_api/services/jobrecordservice.py | 22 +++ api/reviewer_api/services/radactionservice.py | 24 ++- .../services/zippingservice.py | 3 +- .../redlineresponsenotificationmessage.py | 3 +- .../models/zipperproducermessage.py | 3 +- .../services/notificationservice.py | 1 + .../services/docReviewerService.tsx | 2 +- web/src/components/FOI/App.scss | 6 + web/src/components/FOI/Home/Home.js | 8 +- web/src/components/FOI/Home/Redlining.js | 176 ++++++++++++++---- 14 files changed, 315 insertions(+), 46 deletions(-) create mode 100644 api/migrations/versions/9d45ce57481e_.py create mode 100644 api/reviewer_api/models/PDFStitchJobAttributes.py diff --git a/api/migrations/versions/9d45ce57481e_.py b/api/migrations/versions/9d45ce57481e_.py new file mode 100644 index 000000000..25bda2114 --- /dev/null +++ b/api/migrations/versions/9d45ce57481e_.py @@ -0,0 +1,35 @@ +"""empty message + +Revision ID: 9d45ce57481e +Revises: 18a45d1b33cc +Create Date: 2024-06-06 10:19:45.739225 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '9d45ce57481e' +down_revision = '18a45d1b33cc' +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table('PDFStitchJobAttributes', + sa.Column('attributesid', sa.Integer(), autoincrement=True, nullable=False), + sa.Column('pdfstitchjobid', sa.Integer(), primary_key=True, autoincrement=True, nullable=False), + sa.Column('version', sa.Integer(), nullable=False), + sa.Column('ministryrequestid', sa.Integer(), nullable=False), + sa.Column('attributes', postgresql.JSON(astext_type=sa.Text()), nullable=False), + sa.Column('createdat', sa.TIMESTAMP, nullable=False, server_default=sa.func.now()), + sa.Column('createdby', sa.String(length=120), nullable=True), + sa.PrimaryKeyConstraint('attributesid'), + sa.ForeignKeyConstraint(['pdfstitchjobid', 'version'], ['PDFStitchJob.pdfstitchjobid', 'PDFStitchJob.version'], ) + ) + + +def downgrade(): + op.drop_table('PDFStitchJobAttributes') + diff --git a/api/reviewer_api/models/PDFStitchJobAttributes.py b/api/reviewer_api/models/PDFStitchJobAttributes.py new file mode 100644 index 000000000..899a7199a --- /dev/null +++ b/api/reviewer_api/models/PDFStitchJobAttributes.py @@ -0,0 +1,66 @@ +from .db import db, ma +from datetime import datetime as datetime2 +from sqlalchemy.dialects.postgresql import JSON +from sqlalchemy import func, and_ +from .default_method_result import DefaultMethodResult +from .DocumentDeleted import DocumentDeleted +from .DocumentMaster import DocumentMaster +import logging + + +class PDFStitchJobAttributes(db.Model): + __tablename__ = "PDFStitchJobAttributes" + # Defining the columns + attributesid = db.Column(db.Integer, primary_key=True, autoincrement=True) + pdfstitchjobid = db.Column(db.Integer, db.ForeignKey("PDFStitchJob.pdfstitchjobid")) + version = db.Column(db.Integer, db.ForeignKey("PDFStitchJob.version")) + ministryrequestid = db.Column(db.Integer, nullable=False) + attributes = db.Column(JSON, unique=False, nullable=False) + createdat = db.Column(db.DateTime, default=datetime2.now, nullable=False) + createdby = db.Column(db.String(120), nullable=False) + + + @classmethod + def insert(cls, row): + try: + db.session.add(row) + db.session.commit() + return DefaultMethodResult( + True, + "PDF Stitch Job Attributes recorded for ministryrequestid: {0}".format( + row.ministryrequestid + ), + row.pdfstitchjobid, + ) + except Exception as ex: + logging.error(ex) + finally: + db.session.close() + + @classmethod + def getpdfstitchjobattributesbyid(cls, requestid): + try: + pdfstitchjobattributesschema = PDFStitchJobAttributesSchema(many=False) + query = db.session.query(PDFStitchJobAttributes).filter( + PDFStitchJobAttributes.ministryrequestid == requestid + ).first() + return pdfstitchjobattributesschema.dump(query) + except Exception as ex: + logging.error(ex) + finally: + db.session.close() + + + + +class PDFStitchJobAttributesSchema(ma.Schema): + class Meta: + fields = ( + "attributesid", + "pdfstitchjobid", + "version", + "ministryrequestid", + "attributes", + "createdat", + "createdby", + ) diff --git a/api/reviewer_api/resources/document.py b/api/reviewer_api/resources/document.py index cbed4e54c..596204759 100644 --- a/api/reviewer_api/resources/document.py +++ b/api/reviewer_api/resources/document.py @@ -29,6 +29,7 @@ from reviewer_api.services.documentservice import documentservice from reviewer_api.services.docdeletedpageservice import docdeletedpageservice +from reviewer_api.services.jobrecordservice import jobrecordservice API = Namespace('Document Services', description='Endpoints for deleting and replacing documents') TRACER = Tracer.get_instance() @@ -99,13 +100,15 @@ def get(requestid): response.raise_for_status() # get request status jsonobj = response.json() + balancefeeoverrodforrequest = jobrecordservice().isbalancefeeoverrodforrequest(requestid) requestinfo = { "bcgovcode": jsonobj["bcgovcode"], "requesttype": jsonobj["requestType"], "validoipcreviewlayer": documentservice().validate_oipcreviewlayer(jsonobj, requestid), + "balancefeeoverrodforrequest": balancefeeoverrodforrequest } - result = documentservice().getdocuments(requestid, requestinfo["bcgovcode"]) - return json.dumps({"requeststatuslabel": jsonobj["requeststatuslabel"], "documents": result, "requestnumber":jsonobj["axisRequestId"], "requestinfo":requestinfo}), 200 + documentdivisionslist,result = documentservice().getdocuments(requestid, requestinfo["bcgovcode"]) + return json.dumps({"requeststatuslabel": "", "documents": result, "requestnumber":"", "requestinfo":requestinfo,"documentdivisions":documentdivisionslist}), 200 except KeyError as error: return {'status': False, 'message': CUSTOM_KEYERROR_MESSAGE + str(error)}, 400 except BusinessException as exception: diff --git a/api/reviewer_api/schemas/finalpackage.py b/api/reviewer_api/schemas/finalpackage.py index 702aeb858..751fcaded 100644 --- a/api/reviewer_api/schemas/finalpackage.py +++ b/api/reviewer_api/schemas/finalpackage.py @@ -9,6 +9,8 @@ class FileSchema(Schema): class AttributeSchema(Schema): files = fields.Nested(FileSchema, many=True, required=True, allow_none=False) +class FeeOverrideSchema(Schema): + feeoverridereason = fields.Str(data_key="feeoverridereason", allow_none=True) class SummaryPkgSchema(Schema): divisionid = fields.Int(data_key="divisionid", allow_none=True) @@ -27,4 +29,5 @@ class FinalPackageSchema(Schema): AttributeSchema, many=True, required=True, allow_none=False ) summarydocuments = fields.Nested(SummarySchema, allow_none=True) - redactionlayerid = fields.Int(data_key="redactionlayerid", allow_none=False) \ No newline at end of file + redactionlayerid = fields.Int(data_key="redactionlayerid", allow_none=False) + pdfstitchjobattributes = fields.Nested(FeeOverrideSchema, allow_none=True, many=False) \ No newline at end of file diff --git a/api/reviewer_api/services/jobrecordservice.py b/api/reviewer_api/services/jobrecordservice.py index 587c94bc4..863a1e03b 100644 --- a/api/reviewer_api/services/jobrecordservice.py +++ b/api/reviewer_api/services/jobrecordservice.py @@ -6,6 +6,7 @@ from reviewer_api.models.DocumentAttributes import DocumentAttributes from reviewer_api.services.annotationservice import annotationservice from reviewer_api.services.documentpageflagservice import documentpageflagservice +from reviewer_api.models.PDFStitchJobAttributes import PDFStitchJobAttributes from reviewer_api.auth import auth, AuthHelper from datetime import datetime as datetime2 from reviewer_api.utils.constants import FILE_CONVERSION_FILE_TYPES, DEDUPE_FILE_TYPES @@ -129,3 +130,24 @@ def insertpagecalculatorjobstatus(self, message, userid): ) job = PageCalculatorJob.insert(row) return job + + def insertfeeoverridereason(self, message, pdfstitchjobid, userid): + row = PDFStitchJobAttributes( + pdfstitchjobid=pdfstitchjobid, + version=1, + ministryrequestid=message['ministryrequestid'], + attributes=message['pdfstitchjobattributes'], + createdby=userid + ) + job = PDFStitchJobAttributes.insert(row) + return job + + def __getpdfstitchjobattributesbyid(self, requestid): + job = PDFStitchJobAttributes().getpdfstitchjobattributesbyid(requestid) + return job + + def isbalancefeeoverrodforrequest(self, requestid): + pdfstitchjobattributes= self.__getpdfstitchjobattributesbyid(requestid) + isbalancefeeoverrode= False if pdfstitchjobattributes is None or not pdfstitchjobattributes else True + #print("\nisbalancefeeoverrode:",isbalancefeeoverrode) + return isbalancefeeoverrode diff --git a/api/reviewer_api/services/radactionservice.py b/api/reviewer_api/services/radactionservice.py index 80468ab66..27a3b9844 100644 --- a/api/reviewer_api/services/radactionservice.py +++ b/api/reviewer_api/services/radactionservice.py @@ -122,7 +122,16 @@ def triggerdownloadredlinefinalpackage(self, finalpackageschema, userinfo): job = jobrecordservice().insertpdfstitchjobstatus( _jobmessage, userinfo["userid"] ) + print("job:: ",job.message) + print("job-2:: ",job.identifier) if job.success: + if finalpackageschema['pdfstitchjobattributes'] is not None: + feeoverridereason= finalpackageschema['pdfstitchjobattributes']['feeoverridereason'] + print("feeoverridereason:",feeoverridereason) + if feeoverridereason is not None and feeoverridereason != '': + feeoverridereasonresult= jobrecordservice().insertfeeoverridereason(finalpackageschema,job.identifier,userinfo["userid"]) + #print("feeoverridereasonresult:",feeoverridereasonresult) + #Add here the reason- comment text and a boolean _message = self.__preparemessageforsummaryservice( finalpackageschema, userinfo, job ) @@ -130,6 +139,17 @@ def triggerdownloadredlinefinalpackage(self, finalpackageschema, userinfo): # redline/final package download: prepare message for zipping service def __preparemessageforsummaryservice(self, messageschema, userinfo, job): + pdf_stitch_job_attributes = to_json(messageschema['pdfstitchjobattributes']) + print("pdf_stitch_job_attributes:",pdf_stitch_job_attributes) + if pdf_stitch_job_attributes is not None: + feeoverridereason= json.loads(pdf_stitch_job_attributes).get("feeoverridereason", None) + if feeoverridereason is not None and feeoverridereason != '': + feeoverridereason= userinfo["firstname"]+" "+userinfo["lastname"]+" overrode balance outstanding warning for the following reason: "+feeoverridereason + print("feeoverridereason:",feeoverridereason) + else: + feeoverridereason= "" + else: + feeoverridereason= "" _message = { "jobid": job.identifier, "requestid": -1, @@ -144,8 +164,10 @@ def __preparemessageforsummaryservice(self, messageschema, userinfo, job): "finaloutput": to_json(""), "attributes": to_json(messageschema["attributes"]), "summarydocuments": json.dumps(messageschema["summarydocuments"]), - "redactionlayerid": json.dumps(messageschema["redactionlayerid"]) + "redactionlayerid": json.dumps(messageschema["redactionlayerid"]), + "feeoverridereason":feeoverridereason } + print("_message:",_message) return _message # redline/final package download: prepare message for zipping service diff --git a/computingservices/DocumentServices/services/zippingservice.py b/computingservices/DocumentServices/services/zippingservice.py index c997af363..1ec9282c0 100644 --- a/computingservices/DocumentServices/services/zippingservice.py +++ b/computingservices/DocumentServices/services/zippingservice.py @@ -18,7 +18,8 @@ def preparemessageforzipperservice(self,summaryfiles, message): print('filestozip_list: ', filestozip_list) msgjson['filestozip'] = self.to_json(filestozip_list) msgjson['attributes'] = self.to_json(msgjson['attributes']) - msgjson['summarydocuments'] = self.to_json(msgjson['summarydocuments']) + msgjson['summarydocuments'] = self.to_json(msgjson['summarydocuments']) + return msgjson except (Exception) as error: print('error occured in zipping service: ', error) diff --git a/computingservices/ZippingServices/models/redlineresponsenotificationmessage.py b/computingservices/ZippingServices/models/redlineresponsenotificationmessage.py index 5028e8783..ccb851933 100644 --- a/computingservices/ZippingServices/models/redlineresponsenotificationmessage.py +++ b/computingservices/ZippingServices/models/redlineresponsenotificationmessage.py @@ -1,6 +1,7 @@ class redlineresponsenotificationmessage(object): - def __init__(self, ministryrequestid, serviceid, errorflag, createdby) -> None: + def __init__(self, ministryrequestid, serviceid, errorflag, createdby,feeoverridereason) -> None: self.ministryrequestid = ministryrequestid self.serviceid = serviceid self.errorflag = errorflag self.createdby = createdby + self.feeoverridereason=feeoverridereason diff --git a/computingservices/ZippingServices/models/zipperproducermessage.py b/computingservices/ZippingServices/models/zipperproducermessage.py index deee421e1..73b4b795c 100644 --- a/computingservices/ZippingServices/models/zipperproducermessage.py +++ b/computingservices/ZippingServices/models/zipperproducermessage.py @@ -1,5 +1,5 @@ class zipperproducermessage(object): - def __init__(self,jobid,requestid,category,requestnumber,bcgovcode,createdby,ministryrequestid,filestozip,finaloutput,attributes,summarydocuments=None,redactionlayerid=None,foldername=None) -> None: + def __init__(self,jobid,requestid,category,requestnumber,bcgovcode,createdby,ministryrequestid,filestozip,finaloutput,attributes,feeoverridereason,summarydocuments=None,redactionlayerid=None,foldername=None) -> None: self.jobid = jobid self.requestid = requestid self.category=category @@ -13,3 +13,4 @@ def __init__(self,jobid,requestid,category,requestnumber,bcgovcode,createdby,min self.foldername = foldername self.summarydocuments = summarydocuments self.redactionlayerid = redactionlayerid + self.feeoverridereason= feeoverridereason \ No newline at end of file diff --git a/computingservices/ZippingServices/services/notificationservice.py b/computingservices/ZippingServices/services/notificationservice.py index f237393f9..5fc5f1c5c 100644 --- a/computingservices/ZippingServices/services/notificationservice.py +++ b/computingservices/ZippingServices/services/notificationservice.py @@ -44,6 +44,7 @@ def __responsepackagepublishtostream(self, message, error=False): serviceid="pdfstitchforresponsepackage", createdby=message.createdby, errorflag=self.__booltostr(error), + feeoverridereason= message.feeoverridereason ) logging.info( diff --git a/web/src/apiManager/services/docReviewerService.tsx b/web/src/apiManager/services/docReviewerService.tsx index 90758eb1e..4cdf3215b 100644 --- a/web/src/apiManager/services/docReviewerService.tsx +++ b/web/src/apiManager/services/docReviewerService.tsx @@ -34,7 +34,7 @@ export const fetchDocuments = ( store.dispatch(setRequestNumber(res.data.requestnumber) as any); store.dispatch(setRequestStatus(res.data.requeststatuslabel) as any); store.dispatch(setRequestInfo(res.data.requestinfo) as any); - callback(res.data.documents); + callback(res.data); } else { throw new Error(); } diff --git a/web/src/components/FOI/App.scss b/web/src/components/FOI/App.scss index f518f21da..a67a0dafb 100644 --- a/web/src/components/FOI/App.scss +++ b/web/src/components/FOI/App.scss @@ -144,6 +144,12 @@ li.modal-message-list-item { height: calc(100% - 198px); } +.modal-content{ + padding: 20px 30px !important; + overflow-y: visible !important; + height: calc(100% - 198px); +} + .section-list{ >li:nth-child(odd) { background-color: #E5EAEF; diff --git a/web/src/components/FOI/Home/Home.js b/web/src/components/FOI/Home/Home.js index 7f9e53500..bfe6697cb 100644 --- a/web/src/components/FOI/Home/Home.js +++ b/web/src/components/FOI/Home/Home.js @@ -43,6 +43,7 @@ function Home() { const [pageMappedDocs, setPageMappedDocs] = useState([]); const [isStitchingLoaded, setIsStitchingLoaded] = useState(false); const [warningModalOpen, setWarningModalOpen] = useState(false); + const [isBalanceFeeOverrode , setIsBalanceFeeOverrode] = useState(false); const redliningRef = useRef(); const selectorRef = useRef(); @@ -66,7 +67,7 @@ function Home() { fetchDocuments( parseInt(foiministryrequestid), async (data) => { - + setIsBalanceFeeOverrode(data.requestinfo.balancefeeoverrodforrequest) const getFileExt = (filepath) => { const parts = filepath.split(".") const fileExt = parts.pop() @@ -75,7 +76,7 @@ function Home() { // New code added to get the incompatable files for download redline // data has all the files including incompatable ones // _files has all files except incompatable ones - const _incompatableFiles = data.filter( + const _incompatableFiles = data.documents.filter( (d) => { const isPdfFile = getFileExt(d.filepath) === "pdf" if (isPdfFile) { @@ -86,7 +87,7 @@ function Home() { } ); setIncompatibleFiles(_incompatableFiles); - const _files = data.filter((d) => { + const _files = data.documents.filter((d) => { const isPdfFile = getFileExt(d.filepath) === "pdf" const isCompatible = !d.attributes.incompatible || isPdfFile return isCompatible @@ -276,6 +277,7 @@ function Home() { incompatibleFiles={incompatibleFiles} setWarningModalOpen={setWarningModalOpen} scrollLeftPanel={scrollLeftPanel} + isBalanceFeeOverrode={isBalanceFeeOverrode} /> ) // :
Loading
diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index fff6658b5..3fa98cb00 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -96,7 +96,8 @@ const Redlining = React.forwardRef( isStitchingLoaded, licenseKey, setWarningModalOpen, - scrollLeftPanel + scrollLeftPanel, + isBalanceFeeOverrode }, ref ) => { @@ -192,6 +193,10 @@ const Redlining = React.forwardRef( const [enableRedactionPanel, setEnableRedactionPanel] = useState(false); const [clickRedactionPanel, setClickRedactionPanel] = useState(false); + const [outstandingBalanceModal, setOutstandingBalanceModal] = useState(false); + const [outstandingBalance, setOutstandingBalance]= useState(1) + const [isOverride, setIsOverride]= useState(false); + const [feeOverrideReason, setFeeOverrideReason]= useState(""); //xml parser const parser = new XMLParser(); @@ -447,32 +452,44 @@ const Redlining = React.forwardRef( finalPackageBtn.disabled = !enableSavingFinal; finalPackageBtn.onclick = () => { - // Download - setModalFor("responsepackage"); - setModalTitle("Create Package for Applicant"); - setModalMessage([ - "This should only be done when all redactions are finalized and ready to ", - - be - , - " sent to the ", - - Applicant - , - ". This will ", - - permanently - , - " apply the redactions and automatically create page stamps.", -
, -
, - - When you create the response package, your web browser page - will automatically refresh - , - ]); - setModalButtonLabel("Create Applicant Package"); - setRedlineModalOpen(true); + if(outstandingBalance > 0 && !isBalanceFeeOverrode){ + setModalFor("responsepackage"); + setModalTitle("Create Package for Applicant"); + setModalMessage([ + "There is an outstanding balance of fees, please cancel to resolve, or click override to proceed", + ]); + setModalButtonLabel("Override"); + setOutstandingBalanceModal(true); + setIsOverride(false) + } + else{ + // Download + setModalFor("responsepackage"); + setModalTitle("Create Package for Applicant"); + setModalMessage([ + "This should only be done when all redactions are finalized and ready to ", + + be + , + " sent to the ", + + Applicant + , + ". This will ", + + permanently + , + " apply the redactions and automatically create page stamps.", +
, +
, + + When you create the response package, your web browser page + will automatically refresh + , + ]); + setModalButtonLabel("Create Applicant Package"); + setRedlineModalOpen(true); + } }; menu.appendChild(finalPackageBtn); @@ -490,6 +507,7 @@ const Redlining = React.forwardRef( parent.appendChild(menu); menuBtn.onclick = async () => { + console.log("Menu button clicked"); if (menu.style.display == "flex") { menu.style.display = "none"; } else { @@ -2252,8 +2270,14 @@ const Redlining = React.forwardRef( }, [deleteQueue, newRedaction]); const cancelRedaction = () => { - setModalOpen(false); - setMessageModalOpen(false); + if(outstandingBalance > 0 && !isBalanceFeeOverrode){ + setIsOverride(false) + setOutstandingBalanceModal(false) + } + else{ + setModalOpen(false); + setMessageModalOpen(false); + } setSelectedPageFlagId(null); setSelectedSections([]); setSaveDisabled(true); @@ -3149,10 +3173,18 @@ const Redlining = React.forwardRef( const cancelSaveRedlineDoc = () => { disableNRDuplicate(); - setRedlineModalOpen(false); + if(outstandingBalance > 0 && !isBalanceFeeOverrode){ + setOutstandingBalanceModal(false) + setIsOverride(false) + } + else + setRedlineModalOpen(false); }; const saveDoc = () => { + console.log("Inside saveDoc!") + setIsOverride(false) + setOutstandingBalanceModal(false) setRedlineModalOpen(false); setRedlineSaving(true); setRedlineCategory(modalFor); @@ -3166,7 +3198,8 @@ const Redlining = React.forwardRef( saveRedlineDocument(docInstance, modalFor); break; case "responsepackage": - saveResponsePackage(docViewer, annotManager, docInstance); + console.log("Inside responsepackage -- ", feeOverrideReason) + saveResponsePackage(docViewer, annotManager, docInstance,feeOverrideReason); break; default: } @@ -3896,7 +3929,8 @@ const Redlining = React.forwardRef( requestnumber: "", bcgovcode: "", summarydocuments : prepareresponseredlinesummarylist(documentList), - redactionlayerid: currentLayer.redactionlayerid + redactionlayerid: currentLayer.redactionlayerid, + pdfstitchjobattributes:{"feeoverridereason":""} }; getResponsePackagePreSignedUrl( requestid, @@ -3905,6 +3939,7 @@ const Redlining = React.forwardRef( const toastID = toast.loading("Start generating final package..."); zipServiceMessage.requestnumber = res.requestnumber; zipServiceMessage.bcgovcode = res.bcgovcode; + zipServiceMessage.pdfstitchjobattributes= {"feeoverridereason":feeOverrideReason} let annotList = annotationManager.getAnnotationsList(); annotManager.ungroupAnnotations(annotList); /** remove duplicate and not responsive pages */ @@ -3997,9 +4032,9 @@ const Redlining = React.forwardRef( res.s3path_save, zipServiceMessage ); - setTimeout(() => { - window.location.reload(true); - }, 3000); + // setTimeout(() => { + // window.location.reload(true); + // }, 3000); }, (_err) => { console.log(_err); @@ -4114,6 +4149,20 @@ const Redlining = React.forwardRef( setIncludeDuplicatePages(e.target.checked); } + const overrideOutstandingBalance = () => { + setIsOverride(true) + } + + // const saveOverrideReason = () => { + // console.log("Saved override reason!",feeOverrideReason) + // saveDoc("responsepackage") + // setIsOverride(false) + // setOutstandingBalanceModal(false) + // } + + const handleOverrideReasonChange = (event) => { + setFeeOverrideReason(event.target.value); + }; return ( @@ -4329,6 +4378,63 @@ const Redlining = React.forwardRef( + + +

{modalTitle}

+ + Close + + +
+ + + + {modalMessage} + {isOverride && <> +

+ + + } +
+
+
+ + {!isOverride && + + } + {isOverride && + + } + + +
); } From e9dbd91979919a2ce43fdebd51444533868a6f7c Mon Sep 17 00:00:00 2001 From: Aparna Date: Mon, 10 Jun 2024 15:31:24 -0700 Subject: [PATCH 16/16] Removed debug codes and updated changes from code review --- api/reviewer_api/services/jobrecordservice.py | 7 +------ api/reviewer_api/services/radactionservice.py | 20 +++++-------------- web/src/components/FOI/Home/Redlining.js | 16 +++------------ 3 files changed, 9 insertions(+), 34 deletions(-) diff --git a/api/reviewer_api/services/jobrecordservice.py b/api/reviewer_api/services/jobrecordservice.py index 863a1e03b..09a74039e 100644 --- a/api/reviewer_api/services/jobrecordservice.py +++ b/api/reviewer_api/services/jobrecordservice.py @@ -141,13 +141,8 @@ def insertfeeoverridereason(self, message, pdfstitchjobid, userid): ) job = PDFStitchJobAttributes.insert(row) return job - - def __getpdfstitchjobattributesbyid(self, requestid): - job = PDFStitchJobAttributes().getpdfstitchjobattributesbyid(requestid) - return job def isbalancefeeoverrodforrequest(self, requestid): - pdfstitchjobattributes= self.__getpdfstitchjobattributesbyid(requestid) + pdfstitchjobattributes= PDFStitchJobAttributes().getpdfstitchjobattributesbyid(requestid) isbalancefeeoverrode= False if pdfstitchjobattributes is None or not pdfstitchjobattributes else True - #print("\nisbalancefeeoverrode:",isbalancefeeoverrode) return isbalancefeeoverrode diff --git a/api/reviewer_api/services/radactionservice.py b/api/reviewer_api/services/radactionservice.py index 27a3b9844..570145bfa 100644 --- a/api/reviewer_api/services/radactionservice.py +++ b/api/reviewer_api/services/radactionservice.py @@ -122,16 +122,12 @@ def triggerdownloadredlinefinalpackage(self, finalpackageschema, userinfo): job = jobrecordservice().insertpdfstitchjobstatus( _jobmessage, userinfo["userid"] ) - print("job:: ",job.message) - print("job-2:: ",job.identifier) if job.success: if finalpackageschema['pdfstitchjobattributes'] is not None: - feeoverridereason= finalpackageschema['pdfstitchjobattributes']['feeoverridereason'] - print("feeoverridereason:",feeoverridereason) - if feeoverridereason is not None and feeoverridereason != '': - feeoverridereasonresult= jobrecordservice().insertfeeoverridereason(finalpackageschema,job.identifier,userinfo["userid"]) - #print("feeoverridereasonresult:",feeoverridereasonresult) - #Add here the reason- comment text and a boolean + if 'feeoverridereason' in finalpackageschema['pdfstitchjobattributes']: + feeoverridereason= finalpackageschema['pdfstitchjobattributes']['feeoverridereason'] + if feeoverridereason is not None and feeoverridereason != '': + jobrecordservice().insertfeeoverridereason(finalpackageschema,job.identifier,userinfo["userid"]) _message = self.__preparemessageforsummaryservice( finalpackageschema, userinfo, job ) @@ -139,17 +135,12 @@ def triggerdownloadredlinefinalpackage(self, finalpackageschema, userinfo): # redline/final package download: prepare message for zipping service def __preparemessageforsummaryservice(self, messageschema, userinfo, job): + feeoverridereason= None pdf_stitch_job_attributes = to_json(messageschema['pdfstitchjobattributes']) - print("pdf_stitch_job_attributes:",pdf_stitch_job_attributes) if pdf_stitch_job_attributes is not None: feeoverridereason= json.loads(pdf_stitch_job_attributes).get("feeoverridereason", None) if feeoverridereason is not None and feeoverridereason != '': feeoverridereason= userinfo["firstname"]+" "+userinfo["lastname"]+" overrode balance outstanding warning for the following reason: "+feeoverridereason - print("feeoverridereason:",feeoverridereason) - else: - feeoverridereason= "" - else: - feeoverridereason= "" _message = { "jobid": job.identifier, "requestid": -1, @@ -167,7 +158,6 @@ def __preparemessageforsummaryservice(self, messageschema, userinfo, job): "redactionlayerid": json.dumps(messageschema["redactionlayerid"]), "feeoverridereason":feeoverridereason } - print("_message:",_message) return _message # redline/final package download: prepare message for zipping service diff --git a/web/src/components/FOI/Home/Redlining.js b/web/src/components/FOI/Home/Redlining.js index 3fa98cb00..babf9df43 100644 --- a/web/src/components/FOI/Home/Redlining.js +++ b/web/src/components/FOI/Home/Redlining.js @@ -507,7 +507,6 @@ const Redlining = React.forwardRef( parent.appendChild(menu); menuBtn.onclick = async () => { - console.log("Menu button clicked"); if (menu.style.display == "flex") { menu.style.display = "none"; } else { @@ -3182,7 +3181,6 @@ const Redlining = React.forwardRef( }; const saveDoc = () => { - console.log("Inside saveDoc!") setIsOverride(false) setOutstandingBalanceModal(false) setRedlineModalOpen(false); @@ -3198,7 +3196,6 @@ const Redlining = React.forwardRef( saveRedlineDocument(docInstance, modalFor); break; case "responsepackage": - console.log("Inside responsepackage -- ", feeOverrideReason) saveResponsePackage(docViewer, annotManager, docInstance,feeOverrideReason); break; default: @@ -4032,9 +4029,9 @@ const Redlining = React.forwardRef( res.s3path_save, zipServiceMessage ); - // setTimeout(() => { - // window.location.reload(true); - // }, 3000); + setTimeout(() => { + window.location.reload(true); + }, 3000); }, (_err) => { console.log(_err); @@ -4153,13 +4150,6 @@ const Redlining = React.forwardRef( setIsOverride(true) } - // const saveOverrideReason = () => { - // console.log("Saved override reason!",feeOverrideReason) - // saveDoc("responsepackage") - // setIsOverride(false) - // setOutstandingBalanceModal(false) - // } - const handleOverrideReasonChange = (event) => { setFeeOverrideReason(event.target.value); };