idCol     <- c("vendor_identifier")
dateCol   <- c("download_date")
nameCol   <- c("fullName")



## CHECK THAT WE HAVE AT LEAST A `One-TO-Many` relationship 
# ------------------------------------------------------- #
  oMany.nameCol <- OneOrMany(DB.raw, nameCol, by=idCol, dateCol=dateCol)
  oMany.idCol   <- OneOrMany(DB.raw, idCol, by=nameCol, dateCol=dateCol)

  cat("'", nameCol, "'", "-TO-", "'", idCol, "'", "  is  ", oMany.nameCol, "-TO-", oMany.idCol, sep="")
  stopifnot(oMany.nameCol == "One")
# ------------------------------------------------------- #


## Identify which columns to keep for DT.agg 
# ------------------------------------------------------- #
  colsUsing <- c("download_date", "vendor_identifier", "upc"
                , "fullName", "artist", "title"
                , "order_id", "customer_identifier"
                , "customer_price", "units", "product", "wasFree", "sale_return"
                , "releaseDate", "startDate", "endDate")

  ## For my own viewing
  notUsed <- setdiff(names(DB.raw), colsUsing)
  if (verbose && length(notUsed))
    message(warningCols("The following columns are not being used", notUsed))
  # rm(notUsed)
# ------------------------------------------------------- #


# ------------------------------------------------------- #  
# CREATE         DT.agg 
# ------------------------------------------------------- #  
  inds <- TRUE
  if (onlyBrasil)
    inds <- DB.raw[["country_code"]] == "BR"
  DT.agg <- DB.raw[inds, colsUsing, with=FALSE]


  # This is to confirm that vendor id works as an key value
  # ------------------------------------------------------- #  
    should.be.unique.by.idCol <- c("upc", "fullName", "artist", "title", "product")
    whereDups <- whereAreTheMultipleRowsPerGroup(DT.agg, colsToCheck=should.be.unique.by.idCol, byCols=idCol, verbose=verbose)
    if(length(whereDups))
      stop("\n\nIn `DT.agg`, when grouping by `idCol=c", pasteQ(idCol), "`.\nthere should be only one set of unique values per each of\n   c", pasteQ(should.be.unique.by.idCol),"\n\nCheck the object `whereDups` for problem rows.\n\n")
  # ------------------------------------------------------- #  

  reconcileReturns(DT, dontRename=FALSE)

# ------------------------------------------------------- #  

# Total by vID
DT.agg[, list(netDailyUnits.by.vID=sum(units) 
            , grossDailyUnits.by.vID=sum(units[units > 0])
            , grossDailyReturns.by.vID=sum(units[units < 0])
            )
      ,by=c(idCol, dateCol)]

# Total by vID
DT.agg[, list(netDailyUnits.by.upc=sum(units) 
            , grossDailyUnits.by.upc=sum(units[units > 0])
            , grossDailyReturns.by.upc=sum(units[units < 0])
            )
      ,by=c("upc", dateCol)]


# Total by vID
DT.agg[sale_return == "sale"
        , list(grossDailyOrders.by.upc=lunique(orders)
            , grossDailyReturns.by.upc=sum(units[units < 0])
            )
      ,by=c("upc", dateCol)]

DT.agg[, list(sale_return, customer_identifier,
            newCustomer.by.upc = 
                !duplicated(customer_identifier)
      ), by="upc"]



DT.agg[, list(totalDailyUnits=sum(units)),by=byCols][totalDailyUnits>100]




DB.raw[, .N, by=vendor_identifier]
DB.raw[, .N, by=isrc]


DB.raw[, list(customer_price, product_type_identifier)]
DB.raw[customer_price!=0, mean(customer_price), by=product_type_identifier]
DB.raw[, length(customer_price==0), by=product_type_identifier]


DT.agg[]
DT.agg <- DB.raw[, colsUsing, with=FALSE]
colsUsing <- setdiff(colsUsing, byCols)
DB.raw[, c(list(x=sum(units)), .SD), by=byCols, .SDcols=colsUsing]
[dailyUnits > 100]


quoteMe <- function(x) {
  x.sub <- as.character(substitute(x))
  ret <- pasteQ(unlist(x.sub[-1L], use.names=FALSE), q='"')
  ret <- paste0(x.sub[[1L]], ret)
  ret <- capture.output(cat(ret))
  clipCopy(ret)
  cat(ret)
  return(invisible(ret))
}
quoteMe(c(upc, fullName, artist, title, product, units, wasFree))
