Skip to content
Snippets Groups Projects
Commit 62d9918e authored by Johannes Hörmann's avatar Johannes Hörmann
Browse files

fix turnover chart - Months & Documentation

parent 0fba7a41
No related branches found
No related tags found
No related merge requests found
= Turnover
This entity provides charts to display the Turnover.
\ No newline at end of file
This entity provides charts to display the Turnover.
This chart can show any data in a cumulative way:
* It loads the most specific data (e.g. Productgroups) and calculates the layers above (e.g. Productgroups -> Months -> years)
* And then it shows the most top layer (years) at the top. If you click on it, it drills down to the more specific layer (Months / Productgroups)
\ No newline at end of file
......@@ -7,6 +7,26 @@ import("KeywordRegistry_basic");
import("Keyword_lib");
import("system.translate");
/**
* Documentation:
* This chart can show any data in a cumulative way:
* It loads the most specific data (e.g. Productgroups) and calculates the layers above (e.g. Productgroups -> Months -> years)
* And then it shows the most top layer (years) at the top. If you click on it, it drills down to the more specific layer (Months / Productgroups)
*
* Technic:
* 1. Loading data
* The data is loaded via selects in the TurnoverUtil. (You may change this in your porjects to your liking)
* The select has to provide at least the following fields:
* - Type (e.g. "Forecast" / "Turnover") this will split the data into different groups which are displayed ina a seperate color (connected to the chart viewtemplate as "Category"
* - For each layer an ID (e.g. for the years layer a year-number, for the Productgroups the productgroup keyid,...)
* - Optionally: if the displayvalue should be different: a display value for the id.
* The X-axis will display either the ID or the disply value
* - The Value (used as Y-Value) which should be a number
*
* ... (see next comment block)
*/
var turnoverCategory = translate.text('Turnover');
var forecastCategory = translate.text('Forecast');
......@@ -21,6 +41,7 @@ var salesprojectId = vars.exists("$param.SalesprojectId_param") && vars.get("$pa
var data = TurnoverUtil.getTurnoverAndForecastData(maxYear, yearCountToShow, showForecast, showTurnover, salesprojectId);
// this object is for better code with readable names to access the data-fields
var columns = {
type: 0,
year: 1,
......@@ -38,12 +59,22 @@ var countData = {}
var monthDate;
// add all months for all years
/**
* 2. Special treatment for some layers
* Some data needs special treatment. You may ommit these if you don't need it.
* - As there should each month of a year be displayed, this for loops add empty (0.0) datasets for each month.
* (note that it is done for each month to set it initally to 0.0)
*
* NOTE: the _addCount function will be explaned later
*
* ...
*/
for (let y = minYear; y <= maxYear; y++)
{
for (let m = 0; m < 12; m++)
{
monthDate = new Date(y, m-1);
// load the display value for the months
monthDate = new Date(y, m);
monthDate = datetime.toDate(monthDate.getTime(), "MMM yyyy", "UTC");
if (showForecast)
......@@ -54,9 +85,21 @@ for (let y = minYear; y <= maxYear; y++)
}
}
/**
* 3. iterate through all data and add it to the chart
* - this is done via _addCount-calls
* - Note that for turnover MoneyUtils.getGross is called. This is needed because the raw data does provides vat, price, quantity and discount but not the final gross-price
* You may ommit this if it is not needed by your project
*
*
* NOTE: the _addCount function will be explaned later
*
* ...
*/
data.forEach(function(row)
{
monthDate = new Date(row[columns.year], row[columns.month]-1);
// load the display value for the months
monthDate = new Date(row[columns.year], row[columns.month]);
monthDate = datetime.toDate(monthDate.getTime(), "MMM yyyy", "UTC");
switch(row[columns.type])
......@@ -75,50 +118,92 @@ data.forEach(function(row)
}
});
/**
* 4. iterate through the final counts - generate chart
* - this is done via simple push to the final chartData
*/
for (let key in countData) {
var countDataSet = countData[key];
chartData.push([key, countDataSet.parent, countDataSet.category, countDataSet.x, countDataSet.count]);
}
// return the final chart
result.object(chartData);
/**
* add the counts to countData for the given key and value
* 5. _addCount
* - It counts the final values for each layer. So if you put in: (simplified)
* [year1, month5, product10, 50.8]
* it counts +50.8 for each layer:
* year1; += 50.8
* year1;month5; += 50.8
* year1;month5;product10; += 50.8
*
* This values are all stored in the "countData" object and the keys of it are later used as UID.
* The Keys just consist of the concatenated id's mentioned in 1.
*
* You can provide any count of keys so if you need another layer, just add it to the data (1.) and add the keyid (or [keyid, keydisplayvalue]) to the _addCount-calls appended to the array provided as first parameter
*
* @param {Array} pKeys an array containing all keys for this value. If the x-value for one key is different from the key-value: add an array [key, value] instead of only the key
* the first key is the Category
* e.g.
* [
* category,
* year,
* [
* month(number),
* monthName(displayValue)
* ],
* [
* productGroupcodeId,
* productGroupcodeName(displayValue)
* ]
* ]
* This will lead to 3 layers: year -> month -> productGroup
*
* @param {float} pValue the value to display
*/
function _addCount(pKeys, pValue) {
var key = "";
// iterate through all keys (e.g. through each layer) and count for each of them seperately
for (let i = 0; i < pKeys.length; i++) {
let keyId;
let keyName;
// if the key type is not "object" it is a string ("object" means Array of ["id", "displayValue"], "string" means only "id"
if (typeof pKeys[i] != "object")
{
// add key as id and display value
keyId = pKeys[i];
keyName = pKeys[i];
}
else // handle array: first is id seccond is name for X-value
else
{
// handle array: first is id seccond is name for X-value
keyId = pKeys[i][0];
keyName = pKeys[i][1];
}
var parent = key;
// if we are first or second: we are category or the top layer -> we have no parent
if (i < 2)
{
parent = ""
}
// concatenate the previous (parent) key with the new one to get a new unique id
key += ";" + keyId;
// if we are not category
if (i > 0)
{
// add the data to the count-object
if (countData[key] == undefined)
{
// if the key was not added before create it with initial value 0.0
countData[key] = {parent: parent, count: 0.0, category: pKeys[0], x: keyName}; // keys[0] is the category
}
// count
countData[key].count += parseFloat(pValue);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment