예제 #1
0
def test_handle_extra_filters(teacher):
    new_user = User.create(email="[email protected]",
                           password="******",
                           name="absolutely",
                           area="nope")
    student = Student.create(teacher=teacher,
                             creator=teacher.user,
                             user=new_user)

    def custom_filter(model, key, value):
        return getattr(model, key) == value

    extra_filters = {User: {"area": custom_filter}}
    new_student = Student._handle_extra_filters(
        query=Student.query, args={
            "area": "npe"
        }, extra_filters=extra_filters).first()
    assert not new_student
    new_student = Student._handle_extra_filters(
        query=Student.query,
        args={
            "area": "nope"
        },
        extra_filters=extra_filters).first()
    assert new_student == student
예제 #2
0
def get_data(data: dict, user: User, appointment: Optional[Appointment] = None) -> dict:
    """get request data and a specific user
    - we need the user because we are not decorated in login_required here
    returns dict of new lesson or edited lesson"""
    try:
        date = datetime.strptime(data.get("date"), DATE_FORMAT).replace(
            second=0, microsecond=0
        )
    except (ValueError, TypeError):
        raise RouteError("Date is not valid.")
    if appointment:
        type_ = appointment.type
    else:
        type_ = None

    duration = data.get("duration")
    if not duration:
        raise RouteError("Duration is required.")
    duration = int(duration)
    if user.student:
        student = user.student
        teacher = user.student.teacher
        type_ = type_ or AppointmentType.LESSON
        if date < datetime.utcnow():
            # trying to add a new lesson in the past??
            raise RouteError("Date is not valid.")
        check_available_hours_for_student(date, student, appointment, duration)
    elif user.teacher:
        type_ = getattr(
            AppointmentType,
            data.get("type", "").upper(),
            type_ or AppointmentType.LESSON,
        )
        handle_teacher_hours(user.teacher, date, duration, type_, appointment)
        teacher = user.teacher
        student = Student.get_by_id(data.get("student_id"))
        if not student:
            raise RouteError("Student does not exist.")
    else:
        raise RouteError("Not authorized.", 401)

    meetup, dropoff = handle_places(data, student, appointment)
    try:
        price = int(data.get("price", ""))
    except ValueError:
        price = None
    return {
        "date": date,
        "meetup_place": meetup,
        "dropoff_place": dropoff,
        "student": student,
        "teacher": teacher,
        "duration": duration,
        "price": price,
        "comments": data.get("comments"),
        "is_approved": True if user.teacher else False,
        "type": type_,
    }
예제 #3
0
def test_invalid_update_topics(auth, meetup, dropoff, teacher, requester,
                               topic, student_id, topics, error):
    auth.login(email=teacher.user.email)
    date = tomorrow.replace(hour=13, minute=00)
    student = Student.get_by_id(student_id) if student_id else None
    lesson = create_lesson(teacher, student, meetup, dropoff, date)
    resp = requester.post(f"/appointments/{lesson.id}/topics",
                          json={"topics": topics})
    assert resp.status_code == 400
    assert resp.json["message"] == error
예제 #4
0
def deactivate(student_id):
    student = Student.get_by_id(student_id)
    if not student:
        raise RouteError("Student does not exist.", 404)

    if student.teacher != current_user.teacher:
        raise RouteError("Not authorized.", 401)

    student.update(is_active=False)
    return {"data": student.to_dict()}
예제 #5
0
def delete_student(student_id):
    student = Student.get_by_id(student_id)
    if not student:
        raise RouteError("Student does not exist.", 404)
    if student.appointments.first():  # if any lessons exist
        raise RouteError("Can't delete student.")

    if current_user != student.teacher.user:
        raise RouteError("Not authorized.", 401)

    student.delete()
    return {"message": "Student deleted."}
예제 #6
0
파일: teacher.py 프로젝트: zhmkof/Dryvo
def students():
    """allow filtering by name / area of student, and sort by balance,
    lesson number"""
    try:
        query = current_user.teacher.students
        args = flask.request.args
        extra_filters = {User: {"name": like_filter, "area": like_filter}}
        return Student.filter_and_sort(args,
                                       query,
                                       extra_filters=extra_filters,
                                       with_pagination=True)
    except ValueError:
        raise RouteError("Wrong parameters passed.")
예제 #7
0
def test_students(auth, teacher, requester):
    new_user = User.create(
        email="[email protected]", password="******", name="absolutely", area="nope"
    )
    new_student = Student.create(teacher=teacher, creator=teacher.user, user=new_user)
    auth.login(email=teacher.user.email)
    resp = requester.get("/teacher/students?order_by=balance desc")
    assert resp.json["data"][1]["student_id"] == new_student.id
    resp = requester.get("/teacher/students?name=solut")
    assert resp.json["data"][0]["student_id"] == new_student.id
    resp = requester.get("/teacher/students?name=le:no way")
    assert not resp.json["data"]
    resp = requester.get("/teacher/students?limit=1")
    assert len(resp.json["data"]) == 1
예제 #8
0
def test_delete_student(auth, requester, student, teacher):
    auth.login(email=teacher.user.email)
    resp = requester.delete(f"/student/{student.id}")
    assert "Can't delete" in resp.json["message"]
    student_user = User.create(email="*****@*****.**",
                               password="******",
                               name="student",
                               area="test")
    new_student = Student.create(user=student_user,
                                 teacher=teacher,
                                 creator=teacher.user,
                                 is_approved=True)
    resp = requester.delete(f"/student/{new_student.id}")
    assert "deleted" in resp.json["message"]
예제 #9
0
def approve(student_id):
    student = Student.get_by_id(student_id)
    if not student:
        raise RouteError("Student does not exist.", 404)

    if current_user != student.creator and (
            current_user.teacher == student.teacher
            or current_user.student == student or current_user.is_admin):
        # only allow approving for the user himself or
        # the teacher that is requested. don't allow for the requester to approve.
        student.update(is_approved=True)
        return {"data": student.to_dict()}

    raise RouteError("Not authorized.", 401)
예제 #10
0
def make_student():
    data = flask.request.args
    user = current_user
    teacher = Teacher.get_by_id(data.get("teacher_id"))
    if current_user.teacher:
        user = User.get_by_id(data.get("user_id"))
        teacher = current_user.teacher

    if not user:
        raise RouteError("User was not found.", 401)
    if user.teacher or user.student:
        raise RouteError("User is already a student or a teacher.")

    if not teacher:
        raise RouteError("Teacher was not found.")

    try:
        price = int(data.get("price", ""))
    except ValueError:
        price = None
    student = Student.create(user=user,
                             teacher=teacher,
                             creator=current_user,
                             price=price)
    # send notification
    user_to_send_to = student.user
    body_text = gettext("%(teacher)s added you as a student!",
                        teacher=teacher.user.name)
    if student.creator == user_to_send_to:
        user_to_send_to = teacher.user
        body_text = gettext("%(student)s added you as a teacher!",
                            student=student.user.name)
    if user_to_send_to.firebase_token:
        logger.debug(f"sending fcm to {user_to_send_to}")
        try:
            FCM.notify(
                token=user_to_send_to.firebase_token,
                title=gettext("Join Request"),
                body=body_text,
            )
        except:
            pass
    return {"data": student.to_dict()}, 201
예제 #11
0
파일: teacher.py 프로젝트: zhmkof/Dryvo
def create_bot_student():
    teacher = current_user.teacher
    data = flask.request.values
    user = create_user_from_data(data, required=["email", "name", "phone"])
    car = teacher.cars.filter_by(id=data.get("car_id")).first()
    if not car:
        raise RouteError("Car does not exist.")
    try:
        price = int(data.get("price", ""))
    except ValueError:
        price = None
    student = Student.create(
        user=user,
        teacher=teacher,
        creator=current_user,
        price=price,
        car=car,
        is_approved=True,
    )

    return {"data": student.user.to_dict()}, 201
예제 #12
0
def topics(student_id: int):
    """show topics by: finished, unfinished or haven't started"""
    student = Student.get_by_id(student_id)
    if not student:
        raise RouteError("Student does not exist.", 404)
    finished_topics = [
        topic.to_dict() for topic in student.topics(is_finished=True)
    ]
    in_progress_topics = [
        topic.to_dict() for topic in student.topics(is_finished=False)
    ]
    new_topics = [
        topic.to_dict() for topic in Topic.query.all()
        if topic.to_dict() not in in_progress_topics
        and topic.to_dict() not in finished_topics
    ]
    return {
        "data": {
            "finished": finished_topics,
            "in_progress": in_progress_topics,
            "new": new_topics,
        }
    }
예제 #13
0
파일: teacher.py 프로젝트: zhmkof/Dryvo
def add_payment():
    data = flask.request.get_json()
    student = Student.get_by_id(data.get("student_id"))
    amount = data.get("amount")
    details = data.get("details")
    if not student:
        raise RouteError("Student does not exist.")
    if not amount:
        raise RouteError("Amount must not be empty.")
    if not details:
        raise RouteError("Details must not be empty.")

    payment = Payment.create(
        teacher=current_user.teacher,
        student=student,
        amount=amount,
        payment_type=getattr(PaymentType, data.get("payment_type", ""), 1),
        details=details,
        crn=int(data.get("crn")) if data.get("crn") else None,
    )
    # send notification to student
    if student.user.firebase_token:
        logger.debug(f"sending fcm to {student.user} for new payment")
        try:
            FCM.notify(
                token=student.user.firebase_token,
                title=gettext("New Payment"),
                body=gettext(
                    "%(user)s charged you for %(amount)s",
                    user=current_user.name,
                    amount=amount,
                ),
            )
        except NotificationError:
            pass
    return {"data": payment.to_dict()}, 201
예제 #14
0
def edit_student(student_id):
    student = Student.get_by_id(student_id)
    if not student:
        raise RouteError("Student does not exist.", 404)

    if (current_user.teacher and student.teacher == current_user.teacher) or (
            current_user.student and current_user.student == student):
        data = flask.request.values
        image = flask.request.files.get("green_form")
        extra_data = dict()
        if (current_user.teacher
            ):  # only teacher is allowed to edit num of lessons and theory
            try:
                price = int(data.get("price", ""))
            except ValueError:
                price = None
            car = current_user.teacher.cars.filter_by(
                id=data.get("car_id")).first()
            if not car:
                raise RouteError("Car does not exist.")
            extra_data = dict(
                theory=data.get("theory", False) == "true",
                number_of_old_lessons=float(
                    data.get("number_of_old_lessons", 0)),
                car=car,
                price=price,
            )
        if image:
            extra_data["green_form"] = upload(image)["public_id"]
        student.update(doctor_check=data.get("doctor_check", False) == "true",
                       eyes_check=data.get("eyes_check", False) == "true",
                       id_number=data.get("id_number"),
                       **extra_data)
        return {"data": student.user.to_dict()}

    raise RouteError("Not authorized.", 401)
예제 #15
0
파일: conftest.py 프로젝트: zhmkof/Dryvo
def setup_db(app):
    User.create(email="*****@*****.**",
                password="******",
                name="test",
                area="test",
                phone="044444444")
    User.create(
        email="*****@*****.**",
        password="******",
        name="admin",
        area="test",
        is_admin=True,
        phone="055555555",
    )
    teacher_user = User.create(email="*****@*****.**",
                               password="******",
                               name="teacher",
                               area="test")
    teacher = Teacher.create(
        user=teacher_user,
        price=100,
        lesson_duration=40,
        is_approved=True,
        crn=999999999,
        invoice_api_key=DEMO_API_KEY,
    )
    Car.create(teacher=teacher, number=1111111111)
    student_user = User.create(email="*****@*****.**",
                               password="******",
                               name="student",
                               area="test")
    student = Student.create(user=student_user,
                             teacher=teacher,
                             creator=teacher.user,
                             is_approved=True)
    meetup = Place.create(
        description="test",
        used_as=PlaceType.meetup.value,
        student=student,
        google_id="ID1",
    )
    dropoff = Place.create(
        description="test",
        used_as=PlaceType.dropoff.value,
        student=student,
        google_id="ID2",
    )
    WorkDay.create(
        teacher=teacher,
        day=1,
        from_hour=0,
        to_hour=23,
        to_minutes=59,
        on_date=(datetime.utcnow() + timedelta(days=2)).date(),
    )  # 2 days from now
    Topic.create(title="topic test", min_lesson_number=1, max_lesson_number=5)
    Appointment.create(
        teacher=teacher,
        student=student,
        # schedule to 5 days from now to it won't bother with no test
        creator=teacher.user,
        duration=40,
        date=(datetime.utcnow() + timedelta(days=5)),
        meetup_place=meetup,
        dropoff_place=dropoff,
    )