define([
'entity/js/api/Property',
'entity/js/api/PropertyType',
'operation/js/api/FieldPath'
], function(
Property,
PropertyType,
FieldPath
) {
'use strict';
/**
* An API object providing methods to create sorting rule which can be applied within the custom code.
*
* @AbcsAPI stable
* @version 17.1.1
* @exports operation/js/api/Sorting
*
* @constructor
* @private
*
* @see {@link module:api/js/Operations.read Abcs.Operations().read(..)} to use <code>Sorting</code> from Application Builder custom code.
*
* @param {Sorting.Criterion[]} sortingCriteria
*/
var Sorting = function(sortingCriteria) {
AbcsLib.checkThis(this);
this._sortingCriteria = sortingCriteria ? sortingCriteria : [];
};
/**
* Creates an instance of <code>Sorting</code> in ascending order.
*
* @AbcsAPI stable
* @version 17.1.1
* @public
* @static
*
* @param {entity/js/api/Property} property - {@link entity/js/api/Property Property} used for sorting.
* @returns {operation/js/api/Sorting}
*
* @see {@link module:api/js/Operations.read Abcs.Operations().read(..)} to use <code>Sorting</code> from Application Builder custom code.
*
* @example
* <caption>
* Create an instance of {@link operation/js/api/Sorting Sorting} for the given {@link entity/js/api/Property Property} in ascending order.
* </caption>
*
* var employee = Abcs.Entities().findById('my.custom.bop.Employee');
* var firstname = employee.getProperty('firstname');
* var sorting = Sorting.ascending(firstname);
*/
Sorting.ascending = function(property) {
AbcsLib.checkDefined(property, 'property');
AbcsLib.checkParameterCount(arguments, 1);
var entity = property.getEntity();
var sortingCriteria = new Sorting.Criterion(entity, property, false);
return new Sorting([sortingCriteria]);
};
/**
* Creates an instance of <code>Sorting</code> in descending order.
*
* @AbcsAPI stable
* @version 17.1.1
* @public
* @static
*
* @param {entity/js/api/Property} property - {@link entity/js/api/Property Property} used for sorting.
* @returns {operation/js/api/Sorting}
*
* @see {@link module:api/js/Operations.read Abcs.Operations().read(..)} to use <code>Sorting</code> from Application Builder custom code.
*
* @example
* <caption>
* Create an instance of {@link operation/js/api/Sorting Sorting} for the given {@link entity/js/api/Property Property} in descending order.
* </caption>
*
* var employee = Abcs.Entities().findById('my.custom.bop.Employee');
* var fistname = employee.getProperty('firstname');
* var sorting = Sorting.descending(firstname);
*/
Sorting.descending = function(property) {
AbcsLib.checkDefined(property, 'property');
AbcsLib.checkParameterCount(arguments, 1);
var entity = property.getEntity();
var sortingCriteria = new Sorting.Criterion(entity, property, true);
return new Sorting([sortingCriteria]);
};
/**
* Gets an array of {@link operation/js/api/Sorting.Criterion Sorting.Criterion} assigned to this <code>Sorting</code>.
*
* @AbcsExtension stable
* @version 17.1.1
*
* @returns {operation/js/api/Sorting.Criterion[]}
*/
Sorting.prototype.getSortingCriteria = function() {
return this._sortingCriteria;
};
/**
* StaticViewModelGenerator calls JSON.stringify on ArchetypeConfiguration
* which may contain instance of Sorting. Hence toJSON below is needed.
*/
Sorting.prototype.toJSON = function() {
return this.getDefinition();
};
Sorting.prototype.getDefinition = function() {
var self = this;
var result = [];
self._sortingCriteria.forEach(function(sortingProperty) {
result.push(sortingProperty.getDefinition());
});
return result;
};
Sorting.createFromDefinition = function(sortingJSON) {
var sortingCriteria = [];
for (var i = 0; i < sortingJSON.length; i++) {
var sortingPropertyJSON = sortingJSON[i];
sortingCriteria.push(Sorting.Criterion.createFromDefinition(sortingPropertyJSON));
}
return new Sorting(sortingCriteria);
};
/**
* Represents single {@link operation/js/api/Sorting Sorting} criterion.
*
* <p>
* Single criterion consist of assigned {@link entity/js/api/Property Property} and the order in which the result needs to be sorted (ascending/descending).
* </p>
*
* <p>
* In the future, Application Builder is going to support multiple criteria.
* </p>
*
* @AbcsExtension stable
* @version 17.1.1
* @constructor
* @private
*
* @param {entity/js/api/Entity} entity
* @param {entity/js/api/Property} property
* @param {boolean} descending - Flag whether this criterion is descending or ascending
*/
Sorting.Criterion = function(entity, property, descending) {
AbcsLib.checkThis(this);
this.entity = entity;
if (property && !(property instanceof FieldPath)) {
AbcsLib.checkDataType(property, Property);
var prop = property;
var rels = [];
// BUFP-10262 Auto add default display name in Field pickers, pending tree implementation
// For backward compatibility, if a REFERENCE Property is provided,
// replace this with the Relation and default displayProperty of the
// referenced BO
if (property.getType() === PropertyType.REFERENCE) {
var rel = property.getEntity().getRelation(property);
if (rel) {
var target = rel.getTargetEntity();
var dispPropId = rel.getDefaultDisplayProperty();
var dispProp = (dispPropId && target && target.isInternal()) ? target.getProperty(dispPropId) : undefined;
if (dispProp && !dispProp.getFormula() && dispProp.getType !== PropertyType.REFERENCE) {
rels.push(rel);
prop = dispProp;
}
}
}
this.fieldPath = new FieldPath(prop, rels);
} else {
this.fieldPath = property;
}
this.descending = descending ? true : false;
};
/**
* Gets the {@link entity/js/api/Property Property} assigned to this criterion.
*
* @AbcsExtension stable
* @version 17.1.1
* @memberof operation/js/api/Sorting.Criterion
*
* @returns {entity/js/api/Property}
*/
Sorting.Criterion.prototype.getProperty = function() {
if (this.fieldPath) {
return this.fieldPath.getProperty();
}
};
Sorting.Criterion.prototype.getPropertyId = function() {
if (this.fieldPath) {
return this.fieldPath.getId();
}
};
/**
* Gets the FieldPath of this criterion.
*
* @returns {operation/js/api/FieldPath}
*/
Sorting.Criterion.prototype.getFieldPath = function() {
return this.fieldPath;
};
/**
* Checks whether this <code>Sorting.Criterion</code> is ascending.
*
* @AbcsExtension stable
* @version 17.1.1
* @memberof operation/js/api/Sorting.Criterion
*
* @returns {Boolean} - <code>true</code> if this is ascending criterion, <code>false</code> otherwise
*/
Sorting.Criterion.prototype.isAscending = function() {
return !this.descending;
};
/**
* Checks whether this <code>Sorting.Criterion</code> is descending.
*
* @AbcsExtension stable
* @version 17.1.1
* @memberof operation/js/api/Sorting.Criterion
*
* @returns {Boolean} - <code>true</code> if this is descending criterion, <code>false</code> otherwise
*/
Sorting.Criterion.prototype.isDescending = function() {
return this.descending;
};
/**
* StaticViewModelGenerator calls JSON.stringify on ArchetypeConfiguration
* which may contain instance of SortingProperty. Hence toJSON below is needed.
*/
Sorting.Criterion.prototype.toJSON = function () {
return this.getDefinition();
};
Sorting.Criterion.prototype.getDefinition = function() {
return {
descending: this.isDescending(),
fieldPath: this.fieldPath && this.fieldPath.toJSON()
};
};
Sorting.Criterion.createFromDefinition = function(sortingPropertyJSON) {
var descending = sortingPropertyJSON.descending;
var fieldPath = FieldPath.createFromDefinition(sortingPropertyJSON.fieldPath);
var entity;
if (fieldPath) {
entity = fieldPath ? fieldPath.getEntity() : undefined;
} else {
// Backward compatibility
entity = Abcs.Entities().findById(sortingPropertyJSON.entityID);
var property = entity.getProperty(sortingPropertyJSON.propertyID);
fieldPath = new FieldPath(property);
}
return new Sorting.Criterion(entity, fieldPath, descending);
};
return Sorting;
});