def handler(event, context):
    # check authorization
    authorized_user_types = [
        UserType.ADMIN
    ]
    success, _ = check_auth(event['headers']['Authorization'], authorized_user_types)
    if not success:
        return http_status.unauthorized()

    chatId = event["pathParameters"].get("chatId") if event["pathParameters"] else None
    if not chatId:
        return http_status.bad_request("missing path parameter(s): 'chatId'")

    session = Session()
    chat = session.query(Chat).get(chatId)
    if not chat:
        session.close()
        return http_status.not_found("chat with id '{}' not found".format(chatId))

    admin_update_declared_chats_frequency(chat.senior_executive, -1)
    if chat.chat_status == ChatStatus.PENDING:
        admin_update_remaining_chats_frequency(chat.senior_executive, -1)

    session.delete(chat)
    session.commit()
    session.close()

    return http_status.success()
def activate_expiring_chats(user, chats, current_date, next_date):
    num_activated = 0
    for chat in chats:
        if chat.chat_status == ChatStatus.PENDING and not chat.fixed_date and chat.expiry_date:
            if current_date <= chat.expiry_date < next_date:
                num_activated += 1

                chat.chat_status = ChatStatus.ACTIVE
                admin_update_remaining_chats_frequency(user['email'], -1)
    return num_activated
def handler(event, context):
    # check authorization
    authorized_user_types = [
        UserType.ADMIN
    ]
    success, _ = check_auth(event['headers']['Authorization'], authorized_user_types)
    if not success:
        return http_status.forbidden()

    # validate body
    body = json.loads(event["body"])
    senior_executive = body.get('senior_executive')
    chats_new = body.get('chats')
    if not senior_executive or not chats_new:
        return http_status.bad_request("invalid parameter(s): 'senior_executive, chats'")

    session = Session()
    for chat_new in chats_new:
        if not chat_new.get('chat_type') or chat_new['chat_type'] not in ChatType.__members__:
            session.close()
            return http_status.bad_request("invalid parameter(s): 'chat_type'")

        chat_type = ChatType[chat_new['chat_type']]
        description = chat_new.get('description')
        tags = chat_new.get('tags')
        fixed_date = chat_new.get('fixed_date')
        if chat_type in mandatory_date and not fixed_date:
            session.rollback()
            session.close()
            return http_status.bad_request("missing body attribute { fixed_date } with chat_type { %s }" % (chat_type.name))

        chat = Chat(
            chat_type=chat_type, description=description,
            chat_status=ChatStatus.PENDING, tags=tags,
            senior_executive=senior_executive
        )

        admin_update_declared_chats_frequency(senior_executive, 1)
        if fixed_date:
            chat.fixed_date = datetime.fromtimestamp(fixed_date).replace(hour=0, minute=0,second=0, microsecond=0)
            chat.chat_status = ChatStatus.ACTIVE
        else:
            admin_update_remaining_chats_frequency(senior_executive, 1)
        session.add(chat)

    session.commit()
    session.close()

    return http_status.success()
def process_undated_chats(user, chats, current_date, next_date):
    num_unbooked = 0
    for chat in chats:
        if chat.expiry_date:
            if chat.chat_status == ChatStatus.RESERVED_PARTIAL \
               or chat.chat_status == ChatStatus.RESERVED:
                chat.chat_status = ChatStatus.RESERVED_CONFIRMED
            elif chat.chat_status == ChatStatus.ACTIVE:
                if chat.expiry_date < current_date or chat.expiry_date > next_date:
                    num_unbooked += 1
                    chat.chat_status = ChatStatus.PENDING
                    admin_update_remaining_chats_frequency(user['email'], 1)
                    if chat.expiry_date < current_date:
                        # TODO: set expiry_date to None to allow for rescheduling
                        # chat.expiry_date = None
                        chat.chat_status = ChatStatus.EXPIRED
    return num_unbooked
def schedule_activate(session, default_num_activate, num_carry_over):
    num_activate = default_num_activate + num_carry_over
    if num_activate <= 0:
        return

    chats = get_chats(session,
                      status=['PENDING'],
                      expiry_date='DATED',
                      order_by='expiry_date',
                      num=num_activate)
    for chat in chats:
        chat.chat_status = ChatStatus.ACTIVE
        user, _ = get_users(filter_=('email', chat.senior_executive))

        try:
            admin_update_remaining_chats_frequency(user['attributes']['email'],
                                                   -1)
        except:
            chat.chat_status = ChatStatus.PENDING
            print(chat.senior_executive)
def handler(event, context):
    # check authorization
    authorized_user_types = [UserType.ADMIN]
    success, _ = check_auth(event['headers']['Authorization'],
                            authorized_user_types)
    if not success:
        return http_status.unauthorized()

    status_filter = event["queryStringParameters"].get(
        "status", "") if event["queryStringParameters"] else ""
    type_filter = event["queryStringParameters"].get(
        "type", "") if event["queryStringParameters"] else ""
    senior_executive_filter = event["queryStringParameters"].get(
        "senior_executive", "") if event["queryStringParameters"] else ""

    session = Session()
    filtered_query = session.query(Chat)
    if status_filter and status_filter in ChatStatus.__members__:
        filtered_query = filtered_query.filter(
            Chat.chat_status == ChatStatus[status_filter])
    if type_filter and type_filter in ChatType.__members__:
        filtered_query = filtered_query.filter(
            Chat.chat_type == ChatType[type_filter])
    if senior_executive_filter:
        filtered_query = filtered_query.filter(
            Chat.senior_executive == senior_executive_filter)

    chats = filtered_query.all()
    for chat in chats:
        admin_update_declared_chats_frequency(chat.senior_executive, -1)
        if chat.chat_status == ChatStatus.PENDING:
            admin_update_remaining_chats_frequency(chat.senior_executive, -1)
        session.delete(chat)

    session.commit()
    session.close()
    return http_status.success()
def handler(event, context):
    # check authorization
    authorized_user_types = [UserType.ADMIN, UserType.MENTOR]
    success, user = check_auth(event['headers']['Authorization'],
                               authorized_user_types)
    if not success:
        return http_status.unauthorized()

    chatId = event["pathParameters"].get(
        "chatId") if event["pathParameters"] else None
    if not chatId:
        return http_status.bad_request("missing path parameter(s): 'chatId'")

    session = Session()
    chat = session.query(Chat).get(chatId)
    if not chat:
        session.close()
        return http_status.not_found(
            "chat with id '{}' not found".format(chatId))

    success = edit_auth(user, chat.senior_executive)
    if not success:
        session.close()
        return http_status.unauthorized()

    # CANCELED state can be achieved from PENDING, ACTIVE, RESERVED_PARTIAL, RESERVED or RESERVED_CONFIRMED
    #
    # if chat to be canceled is dated (i.e. cannot be rescheduled):
    #   - if PENDING    => N/A
    #   - else          => set to CANCELED, refund APs
    #
    # if chat to be canceled is undated (i.e. can be rescheduled):
    #   - set to CANCELED
    #   - refund APs
    #   - create a new PENDING chat to be rescheduled
    #   - if not PENDING
    #       - increment remaining chat frequency in Cognito
    # TODO: send email notification to SEs and APs
    if chat.chat_status == ChatStatus.DONE or chat.chat_status == ChatStatus.CANCELED or chat.chat_status == ChatStatus.EXPIRED:
        session.close()
        return http_status.forbidden(
            "cannot cancel DONE, CANCELED or EXPIRED chat with id '{}'".format(
                chatId))

    for ap in chat.aspiring_professionals:
        admin_update_credits(ap, credit_mapping[chat.chat_type])

    if not chat.fixed_date:
        chat_new = Chat(chat_type=chat.chat_type,
                        description=chat.description,
                        chat_status=ChatStatus.PENDING,
                        tags=chat.tags,
                        senior_executive=chat.senior_executive)
        session.add(chat_new)

        if chat.chat_status != ChatStatus.PENDING:
            admin_update_remaining_chats_frequency(chat.senior_executive, 1)
    chat.chat_status = ChatStatus.CANCELED

    session.commit()
    session.close()
    return http_status.success()