From f022d659347f13a80a15f74c2ce3e5962a6cc3c8 Mon Sep 17 00:00:00 2001 From: Milos Despotovic Date: Mon, 15 Jan 2024 11:28:51 -0800 Subject: [PATCH 1/6] Update replaceattachmenet message --- .../FOI/customComponents/Attachments/AttachmentModal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forms-flow-web/src/components/FOI/customComponents/Attachments/AttachmentModal.js b/forms-flow-web/src/components/FOI/customComponents/Attachments/AttachmentModal.js index 5ac12bd45..b250306fd 100644 --- a/forms-flow-web/src/components/FOI/customComponents/Attachments/AttachmentModal.js +++ b/forms-flow-web/src/components/FOI/customComponents/Attachments/AttachmentModal.js @@ -323,8 +323,8 @@ export default function AttachmentModal({ body: ( <> Replace the existing record with a reformatted or updated - version of the same record.

The original file that was - uploaded will still be available for download. + version of the same record.

If the file being replaced + is also a pdf file, the replaced file will no longer be available. ), }; From 1648013ed5058154834605fa9ca3a0e4b86e1a73 Mon Sep 17 00:00:00 2001 From: Milos Despotovic Date: Mon, 15 Jan 2024 12:19:19 -0800 Subject: [PATCH 2/6] Handle .pdf mimetype --- .../components/FOI/customComponents/FileUpload/util.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/forms-flow-web/src/components/FOI/customComponents/FileUpload/util.js b/forms-flow-web/src/components/FOI/customComponents/FileUpload/util.js index dbc2c3831..026508ccd 100644 --- a/forms-flow-web/src/components/FOI/customComponents/FileUpload/util.js +++ b/forms-flow-web/src/components/FOI/customComponents/FileUpload/util.js @@ -35,8 +35,16 @@ export const getErrorMessage = (_duplicateFiles, _typeErrorFiles, _overSizedFile if (_overSizedFiles.length > 0) { _errorMessage.push(<>The specified file(s) {_overSizedFiles.join(", ")} could not be uploaded. Only files {maxFileSize}MB or under can be uploaded.); } + const hasOnlyPdfMimeTypes = (mimeTypes) => { + let result = true; + mimeTypes.forEach((mimeType) => { + if (mimeType !== 'application/pdf' && mimeType !== '.pdf') result = false; + }) + return result; + } + if (_typeErrorFiles.length > 0) { - if (mimeTypes.length === 1 && mimeTypes[0] === 'application/pdf') { + if (hasOnlyPdfMimeTypes(mimeTypes)) { _errorMessage.push(<>The specified file(s) {_typeErrorFiles.join(", ")} could not be uploaded. Only PDF filetypes are allowed.); } else { _errorMessage.push(<>The specified file(s) {_typeErrorFiles.join(", ")} could not be uploaded. Only files with the following extensions are allowed: {multipleFiles ? 'Excel (xls, xlsx, macro), pdf, image, word, email' : singleFileUploadAllowedFileExtensions}); From bf01db2d07fef40487a5aba11683007465bfe143 Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Mon, 15 Jan 2024 12:33:08 -0800 Subject: [PATCH 3/6] 4929 (Bug fix) Changes to validate user group (before open) --- request-management-api/request_api/models/FOIRawRequests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/request-management-api/request_api/models/FOIRawRequests.py b/request-management-api/request_api/models/FOIRawRequests.py index 7a244d0c8..8d5d4d0c9 100644 --- a/request-management-api/request_api/models/FOIRawRequests.py +++ b/request-management-api/request_api/models/FOIRawRequests.py @@ -629,7 +629,7 @@ def addadditionalfilter(cls, basequery, additionalfilter=None, userid=None, isia return basequery.filter( and_( FOIRawRequest.status.notin_(['Archived']), - or_(and_(FOIRawRequest.isiaorestricted == False, FOIRawRequest.assignedgroup.in_(ProcessingTeamWithKeycloackGroup.list())), and_(FOIRawRequest.isiaorestricted == True, FOIRawRequest.assignedto == userid)))) + or_(and_(FOIRawRequest.isiaorestricted == False, FOIRawRequest.assignedgroup.in_(ProcessingTeamWithKeycloackGroup.list()), FOIRawRequest.assignedgroup.in_(tuple(groups))), and_(FOIRawRequest.isiaorestricted == True, FOIRawRequest.assignedto == userid)))) return basequery.filter( and_( FOIRawRequest.status.notin_(['Archived']), From e070abbb6a510c1d82382dc9fe5c56b6e6118287 Mon Sep 17 00:00:00 2001 From: sumathi-thirumani-aot <57740789+sumathi-thirumani-aot@users.noreply.github.com> Date: Tue, 16 Jan 2024 09:44:16 -0800 Subject: [PATCH 4/6] Revert "4929 (Bug fix) Changes to validate user group (before open)" --- request-management-api/request_api/models/FOIRawRequests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/request-management-api/request_api/models/FOIRawRequests.py b/request-management-api/request_api/models/FOIRawRequests.py index 8d5d4d0c9..7a244d0c8 100644 --- a/request-management-api/request_api/models/FOIRawRequests.py +++ b/request-management-api/request_api/models/FOIRawRequests.py @@ -629,7 +629,7 @@ def addadditionalfilter(cls, basequery, additionalfilter=None, userid=None, isia return basequery.filter( and_( FOIRawRequest.status.notin_(['Archived']), - or_(and_(FOIRawRequest.isiaorestricted == False, FOIRawRequest.assignedgroup.in_(ProcessingTeamWithKeycloackGroup.list()), FOIRawRequest.assignedgroup.in_(tuple(groups))), and_(FOIRawRequest.isiaorestricted == True, FOIRawRequest.assignedto == userid)))) + or_(and_(FOIRawRequest.isiaorestricted == False, FOIRawRequest.assignedgroup.in_(ProcessingTeamWithKeycloackGroup.list())), and_(FOIRawRequest.isiaorestricted == True, FOIRawRequest.assignedto == userid)))) return basequery.filter( and_( FOIRawRequest.status.notin_(['Archived']), From b028f3488df861766b90931af6b39f86c0d54d33 Mon Sep 17 00:00:00 2001 From: "sumathi.thirumani" Date: Thu, 18 Jan 2024 14:46:30 -0800 Subject: [PATCH 5/6] Sync from dev. --- request-management-api/request_api/services/events/oipc.py | 6 ++++-- request-management-api/request_api/services/eventservice.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/request-management-api/request_api/services/events/oipc.py b/request-management-api/request_api/services/events/oipc.py index a440a1104..df3305dec 100644 --- a/request-management-api/request_api/services/events/oipc.py +++ b/request-management-api/request_api/services/events/oipc.py @@ -18,11 +18,13 @@ class oipcevent: """ FOI OIPC Event management service """ - def createoipcevent(self, requestid, userid): + def createoipcevent(self, requestid, requesttype, userid): + if requesttype != "ministryrequest": + return DefaultMethodResult(True,'No change',requestid) ministryrequest = FOIMinistryRequest.getmetadata(requestid) if ministryrequest["isoipcreview"] in (None, False): notificationservice().dismissnotifications_by_requestid_type(requestid, "ministryrequest", self.__notificationtype()) - return DefaultMethodResult(True,'No change',requestid) + return DefaultMethodResult(True,'Dismiss OIPC events',requestid) inquiryoutcomes = oipcservice().getinquiryoutcomes() version = ministryrequest["version"] curoipcs = FOIRequestOIPC.getoipc(requestid, version) diff --git a/request-management-api/request_api/services/eventservice.py b/request-management-api/request_api/services/eventservice.py index 614cd4351..96ba48dcc 100644 --- a/request-management-api/request_api/services/eventservice.py +++ b/request-management-api/request_api/services/eventservice.py @@ -36,7 +36,7 @@ def posteventsync(self, requestid, requesttype, userid, username, isministryuser stateeventresponse = stateevent().createstatetransitionevent(requestid, requesttype, userid, username) divisioneventresponse = divisionevent().createdivisionevent(requestid, requesttype, userid) assignmentresponse = assignmentevent().createassignmentevent(requestid, requesttype, userid, isministryuser,assigneename,username) - oipcresponse = oipcevent().createoipcevent(requestid, userid) + oipcresponse = oipcevent().createoipcevent(requestid, requesttype, userid) if stateeventresponse.success == False or divisioneventresponse.success == False or assignmentresponse.success == False or oipcresponse.success == False: current_app.logger.error("FOI Notification failed for event for request= %s ; state response=%s ; division response=%s ; assignment response=%s ; oipc response=%s" % (requestid, stateeventresponse.message, divisioneventresponse.message, assignmentresponse.message, oipcresponse.message)) except BusinessException as exception: From c923a955ad3615aa645e2df5c350db2add82ac40 Mon Sep 17 00:00:00 2001 From: sumathi-thirumani-aot <57740789+sumathi-thirumani-aot@users.noreply.github.com> Date: Thu, 18 Jan 2024 09:15:31 -0800 Subject: [PATCH 6/6] Merge commit '59e01ed63a032698ee9859f60ac1527df5b11daf' into test-rook-merge-dev # Conflicts: # notification-manager/common/notificationusertypes.json # request-management-api/common/notificationusertypes.json --- .../common/notificationusertypes.json | 2 +- .../dao/models/NotificationUserTypes.py | 20 +++++++++++ .../notifications/notificationconfig.py | 33 ++++++++++++++----- .../notifications/notificationuser.py | 10 +++--- .../services/notificationservice.py | 8 ++--- .../models/FOIRawRequestNotificationUsers.py | 5 +-- .../request_api/services/events/state.py | 4 ++- 7 files changed, 59 insertions(+), 23 deletions(-) diff --git a/notification-manager/common/notificationusertypes.json b/notification-manager/common/notificationusertypes.json index 3a5185cd9..a0adaa57e 100644 --- a/notification-manager/common/notificationusertypes.json +++ b/notification-manager/common/notificationusertypes.json @@ -25,7 +25,7 @@ }, "comment tagged user": { "name": "comment tagged user", - "notificationusertypelabel": "commentuser" + "notificationusertypelabel": "assignee" }, "triggereduser": { "name": "Triggered User", diff --git a/notification-manager/notification_api/dao/models/NotificationUserTypes.py b/notification-manager/notification_api/dao/models/NotificationUserTypes.py index ae06e67f6..99bd7be46 100644 --- a/notification-manager/notification_api/dao/models/NotificationUserTypes.py +++ b/notification-manager/notification_api/dao/models/NotificationUserTypes.py @@ -26,3 +26,23 @@ def getid(self, name): finally: if conn: conn.close() + + def getidbylabel(self, label): + conn = None + try: + _notificationusertypes = [] + conn = getconnection() + cursor = conn.cursor() + cursor.execute("""select notificationusertypeid from "NotificationUserTypes" nt where isactive = true and notificationusertypelabel = '{0}'""".format(label)) + data = cursor.fetchone() + if data is not None: + data = {"notificationusertypeid": data[0]} + return data + + cursor.close() + return _notificationusertypes + except(Exception) as error: + logging.error(error) + finally: + if conn: + conn.close() diff --git a/notification-manager/notification_api/services/notifications/notificationconfig.py b/notification-manager/notification_api/services/notifications/notificationconfig.py index 6b18da016..215a969b0 100644 --- a/notification-manager/notification_api/services/notifications/notificationconfig.py +++ b/notification-manager/notification_api/services/notifications/notificationconfig.py @@ -5,32 +5,47 @@ import os from notification_api.dao.models.NotificationTypes import NotificationType from notification_api.dao.models.NotificationUserTypes import NotificationUserType +notificationuserfile = open('common/notificationusertypes.json', encoding="utf8") +notificationusertypes_cache = json.load(notificationuserfile) + +notificationfile = open('common/notificationtypes.json', encoding="utf8") +notificationtypes_cache = json.load(notificationfile) class notificationconfig: """ Notfication config """ - - def getnotificationtypeid(self, notificationtype): - notificationid = NotificationType().getid(notificationtype) - if notificationid is not None: - return notificationid - def getnotificationtype(self, notificationtype): notificationid = NotificationType().getid(notificationtype) if notificationid is not None: return notificationid - def getnotificationusertypeid(self, notificationusertype): + def getnotificationusertype(self, notificationusertype): notificationuserid = NotificationUserType().getid(notificationusertype) if notificationuserid is not None: return notificationuserid + - def getnotificationusertype(self, notificationusertype): - notificationuserid = NotificationUserType().getid(notificationusertype) + # This method is used to get the notification user type label + # It first tries to get the notification user type label from the cache + # If it is not found in the cache, it fetches it from the DB + def getnotificationusertypelabel(self, notificationusertype): + notificationusertype_format = notificationusertype.replace(" ", "").lower() + if notificationusertype_format in notificationusertypes_cache: + return notificationusertypes_cache[notificationusertype_format]['notificationusertypelabel'] + else: + print("Notification user type not found in json. Fetching from DB", notificationusertype) + notificationusertypeobj = self.getnotificationusertype(notificationusertype) + if notificationusertypeobj is not None: + return notificationusertypeobj['notificationusertypelabel'] + return None + + def getnotificationusertypeidbylabel(self, label): + notificationuserid = NotificationUserType().getidbylabel(label) if notificationuserid is not None: return notificationuserid + def getnotificationdays(self): if 'FOI_NOTIFICATION_DAYS' in os.environ and os.getenv('FOI_NOTIFICATION_DAYS') != '': return os.getenv('FOI_NOTIFICATION_DAYS') diff --git a/notification-manager/notification_api/services/notifications/notificationuser.py b/notification-manager/notification_api/services/notifications/notificationuser.py index 35341738f..24e99537c 100644 --- a/notification-manager/notification_api/services/notifications/notificationuser.py +++ b/notification-manager/notification_api/services/notifications/notificationuser.py @@ -53,22 +53,24 @@ def __istaggeduser(self, notificationuser, foicomment, notificationtype): def __gettriggereduser(self, userid, notificationtype): notificationusers = [] + notificationtypelabel = "assignee" if notificationtype in ["Records", "PDFStitch"]: - notificationusers.append({"userid":userid, "usertype":notificationconfig().getnotificationusertype("Triggered User")['notificationusertypelabel']}) + notificationusers.append({"userid":userid, "usertype":notificationtypelabel}) return notificationusers def __getwatchers(self, notificationtype, foirequest, requesttype, requestjson=None): notificationusers = [] - if notificationtype == "Watcher": - notificationusers.append({"userid": requestjson['watchedby'], "usertype":notificationconfig().getnotificationusertype("Watcher")['notificationusertypelabel']}) + notificationtypelabel = "watcher" + if notificationtype == "Watcher": + notificationusers.append({"userid": requestjson['watchedby'], "usertype":notificationtypelabel}) else: if requesttype == "ministryrequest": watchers = FOIMinistryRequest().getwatchers(foirequest["foiministryrequestid"]) else: watchers = FOIRawRequest().getwatchers(foirequest['requestid']) for watcher in watchers: - notificationusers.append({"userid":watcher["watchedby"], "usertype":notificationconfig().getnotificationusertype("Watcher")['notificationusertypelabel']}) + notificationusers.append({"userid":watcher["watchedby"], "usertype":notificationtypelabel}) return notificationusers def __getassignees(self, foirequest, requesttype, notificationtype, requestjson=None): diff --git a/notification-manager/notification_api/services/notificationservice.py b/notification-manager/notification_api/services/notificationservice.py index 3a9df645d..aa6fe43fe 100644 --- a/notification-manager/notification_api/services/notificationservice.py +++ b/notification-manager/notification_api/services/notificationservice.py @@ -87,10 +87,10 @@ def __preparenotificationuser(self, notificationid, notificationuser, userid, mu usertype = notificationusertypes_cache[notificationuser["usertype"]] if usertype is None: print('User type not found', notificationuser["usertype"]) - return None - notificationtypes = notificationconfig().getnotificationusertype(usertype['name']) - user.notificationusertypelabel = notificationtypes['notificationusertypelabel'] - user.notificationusertypeid = notificationtypes['notificationusertypeid'] + return None + notificationusertypelabel = notificationconfig().getnotificationusertypelabel(usertype['name']) + user.notificationusertypelabel = notificationusertypelabel + user.notificationusertypeid = notificationconfig().getnotificationusertypeidbylabel(notificationusertypelabel)['notificationusertypeid'] user.notificationid = notificationid user.userid = notificationuser["userid"] user.createdby = userid diff --git a/request-management-api/request_api/models/FOIRawRequestNotificationUsers.py b/request-management-api/request_api/models/FOIRawRequestNotificationUsers.py index 2f114310d..9d3b15523 100644 --- a/request-management-api/request_api/models/FOIRawRequestNotificationUsers.py +++ b/request-management-api/request_api/models/FOIRawRequestNotificationUsers.py @@ -96,10 +96,7 @@ def getnotificationsbyuser(cls, userid): return notifications @classmethod - def getnotificationsbyuserandtype(cls, userid, typeid): - for key in notificationusertypes_cache: - if (notificationusertypes_cache[key].notificationusertypeid == typeid) or (notificationusertypes_cache[key].notificationusertypelabel == typeid): - notificationusertypelabel = notificationusertypes_cache[key].notificationusertypelabel + def getnotificationsbyuserandtype(cls, userid, notificationusertypelabel): notifications = [] try: sql = """select notificationid, count(1) as relcount from "FOIRawRequestNotificationUsers" frnu diff --git a/request-management-api/request_api/services/events/state.py b/request-management-api/request_api/services/events/state.py index 877009889..d5b015d43 100644 --- a/request-management-api/request_api/services/events/state.py +++ b/request-management-api/request_api/services/events/state.py @@ -63,7 +63,6 @@ def __createnotification(self, requestid, state, requesttype, userid): if state == StateName.callforrecords.value and requesttype == "ministryrequest": foirequest = notificationservice().getrequest(requestid, requesttype) _notificationtype = "Group Members" if foirequest['assignedministryperson'] is None else "State" - notificationtype = NotificationType().getnotificationtypeid(_notificationtype) notification = self.__preparenotification(state) if state == StateName.response.value and requesttype == "ministryrequest": signgoffapproval = FOIMinistryRequest().getrequest(requestid)['ministrysignoffapproval'] @@ -74,10 +73,13 @@ def __createnotification(self, requestid, state, requesttype, userid): if state == StateName.archived.value: _openedministries = FOIMinistryRequest.getministriesopenedbyuid(requestid) for ministry in _openedministries: + notificationtype = NotificationType().getnotificationtypeid("State") response = notificationservice().createnotification({"message" : notification}, ministry["ministryrequestid"], 'ministryrequest', notificationtype, userid) else: + notificationtype = NotificationType().getnotificationtypeid("State") response = notificationservice().createnotification({"message" : notification}, requestid, requesttype, notificationtype, userid) if _notificationtype == "Group Members": + notificationtype = NotificationType().getnotificationtypeid(_notificationtype) notification = self.__preparegroupmembernotification(state, requestid) groupmemberresponse = notificationservice().createnotification({"message" : notification}, requestid, requesttype, notificationtype, userid) if response.success == True and groupmemberresponse.success == True :