Something went wrong on our end
-
Pascal Neub authoredPascal Neub authored
process.js 13.52 KiB
import("system.datetime");
import("system.logging");
import("KeywordData_lib");
import("Sql_lib");
import("system.neon");
import("system.vars");
import("system.util");
import("system.translate");
import("system.db");
import("system.eMath");
import("system.question");
import("Util_lib");
import("Keyword_lib");
import("system.neonTools");
import("KeywordRegistry_basic");
/**
* Methods used by the Salesproject.
* Do not create an instance of this!
*
* @class
*/
function Salesproject() {}
/**
* Delivers the next valid project number (has to be unique)
*
* @result {String} next valid project number
*/
Salesproject.getNextProjectNumber = function() {
return NumberSequencingUtils.getNextUniqueNumber("PROJECTCODE", "SALESPROJECT");
}
/**
* Checks if the passed project number is valid (has to be unique)
*
* @param {String} projectNumber project number to check
*
* @result {Boolean} passed number is valid
*/
Salesproject.validateProjectNumber = function(projectNumber) {
return NumberSequencingUtils.validateUniqueNumber(projectNumber, "PROJECTCODE", "SALESPROJECT");
}
/**
* Insert a new milestone.
*
* @param {String} salesprojectId of the salesproject
* @param {Integer} type can be any value of the keyword SALESPROJECT.MILESTONE.KIND
* @param {Integer} value value of the phase or state
* @param {Boolean} [notifyForecast=false] if true, notify user to update the forecast
*
* @result {Boolean} true if inserted, else false
*/
Salesproject.insertMilestone = function(salesprojectId, type, value, notifyForecast) {
if (KeywordUtils.exists(value, type)) {
var id = newSelect("SALESPROJECT_MILESTONE.SALESPROJECT_MILESTONEID")
.from("SALESPROJECT_MILESTONE")
.where("SALESPROJECT_MILESTONE.SALESPROJECT_ID", salesprojectId)
.and("SALESPROJECT_MILESTONE.KIND", type)
.and("SALESPROJECT_MILESTONE.DATE_END is null")
.cell();
newWhere("SALESPROJECT_MILESTONE.SALESPROJECT_ID", salesprojectId)
.and("SALESPROJECT_MILESTONE.KIND", type)
.and("SALESPROJECT_MILESTONE.DATE_END is null")
.updateData(true, "SALESPROJECT_MILESTONE", ["DATE_END"], null, [vars.get("$sys.date")]);
db.insertData(
"SALESPROJECT_MILESTONE",
["SALESPROJECT_MILESTONEID", "SALESPROJECT_ID", "KIND", "MILESTONEVALUE", "DATE_START", "PARENT_ID"],
null,
[util.getNewUUID(), salesprojectId, type, value, vars.get("$sys.date"), id]);
if (notifyForecast) {
Salesproject.notifyToUpdateForecast()
}
return true;
}
return false;
}
/**
* Notify the user to update the forecast
*/
Salesproject.notifyToUpdateForecast = function() {
if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_NEW)
{
// TODO: workflows
}
}
/**
* get the title of a salesproject by id
* @param {String} pSalesProjectId
* <br>
* @return {String} title of the salesproject
*/
Salesproject.getSalesProjectTitleById = function(pSalesProjectId)
{
return newSelect("PROJECTTITLE")
.from("SALESPROJECT")
.where("SALESPROJECT.SALESPROJECTID", pSalesProjectId)
.cell();
}
/**
* Create a new Salesproject and open the Salesproject context in NEW-mode
*/
Salesproject.createNewSalesproject= function(pRelationId)
{
var params = {};
if (pRelationId)
params["ContactId_param"] = pRelationId;
neon.openContext("Salesproject", null, null, neon.OPERATINGSTATE_NEW, params);
}
/**
* Create a new Salesproject from a organisation
*/
Salesproject.createNewSalesprojectFromOrg = function(pRelationId, pSalesprojectName)
{
var uid = util.getNewUUID();
db.insertData(
"SALESPROJECT",
["SALESPROJECTID", "CONTACT_ID", "PROJECTTITLE", "PROJECTCODE", "STARTDATE", "STATUS", "PHASE"],
null,
[uid, pRelationId, pSalesprojectName, Salesproject.getNextProjectNumber(),
vars.get("$sys.date"), $KeywordRegistry.salesprojectState$open(), $KeywordRegistry.salesprojectPhase$nqc()]);
return uid;
}
/**
* Insert a new touchpoint for the salesproject
*/
Salesproject.insertTouchPoint = function(pSalesprojectId, pTouchPoint, pInfo)
{
var uid = util.getNewUUID();
db.insertData(
"SALESPROJECT_TOUCHPOINT",
["SALESPROJECT_TOUCHPOINTID", "SALESPROJECT_ID", "ENTRYDATE", "INFO", "TOUCHPOINT"],
null,
[uid, pSalesprojectId, vars.get("$sys.date"), pInfo, pTouchPoint]);
return uid;
}
/**
* Set a new phase for the salesproject
*/
Salesproject.updateSalesprojectPhase = function(pSalesprojectId, pPhase)
{
newWhere("SALESPROJECT.SALESPROJECTID", pSalesprojectId)
.updateData(true, "SALESPROJECT", ["PHASE"], null, [pPhase]);
}
/**
* Methods used by the SalesprojectConversionRate.
* Do not create an instance of this!
*
* @class
*/
function SalesprojectConversionRate() {
this.MILESTONES = {};
this.isGrouping = null;
}
/**
* Returns the Mapping of the Fields and FilterExtention for the grouping
*
* @param {Boolean} pRightOneTables if true you get the Mappings with the actual Tablenames
*
* @return {Object}
*/
SalesprojectConversionRate.groupMapping = function (pRightOneTables)
{
let sqlHelper = new SqlMaskingUtils();
if (pRightOneTables)
{
return {
"AB_KEYWORD_ENTRYID_KEYID": "AB_KEYWORD_ENTRY.KEYID",
"#EXTENSION.Year.Year#NUMBER" : sqlHelper.yearFromDate("SALESPROJECT_MILESTONE.DATE_START"),
"#EXTENSION.Month.Month#NUMBER" : sqlHelper.monthFromDate("SALESPROJECT_MILESTONE.DATE_START")
}
}
let dateStartYear = sqlHelper.yearFromDate("SALESPROJECT_MILESTONE.DATE_START");
let dateStartMonth = sqlHelper.monthFromDate("SALESPROJECT_MILESTONE.DATE_START");
return {
"AB_KEYWORD_ENTRYID_KEYID": ["AB_KEYWORD_ENTRY.KEYID", "AB_KEYWORD_ENTRY.TITLE", "AB_KEYWORD_ENTRY.SORTING"],
"#EXTENSION.Year.Year#NUMBER" : [dateStartYear, dateStartYear, dateStartYear],
"#EXTENSION.Month.Month#NUMBER" : [dateStartMonth, dateStartMonth, dateStartMonth]
}
}
/**
* Returns the FieldMappings for the FilterExtentions for the giffen Table
* if there is a TableAlias used as pField there have to be a pTable
*
* @param {String} pField the filtered Feld in the format Table.Column or TableAlias.Column
* @param {Boolean} pIsAll if true you get the Mapping for all Fields
* @param {Integer} pTable the Table of the used TableAlias
*
* @return {Object} FieldMapping
*/
SalesprojectConversionRate.filterMapping = function(pField, pIsAll, pTable)
{
let sqlHelper = new SqlMaskingUtils();
if (pField == null){
return {
"AB_KEYWORD_ENTRYID_KEYID": "AB_KEYWORD_ENTRY.KEYID",
"#EXTENSION.Year.Year#NUMBER" : null,
"#EXTENSION.Month.Month#NUMBER" : null,
"#EXTENSION.DATE_START.DATE_START#DATE" : null
}
} else {
let mapping = {
"AB_KEYWORD_ENTRYID_KEYID": null,
"#EXTENSION.Year.Year#NUMBER" : function (pValue, pOperator) {
return _getFilterByFunction(pValue, pOperator, sqlHelper.yearFromDate(pField));
}
,
"#EXTENSION.Month.Month#NUMBER" : function (pValue, pOperator) {
return _getFilterByFunction(pValue, pOperator, sqlHelper.monthFromDate(pField));
}
,
"#EXTENSION.DATE_START.DATE_START#DATE" : pField
};
if (pIsAll){
mapping.AB_KEYWORD_ENTRYID_KEYID = "AB_KEYWORD_ENTRY.KEYID";
}
if (pTable) {
let arr = pField.split(".");
mapping["#EXTENSION.DATE_START.DATE_START#DATE"] = [pTable, arr[1], arr[0]];
}
return mapping;
}
function _getFilterByFunction (pValue, pOperator, pAggregate) {
let sqlCond = "" + pAggregate;
if (pOperator == "EQUAL")
sqlCond += " = " + pValue + "";
else if (pOperator == "NOT_EQUAL")
sqlCond += " <> " + pValue + "";
else
sqlCond = "1=1";
return sqlCond;
}
}
/**
* Returns the Phases Keywordkeys
*
* @return {Array} Phases Keywordkeys
*/
SalesprojectConversionRate.prototype.PHASE = function () {
return KeywordData.getSimpleData($KeywordRegistry.salesprojectPhase()).map(function (r) {
return r[0];
});
}
/**
* Add Milestones to the Phases of the given Grouping.
* The Milestone is adding to the given and overlying Phases.
*
* @param {String} [pSalesprojectID] the ID of the Salesproject
* @param {String} [pPhase] the phase of the milestone
* @param {String} [pGrouping] the grouping Field
*/
SalesprojectConversionRate.prototype.insertMilestone = function (pSalesprojectID, pPhase, pGrouping) {
let logDetail = ["SALESPROJECT_MILESTONEID: " + pSalesprojectID, "PHASE: " + pPhase, "GROUPING: " + pGrouping]
let indexPhase = this.PHASE().indexOf(pPhase)
if (indexPhase > -1) {
let tempPhases;
if (pGrouping)
{
if ((!this.isGrouping) && this.isGrouping != null){
logging.log(translate.text("The grouping is not active, but there is one given!"), logging.ERROR, logDetail);
return;
}
if (!this.MILESTONES[pGrouping])
this.MILESTONES[pGrouping] = {};
this.isGrouping = true;
tempPhases = this.MILESTONES[pGrouping];
}
else if (this.isGrouping && this.isGrouping != null)
{
logging.log(translate.text("The grouping is active, but there is no one given!"), logging.ERROR, logDetail);
return;
}
else
{
tempPhases = this.MILESTONES;
this.isGrouping = false;
}
if (!tempPhases[pPhase])
{
tempPhases[pPhase] = {};
tempPhases[pPhase].size = 0;
}
if (!tempPhases[pPhase][pSalesprojectID])
{
tempPhases[pPhase][pSalesprojectID] = true;
tempPhases[pPhase].size++;
}
if (indexPhase - 1 != -1)
this.insertMilestone(pSalesprojectID, this.PHASE()[indexPhase - 1], pGrouping);
}
else
{
logging.log(translate.withArguments("The given Phase \"%0\" can not be found.", [pPhase]), logging.ERROR, logDetail);
}
}
/**
* Calculates the Conversion Rate for evry grouping field
*
* @param {Array} [pFilter] the ids of the phases, which has to be filtered
*
*/
SalesprojectConversionRate.prototype.getConversionRates = function (pFilter) {
if (this.isGrouping == null)
logging.log(translate.text("You have to use the insertMilestone Function before."), logging.ERROR);
else if (this.isGrouping)
{
let groupingResults = [];
Object.keys(this.MILESTONES).forEach(function (grouping) {
let count = 0;
let sum = 0.0;
let sumMilestones = 0;
this._getConversionRatesofPhases(this.MILESTONES[grouping], pFilter).forEach(function (phase) {
sum += phase[3];
sumMilestones += phase[0]
count++;
}, this);
if (sumMilestones != 0)
groupingResults.push(["" + sumMilestones, grouping, this._getTitleOfKey(grouping, true), (sum / count)])
}, this);
return groupingResults
}
else
{
return this._getConversionRatesofPhases(this.MILESTONES, pFilter);
}
return [];
}
/**
* Calculates the Conversion Rate for the phases
*
* @param {Array} [pPhases] the phases of the current grouping
* @param {Array} [pFilter] the ids of the phases, which has to be filtered
*
*/
SalesprojectConversionRate.prototype._getConversionRatesofPhases = function (pPhases, pFilter) {
let results = [];
this._addToResult(pPhases[this.PHASE()[0]].size, this.PHASE()[0], -1, results, pFilter);
for (let i = 1; i < Object.keys(pPhases).length ;i++)
{
this._addToResult(pPhases[this.PHASE()[i]].size, this.PHASE()[i], pPhases[this.PHASE()[i-1]].size, results, pFilter);
}
return results;
}
/**
* Adds the Values to the result array
*
* @param {Array} [pCount] the count of the phase
* @param {Array} [pId] the id of the phase
* @param {Array} [pPreCount] the count of the previous phase
* @param {Array} [pResult] the array into which the data will be added
* @param {Array} [pFilter] the ids of the phases, which has to be filtered
*/
SalesprojectConversionRate.prototype._addToResult = function (pCount, pId, pPreCount, pResult, pFilter){
if ((pFilter && pFilter.indexOf(pId)> -1) || !pFilter)
// COUNT, ID, TITLE, CONVERSION_RATE
pResult.push([this.isGrouping ? pCount : ("" + pCount), pId, this._getTitleOfKey(pId), pPreCount == -1 ? 0 : (pCount /pPreCount)]);
}
/**
* gets the title of the key
* @param {Array} [pKey] the key, which has to translate
* @param {Array} [pIsGrouping] is this title of a grouping
*/
SalesprojectConversionRate.prototype._getTitleOfKey = function (pKey, pIsGrouping) {
if (pIsGrouping)
{
if (pKey <= 12)
{
// When convert the Number of the Month to the Month name it doesn't matter which Year is used, so here is the Year 2020 hard-coded.
let monthDate = new Date(2020, parseInt(pKey)-1);
return translate.text(datetime.toDate(monthDate.getTime(), "MMMM", "UTC"));
}
}
else
return KeywordUtils.getViewValue($KeywordRegistry.salesprojectPhase(),pKey);
return pKey;
}