def _appointments_search(search_phrase, params): appointment_options = util.get(params, 'appointmentOptions', {}) advisor_uid = appointment_options.get('advisorUid') advisor_csid = appointment_options.get('advisorCsid') student_csid = appointment_options.get('studentCsid') topic = appointment_options.get('topic') limit = int(util.get(appointment_options, 'limit', 20)) offset = int(util.get(appointment_options, 'offset', 0)) date_from = appointment_options.get('dateFrom') date_to = appointment_options.get('dateTo') if not len(search_phrase) and not (advisor_uid or advisor_csid or student_csid or topic or date_from or date_to): raise BadRequestError('Invalid or empty search input') if advisor_csid and not advisor_uid: advisor_uid = get_uid_for_csid(app, advisor_csid) if date_from: try: datetime_from = util.localized_timestamp_to_utc( f'{date_from}T00:00:00') except ValueError: raise BadRequestError('Invalid dateFrom value') else: datetime_from = None if date_to: try: datetime_to = util.localized_timestamp_to_utc( f'{date_to}T00:00:00') + timedelta(days=1) except ValueError: raise BadRequestError('Invalid dateTo value') else: datetime_to = None if datetime_from and datetime_to and datetime_to <= datetime_from: raise BadRequestError('dateFrom must be less than dateTo') appointment_results = search_advising_appointments( search_phrase=search_phrase, advisor_uid=advisor_uid, student_csid=student_csid, topic=topic, datetime_from=datetime_from, datetime_to=datetime_to, offset=offset, limit=limit, ) return { 'appointments': appointment_results, }
def _notes_search(search_phrase, params): note_options = util.get(params, 'noteOptions', {}) author_csid = note_options.get('authorCsid') student_csid = note_options.get('studentCsid') topic = note_options.get('topic') limit = util.get(note_options, 'limit', 100) offset = util.get(note_options, 'offset', 0) date_from = note_options.get('dateFrom') date_to = note_options.get('dateTo') if not len(search_phrase) and not (author_csid or student_csid or topic or date_from or date_to): raise BadRequestError('Invalid or empty search input') if date_from: try: datetime_from = util.localized_timestamp_to_utc( f'{date_from}T00:00:00') except ValueError: raise BadRequestError('Invalid dateFrom value') else: datetime_from = None if date_to: try: datetime_to = util.localized_timestamp_to_utc( f'{date_to}T00:00:00') + timedelta(days=1) except ValueError: raise BadRequestError('Invalid dateTo value') else: datetime_to = None if datetime_from and datetime_to and datetime_to <= datetime_from: raise BadRequestError('dateFrom must be less than dateTo') notes_results = search_advising_notes( search_phrase=search_phrase, author_csid=author_csid, student_csid=student_csid, topic=topic, datetime_from=datetime_from, datetime_to=datetime_to, offset=int(offset), limit=int(limit), ) return { 'notes': notes_results, }
def get_scheduled(cls, dept_code, local_date, advisor_uid=None): date_str = local_date.strftime('%Y-%m-%d') start_of_today = localized_timestamp_to_utc(f'{date_str}T00:00:00') end_of_today = localized_timestamp_to_utc(f'{date_str}T23:59:59') query = cls.query.filter( and_( cls.scheduled_time >= start_of_today, cls.scheduled_time <= end_of_today, cls.appointment_type == 'Scheduled', cls.deleted_at == None, # noqa: E711 cls.dept_code == dept_code, ), ) if advisor_uid: query = query.filter(cls.advisor_uid == advisor_uid) return query.order_by(cls.scheduled_time).all()
def update_appointment(appointment_id): appointment = Appointment.find_by_id(appointment_id) if not appointment: raise ResourceNotFoundError('Unknown path') has_privilege = current_user.is_admin or appointment.dept_code in _dept_codes_with_scheduler_privilege() if not has_privilege: raise ForbiddenRequestError(f'You are unauthorized to manage {appointment.dept_code} appointments.') params = request.get_json() details = params.get('details', None) scheduled_time = params.get('scheduledTime', None) if scheduled_time: scheduled_time = localized_timestamp_to_utc(scheduled_time) student_contact_info = params.get('studentContactInfo', None) student_contact_type = params.get('studentContactType', None) topics = params.get('topics', None) appointment.update( details=process_input_from_rich_text_editor(details), scheduled_time=scheduled_time, student_contact_info=student_contact_info, student_contact_type=student_contact_type, topics=topics, updated_by=current_user.get_id(), ) api_json = appointment.to_api_json(current_user.get_id()) _put_student_profile_per_appointment([api_json]) return tolerant_jsonify(api_json)
def test_search_with_no_input_and_date(self, coe_advisor, client): """Notes and appointments search needs no input when date options are set.""" from boac import db, std_commit appointment = Appointment.find_by_id(2) appointment.created_at = util.localized_timestamp_to_utc( '2017-11-01T00:00:00') std_commit() db.session.refresh(appointment) response = client.post( '/api/search', data=json.dumps({ 'appointments': True, 'notes': True, 'searchPhrase': '', 'appointmentOptions': { 'dateFrom': '2017-11-01', 'dateTo': '2017-11-02' }, 'noteOptions': { 'dateFrom': '2017-11-01', 'dateTo': '2017-11-02' }, }), content_type='application/json', ) self._assert(response, note_count=4, appointment_count=1)
def get_drop_in_waitlist(cls, dept_code, statuses=()): local_today = localize_datetime(datetime.now()).strftime('%Y-%m-%d') start_of_today = localized_timestamp_to_utc(f'{local_today}T00:00:00') criterion = and_( cls.created_at >= start_of_today, cls.appointment_type == 'Drop-in', cls.status.in_(statuses), cls.deleted_at == None, # noqa: E711 cls.dept_code == dept_code, ) return cls.query.filter(criterion).order_by(cls.created_at).all()
def test_search_respects_date_filters(self, app, coe_advisor, client): """Search results include appointments created within provided date range.""" from boac import std_commit appointment = Appointment.find_by_id(2) appointment.created_at = util.localized_timestamp_to_utc( '2017-10-31T00:00:00') std_commit(allow_test_environment=True) api_json = _api_search( client, 'pick me', appointments=True, appointment_options={ 'dateFrom': '2017-10-31', 'dateTo': '2017-11-01', }, ) self._assert(api_json, appointment_count=1)
def test_appointment_search_with_no_input_and_date(self, coe_advisor, client): """Appointments search needs no input when date options are set.""" from boac import db, std_commit appointment = Appointment.find_by_id(2) appointment.created_at = util.localized_timestamp_to_utc( '2017-11-01T00:00:00') std_commit() db.session.refresh(appointment) api_json = _api_search( client, '', appointments=True, appointment_options={ 'dateFrom': '2017-11-01', 'dateTo': '2017-11-02' }, ) self._assert(api_json, appointment_count=3)
def create_appointment(): params = request.get_json() dept_code = params.get('deptCode', None) sid = params.get('sid', None) appointment_type = params.get('appointmentType', None) topics = params.get('topics', None) if not dept_code or not sid or not appointment_type or not len(topics): raise BadRequestError('Appointment creation: required parameters were not provided') dept_code = dept_code.upper() if dept_code not in BERKELEY_DEPT_CODE_TO_NAME: raise ResourceNotFoundError(f'Unrecognized department code: {dept_code}') if dept_code not in _dept_codes_with_scheduler_privilege(): raise ForbiddenRequestError(f'You are unauthorized to manage {dept_code} appointments.') advisor_attrs = None advisor_uid = params.get('advisorUid') if advisor_uid: advisor_attrs = _advisor_attrs_for_uid(advisor_uid) if not advisor_attrs: raise BadRequestError('Invalid "advisorUid"') details = params.get('details', None) scheduled_time = params.get('scheduledTime', None) if scheduled_time: scheduled_time = localized_timestamp_to_utc(scheduled_time) student_contact_info = params.get('studentContactInfo', None) student_contact_type = params.get('studentContactType', None) appointment = Appointment.create( advisor_attrs=advisor_attrs, appointment_type=appointment_type, created_by=current_user.get_id(), dept_code=dept_code, details=process_input_from_rich_text_editor(details), scheduled_time=scheduled_time, student_contact_info=student_contact_info, student_contact_type=student_contact_type, student_sid=sid, topics=topics, ) AppointmentRead.find_or_create(current_user.get_id(), appointment.id) api_json = appointment.to_api_json(current_user.get_id()) _put_student_profile_per_appointment([api_json]) return tolerant_jsonify(api_json)
def test_search_respects_date_filters(self, coe_advisor, client): """Search results include notes and appointments updated within provided date range.""" from boac import std_commit appointment = Appointment.find_by_id(2) appointment.updated_at = util.localized_timestamp_to_utc( '2017-10-31T00:00:00') std_commit(allow_test_environment=True) response = client.post( '/api/search', data=json.dumps({ 'appointments': True, 'notes': True, 'searchPhrase': 'making', 'noteOptions': { 'dateFrom': '2017-10-31', 'dateTo': '2017-11-01', }, }), content_type='application/json', ) self._assert(response, note_count=1, appointment_count=2, note_ids=['11667051-00001'])
def _param_to_utc_date(key): value = (params.get(key) or '').strip() return localized_timestamp_to_utc( value, date_format='%m/%d/%Y') if value else None