Untitled

 avatar
unknown
plain_text
10 months ago
19 kB
23
Indexable
const includeFeatured = async data => {
	const { items, featuredData, dataset, isSuperAdmin, dsScope, isQualitrack = false } = data;
	const levelsPromise = levelDAO.find({}, 'name');
	const attributesPromise = attributeDAO.find({}, 'name values type translations entityLevel unit isUrl library');
	const librariesPromise = libraryDAO.find({}, 'name type objectSchema');
	const [levelsData, attributesData, librariesData] = await Promise.all([
		levelsPromise,
		attributesPromise,
		librariesPromise
	]);
	 
	const levelsMap = new Map(levelsData.map(level => [level._id.toString(), level]));
	const attributesMap = new Map(attributesData.map(attr => [attr._id.toString(), attr]));
	const librariesMap = new Map(librariesData.map(lib => [lib._id.toString(), lib]));

	let batchEntityIds = [];
	let allRelationItemIds = new Set();
	let allUserIds = new Set();
	let allLevelIds = new Set();
	let allAttributeIds = new Set();

 	for (const item of items) {
		// Collect relation item IDs
		for (const relation of item?.relations || []) {
			if (relation?.items) {
				relation.items.forEach(id => allRelationItemIds.add(id));
			}
		}

 		for (const attribute of item?.populatedAttributes || []) {
			const level = attributesMap.get(attribute?.attribute?.toString());
			if (level?.type === 'Entity') {
				const values = attribute?.values || [];
				values.forEach(value => {
					if (value?.value) {
						batchEntityIds.push(value.value);
					}
				});
			}
		}
	}

	for (const currentFeatured of featuredData || []) {
		if (
			currentFeatured?.type === 'DEFAULT' &&
			['createdBy', 'updatedBy'].includes(currentFeatured?.value?.default)
		) {
			items.forEach(item => {
				if (item[currentFeatured?.value?.default]) {
					allUserIds.add(item[currentFeatured?.value?.default]);
				}
			});
		}
		if (currentFeatured?.type === 'RELATION') {
			allLevelIds.add(currentFeatured?.value?.entity);
		}
		if (currentFeatured?.type === 'ATTRIBUTE') {
			allAttributeIds.add(currentFeatured?.value?.attribute);
		}
	}


	const [batchRelationItems, batchEntityData, batchUsers, batchLevels, batchAttributes] = await Promise.all([
		itemDAO.find({ _id: { $in: Array.from(allRelationItemIds) } }, 'name attributes'),
		itemDAO.find({ _id: { $in: batchEntityIds } }, 'name attributes'),
		userDAO.find({ _id: { $in: Array.from(allUserIds) } }, 'firstName familyName active'),
		levelDAO.find({ _id: { $in: Array.from(allLevelIds) } }, 'name translations'),
		attributeDAO.find(
			{ _id: { $in: Array.from(allAttributeIds) } },
			'name type unit values entityLevel translations form boundaries isUrl'
		)
	]);

 	const relationItemsMap = new Map(batchRelationItems.map(item => [item._id.toString(), item]));
	const entityDataCache = new Map(batchEntityData.map(item => [item._id.toString(), item]));
	const usersMap = new Map(batchUsers.map(user => [user._id.toString(), user]));
	const levelsMapBatch = new Map(batchLevels.map(level => [level._id.toString(), level]));
	const attributesMapBatch = new Map(batchAttributes.map(attr => [attr._id.toString(), attr]));

 	for (const item of items) {
 		for (const [index, relation] of item?.relations?.entries() || []) {
			item.relations[index].level = levelsMap.get(relation?.level?.toString());
			const relationItems = relation?.items || [];
			relation.items = relationItems
				.map(id => relationItemsMap.get(id.toString()))
				.filter(Boolean)
				.map(i => ({ ...i, isRemoved: !dsScope.includes(i._id.toString()) }));
		}

		for (const [index, attribute] of item?.populatedAttributes?.entries() || []) {
			const level = attributesMap.get(attribute?.attribute?.toString());
			if (['Values', 'Entity', 'User'].includes(level?.type)) {
				attribute.values = attribute?.values?.filter(value => value?.value || value?.name || value?.firstName);
				if (level?.type === 'Values') {
					attribute.values = attribute?.values?.map(value => {
						const itemValue = level?.values?.find(v => v?.name === value?.name);
						return {
							name: itemValue?.name,
							_id: itemValue?._id,
							id: itemValue?._id,
							value: itemValue?.name,
							color: itemValue?.color
						};
					});
				}
				if (level?.type === 'Entity') {
					const values = attribute?.values || [];
					attribute.values = values.map(value => {
						const entityItem = entityDataCache.get(value?.value?.toString());
						return {
							_id: entityItem?._id,
							value: entityItem?.name,
							name: entityItem?.name,
							id: entityItem?._id,
							isRemoved: !dsScope.includes(entityItem?._id?.toString())
						};
					});
				}
				if (level?.type === 'User') {
					attribute.values = attribute?.values?.map(value => {
						return {
							name: value?.familyName ? `${value?.firstName} ${value?.familyName}` : value?.firstName,
							_id: value?._id,
							id: value?._id,
							firstName: value?.firstName,
							familyName: value?.familyName
						};
					});
				}
			}
			item.populatedAttributes[index] = {
				values: attribute.values,
				level: level,
				attribute: attribute?.attribute
			};
		}
	}

	// Pre-fetch all attributes needed for featured data
	const featuredAttributeIds = featuredData
		?.filter(f => (f?.type === 'ATTRIBUTE' && f?.isAllowedToEdit) || f?.type === 'ATTRIBUTE_RELATION')
		?.map(f => f?.value?.attribute)
		?.filter(Boolean);

	const featuredAttributes = featuredAttributeIds?.length
		? await attributeDAO.find(
				{ _id: { $in: featuredAttributeIds } },
				'level entityLevel values businessRoles form boundaries'
		  )
		: [];

	const featuredAttributesMap = new Map(featuredAttributes.map(attr => [attr._id.toString(), attr]));

	// Pre-fetch all entity levels needed
	const entityLevelIds = featuredData
		?.filter(f => f?.entityReference && f?.entityLevel)
		?.map(f => f.entityLevel)
		?.filter(Boolean);

	const entityLevels = entityLevelIds?.length
		? await levelDAO.find({ _id: { $in: entityLevelIds } }, 'name translations')
		: [];

	const entityLevelsMap = new Map(entityLevels.map(level => [level._id.toString(), level]));

	// Process featured data with pre-fetched data
	for (let i = 0; i < featuredData?.length; i++) {
		const currentFeatured = featuredData[i];
		if (
			(currentFeatured?.type === 'ATTRIBUTE' && currentFeatured?.isAllowedToEdit) ||
			currentFeatured?.type === 'ATTRIBUTE_RELATION'
		) {
			const attribute = featuredAttributesMap.get(currentFeatured?.value?.attribute?.toString());
			if (!attribute) continue;

			// add values for entity, user, and values
			if (currentFeatured?.attributeType === 'User') {
				const query = attribute?.businessRoles?.length
					? {
							$or: [
								{ businessRole: { $in: attribute?.businessRoles } },
								{ 'datasets.businessRole': { $in: attribute?.businessRoles } }
							]
					  }
					: {};
				const users = await userDAO.find(query, 'firstName familyName active');
				currentFeatured.users = users?.map(user => ({
					_id: user?._id,
					active: user?.active,
					name: `${user?.firstName} ${user?.familyName}`,
					firstName: user?.firstName,
					familyName: user?.familyName
				}));
			} else if (currentFeatured?.attributeType === 'Entity') {
				const pipeLine = await buildItemsPipeline(
					currentFeatured?.restrictions,
					attribute?.entityLevel,
					dataset,
					isSuperAdmin,
					batchEntityIds
				);
				currentFeatured.items = await itemDAO.aggregate(pipeLine);
				currentFeatured.items = currentFeatured.items.map(i => ({
					...i,
					isRemoved: !dsScope.includes(i._id.toString())
				}));
			} else if (currentFeatured?.attributeType === 'Values') {
				currentFeatured.allValues = attribute?.values.map(value => ({
					...value,
					id: value?._id,
					value: value?.name
				}));
			} else if (currentFeatured?.attributeType === 'String') {
				currentFeatured.form = attribute?.form;
				if (currentFeatured?.entityReference && currentFeatured?.entityLevel) {
					currentFeatured.entityLevel = entityLevelsMap.get(currentFeatured.entityLevel?.toString());
				}
			} else if (currentFeatured?.attributeType === 'Number') {
				currentFeatured.boundaries = attribute?.boundaries;
				if (currentFeatured?.entityReference && currentFeatured?.entityLevel) {
					currentFeatured.entityLevel = entityLevelsMap.get(currentFeatured.entityLevel?.toString());
				}
			}
		}
	}

	for (const [index, item] of items.entries()) {
		const relations = item.relations.map(relation => ({
			level: relation.level,
			values: relation.items.map(i => ({ ...i, isRemoved: !dsScope.includes(i._id.toString()) }))
		}));
		const attributes = item.populatedAttributes.map(attr => ({ level: attr?.level, values: attr.values }));
		const featuredRelations = relations.filter(relation =>
			featuredData.map(f => f.value.entity?.toString()).includes(relation?.level?._id?.toString())
		);
		const featuredAttributes = attributes.filter(attribute =>
			featuredData
				.map(f => f.value?.attribute?.toString())
				.includes(attribute?.level?.attribute?.toString() || attribute?.level?._id?.toString())
		);
		const featured = [];
		const featuredLength = featuredData?.length;
		for (let index = 0; index < featuredLength; ++index) {
			const currentFeatured = featuredData[index];
			if (currentFeatured.type === 'DEFAULT') {
				let value;
				if (['createdBy', 'updatedBy'].includes(currentFeatured?.value?.default)) {
					const user = usersMap.get(item[currentFeatured?.value?.default]?.toString());
					value = user ? user?.firstName + ' ' + user?.familyName : '';
				} else {
					value = currentFeatured?.value?.default ? { value: item[currentFeatured?.value?.default] } : null;
				}
				const values = value ? [value] : [];
				const level = { name: currentFeatured?.value?.default, type: 'Default' };
				featured.push({ level, values });
			} else if (currentFeatured.type === 'RELATION') {
				const relation = featuredRelations?.find(
					f2 => f2?.level?._id?.toString() === currentFeatured?.value?.entity.toString()
				);
				if (relation) featured.push({ level: relation?.level, values: relation?.values });
				else {
					const level =
						levelsMapBatch.get(currentFeatured.value?.entity?.toString()) ||
						levelsMap.get(currentFeatured.value?.entity?.toString());
					let values = await itemDAO.find({ 'relations.items': item?._id });
					values = values.map(i => ({ ...i, isRemoved: !dsScope.includes(i._id.toString()) }));
					featured.push({ level, values });
				}
			} else if (currentFeatured.type === 'ATTRIBUTE') {
				let featuredAttribute = featuredAttributes?.find(
					f2 => f2?.level?._id?.toString() === currentFeatured?.value?.attribute?.toString()
				);
				if (!featuredAttribute) {
					const featuredAttributeId = currentFeatured?.value?.attribute;
					featuredAttribute = {};
					featuredAttribute.level =
						attributesMapBatch.get(featuredAttributeId?.toString()) ||
						attributesMap.get(featuredAttributeId?.toString());
				}
				if (!currentFeatured?.value?.source?.model) {
					const featuredToPush = {
						level: featuredAttribute?.level,
						values: featuredAttribute?.values,
						isAllowedToEdit: currentFeatured?.isAllowedToEdit,
						isAllowedToBulkEdit: currentFeatured?.isAllowedToBulkEdit,
						addEntries: currentFeatured?.addEntries,
						attributeType: currentFeatured?.attributeType,
						localScope: currentFeatured?.localScope
					};
					// get values from item
					featured.push(featuredToPush);
				} else {
					// get values from profiling-v2 answers
					let query = {
						model: currentFeatured.value?.source?.model,
						centralItem: item._id,
						['data.' + featuredAttribute?.level?._id]: { $exists: true }
					};
					let currentFeaturedFrequency = await getFeaturedFrequency(currentFeatured?.value?.source);
					if (currentFeaturedFrequency === 'ADHOC') {
						query['isAdhoc'] = true;
						currentFeaturedFrequency = [];
					} else if (currentFeaturedFrequency?.length)
						query['frequency'] = { $in: currentFeaturedFrequency.map(f => f._id) };
					let values = await answerDAO.find(query, 'data frequency submitted', null, '-createdAt');
					if (values?.length) {
						if (currentFeaturedFrequency?.length) {
							values = currentFeaturedFrequency
								.map(
									f =>
										values.find(a => a.frequency.toString() === f._id.toString())?.data[
											featuredAttribute.level._id
										]
								)
								.filter(v => v?.length)
								.flat();
						} else {
							values = values
								.map(a => a?.data[featuredAttribute.level._id])
								.filter(v => v?.length)
								.flat();
						}
						if (featuredAttribute?.level?.type === 'Values') {
							values = values?.map(val =>
								featuredAttribute.level.values.find(v => v?._id?.toString() === val?.toString())
							);
						}

						if (featuredAttribute?.level?.type === 'Entity') {
							const valuePromises = values.map(value => itemDAO.findById(value, true, 'name attributes'));
							const resolvedValues = await Promise.all(valuePromises);
							values = resolvedValues.map(result => result?.name);
						}

						if (['Number', 'Date', 'Boolean', 'Text'].includes(featuredAttribute?.level?.type)) {
							values = values?.map(val => ({ value: val }));
						}
					}
					for (let index = 0; index < values.length; index++) {
						const attribute = values[index];
						if (typeof attribute === 'string') {
							values[index] = { value: attribute };
						}
					}
					featured.push({
						level: featuredAttribute?.level,
						values,
						frequencies: currentFeaturedFrequency?.map(f => f?.period)
					});
				}
			} else if (currentFeatured.type === 'ATTRIBUTE_RELATION') {
				//Get Selected xRef attribute to show
				const attributesCurrentFeatured = item.populatedAttributes.find(
					attribute => attribute.level._id?.toString() === currentFeatured.value?.linkedAttribute?.toString()
				);
				// attributesCurrentFeatured is undefined if currentFeatured is a natural attribute
				if (attributesCurrentFeatured) {
					let valuesOfEntityAttribute = item.attributes
						.find(
							attribute =>
								attribute.attribute.toString() === attributesCurrentFeatured.level._id.toString()
						)
						.values?.filter(
							value => /^[0-9a-fA-F]{24}$/.test(value?.value) && dsScope.includes(value?.value)
						);
					const currentAttr = attributesData.find(
						attribute => attribute._id.toString() === currentFeatured.value.attribute?.toString()
					);
					const originAttribute = cloneDeep(currentAttr);
					originAttribute.name = `${originAttribute?.name} ( ${attributesCurrentFeatured?.level?.name} )`;
					const values = [];
					if (valuesOfEntityAttribute?.length) {
						const itemsIds = valuesOfEntityAttribute
							?.map(value => value?.value)
							?.filter(value => value && /^[0-9a-fA-F]{24}$/.test(value));
						// Batch fetch all item entity attributes
						const itemEntityAttributes = await itemDAO.find({ _id: { $in: itemsIds } }, 'name attributes');
						const itemEntityAttributesMap = new Map(
							itemEntityAttributes.map(item => [item._id.toString(), item])
						);

						for (const itemId of itemsIds) {
							const itemEntityAttribute = itemEntityAttributesMap.get(itemId?.toString());
							if (!itemEntityAttribute) continue;
							itemEntityAttribute.isRemoved = !dsScope.includes(itemEntityAttribute?._id?.toString());
							//Get values of the xRef attribute to show related to the current item
							let xRefItemValues = itemEntityAttribute?.attributes?.find(
								attribute =>
									attribute?.attribute?.toString() === currentFeatured?.value?.attribute?.toString()
							)?.values;
							if (originAttribute?.type === 'Values') {
								xRefItemValues = originAttribute.values.filter(value =>
									xRefItemValues?.map(v => v?.name).includes(value?.name)
								);
							}
							if (isQualitrack) {
								let shouldReplace = false;

								if (originAttribute?.type === 'Values') {
									shouldReplace =
										!xRefItemValues ||
										xRefItemValues.length === 0 ||
										xRefItemValues.every(
											item =>
												!item?.name &&
												(item?.value === null ||
													item?.value === undefined ||
													!item.hasOwnProperty('value'))
										);
								} else {
									shouldReplace =
										!xRefItemValues ||
										xRefItemValues.length === 0 ||
										xRefItemValues.every(
											item =>
												item?.value === null ||
												item?.value === undefined ||
												!item.hasOwnProperty('value')
										);
								}

								if (shouldReplace) {
									const existingId =
										xRefItemValues && xRefItemValues.length > 0 && xRefItemValues[0]?.id
											? xRefItemValues[0].id
											: itemId;

									xRefItemValues = [{ value: '-', id: existingId }];
								}
							}
							values.push(xRefItemValues);
						}
					}
					featured.push({ level: originAttribute, values: values?.flat() });
				} else {
					//Get the item of the natural relation
					const attributesCurrentFeatured = item.relations.find(
						relation => relation.level?._id?.toString() === currentFeatured.value?.entity?.toString()
					);

					const originAttribute = attributesData.find(
						attribute => attribute._id.toString() === currentFeatured.value.attribute?.toString()
					);
					let naturalAttributeValues = [];
					if (attributesCurrentFeatured?.items?.length) {
						const itemRelations = attributesCurrentFeatured.items;
						if (itemRelations?.length) {
							naturalAttributeValues = itemRelations.reduce((acc, curr) => {
								const currentItemValues =
									curr?.attributes?.find(
										attribute =>
											attribute.attribute.toString() ===
											currentFeatured.value.attribute?.toString()
									)?.values || [];
								return [...acc, ...currentItemValues];
							}, []);
							if (originAttribute.type === 'Values') {
								naturalAttributeValues = originAttribute.values?.filter(value =>
									naturalAttributeValues?.map(v => v?.name).includes(value.name)
								);
							}
						}
					}
					featured.push({ level: originAttribute, values: naturalAttributeValues });
				}
			} else if (currentFeatured.type === 'LIBRARY') {
				//only for qualitrack
				let featuredAttribute = cloneDeep(
					featuredAttributes?.find(
						attribute => attribute?.level?._id?.toString() === currentFeatured?.value?.attribute?.toString()
					)
				);
				if (!featuredAttribute)
					featuredAttribute = { level: { _id: currentFeatured?.value?.attribute, library: {} }, values: [] };
				else
					featuredAttribute.level.library =
						librariesMap.get(featuredAttribute.level?.library?.toString()) || {};
				featured.push({ level: featuredAttribute.level, values: featuredAttribute.values });
			}
		}
		delete item.attributes;
		delete item.populatedAttributes;
		items[index] = { ...item, featured };
	}
	return items;
};
Editor is loading...
Leave a Comment