def book_appointment(db: PeeweeSession, body: hug.types.json, user: hug.directives.user):
    with db.atomic():
        try:
            assert user.coupons > 0
            if all(key in body for key in ('claim_token', 'start_date_time', 'first_name', 'name', 'phone', 'office')):
                claim_token = body['claim_token']
                start_date_time = body['start_date_time']
                start_date_time_object = datetime.fromisoformat(start_date_time)
                now = datetime.now(tz=config.Settings.tz).replace(tzinfo=None)
                if start_date_time_object < now:
                    raise ValueError("Can't claim an appointment in the past")
                time_slot = TimeSlot.get(TimeSlot.start_date_time == start_date_time_object)
                appointment = Appointment.get(
                    (Appointment.time_slot == time_slot) &
                    (Appointment.booked == False) &
                    (Appointment.claim_token == claim_token)
                )
                appointment.booked = True
                appointment.claim_token = None
                appointment.claimed_at = None
                appointment.save()
                success = False
                with db.atomic():
                    while not success:
                        secret = get_secret_token(6)
                        try:
                            SlotCode.create(date=time_slot.start_date_time.date(), secret=secret)
                            success = True
                        except IntegrityError as e:  # in the offchance that we had a collision with secret codes, retry
                            pass

                booking = Booking.create(appointment=appointment, first_name=body['first_name'], surname=body['name'],
                                         phone=body['phone'], office=body['office'], secret=secret,
                                         booked_by=user.user_name)
                booking.save()
                user.coupons -= 1
                user.save()
                return {
                    "secret": booking.secret,
                    "time_slot": time_slot.start_date_time,
                    "slot_length_min": time_slot.length_min
                }
            else:
                raise ValueError("Missing parameter")
        except DoesNotExist as e:
            raise hug.HTTPGone
        except ValueError as e:
            raise hug.HTTPBadRequest
        except AssertionError as e:
            raise hug.HTTPBadRequest
Exemple #2
0
def booked(db: PeeweeSession, user: hug.directives.user, start_date: hug.types.text,
           end_date: hug.types.text):
    user_name = user.user_name
    with db.atomic():
        try:
            user_role = user.role
            start_day_object = date.fromisoformat(start_date)
            end_day_object = date.fromisoformat(end_date)
            if user_role != UserRoles.ADMIN:
                start_day_object = date.fromisoformat('2021-01-01') #FIXME: hack to show users all their bookings
                end_day_object = date.fromisoformat('2022-12-31') #FIXME: hack to show users all their bookings
            bookings = []
            for timeslot in TimeSlot.select().where((TimeSlot.start_date_time >= start_day_object) &
                                                    (TimeSlot.start_date_time < end_day_object + timedelta(days=1))) \
                    .order_by(TimeSlot.start_date_time.desc()):
                for appointment in Appointment.select().where(
                        (Appointment.time_slot == timeslot) & (Appointment.booked == True)):
                    try:
                        booking = Booking.get(
                            Booking.appointment == appointment)
                        if user_role != UserRoles.ADMIN:
                            booking = Booking.select().where((Booking.appointment == appointment) &
                                                             (Booking.booked_by == user_name)).get()
                        bookings.append({'start_date_time': timeslot.start_date_time, 'first_name': booking.first_name,
                                         'surname': booking.surname, 'phone': booking.phone, 'office': booking.office,
                                         'secret': booking.secret, 'booked_by': booking.booked_by,
                                         'booked_at': booking.booked_at, 'booking_id': booking.get_id()})
                    except DoesNotExist as e:
                        pass
            return bookings
        except DoesNotExist as e:
            raise hug.HTTPGone
        except ValueError as e:
            raise hug.HTTPBadRequest
def cancel_booking(db: directives.PeeweeSession,
                   secret: hug.types.text,
                   start_date_time: hug.types.text,
                   for_real: hug.types.smart_boolean = False):
    with db.atomic():
        sdt = datetime.fromisoformat(start_date_time).replace(tzinfo=None)
        timeslot = TimeSlot.get(TimeSlot.start_date_time == sdt)
        booking = Booking.select(Booking).join(
            Appointment).where((Booking.secret == secret)
                               & (Appointment.time_slot == timeslot)).get()

        if not for_real:
            print(
                f"This would delete the booking with id '{booking.id}' and secret '{booking.secret}'. Run with "
                f"--for_real if you are sure.")
            sys.exit(1)
        else:
            print(
                f"Deleting the booking with id '{booking.id}' and secret '{booking.secret}'."
            )
            booking.appointment.booked = False
            booking.appointment.save()
            q = Booking.delete().where(Booking.id == booking.id)
            q.execute()
            print("Done.")
def set_frontend_config(db: directives.PeeweeSession, instance_name: hug.types.text, long_instance_name: hug.types.text,
                        contact_info_bookings: hug.types.text, contact_info_appointments: hug.types.text = None,
                        form_fields: hug.types.text = "base,address,dayOfBirth,reason",
                        for_real: hug.types.smart_boolean = False):
    with db.atomic():

        if not contact_info_appointments:
            appointments_contact = contact_info_bookings
        else:
            appointments_contact = contact_info_appointments

        template = {
            "instanceName": f"{instance_name}",
            "longInstanceName": f"{long_instance_name}",
            "contactInfoCoupons": f"{contact_info_bookings}",
            "contactInfoAppointment": f"{appointments_contact}",
            "formFields": form_fields.split(","),
        }

        if not for_real:
            print(f"This would update the config with '{json.dumps(template, indent=2)}'. Run with --for_real if you "
                  f"are sure.")
            sys.exit(1)
        else:
            print(
                f"Updating the config with '{json.dumps(template, indent=2)}'.")
            try:
                config = FrontendConfig.get()
                config.config = template
            except FrontendConfig.DoesNotExist:
                config = FrontendConfig.create(config=template)

            config.save()
            print("Done.")
def load_frontend_config(db: directives.PeeweeSession, frontend_config_file: hug.types.text,
                         for_real: hug.types.smart_boolean = False):
    with db.atomic():
        with open(frontend_config_file, 'r') as j_file:
            try:
                new_config = json.load(j_file)
                if 'instanceName' not in new_config or 'longInstanceName' not in new_config or \
                        'contactInfoCoupons' not in new_config \
                        or 'contactInfoAppointment' not in new_config or 'formFields' not in new_config:
                    print(
                        f"Given file '{json.dumps(new_config, indent=2)}' missing required fields!")
                    sys.exit(1)
                elif type(new_config['formFields']) != list:
                    print("field formFields is not a list!")
                    sys.exit(1)
            except json.JSONDecodeError as e:
                print("The file can not decoded as json!")
                sys.exit(1)

            if not for_real:
                print(
                    f"This would update the config with '{json.dumps(new_config, indent=2)}'. "
                    f"Run with --for_real if you are sure.")
                sys.exit(1)
            else:
                print(
                    f"Updating the config with '{json.dumps(new_config, indent=2)}'.")
                try:
                    config = FrontendConfig.get()
                    config.config = new_config
                except FrontendConfig.DoesNotExist:
                    config = FrontendConfig.create(config=new_config)

                config.save()
                print("Done.")
def init_database(db: PeeweeSession):
    log.info("Initializing the Database")
    with db.atomic():
        db_proxy.create_tables(tables)
        log.info("Tables created. Setting migration level.")
        Migration.create(version=2)
        log.info("Migration level set.")
def get_bookings_created_at(db: directives.PeeweeSession, booked_at: hug.types.text):
    """
    [--booked_at <ISO datetime string>] get all bookings made at specific day or time
    Get bookings for a day with yyyy-mm-dd or one specific booking at yyyy-mm-ddThh:mm:ss.mmmmmm
    """
    with db.atomic():
        query = Booking.select(
            Booking,
            Appointment.time_slot.start_date_time.alias("start_date_time")
        ).join(Appointment).join(TimeSlot)

        booked_start = datetime.fromisoformat(booked_at).replace(tzinfo=None)

        if str(booked_start.date()) == booked_at:
            # booked_at is yyyy-mm-dd
            booked_end = booked_start.date() + timedelta(days=1)
            bookings = query.where(
                Booking.booked_at.between(booked_start, booked_end))
        else:
            # booked_at is yyyy-mm-ddThh:mm:ss.mmmmmm
            bookings = query.where(Booking.booked_at == booked_start)

        result = []
        for booking in bookings.dicts().iterator():
            del booking["appointment"]
            result.append({**booking})

        return result
def list_for_day(db: PeeweeSession, user: hug.directives.user,
                 date_of_day: hug.types.text = None):
    if not date_of_day:
        date_of_day = (date.today() + timedelta(days=1)).isoformat()
    user_name = user.user_name
    with db.atomic():
        try:
            user_role = user.role
            requested_day_object = date.fromisoformat(date_of_day)
            result = io.StringIO()
            writer = csv.DictWriter(result,
                                    fieldnames=['start_date_time', 'first_name', 'surname', 'phone', 'office', 'secret',
                                                'booked_by'])
            writer.writeheader()
            for timeslot in TimeSlot.select().where(
                    (TimeSlot.start_date_time > requested_day_object - timedelta(days=1)) &
                    (TimeSlot.start_date_time < requested_day_object + timedelta(days=1))):
                for appointment in Appointment.select().where(
                        (Appointment.time_slot == timeslot) & (Appointment.booked == True)):
                    try:
                        booking = Booking.get(Booking.appointment == appointment)
                        if user_role != UserRoles.ADMIN:
                            booking = Booking.select().where((Booking.appointment == appointment) &
                                                             (Booking.booked_by == user_name)).get()

                        writer.writerow({'start_date_time': timeslot.start_date_time, 'first_name': booking.first_name,
                                         'surname': booking.surname, 'phone': booking.phone, 'office': booking.office,
                                         'secret': booking.secret, 'booked_by': booking.booked_by})
                    except DoesNotExist as e:
                        pass
            return result.getvalue().encode('utf8')
        except DoesNotExist as e:
            raise hug.HTTPGone
        except ValueError as e:
            raise hug.HTTPBadRequest
def set_coupon_count(db: directives.PeeweeSession, user_name: hug.types.text, value: hug.types.number):
    """
    [--user_name] <string> [--value] <number>; set the user coupon_count to <value>
    """
    with db.atomic():
        user = User.get(User.user_name == user_name)
        user.coupons = value
        user.save()
def inc_coupon_count(db: directives.PeeweeSession, user_name: hug.types.text, increment: hug.types.number):
    """
    [--user_name] <string> [--increment] <number>; increment the user coupon_count, to decrement give a negative number
    """
    with db.atomic():
        user = User.get(User.user_name == user_name)
        user.coupons += increment
        user.save()
Exemple #11
0
def delete_claim_token(db: PeeweeSession, claim_token: hug.types.text):
    with db.atomic():
        try:
            appointment = Appointment.get((Appointment.booked == False) & (
                Appointment.claim_token == claim_token))
            appointment.claim_token = None
            appointment.claimed_at = None
            appointment.save()
        except DoesNotExist as e:
            pass
        except ValueError as e:
            pass
def _add_one_user(db: directives.PeeweeSession, username: hug.types.text, password: hug.types.text = None,
                  role: hug.types.one_of(UserRoles.user_roles()) = UserRoles.USER,
                  coupons: hug.types.number = 10):
    with db.atomic():
        name = username.lower()
        salt = get_random_string(2)
        secret_password = password or get_random_string(12)
        hashed_password = hash_pw(name, salt, secret_password)
        user = User.create(user_name=name, role=role, salt=salt,
                           password=hashed_password, coupons=coupons)
        user.save()
        return {"name": user.user_name, "password": secret_password}
def delete_timeslots(db: directives.PeeweeSession,
                     year: hug.types.number,
                     month: hug.types.number,
                     day: hug.types.number,
                     start_hour: hug.types.number,
                     start_min: hug.types.number,
                     num_slots: hug.types.number,
                     for_real: hug.types.boolean = False):
    with db.atomic():
        dto = datetime(year, month, day, start_hour, start_min, tzinfo=None)
        tomorrow = datetime(year, month, day, tzinfo=None) + timedelta(days=1)
        ts = TimeSlot.select().where((TimeSlot.start_date_time >= dto) & (
            TimeSlot.start_date_time < tomorrow)).order_by(
                TimeSlot.start_date_time).limit(num_slots)
        if not for_real:
            log.info(
                f"I would delete the following time slots - run with --for_real if these are correct"
            )
        else:
            log.info(f"Deleting the following time slots")
        tsids_to_delete = []
        for t in ts:
            tsids_to_delete.append(t.id)
            log.info(f"ID: {t.id} - {t.start_date_time}")
        if not tsids_to_delete:
            log.error("No matching timeslots found! Exiting.")
            sys.exit(1)
        apts = Appointment.select().where(
            Appointment.time_slot.in_(tsids_to_delete))
        log.info(
            f"this {'will' if for_real else 'would'} affect the following appointments"
        )
        apts_to_delete = []
        for apt in apts:
            apts_to_delete.append(apt)
            log.info(
                f"ID: {apt.id} - {apt.time_slot.start_date_time}: {'booked!' if apt.booked else 'free'}"
            )
        if all(not apt.booked for apt in apts_to_delete):
            log.info(
                f"none of these appointments are booked, so I {'will' if for_real else 'would'} delete them"
            )
            if for_real:
                aq = Appointment.delete().where(
                    Appointment.id.in_([a.id for a in apts_to_delete]))
                tq = TimeSlot.delete().where(TimeSlot.id.in_(tsids_to_delete))
                aq.execute()
                tq.execute()
                log.info("Done!")
        else:
            log.error(
                f"Some of these appointments are already booked, {'will' if for_real else 'would'} not delete!"
            )
def init_db(db: directives.PeeweeSession, for_real: hug.types.smart_boolean = False):
    if not for_real:
        print('this will create the database (potentially destroying data), run with --for_real, if you are sure '
              '*and* have a backup')
        sys.exit(1)
    else:
        with db.atomic():
            try:
                migration = Migration.get()
                print(f'Migration level is already set to version {migration.version} - implying the db has already been '
                      f'initialized. Run command `run_migrations` instead.')
                sys.exit(1)
            except DatabaseError:
                init_database()
Exemple #15
0
def delete_booking(db: PeeweeSession, user: hug.directives.user,
                   booking_id: hug.types.text):
    if user.role == UserRoles.ADMIN:
        with db.atomic():
            try:
                booking = Booking.get_by_id(booking_id)
                appointment = booking.appointment
                appointment.booked = False
                appointment.save()
                booking.delete_instance()
            except DoesNotExist as e:
                raise hug.HTTP_NOT_FOUND
        return {"booking_id": booking_id, "deleted": "successful"}
    else:
        raise hug.HTTP_METHOD_NOT_ALLOWED
def change_user_pw(db: directives.PeeweeSession, username: hug.types.text, password: hug.types.text, for_real: hug.types.smart_boolean = False):
    if not for_real:
        print(
            f"this would change {username}'s pw to {password}. Run with --for_real if you're sure.")
        sys.exit(1)
    with db.atomic():
        name = username.lower()
        salt = get_random_string(2)
        secret_password = password
        hashed_password = hash_pw(name, salt, secret_password)
        user = User.get(User.user_name == username)
        user.salt = salt
        user.password = hashed_password
        user.save()
        print(f"{user.user_name}'s pw successfully changed.")
def get_or_create_auto_user(db: PeeweeSession, role: str, name: str):
    coupons = 4 if (
        role == UserRoles.ANON
    ) else config.Ldap.user_coupon_number if role == UserRoles.USER else 1
    with db.atomic():
        try:
            user = User.get(User.user_name == name)
            return user
        except DoesNotExist:
            user = User.create(user_name=name,
                               role=role,
                               salt="",
                               password="",
                               coupons=coupons)
            user.save()
            return user
def patch_user(db: PeeweeSession, user_name: hug.types.text,
               coupons: hug.types.number):
    with db.atomic():
        try:
            user = User.get(User.user_name == user_name)
            if coupons < 0:
                coupons = 0
            user.coupons = coupons
            user.save()
            return {"user_name": user.user_name, "coupons": user.coupons}
        except DoesNotExist as e:
            raise hug.HTTPBadRequest
        except ValueError as e:
            raise hug.HTTPBadRequest
        except AssertionError as e:
            raise hug.HTTPBadRequest
def migrate_db(db: PeeweeSession):
    with db.atomic() as txs:
        migrator = PostgresqlMigrator(db)
        try:
            migration = Migration.get()
            if migration.version < 1:
                # do everything for level 1
                level_1(db, migration, migrator)
            if migration.version < 2:
                # do everything for level 1
                level_2(db, migration, migrator)

        except ProgrammingError:
            log.exception('Error - Migrations table not found, please run init_db first!')
            txs.rollback()
            sys.exit(1)
Exemple #20
0
def claim_appointment(db: PeeweeSession, start_date_time: hug.types.text,
                      user: hug.directives.user):
    """
    UPDATE appointment app
    SET claim_token = 'claimed'
    WHERE app.id
          IN (
              SELECT a.id FROM appointment a
                                 JOIN timeslot t on a.time_slot_id = t.id
              WHERE t.start_date_time = '2020-03-25 08:30:00.000000'
                AND a.claim_token isnull
                AND NOT a.booked
              LIMIT 1
              )
    RETURNING *
    """
    with db.atomic():
        try:
            if user.role != UserRoles.ANON:
                assert user.coupons > 0
            start_date_time_object = datetime.fromisoformat(start_date_time)
            now = datetime.now(tz=config.Settings.tz).replace(tzinfo=None)
            if start_date_time_object < now:
                raise ValueError("Can't claim an appointment in the past")
            time_slot = TimeSlot.get(
                TimeSlot.start_date_time == start_date_time_object)
            appointment = Appointment.select() \
                .where(
                (Appointment.time_slot == time_slot) &
                (Appointment.booked == False) &
                (Appointment.claim_token.is_null() | (Appointment.claimed_at +
                                                      timedelta(
                                                          minutes=config.Settings.claim_timeout_min) < now))
            ) \
                .order_by(Appointment.claim_token.desc()) \
                .get()
            appointment.claim_token = get_random_string(32)
            appointment.claimed_at = now
            appointment.save()
            return appointment.claim_token
        except DoesNotExist as e:
            raise hug.HTTPGone
        except ValueError as e:
            raise hug.HTTPBadRequest
        except AssertionError as e:
            raise hug.HTTPBadRequest
Exemple #21
0
def put_user(db: PeeweeSession, newUserName: hug.types.text, newUserPassword: hug.types.text,
             newUserPasswordConfirm: hug.types.text):
    if newUserPassword != newUserPasswordConfirm:
        raise hug.HTTPBadRequest
    with db.atomic():
        try:
            name = newUserName.lower()
            salt = get_random_string(2)
            secret_password = newUserPassword
            hashed_password = hash_pw(name, salt, secret_password)
            user = User.create(user_name=name, role=UserRoles.USER, salt=salt, password=hashed_password, coupons=10)
            user.save()
            return {
                "username": user.user_name
            }
        except IntegrityError:
            raise hug.HTTPConflict('User already exists.')
def get_free_timeslots_between(db: directives.PeeweeSession, start: datetime, end: datetime):
    with db.atomic():
        now = datetime.now(tz=config.Settings.tz).replace(tzinfo=None)
        slots = TimeSlot \
            .select(TimeSlot.start_date_time, TimeSlot.length_min,
                    fn.count(Appointment.time_slot).alias("free_appointments")) \
            .join(Appointment) \
            .where(
                (TimeSlot.start_date_time >= start) & (TimeSlot.start_date_time <= end) &
                (Appointment.claim_token.is_null() | (Appointment.claimed_at +
                                                      timedelta(
                                                          minutes=config.Settings.claim_timeout_min) < now)) &
                (Appointment.booked == False)
            ) \
            .group_by(TimeSlot.start_date_time, TimeSlot.length_min) \
            .order_by(TimeSlot.start_date_time) \
            # @formatter:on
        return [{"startDateTime": str(slot.start_date_time)} for slot in slots]
def create_appointments(db: directives.PeeweeSession,
                        day: hug.types.number,
                        month: hug.types.number,
                        year: hug.types.number = 2020,
                        start_hour: hug.types.number = 8,
                        start_min: hug.types.number = 30,
                        num_slots: hug.types.number = 13,
                        num_appointment_per_slot: hug.types.number = 8,
                        slot_duration_min: hug.types.number = 30):
    with db.atomic():
        for i in range(num_slots):
            ts = TimeSlot.create(start_date_time=datetime(
                year, month, day, start_hour, start_min, tzinfo=None) +
                                 timedelta(minutes=i * slot_duration_min),
                                 length_min=slot_duration_min)
            for _ in range(num_appointment_per_slot):
                Appointment.create(booked=False, time_slot=ts)
            ts.save()
def set_frontend_config(db: directives.PeeweeSession,
                        instance_name: hug.types.text,
                        long_instance_name: hug.types.text,
                        contact_info_bookings: hug.types.text,
                        contact_info_appointments: hug.types.text = None,
                        for_real: hug.types.smart_boolean = False):
    with db.atomic():
        if "@" in contact_info_bookings:
            bookings_contact = f"<a href=\"mailto:{contact_info_bookings}\">{contact_info_bookings}</a>"
        else:
            bookings_contact = contact_info_bookings

        if not contact_info_appointments:
            appointments_contact = bookings_contact
        else:
            if "@" in contact_info_appointments:
                appointments_contact = f"<a href=\"mailto:{contact_info_appointments}\">{contact_info_appointments}</a>"
            else:
                appointments_contact = contact_info_appointments

        template = {
            "instanceName":
            f"{instance_name}",
            "longInstanceName":
            f"{long_instance_name}",
            "contactInfoCoupons":
            f"<span class=\"hintLabel\">Um mehr Termine vergeben zu können wenden Sie sich an "
            f"{bookings_contact}</span>",
            "contactInfoAppointment":
            f"<span class=\"hintLabel\">Kontaktieren Sie {appointments_contact}</span>"
        }

        if not for_real:
            print(
                f"This would update the config with '{json.dumps(template, indent=2)}'. Run with --for_real if you "
                f"are sure.")
            sys.exit(1)
        else:
            print(
                f"Updating the config with '{json.dumps(template, indent=2)}'."
            )
            config = FrontendConfig.create(config=template)
            config.save()
            print("Done.")
Exemple #25
0
def next_free_slots(db: PeeweeSession,
                    user: hug.directives.user,
                    at_datetime: hug.types.text = None):
    """
    SELECT t.start_date_time, count(a.time_slot_id)
FROM appointment a
         JOIN timeslot t ON a.time_slot_id = t.id
WHERE a.booked IS false
  AND a.claim_token ISNULL
  AND t.start_date_time > NOW()
GROUP BY t.start_date_time
ORDER BY t.start_date_time
    """
    with db.atomic():
        # @formatter:off
        if at_datetime is not None:
            now = datetime.fromisoformat(at_datetime).replace(tzinfo=None)
        else:
            now = datetime.now(tz=config.Settings.tz).replace(tzinfo=None)
        slots = TimeSlot \
            .select(TimeSlot.start_date_time, TimeSlot.length_min,
                    fn.count(Appointment.time_slot).alias("free_appointments")) \
            .join(Appointment) \
            .where(
                (TimeSlot.start_date_time > now) &
                (Appointment.claim_token.is_null() | (Appointment.claimed_at +
                                                      timedelta(
                                                          minutes=config.Settings.claim_timeout_min) < now)) &
                (Appointment.booked == False)
            ) \
            .group_by(TimeSlot.start_date_time, TimeSlot.length_min) \
            .order_by(TimeSlot.start_date_time) \
            .limit(config.Settings.num_display_slots)
        # @formatter:on
        return {
            "slots": [{
                "startDateTime": slot.start_date_time,
                "freeAppointments": slot.free_appointments,
                "timeSlotLength": slot.length_min
            } for slot in slots],
            "coupons":
            user.coupons
        }
Exemple #26
0
def patch_user(db: PeeweeSession, body: hug.types.json,
               user: hug.directives.user):
    old_user_password = body["old_user_password"]
    new_user_password = body["new_user_password"]
    new_user_password_confirm = body["new_user_password_confirm"]
    if new_user_password != new_user_password_confirm:
        raise hug.HTTPBadRequest
    with db.atomic():
        try:
            if user.password != hash_pw(user.user_name, user.salt,
                                        old_user_password):
                raise hug.HTTPBadRequest
            salt = get_random_string(2)
            secret_password = new_user_password
            hashed_password = hash_pw(user.user_name, salt, secret_password)
            user.salt = salt
            user.password = hashed_password
            user.save()
            log.info(f"updated {user.user_name}'s pw.")
            return "updated"
        except DoesNotExist as e:
            raise hug.HTTPBadRequest
        except ValueError as e:
            raise hug.HTTPBadRequest
def create_appointments(
        db: directives.PeeweeSession,
        day: hug.types.number,
        month: hug.types.number,
        year: hug.types.number = date.today().year,
        start_hour: hug.types.number = 8,
        start_min: hug.types.number = 30,
        num_slots: hug.types.number = 13,
        num_appointment_per_slot: hug.types.number = 8,
        slot_duration_min: hug.types.number = 30
):
    """
    [--day] <number> [--month] <number> [--year <number=date.today().year>] [--start_hour <number=8>] [--start_min <number=30>] [--num_slots <number=13>] [--num_appointment_per_slot <number=8>] [--slot_duration_min <number=30>]
    creates timeslots and their corresponsing appointments
    """
    with db.atomic():
        for i in range(num_slots):
            ts = TimeSlot.create(
                start_date_time=datetime(year, month, day, start_hour, start_min, tzinfo=None) + timedelta(
                    minutes=i * slot_duration_min),
                length_min=slot_duration_min)
            for _ in range(num_appointment_per_slot):
                Appointment.create(booked=False, time_slot=ts)
            ts.save()
Exemple #28
0
def list_for_day(db: PeeweeSession, user: hug.directives.user,
                 start_date: hug.types.text, end_date: hug.types.text):
    user_name = user.user_name
    with db.atomic():
        try:
            user_role = user.role
            start_day_object = date.fromisoformat(start_date)
            end_day_object = date.fromisoformat(end_date)
            result = io.BytesIO()
            workbook = xlsxwriter.Workbook(result)
            worksheet = workbook.add_worksheet()
            bold = workbook.add_format({'bold': 1})
            date_format = workbook.add_format({'num_format': 'dd.mm.yyyy'})
            time_format = workbook.add_format({'num_format': 'hh:mm'})
            worksheet.set_column('A:A', 15)
            worksheet.set_column('B:B', 8)
            worksheet.set_column('C:C', 18)
            worksheet.set_column('D:D', 15)
            worksheet.set_column('E:E', 18)
            worksheet.set_column('F:F', 15)
            worksheet.set_column('G:G', 15)
            worksheet.set_column('H:H', 15)
            worksheet.set_column('I:I', 15)
            worksheet.set_column('J:J', 15)
            worksheet.set_column('K:K', 15)
            worksheet.set_column('L:L', 15)
            worksheet.set_column('M:M', 15)
            worksheet.set_column('N:N', 15)
            worksheet.set_column('O:O', 15)
            worksheet.write('A1', 'Termin', bold)
            worksheet.write('B1', 'Uhrzeit', bold)
            worksheet.write('C1', 'Vorname', bold)
            worksheet.write('D1', 'Nachname', bold)
            worksheet.write('E1', 'Telefon', bold)
            worksheet.write('F1', 'Straße', bold)
            worksheet.write('G1', 'Hausnummer', bold)
            worksheet.write('H1', 'PLZ', bold)
            worksheet.write('I1', 'Stadt', bold)
            worksheet.write('J1', 'Geburtdatum', bold)
            worksheet.write('K1', 'Risikokategorie 1', bold)
            worksheet.write('L1', 'Berechtigungscode', bold)
            worksheet.write('M1', 'Behörde', bold)
            worksheet.write('N1', 'Gebucht von', bold)
            worksheet.write('O1', 'Gebucht am', bold)
            row = 1
            col = 0
            for timeslot in TimeSlot.select().where(
                (TimeSlot.start_date_time >= start_day_object)
                    & (TimeSlot.start_date_time < end_day_object +
                       timedelta(days=1))).order_by(
                           TimeSlot.start_date_time.desc()):
                for appointment in Appointment.select().where(
                    (Appointment.time_slot == timeslot)
                        & (Appointment.booked == True)):
                    try:
                        booking = Booking.get(
                            Booking.appointment == appointment)
                        if user_role != UserRoles.ADMIN:
                            booking = Booking.select().where(
                                (Booking.appointment == appointment)
                                & (Booking.booked_by == user_name)).get()

                        worksheet.write_datetime(row, col,
                                                 timeslot.start_date_time,
                                                 date_format)
                        worksheet.write_datetime(row, col + 1,
                                                 timeslot.start_date_time,
                                                 time_format)
                        worksheet.write_string(row, col + 2,
                                               booking.first_name)
                        worksheet.write_string(row, col + 3, booking.surname)
                        worksheet.write_string(row, col + 4, booking.phone)
                        worksheet.write_string(
                            row, col + 5, booking.street
                            if booking.street is not None else "")
                        worksheet.write_string(
                            row, col + 6, booking.street_number
                            if booking.street_number is not None else "")
                        worksheet.write_string(
                            row, col + 7, booking.post_code
                            if booking.post_code is not None else "")
                        worksheet.write_string(
                            row, col + 8,
                            booking.city if booking.city is not None else "")
                        if booking.birthday is None:
                            worksheet.write_string(row, col + 9, "")
                        else:
                            worksheet.write_datetime(row, col + 9,
                                                     booking.birthday,
                                                     date_format)
                        worksheet.write_string(
                            row, col + 10, booking.reason
                            if booking.reason is not None else "")
                        worksheet.write_string(row, col + 11, booking.secret)
                        worksheet.write_string(row, col + 12, booking.office)
                        worksheet.write_string(row, col + 13,
                                               booking.booked_by)
                        worksheet.write_datetime(row, col + 14,
                                                 booking.booked_at,
                                                 date_format)
                        row += 1
                    except DoesNotExist as e:
                        pass
            workbook.close()
            result.flush()
            return result.getvalue()
        except DoesNotExist as e:
            raise hug.HTTPGone
        except ValueError as e:
            raise hug.HTTPBadRequest
Exemple #29
0
def instance_admin_config(db: PeeweeSession):
    with db.atomic():
        return f"window.config = {json.dumps(FrontendConfig.get().config)};"
def inc_coupon_count(db: directives.PeeweeSession, user_name: hug.types.text,
                     increment: hug.types.number):
    with db.atomic():
        user = User.get(User.user_name == user_name)
        user.coupons += increment
        user.save()