示例#1
0
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
示例#2
0
    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
示例#4
0
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
示例#5
0
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
示例#8
0
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
示例#12
0
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
示例#13
0
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