class ServiceRequestActivate(Resource): citizen_schema = CitizenSchema() service_requests_schema = ServiceReqSchema(many=True) service_request_schema = ServiceReqSchema() @oidc.accept_token(require_token=True) @api_call_with_retry def post(self, id): csr = CSR.find_by_username(g.oidc_token_info['username']) service_request = ServiceReq.query.filter_by(sr_id=id) \ .join(ServiceReq.citizen, aliased=True) \ .filter_by(office_id=csr.office_id).first_or_404() active_service_state = SRState.get_state_by_name("Active") complete_service_state = SRState.get_state_by_name("Complete") # Find the currently active service_request and close it current_sr_number = 0 for req in service_request.citizen.service_reqs: if req.sr_state_id == active_service_state.sr_state_id: req.sr_state_id = complete_service_state.sr_state_id req.finish_service(csr, clear_comments=False) current_sr_number = req.sr_number db.session.add(req) # Then set the requested service to active service_request.sr_state_id = active_service_state.sr_state_id period_state_being_served = PeriodState.get_state_by_name("Being Served") new_period = Period( sr_id=service_request.sr_id, csr_id=csr.csr_id, reception_csr_ind=csr.receptionist_ind, ps_id=period_state_being_served.ps_id, time_start=datetime.now() ) db.session.add(new_period) db.session.add(service_request) db.session.commit() # To make service active, stop current service, restart previous service. SnowPlow.snowplow_event(service_request.citizen.citizen_id, csr, "stopservice", current_sr_number=current_sr_number) SnowPlow.snowplow_event(service_request.citizen.citizen_id, csr, "restartservice", current_sr_number=service_request.sr_number) citizen_result = self.citizen_schema.dump(service_request.citizen) socketio.emit('update_active_citizen', citizen_result.data, room=csr.office_id) result = self.service_request_schema.dump(service_request) return {'service_request': result.data, 'errors': result.errors}, 200
def test_create_edit_delete_note(self): with application.app_context(): service_request_schema = ServiceReqSchema() json_data = { 'service_id': 12, 'citizen_id': '', 'quantity': 3, 'channel_id': 2 } service_request = service_request_schema.load(json_data) # Confirm a marshmallow bug, returns a dict when invalid data passed in. assert type(service_request) is dict
class ServiceRequestsDetail(Resource): citizen_schema = CitizenSchema() service_requests_schema = ServiceReqSchema(many=True) service_request_schema = ServiceReqSchema() @jwt.has_one_of_roles([Role.internal_user.value]) @api_call_with_retry def put(self, id): json_data = request.get_json() if not json_data: return { 'message': 'No input data received for updating citizen' }, 400 csr = CSR.find_by_username(g.jwt_oidc_token_info['username']) service_request = ServiceReq.query.filter_by(sr_id=id) \ .join(ServiceReq.citizen, aliased=True).first_or_404() try: service_request = self.service_request_schema.load( json_data, instance=service_request, partial=True) except ValidationError as err: return {'message': err.messages}, 422 db.session.add(service_request) db.session.commit() SnowPlow.choose_service(service_request, csr, "chooseservice") result = self.service_request_schema.dump(service_request) citizen_result = self.citizen_schema.dump(service_request.citizen) socketio.emit('update_active_citizen', citizen_result, room=csr.office_id) return { 'service_request': result, 'errors': self.service_request_schema.validate(service_request) }, 200
class CitizenServiceRequests(Resource): service_requests_schema = ServiceReqSchema(many=True) @oidc.accept_token(require_token=True) def get(self, id): try: csr = CSR.find_by_username(g.oidc_token_info['username']) citizen = Citizen.query.filter_by(citizen_id=id, office_id=csr.office_id).first() result = self.service_requests_schema.dump(citizen.service_reqs) return {'service_requests': result.data, 'errors': result.errors} except exc.SQLAlchemyError as e: print(e) return {'message': 'API is down'}, 500
class CitizenSchema(ma.ModelSchema): class Meta: model = Citizen jit = toastedmarshmallow.Jit exclude = ('office_citizens','office',) citizen_id = fields.Int(dump_only=True) office_id = fields.Int() ticket_number = fields.Str(dump_only=True) citizen_comments = fields.Str() qt_xn_citizen_ind = fields.Int() start_time = fields.DateTime(dump_only=True) accurate_time_ind = fields.Int() service_reqs = fields.Nested(ServiceReqSchema(exclude=('citizen',)), many=True) cs = fields.Nested(CitizenStateSchema(exclude=('cs_state_desc', 'cs_id', 'citizens', 'state_citizens'))) priority = fields.Int()
class CitizenSchema(BaseSchema): class Meta(BaseSchema.Meta): model = Citizen include_relationships = True datetimeformat = '%Y-%m-%dT%H:%M:%SZ' citizen_id = fields.Int(dump_only=True) citizen_name = fields.Str() office_id = fields.Int() ticket_number = fields.Str(dump_only=True) citizen_comments = fields.Str() qt_xn_citizen_ind = fields.Int() counter_id = fields.Int() start_time = fields.DateTime() accurate_time_ind = fields.Int() service_reqs = fields.Nested(ServiceReqSchema(exclude=('citizen', )), many=True) cs = fields.Nested(CitizenStateSchema(exclude=('cs_state_desc', 'cs_id'))) priority = fields.Int() user_id = fields.Int()
class CitizenServiceRequests(Resource): service_requests_schema = ServiceReqSchema(many=True) @oidc.accept_token(require_token=True) @has_any_role(roles=[Role.internal_user.value]) def get(self, id): try: csr = CSR.find_by_username(g.oidc_token_info['username']) citizen = Citizen.query.filter_by(citizen_id=id, office_id=csr.office_id).first() my_print("==> GET /citizens/" + str(citizen.citizen_id) + '/service_requests/, Ticket: ' + citizen.ticket_number) result = self.service_requests_schema.dump(citizen.service_reqs) return {'service_requests': result.data, 'errors': result.errors} except exc.SQLAlchemyError as e: print(e) return {'message': 'API is down'}, 500
class CitizenSchema(ma.SQLAlchemySchema): class Meta: model = Citizen include_relationships = True load_instance = True jit = toastedmarshmallow.Jit citizen_id = fields.Int(dump_only=True) citizen_name = fields.Str() office_id = fields.Int() ticket_number = fields.Str(dump_only=True) citizen_comments = fields.Str() qt_xn_citizen_ind = fields.Int() counter_id = fields.Int() start_time = fields.DateTime() accurate_time_ind = fields.Int() service_reqs = fields.Nested(ServiceReqSchema(exclude=('citizen', )), many=True) cs = fields.Nested( CitizenStateSchema(exclude=('cs_state_desc', 'cs_id', 'citizens', 'state_citizens'))) priority = fields.Int() user_id = fields.Int()
class CitizenSchema(BaseSchema): class Meta(BaseSchema.Meta): model = Citizen include_relationships = True datetimeformat = '%Y-%m-%dT%H:%M:%SZ' citizen_id = fields.Int(dump_only=True) citizen_name = fields.Str() office_id = fields.Int() ticket_number = fields.Str(dump_only=True) citizen_comments = fields.Str() qt_xn_citizen_ind = fields.Int() counter_id = fields.Int() start_time = fields.DateTime() accurate_time_ind = fields.Int() service_reqs = fields.Nested(ServiceReqSchema(exclude=('citizen', )), many=True) cs = fields.Nested(CitizenStateSchema(exclude=('cs_state_desc', 'cs_id'))) priority = fields.Int() user_id = fields.Int() # for walk-in notification_sent_time = fields.DateTime() notification_phone = fields.Str() notification_email = fields.Str() # reminder_flag # 0 - reminder not sent - grey icon # 1 - first reminder sent - blue icon # 2 - second reminder sent - red icon reminder_flag = fields.Int() walkin_unique_id = fields.Str() # 0/null-automatic reminder not send # 1-automatic reminder sent once automatic_reminder_flag = fields.Int() # Digital signange created_at = fields.DateTime()
class ServiceRequestsList(Resource): citizen_schema = CitizenSchema() service_request_schema = ServiceReqSchema() @oidc.accept_token(require_token=True) @api_call_with_retry def post(self): json_data = request.get_json() if not json_data: return {"message": "No input data received for creating service request"}, 400 csr = CSR.find_by_username(g.oidc_token_info['username']) try: service_request = self.service_request_schema.load(json_data['service_request']).data except ValidationError as err: return {"message": err.messages}, 422 except KeyError as err: print (err) return {"message": str(err)} active_sr_state = SRState.get_state_by_name("Active") complete_sr_state = SRState.get_state_by_name("Complete") citizen_state = CitizenState.query.filter_by(cs_state_name="Active").first() citizen = Citizen.query.get(service_request.citizen_id) service = Service.query.get(service_request.service_id) if citizen is None: return {"message": "No matching citizen found for citizen_id"}, 400 if service is None: return {"message": "No matching service found for service_id"}, 400 # Find the currently active service_request and close it (if it exists) current_sr_number = 0 for req in citizen.service_reqs: if req.sr_state_id == active_sr_state.sr_state_id: req.sr_state_id = complete_sr_state.sr_state_id req.finish_service(csr, clear_comments=False) current_sr_number = req.sr_number db.session.add(req) service_request.sr_state_id = active_sr_state.sr_state_id # Only add ticket creation period and ticket number if it's their first service_request if len(citizen.service_reqs) == 0: period_state_ticket_creation = PeriodState.get_state_by_name("Ticket Creation") ticket_create_period = Period( csr_id=csr.csr_id, reception_csr_ind=csr.receptionist_ind, ps_id=period_state_ticket_creation.ps_id, time_start=citizen.get_service_start_time(), time_end=datetime.now() ) service_request.periods.append(ticket_create_period) # Move start_time back 6 hours to account for DST and UTC offsets # It's only important that the number carries over _around_ midnight offset_start_time = citizen.start_time - timedelta(hours=6) service_count = ServiceReq.query \ .join(ServiceReq.citizen, aliased=True) \ .filter(Citizen.start_time >= offset_start_time.strftime("%Y-%m-%d")) \ .filter_by(office_id=csr.office_id) \ .join(ServiceReq.service, aliased=True) \ .filter_by(prefix=service.prefix) \ .count() citizen.ticket_number = service.prefix + str(service_count) else: period_state_being_served = PeriodState.get_state_by_name("Being Served") ticket_create_period = Period( csr_id=csr.csr_id, reception_csr_ind=csr.receptionist_ind, ps_id=period_state_being_served.ps_id, time_start=datetime.now() ) service_request.periods.append(ticket_create_period) citizen.cs_id = citizen_state.cs_id # If first service, just choose it. If additional service, more work needed. if len(citizen.service_reqs) == 0: snowplow_event = "chooseservice" else: snowplow_event = "additionalservice" service_request.sr_number = len(citizen.service_reqs) + 1 db.session.add(service_request) db.session.add(citizen) db.session.commit() # If first service, just need a choose service call. if snowplow_event == "chooseservice": SnowPlow.choose_service(service_request, csr, "chooseservice") # If not first service, need stop service, choose service, and additional service calls. else: SnowPlow.snowplow_event(citizen.citizen_id, csr, "stopservice", current_sr_number=current_sr_number) SnowPlow.choose_service(service_request, csr, "chooseservice") SnowPlow.snowplow_event(citizen.citizen_id, csr, "additionalservice", current_sr_number=service_request.sr_number) citizen_result = self.citizen_schema.dump(citizen) socketio.emit('update_active_citizen', citizen_result.data, room=csr.office_id) result = self.service_request_schema.dump(service_request) return {'service_request': result.data, 'errors': result.errors}, 201
class ServiceRequestsList(Resource): citizen_schema = CitizenSchema() service_request_schema = ServiceReqSchema() @jwt.has_one_of_roles([Role.internal_user.value]) @api_call_with_retry def post(self): try: json_data = request.get_json() except Exception as error: return {"message": str(error)}, 401 csr = CSR.find_by_username(g.jwt_oidc_token_info['username']) service_request, message, code = get_service_request( self, json_data, csr) if (service_request is None): return {"message": message}, code active_sr_state = SRState.get_state_by_name("Active") complete_sr_state = SRState.get_state_by_name("Complete") citizen = None try: citizen = Citizen.query.get(service_request.citizen_id) except: print("==> An exception getting citizen info") print(" --> CSR: " + csr.username) print(" --> json_data: " + json.dumps(json_data['service_request'])) if citizen is None: return {"message": "No matching citizen found for citizen_id"}, 400 service, message, code = get_service(service_request, json_data, csr) if (service is None): return {"message": message}, code # Find the currently active service_request and close it (if it exists) current_sr_number = 0 for req in citizen.service_reqs: if req.sr_state_id == active_sr_state.sr_state_id: req.sr_state_id = complete_sr_state.sr_state_id req.finish_service(csr, clear_comments=False) current_sr_number = req.sr_number db.session.add(req) service_request.sr_state_id = active_sr_state.sr_state_id # Only add ticket creation period and ticket number if it's their first service_request if len(citizen.service_reqs) == 0: period_state_ticket_creation = PeriodState.get_state_by_name( "Ticket Creation") ticket_create_period = Period( csr_id=csr.csr_id, reception_csr_ind=csr.receptionist_ind, ps_id=period_state_ticket_creation.ps_id, time_start=citizen.get_service_start_time(), time_end=datetime.now()) service_request.periods.append(ticket_create_period) # Move start_time back 6 hours to account for DST and UTC offsets # It's only important that the number carries over _around_ midnight offset_start_time = citizen.start_time - timedelta(hours=6) service_count = ServiceReq.query \ .join(ServiceReq.citizen, aliased=True) \ .filter(Citizen.start_time >= offset_start_time.strftime("%Y-%m-%d")) \ .filter_by(office_id=csr.office_id) \ .join(ServiceReq.service, aliased=True) \ .filter_by(prefix=service.prefix) \ .count() citizen.ticket_number = service.prefix + str(service_count) else: period_state_being_served = PeriodState.get_state_by_name( "Being Served") ticket_create_period = Period( csr_id=csr.csr_id, reception_csr_ind=csr.receptionist_ind, ps_id=period_state_being_served.ps_id, time_start=datetime.now()) service_request.periods.append(ticket_create_period) citizen.cs_id = active_id # If first service, just choose it. If additional service, more work needed. if len(citizen.service_reqs) == 0: snowplow_event = "chooseservice" else: snowplow_event = "additionalservice" service_request.sr_number = len(citizen.service_reqs) + 1 db.session.add(service_request) db.session.add(citizen) db.session.commit() # If first service, just need a choose service call. if snowplow_event == "chooseservice": SnowPlow.choose_service(service_request, csr, "chooseservice") # If not first service, need stop service, choose service, and additional service calls. else: SnowPlow.snowplow_event(citizen.citizen_id, csr, "stopservice", current_sr_number=current_sr_number) SnowPlow.choose_service(service_request, csr, "chooseservice") SnowPlow.snowplow_event( citizen.citizen_id, csr, "additionalservice", current_sr_number=service_request.sr_number) citizen_result = self.citizen_schema.dump(citizen) socketio.emit('update_active_citizen', citizen_result, room=csr.office_id) result = self.service_request_schema.dump(service_request) return { 'service_request': result, 'errors': self.service_request_schema.validate(service_request) }, 201
class CitizenLeft(Resource): service_request_schema = ServiceReqSchema(many=True) citizen_schema = CitizenSchema() clear_comments_flag = (os.getenv("THEQ_CLEAR_COMMENTS_FLAG", "True")).upper() == "TRUE" @oidc.accept_token(require_token=True) @api_call_with_retry def post(self, id): my_print("++> POST API call time before csr = statement: " + str(datetime.now())) csr = CSR.find_by_username(g.oidc_token_info['username']) my_print(" ++> Time before citizen = statement: " + str(datetime.now())) citizen = Citizen.query.filter_by(citizen_id=id).first() my_print(" ++> Time before citizen ID statement: " + str(datetime.now())) citizen_id_string = self.get_citizen_string(citizen) citizen_ticket = self.get_ticket_string(citizen) my_print(" ++> Time before citizen ticket statement: " + str(datetime.now())) my_print(" ++> POST /citizens/" + citizen_id_string + '/citizen_left/, Ticket: ' + citizen_ticket) my_print(" ++> Time before sr_state statement: " + str(datetime.now())) sr_state = SRState.get_state_by_name("Complete") # Create parameters for and make snowplow call. Default is no service request, CSR pressed cancel. quantity = 0 sr_number = 1 active_sr = 0 status = "service-creation" if len(citizen.service_reqs) != 0: active_service_request = citizen.get_active_service_request() quantity = active_service_request.quantity sr_number = active_service_request.sr_number active_sr = active_service_request.sr_id active_period = active_service_request.get_active_period() if active_period.ps.ps_name == "Invited": status = "at-prep" else: status = "being-served" my_print(" ++> Time before Snowplow call: " + str(datetime.now())) SnowPlow.snowplow_event(citizen.citizen_id, csr, ("left/" + status), quantity = quantity, current_sr_number= sr_number) my_print(" ++> Time before closing non-active service requests: " + str(datetime.now())) for service_request in citizen.service_reqs: service_request.sr_state_id = sr_state.sr_state_id for p in service_request.periods: if p.time_end is None: p.time_end = datetime.now() # Make snowplow calls to finish any stopped services if service_request.sr_id != active_sr: SnowPlow.snowplow_event(citizen.citizen_id, csr, "finishstopped", quantity = service_request.quantity, current_sr_number= service_request.sr_number) my_print(" ++> Time before updating citizen state: " + str(datetime.now())) citizen.cs = CitizenState.query.filter_by(cs_state_name='Left before receiving services').first() if self.clear_comments_flag: citizen.citizen_comments = None if citizen.start_time.date() != datetime.now().date(): citizen.accurate_time_ind = 0 my_print(" ++> Time before updating citizen database: " + str(datetime.now())) db.session.add(citizen) my_print(" ++> Time before database commit: " + str(datetime.now())) db.session.commit() my_print(" ++> Time before socket io invited call: " + str(datetime.now())) socketio.emit('citizen_invited', {}, room='sb-%s' % csr.office.office_number) my_print(" ++> Time before creating the result: " + str(datetime.now())) result = self.citizen_schema.dump(citizen) my_print(" ++> Time before socket io update call: " + str(datetime.now())) socketio.emit('update_active_citizen', result.data, room=csr.office_id) my_print(" ++> Time before return result call: " + str(datetime.now())) return {'citizen': result.data, 'errors': result.errors}, 200 def get_citizen_string(self, citizen): if citizen is not None: if citizen.citizen_id is not None: citizen_id_string = str(citizen.citizen_id) else: citizen_id_string = "No ID" else: citizen_id_string = "No citizen" return citizen_id_string def get_ticket_string(self, citizen): if citizen is not None: if citizen.ticket_number is not None: citizen_ticket = citizen.ticket_number else: citizen_ticket = "None" else: citizen_ticket = "No citizen" return citizen_ticket
class CitizenLeft(Resource): service_request_schema = ServiceReqSchema(many=True) citizen_schema = CitizenSchema() clear_comments_flag = (os.getenv("THEQ_CLEAR_COMMENTS_FLAG", "True")).upper() == "TRUE" @oidc.accept_token(require_token=True) @api_call_with_retry def post(self, id): csr = CSR.find_by_username(g.oidc_token_info['username']) citizen = Citizen.query.filter_by(citizen_id=id, office_id=csr.office_id).first() sr_state = SRState.get_state_by_name("Complete") # Create parameters for and make snowplow call. Default is no service request, CSR pressed cancel. quantity = 0 sr_number = 1 active_sr = 0 status = "service-creation" if len(citizen.service_reqs) != 0: active_service_request = citizen.get_active_service_request() quantity = active_service_request.quantity sr_number = active_service_request.sr_number active_sr = active_service_request.sr_id active_period = active_service_request.get_active_period() if active_period.ps.ps_name == "Invited": status = "at-prep" else: status = "being-served" SnowPlow.snowplow_event(citizen.citizen_id, csr, ("left/" + status), quantity = quantity, current_sr_number= sr_number) for service_request in citizen.service_reqs: service_request.sr_state_id = sr_state.sr_state_id for p in service_request.periods: if p.time_end is None: p.time_end = datetime.now() # Make snowplow calls to finish any stopped services if service_request.sr_id != active_sr: SnowPlow.snowplow_event(citizen.citizen_id, csr, "finishstopped", quantity = service_request.quantity, current_sr_number= service_request.sr_number) citizen.cs = CitizenState.query.filter_by(cs_state_name='Left before receiving services').first() if self.clear_comments_flag: citizen.citizen_comments = None if citizen.start_time.date() != datetime.now().date(): citizen.accurate_time_ind = 0 db.session.add(citizen) db.session.commit() socketio.emit('citizen_invited', {}, room='sb-%s' % csr.office.office_number) result = self.citizen_schema.dump(citizen) socketio.emit('update_active_citizen', result.data, room=csr.office_id) return {'citizen': result.data, 'errors': result.errors}, 200