/FileCabinet/SuiteScripts/sku-analytics/total-monthly-by-reseller/sa-TotalMonthlyByReseller.js
JavaScript | 342 lines | 95 code | 22 blank | 225 comment | 0 complexity | 95ed62aa9e1bf63cb76b030a870107e6 MD5 | raw file
- define([
- "N/search",
- "../lib/ramda.min",
- "../lib/moment.min",
- "../lib/sa-DateUtilities"
- ], function (s, R, moment, d) {
- /**
- * Business logic and data manipulation methods for the Total Monthly
- * Sales by Reseller data
- *
- * @exports sa/total-monthly-by-reseller
- *
- * @requires N/search
- * @requires ramda
- * @requires moment
- * @requires sa/date-util
- *
- * @copyright 2016 Stoic Software
- * @author Eric T Grubaugh <eric@stoic.software>
- *
- * @NApiVersion 2.x
- * @NModuleScope Public
- */
- var exports = {};
- /**
- * The data format used to define Total Monthly Sales by Reseller data
- *
- * @typedef {Object} MonthlySalesByResellerData
- *
- * @property resellerId {Number} Internal ID of the Reseller
- * @property resellerName {String} Display name of the Reseller
- * @property month {moment} A moment representing the first of the month
- * @property sales {Number} The revenue from sales in the month for the
- * Reseller
- */
- /**
- * The current timestamp at the time this module is loaded
- *
- * @type {moment}
- *
- * @private
- * @property now
- */
- var now = R.always(moment());
- /**
- * monthToData :: moment -> MonthlySalesByResellerData
- *
- * Translates a moment representing a month in the year into a processable
- * data object
- *
- * @governance 0
- *
- * @param m {moment} The moment to translate
- *
- * @return {MonthlySalesByResellerData} Translated moment
- *
- * @private
- * @function monthToData
- */
- function monthToData(m) {
- return {
- "month": m,
- "sales": 0
- };
- }
- /**
- * monthsToData :: [moment] -> [MonthlySalesByResellerData]
- *
- * Translates a list of moments representing a month in the year into a
- * list of processable data objects
- *
- * @governance 0
- *
- * @param data {moment[]} The moments to translate
- *
- * @return {MonthlySalesByResellerData[]} Translated moments
- *
- * @private
- * @function monthsToData
- */
- var monthsToData = R.map(monthToData);
- /**
- * generateYear :: moment -> [MonthlySalesByResellerData]
- *
- * @governance 0
- *
- * @param seedDate {moment} The moment to seed year generation
- *
- * @return {MonthlySalesByResellerData[]} Full year of empty sales data
- *
- * @private
- * @function generateYear
- */
- var generateYear = R.pipe(
- d.monthsSameYear,
- monthsToData
- );
- var currentRollingYear = generateYear(now());
- /**
- * emptyYear :: [MonthlySalesByResellerData] ->
- * [MonthlySalesByResellerData]
- *
- * Accepts a list of Monthly Sales by Reseller data and ensures that a
- * value
- * exists for every month in the current rolling year
- *
- * @governance 0
- *
- * @param data {MonthlySalesByResellerData[]} The Monthly Sales by Reseller
- * data to fill out
- *
- * @return {MonthlySalesByResellerData[]} A full year of Monthly Sales by
- * Reseller data
- *
- * @private
- * @function emptyYear
- */
- var emptyYear = R.flip(
- R.useWith(R.map, [
- R.pipe(R.head, R.merge),
- R.identity
- ])
- )(currentRollingYear);
- /**
- * resultToData :: search.Result -> MonthlySalesByResellerData
- *
- * Translates a Total Monthly Sales by Reseller search result into a
- * processable data object
- *
- * @governance 0
- *
- * @param result {search.Result} The search result to translate
- *
- * @return {MonthlySalesByResellerData} Translated search result
- *
- * @private
- * @function resultToData
- */
- function resultToData(result) {
- var month = moment(
- result.getValue({
- "name": "formulatext",
- "summary": s.Summary.GROUP
- }),
- "MMMM YYYY"
- );
- return {
- "resellerId": result.getValue({
- "name": "partner",
- "summary": s.Summary.GROUP
- }),
- "resellerName": result.getText({
- "name": "partner",
- "summary": s.Summary.GROUP
- }),
- "month": month.startOf("month"),
- "sales": parseFloat(result.getValue({
- "name": "amount",
- "summary": s.Summary.SUM
- }))
- };
- }
- /**
- * resultsToData :: [search.Result] -> [MonthlySalesByResellerData]
- *
- * Translates a list of Total Monthly Sales search results into a list of
- * processable data object
- *
- * @governance 0
- *
- * @param data {search.Result[]} The list of search results to translate
- *
- * @return {MonthlySalesByResellerData[]} List of Monthly Sales data objects
- *
- * @private
- * @function resultsToData
- */
- var resultsToData = R.map(resultToData);
- /**
- * sortChronologically :: [MonthlySalesBySkuData] ->
- * [MonthlySalesBySkuData]
- *
- * Sorts a list of Monthly Sales by SKU data chronologically in ascending
- * order
- *
- * @governance 0
- *
- * @param data {MonthlySalesBySkuData[]} The list to sort
- *
- * @return {MonthlySalesBySkuData[]} The sorted list
- *
- * @private
- * @function sortChronologically
- */
- var sortChronologically = R.sortBy(R.pipe(
- R.prop("month"),
- R.invoker(0, "valueOf")
- ));
- var groupByReseller = R.groupBy(R.prop("resellerId"));
- var unionByMonth = R.unionWith(
- R.useWith(d.sameMonth, [R.prop("month"), R.prop("month")])
- );
- var fillYear = R.pipe(
- R.converge(unionByMonth, [R.identity, emptyYear]),
- sortChronologically
- );
- var fillYears = R.map(fillYear);
- /**
- * translateResults :: [search.Result] -> [MonthlySalesByResellerData]
- *
- * Translates the given search results to Monthly Sales by Reseller data
- *
- * @governance 0
- *
- * @param results {search.Result[]} List of Total Monthly Sales by Reseller
- * search results to translate into processable data Objects. Results
- * must be grouped by a formulatext column representing the month and
- * contain a summed quantity column representing the sales for that
- * month
- *
- * @return {MonthlySalesByResellerData[]} Data list processable by the Total
- * Monthly by Reseller module
- *
- * @static
- * @function translateResults
- */
- var translateResults = R.pipe(
- resultsToData,
- groupByReseller,
- fillYears
- );
- /**
- * label :: MonthlySalesByResellerData -> String
- *
- * Generates a label for a MonthlySalesByResellerData object that can be
- * used on, for instance, a chart axis
- *
- * @governance 0
- *
- * @param data {MonthlySalesByResellerData} The data object to generate a
- * label for
- *
- * @return {String} The label for the given data object
- *
- * @private
- * @function label
- */
- var label = R.pipe(
- R.prop("month"),
- d.format("MMM YYYY")
- );
- /**
- * labels :: [MonthlySalesByResellerData] -> [String]
- *
- * Generates the list of axis labels for the given dataset
- *
- * @governance 0
- *
- * @param data {MonthlySalesByResellerData[]} The dataset to transform to
- * labels
- *
- * @return {String[]} The list of labels to be used for the data
- *
- * @static
- * @function labels
- */
- var labels = R.always(R.pipe(
- sortChronologically,
- R.map(label)
- )(currentRollingYear));
- /**
- * resellerGroupToDataset :: [MonthlySalesByResellerData] -> Chart.Dataset
- *
- * Translates the Monthly Sales data for a single Reseller into a chartable
- * dataset
- *
- * @governance 0
- *
- * @param data {MonthlySalesByResellerData[]} The Monthly Sales data for a
- * single Reseller
- *
- * @return {Chart.Dataset} Chartable dataset for the item group
- *
- * @private
- * @function resellerGroupToDataset
- */
- function resellerGroupToDataset(data) {
- return {
- "label": R.pipe(R.head, R.prop("resellerName"))(data),
- "data": R.pluck("sales")(data)
- };
- }
- /**
- * datasets :: {k: MonthlySalesByResellerData} -> [Chart.Dataset]
- *
- * Translates an Object of Monthly Sales by Reseller data that is grouped
- * by Reseller into a list of chartable datasets
- *
- * @governance 0
- *
- * @param data {Object} The Monthly Sales data grouped by Reseller
- *
- * @return {Number[]} The values to be used for the chart
- *
- * @static
- * @function datasets
- */
- var datasets = R.pipe(
- R.map(resellerGroupToDataset),
- R.values,
- R.sortBy(R.pipe(R.prop("data"), R.sum)),
- // TODO Parameterize this somehow
- R.takeLast(5),
- R.tap(console.log)
- );
- exports.datasets = datasets;
- exports.labels = labels;
- exports.translateResults = translateResults;
- return exports;
- });