@blackcode_sa/metaestetics-api 1.12.39 → 1.12.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/index.d.mts +12 -6
- package/dist/admin/index.d.ts +12 -6
- package/dist/backoffice/index.d.mts +178 -19
- package/dist/backoffice/index.d.ts +178 -19
- package/dist/backoffice/index.js +261 -17
- package/dist/backoffice/index.mjs +277 -30
- package/dist/index.d.mts +170 -11
- package/dist/index.d.ts +170 -11
- package/dist/index.js +346 -25
- package/dist/index.mjs +357 -33
- package/package.json +1 -1
- package/src/backoffice/services/migrate-products.ts +116 -0
- package/src/backoffice/services/product.service.ts +216 -21
- package/src/backoffice/services/technology.service.ts +111 -0
- package/src/backoffice/types/product.types.ts +115 -6
- package/src/services/appointment/appointment.service.ts +120 -16
package/dist/index.js
CHANGED
|
@@ -2337,9 +2337,57 @@ var AppointmentService = class extends BaseService {
|
|
|
2337
2337
|
* @returns The updated appointment
|
|
2338
2338
|
*/
|
|
2339
2339
|
async updateAppointment(appointmentId, data) {
|
|
2340
|
+
var _a, _b, _c, _d;
|
|
2340
2341
|
try {
|
|
2341
2342
|
console.log(`[APPOINTMENT_SERVICE] Updating appointment with ID: ${appointmentId}`);
|
|
2343
|
+
if ((_a = data.metadata) == null ? void 0 : _a.zonePhotos) {
|
|
2344
|
+
const migratedZonePhotos = {};
|
|
2345
|
+
for (const [key, value] of Object.entries(data.metadata.zonePhotos)) {
|
|
2346
|
+
if (Array.isArray(value)) {
|
|
2347
|
+
migratedZonePhotos[key] = value;
|
|
2348
|
+
} else {
|
|
2349
|
+
console.log(`[APPOINTMENT_SERVICE] Auto-migrating ${key} from object to array format`);
|
|
2350
|
+
const oldData = value;
|
|
2351
|
+
migratedZonePhotos[key] = [
|
|
2352
|
+
{
|
|
2353
|
+
before: oldData.before || null,
|
|
2354
|
+
after: oldData.after || null,
|
|
2355
|
+
beforeNote: null,
|
|
2356
|
+
afterNote: null
|
|
2357
|
+
}
|
|
2358
|
+
];
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
data.metadata.zonePhotos = migratedZonePhotos;
|
|
2362
|
+
}
|
|
2363
|
+
console.log(
|
|
2364
|
+
"[APPOINTMENT_SERVICE] \u{1F50D} BEFORE CLEANUP - recommendedProcedures:",
|
|
2365
|
+
JSON.stringify((_b = data.metadata) == null ? void 0 : _b.recommendedProcedures, null, 2)
|
|
2366
|
+
);
|
|
2367
|
+
if (((_c = data.metadata) == null ? void 0 : _c.recommendedProcedures) && Array.isArray(data.metadata.recommendedProcedures)) {
|
|
2368
|
+
const validRecommendations = data.metadata.recommendedProcedures.filter((rec) => {
|
|
2369
|
+
const isValid = rec.note && typeof rec.note === "string" && rec.note.trim().length > 0;
|
|
2370
|
+
if (!isValid) {
|
|
2371
|
+
console.log("[APPOINTMENT_SERVICE] \u274C INVALID recommendation found:", rec);
|
|
2372
|
+
}
|
|
2373
|
+
return isValid;
|
|
2374
|
+
});
|
|
2375
|
+
if (validRecommendations.length !== data.metadata.recommendedProcedures.length) {
|
|
2376
|
+
console.log(
|
|
2377
|
+
`[APPOINTMENT_SERVICE] \u{1F9F9} Removing ${data.metadata.recommendedProcedures.length - validRecommendations.length} invalid recommended procedures with empty notes`
|
|
2378
|
+
);
|
|
2379
|
+
data.metadata.recommendedProcedures = validRecommendations;
|
|
2380
|
+
} else {
|
|
2381
|
+
console.log("[APPOINTMENT_SERVICE] \u2705 All recommendedProcedures are valid");
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
console.log(
|
|
2385
|
+
"[APPOINTMENT_SERVICE] \u{1F50D} AFTER CLEANUP - recommendedProcedures:",
|
|
2386
|
+
JSON.stringify((_d = data.metadata) == null ? void 0 : _d.recommendedProcedures, null, 2)
|
|
2387
|
+
);
|
|
2388
|
+
console.log("[APPOINTMENT_SERVICE] \u{1F50D} Starting Zod validation...");
|
|
2342
2389
|
const validatedData = await updateAppointmentSchema.parseAsync(data);
|
|
2390
|
+
console.log("[APPOINTMENT_SERVICE] \u2705 Zod validation passed!");
|
|
2343
2391
|
const updatedAppointment = await updateAppointmentUtil(this.db, appointmentId, validatedData);
|
|
2344
2392
|
console.log(`[APPOINTMENT_SERVICE] Appointment ${appointmentId} updated successfully`);
|
|
2345
2393
|
return updatedAppointment;
|
|
@@ -2977,7 +3025,25 @@ var AppointmentService = class extends BaseService {
|
|
|
2977
3025
|
finalbilling: null,
|
|
2978
3026
|
finalizationNotes: null
|
|
2979
3027
|
};
|
|
2980
|
-
|
|
3028
|
+
let currentZonePhotos = {};
|
|
3029
|
+
if (currentMetadata.zonePhotos) {
|
|
3030
|
+
for (const [key, value] of Object.entries(currentMetadata.zonePhotos)) {
|
|
3031
|
+
if (Array.isArray(value)) {
|
|
3032
|
+
currentZonePhotos[key] = value;
|
|
3033
|
+
} else {
|
|
3034
|
+
console.log(`[APPOINTMENT_SERVICE] Auto-migrating ${key} from object to array format`);
|
|
3035
|
+
const oldData = value;
|
|
3036
|
+
currentZonePhotos[key] = [
|
|
3037
|
+
{
|
|
3038
|
+
before: oldData.before || null,
|
|
3039
|
+
after: oldData.after || null,
|
|
3040
|
+
beforeNote: null,
|
|
3041
|
+
afterNote: null
|
|
3042
|
+
}
|
|
3043
|
+
];
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
2981
3047
|
if (!currentZonePhotos[zoneId]) {
|
|
2982
3048
|
currentZonePhotos[zoneId] = [];
|
|
2983
3049
|
}
|
|
@@ -3376,7 +3442,13 @@ var AppointmentService = class extends BaseService {
|
|
|
3376
3442
|
console.log(
|
|
3377
3443
|
`[APPOINTMENT_SERVICE] Adding recommended procedure ${procedureId} to appointment ${appointmentId}`
|
|
3378
3444
|
);
|
|
3379
|
-
return await addRecommendedProcedureUtil(
|
|
3445
|
+
return await addRecommendedProcedureUtil(
|
|
3446
|
+
this.db,
|
|
3447
|
+
appointmentId,
|
|
3448
|
+
procedureId,
|
|
3449
|
+
note,
|
|
3450
|
+
timeframe
|
|
3451
|
+
);
|
|
3380
3452
|
} catch (error) {
|
|
3381
3453
|
console.error(`[APPOINTMENT_SERVICE] Error adding recommended procedure:`, error);
|
|
3382
3454
|
throw error;
|
|
@@ -3413,7 +3485,12 @@ var AppointmentService = class extends BaseService {
|
|
|
3413
3485
|
console.log(
|
|
3414
3486
|
`[APPOINTMENT_SERVICE] Updating recommended procedure at index ${recommendationIndex} in appointment ${appointmentId}`
|
|
3415
3487
|
);
|
|
3416
|
-
return await updateRecommendedProcedureUtil(
|
|
3488
|
+
return await updateRecommendedProcedureUtil(
|
|
3489
|
+
this.db,
|
|
3490
|
+
appointmentId,
|
|
3491
|
+
recommendationIndex,
|
|
3492
|
+
updates
|
|
3493
|
+
);
|
|
3417
3494
|
} catch (error) {
|
|
3418
3495
|
console.error(`[APPOINTMENT_SERVICE] Error updating recommended procedure:`, error);
|
|
3419
3496
|
throw error;
|
|
@@ -18570,6 +18647,11 @@ var SubcategoryService = class extends BaseService {
|
|
|
18570
18647
|
|
|
18571
18648
|
// src/backoffice/services/technology.service.ts
|
|
18572
18649
|
var import_firestore61 = require("firebase/firestore");
|
|
18650
|
+
|
|
18651
|
+
// src/backoffice/types/product.types.ts
|
|
18652
|
+
var PRODUCTS_COLLECTION = "products";
|
|
18653
|
+
|
|
18654
|
+
// src/backoffice/services/technology.service.ts
|
|
18573
18655
|
var DEFAULT_CERTIFICATION_REQUIREMENT = {
|
|
18574
18656
|
minimumLevel: "aesthetician" /* AESTHETICIAN */,
|
|
18575
18657
|
requiredSpecialties: []
|
|
@@ -19167,18 +19249,109 @@ var TechnologyService = class extends BaseService {
|
|
|
19167
19249
|
})
|
|
19168
19250
|
);
|
|
19169
19251
|
}
|
|
19252
|
+
// ==========================================
|
|
19253
|
+
// NEW METHODS: Product assignment management
|
|
19254
|
+
// ==========================================
|
|
19255
|
+
/**
|
|
19256
|
+
* Assigns multiple products to a technology
|
|
19257
|
+
* Updates each product's assignedTechnologyIds array
|
|
19258
|
+
*/
|
|
19259
|
+
async assignProducts(technologyId, productIds) {
|
|
19260
|
+
const batch = (0, import_firestore61.writeBatch)(this.db);
|
|
19261
|
+
for (const productId of productIds) {
|
|
19262
|
+
const productRef = (0, import_firestore61.doc)(this.db, PRODUCTS_COLLECTION, productId);
|
|
19263
|
+
batch.update(productRef, {
|
|
19264
|
+
assignedTechnologyIds: (0, import_firestore61.arrayUnion)(technologyId),
|
|
19265
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
19266
|
+
});
|
|
19267
|
+
}
|
|
19268
|
+
await batch.commit();
|
|
19269
|
+
}
|
|
19270
|
+
/**
|
|
19271
|
+
* Unassigns multiple products from a technology
|
|
19272
|
+
* Updates each product's assignedTechnologyIds array
|
|
19273
|
+
*/
|
|
19274
|
+
async unassignProducts(technologyId, productIds) {
|
|
19275
|
+
const batch = (0, import_firestore61.writeBatch)(this.db);
|
|
19276
|
+
for (const productId of productIds) {
|
|
19277
|
+
const productRef = (0, import_firestore61.doc)(this.db, PRODUCTS_COLLECTION, productId);
|
|
19278
|
+
batch.update(productRef, {
|
|
19279
|
+
assignedTechnologyIds: (0, import_firestore61.arrayRemove)(technologyId),
|
|
19280
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
19281
|
+
});
|
|
19282
|
+
}
|
|
19283
|
+
await batch.commit();
|
|
19284
|
+
}
|
|
19285
|
+
/**
|
|
19286
|
+
* Gets products assigned to a specific technology
|
|
19287
|
+
* Reads from top-level collection for immediate consistency (Cloud Functions may lag)
|
|
19288
|
+
*/
|
|
19289
|
+
async getAssignedProducts(technologyId) {
|
|
19290
|
+
const q = (0, import_firestore61.query)(
|
|
19291
|
+
(0, import_firestore61.collection)(this.db, PRODUCTS_COLLECTION),
|
|
19292
|
+
(0, import_firestore61.where)("assignedTechnologyIds", "array-contains", technologyId),
|
|
19293
|
+
(0, import_firestore61.where)("isActive", "==", true),
|
|
19294
|
+
(0, import_firestore61.orderBy)("name")
|
|
19295
|
+
);
|
|
19296
|
+
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19297
|
+
return snapshot.docs.map(
|
|
19298
|
+
(doc44) => ({
|
|
19299
|
+
id: doc44.id,
|
|
19300
|
+
...doc44.data()
|
|
19301
|
+
})
|
|
19302
|
+
);
|
|
19303
|
+
}
|
|
19304
|
+
/**
|
|
19305
|
+
* Gets products NOT assigned to a specific technology
|
|
19306
|
+
*/
|
|
19307
|
+
async getUnassignedProducts(technologyId) {
|
|
19308
|
+
const q = (0, import_firestore61.query)(
|
|
19309
|
+
(0, import_firestore61.collection)(this.db, PRODUCTS_COLLECTION),
|
|
19310
|
+
(0, import_firestore61.where)("isActive", "==", true),
|
|
19311
|
+
(0, import_firestore61.orderBy)("name")
|
|
19312
|
+
);
|
|
19313
|
+
const snapshot = await (0, import_firestore61.getDocs)(q);
|
|
19314
|
+
const allProducts = snapshot.docs.map(
|
|
19315
|
+
(doc44) => ({
|
|
19316
|
+
id: doc44.id,
|
|
19317
|
+
...doc44.data()
|
|
19318
|
+
})
|
|
19319
|
+
);
|
|
19320
|
+
return allProducts.filter(
|
|
19321
|
+
(product) => {
|
|
19322
|
+
var _a;
|
|
19323
|
+
return !((_a = product.assignedTechnologyIds) == null ? void 0 : _a.includes(technologyId));
|
|
19324
|
+
}
|
|
19325
|
+
);
|
|
19326
|
+
}
|
|
19327
|
+
/**
|
|
19328
|
+
* Gets product assignment statistics for a technology
|
|
19329
|
+
*/
|
|
19330
|
+
async getProductStats(technologyId) {
|
|
19331
|
+
const products = await this.getAssignedProducts(technologyId);
|
|
19332
|
+
const byBrand = {};
|
|
19333
|
+
products.forEach((product) => {
|
|
19334
|
+
byBrand[product.brandName] = (byBrand[product.brandName] || 0) + 1;
|
|
19335
|
+
});
|
|
19336
|
+
return {
|
|
19337
|
+
totalAssigned: products.length,
|
|
19338
|
+
byBrand
|
|
19339
|
+
};
|
|
19340
|
+
}
|
|
19170
19341
|
};
|
|
19171
19342
|
|
|
19172
19343
|
// src/backoffice/services/product.service.ts
|
|
19173
19344
|
var import_firestore62 = require("firebase/firestore");
|
|
19174
|
-
|
|
19175
|
-
// src/backoffice/types/product.types.ts
|
|
19176
|
-
var PRODUCTS_COLLECTION = "products";
|
|
19177
|
-
|
|
19178
|
-
// src/backoffice/services/product.service.ts
|
|
19179
19345
|
var ProductService = class extends BaseService {
|
|
19180
19346
|
/**
|
|
19181
|
-
* Gets reference to products collection
|
|
19347
|
+
* Gets reference to top-level products collection (source of truth)
|
|
19348
|
+
* @returns Firestore collection reference
|
|
19349
|
+
*/
|
|
19350
|
+
getTopLevelProductsRef() {
|
|
19351
|
+
return (0, import_firestore62.collection)(this.db, PRODUCTS_COLLECTION);
|
|
19352
|
+
}
|
|
19353
|
+
/**
|
|
19354
|
+
* Gets reference to products collection under a technology (backward compatibility)
|
|
19182
19355
|
* @param technologyId - ID of the technology
|
|
19183
19356
|
* @returns Firestore collection reference
|
|
19184
19357
|
*/
|
|
@@ -19194,6 +19367,7 @@ var ProductService = class extends BaseService {
|
|
|
19194
19367
|
...product,
|
|
19195
19368
|
brandId,
|
|
19196
19369
|
technologyId,
|
|
19370
|
+
// Required for old subcollection structure
|
|
19197
19371
|
createdAt: now,
|
|
19198
19372
|
updatedAt: now,
|
|
19199
19373
|
isActive: true
|
|
@@ -19252,31 +19426,24 @@ var ProductService = class extends BaseService {
|
|
|
19252
19426
|
return snapshot.data().count;
|
|
19253
19427
|
}
|
|
19254
19428
|
/**
|
|
19255
|
-
* Gets counts of active products grouped by
|
|
19256
|
-
*
|
|
19429
|
+
* Gets counts of active products grouped by technology.
|
|
19430
|
+
* NOTE: Only counts top-level collection to avoid duplication during migration.
|
|
19431
|
+
* Categories/subcategories not available in top-level structure.
|
|
19257
19432
|
*/
|
|
19258
19433
|
async getProductCounts() {
|
|
19259
|
-
const q = (0, import_firestore62.query)((0, import_firestore62.collectionGroup)(this.db, PRODUCTS_COLLECTION), (0, import_firestore62.where)("isActive", "==", true));
|
|
19260
|
-
const snapshot = await (0, import_firestore62.getDocs)(q);
|
|
19261
19434
|
const counts = {
|
|
19262
19435
|
byCategory: {},
|
|
19263
19436
|
bySubcategory: {},
|
|
19264
19437
|
byTechnology: {}
|
|
19265
19438
|
};
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
}
|
|
19439
|
+
const q = (0, import_firestore62.query)(this.getTopLevelProductsRef(), (0, import_firestore62.where)("isActive", "==", true));
|
|
19440
|
+
const snapshot = await (0, import_firestore62.getDocs)(q);
|
|
19269
19441
|
snapshot.docs.forEach((doc44) => {
|
|
19270
19442
|
const product = doc44.data();
|
|
19271
|
-
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
if (subcategoryId) {
|
|
19276
|
-
counts.bySubcategory[subcategoryId] = (counts.bySubcategory[subcategoryId] || 0) + 1;
|
|
19277
|
-
}
|
|
19278
|
-
if (technologyId) {
|
|
19279
|
-
counts.byTechnology[technologyId] = (counts.byTechnology[technologyId] || 0) + 1;
|
|
19443
|
+
if (product.assignedTechnologyIds && Array.isArray(product.assignedTechnologyIds)) {
|
|
19444
|
+
product.assignedTechnologyIds.forEach((techId) => {
|
|
19445
|
+
counts.byTechnology[techId] = (counts.byTechnology[techId] || 0) + 1;
|
|
19446
|
+
});
|
|
19280
19447
|
}
|
|
19281
19448
|
});
|
|
19282
19449
|
return counts;
|
|
@@ -19355,6 +19522,160 @@ var ProductService = class extends BaseService {
|
|
|
19355
19522
|
...docSnap.data()
|
|
19356
19523
|
};
|
|
19357
19524
|
}
|
|
19525
|
+
// ==========================================
|
|
19526
|
+
// NEW METHODS: Top-level collection (preferred)
|
|
19527
|
+
// ==========================================
|
|
19528
|
+
/**
|
|
19529
|
+
* Creates a new product in the top-level collection
|
|
19530
|
+
*/
|
|
19531
|
+
async createTopLevel(brandId, product, technologyIds = []) {
|
|
19532
|
+
const now = /* @__PURE__ */ new Date();
|
|
19533
|
+
const newProduct = {
|
|
19534
|
+
...product,
|
|
19535
|
+
brandId,
|
|
19536
|
+
assignedTechnologyIds: technologyIds,
|
|
19537
|
+
createdAt: now,
|
|
19538
|
+
updatedAt: now,
|
|
19539
|
+
isActive: true
|
|
19540
|
+
};
|
|
19541
|
+
const productRef = await (0, import_firestore62.addDoc)(this.getTopLevelProductsRef(), newProduct);
|
|
19542
|
+
return { id: productRef.id, ...newProduct };
|
|
19543
|
+
}
|
|
19544
|
+
/**
|
|
19545
|
+
* Gets all products from the top-level collection
|
|
19546
|
+
*/
|
|
19547
|
+
async getAllTopLevel(options) {
|
|
19548
|
+
const { rowsPerPage, lastVisible, brandId } = options;
|
|
19549
|
+
const constraints = [(0, import_firestore62.where)("isActive", "==", true), (0, import_firestore62.orderBy)("name")];
|
|
19550
|
+
if (brandId) {
|
|
19551
|
+
constraints.push((0, import_firestore62.where)("brandId", "==", brandId));
|
|
19552
|
+
}
|
|
19553
|
+
if (lastVisible) {
|
|
19554
|
+
constraints.push((0, import_firestore62.startAfter)(lastVisible));
|
|
19555
|
+
}
|
|
19556
|
+
constraints.push((0, import_firestore62.limit)(rowsPerPage));
|
|
19557
|
+
const q = (0, import_firestore62.query)(this.getTopLevelProductsRef(), ...constraints);
|
|
19558
|
+
const snapshot = await (0, import_firestore62.getDocs)(q);
|
|
19559
|
+
const products = snapshot.docs.map(
|
|
19560
|
+
(doc44) => ({
|
|
19561
|
+
id: doc44.id,
|
|
19562
|
+
...doc44.data()
|
|
19563
|
+
})
|
|
19564
|
+
);
|
|
19565
|
+
const newLastVisible = snapshot.docs[snapshot.docs.length - 1];
|
|
19566
|
+
return { products, lastVisible: newLastVisible };
|
|
19567
|
+
}
|
|
19568
|
+
/**
|
|
19569
|
+
* Gets a product by ID from the top-level collection
|
|
19570
|
+
*/
|
|
19571
|
+
async getByIdTopLevel(productId) {
|
|
19572
|
+
const docRef = (0, import_firestore62.doc)(this.getTopLevelProductsRef(), productId);
|
|
19573
|
+
const docSnap = await (0, import_firestore62.getDoc)(docRef);
|
|
19574
|
+
if (!docSnap.exists()) return null;
|
|
19575
|
+
return {
|
|
19576
|
+
id: docSnap.id,
|
|
19577
|
+
...docSnap.data()
|
|
19578
|
+
};
|
|
19579
|
+
}
|
|
19580
|
+
/**
|
|
19581
|
+
* Updates a product in the top-level collection
|
|
19582
|
+
*/
|
|
19583
|
+
async updateTopLevel(productId, product) {
|
|
19584
|
+
const updateData = {
|
|
19585
|
+
...product,
|
|
19586
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
19587
|
+
};
|
|
19588
|
+
const docRef = (0, import_firestore62.doc)(this.getTopLevelProductsRef(), productId);
|
|
19589
|
+
await (0, import_firestore62.updateDoc)(docRef, updateData);
|
|
19590
|
+
return this.getByIdTopLevel(productId);
|
|
19591
|
+
}
|
|
19592
|
+
/**
|
|
19593
|
+
* Deletes a product from the top-level collection (soft delete)
|
|
19594
|
+
*/
|
|
19595
|
+
async deleteTopLevel(productId) {
|
|
19596
|
+
await this.updateTopLevel(productId, {
|
|
19597
|
+
isActive: false
|
|
19598
|
+
});
|
|
19599
|
+
}
|
|
19600
|
+
/**
|
|
19601
|
+
* Assigns a product to a technology
|
|
19602
|
+
*/
|
|
19603
|
+
async assignToTechnology(productId, technologyId) {
|
|
19604
|
+
const docRef = (0, import_firestore62.doc)(this.getTopLevelProductsRef(), productId);
|
|
19605
|
+
await (0, import_firestore62.updateDoc)(docRef, {
|
|
19606
|
+
assignedTechnologyIds: (0, import_firestore62.arrayUnion)(technologyId),
|
|
19607
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
19608
|
+
});
|
|
19609
|
+
}
|
|
19610
|
+
/**
|
|
19611
|
+
* Unassigns a product from a technology
|
|
19612
|
+
*/
|
|
19613
|
+
async unassignFromTechnology(productId, technologyId) {
|
|
19614
|
+
const docRef = (0, import_firestore62.doc)(this.getTopLevelProductsRef(), productId);
|
|
19615
|
+
await (0, import_firestore62.updateDoc)(docRef, {
|
|
19616
|
+
assignedTechnologyIds: (0, import_firestore62.arrayRemove)(technologyId),
|
|
19617
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
19618
|
+
});
|
|
19619
|
+
}
|
|
19620
|
+
/**
|
|
19621
|
+
* Gets products assigned to a specific technology
|
|
19622
|
+
*/
|
|
19623
|
+
async getAssignedProducts(technologyId) {
|
|
19624
|
+
const q = (0, import_firestore62.query)(
|
|
19625
|
+
this.getTopLevelProductsRef(),
|
|
19626
|
+
(0, import_firestore62.where)("assignedTechnologyIds", "array-contains", technologyId),
|
|
19627
|
+
(0, import_firestore62.where)("isActive", "==", true),
|
|
19628
|
+
(0, import_firestore62.orderBy)("name")
|
|
19629
|
+
);
|
|
19630
|
+
const snapshot = await (0, import_firestore62.getDocs)(q);
|
|
19631
|
+
return snapshot.docs.map(
|
|
19632
|
+
(doc44) => ({
|
|
19633
|
+
id: doc44.id,
|
|
19634
|
+
...doc44.data()
|
|
19635
|
+
})
|
|
19636
|
+
);
|
|
19637
|
+
}
|
|
19638
|
+
/**
|
|
19639
|
+
* Gets products NOT assigned to a specific technology
|
|
19640
|
+
*/
|
|
19641
|
+
async getUnassignedProducts(technologyId) {
|
|
19642
|
+
const q = (0, import_firestore62.query)(
|
|
19643
|
+
this.getTopLevelProductsRef(),
|
|
19644
|
+
(0, import_firestore62.where)("isActive", "==", true),
|
|
19645
|
+
(0, import_firestore62.orderBy)("name")
|
|
19646
|
+
);
|
|
19647
|
+
const snapshot = await (0, import_firestore62.getDocs)(q);
|
|
19648
|
+
const allProducts = snapshot.docs.map(
|
|
19649
|
+
(doc44) => ({
|
|
19650
|
+
id: doc44.id,
|
|
19651
|
+
...doc44.data()
|
|
19652
|
+
})
|
|
19653
|
+
);
|
|
19654
|
+
return allProducts.filter(
|
|
19655
|
+
(product) => {
|
|
19656
|
+
var _a;
|
|
19657
|
+
return !((_a = product.assignedTechnologyIds) == null ? void 0 : _a.includes(technologyId));
|
|
19658
|
+
}
|
|
19659
|
+
);
|
|
19660
|
+
}
|
|
19661
|
+
/**
|
|
19662
|
+
* Gets all products for a brand (from top-level collection)
|
|
19663
|
+
*/
|
|
19664
|
+
async getByBrand(brandId) {
|
|
19665
|
+
const q = (0, import_firestore62.query)(
|
|
19666
|
+
this.getTopLevelProductsRef(),
|
|
19667
|
+
(0, import_firestore62.where)("brandId", "==", brandId),
|
|
19668
|
+
(0, import_firestore62.where)("isActive", "==", true),
|
|
19669
|
+
(0, import_firestore62.orderBy)("name")
|
|
19670
|
+
);
|
|
19671
|
+
const snapshot = await (0, import_firestore62.getDocs)(q);
|
|
19672
|
+
return snapshot.docs.map(
|
|
19673
|
+
(doc44) => ({
|
|
19674
|
+
id: doc44.id,
|
|
19675
|
+
...doc44.data()
|
|
19676
|
+
})
|
|
19677
|
+
);
|
|
19678
|
+
}
|
|
19358
19679
|
};
|
|
19359
19680
|
|
|
19360
19681
|
// src/backoffice/services/constants.service.ts
|