Esempio n. 1
0
def patch_courier(courier_id, new_data: dict, couriers_db: Couriers,
                  orders_db: Orders):
    """
    Change data for courier with courier_id and remove orders from assigned orders,
    if they don't fit by region, delivery hours or weight anymore
    """
    courier_id = int(courier_id)
    courier = couriers_db.get_item(courier_id)

    # Get assigned orders' data and create copy of its list
    assigned_orders_ids = get_ids(courier['assigned_orders'])
    assigned_orders = orders_db.get_items_by_ids(assigned_orders_ids)
    new_assigned_orders = deepcopy(assigned_orders)

    # Remove orders, that don't fit anymore, from assigned_orders
    if 'regions' in new_data:
        new_assigned_orders = list(
            filter(lambda o: o['region'] in new_data['regions'],
                   new_assigned_orders))
    if 'working_hours' in new_data:
        new_assigned_orders = list(
            filter(
                lambda o: _is_intervals_fitted(new_data['working_hours'], o[
                    'intervals']), new_assigned_orders))
    if 'courier_type' in new_data and \
            COURIERS_CAPACITY[new_data['courier_type']] < COURIERS_CAPACITY[courier['courier_type']]:
        # if capacity of courier get down
        new_capacity = _get_courier_capacity(new_data['courier_type'],
                                             new_assigned_orders)
        new_assigned_orders = _replace_orders(new_assigned_orders,
                                              new_capacity)

    # Add edited assigned list to new data and edit courier data in DB
    new_data['assigned_orders'] = [{
        'id': order['id']
    } for order in new_assigned_orders]
    couriers_db.edit_item(courier_id, new_data)

    # Update status to 0 (not assigned) for orders that are not in new assigned orders
    dropped_orders = [{
        'id': order['id']
    } for order in assigned_orders if order not in new_assigned_orders]
    orders_db.update_status(dropped_orders, 0, courier_type='')

    # Get edited courier's data from DB
    edited_courier = couriers_db.get_item(courier_id)
    return {
        'courier_id': edited_courier['_id'],
        'courier_type': edited_courier['courier_type'],
        'regions': edited_courier['regions'],
        'working_hours': edited_courier['working_hours']
    }
Esempio n. 2
0
def assign_orders(courier_id_data: dict, couriers_db: Couriers,
                  orders_db: Orders):
    """
    Find orders that fit by region, delivery hours and put max number of them to assigned_orders.
    """
    courier_id = courier_id_data['courier_id']
    courier = couriers_db.get_item(courier_id)

    assigned_orders_ids = get_ids(
        courier['assigned_orders']
    )  # ids of orders that already in courier's bag

    # if courier has assigned orders, return them
    if len(assigned_orders_ids) != 0:
        courier = couriers_db.get_item(courier_id)
        return {
            'orders': [{
                'id': o['id']
            } for o in courier['assigned_orders']],
            'assign_time': courier['assign_time'].isoformat()
        }

    # Find orders that fit time intervals
    intervals = parse_intervals(
        courier['working_hours'])  # get intervals in seconds
    orders_to_place = []
    for interval in intervals:
        fitted_orders = orders_db.get_fitted_orders(interval[0], interval[1],
                                                    courier['regions'])
        orders_to_place = update_orders(orders_to_place, fitted_orders)

    # Put all possible new orders to courier's bag
    courier_type = courier['courier_type']
    capacity = COURIERS_CAPACITY[courier['courier_type']]
    assigned_orders = _place_orders(orders_to_place, capacity)

    # Write assigned orders to DB (if it is empty list, it is already in DB) and update their statuses
    if len(assigned_orders) != 0:
        couriers_db.write_assigned_orders(courier_id,
                                          assigned_orders,
                                          assign_time=datetime.now())
        orders_db.update_status(assigned_orders, 1, courier_type=courier_type)

    # Get assigned orders from DB
    courier = couriers_db.get_item(courier_id)
    return {
        'orders': [{
            'id': o['id']
        } for o in courier['assigned_orders']],
        'assign_time': courier['assign_time'].isoformat()
    }
Esempio n. 3
0
def complete_order(complete_data: dict, couriers_db: Couriers,
                   orders_db: Orders):
    """
    Move order with id=complete_data['order_id'] from assigned_orders to completed_orders and change its status
    """
    courier_id = complete_data['courier_id']
    order_id = complete_data['order_id']
    complete_time = str_to_datetime(complete_data['complete_time'])

    courier_type = couriers_db.get_item(courier_id)['courier_type']
    delivery_time = _calculate_delivery_time(courier_id, complete_time,
                                             couriers_db, orders_db)
    # Update data of completed order in DB
    orders_db.update_status([{
        'id': order_id
    }],
                            2,
                            complete_time=complete_time,
                            delivery_time=delivery_time)
    # Change status of order in couriers' DB
    couriers_db.move_order_to_completed(courier_id, order_id)
    return {'order_id': order_id}