Esempio n. 1
0
def get_shift_data(path_to_csv, path_to_json_dir, company, department, needs_type='manual'):
    """
    Combines all data into a list of tuples (X_df, y_df).
    :param path_to_csv: String. Path to csv file of all the shifts.
    :param path_to_json_dir: String. Path to a directory containing all json schedules.
    :param company: String. Name of the company.
    :param department: String. Name of the department in the company.
    :param needs_type: String. Specifies type of needs to use. 'manual', 'avg', or 'median'.
    :return: Tuple of (list of (features_df, labels_df), max_scale_value).
    """

    company = org_names_filter(company)
    department = org_names_filter(department)

    shift_ratios = create_shift_ratios(path_to_csv, path_to_json_dir)  # called for training the model.
    manual_needs, auto_avg_needs, auto_median_needs = get_needs_methods(path_to_json_dir, company, department)

    json_schedules = get_json_schedules(path_to_json_dir)

    if needs_type == 'manual':
        needs = manual_needs
    elif needs_type == 'avg':
        needs = auto_avg_needs
    elif needs_type == 'median':
        needs = auto_median_needs
    else:
        raise ValueError('Invalid needs_type: \'' + needs_type + '\'. Must be string \'manual\', \'avg\', or \'median\'.')

    data, max_scale_value = features_targets_from_needs_list(needs, shift_ratios, json_schedules, path_to_json_dir)

    return data, max_scale_value
Esempio n. 2
0
def get_full_needs(company, department):  # past and present needs
    company = org_names_filter(company)
    department = org_names_filter(department)
    current_needs_dict = get_needs(company, department)
    past_needs_list = get_past_needs(company, department)

    past_needs_list.append(current_needs_dict)

    return past_needs_list
Esempio n. 3
0
def get_user_data(path_to_csv, company, department, shifts_key):
    company = org_names_filter(company)
    department = org_names_filter(department)

    ratio_a, ratio_b = create_user_ratios(path_to_csv, shifts_key)

    data = features_targets_from_user_ratios(path_to_csv, ratio_a, ratio_b, shifts_key)

    return data
Esempio n. 4
0
def test(company, department):
    company = org_names_filter(company)
    department = org_names_filter(department)

    department_avails, department_time_offs = get_full_avail_and_time_off(
        company, department)

    print(department_avails)
    print(department_time_offs
          )  # time off might be none. If so, set all the ratios to zero.
Esempio n. 5
0
def parse_csv(path_to_csv):
    """
    Path
    :param path_to_csv: Filepath to the csv file with a list of users in the new client company.
    :return: Dict with structure: {'company': String, 'departments': [String], 'users': [{}, {}, {}]}
    """
    company_name = ''
    departments_dict = {}
    users = []

    with open(path_to_csv, 'r', encoding='utf-8-sig') as csv_file:
        reader = csv.reader(csv_file, delimiter=',')
        for row in reader:
            company_name = org_names_filter(row[0])
            user_departments = row[1].split(', ')
            for department in user_departments:
                departments_dict[org_names_filter(department)] = True

            last_name = row[2]
            first_name = row[3]
            email = row[4]
            position = row[5]
            is_pt = bool(row[6])
            account_type = int(row[7])

            current_user_dict = {
                'last_name': last_name,  # type string
                'first_name': first_name,  # type string
                'email': email,  # type string
                'position': position,  # type string
                'departments': user_departments,  # type list of strings
                'company': company_name,  # type string
                'is_pt':
                is_pt,  # type int 0 for full time or 1 for part time. Can be bool as well
                'account_type':
                account_type,  # type int 0 for basic, 1 for manager, 2 for master
                'status': 'active'  # type string 'active', 'leave', 'remove'
            }
            users.append(current_user_dict)

    departments_list = list(departments_dict.keys())

    parsed_company_dict = {
        'company': company_name,
        'departments': departments_list,
        'users': users
    }

    return parsed_company_dict
Esempio n. 6
0
def get_manager_users(company, department):
    current_company = get_company_from_local_db(org_names_filter(company))
    department_name = org_names_filter(department)

    users_ref = current_company.collection('manager_users')
    user_docs = users_ref.where('primary_department', '==', department_name).get()

    users = []
    for user in user_docs:
        user_dict = user.to_dict()
        user_dict['is_part_time'] = True

        users.append(user_dict)

    return users
Esempio n. 7
0
def add_manager_user(user_dict, company):
    user_dict['primary_department'] = org_names_filter(user_dict['departments'][0])

    new_user_dict = {
        'email': user_dict['email'],
        'name': user_dict['name'],
        'position': user_dict['position'],
        'primary_department': user_dict['primary_department'],
        'account_type': user_dict['account_type'],
        'status': user_dict['status']
    }

    new_onboarding = {
        'is_password_changed': False,
        'is_onboard_complete': False
    }

    new_avail = {
        'is_part_time': user_dict['is_part_time'],
    }

    encoded_email = user_dict['encoded_email']
    current_company = get_company_by_name(company)

    current_company.collection('manager_users').document(encoded_email).set(new_user_dict)
    current_company.collection('manager_users').document(encoded_email + '/scheduling/onboarding').set(new_onboarding)
    current_company.collection('manager_users').document(encoded_email + '/scheduling/availability').set(new_avail)
Esempio n. 8
0
def get_full_avail_and_time_off(company, department):
    company = org_names_filter(company)
    department = org_names_filter(department)

    all_department_basic_users = get_users(company, department)

    availabilities = {}
    time_offs = {}
    for user in all_department_basic_users:
        email = user['email']
        encoded_email = encode_email(email)

        avail_dict = get_availability(company, encoded_email)
        time_off_dict = get_user_time_off(company, encoded_email)

        availabilities[email] = avail_dict
        time_offs[email] = time_off_dict

    return availabilities, time_offs
Esempio n. 9
0
def predict_week_users(path_to_csv, company, department, shifts_key, classifier_id=None):
    """
    Predicts the chance of each user having every shift on every day of the week.
    :param path_to_csv: String. Path to csv file of all the shifts.
    :param company: String. Name of the company.
    :param department: String. Name of the department in the company.
    :param shifts_key: List of strings representing every possible shift to be had, in specific order.
    :param classifier_id: String. The classifier to use for training and prediction. 'random_forest', 'k_neighbors',
     'radius_neighbors' or None. If None, use a neural net from Tensorflow.
    :return: Tuple. Nested Dict. Day of week -> email -> predictions vector. AND list of users_dicts. AND shifts_key
    """
    company = org_names_filter(company)
    department = org_names_filter(department)

    model, day_of_week_key = train_model_for_prediction(path_to_csv, company, department, shifts_key, classifier_id=classifier_id)
    ratio_a, ratio_b = create_user_ratios(path_to_csv, shifts_key)

    predictions, users = get_week_prediction(model, ratio_a, ratio_b, company, department, shifts_key)

    return predictions, users, shifts_key
Esempio n. 10
0
def add_basic_user(user_dict, company):
    company_code = get_company_code_by_name(company)

    user_dict['primary_department'] = org_names_filter(user_dict['departments'][0])

    departments = []
    for department in user_dict['departments']:
        department_doc = db.document('companies/' + company_code + '/departments/' + org_names_filter(department))
        departments.append(department_doc)

    user_dict['departments'] = departments

    new_user_dict = {
        'email': user_dict['email'],
        'name': user_dict['name'],
        'position': user_dict['position'],
        'primary_department': user_dict['primary_department'],
        'account_type': user_dict['account_type'],
        'status': user_dict['status']
    }

    new_onboarding = {
        'is_password_changed': False,
        'is_onboard_complete': False
    }

    new_avail = {
        'is_part_time': user_dict['is_part_time'],
        'departments': departments
    }

    encoded_email = user_dict['encoded_email']
    current_company = get_company_by_name(company)

    current_company.collection('basic_users').document(encoded_email).set(new_user_dict)
    current_company.collection('basic_users').document(encoded_email + '/scheduling/onboarding').set(new_onboarding)
    current_company.collection('basic_users').document(encoded_email + '/scheduling/availability').set(new_avail)
Esempio n. 11
0
def get_users(company, department):  # gets all basic users
    current_company = get_company_from_local_db(org_names_filter(company))
    department_name = org_names_filter(department)

    users_ref = current_company.collection('basic_users')
    user_docs = users_ref.where('primary_department', '==', department_name).get()

    users = []
    for user in user_docs:
        user_dict = user.to_dict()

        availability_ref = get_user_availability_ref(company, encode_email(user_dict['email']))
        availability = availability_ref.get()
        availability_dict = availability.to_dict()
        user_dict['is_part_time'] = availability_dict['is_part_time']
        user_dict['avail'] = availability_dict

        # new_departments = department_list_to_dict(user_dict['departments'])

        # user_dict['departments'] = new_departments

        users.append(user_dict)

    return users
Esempio n. 12
0
def create_new_client(path_to_csv):
    """
    :return: The company code.
    """
    new_client_dict = parse_csv(path_to_csv)
    company_dict = company_to_dict(new_client_dict['company'],
                                   new_client_dict['departments'])

    # Create the company in databases and then add the users
    add_company(company_dict)
    email_data = add_new_users(new_client_dict)

    # email the user their password and the company code
    company_code = get_company_code_by_name(
        org_names_filter(new_client_dict['company']))
    email_temp_passwords(email_data, company_code)
Esempio n. 13
0
def add_single_user(user_dict, company):
    """
    Adds a single user to a company.
    :param user_dict: Dict of the user containing last_name (string), first_name (string), email (string), position
    (string), departments([string]), is_pt (Bool), account_type (int), status (string)
    :param company: Name of the company, assumed to be unfiltered.
    :return: A dict of data containing everything needed for emailing the user their onboarding info.
    """
    last_name = user_dict['last_name']
    first_name = user_dict['first_name']
    full_name = first_name + ' ' + last_name
    email = user_dict['email']
    position = user_dict['position']
    departments = user_dict['departments']
    is_pt = user_dict['is_pt']
    account_type = user_dict['account_type']
    status = user_dict['status']

    auto_generated_password = generate_password(randint(10, 15))
    is_already_added = False
    try:
        auth.create_user(email=email,
                         password=auto_generated_password,
                         display_name=full_name)
    except AuthError:
        is_already_added = True

    user_dict = user_to_dict(position, departments, email, first_name,
                             last_name, is_pt, account_type, status)
    add_user(user_dict, org_names_filter(company))

    email_dict = {
        'email_address': email,
        'temp_password': auto_generated_password,
        'first_name': first_name,
        'company_name': company,
        'is_already_added': is_already_added
    }
    return email_dict
Esempio n. 14
0
def test(path_to_csv,
         path_to_json_dir,
         company,
         department,
         needs_type='avg',
         remove_ratios=False,
         remove_needs=False,
         classifier_id=None,
         include_manager=False):
    """

    :param path_to_csv: String. Path to csv file of all the shifts.
    :param path_to_json_dir: String. Path to a directory containing all json schedules.
    :param company: String. Name of the company.
    :param department: String. Name of the department in the company.
    :param needs_type: String. Specifies type of needs to use. 'manual', 'avg', or 'median'.
    :param remove_ratios: Bool. Whether or not the remove the ratios from the features.
    :param remove_needs: Bool. Whether or not the remove the needs from the features.
    :param classifier_id: String. The classifier to use for training and prediction of the user predictor.
     'random_forest', 'k_neighbors', 'radius_neighbors' or None. If None, use a neural net from Tensorflow.
    :param include_manager: Bool. Whether or not to include the scheduling manager of the department in the schedule.
    :return:
    """
    company = org_names_filter(company)
    department = org_names_filter(department)

    shifts_predictions, shifts_shifts_key = predict_week_shifts(
        path_to_csv,
        path_to_json_dir,
        company,
        department,
        needs_type=needs_type,
        remove_ratios=remove_ratios,
        remove_needs=remove_needs)

    user_predictions, users, shifts_key = predict_week_users(
        path_to_csv,
        company,
        department,
        shifts_shifts_key,
        classifier_id=classifier_id)

    print(shifts_predictions)
    print(user_predictions)

    for a, b in zip(shifts_shifts_key, shifts_key):
        if a != b:
            raise ValueError('shifts_keys not aligned')

    for day_of_week, shift_pred in shifts_predictions.items():
        needed_shift_indexes = {}
        for index, shift in enumerate(shift_pred):
            if shift == 1:
                needed_shift_indexes[index] = ''

        # what if a user wins two in one day???
        for shift_index in needed_shift_indexes.keys():
            current_highest = 0
            for email, user_pred in user_predictions[day_of_week].items():
                if user_pred[0][shift_index] > current_highest:
                    current_highest = user_pred[0][shift_index]
                    needed_shift_indexes[shift_index] = email

        print(needed_shift_indexes)

    print(users[0])