示例#1
0
class CitizenList(Resource):

    citizen_schema = CitizenSchema()
    citizens_schema = CitizenSchema(many=True)

    @oidc.accept_token(require_token=True)
    def get(self):
        try:
            csr = CSR.query.filter_by(username=g.oidc_token_info['username'].
                                      split("idir/")[-1]).first()
            active_state = CitizenState.query.filter_by(
                cs_state_name="Active").first()
            citizens = Citizen.query.filter_by(office_id=csr.office_id, cs_id=active_state.cs_id) \
                .join(Citizen.service_reqs).all()
            result = self.citizens_schema.dump(citizens)
            return {'citizens': result.data, 'errors': result.errors}, 200

        except exc.SQLAlchemyError as e:
            print(e)
            return {'message': 'API is down'}, 500

    @oidc.accept_token(require_token=True)
    @api_call_with_retry
    def post(self):
        json_data = request.get_json()

        csr = CSR.query.filter_by(
            username=g.oidc_token_info['username'].split("idir/")[-1]).first()

        try:
            citizen = self.citizen_schema.load(json_data).data
            citizen.office_id = csr.office_id
            citizen.start_time = datetime.now()

        except ValidationError as err:
            print(err)
            return {"message": err.messages}, 422

        citizen_state = CitizenState.query.filter_by(
            cs_state_name="Active").first()
        citizen.cs_id = citizen_state.cs_id
        db.session.add(citizen)
        db.session.commit()

        SnowPlow.add_citizen(citizen, csr)

        # socketio.emit('update_customer_list', {})
        result = self.citizen_schema.dump(citizen)

        return {'citizen': result.data, 'errors': result.errors}, 201
示例#2
0
class CsrSelf(Resource):

    csr_schema = CSRSchema()
    citizen_schema = CitizenSchema(many=True)

    @oidc.accept_token(require_token=True)
    def get(self):
        try:
            csr = CSR.query.filter_by(username=g.oidc_token_info['username'].
                                      split("idir/")[-1]).first()
            active_sr_state = SRState.query.filter_by(sr_code='Active').first()

            active_citizens = Citizen.query \
                .join(Citizen.service_reqs) \
                .filter_by(sr_state_id=active_sr_state.sr_state_id) \
                .join(ServiceReq.periods) \
                .filter_by(csr_id=csr.csr_id) \
                .filter(Period.time_end.is_(None))

            result = self.csr_schema.dump(csr)
            active_citizens = self.citizen_schema.dump(active_citizens)

            return {
                'csr': result.data,
                'active_citizens': active_citizens.data,
                'errors': result.errors
            }

        except exc.SQLAlchemyError as e:
            print(e)
            return {'message': 'API is down'}, 500
class CitizenPlaceOnHold(Resource):

    citizen_schema = CitizenSchema()

    @oidc.accept_token(require_token=True)
    @api_call_with_retry
    def post(self, id):
        csr = CSR.query.filter_by(
            username=g.oidc_token_info['username'].split("idir/")[-1]).first()

        citizen = Citizen.query.filter_by(citizen_id=id,
                                          office_id=csr.office_id).first()
        active_service_request = citizen.get_active_service_request()

        if active_service_request is None:
            return {"message": "Citizen has no active service requests"}

        active_service_request.place_on_hold(csr)
        pending_service_state = SRState.query.filter_by(
            sr_code='Active').first()
        active_service_request.sr_state_id = pending_service_state.sr_state_id

        db.session.add(citizen)
        db.session.commit()

        socketio.emit('update_customer_list', {}, room=csr.office_id)
        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
示例#4
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
        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)
                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)

        citizen_obj = Citizen.query.get(service_request.citizen_id)
        citizen_obj.service_count = citizen_obj.service_count + 1

        db.session.commit()

        SnowPlow.choose_service(service_request, csr, "additionalservice")

        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
class CitizenBeginService(Resource):

    citizen_schema = CitizenSchema()

    @oidc.accept_token(require_token=True)
    @api_call_with_retry
    def post(self, id):
        lock = FileLock("lock/begin_citizen.lock")

        with lock:
            csr = CSR.find_by_username(g.oidc_token_info['username'])
            citizen = Citizen.query.filter_by(citizen_id=id,
                                              office_id=csr.office_id).first()
            pending_service_state = SRState.get_state_by_name("Active")

            active_service_request = citizen.get_active_service_request()

            if active_service_request is None:
                return {"message": "Citizen has no active service requests"}

            try:
                #  Get Snowplow call.
                active_period = active_service_request.get_active_period()
                snowplow_event = "beginservice"
                if active_period.ps.ps_name == "On hold":
                    snowplow_event = "invitefromhold"
                if active_period.ps.ps_name == "Waiting":
                    snowplow_event = "invitefromlist"

                active_service_request.begin_service(csr, snowplow_event)
            except TypeError:
                return {"message": "Citizen  has already been invited"}, 400

            active_service_request.sr_state_id = pending_service_state.sr_state_id

            db.session.add(citizen)
            db.session.commit()

            if snowplow_event != "beginservice":
                socketio.emit('update_customer_list', {}, room=csr.office_id)

            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
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")

        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()

        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()

        SnowPlow.snowplow_event(citizen.citizen_id, csr, "customerleft")

        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
class CitizenSpecificInvite(Resource):

    citizen_schema = CitizenSchema()

    @oidc.accept_token(require_token=True)
    @api_call_with_retry
    def post(self, id):
        lock = FileLock("lock/invite_citizen.lock")

        with lock:
            csr = CSR.query.filter_by(username=g.oidc_token_info['username'].
                                      split("idir/")[-1]).first()
            citizen = db.session.query(Citizen).with_lockmode(
                'update').filter_by(citizen_id=id).first()
            active_service_state = SRState.query.filter_by(
                sr_code='Active').first()

            active_service_request = citizen.get_active_service_request()

            if active_service_request is None:
                return {
                    "message": "Citizen has no active service requests"
                }, 400

            try:
                active_service_request.invite(csr)
            except TypeError:
                return {"message": "Citizen  has already been invited"}, 400

            active_service_request.sr_state_id = active_service_state.sr_state_id

            db.session.add(citizen)
            db.session.commit()

            socketio.emit('update_customer_list', {}, room=csr.office_id)
            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
示例#8
0
class CitizenDetail(Resource):

    citizen_schema = CitizenSchema()

    @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.citizen_schema.dump(citizen)
            return {'citizen': result.data,
                    'errors': result.errors}

        except exc.SQLAlchemyError as e:
            print(e)
            return {'message': 'API is down'}, 500

    @oidc.accept_token(require_token=True)
    @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.oidc_token_info['username'])
        citizen = Citizen.query.filter_by(citizen_id=id, office_id=csr.office_id).first()

        try:
            citizen = self.citizen_schema.load(json_data, instance=citizen, partial=True).data

        except ValidationError as err:
            return {'message': err.messages}, 422

        db.session.add(citizen)
        db.session.commit()

        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
示例#9
0
class CitizenLeft(Resource):

    service_request_schema = ServiceReqSchema(many=True)
    citizen_schema = CitizenSchema()

    @oidc.accept_token(require_token=True)
    @api_call_with_retry
    def post(self, id):

        csr = CSR.query.filter_by(
            username=g.oidc_token_info['username'].split("idir/")[-1]).first()
        citizen = Citizen.query.filter_by(citizen_id=id,
                                          office_id=csr.office_id).first()
        sr_state = SRState.query.filter_by(sr_code="Complete").first()

        #  Save this service for the Snowplow call later.
        active_service_request = citizen.get_active_service_request()

        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()

        citizen.cs = CitizenState.query.filter_by(
            cs_state_name='Left before receiving services').first()
        citizen.citizen_comments = None

        db.session.add(citizen)
        db.session.commit()

        SnowPlow.snowplow_event(citizen.citizen_id, csr, "customerleft")

        socketio.emit('update_customer_list', {}, room=csr.office_id)
        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
class ServiceRequestsDetail(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 put(self, id):
        json_data = request.get_json()

        if not json_data:
            return {
                'message': 'No input data received for updating citizen'
            }, 400

        csr = CSR.query.filter_by(
            username=g.oidc_token_info['username'].split("idir/")[-1]).first()

        service_request = ServiceReq.query.filter_by(sr_id=id) \
                .join(ServiceReq.citizen, aliased=True) \
                .filter_by(office_id=csr.office_id).first_or_404()
        try:
            service_request = self.service_request_schema.load(
                json_data, instance=service_request, partial=True).data

        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.data,
                      room=csr.office_id)

        return {'service_request': result.data, 'errors': result.errors}, 200
示例#11
0
class CitizenAddToQueue(Resource):

    citizen_schema = CitizenSchema()

    @oidc.accept_token(require_token=True)
    @api_call_with_retry
    def post(self, id):
        csr = CSR.query.filter_by(
            username=g.oidc_token_info['username'].split("idir/")[-1]).first()
        citizen = Citizen.query.filter_by(citizen_id=id,
                                          office_id=csr.office_id).first()
        active_service_request = citizen.get_active_service_request()

        if active_service_request is None:
            return {"message": "Citizen has no active service requests"}

        #  Figure out what Snowplow call to make.
        snowplow_call = "returntoqueue"
        if ((len(citizen.service_reqs) == 1)
                and (len(active_service_request.periods) == 1)):
            snowplow_call = "addtoqueue"

        active_service_request.add_to_queue(csr, snowplow_call)

        pending_service_state = SRState.query.filter_by(
            sr_code='Pending').first()
        active_service_request.sr_state_id = pending_service_state.sr_state_id

        db.session.add(citizen)
        db.session.commit()

        socketio.emit('update_customer_list', {}, room=csr.office_id)
        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
class CitizenFinishService(Resource):

    citizen_schema = CitizenSchema()

    @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()
        active_service_request = citizen.get_active_service_request()

        if active_service_request is None:
            return {"message": "Citizen has no active service requests"}

        quantity = active_service_request.quantity
        active_service_request.finish_service(csr)
        citizen_state = CitizenState.query.filter_by(
            cs_state_name="Received Services").first()
        citizen.cs_id = citizen_state.cs_id

        pending_service_state = SRState.get_state_by_name("Complete")
        active_service_request.sr_state_id = pending_service_state.sr_state_id

        db.session.add(citizen)
        db.session.commit()

        SnowPlow.snowplow_event(citizen.citizen_id,
                                csr,
                                "finish",
                                quantity=quantity)

        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
示例#13
0
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)
        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)
                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

        #  See whether first service, or next service.
        if len(citizen.service_reqs) == 0:
            snowplow_event = "chooseservice"
            citizen.service_count = 1
        else:
            snowplow_event = "additionalservice"
            citizen.service_count = citizen.service_count + 1

        db.session.add(service_request)
        db.session.add(citizen)
        db.session.commit()

        SnowPlow.choose_service(service_request, csr, snowplow_event)

        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 CitizenGenericInvite(Resource):

    citizen_schema = CitizenSchema()
    citizens_schema = CitizenSchema(many=True)

    @oidc.accept_token(require_token=True)
    @api_call_with_retry
    def post(self):

        lock = FileLock("lock/invite_citizen.lock")

        with lock:
            csr = CSR.find_by_username(g.oidc_token_info['username'])

            active_citizen_state = CitizenState.query.filter_by(
                cs_state_name='Active').first()
            waiting_period_state = PeriodState.get_state_by_name("Waiting")
            citizen = None

            try:
                qt_xn_csr_ind = request.get_json().get('qt_xn_csr_ind')
            except AttributeError:
                qt_xn_csr_ind = csr.qt_xn_csr_ind

            if qt_xn_csr_ind:
                citizen = Citizen.query \
                    .filter_by(qt_xn_citizen_ind=1, cs_id=active_citizen_state.cs_id, office_id=csr.office_id) \
                    .join(Citizen.service_reqs) \
                    .join(ServiceReq.periods) \
                    .filter_by(ps_id=waiting_period_state.ps_id) \
                    .filter(Period.time_end.is_(None)) \
                    .order_by(Citizen.priority, Citizen.citizen_id) \
                    .first()
            else:
                citizen = Citizen.query \
                    .filter_by(qt_xn_citizen_ind=0, cs_id=active_citizen_state.cs_id, office_id=csr.office_id) \
                    .join(Citizen.service_reqs) \
                    .join(ServiceReq.periods) \
                    .filter_by(ps_id=waiting_period_state.ps_id) \
                    .filter(Period.time_end.is_(None)) \
                    .order_by(Citizen.priority, Citizen.citizen_id) \
                    .first()

            # Either no quick txn citizens for the quick txn csr, or vice versa
            if citizen is None:
                citizen = Citizen.query \
                    .filter_by(cs_id=active_citizen_state.cs_id, office_id=csr.office_id) \
                    .join(Citizen.service_reqs) \
                    .join(ServiceReq.periods) \
                    .filter_by(ps_id=waiting_period_state.ps_id) \
                    .filter(Period.time_end.is_(None)) \
                    .order_by(Citizen.priority, Citizen.citizen_id) \
                    .first()

            if citizen is None:
                return {"message": "There is no citizen to invite"}, 400

            db.session.refresh(citizen)
            active_service_request = citizen.get_active_service_request()

            try:
                active_service_request.invite(csr, "invitecitizen")
            except TypeError:
                return {
                    "message": "Error inviting citizen. Please try again."
                }, 400

            active_service_state = SRState.get_state_by_name("Active")
            active_service_request.sr_state_id = active_service_state.sr_state_id

            db.session.add(citizen)
            db.session.commit()

            socketio.emit('update_customer_list', {}, room=csr.office_id)
            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
示例#15
0
from app import app, db
from flask import request
from flask import jsonify
from app.schemas import CitizenSchema, ImportSchema, ChangeCitizenSchema
from app.models import Imports, Citizens
from marshmallow import ValidationError
from sqlalchemy import func
import numpy as np
from sqlalchemy.exc import IntegrityError

import_schema = ImportSchema()
citizen_schema = CitizenSchema()
change_citizen_schema = ChangeCitizenSchema()


@app.route('/imports', methods=['POST'])
def imports():
    try:
        content = request.get_json()
        # Валидация
        import_obj = import_schema.load(content)
        # Сохраняем import и получаем import_id
        new_import = Imports()
        db.session.add(new_import)
        db.session.flush()
        db.session.refresh(new_import)

        # Сохраняем каждого горожанина
        for c in import_obj['citizens']:
            citizen = Citizens(**c)
            citizen.import_id = new_import.id