"use strict"; /** * Value object for AR field descriptor. * * @author Igor Samulenko * @constructor */ function FieldVO() { // simple fields this.name = ''; this.label = ''; this.arFieldName = ''; this.type = ''; this.dataType = ''; this.required = false; this.requiredCondition = ''; this.requiredConditionFlag = false; this.itsmRequired = false; this.itsmEditable = true; this.editable = true; this.readOnly = false; this.readOnlyCondition = ''; this.readOnlyConditionFlag = false; this.hide = false; this.hideCondition = ''; this.hideConditionFlag = false; this.setValueCondition = ''; this.setValueConditionFlag = false; this.displayOrder = 0; this.order = 0; this.columnIndex = 0; this.hideLabel = false; this.accessible = true; this.min = 0; this.max = 0; this.maxLength = 0; this.precision = 0; this.availability = 0; this.menu = null; this.dependency = []; this.fieldUnavailableOn = []; this.valueField = null; this.members = []; this.options = []; this.groupMember = false; this.rowCount = 0; // flags this.expanded = false; this.sealed = false; this.hasValue = false; this.isDynamic = false; this.widgetMember = false; // derived fields this.value = null; //keep track of ealier selected values this.previousValue = null; this.extension = []; //runtime flags this.isRequired = false; this.isReadOnly = false; this.isHidden = false; this.isMapped = false; this.selectionDisabled = false; this.mappedAction = null; this.selectedIcon = ''; //Use this to propagate setvalue changes via expression this.setValueFlag = '#$#'; } /** * Setup inheritance chain. */ FieldVO.prototype = Object.create(BaseVO.prototype); FieldVO.prototype.constructor = FieldVO; /** * Constants section. * Read-only state will be enforced later. */ FieldVO.prototype.CHARACTER_FIELD = 'characterField'; FieldVO.prototype.TIME_FIELD = 'timeField'; FieldVO.prototype.DATE_FIELD = 'dateField'; FieldVO.prototype.DATE_TIME_FIELD = 'dateTimeField'; FieldVO.prototype.STATIC_SELECTION_FIELD = 'staticSelectionField'; FieldVO.prototype.SELECTION_FIELD = 'selectionField'; FieldVO.prototype.DYNAMIC_SELECTION_FIELD = 'dynamicSelectionField'; FieldVO.prototype.NUMBER_FIELD = 'numberField'; FieldVO.prototype.EMAIL_FIELD = 'emailField'; FieldVO.prototype.PHONE_FIELD = 'phoneField'; FieldVO.prototype.TICKET_TYPE = 'ticketType'; FieldVO.prototype.GROUP_FIELD = 'groupField'; FieldVO.prototype.PERSON_NAME = 'personName'; FieldVO.prototype.PERSON_SITE = 'personSite'; FieldVO.prototype.AFFECTED_ASSET = 'affectedAsset'; FieldVO.prototype.DESCRIPTION = 'description'; FieldVO.prototype.PRIORITY = 'priority'; FieldVO.prototype.STATUS = 'status'; FieldVO.prototype.STATUS_REASON = 'statusReason'; FieldVO.prototype.TICKET_CLASS = 'ticketClass'; FieldVO.prototype.TICKET_RISK = 'ticketRisk'; FieldVO.prototype.CATEGORY_FIELD = 'category'; FieldVO.prototype.CATEGORY_COMPANY = 'categoryCompany'; FieldVO.prototype.ORGANIZATION_FIELD = 'organization'; FieldVO.prototype.SUPPORT_GROUP_FIELD = 'supportGroups'; FieldVO.prototype.PERSON_LOCATION_MAP = 'personLocationMap'; FieldVO.prototype.TICKET_LOCATION = 'ticketLocation'; FieldVO.prototype.TICKET_TEMPLATE = 'ticketTemplate'; FieldVO.prototype.IMPACTED_AREAS = 'impactedAreas'; FieldVO.prototype.TICKET_DATE = 'ticketDate'; FieldVO.prototype.POI_LOCATION = 'poiLocation'; FieldVO.prototype.TASK_PHASE = 'taskPhase'; FieldVO.prototype.DATA_TYPE_TEXT = 'text'; FieldVO.prototype.DATA_TYPE_TEXTAREA = 'textarea'; FieldVO.prototype.DATA_TYPE_DATE_TIME = 'datetime'; FieldVO.prototype.DATA_TYPE_DATE = 'date'; FieldVO.prototype.DATA_TYPE_TIME = 'time'; FieldVO.prototype.DATA_TYPE_RADIO = 'radio'; FieldVO.prototype.DATA_TYPE_DROPDOWN = 'dropdown'; FieldVO.prototype.DATA_TYPE_CHECKBOX = 'checkbox'; FieldVO.prototype.DATA_TYPE_MENU = 'menu'; FieldVO.prototype.DATA_TYPE_INTEGER = 'integer'; FieldVO.prototype.DATA_TYPE_REAL = 'real'; FieldVO.prototype.DATA_TYPE_DECIMAL = 'decimal'; FieldVO.prototype.DATA_TYPE_GROUP = 'group'; FieldVO.prototype.DATA_TYPE_WIDGET = 'widget'; // Widget names FieldVO.prototype.WIDET_NAMES = { assignee: 'assignee', assigneeName: 'assigneeName', changeCoordinator: 'changeCoordinator', changeManager: 'changeManager', requestManager: 'requestManager', customer: 'customer', requestedFor: 'requestedFor', contact: 'contact', assigneeSupportGroups: 'assigneeSupportGroups', priority: 'priority', changeRisk: 'changeRisk', changeRiskBadge: 'changeRiskBadge', changeClass: 'changeClass', changeLocation: 'changeLocation', impactedAreas: 'impactedAreas', taskPhase: 'taskPhase' }; FieldVO.prototype.ASSIGNMENT_WIDGETS = [ FieldVO.prototype.WIDET_NAMES.assignee, FieldVO.prototype.WIDET_NAMES.assigneeName, FieldVO.prototype.WIDET_NAMES.changeCoordinator, FieldVO.prototype.WIDET_NAMES.changeManager, FieldVO.prototype.WIDET_NAMES.requestManager ]; FieldVO.prototype.WIDGET_NAMES_TO_TICKET_PROPERTY_MAP = { assignee: 'assignee', changeCoordinator: 'assignee', changeManager: 'manager', resolutionOperational: 'resolution' }; FieldVO.prototype.SPECIAL_HANDLING_SYSTEM_FIELD_NAMES_LIST = { submitter: { arFieldName: 'Submitter', itsmFieldId: 2 }, submittedBy: { arFieldName: 'Submitter', itsmFieldId: 2 }, company: { arFieldName: 'Location Company', itsmFieldId: 1000000001 }, type: { arFieldName: 'Change Type', itsmFieldId: 1000000181 }, workOrderType: { arFieldName: 'Work Order Type', itsmFieldId: 1000000181 }, locationCompany: { arFieldName: 'Location Company', itsmFieldId: 1000000001 }, rootRequestName: { arFieldName: 'RootRequestName', itsmFieldId: 10000001 }, rootRequestMode: { arFieldName: 'RootRequestMode', itsmFieldId: 10000003 }, name: { arFieldName: 'TaskName', itsmFieldId: 10007000 }, rootRequestInstanceId: { arFieldName: 'RootRequestInstanceID', itsmFieldId: 10000000 }, taskType: { arFieldName: 'TaskType', itsmFieldId: 10001980 } }; /** * @override * @return {Array} */ FieldVO.prototype.getProps = function () { return BaseVO.prototype.getProps().concat('name', 'label', 'type', 'dataType', 'required', 'itsmRequired', 'requiredCondition', 'requiredConditionFlag', 'itsmEditable', 'editable', 'readOnly', 'readOnlyCondition', 'readOnlyConditionFlag', 'hide', 'hideCondition', 'hideConditionFlag', 'setValueCondition', 'setValueConditionFlag', 'displayOrder', 'columnIndex', 'hideLabel', 'min', 'max', 'maxLength', 'precision', 'availability', 'menu', 'dependency', 'valueField', 'isDynamic', 'fieldUnavailableOn', 'members', 'groupMember', 'rowCount', 'arFieldName', 'value', 'extension', 'itsmFieldId', 'ootb', 'widgetMember', 'parentId', 'accessible', 'options'); }; FieldVO.prototype.postBuild = function () { this.readOnly = !this.editable; this.requiredConditionFlag = this.requiredCondition ? 1 : 0; this.readOnlyConditionFlag = this.readOnlyCondition ? 1 : 0; this.hideConditionFlag = this.hideCondition ? 1 : 0; this.setValueConditionFlag = this.setValueCondition ? true : false; this.isRequired = this.required && !this.requiredCondition; this.isReadOnly = this.readOnly && !this.readOnlyCondition; this.isHidden = this.hide && !this.hideCondition; if (this.isWidget()) { this.members = this.members.map(function (memberField) { return new FieldVO().build(memberField); }); } }; /** * Returns true if field is closed for modifications * TODO: change to different name, because it may conflict in future * @returns {boolean} */ FieldVO.prototype.isSealed = function () { return this.itsmRequired || !this.itsmEditable; }; /** * Returns true if field has selection type * @returns {boolean} */ FieldVO.prototype.isStaticSelectionField = function () { return this.type === FieldVO.prototype.STATIC_SELECTION_FIELD; }; /** * Returns true if field has selection type * @returns {boolean} */ FieldVO.prototype.isSelectionField = function () { return this.type === FieldVO.prototype.SELECTION_FIELD; }; /** * Returns true if field has dynamic selection type * @returns {boolean} */ FieldVO.prototype.isDynamicSelectionField = function () { return this.type === FieldVO.prototype.DYNAMIC_SELECTION_FIELD; }; /** * Returns true if field has text data type * @returns {boolean} */ FieldVO.prototype.isTextField = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_TEXT; }; /** * Returns true if field has text area data type * @returns {boolean} */ FieldVO.prototype.isTextareaField = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_TEXTAREA; }; /** * Returns true if field has radio data type * @returns {boolean} */ FieldVO.prototype.isRadioField = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_RADIO; }; /** * Returns true if field has dropdown data type * @returns {boolean} */ FieldVO.prototype.isDropdownField = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_DROPDOWN; }; /** * Returns true if field has checkbox data type * @returns {boolean} */ FieldVO.prototype.isCheckboxField = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_CHECKBOX; }; /** * Returns true if field has checkbox data type * @returns {boolean} */ FieldVO.prototype.isMenuField = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_MENU; }; /** * Returns true if field has number type * @returns {boolean} */ FieldVO.prototype.isNumberField = function () { return this.type === FieldVO.prototype.NUMBER_FIELD; }; /** * Returns true if field has email type * @returns {boolean} */ FieldVO.prototype.isEmailField = function () { return this.type === FieldVO.prototype.EMAIL_FIELD; }; /** * Returns true if field has phone type * @returns {boolean} */ FieldVO.prototype.isPhoneField = function () { return this.type === FieldVO.prototype.PHONE_FIELD; }; /** * Returns true if field has ticket type * @returns {boolean} */ FieldVO.prototype.isTicketType = function () { return this.type === FieldVO.prototype.TICKET_TYPE; }; /** * Returns true if field has ticket date * @returns {boolean} */ FieldVO.prototype.isTicketDate = function () { return this.type === FieldVO.prototype.TICKET_DATE; }; /** * Returns true if field has date type * @returns {boolean} */ FieldVO.prototype.isDateField = function () { return this.type === FieldVO.prototype.DATE_FIELD; }; /** * Returns true if field has time type * @returns {boolean} */ FieldVO.prototype.isTimeField = function () { return this.type === FieldVO.prototype.TIME_FIELD; }; /** * Returns true if field has date/time type * @returns {boolean} */ FieldVO.prototype.isDateTimeField = function () { return this.type === FieldVO.prototype.DATE_TIME_FIELD; }; /** * Returns true if field has "date" data type * @returns {boolean} */ FieldVO.prototype.hasDateDataType = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_DATE; }; /** * Returns true if field has "datetime" data type * @returns {boolean} */ FieldVO.prototype.hasDateTimeDataType = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_DATE_TIME; }; /** * Returns true if field has "time" data type * @returns {boolean} */ FieldVO.prototype.hasTimeDataType = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_TIME; }; FieldVO.prototype.hasDataTypeValueFormat = function () { return [FieldVO.prototype.DATA_TYPE_DATE, FieldVO.prototype.DATA_TYPE_DATE_TIME, FieldVO.prototype.DATA_TYPE_TIME].indexOf(this.dataType) !== -1; }; /** * Returns true if field is available for adding to custom area * @returns {boolean} */ FieldVO.prototype.isAvailable = function () { return +this.availability === 0; }; /** * Returns true if field should save other field value on save * @returns {boolean} */ FieldVO.prototype.linkedFieldExist = function () { return !!this.valueField; }; /** * Returns true if field is a Group field object * @returns {boolean} */ FieldVO.prototype.isGroupField = function () { return this.type === FieldVO.prototype.GROUP_FIELD; }; /** * Returns true if field is a Group member object * @returns {boolean} */ FieldVO.prototype.isGroupMember = function () { return this.groupMember; }; /** * Returns true if field is a Widget member object * @returns {boolean} */ FieldVO.prototype.isWidgetMember = function () { return this.widgetMember; }; /** * Returns true if field is a Category field object * @returns {boolean} */ FieldVO.prototype.isCategoryField = function () { return this.type === FieldVO.prototype.CATEGORY_FIELD; }; /** * Returns true if field is a category location company object * @returns {boolean} */ FieldVO.prototype.isCategoryCompany = function () { return this.type === FieldVO.prototype.CATEGORY_COMPANY; }; /** * Returns number value * * @param {String} value * @returns {*} */ FieldVO.prototype.parseNumberValue = function (value) { // Preventing from setting NaN, as a result of parsing undefined if (_.isUndefined(value)) { return null; } switch (this.dataType) { case FieldVO.prototype.DATA_TYPE_DECIMAL: case FieldVO.prototype.DATA_TYPE_REAL: return parseFloat(value); case FieldVO.prototype.DATA_TYPE_INTEGER: return parseInt(parseInt(value, 10).toFixed(0)); default: return value; } }; /** * Returns value to be sent to server * * @returns {*} */ FieldVO.prototype.getValue = function () { var milliseconds, numberValue; if (!this.hasValue) { return null; } // TODO: extract it to common library // helper function function getTimeInMillis(date) { if (date && _.isDate(date)) { return ((date.getHours() * 60 + date.getMinutes()) * 60) * 1000; } else { return date; } } if (this.isDateField()) { milliseconds = moment(this.value).unix() * 1000; if (this.hasDateDataType()) { // need to transform date to GMT milliseconds -= this.getLocalOffsetInMillisecondsForDate(this.value); } console.log('milliseconds: ' + milliseconds); return milliseconds; } else if (this.isTimeField()) { milliseconds = moment(this.value).unix() * 1000; if (this.hasTimeDataType()) { milliseconds = getTimeInMillis(this.value); } console.log('milliseconds: ' + milliseconds); return milliseconds; } else if (this.isDateTimeField()) { milliseconds = moment(this.value).unix() * 1000; if (this.hasTimeDataType()) { milliseconds = getTimeInMillis(this.value); } else if (this.hasDateDataType()) { // need to transform date to GMT milliseconds -= this.getLocalOffsetInMillisecondsForDate(this.value); } console.log('milliseconds: ' + milliseconds); return milliseconds; } else if (this.isNumberField()) { numberValue = this.parseNumberValue(this.value); return isNaN(numberValue) ? null : numberValue; } else { return this.value; } }; /** * Returns value of the linked field * * @returns {String} */ FieldVO.prototype.getLinkedValue = function () { return this.valueLinkedField; }; /** * Sets value to be used by custom fields * * @param value */ FieldVO.prototype.setValue = function (value) { if (this.isNumberField()) { this.value = this.parseNumberValue(value); } else if ((value || value === 0) && this.isDateTimeField()) { if (this.hasTimeDataType()) { this.value = this.prepareDateForTimeInput(value / 1000); console.log('time: ' + this.value); } else if (this.hasDateTimeDataType()) { this.value = new Date(+value); console.log('datetime: ' + this.value); } else if (this.hasDateDataType()) { // date timestamp comes in GMT, so we need to adjust it to client time zone //it should check timezone offset for the date being set, not for current date //The getTimezoneOffset() method returns the time difference between UTC time and local time, in minutes var gmtDate = new Date(value); this.value = new Date(+value + this.getLocalOffsetInMillisecondsForDate(gmtDate)); console.log('date: ' + this.value); } } else if ((value || value === 0) && this.isTimeField()) { if (this.hasTimeDataType()) { this.value = this.prepareDateForTimeInput(value / 1000); console.log('time: ' + this.value); } } else { this.value = value; } if (this.value !== null && this.value !== undefined) { this.hasValue = true; } }; /** * Sets other field value value to be used by custom fields * * @param value */ FieldVO.prototype.setLinkedFieldValue = function (value) { if (this.linkedFieldExist()) { this.valueLinkedField = value; } }; /** * Clears field value */ FieldVO.prototype.clearValue = function () { this.value = null; this.hasValue = false; }; /** * Clears other field value */ FieldVO.prototype.clearLinkedFieldValue = function () { this.valueLinkedField = null; }; /** * Returns true if required field has value, * optional fields are always valid * @returns {boolean|*} */ FieldVO.prototype.isValid = function () { return this.required ? (angular.isDefined(this.value) && this.value !== null) : true; }; /** * Returns true is field is visible * @return {boolean} */ FieldVO.prototype.isVisible = function () { if (this.isGroupField()) { for (var i = 0, l = this.members.length; i < l; i++) { if (this.members[i].isVisible()) { return true; } } } // Require field should always be shown. If it is empty we will show warning label to inform user to input it. return this.required || this.ootb || this.dynamicField || (this.isCheckboxField() ? (this.value != -1 && this.value !== undefined) : (this.value !== null && this.value !== '')); }; /** * Helper function for preparing value for "time" custom field * @param timeInSeconds * @returns {Date} */ FieldVO.prototype.prepareDateForTimeInput = function (timeInSeconds) { // prepare date object to be used by time input var hours = Math.floor(timeInSeconds / 3600), minutes = Math.floor((timeInSeconds % 3600) / 60), date = new Date(); console.log('hours: ' + hours + ', minutes: ' + minutes); date.setHours(hours); date.setMinutes(minutes); date.setSeconds(0); date.setMilliseconds(0); return date; }; /** * Helper function to get client time zone offset in milliseconds * @returns {number} */ FieldVO.prototype.getLocalOffsetInMilliseconds = function () { return new Date().getTimezoneOffset() * 60000; }; FieldVO.prototype.getLocalOffsetInMillisecondsForDate = function (forDate) { // Convert epoch value to date var dateValue = new Date(forDate); console.log('for date timezoneoffset =' + dateValue.getTimezoneOffset()); return dateValue.getTimezoneOffset() * 60000; }; FieldVO.prototype.isPersonName = function () { return this.type === FieldVO.prototype.PERSON_NAME; }; FieldVO.prototype.isAffectedAsset = function () { return this.type === FieldVO.prototype.AFFECTED_ASSET; }; FieldVO.prototype.isDescription = function () { return this.type === FieldVO.prototype.DESCRIPTION; }; FieldVO.prototype.isPersonSite = function () { return this.type === FieldVO.prototype.PERSON_SITE; }; FieldVO.prototype.isPriority = function () { return this.type === FieldVO.prototype.PRIORITY; }; FieldVO.prototype.isStatus = function () { return this.type === FieldVO.prototype.STATUS; }; FieldVO.prototype.isTicketRisk = function () { return this.type === FieldVO.prototype.TICKET_RISK; }; FieldVO.prototype.isPOILocation = function () { return this.type === FieldVO.prototype.POI_LOCATION; }; FieldVO.prototype.isOrganizationField = function () { return this.type === FieldVO.prototype.ORGANIZATION_FIELD; }; FieldVO.prototype.isPersonLocationMap = function () { return this.type === FieldVO.prototype.PERSON_LOCATION_MAP; }; FieldVO.prototype.isSupportGroupField = function () { return this.type === FieldVO.prototype.SUPPORT_GROUP_FIELD; }; FieldVO.prototype.isTicketTemplate = function () { return this.type === FieldVO.prototype.TICKET_TEMPLATE; }; FieldVO.prototype.isWidget = function () { return this.dataType === FieldVO.prototype.DATA_TYPE_WIDGET; }; FieldVO.prototype.markFieldUnavailable = function () { this.availability = 1; return this; }; FieldVO.prototype.markFieldAvailable = function () { this.availability = 0; return this; }; FieldVO.prototype.disableFieldSelection = function () { this.selectionDisabled = true; return this; }; FieldVO.prototype.enableFieldForSelection = function () { this.selectionDisabled = false; return this; }; FieldVO.prototype.isSelectionDisabled = function () { return this.selectionDisabled; }; FieldVO.prototype.isEqual = function (compareToField) { return this.name === compareToField.name && this.dataType === compareToField.dataType; }; FieldVO.prototype.isCustomField = function () { return !this.isWidget() && !this.ootb; }; FieldVO.prototype.fillParentInfo = function (parent) { if (parent.isWidget()) { this.widgetMember = true; } this.parentId = parent.id; return this; }; FieldVO.prototype.isAccessible = function () { var accessibleFlag; if (this.isWidget()) { var fieldIndex = _.findIndex(this.members, { accessible: false }); accessibleFlag = fieldIndex !== -1 ? false : true; } else { accessibleFlag = this.accessible; } return accessibleFlag; }; FieldVO.prototype.isEditable = function (accessMappings) { var checkAccessMapping = function (fieldName) { var accessMapping = accessMappings.fieldMappings ? accessMappings.fieldMappings[fieldName] : null; if (accessMapping) { return (accessMapping === 'write'); } else { return accessMappings.detailsEditAllowed; } }; var editable; if (this.isWidget()) { if (this.members.length > 0) { _.forEach(this.members, function (member) { editable = checkAccessMapping(member.name); if (!editable) { return editable; } }); } else { return accessMappings.detailsEditAllowed; } } else { editable = checkAccessMapping(this.name); } return editable; }; FieldVO.prototype.isPriorityWidget = function () { return this.isWidget() && this.name === this.WIDET_NAMES.priority; }; FieldVO.prototype.isChangeClassWidget = function () { return this.isWidget() && this.name === this.WIDET_NAMES.changeClass; }; FieldVO.prototype.isAssigneeWidget = function () { return this.isWidget() && this.ASSIGNMENT_WIDGETS.indexOf(this.name) !== -1; }; FieldVO.prototype.isCustomerWidget = function () { return this.isWidget() && (this.name === this.WIDET_NAMES.customer || this.name === this.WIDET_NAMES.requestedFor); }; FieldVO.prototype.isRequestedForWidget = function () { return this.isWidget() && this.name === this.WIDET_NAMES.requestedFor; }; FieldVO.prototype.isContactWidget = function () { return this.isWidget() && this.name === this.WIDET_NAMES.contact; }; FieldVO.prototype.isSupportGroupWidget = function () { return this.isWidget() && this.type === this.SUPPORT_GROUP_FIELD; }; FieldVO.prototype.isChangeRiskWidget = function () { return this.isWidget() && this.name === this.WIDET_NAMES.changeRisk; }; FieldVO.prototype.isChangeRiskBadgeWidget = function () { return this.isWidget() && this.name === this.WIDET_NAMES.changeRiskBadge; }; FieldVO.prototype.isChangeLocation = function () { return this.isWidget() && this.name === this.WIDET_NAMES.changeLocation; }; FieldVO.prototype.isImpactedAreas = function () { return this.isWidget() && this.name === this.WIDET_NAMES.impactedAreas; }; FieldVO.prototype.isTaskPhaseWidget = function () { return this.isWidget() && this.name === this.WIDET_NAMES.taskPhase; }; FieldVO.prototype.getCategorizationPropertyName = function () { return this.WIDGET_NAMES_TO_TICKET_PROPERTY_MAP[this.name] || this.name; }; FieldVO.prototype.isFieldMemberOfThisGroup = function (field) { var isMember = false; if (this.isGroupField() && field) { isMember = this.members.some(function (member) { return member.isEqual(field); }); } return isMember; }; FieldVO.prototype.checkSystemRequiredFlag = function () { var isSystemRequiredField = this.isSystemRequired(); var hasAtLeaseOneSystemField = (this.members || []).some(function (member) { return member.isSystemRequired(); }); return isSystemRequiredField || hasAtLeaseOneSystemField; }; FieldVO.prototype.isSystemPopulatedField = function () { var matchingFieldCriteria = this.SPECIAL_HANDLING_SYSTEM_FIELD_NAMES_LIST[this.name]; var self = this; if (matchingFieldCriteria) { return !Object.keys(matchingFieldCriteria) .some(function (prop) { return matchingFieldCriteria[prop] !== self[prop]; }); } return false; }; FieldVO.prototype.isSystemRequired = function () { return this.itsmRequired && !this.isSystemPopulatedField() && this.isAvailable(); }; FieldVO.prototype.isMissingSystemRequiredField = function () { return this.isSystemRequired() && !this.isSelectionDisabled(); }; FieldVO.prototype.hasValuesInMembers = function () { var hasValues = false; hasValues = this.members.some(function (member) { return member.value || member.value === 0; }); return hasValues; };