示例#1
0
 async def create_for_affiliate(
         cls, affiliate_dni: str,
         consultation_data: ConsultationDTO) -> Consultation:
     """ Creates a new consultation for the given affiliate and returns it's id. """
     # Get petitioner object
     affiliate = await AffiliateDAO.find(affiliate_dni)
     if not affiliate:
         raise BusinessError(
             f'There is no affiliate with DNI {affiliate_dni}.', 404)
     # Get patient object
     patient = await AffiliateDAO.find(consultation_data.patient_dni)
     if not patient:
         raise BusinessError(
             f'There is no affiliate with DNI {patient.dni}.', 404)
     # If there is an ongoing call, return it's id
     consultation = await ConsultationDAO.affiliate_required_consultation(
         affiliate_dni)
     if consultation: return consultation
     # Create new consultation and store
     consultation_id = str(uuid.uuid4())
     consultation = Consultation(id=consultation_id,
                                 affiliate_dni=affiliate_dni,
                                 patient=patient,
                                 symptoms=ast.literal_eval(
                                     consultation_data.symptoms),
                                 reason=consultation_data.reason,
                                 patient_dni=consultation_data.patient_dni)
     await ConsultationDAO.store(consultation)
     # Return id for response
     return consultation
示例#2
0
 async def start_call(cls, doctor_id: str) -> str:
     """ Returns a call ID if there is any for the given doctor. """
     doctor = await DoctorDAO.find_by_id(doctor_id)
     if not doctor:
         raise BusinessError(f'There is no doctor with ID {doctor_id}.',
                             404)
     # There could be a consultation in progress (in which case we would return that same call_id)
     consultation = await ConsultationDAO.doctor_consultation_in_progress(
         doctor_id)
     if consultation: return consultation.call_id
     # If it is a new consultation, then we need to create the call
     consultation = await ConsultationDAO.next_consultation_waiting_call(
         doctor_id)
     # There may be no affiliate to talk with at the moment
     if not consultation:
         raise BusinessError(
             f'There is no consultation waiting for the given doctor.', 404)
     # Create a call id for the consultation
     call_id = str(uuid.uuid4())
     # Notify start of call to affiliate via socket
     socket_id = consultation.socket_id
     await SocketManager.notify_call_start(call_id, socket_id)
     # Notify start of call to affiliate via push notification
     affiliate = await AffiliateDAO.find(consultation.affiliate_dni)
     # TODO -> This if shouldn't be necessary, but it'll be here temporarily to avoid bugs
     if affiliate.device_id:
         NotificationService.notify_call_start(affiliate.device_id,
                                               doctor.last_name,
                                               affiliate.first_name)
     # Update consultation with new call id and IN_PROGRESS status
     consultation.status = ConsultationStatus.IN_PROGRESS
     consultation.call_id = call_id
     await ConsultationDAO.store(consultation)
     # Return the id of the call
     return call_id
 async def add(cls, doctor: Doctor):
     # Check if doctor with given dni exists
     if await DoctorDAO.find_by_dni(doctor.dni):
         raise BusinessError(
             f'Doctor with DNI {doctor.dni} already exists.', 409)
     # Check if doctor with given licence exists
     if await DoctorDAO.find_by_licence(doctor):
         raise BusinessError(
             f'Doctor with licence {doctor.licence} already exists.', 409)
     # Assign id and store new doctor
     doctor.id = str(uuid4())
     await DoctorDAO.store(doctor)
示例#4
0
 def map_modification(request_body: dict,
                      resource_id: str) -> ExampleResource:
     # Check if the request contains all needed fields
     if not resource_id:
         raise BusinessError('Resource ID is compulsory for this service.',
                             400)
     if not request_body:
         raise BusinessError(
             'Tried to update doctor with an empty patch body.', 400)
     # Create model object only with the elements that were received
     resource = ExampleResource(id=resource_id)
     if 'name' in request_body: resource.name = request_body['name']
     if 'value' in request_body: resource.value = request_body['value']
     return resource
 def map_modification(request_body: dict, doctor_id: str) -> Doctor:
     # Check if the request contains all needed fields
     if not doctor_id: raise BusinessError('Doctor ID is compulsory for this service.', 400)
     if not request_body: raise BusinessError('Tried to update doctor with an empty patch body.', 400)
     # Create model object only with the elements that were received
     doctor = Doctor(id=doctor_id)
     if 'dni' in request_body: doctor.dni = request_body['dni']
     if 'licence' in request_body: doctor.licence = request_body['licence']
     if 'first_name' in request_body: doctor.first_name = request_body['first_name']
     if 'last_name' in request_body: doctor.last_name = request_body['last_name']
     if 'email' in request_body: doctor.email = request_body['email']
     if 'centers' in request_body: doctor.centers = request_body['centers']
     if 'specialties' in request_body: doctor.specialties = request_body['specialties']
     if 'availability_times' in request_body: doctor.availability_times = request_body['availability_times']
     return doctor
 async def add(cls, resource: ExampleResource):
     # Check if resource with given id exists
     if await ExampleDAO.find(resource.id):
         raise BusinessError(
             f'Resource with ID {resource.id} already exists.', 409)
     # Store new resource
     await ExampleDAO.store(resource)
 async def retrieve(cls, resource_id: str) -> ExampleResource:
     """ Returns the doctor object associated to the given ID, if existent. """
     resource = await ExampleDAO.find(resource_id)
     if not resource:
         raise BusinessError(f'There is no resource with id {resource_id}.',
                             404)
     return resource
 async def update(cls, resource: ExampleResource):
     # Check if the resource to be modified exists
     if not await ExampleDAO.find(resource.id):
         raise BusinessError(f'There is no resource with id {resource.id}.',
                             404)
     # Modify resource
     await ExampleDAO.store(resource)
 async def retrieve(cls, doctor_id: str) -> Doctor:
     """ Returns the doctor object associated to the given ID, if existent. """
     doctor = await DoctorDAO.find_by_id(doctor_id)
     if not doctor:
         raise BusinessError(f'There is no doctor with id {doctor_id}.',
                             404)
     return doctor
示例#10
0
 async def do_request(cls):
     """ Example method to show how to call an external service. """
     try:
         client_response = await ExampleClientConnector.get_info_from_client()
     except ExampleClientError:
         raise BusinessError(f'Failed to retrieve the information from the client.')
     # Here you could do something with the response received from the client
     return client_response
 def map(request_body: dict) -> ConsultationDTO:
     for field in ['patient_dni', 'symptoms']:
         if field not in request_body:
             raise BusinessError(f'Invalid request. Missing field "{field}".', 400)
     return ConsultationDTO(
         symptoms=request_body['symptoms'],
         patient_dni=request_body['patient_dni'],
         reason=request_body.get('reason')
     )
 async def update_information(cls, doctor: Doctor):
     # Check if doctor to be modified exists
     db_doctor = await DoctorDAO.find_by_id(doctor.id)
     if not db_doctor:
         raise BusinessError(f'There is no doctor with id {doctor.id}.',
                             404)
     # Check if doctor with given dni exists
     if doctor.dni and db_doctor.dni != doctor.dni and await DoctorDAO.find_by_dni(
             doctor.dni):
         raise BusinessError(
             f'Doctor with DNI {doctor.dni} already exists.', 409)
     # Check if doctor with given licence exists
     if doctor.licence and db_doctor.licence != doctor.licence and await DoctorDAO.find_by_licence(
             doctor):
         raise BusinessError(
             f'Doctor with licence {doctor.licence} already exists.', 409)
     # Assign id and store new doctor
     await DoctorDAO.store(doctor)
示例#13
0
 async def next_consultation(cls,
                             doctor_id) -> Tuple[Consultation, Affiliate]:
     """ Returns a consultation that is waiting for a doctor. """
     doctor = await DoctorDAO.find_by_id(doctor_id)
     if not doctor:
         raise BusinessError(f'There are no doctors with ID {doctor_id}.',
                             404)
     consultation = await QueueManager.pop(doctor.specialties)
     if not consultation:
         raise BusinessError(
             'There are no consultations waiting for the given doctor.',
             404)
     # Update information
     consultation.doctor_id = doctor_id
     consultation.status = ConsultationStatus.WAITING_CALL
     await ConsultationDAO.store(consultation)
     # Get associated affiliate
     affiliate = await AffiliateDAO.find(consultation.affiliate_dni)
     # Return id
     return consultation, affiliate
示例#14
0
 def map(request_body: dict) -> AuthData:
     # Check correctness of request
     for field in ['user_id', 'password']:
         if field not in request_body:
             raise BusinessError(
                 f'Failed to map incoming request. Missing field with ID {field}',
                 400)
     # Do mapping
     return AuthData(user_id=request_body['user_id'],
                     password=request_body['password'],
                     device_id=request_body.get('token'))
 async def delete(self, resource_id):
     try:
         if not resource_id:
             raise BusinessError('No resource ID specified for deletion.')
         await ExampleCRUDService.remove(resource_id)
         # This service only returns an HTTP 200
         self.make_response(status_code=200)
     except BusinessError as be:
         self.make_error_response(be.status, be.message)
     except RuntimeError:
         self.make_error_response(500, self.INTERNAL_ERROR_MESSAGE)
示例#16
0
 async def get_doctor_consultations(
         cls, doctor_id: str) -> Tuple[List[Consultation], List[Affiliate]]:
     """ Returns all finished consultation of the given doctor. """
     if not await DoctorDAO.find_by_id(doctor_id):
         raise BusinessError(f'There is no doctor with ID {doctor_id}.',
                             404)
     consultations = await ConsultationDAO.all_doctor_consultations(
         doctor_id)
     affiliates = [
         await AffiliateDAO.find(consultation.patient_dni)
         for consultation in consultations
     ]
     return consultations, affiliates
示例#17
0
 async def all_consultations(
         cls,
         affiliate_dni: str) -> Tuple[List[Consultation], List[Doctor]]:
     """ Returns all the past consultations of the given affiliate. """
     if not await AffiliateDAO.find(affiliate_dni):
         raise BusinessError(
             f'There is no affiliate with DNI {affiliate_dni}.', 404)
     consultations = await ConsultationDAO.all_affiliate_consultations(
         affiliate_dni)
     doctors = [
         await DoctorDAO.find_by_id(consultation.doctor_id)
         for consultation in consultations
     ]
     return consultations, doctors
示例#18
0
 async def authenticate(cls,
                        auth_data: AuthData) -> Tuple[AuthData, object]:
     # Retrieve auth data from database
     fetched_data = await AuthenticationDAO.find(auth_data)
     # Check if user exists
     if not fetched_data:
         raise BusinessError(f'Unknown user with id {auth_data.user_id}',
                             404)
     # Validate password
     if fetched_data.password != auth_data.password:
         raise BusinessError(
             f'Invalid password for user {auth_data.user_id}', 413)
     if fetched_data.role == 'doctor':
         user_info = await DoctorDAO.find_by_dni(auth_data.user_id)
     elif fetched_data.role == 'affiliate':
         user_info = await AffiliateDAO.find(auth_data.user_id)
         await AffiliateDAO.store_device_id(user_info.dni,
                                            auth_data.device_id)
     else:
         # TODO -> This is for admin users
         user_info = None
     # Return related data found in database
     return fetched_data, user_info
示例#19
0
 async def put_doctors_opinion(cls, doctor_id: str, consultation_id: str,
                               opinion: ConsultationOpinion):
     """ Update a consultation with prescription and indications. """
     consultation = await cls.__get_doctor_consultation(
         doctor_id, consultation_id)
     # Check that the consultation belongs to the doctor
     if not consultation.doctor_id == doctor_id:
         raise BusinessError(
             f'Failed to match doctor ID to consultation ID.', 400)
     # Update and store
     consultation.prescription = opinion.prescription
     consultation.indications = opinion.indications
     consultation.status = ConsultationStatus.FINISHED
     await ConsultationDAO.store(consultation)
示例#20
0
 async def doctor_consultation(
         cls, doctor_id: str,
         consultation_id: str) -> Tuple[Consultation, Doctor, Affiliate]:
     """ Get consultation and check if doctor and consultation are related. """
     consultation = await cls.__get_doctor_consultation(
         doctor_id, consultation_id)
     # Check that the consultation belongs to the affiliate
     if not consultation.doctor_id == doctor_id:
         raise BusinessError(
             f'Failed to match affiliate DNI to consultation ID.', 404)
     # Get consultation doctor
     doctor = await DoctorDAO.find_by_id(consultation.doctor_id)
     # Get consultation patient
     patient = await AffiliateDAO.find(consultation.patient_dni)
     # Return both objects for mapping
     return consultation, doctor, patient
 def map_creation(request_body: dict) -> Doctor:
     # Check if the request contains all needed fields
     for field in Doctor.fields():
         if field not in request_body and field != 'id':
             raise BusinessError(f'Invalid resource creation request. Missing field {field}.', 400)
     # Create model object
     return Doctor(
         dni=request_body['dni'],
         licence=request_body['licence'],
         first_name=request_body['first_name'],
         last_name=request_body['last_name'],
         email=request_body['email'],
         centers=request_body['centers'],
         specialties=request_body['specialties'],
         availability_times=request_body['availability_times']
     )
示例#22
0
 async def __get_doctor_consultation(cls, doctor_id: str,
                                     consultation_id: str) -> Consultation:
     if not await DoctorDAO.find_by_id(doctor_id):
         raise BusinessError(f'There is no doctor with ID {doctor_id}.',
                             404)
     return await cls.__get_consultation(consultation_id)
示例#23
0
 async def __get_affiliate_consultation(
         cls, affiliate_dni: str, consultation_id: str) -> Consultation:
     if not await AffiliateDAO.find(affiliate_dni):
         raise BusinessError(
             f'There is no affiliate with DNI {affiliate_dni}.', 404)
     return await cls.__get_consultation(consultation_id)
 async def remove(cls, doctor_id: str):
     # Check if doctor with given id exists
     if not await DoctorDAO.find_by_id(doctor_id):
         raise BusinessError(f'There is no doctor with id {doctor_id}.',
                             404)
     await DoctorDAO.delete(doctor_id)
 async def remove(cls, resource_id: str):
     # Check if doctor with given id exists
     if not await ExampleDAO.find(resource_id):
         raise BusinessError(f'There is no resource with id {resource_id}.',
                             404)
     await ExampleDAO.delete(resource_id)
 def _parse_body(self):
     try:
         return MappingUtils.decode_request_body(self.request.body)
     except RuntimeError:
         raise BusinessError(f'Invalid request body {self.request.body}',
                             400)
示例#27
0
 async def __get_consultation(cls, consultation_id: str) -> Consultation:
     consultation = await ConsultationDAO.find(consultation_id)
     if not consultation:
         raise BusinessError(
             f'There is no consultation with ID {consultation_id}.', 404)
     return consultation
示例#28
0
 async def get(self, consultation_id):
     doctor_id = self.get_argument('doctor', None, True)
     if not doctor_id:
         raise BusinessError('Missing query parameter "doctor".', 400)
     await self.wrap_coroutine(self.__next_consultation,
                               **{'doctor_id': doctor_id})