R/customers.r

#' Start a New Customer with Initial Inventory
#'
#' Start a new customer with an initial delivery of starting inventory.
#' @param state current simulation state
#' @param items items to be shipped
#' @param amounts of items to be shipped
#' @param at_time delivery time
#' @param scan_prob probability that a tagged item will be "scanned"
#' @importFrom dplyr data_frame
#' @export
start_customer <- function(state, at_time,
                           items=NA, amounts=NA, scan_prob = 1) {
    new_id <- max_id(state, "locations", "location") + 1

    new_customer <- data_frame(
        name = paste0("Customer ", new_id),
        location = new_id,
        terminal = FALSE,
        customer = TRUE
    )
    state[["locations"]] <- dplyr::bind_rows(state[["locations"]], new_customer)

    if (!is.na(items) && !is.na(amounts)){
        state <- move_inventory(state, items, amounts,
                                location_id(state, "Plant"),
                                new_id, at_time,  scan_prob,
                                limit_status = TRUE)
    }

    return(state)
}

#' Customer Use Inventory
#'
#' Customer uses inventory, changing it's state to soiled, and possibly
#' misplacing it.
#' @param state current simulation state to modify
#' @param order data_frame of \code{item}'s and \code{order_qty}'s
#' @param where location using inventory
#' @param at_time time-stamp to associate with this move
#' @param loss_prob probability that an item being used is lost
#' @importFrom dplyr data_frame inner_join group_by summarize
#' @export
customer_uses_inventory <- function(state, order, where, at_time,
                                    loss_prob=0){
    inventory <- current_inventory(state, where)

    inventory %>%
        inner_join(state[["population"]], by = "piece") %>%
        group_by(item) %>%
        summarize(
            clean_count = sum(clean)
        ) %>%
        inner_join(order, by = "item") %>%
        mutate(
            qty_lost_at_customer = rbinom(length(item), clean_count, loss_prob),
            return_qty = order_qty - qty_lost_at_customer
        ) -> moveing

    # Pick the losses first, because we're picking from clean inventory
    moveing %>%
        select(item, order_qty = qty_lost_at_customer) %>%
        customer_loses_inventory(state, order = .,
            from = where, to = location_id(state, "Loss_Customer"),
            limit_status = TRUE, change_status = FALSE, scan_prob = 0) -> state

    # Pick soiled from remaining clean inventory
    moveing %>%
        select(item, order_qty = return_qty) %>%
        move_inventory(state, order = .,
            from = where, to = where,
            limit_status = TRUE, change_status = FALSE, scan_prob = 0) -> state

    return(state)
}


#' Customer Loses Inventory
#'
#' Customer loses inventory, transitioning it to a terminal state
#' @param state current simulation state to modify
#' @param order data_frame of \code{item}'s and \code{order_qty}'s
#' @param who location to move from
#' @param at_time time-stamp to associate with this move
#' @export
customer_loses_inventory <- function(state, order, who, at_time,
                                     limit_status=NA) {
    move_inventory(state,
        order, from = who, to = location_id("Loss_Customer"),
        at_time = at_time,
        limit_status = limit_status,
        scan_prob = 0)
}
milumtextiles/itemsim documentation built on May 22, 2019, 11:54 p.m.