SmartIT_Extensions/BMC/smart-it-full/scripts/app/common/expression-engine/expression-object-value-map...

640 lines
32 KiB
JavaScript

"use strict";
(function () {
'use strict';
angular.module('myitsmApp')
.service('objectValueMapperService', ['$q', 'metadataModel', 'configurationModel', '$log', '$timeout',
'$rootScope', 'events', 'fieldValidationModel',
function ($q, metadataModel, configurationModel, $log, $timeout, $rootScope, events, fieldValidationModel) {
var ticketType = '', ticketMetadata, ootbMapping, fieldList = {}, parentFieldList = {}, widgetMemberFieldList = {}, expressionMapper = {
__constantExpressions: []
}, providerActionExpressionMapper = {
__constantExpressions: []
}, widgetMemberMap = {}, widgetFieldMap = {}, ootbFieldValueMap = {}, ticket, providerActionsList = [], fieldActionMapping = {}, providerActionTriggerField = {}, isCopyChangeScreen = false, isProviderActionCallExpressionEventRegistered, isParentShelved = false, parentMapping = {};
this.clearMap = function (type) {
fieldList = {};
expressionMapper = {
__constantExpressions: []
};
providerActionExpressionMapper = {
__constantExpressions: []
};
ticketType = type;
isCopyChangeScreen = false;
};
this.shelveAsParent = function (type) {
parentFieldList = fieldList;
parentMapping = {
expressionMapper: expressionMapper,
providerActionExpressionMapper: providerActionExpressionMapper,
isCopyChangeScreen: isCopyChangeScreen
};
isParentShelved = true;
this.clearMap(type);
};
this.unshelveParent = function (type) {
this.clearMap(type);
fieldList = parentFieldList;
expressionMapper = parentMapping.expressionMapper;
providerActionExpressionMapper = parentMapping.providerActionExpressionMapper;
isCopyChangeScreen = parentMapping.isCopyChangeScreen;
isParentShelved = false;
};
this.isShelvedParentEmpty = function () {
return !isParentShelved;
};
this.setCopyChangeTicket = function () {
isCopyChangeScreen = true;
};
this.isCopyChange = function () {
return isCopyChangeScreen;
};
this.changeMode = function (mode, firstLoad, ticketObj) {
if (firstLoad) {
ootbFieldValueMap = configurationModel.get('ootbFieldValueMap.' + (ticketType || ticketObj.type));
widgetFieldMap = configurationModel.get('widgetFieldMap');
ticket = ticketObj;
metadataModel.getMetadataByType(ticketType || ticketObj.type).then(function (metadata) {
ootbMapping = metadata.ootbMapping;
ticketMetadata = metadata;
});
}
};
this.getTicketType = function () {
return ticketType;
};
this.getFieldList = function () {
return fieldList;
};
this.addFields = function (fields) {
_.each(fields, function (field) {
if (!field.isWidgetMember() && field.dataType !== 'group') {
console.log(field.name + ' ' + field.dataType);
if (widgetFieldMap[ticketType] && widgetFieldMap[ticketType][field.name]) {
_.each(widgetFieldMap[ticketType][field.name], function (member) {
widgetMemberMap[member] = field.name;
});
}
else if (field.members.length) {
_.each(field.members, function (member) {
widgetMemberMap[member.name] = field.name;
});
}
fieldList[field.name] = field;
_handleFieldExpression(field);
}
else if (field.dataType === 'group') {
_.each(field.members, function (member) {
fieldList[member.name] = member;
_handleFieldExpression(member);
});
}
else {
widgetMemberFieldList[field.name] = field;
}
});
};
this.getFieldsByType = function (fieldType) {
var fieldArray = [];
_.forEach(fieldList, function (field) {
if (field.type === fieldType) {
fieldArray.push(field);
}
});
return fieldArray;
};
this.getValueByFieldName = function (fieldName) {
return fieldList[fieldName] ? fieldList[fieldName].value : '';
};
this.getExactValueByFieldName = function (fieldName) {
var value, ootbFieldValMap = ootbFieldValueMap[fieldName], valObj, dataType, tempObj;
//Fix for SW00542661 - WO and Task uses assigneeName while the assignee widget is built as assignee,
//so it fails to find it in the fieldList and looks up in the ticketObject which has the old value so the evaluation fails
if (fieldName === 'assigneeName') {
fieldName = 'assignee';
}
if (ootbFieldValMap && fieldList[ootbFieldValMap.fieldName]) {
value = _.get(fieldList[ootbFieldValMap.fieldName].value, ootbFieldValMap.path, '');
//SW00542730 - fix
//Todo: Need to think of better approach
if (typeof value === 'object' && value !== null && value.name) {
value = value.name;
}
}
else if (widgetMemberMap[fieldName] && fieldList[widgetMemberMap[fieldName]] && fieldList[widgetMemberMap[fieldName]].type === 'category') {
valObj = _.find(fieldList[widgetMemberMap[fieldName]].value.listOfTiers, { name: fieldName });
value = valObj.selectedValue || '';
}
//It could be custom field so lookup directly in fieldList
if (!value) {
value = fieldList[fieldName] ? fieldList[fieldName].value : undefined;
}
//Just fallback to ticketObject which was loaded if still null
if (value === undefined && ootbMapping && ootbMapping[fieldName]) {
value = _.get(ticket, ootbMapping[fieldName][0], '');
if (!value && ootbMapping[fieldName][1]) {
value = _.get(ticket, ootbMapping[fieldName][1], '');
}
}
if (value && value.toString() === '[object Object]') {
value = '';
}
if (widgetMemberMap[fieldName] && fieldList[widgetMemberMap[fieldName]]) {
tempObj = _.find(fieldList[widgetMemberMap[fieldName]].members, { name: fieldName });
dataType = tempObj ? tempObj.type : '';
}
if (!dataType) {
dataType = fieldList[fieldName] ? fieldList[fieldName].type : '';
}
if (value && _.contains(['dateField', 'dateTimeField'], dataType)) {
//convert to epoch
value = new Date(value).getTime();
}
if (value || value === 0 || value === false) {
return value;
}
else {
return '';
}
};
this.setValueByFieldName = function (fieldName, value) {
var field = fieldList[fieldName];
if (field) {
field.setValue(value);
}
};
this.getFieldByName = function (fieldName) {
if (fieldList[fieldName]) {
return fieldList[fieldName];
}
};
this.getFieldPropertyValue = function (fieldName, propertyName) {
var field, widgetName, widget, statusFieldVal, matchedStatus;
field = this.getFieldByName(fieldName);
if (!field) {
widgetName = widgetMemberMap[fieldName];
widget = this.getFieldByName(widgetName);
field = _.find(widget.members, { name: fieldName });
}
if (fieldName === 'statusReason' || fieldName === 'taskStatusReason') {
if (propertyName === 'isReadOnly') {
return field && field[propertyName];
}
statusFieldVal = fieldName === 'taskStatusReason' ? this.getValueByFieldName('taskStatus') : this.getValueByFieldName('status');
matchedStatus = _.find(ticketMetadata.statuses, { name: statusFieldVal });
if (propertyName === 'isRequired') {
var statusReasonFieldName = 'statusReason', changeTiming = //fieldValidationModel uses statusReason even for task
void 0; //fieldValidationModel uses statusReason even for task
if (this.getTicketType() === EntityVO.TYPE_CHANGE) {
var changeClass = this.getValueByFieldName('changeClass');
changeTiming = changeClass.timing;
}
return matchedStatus.statusReasons ?
fieldValidationModel.isFieldRequired(ticketType, statusFieldVal, changeTiming, statusReasonFieldName) : false;
}
if (propertyName === 'isHidden') {
return !matchedStatus.statusReasons ? true : false;
}
}
else {
if (widget && widget.type === 'category' && fieldName.indexOf('Tier1') === -1 && propertyName === 'isRequired') {
return field && field[propertyName];
}
return (field && field[propertyName]) || (widget && widget[propertyName]);
}
};
/**
* Get field metadata using field name and itsm field id (optional)
*
* @param {String} fieldName - field name to search
* @param {String} id - itsm field id to narrow search result
* @returns {FieldVO} field - matching field definition
*/
this.getFieldDefinitionByName = function (fieldName, id) {
var field = this.getFieldByName(fieldName), ootbFieldValMap = ootbFieldValueMap[fieldName] || {}, parentWidgetName = widgetMemberMap[fieldName];
if (!field || (id && id !== field.itsmFieldId)) {
var parentField = this.getFieldByName(ootbFieldValMap.fieldName || parentWidgetName);
if (parentField) {
var searchParam = { name: fieldName };
if (id) {
searchParam.itsmFieldId = id;
}
field = _.find(parentField.members, searchParam);
}
}
return field;
};
this.setByProperty = function (fieldName, property, value, isWidget, source) {
$log.debug('Set ' + fieldName + ' property ' + property + ' to ' + value);
//ignore if typeof value is function
if (typeof value !== 'function') {
switch (property) {
case 'required':
fieldList[fieldName].isRequired = value;
break;
case 'hide':
fieldList[fieldName].isHidden = value;
break;
case 'readOnly':
fieldList[fieldName].isReadOnly = value;
break;
case 'value':
if (isWidget) {
_setWidgetValue(fieldName, value, source);
}
else {
_setFieldValue(fieldName, value, source);
}
break;
}
if (value && (property === 'required' || property === 'hide' || property === 'readOnly')) {
if (isWidget) {
var widgetMembers = this.getWidgetMembers(fieldName);
if (widgetMembers) {
$rootScope.$broadcast(events.WIDGET_VALUE_CHANGE, { fieldName: fieldName, memberName: widgetMembers, isCalledFromSetProp: true, source: source });
}
}
else {
$rootScope.$broadcast(events.FIELD_VALUE_CHANGE, { name: fieldName, isCalledFromSetProp: true, source: source });
}
}
}
};
this.setFieldFromProvider = function (dataMap, mappings) {
var deferred = $q.defer(), self = this, objWidgetMap = {
impactedService: 'ASSET',
causalCI: 'ASSET',
assignee: 'PERSON',
assigneeSupportGroups: 'GROUP',
customer: 'PERSON',
site: 'SITE',
changeLocation: 'SITE',
locationCompany: 'LOCATION',
contact: 'PERSON',
requestedFor: 'PERSON',
changeManager: 'PERSON',
changeCoordinator: 'PERSON',
changeCoordinatorSupportGroups: 'GROUP',
changeManagerSupportGroups: 'GROUP',
product: 'CATEGORY',
resolutionOperational: 'CATEGORY',
resolutionProduct: 'CATEGORY',
operational: 'CATEGORY',
targetDate: 'DATE',
scheduledDates: 'DATE',
actualDates: 'DATE'
}, dummy = {
ASSET: {
ci: {
instanceId: '',
name: '',
classId: ''
}
},
GROUP: {
supportGroups: '',
name: '',
id: '',
organization: '',
company: {
name: ''
}
},
SITE: {
site: {
name: ''
},
region: {
name: ''
},
siteGroup: {
name: ''
},
attributeMap: {
siteAddress: {
street: '',
city: '',
state: '',
country: '',
zip: ''
}
}
},
LOCATION: {
locationCompany: ''
},
PERSON: {
firstName: '',
lastName: '',
fullName: '',
organization: '',
loginId: '',
personId: '',
id: '',
isVIP: '',
site: {
name: '',
siteGroup: '',
region: '',
address: {
street: '',
city: '',
state: '',
country: '',
zip: ''
}
},
company: {
name: ''
}
},
CATEGORY: {
name: '',
tiers: {}
},
DATE: {
"scheduledStartDate": '',
"scheduledEndDate": '',
"actualStartDate": '',
"actualEndDate": '',
"targetDate": ''
}
}, widgetSetFields = {}, customSetFields = {}, customSetWidgets = {};
_.each(mappings, function (map) {
var fieldName = map.mappedFieldValue;
if (map.type === 'output') {
var mappedField = self.getFieldDefinitionByName(fieldName, map.mappedFieldId), mappedValue = dataMap[map.mappedFieldId];
if (mappedField && mappedField.isDropdownField()) {
var mappedValueOption = _.find(mappedField.options, { name: mappedValue });
if (mappedValueOption) {
mappedValue = mappedValueOption.name;
}
}
//check if this is custom or widget
if (fieldList[fieldName] && !fieldList[fieldName].isWidget()) {
customSetFields[fieldName] = mappedValue;
}
else if (fieldList[fieldName] && _.includes(['priority', 'status', 'desc', 'phoneNumber', 'internetEmail', 'changeClass', 'organization'], fieldName)) {
customSetWidgets[fieldName] = mappedValue;
}
else if (widgetMemberMap[fieldName] && fieldList[widgetMemberMap[fieldName]] && fieldList[widgetMemberMap[fieldName]].type === 'category') {
if (!widgetSetFields[widgetMemberMap[fieldName]]) {
widgetSetFields[widgetMemberMap[fieldName]] = _.cloneDeep(dummy[objWidgetMap[widgetMemberMap[fieldName]]]);
widgetSetFields[widgetMemberMap[fieldName]].name = widgetMemberMap[fieldName]; //fieldList[widgetMemberMap[fieldName]].fieldName;
}
widgetSetFields[widgetMemberMap[fieldName]].tiers[fieldName] = mappedValue;
if (mappedValue) {
if (!(widgetSetFields[widgetMemberMap[fieldName]].changedTiers)) {
widgetSetFields[widgetMemberMap[fieldName]].changedTiers = [];
}
widgetSetFields[widgetMemberMap[fieldName]].changedTiers.push(fieldName);
}
}
else {
if (ootbFieldValueMap[fieldName] && ootbFieldValueMap[fieldName].fieldName) {
//var dataValue = (ootbFieldValueMap[fieldName].path.indexOf('.') !== -1) ? buildObject(ootbFieldValueMap[fieldName].path.split('.'), 0, mappedValue) : { ootbFieldValueMap.fieldName.path : mappedValue};
if (!widgetSetFields[ootbFieldValueMap[fieldName].fieldName]) {
var widgetValueMock = dummy[objWidgetMap[ootbFieldValueMap[fieldName].fieldName]];
if (widgetValueMock) {
widgetSetFields[ootbFieldValueMap[fieldName].fieldName] = _.cloneDeep(dummy[objWidgetMap[ootbFieldValueMap[fieldName].fieldName]]);
}
else {
widgetSetFields[ootbFieldValueMap[fieldName].fieldName] = {};
}
}
_.set(widgetSetFields[ootbFieldValueMap[fieldName].fieldName], ootbFieldValueMap[fieldName].path, mappedValue);
}
}
}
});
console.log('customSetFields-', customSetFields);
Object.keys(customSetFields).forEach(function (key) {
_setFieldValue(key, customSetFields[key]);
});
console.log('customSetWidgets-', customSetWidgets);
Object.keys(customSetWidgets).forEach(function (key) {
_setWidgetValue(key, customSetWidgets[key]);
});
console.log('widgetSetFields-', widgetSetFields);
Object.keys(widgetSetFields).forEach(function (key) {
fieldList[key].setValueFlag = widgetSetFields[key];
});
deferred.resolve();
return deferred.promise;
};
this.setProviderActionToExecute = function (action) {
if (!_.find(providerActionsList, { actionId: action.actionId })) {
providerActionsList.push(action);
$rootScope.$broadcast(events.PROVIDER_ACTION, providerActionsList);
}
};
this.getProviderActionsList = function () {
return providerActionsList;
};
this.clearProviderActionFromList = function (action) {
if (providerActionsList.length) {
_.remove(providerActionsList, { actionId: action.id });
}
};
function _setFieldValue(fieldName, value, source) {
console.log('Set field value: ' + fieldName + '=' + value);
/* Todo
* 1. Get Field type
* 2. convert the value to field type
* * like casting for date type and
* * for menu driven fields
* * if it is static menu and if mapping is available in metadata get object value else get data from dynamics election query menu call
*/
var field = fieldList[fieldName];
if (field) {
field.setValueFlag = value;
field.isFromTicketLoad = (source === 'fromTicketLoad') ? true : false;
if (field.isTextField() || field.isTextareaField() || field.isNumberField()) {
value = (field.isTextField() || field.isTextareaField()) ? value + '' : value;
if (value !== '') {
field.setValue(value);
}
else {
field.clearValue();
}
}
else if (field.hasDateDataType() || field.hasDateTimeDataType() || field.hasTimeDataType()) {
_setDateField(field, value);
}
else if (field.isMenuField() || field.isDropdownField() || field.isRadioField()) {
field.setValue(value);
}
}
}
function _setDateField(field, value) {
if (value && moment(value).isValid()) {
if (field.hasDateDataType) {
//as we are offsetting the GMT in setValue thinking that it is coming from server
field.value = new Date(value).getTime();
field.hasValue = true;
}
else {
field.setValue(new Date(value).getTime());
}
}
else {
field.clearValue();
}
}
function _setWidgetValue(fieldName, value, source) {
console.log('Set widget value: ' + fieldName + '=' + value);
var field = fieldList[fieldName];
if (field) {
field.setValueFlag = value;
field.isFromTicketLoad = (source === 'fromTicketLoad') ? true : false;
}
}
this.getExpreesionMapByFieldName = function (fieldName) {
return expressionMapper[fieldName];
};
this.getAllExpressionFields = function () {
return Object.keys(expressionMapper);
};
this.getWidgetMembers = function (name) {
var members = [];
if (widgetFieldMap[ticketType] && widgetFieldMap[ticketType][name]) {
return widgetFieldMap[ticketType][name];
}
else if (fieldList[name] && fieldList[name].members && fieldList[name].members.length) {
_.each(fieldList[name].members, function (m) {
members.push(m.name);
});
return members;
}
else {
return [name];
}
};
this.setProviderActionFieldName = function (fieldName, actionId) {
if (!providerActionTriggerField[fieldName]) {
providerActionTriggerField[fieldName] = [];
}
if (actionId) {
if (getActionIndex(fieldName, actionId) === -1) {
providerActionTriggerField[fieldName].push(actionId);
}
}
};
this.clearProviderActionFieldName = function (fieldName, actionId) {
if (actionId && providerActionTriggerField[fieldName] && providerActionTriggerField[fieldName].length > 0) {
var currIndex = getActionIndex(fieldName, actionId);
if (currIndex !== -1) {
providerActionTriggerField[fieldName].splice(currIndex, 1);
}
}
};
function getActionIndex(fieldName, actionId) {
return providerActionTriggerField[fieldName] && providerActionTriggerField[fieldName].indexOf(actionId);
}
this.getProviderActionFieldName = function (fieldName) {
return providerActionTriggerField[fieldName] && providerActionTriggerField[fieldName].length > 0 ? fieldName : false;
};
this.getProviderActionExpressionMapByFieldName = function (fieldName) {
return providerActionExpressionMapper[fieldName];
};
this.getAllProviderActionExpressionFields = function () {
return Object.keys(providerActionExpressionMapper);
};
this.addToProviderActionExpressionMapper = function (expression, action) {
var variables = _extractFieldVariables(expression);
if (!variables.length) {
providerActionExpressionMapper.__constantExpressions.push({
expression: expression,
action: action,
actionId: action.id
});
}
_.each(variables, function (fieldVariable) {
if (!providerActionExpressionMapper[fieldVariable]) {
providerActionExpressionMapper[fieldVariable] = [];
}
if (!_.find(providerActionExpressionMapper[fieldVariable], { actionId: action.id })) {
providerActionExpressionMapper[fieldVariable].push({
expression: expression,
action: action,
actionId: action.id
});
}
});
};
/**
* Set fields that have action(s) mapped to it from launchController
*
* @param {Object} fieldActionMap - map of fields with action(s)
*/
this.setFieldActionMapping = function (fieldAction, ticketType) {
if (ticketType && !fieldActionMapping[ticketType]) {
fieldActionMapping[ticketType] = fieldAction;
}
};
/**
* Get fields that have action(s) mapped to it
*
* @returns {Object} map of fields with actions
*/
this.getFieldActionMapping = function (ticketType) {
return fieldActionMapping[ticketType];
};
this.registerProviderActionCallExpressionEvent = function (event) {
isProviderActionCallExpressionEventRegistered = event;
};
this.isProviderActionEventRegistered = function () {
return isProviderActionCallExpressionEventRegistered;
};
function _handleFieldExpression(field) {
var isWidget = field.isWidget();
if (field.requiredCondition) {
_addToExpressionMapper(field.requiredCondition, field.name, 'required', isWidget);
}
if (field.hideCondition) {
_addToExpressionMapper(field.hideCondition, field.name, 'hide', isWidget);
}
if (field.setValueCondition) {
_addToExpressionMapper(field.setValueCondition, field.name, 'value', isWidget);
}
if (field.readOnlyCondition) {
_addToExpressionMapper(field.readOnlyCondition, field.name, 'readOnly', isWidget);
}
}
function _addToExpressionMapper(expression, fieldName, property, isWidget) {
var variables = _extractFieldVariables(expression);
if (!variables.length) {
expressionMapper.__constantExpressions.push({
expression: expression,
field: fieldName,
property: property,
isWidget: isWidget
});
}
_.each(variables, function (fieldVariable) {
if (!expressionMapper[fieldVariable]) {
expressionMapper[fieldVariable] = [];
}
if (!_.find(expressionMapper[fieldVariable], { field: fieldName, property: property })) {
expressionMapper[fieldVariable].push({
expression: expression,
field: fieldName,
property: property,
isWidget: isWidget
});
}
});
}
function _extractFieldVariables(expression) {
//any string of the form '$variable' or $variable extract them
var regex1 = /(?:^|\W)\$(\w+)(?!\w)/g, regex2 = /['"]\$(.*?)['"]/g, match, matches = [];
while ((match = regex1.exec(expression)) !== null) {
matches.push(match[1]);
}
while ((match = regex2.exec(expression)) !== null) {
matches.push(match[1].replace(/['$]/g, ''));
}
return matches;
}
}]);
})();