navidev-abap-gw-api
Version:
API para la extracción de datos de servicios SAP GW
575 lines (574 loc) • 32.3 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const metadataTypes_1 = require("./metadataTypes");
const Result_1 = require("navidev-adt-api/dist/shared/core/Result");
const xmlParser_1 = __importDefault(require("../shared/utilities/parser/xmlParser"));
const metadataApp_1 = __importDefault(require("./metadataApp"));
const metadataConstants_1 = require("./metadataConstants");
const commonConstants_1 = require("../shared/constants/commonConstants");
const metadataURL_1 = __importDefault(require("../shared/utilities/general/metadataURL"));
class MetadataV4App extends metadataApp_1.default {
constructor(connectionController, serviceBindingInfo, options) {
super(connectionController, serviceBindingInfo, options);
this.entitiesWithSemantics = [];
}
/**
* Obtiene el contenido del metadata. En los V4 hay como 2 metadatas el especifico y el general.
* El específico contiene la información de las entidades propias de la aplicación y el general contiene
* las entidades de SAP, como la moneda, unidad de medida, etc.
* @param serviceBindingInfo
*/
getMetadataInfo() {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
this.entitiesWithSemantics = [];
// Metadata especifico
let resultMetadataEspecific = yield this.loadMetadata((_a = this.serviceBindingInfo) === null || _a === void 0 ? void 0 : _a.serviceUrl);
if (resultMetadataEspecific.isFailure)
return Result_1.Result.fail(resultMetadataEspecific.getErrorValue());
yield this.processMetadataEspecific(xmlParser_1.default.fullParse(resultMetadataEspecific.getValue()));
// Metadata general, solo si hay entidades con campos semánticos
if (this.serviceBindingInfo.serviceUrlCommon != "" &&
this.entitiesWithSemantics.length > 0) {
let resultLoadCommon = yield this.loadMetadata((_b = this.serviceBindingInfo) === null || _b === void 0 ? void 0 : _b.serviceUrlCommon);
if (resultLoadCommon.isFailure)
return Result_1.Result.fail(resultLoadCommon.getErrorValue());
this.processMetadataCommon(xmlParser_1.default.fullParse(resultLoadCommon.getValue()));
}
return Result_1.Result.ok(this.metadataContent);
});
}
/**
* Proceso el el metadata especifico del servicio
* @param bodyParsed
*/
processMetadataEspecific(bodyParsed) {
return __awaiter(this, void 0, void 0, function* () {
this.metadataContent.namespace = this.extractNamespace(bodyParsed);
this.metadataContent.alias = this.extractNamespaceAlias(bodyParsed);
this.metadataContent.entities = yield this.extractEntities(bodyParsed);
});
}
/**
* Procesado del metadata general. El metadata general contiene entidades que mete SAP por defecto, como PDF y otras historias,
* pero me interesa las entidades asociadas cuando tengo campos con valores semanticos (moneda o unidades de medida).
* @param bodyParsed
*/
processMetadataCommon(bodyParsed) {
let entities = [];
this.entitiesWithSemantics.forEach((rowEntity) => {
rowEntity.annotation.forEach((rowSemantics) => {
let entitySemantic = entities.find((rowEntity) => rowEntity.name === rowSemantics.entity);
if (!entitySemantic)
entitySemantic = this.extractEntityCommon(bodyParsed, rowSemantics.entity);
if (entitySemantic) {
this.fillEntitySemantic(entitySemantic, rowEntity.name, rowSemantics);
}
});
});
//let entitiesCommon = await this.extractEntities(bodyParsed);
//this.fillCommonEntitiesWithSemantics(entitiesCommon);
}
extractEntityCommon(bodyParsed, entityName) {
let entityTypes = xmlParser_1.default.xmlArray(bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema.EntityType);
// En las anotaciones se ecuentra la información de los campos, aparte de otro tipo de información.
let annotations = xmlParser_1.default.xmlArray(bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema.Annotations);
let entityContainer = xmlParser_1.default.xmlArray(bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer
.EntitySet);
let nameSpace = this.extractNamespace(bodyParsed);
let rowEntity = entityContainer.find((rowContainer) => rowContainer["@_Name"] === entityName);
if (rowEntity) {
let entityInfo = this.fillExtractInfo(rowEntity, nameSpace);
let entity = entityTypes.find((rowEntityType) => rowEntityType["@_Name"] === entityInfo.entityTypeName);
if (entity) {
entityInfo.label = entity["@_sap:label"];
entityInfo.fields = this.extractFieldsEntityCommon(entity, entityInfo, annotations);
return entityInfo;
}
}
return undefined;
}
extractEntities(bodyParsed) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
let entities = [];
// Todos los nodos que son array los convierto a array, ya que si solo hay un elemento no se convierte a array. Y quiero procesarlo
// como si fuera un array para simplificar el código.
let entityTypes = xmlParser_1.default.xmlArray(bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema.EntityType);
// En las anotaciones se ecuentra la información de los campos, aparte de otro tipo de información.
let annotations = xmlParser_1.default.xmlArray(bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema.Annotations);
// Como este método se usa para dos metadata: especifico y el generico, y cada uno de ello tiene su propio nameSpace. Aunque a nivel de datos
// me guardo el namespace del metadata especifico.
let nameSpace = this.extractNamespace(bodyParsed);
let entityContainer = xmlParser_1.default.xmlArray(bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema.EntityContainer
.EntitySet);
for (let x = 0; x < entityContainer.length; x++) {
let rowEntity = entityContainer[x];
// Si la entidad que voy a procesar ya esta añadida (por que se ha añadido en alguna ayuda para búsqueda) no la vuelvo a añadir.
if (entities.findIndex((row) => row.name === rowEntity["@_Name"]) != -1)
continue;
let entityInfo = this.fillExtractInfo(rowEntity, nameSpace);
let entity = entityTypes.find((rowEntityType) => rowEntityType["@_Name"] === entityInfo.entityTypeName);
if (entity) {
entityInfo.label = entity["@_sap:label"];
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.ignoreFields))
entityInfo.fields = yield this.extractEntityTypeFields(bodyParsed, entity, entityInfo, annotations, entities);
// Sacamos que se puede hacer con la entidad: crear, borrar, modificar
this.extratEntityRestrictions(entityInfo, annotations);
if (!((_b = this.options) === null || _b === void 0 ? void 0 : _b.ignoreAnnotVocab))
this.extractEntityAnnotationVocab(entityInfo, annotations);
entities.push(entityInfo);
}
}
return entities;
});
}
/**
* Extrae las anotaciones del vocabulario de la entidad. El vocabulario son las anotaciones fiori de los campos.
* @param entityInfo
* @param annotations
*/
extractEntityAnnotationVocab(entityInfo, annotations) {
let annotationEntity = annotations.find((rowAnnotation) => rowAnnotation["@_Target"] ==
`${this.metadataContent.alias}.${entityInfo.entityTypeName}`);
if (!annotationEntity)
return;
xmlParser_1.default.xmlArray(annotationEntity.Annotation).forEach((rowAnottation) => {
// El label de la anotación sobrescribe al que se haya podido obtener antes.
if (rowAnottation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.LABEL)
entityInfo.label = rowAnottation["@_String"];
if (rowAnottation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.LABEL)
entityInfo.label = rowAnottation["@_String"];
if (rowAnottation["@_Term"].includes(metadataConstants_1.ANNOTATION_VOCAB_TERM.LINE_ITEM))
this.processLineItemAnnotation(xmlParser_1.default.xmlArray(rowAnottation.Collection.Record), entityInfo);
if (rowAnottation["@_Term"].includes(metadataConstants_1.ANNOTATION_VOCAB_TERM.IDENTIFICATION))
this.processIdentificationAnnotation(xmlParser_1.default.xmlArray(rowAnottation.Collection.Record), entityInfo);
});
}
/**
* Procesa la anotación de lineItem
* @param values
* @param entityInfo
*/
processLineItemAnnotation(values, entityInfo) {
for (let x = 0; x < values.length; x++) {
// El propertyValue puede ser un array o una estructura. Es un array cuando tiene alguna anotación como
// @ObjectModel.text.element. Pero si no tiene anotaciones parecidas es una estructura. Por ello, convierto
// siempre a array para simplificar el tratamiento.
let properties = xmlParser_1.default.xmlArray(values[x].PropertyValue);
let rowPath = properties.find((row) => row["@_Property"] == "Value");
if (rowPath) {
let indexField = entityInfo.fields.findIndex((rowField) => rowField.name == rowPath["@_Path"]);
if (indexField != -1)
entityInfo.fields[indexField].lineItem = { position: x + 1 };
}
}
}
/**
* Procesa la anotación de identification
* @param values
* @param entityInfo
*/
processIdentificationAnnotation(values, entityInfo) {
for (let x = 0; x < values.length; x++) {
let properties = xmlParser_1.default.xmlArray(values[x].PropertyValue);
let rowPath = properties.find((row) => row["@_Property"] == "Value");
if (rowPath) {
let indexField = entityInfo.fields.findIndex((rowField) => rowField.name == rowPath["@_Path"]);
if (indexField != -1)
entityInfo.fields[indexField].identification = { position: x + 1 };
}
}
}
/**
* Extrae lo que se puede hacer con la entidad: crear, borrar, modificar. Esto se encuentra
* en la anotación del container. El nombre suele ser: "SAP__self.Container/<entidad>". El "SAP__self" sale
* del alias que tiene el servicio.
* @param entityInfo
* @param annotations
*/
extratEntityRestrictions(entityInfo, annotations) {
let annotationContainer = annotations.find((rowAnnotation) => rowAnnotation["@_Target"] ==
`${this.metadataContent.alias}.${metadataConstants_1.COMMON_ENTITTIES_V4.CONTAINER}/${entityInfo.name}`);
if (annotationContainer) {
annotationContainer.Annotation.forEach((rowAnnotation) => {
// Lo valores de las propiedades están en un objeto salvo el de actualización. Como quiero
// unificar el tratamiento lo convierto a una array y así tratarlo igual que los demás.
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.CREATABLE ||
rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.DELETABLE ||
rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.UPDATABLE ||
rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.SEARCHABLE) {
xmlParser_1.default.xmlArray(rowAnnotation.Record.PropertyValue).forEach((rowProperty) => {
// La propiedad que interesa es la Bool que es la que indica si se puede hacer o no.
if (rowProperty["@_Bool"] != undefined) {
if (rowAnnotation["@_Term"] ==
metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.CREATABLE)
entityInfo.creatable = rowProperty["@_Bool"];
else if (rowAnnotation["@_Term"] ==
metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.DELETABLE)
entityInfo.deletable = rowProperty["@_Bool"];
else if (rowAnnotation["@_Term"] ==
metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.SEARCHABLE)
entityInfo.searchable = rowProperty["@_Bool"];
else if (rowAnnotation["@_Term"] ==
metadataConstants_1.ANNOTATION_CAPABILITIES_TERM.UPDATABLE)
entityInfo.updatable = rowProperty["@_Bool"];
}
});
}
});
}
}
/**
* Extrae los campos de la entityType
* @param entityType
* @returns
*/
extractEntityTypeFields(bodyParsed, entityType, entityInfo, annotations, entities) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
let fields = [];
let keyFields = xmlParser_1.default.xmlArray(entityType.Key.PropertyRef);
let properties = xmlParser_1.default.xmlArray(entityType.Property);
for (let x = 0; x < properties.length; x++) {
let rowProperty = properties[x];
let field = this.fillFieldInfo(rowProperty, keyFields);
let target = `${entityInfo.entityTypeName}/${field.name}`;
let annotationField = annotations.find((rowAnnotation) => rowAnnotation["@_Target"].includes(target));
if (annotationField) {
let annotationsField = xmlParser_1.default.xmlArray(annotationField.Annotation);
for (let y = 0; y < annotationsField.length; y++) {
let rowAnnotation = annotationsField[y];
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.LABEL)
field.label = rowAnnotation["@_String"];
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.HEADING)
field.heading = rowAnnotation["@_String"];
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.QUICKINFO)
field.quickInfo = rowAnnotation["@_String"];
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.IS_CURRENCY) {
field.isCurrency = true;
field.semantics = metadataConstants_1.SEMANTICS_TYPES.CURRENCY;
}
if (rowAnnotation["@_Term"].includes(metadataConstants_1.ANNOTATION_VOCAB_TERM.HIDDEN_FILTER))
field.hiddenFilter = true;
if (rowAnnotation["@_Term"].includes(metadataConstants_1.ANNOTATION_VOCAB_TERM.HIDDEN))
field.hidden = true;
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.CURRENCY_FIELD)
field.unit = rowAnnotation["@_Path"];
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.TEXT) {
field.textElement = rowAnnotation["@_Path"];
// La posición del texto viene en el campo Annotation
if (rowAnnotation.Annotation) {
xmlParser_1.default.xmlArray(rowAnnotation.Annotation).forEach((rowSubAnnotation) => {
if (rowSubAnnotation["@_Term"].includes(metadataConstants_1.ANNOTATION_VOCAB_TERM.TEXT_ARRANGEMENT))
field.textArrangement = this.convertTextArrangementType(rowSubAnnotation["@_EnumMember"]);
});
}
}
if (rowAnnotation["@_Term"] ==
metadataConstants_1.ANNOTATION_FIELD_TERM.VALUE_LIST_VALIDATION)
field.valueHelpInfo.forValidation = true;
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.VALUE_LIST &&
!((_a = this.options) === null || _a === void 0 ? void 0 : _a.ignoreValueHelp))
yield this.fillFieldWithValuesList(rowAnnotation, field, entityInfo, entities);
}
// No todos los campos tienen el campo Heading informado, por ello pongo el label si no
// hay heading.
if (field.heading === "")
field.heading = field.label;
if (field.semantics != "" && !((_b = this.options) === null || _b === void 0 ? void 0 : _b.ignoreValueHelp))
this.addEntityWithSemantics(annotations, entityInfo.entityTypeName, field.semantics);
fields.push(field);
}
}
return fields;
});
}
/**
* Rellena el campo con la información de la ayuda para búsqueda.
* @param rowAnnotation
* @param field
* @param entityInfo
* @param entities
*/
fillFieldWithValuesList(rowAnnotation, field, entityInfo, entities) {
return __awaiter(this, void 0, void 0, function* () {
let urlMetadata = metadataURL_1.default.buildURLMetadataValueList(rowAnnotation.Collection.String, this.serviceBindingInfo.serviceUrl);
// Metadata especifico
let resultLoad = yield this.loadMetadata(urlMetadata);
if (resultLoad.isFailure) {
let valuesError = resultLoad.getErrorValue();
console.log(valuesError);
return;
}
let bodyParsed = xmlParser_1.default.fullParse(resultLoad.getValue());
let entitiesValueList = yield this.extractEntities(bodyParsed);
entitiesValueList.forEach((rowEntity) => {
// Las entidades de la ayuda para búsqueda si están insertadas las quito y las vuelvo a poner. El motivo
// es que estas entidades tiene información complementaría, como más ayudas para búsquedas de campos de la entidad
let index = entities.findIndex((row) => row.entityType === rowEntity.entityType);
if (index != -1)
entities.splice(index, index >= 0 ? 1 : 0);
entities.push(rowEntity);
});
// El siguiente paso es relacionar el campo de la entidad del metadata que se esta procesando con el campo de la entidades leídas
// del metadata de la ayuda para búsqueda.
this.linkFieldEntityWithEntityValueList(field, entityInfo, bodyParsed);
});
}
/**
* Añade que entidad tiene un campo semantico. Campo semantico son campos de moneda, unidad de medida, etc.
* @param entityName
* @param semantic
*/
addEntityWithSemantics(annotations, entityName, semantic) {
// El objetivo es sacar la entidad donde esta los datos del campo semantic de la información del registro del container. Lo fácil sería
// tener en constante la entidad de moneda pero me arriesgo a cambios futuros. Lo que esta montado tampoco me termina de gustar porque sigue
// habiendo hardcode, y luego hay que hacer otro semi hardcode para asociar la entidad del objeto semantico al campo dde la entidad
let annotationContainer = annotations.find((rowAnnotation) => rowAnnotation["@_Target"] ==
`${this.metadataContent.alias}.${metadataConstants_1.COMMON_ENTITTIES_V4.CONTAINER}`);
if (!annotationContainer)
return;
let term = undefined;
if (semantic == metadataConstants_1.SEMANTICS_TYPES.CURRENCY)
term = "Currency";
const pattern = new RegExp(`^${commonConstants_1.PREFIX_SAP_IN_ENTITIES.SAP}CodeList\.${term}.*`);
const recordTerm = annotationContainer.Annotation.find((row) => pattern.test(row["@_Term"]));
if (!recordTerm)
return;
const rowCollectionPath = xmlParser_1.default.xmlArray(recordTerm.Record.PropertyValue).find((row) => row["@_Property"] == metadataConstants_1.PROPERTY_VALUES.COLLECTION_PATH);
if (!rowCollectionPath)
return;
let entityIndex = this.entitiesWithSemantics.findIndex((rowEntity) => rowEntity.name === entityName);
if (entityIndex !== -1) {
this.entitiesWithSemantics[entityIndex].annotation.push({
entity: rowCollectionPath["@_String"],
semantic: semantic,
});
}
else {
this.entitiesWithSemantics.push({
name: entityName,
annotation: [
{
entity: rowCollectionPath["@_String"],
semantic: semantic,
},
],
});
}
}
/**
* Obtiene el alias del namespace del metadata necesario para búsquedas internas
* @param bodyParsed
* @returns
*/
extractNamespaceAlias(bodyParsed) {
var _a;
return ((_a = bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema["@_Alias"]) !== null && _a !== void 0 ? _a : bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema["@_Namespace"]);
}
/**
* Rellena en la entidad donde hay un campo semantic cual es la entidad de SAP para obtener los valores. Además, de informar
* dicha entidad en las entidades leidas del metadata especifico del servicio
* @param entitySemantic
* @param entityTypeName
* @param semantic
*/
fillEntitySemantic(entitySemantic, entityTypeName, semantic) {
var _a, _b;
{
if (this.metadataContent.entities.findIndex((rowEntitySemantic) => rowEntitySemantic.entityTypeName === entitySemantic.entityTypeName) == -1)
this.metadataContent.entities.push(entitySemantic);
let entityIndex = this.metadataContent.entities.findIndex((rowEntitySemantic) => rowEntitySemantic.entityTypeName === entityTypeName);
if (entityIndex != -1) {
let fieldIndex = this.metadataContent.entities[entityIndex].fields.findIndex((rowField) => rowField.semantics === semantic.semantic);
if (fieldIndex != -1) {
this.metadataContent.entities[entityIndex].fields[fieldIndex].valueHelpInfo = {
entityValueHelp: entitySemantic.name,
forValidation: true,
parametersInOut: [
{
entityField: this.metadataContent.entities[entityIndex].fields[fieldIndex]
.name,
valueListField: (_b = (_a = entitySemantic.fields.find((row) => row.key)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "",
onlyDisplay: false,
},
],
parametersDisplay: entitySemantic.fields.map((row) => {
return { field: row.name };
}),
};
}
}
}
}
/**
* Enlaza el campo de la entidad que se esta procesando con la entidad de la ayuda para búsqueda
* @param field
* @param entityInfo
* @param bodyParsed Cuerpo del metadata de la ayuda para búsqueda
*/
linkFieldEntityWithEntityValueList(field, entityInfo, bodyParsed) {
// Nota: Fuerzo arrays para evitar que en algun caso venga una estructura en vez de un array, como suele hacer SAP en
// llamadas al ADT.
let target = `${commonConstants_1.PREFIX_SAP_IN_ENTITIES.PARENT}.${entityInfo.entityTypeName}/${field.name}`;
let rowLink = xmlParser_1.default.xmlArray(bodyParsed["edmx:Edmx"]["edmx:DataServices"].Schema.Annotations).find((row) => row["@_Target"] == target);
if (!rowLink)
return;
// Para asegurar que estoy en la anotación correcta reviso el valor de la propiedad "@_Term"
if (rowLink.Annotation["@_Term"] != metadataConstants_1.ANNOTATION_FIELD_TERM.VALUE_LIST_MAPPING)
return;
xmlParser_1.default.xmlArray(rowLink.Annotation.Record.PropertyValue).forEach((rowProperty) => {
if (rowProperty["@_Property"] == "CollectionPath") {
field.valueHelpInfo.entityValueHelp = rowProperty["@_String"];
}
else if (rowProperty["@_Property"] == "Parameters") {
this.processParametersValueHelp(field, rowProperty["Collection"]["Record"]);
}
});
}
/**
* Procesa los parámetros de la ayuda para búsqueda donde están los campos que la formarán y
* los campos de entrada y salida.
* @param field
* @param valueListParameters
*/
processParametersValueHelp(field, valueListParameters) {
valueListParameters.forEach((row) => {
// Info de como se mapearán los valores de la ayuda para búsqueda con los campos de la entidad
if (row["@_Type"] == metadataConstants_1.ANNOTATION_FIELD_TERM.VALUE_LIST_PARAM_INOUT_V4 ||
row["@_Type"] == metadataConstants_1.ANNOTATION_FIELD_TERM.VALUE_LIST_PARAM_OUT_V4) {
field.valueHelpInfo.parametersInOut.push({
entityField: row.PropertyValue.find((row) => row["@_Property"] == "LocalDataProperty")["@_PropertyPath"],
valueListField: row.PropertyValue.find((row) => row["@_Property"] == "ValueListProperty")["@_String"],
onlyDisplay: row["@_Type"] == metadataConstants_1.ANNOTATION_FIELD_TERM.VALUE_LIST_PARAM_OUT_V4
? true
: false,
});
}
else if (row["@_Type"] ==
`${commonConstants_1.PREFIX_SAP_IN_ENTITIES.COMMON}.ValueListParameterDisplayOnly`) {
field.valueHelpInfo.parametersDisplay.push({
field: row["PropertyValue"]["@_String"],
});
}
});
}
/**
* Rellena la estructura de info de la entidad en base al cuerpo del metadata
* @param rowEntity
* @param nameSpace
* @returns
*/
fillExtractInfo(rowEntity, nameSpace) {
return {
name: rowEntity["@_Name"],
entityType: rowEntity["@_EntityType"],
entityTypeName: this.extractEntityName(nameSpace, rowEntity["@_EntityType"]),
creatable: false,
deletable: false,
updatable: false,
searchable: false,
label: "",
fields: [],
};
}
/**
* Rellena la info básico de un campo
* @param rowProperty
* @param keyFields
* @returns
*/
fillFieldInfo(rowProperty, keyFields) {
var _a, _b, _c, _d;
return {
name: rowProperty["@_Name"],
type: rowProperty["@_Type"],
label: "",
heading: "",
maxLength: (_a = rowProperty["@_MaxLength"]) !== null && _a !== void 0 ? _a : "",
nullable: (_b = rowProperty["@_Nullable"]) !== null && _b !== void 0 ? _b : false,
quickInfo: "",
unit: "",
semantics: "",
isCurrency: false,
searchable: false,
hiddenFilter: false,
key: keyFields.findIndex((keyField) => keyField["@_Name"] === rowProperty["@_Name"]) == -1
? false
: true,
valueHelpInfo: {
entityValueHelp: "",
forValidation: false,
parametersInOut: [],
parametersDisplay: [],
},
hidden: false,
precision: (_c = rowProperty["@_Precision"]) !== null && _c !== void 0 ? _c : 0,
scale: (_d = rowProperty["@_Scale"]) !== null && _d !== void 0 ? _d : 0,
};
}
/**
* Extrae los campos de las entidades comunes
* @param entityType
* @param entityInfo
* @param annotations
* @returns
*/
extractFieldsEntityCommon(entityType, entityInfo, annotations) {
let fields = [];
let keyFields = xmlParser_1.default.xmlArray(entityType.Key.PropertyRef);
xmlParser_1.default.xmlArray(entityType.Property).forEach((rowProperty) => {
let field = this.fillFieldInfo(rowProperty, keyFields);
let target = `${entityInfo.entityTypeName}/${field.name}`;
let annotationField = annotations.find((rowAnnotation) => rowAnnotation["@_Target"].includes(target));
if (annotationField) {
xmlParser_1.default.xmlArray(annotationField.Annotation).forEach((rowAnnotation) => {
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.LABEL)
field.label = rowAnnotation["@_String"];
// El campo "Text" solo estar en las entidad comunes por eso no pongo esta condición en la especifica
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.TEXT)
field.label = rowAnnotation["@_Path"];
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.HEADING)
field.heading = rowAnnotation["@_String"];
if (rowAnnotation["@_Term"] == metadataConstants_1.ANNOTATION_FIELD_TERM.QUICKINFO)
field.quickInfo = rowAnnotation["@_String"];
});
if (field.heading === "")
field.heading = field.label;
}
else {
field.heading = field.name;
}
fields.push(field);
});
return fields;
}
/**
* Convierte un string en un TextArrangementTypes
* @param value
* @returns
*/
convertTextArrangementType(value) {
if (value.includes("UI.TextArrangementType/TextOnly"))
return metadataTypes_1.TextArrangementTypes.TextOnly;
if (value.includes("UI.TextArrangementType/TextFirst"))
return metadataTypes_1.TextArrangementTypes.TextFirst;
if (value.includes("UI.TextArrangementType/TextLast"))
return metadataTypes_1.TextArrangementTypes.TextLast;
return metadataTypes_1.TextArrangementTypes.TextOnly;
}
}
exports.default = MetadataV4App;