Skip to content

Commit

Permalink
930 event history (#591)
Browse files Browse the repository at this point in the history
* new transaction endpoint - events
* added business logic to determine and capture the user action
* added unit tests
* added missing events
* added event history folder and test to postman
Signed-off-by: Lorna Trent <[email protected]>
  • Loading branch information
LJTrent authored and thorwolpert committed Aug 22, 2019
1 parent 1a8eaf5 commit 36a58e5
Show file tree
Hide file tree
Showing 6 changed files with 748 additions and 5 deletions.
6 changes: 3 additions & 3 deletions api/namex/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Event(db.Model):
id = db.Column(db.Integer, primary_key=True)
eventDate = db.Column('event_dt', db.DateTime(timezone=True), default=datetime.utcnow)
action = db.Column(db.String(1000))
jsonZip = db.Column('json_zip', db.LargeBinary)
jsonZip = db.Column('json_zip', db.Text)
eventJson = db.Column('event_json', JSONB)

# relationships
Expand All @@ -40,8 +40,8 @@ class Event(db.Model):
VALID_ACTIONS=[GET, PUT, PATCH, POST, DELETE]

def json(self):
return {"eventDate": self.eventDate, "action": self.action, "jsonData": self.eventJson,
"requestId": self.nrId, "userId": self.userId }
return {"id": self.id, "eventDate": self.eventDate, "action": self.action, "stateCd": self. stateCd, "jsonData": self.eventJson,
"requestId": self.nrId, "userId": self.userId}

def save_to_db(self):
db.session.add(self)
Expand Down
2 changes: 2 additions & 0 deletions api/namex/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .document_analysis import api as analysis_api
from .meta import api as meta_api
from .exact_match import api as exact_match_api
from .events import api as events_api

# This will add the Authorize button to the swagger docs
# TODO oauth2 & openid may not yet be supported by restplus <- check on this
Expand All @@ -29,3 +30,4 @@
api.add_namespace(analysis_api, path='/documents')
api.add_namespace(meta_api, path='/meta')
api.add_namespace(exact_match_api, path='/exact-match')
api.add_namespace(events_api, path='/events')
116 changes: 116 additions & 0 deletions api/namex/resources/events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from flask import jsonify, request
from flask_restplus import Resource, Namespace, cors
from namex.utils.util import cors_preflight
import json
from namex import jwt
from flask import current_app
from namex.models import db

from namex.utils.logging import setup_logging
setup_logging() ## important to do this first

from sqlalchemy.dialects import postgresql
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy import func, text
from sqlalchemy.inspection import inspect


from namex.models import Event as EventDAO, Request as RequestDAO, User

import datetime
from datetime import datetime as dt


# Register a local namespace for the event history
api = Namespace('Events', description='Audit trail of events for a name request')
@cors_preflight("GET")
@api.route('/<string:nr>', methods=['GET','OPTIONS'])
class Events(Resource):
@staticmethod
@cors.crossdomain(origin='*')
@jwt.has_one_of_roles([User.APPROVER, User.EDITOR])
def get(nr):
nrd = RequestDAO.query.filter_by(nrNum=nr.upper()).first_or_404().json()
request_id = 0
if "id" in nrd:
request_id = nrd["id"]
if not request_id:
return jsonify({"message": "Request NR:{} not found".format(nr)}), 404

event = EventDAO.query.filter_by(nrId = request_id).order_by("id").first_or_404().json()
if not "id" in event:
return jsonify({"message": "No events for NR:{} not found".format(nr)}), 404

event_results = EventDAO.query.filter_by(nrId=request_id).order_by("id").all()

e_dict_previous = dict()
e_txn_history = dict()
i=0

for e in event_results:

e_dict = e.json()
user_action = ""
user_name = ""

user = User.query.filter_by(id=e_dict['userId']).first().json()

if e_dict["action"] == "update_from_nro" and ( e_dict["stateCd"] == "INPROGRESS" or e_dict["stateCd"] == "DRAFT"):
user_action = "Get NR Details from NRO"
if e_dict["action"] == "get" and e_dict["stateCd"] == "INPROGRESS":
user_action = "Get Next NR"
if e_dict["action"] == "patch" and e_dict["stateCd"] == "INPROGRESS":
user_action = "Load NR"
if e_dict["action"] == "patch" and e_dict["stateCd"] == "HOLD":
user_action = "Hold Request"
if e_dict["action"] == "marked_on_hold" and e_dict["stateCd"] == "HOLD":
user_action = "Marked on Hold"
if e_dict["action"] == "put" and e_dict["stateCd"] == "DRAFT":
user_action = "Edit NR Details"
if e_dict["action"] == "put" and e_dict["stateCd"] == "INPROGRESS" and "additional" in e_dict["jsonData"]:
if len(e_dict_previous) == 0 or (e_dict_previous["stateCd"] == "HOLD" or e_dict_previous["stateCd"] == "DRAFT" or e_dict_previous["stateCd"] == "INPROGRESS"):
user_action = "Edit NR Details"
if e_dict_previous and e_dict_previous["stateCd"] == "APPROVED" or e_dict_previous["stateCd"]=="REJECTED" or e_dict_previous["stateCd"] == "CONDITIONAL":
if '"furnished": "Y"' in e_dict["jsonData"]:
user_action = "Reset"
else:
user_action = "Re-Open"
if e_dict["action"] == "put" and (e_dict["stateCd"] == "APPROVED" or e_dict["stateCd"] == "REJECTED" or e_dict["stateCd"] == "CONDITIONAL"):
user_action = "Edit NR Details after Completion"
if e_dict["action"] == "put" and e_dict["stateCd"] == "INPROGRESS" and "additional" not in e_dict["jsonData"] and '"state": "NE"' not in e_dict["jsonData"]:
user_action = "Complete the Name Choice"
if e_dict["action"] == "patch" and (e_dict["stateCd"]== "APPROVED" or e_dict["stateCd"] == "REJECTED" or e_dict["stateCd"] == "CONDITIONAL"):
user_action = "Decision"
if e_dict["action"] == "put" and e_dict["stateCd"] == "INPROGRESS" and "additional" not in e_dict["jsonData"] and '"state": "NE"' in e_dict["jsonData"]:
user_action = "Undo Decision"
if e_dict["action"] == "nro_update" and (e_dict["stateCd"]== "APPROVED" or e_dict["stateCd"] == "REJECTED" or e_dict["stateCd"] == "CONDITIONAL"):
user_action = "Updated NRO"
if e_dict["action"] == "post" and "comment" in e_dict["jsonData"]:
user_action = "Staff Comment"
if e_dict["stateCd"] == "CANCELLED" and (e_dict["action"] == "post" or e_dict["action"] == "update_from_nro"):
user_action = "Cancelled in NRO"
if e_dict["stateCd"] == "CANCELLED" and (e_dict["action"] == "patch" or e_dict["action"] == "put"):
user_action = "Cancelled in Namex"
if e_dict["stateCd"] == "EXPIRED" and e_dict["action"] == "post":
user_action = "Expired by NRO"
if e_dict["stateCd"] == "HISTORICAL" and e_dict["action"] == "post":
user_action = "Set to Historical by NRO(Migration)"
if e_dict["stateCd"]=="COMPLETED" and (e_dict["action"] == "post" or e_dict["action"] == "update_from_nro"):
user_action = "Migrated by NRO"

e_dict_previous = e_dict
e_dict["user_action"] = user_action
e_dict["user_name"] = user["username"]

i=i+1
e_txn_history[i] = {}
e_txn_history[i] = e_dict

if i==0:
return jsonify({"message": "No valid events for NR:{} found".format(nr)}), 404

rep = {'response': {'count':i},
'transactions': e_txn_history
}

return jsonify(rep), 200
65 changes: 65 additions & 0 deletions api/tests/postman/namex-pipeline-dev.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -6060,6 +6060,71 @@
}
}
]
},
{
"name": "event-history",
"description": "",
"item": [
{
"name": "event-history",
"event": [
{
"listen": "test",
"script": {
"id": "dff8c184-eedc-453e-b086-d68bdbba2cf0",
"type": "text/javascript",
"exec": [
"eval(globals.postmanBDD);",
"",
"pm.test(\"Response time is less than 5000ms\", function () {",
" pm.expect(pm.response.responseTime).to.be.below(5000);",
"});",
"",
"it('should be an success response', () => {",
" response.ok.should.be.true; // 2XX",
" response.error.should.be.false; // 4XX or 5XX",
" response.clientError.should.be.false; // 4XX",
" response.serverError.should.be.false; // 5XX",
" response.should.have.status(200);",
" response.statusType.should.equal(2);",
"});",
"",
"it('should return JSON', () => {",
" response.should.be.json;",
" response.should.have.header('Content-Type', 'application/json');",
" response.type.should.equal('application/json');",
"});",
""
]
}
}
],
"request": {
"method": "GET",
"header": [
{
"key": "Authorization",
"value": "Bearer {{token}}"
}
],
"body": {},
"url": {
"raw": "{{url}}/api/v1/events/NR 1287084",
"host": [
"{{url}}"
],
"path": [
"api",
"v1",
"events",
"NR 1287084"
]
},
"description": "To be used as transaction history for an NR."
},
"response": []
}
]
}
]
}
152 changes: 150 additions & 2 deletions api/tests/postman/namex-pipeline-test.postman_collection.json

Large diffs are not rendered by default.

Loading

0 comments on commit 36a58e5

Please sign in to comment.