Skip to content

Commit

Permalink
Merge pull request #4832 from bcgov/dev-rook-ST-4694
Browse files Browse the repository at this point in the history
Dev rook st 4694
  • Loading branch information
Aman-Hundal authored Dec 6, 2023
2 parents 35a7d86 + c52dfde commit 2602034
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""empty message
Revision ID: 3e91d4f34699
Revises: 455a24da8c58
Create Date: 2023-11-30 00:11:56.160830
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '3e91d4f34699'
down_revision = '455a24da8c58'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.execute('Insert into public."NotificationTypes" (name, description, isactive) values (\'OIPC\', \'OIPC\', true);commit;')
op.execute('Insert into public."NotificationTypes" (name, description, isactive) values (\'OIPC Due Reminder\', \'OIPC Due Reminder\', true);commit;')
op.execute('Insert into public."CommentTypes" (name, description, isactive) values (\'OIPC Tracking\', \'OIPC Tracking\', true);commit;')
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.execute('delete from public."NotificationTypes" where name in (\'OIPC\');commit;')
op.execute('delete from public."NotificationTypes" where name in (\'OIPC Due Reminder\');commit;')
op.execute('delete from public."CommentTypes" where name in (\'OIPC Tracking\');commit;')
# ### end Alembic commands ###
27 changes: 27 additions & 0 deletions request-management-api/request_api/models/FOIMinistryRequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,33 @@ def getupcomingdivisionduerecords(cls):
finally:
db.session.close()
return upcomingduerecords

@classmethod
def getupcomingoipcduerecords(cls):
upcomingduerecords = []
try:
sql = """select axisrequestid, filenumber, fma.foiministryrequestid , fma.foiministryrequestversion, fma.foirequest_id,
frd.oipcid , frd.inquiryattributes ->> 'orderno'as orderno,
frd.inquiryattributes ->> 'inquirydate' as duedate, frd.created_at, frd.createdby
from "FOIRequestOIPC" frd
inner join (select distinct on (fpa.foiministryrequestid) foiministryrequestid, version as foiministryrequestversion, axisrequestid, filenumber, foirequest_id, requeststatusid
from "FOIMinistryRequests" fpa
order by fpa.foiministryrequestid , fpa.version desc) fma on frd.foiministryrequest_id = fma.foiministryrequestid
and frd.foiministryrequestversion_id = fma.foiministryrequestversion and fma.requeststatusid not in (5,6,4,11,3,15)
and (frd.inquiryattributes ->> 'inquirydate')::date between NOW() - INTERVAL '7 DAY' AND NOW() + INTERVAL '7 DAY'
order by frd.foiministryrequest_id , frd.foiministryrequestversion_id desc;"""
rs = db.session.execute(text(sql))
for row in rs:
upcomingduerecords.append({"axisrequestid": row["axisrequestid"], "filenumber": row["filenumber"],
"foiministryrequestid": row["foiministryrequestid"], "version": row["foiministryrequestversion"],
"foirequest_id": row["foirequest_id"], "created_at": row["created_at"], "createdby": row["createdby"],
"orderno": row["orderno"],"duedate": row["duedate"]})
except Exception as ex:
logging.error(ex)
raise ex
finally:
db.session.close()
return upcomingduerecords

@classmethod
def updateduedate(cls, ministryrequestid, duedate, userid)->DefaultMethodResult:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ class OIPCReviewTypesReasons(db.Model):
__tablename__ = 'OIPCReviewTypesReasons'
# Defining the columns
reviewtypereasonid = db.Column(db.Integer, primary_key=True,autoincrement=True)
reviewtypeid = db.Column(db.Integer, ForeignKey('FOIReviewTypes'))
relationship("FOIReviewTypes", backref=backref("FOIReviewTypes"), uselist=False)
reasonid = db.Column(db.Integer, ForeignKey('FOIReasons'))
relationship("FOIReasons", backref=backref("FOIReasons"), uselist=False)
reviewtypeid = db.Column(db.Integer, ForeignKey('OIPCReviewTypes'))
relationship("OIPCReviewTypes", backref=backref("OIPCReviewTypes"), uselist=False)
reasonid = db.Column(db.Integer, ForeignKey('OIPCReasons'))
relationship("OIPCReasons", backref=backref("OIPCReasons"), uselist=False)
isactive = db.Column(db.Boolean, unique=False, nullable=False)

@classmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ def getpreviousbusinessday(self, cfrduedate,ca_holidays):
return _prevbusinessday
else:
return self.getpreviousbusinessday(_prevbusinessday,ca_holidays)


def getpreviousbusinessday_by_n(self, duedate, ca_holidays, n):
_prevbusinessday = duedate
for i in range(n):
_prevbusinessday = self.getpreviousbusinessday(_prevbusinessday, ca_holidays)
return _prevbusinessday

def formatduedate(self,input):
return datetimehandler().formatdate(input)

Expand Down
156 changes: 156 additions & 0 deletions request-management-api/request_api/services/events/oipc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@

from os import stat
from re import VERBOSE
from request_api.models.FOIRequestOIPC import FOIRequestOIPC
from request_api.services.commentservice import commentservice
from request_api.services.oipcservice import oipcservice
from request_api.services.notificationservice import notificationservice
from request_api.models.FOIMinistryRequests import FOIMinistryRequest
import json
from request_api.models.default_method_result import DefaultMethodResult
from enum import Enum
from request_api.exceptions import BusinessException
from dateutil.parser import parse
from request_api.utils.enums import CommentType

class oipcevent:
""" FOI OIPC Event management service
"""

def createoipcevent(self, requestid, userid):
inquiryoutcomes = oipcservice().getinquiryoutcomes()
version = FOIMinistryRequest.getversionforrequest(requestid)
curoipcs = FOIRequestOIPC.getoipc(requestid, version)
prevoipcs = FOIRequestOIPC.getoipc(requestid, version[0]-1)
oipcsummary = self.__maintained(curoipcs, prevoipcs, inquiryoutcomes)
if oipcsummary is None or (oipcsummary and len(oipcsummary) <1):
return DefaultMethodResult(True,'No change',requestid)
try:
for oipc in oipcsummary:
self.__createcomment(requestid, oipc, userid)
self.__createnotification(requestid, oipc, userid)
return DefaultMethodResult(True,'Comment posted',requestid)
except BusinessException as exception:
return DefaultMethodResult(False,'unable to post comment - '+exception.message,requestid)


def __createcomment(self, requestid, oipc, userid):
comment = {"ministryrequestid": requestid, "comment": self.__preparemessage(oipc)}
commentservice().createministryrequestcomment(comment, userid, CommentType.OIPC.value)

def __createnotification(self, requestid, oipc, userid):
return notificationservice().createnotification({"message" : self.__preparemessage(oipc)}, requestid, "ministryrequest", "OIPC", userid, False)


def __maintained(self,coipcs, poipcs, inquiryoutcomes):
oipcs = []
for coipc in coipcs:
if self.__isoipcpresent(self.__getoipcnumber(coipc), poipcs) == False:
oipcs.append(self.__createoipcsummary(coipc, EventType.add.value, inquiryoutcomes))
else:
if self.__isoutcomeclosed(coipc, poipcs) == True:
oipcs.append(self.__createoipcsummary(coipc, EventType.close.value, inquiryoutcomes))
if self.__isinquirychanged(coipc, poipcs) == True:
oipcs.append(self.__createoipcsummary(coipc, EventType.inquirychange.value, inquiryoutcomes))
elif self.__isinquiryoutcomechanged(coipc, poipcs, inquiryoutcomes) == True:
oipcs.append(self.__createoipcsummary(coipc, EventType.inquiryoutcome.value, inquiryoutcomes))
return oipcs

# def __deleted(self, coipcs, poipcs):
# oipcs = []
# for poipc in poipcs:
# if self.__isoipcpresent(self.__getoipcnumber(poipc), coipcs) == False:
# oipcs.append(self.__createoipcsummary(poipc, EventType.delete.value))
# return oipcs

def __isoipcpresent(self, oipcno, poipcs):
for oipc in poipcs:
if self.__getoipcnumber(oipc) == oipcno:
return True
return False

def __isoutcomeclosed(self, coipc, poipcs):
for oipc in poipcs:
if self.__getoipcnumber(oipc) == self.__getoipcnumber(coipc) and self.__getoutcome(oipc) != self.__getoutcome(coipc) and self.__getoutcome(coipc) == "Closed":
return True
return False

def __isinquirychanged(self, coipc, poipcs):
for oipc in poipcs:
if self.__getoipcnumber(oipc) == self.__getoipcnumber(coipc) and self.__getinquiry(oipc) != self.__getinquiry(coipc):
if self.__getinquirycomplydate(coipc) not in (None, "") and self.__getinquiryorderno(coipc) not in (None, "") and (self.__getinquiryorderno(oipc) != self.__getinquiryorderno(coipc) or self.__getinquirycomplydate(oipc) != self.__getinquirycomplydate(coipc)):
return True
return False

def __isinquiryoutcomechanged(self, coipc, poipcs, inquiryoutcomes):
for oipc in poipcs:
if self.__getoipcnumber(oipc) == self.__getoipcnumber(coipc) and self.__getinquiry(oipc) != self.__getinquiry(coipc):
if self.__getinquiryoutcome(coipc, inquiryoutcomes) not in (None, "") and self.__getinquiryoutcome(oipc, inquiryoutcomes) != self.__getinquiryoutcome(coipc, inquiryoutcomes):
return True
return False

def __createoipcsummary(self, oipc, event, inquiryoutcomes):
return {'oipcno': self.__getoipcnumber(oipc),
'reviewtype': self.__getoipcreviewtype(oipc),
'reason':self.__getreason(oipc),
'outcome': self.__getoutcome(oipc),
'inquirycomplydate': self.__getinquirycomplydate(oipc),
'inquiryorderno': self.__getinquirycomplydate(oipc),
'inquiryoutcome': self.__getinquiryoutcome(oipc, inquiryoutcomes),
'event': event}

def __getoipcnumber(self, dataschema):
return dataschema['oipcno']

def __getoipcreviewtype(self, dataschema):
return dataschema['reviewtype.name']

def __getreason(self, dataschema):
return dataschema['reason.name']

def __getoutcome(self, dataschema):
return dataschema['outcome.name'] if dataschema['outcomeid'] not in (None,"") else None

def __getinquirycomplydate(self, dataschema):
return self.__getinquiry(dataschema)['inquirydate'] if dataschema['inquiryattributes'] not in (None,"") else None

def __getinquiryoutcome(self, dataschema, inquiryoutcomes):
if dataschema['inquiryattributes'] not in (None,""):
inquiryoutcomeid = self.__getinquiry(dataschema)['inquiryoutcome']
if inquiryoutcomeid not in (None,""):
return self.__getinquiryoutcomename(inquiryoutcomeid, inquiryoutcomes)
return None

def __getinquiryorderno(self, dataschema):
return self.__getinquiry(dataschema)['orderno'] if dataschema['inquiryattributes'] not in (None,"") else None

def __getinquiry(self, dataschema):
return dataschema['inquiryattributes']

def __getinquiryoutcomename(self, inquiryoutcomeid, inquiryoutcomes):
for outcome in inquiryoutcomes:
if inquiryoutcomeid == outcome["inquiryoutcomeid"]:
return outcome["name"]
return None

def __preparemessage(self, oipc):
if oipc['event'] == EventType.add.value:
return 'OIPC '+ oipc['reviewtype'] +' opened for '+ oipc['reason']
elif oipc['event'] == EventType.close.value:
return 'OIPC '+ oipc['reviewtype'] +' closed for '+ oipc['reason']
elif oipc['event'] == EventType.inquirychange.value:
_inquirychange_msg = 'OIPC Inquiry Order '+ oipc['inquiryorderno'] +' compliance date due '+oipc['inquirycomplydate']
if oipc['inquiryoutcome'] not in (None, ""):
return _inquirychange_msg+' .Inquiry Decision:' + oipc['inquiryoutcome']
else:
return _inquirychange_msg
elif oipc['event'] == EventType.inquiryoutcome.value:
return 'OIPC '+ oipc['reviewtype'] +' Inquiry Decision: '+ oipc['inquiryoutcome']


class EventType(Enum):
add = "add"
delete = "delete"
close = "close"
inquirychange = "inquirychange"
inquiryoutcome = "inquiryoutcome"
69 changes: 69 additions & 0 deletions request-management-api/request_api/services/events/oipcduedate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

from os import stat
from re import VERBOSE
from request_api.services.commentservice import commentservice
from request_api.services.commons.duecalculator import duecalculator
from request_api.services.notificationservice import notificationservice
from request_api.models.FOIMinistryRequests import FOIMinistryRequest
import json
from request_api.models.default_method_result import DefaultMethodResult
from request_api.exceptions import BusinessException
from dateutil.parser import parse
from flask import current_app

class oipcduedateevent(duecalculator):
""" FOI OIPC Due Date Event management service
"""

def createdueevent(self):
try:
_today = self.gettoday()
notificationservice().dismissremindernotification("ministryrequest", self.__notificationtype())
ca_holidays = self.getholidays()
_upcomingdues = FOIMinistryRequest.getupcomingoipcduerecords()
for entry in _upcomingdues:
_duedate = self.formatduedate(entry['duedate'])
message = None
if _duedate == _today:
message = self.__todayduemessage(entry)
elif self.getpreviousbusinessday(entry['duedate'],ca_holidays) == _today:
message = self.__upcomingduemessage(entry)
elif self.getpreviousbusinessday_by_n(entry['duedate'],ca_holidays, 2) == _today:
message = self.__upcomingduemessage(entry)
self.__createnotification(message,entry['foiministryrequestid'])
self.__createcomment(entry, message)
return DefaultMethodResult(True,'OIPC reminder notifications created',_today)
except BusinessException as exception:
current_app.logger.error("%s,%s" % ('OIPC reminder Notification Error', exception.message))
return DefaultMethodResult(False,'OIPC reminder notifications failed',_today)

def __createnotification(self, message, requestid):
if message is not None:
return notificationservice().createnotification({"message" : message}, requestid, "ministryrequest", self.__notificationtype(), self.__defaultuserid(), False)

def __createcomment(self, entry, message):
if message is not None:
_comment = self.__preparecomment(entry, message)
return commentservice().createcomments(_comment, self.__defaultuserid(), 2)


def __preparecomment(self, foirequest, message):
_comment = dict()
_comment['comment'] = message
_comment['ministryrequestid'] = foirequest["foiministryrequestid"]
_comment['version'] = foirequest["version"]
_comment['taggedusers'] = None
_comment['parentcommentid'] = None
return _comment

def __upcomingduemessage(self, data):
return 'OIPC Inquiry Order '+data['orderno'] +' compliance date due on ' + parse(str(data['duedate'])).strftime("%Y %b %d").upper()

def __todayduemessage(self, data):
return 'OIPC Inquiry Order '+data['orderno'] +' compliance due Today'

def __notificationtype(self):
return "OIPC Due Reminder"

def __defaultuserid(self):
return "System"
Loading

0 comments on commit 2602034

Please sign in to comment.