Files
EM2_ERP/em2rp/functions/utils/helpers.js
T

192 lines
4.8 KiB
JavaScript

/**
* Helpers pour la manipulation de données Firestore
*/
const admin = require("firebase-admin");
/**
* Convertit les Timestamps Firestore en ISO strings pour JSON
*/
function serializeTimestamps(data) {
if (!data) return data;
// Éviter la récursion sur les types Firestore spéciaux
if (data._firestore || data._path || data._converter) {
// C'est un objet Firestore interne, ne pas le traiter
if (data.id && data.path) {
// C'est une DocumentReference
return data.path;
}
return null;
}
const result = {...data};
for (const key in result) {
const value = result[key];
if (!value) {
continue;
}
// Gérer les Timestamps Firestore
if (value.toDate && typeof value.toDate === "function") {
result[key] = value.toDate().toISOString();
}
// Gérer les DocumentReference
else if (value.path && value.id && typeof value.path === "string") {
result[key] = value.path;
}
// Gérer les GeoPoint
else if (value.latitude !== undefined && value.longitude !== undefined) {
result[key] = {
latitude: value.latitude,
longitude: value.longitude,
};
}
// Gérer les tableaux
else if (Array.isArray(value)) {
result[key] = value.map((item) => {
if (!item || typeof item !== "object") return item;
// DocumentReference dans un tableau
if (item.path && item.id) {
return item.path;
}
// Timestamp dans un tableau
if (item.toDate && typeof item.toDate === "function") {
return item.toDate().toISOString();
}
// Objet normal
return serializeTimestamps(item);
});
}
// Gérer les objets imbriqués (mais pas les objets Firestore)
else if (typeof value === "object" && !value._firestore && !value._path) {
result[key] = serializeTimestamps(value);
}
}
return result;
}
/**
* Convertit les ISO strings en Timestamps Firestore
*/
function deserializeTimestamps(data, timestampFields = []) {
if (!data) return data;
const result = {...data};
for (const field of timestampFields) {
if (result[field] && typeof result[field] === "string") {
result[field] = admin.firestore.Timestamp.fromDate(new Date(result[field]));
}
}
return result;
}
/**
* Convertit les références DocumentReference en IDs
*/
function serializeReferences(data) {
if (!data) return data;
const result = {...data};
for (const key in result) {
if (result[key] && result[key].path && typeof result[key].path === "string") {
// C'est une DocumentReference
result[key] = result[key].id;
} else if (Array.isArray(result[key])) {
result[key] = result[key].map((item) => {
if (item && item.path && typeof item.path === "string") {
return item.id;
}
return item;
});
}
}
return result;
}
/**
* Masque les champs sensibles selon les permissions
*/
function maskSensitiveFields(data, canViewSensitive) {
if (canViewSensitive) return data;
const masked = {...data};
// Masquer les prix si pas de permission manage_equipment
delete masked.purchasePrice;
delete masked.rentalPrice;
return masked;
}
/**
* Pagination helper
*/
function paginate(query, limit = 50, startAfter = null) {
let paginatedQuery = query.limit(limit);
if (startAfter) {
paginatedQuery = paginatedQuery.startAfter(startAfter);
}
return paginatedQuery;
}
/**
* Filtre les événements annulés
*/
function filterCancelledEvents(events) {
return events.filter((event) => event.status !== "CANCELLED");
}
/**
* Convertit les IDs en DocumentReference pour maintenir la compatibilité avec l'ancien format
* @param {Object} data - Données de l'événement
* @return {Object} - Données avec DocumentReference
*/
function convertIdsToReferences(data) {
if (!data) return data;
const result = {...data};
// Convertir EventType (ID → DocumentReference)
if (result.EventType && typeof result.EventType === "string" && !result.EventType.includes("/")) {
result.EventType = admin.firestore().collection("eventTypes").doc(result.EventType);
}
// Convertir customer (ID → DocumentReference)
if (result.customer && typeof result.customer === "string" && !result.customer.includes("/")) {
result.customer = admin.firestore().collection("customers").doc(result.customer);
}
// Convertir workforce (IDs → DocumentReference)
if (Array.isArray(result.workforce)) {
result.workforce = result.workforce.map((item) => {
if (typeof item === "string" && !item.includes("/")) {
return admin.firestore().collection("users").doc(item);
}
return item;
});
}
return result;
}
module.exports = {
serializeTimestamps,
deserializeTimestamps,
serializeReferences,
maskSensitiveFields,
paginate,
filterCancelledEvents,
convertIdsToReferences,
};