@blackcode_sa/metaestetics-api 1.12.43 → 1.12.46

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.
@@ -33,14 +33,15 @@ export function calculateItemSubtotal(item: Partial<ZoneItemData>): number {
33
33
  return 0;
34
34
  }
35
35
 
36
- // If price override amount is set, use it
36
+ const quantity = item.quantity || 0;
37
+
38
+ // If price override amount is set, use it as price per unit
37
39
  if (item.priceOverrideAmount !== undefined && item.priceOverrideAmount !== null) {
38
- return item.priceOverrideAmount;
40
+ return item.priceOverrideAmount * quantity;
39
41
  }
40
42
 
41
43
  // Calculate normally: price * quantity
42
44
  const price = item.price || 0;
43
- const quantity = item.quantity || 0;
44
45
  return price * quantity;
45
46
  }
46
47
 
@@ -52,7 +53,7 @@ export function calculateItemSubtotal(item: Partial<ZoneItemData>): number {
52
53
  */
53
54
  export function calculateFinalBilling(
54
55
  zonesData: Record<string, ZoneItemData[]>,
55
- taxRate: number = 0.2,
56
+ taxRate: number = 0.081,
56
57
  ): FinalBilling {
57
58
  let subtotalAll = 0;
58
59
 
@@ -167,8 +168,8 @@ export async function addItemToZoneUtil(
167
168
  // Add item to zone
168
169
  zonesData[zoneId].push(itemWithSubtotal);
169
170
 
170
- // Recalculate final billing
171
- const finalbilling = calculateFinalBilling(zonesData); //TODO: add correct amount of tax
171
+ // Recalculate final billing with Swiss tax rate (8.1%)
172
+ const finalbilling = calculateFinalBilling(zonesData, 0.081);
172
173
 
173
174
  // Update appointment
174
175
  const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
@@ -218,8 +219,8 @@ export async function removeItemFromZoneUtil(
218
219
  delete metadata.zonesData[zoneId];
219
220
  }
220
221
 
221
- // Recalculate final billing
222
- const finalbilling = calculateFinalBilling(metadata.zonesData); //TODO: add correct amount of tax
222
+ // Recalculate final billing with Swiss tax rate (8.1%)
223
+ const finalbilling = calculateFinalBilling(metadata.zonesData, 0.081);
223
224
 
224
225
  // Update appointment
225
226
  const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
@@ -269,11 +270,24 @@ export async function updateZoneItemUtil(
269
270
  updatedAt: new Date().toISOString(),
270
271
  };
271
272
 
273
+ console.log(`[updateZoneItemUtil] BEFORE recalculation:`, {
274
+ itemIndex,
275
+ quantity: items[itemIndex].quantity,
276
+ priceOverrideAmount: items[itemIndex].priceOverrideAmount,
277
+ price: items[itemIndex].price,
278
+ oldSubtotal: items[itemIndex].subtotal,
279
+ });
280
+
272
281
  // Recalculate subtotal for this item
273
282
  items[itemIndex].subtotal = calculateItemSubtotal(items[itemIndex]);
274
283
 
275
- // Recalculate final billing
276
- const finalbilling = calculateFinalBilling(metadata.zonesData); //TODO: add correct amount of tax
284
+ console.log(`[updateZoneItemUtil] AFTER recalculation:`, {
285
+ itemIndex,
286
+ newSubtotal: items[itemIndex].subtotal,
287
+ });
288
+
289
+ // Recalculate final billing with Swiss tax rate (8.1%)
290
+ const finalbilling = calculateFinalBilling(metadata.zonesData, 0.081);
277
291
 
278
292
  // Update appointment
279
293
  const appointmentRef = doc(db, APPOINTMENTS_COLLECTION, appointmentId);
@@ -1,116 +0,0 @@
1
- import * as admin from 'firebase-admin';
2
- import { Product } from '../types/product.types';
3
-
4
- /**
5
- * Migration script to copy existing products from technology subcollections
6
- * to the new top-level products collection
7
- *
8
- * Usage: Run this once to migrate existing data
9
- */
10
- export async function migrateProductsToTopLevel(db: admin.firestore.Firestore) {
11
- console.log('🚀 Starting product migration...');
12
-
13
- // Get all technologies
14
- const technologiesSnapshot = await db.collection('technologies').get();
15
-
16
- const productMap = new Map<string, {
17
- product: any;
18
- technologyIds: string[];
19
- }>();
20
-
21
- let totalProcessed = 0;
22
-
23
- // Step 1: Collect all products from all technology subcollections
24
- for (const techDoc of technologiesSnapshot.docs) {
25
- const technologyId = techDoc.id;
26
- console.log(`📦 Processing technology: ${technologyId}`);
27
-
28
- const productsSnapshot = await db
29
- .collection('technologies')
30
- .doc(technologyId)
31
- .collection('products')
32
- .get();
33
-
34
- for (const productDoc of productsSnapshot.docs) {
35
- const productId = productDoc.id;
36
- const productData = productDoc.data();
37
-
38
- totalProcessed++;
39
-
40
- // Deduplicate by name + brandId
41
- const key = `${productData.name}_${productData.brandId}`;
42
-
43
- if (productMap.has(key)) {
44
- // Product already exists, just add this technology
45
- productMap.get(key)!.technologyIds.push(technologyId);
46
- } else {
47
- // New product
48
- productMap.set(key, {
49
- product: productData,
50
- technologyIds: [technologyId],
51
- });
52
- }
53
- }
54
- }
55
-
56
- console.log(`✅ Found ${productMap.size} unique products from ${totalProcessed} total entries`);
57
-
58
- // Step 2: Create products in top-level collection
59
- const batch = db.batch();
60
- let batchCount = 0;
61
- const MAX_BATCH_SIZE = 500;
62
- let createdCount = 0;
63
-
64
- for (const [key, { product, technologyIds }] of productMap.entries()) {
65
- const productRef = db.collection('products').doc();
66
-
67
- const migratedProduct: any = {
68
- ...product,
69
- assignedTechnologyIds: technologyIds, // Track all assigned technologies
70
- migratedAt: admin.firestore.FieldValue.serverTimestamp(),
71
- migrationKey: key, // For debugging
72
- };
73
-
74
- batch.set(productRef, migratedProduct);
75
- createdCount++;
76
- batchCount++;
77
-
78
- if (batchCount >= MAX_BATCH_SIZE) {
79
- await batch.commit();
80
- console.log(`💾 Committed batch of ${batchCount} products (${createdCount}/${productMap.size})`);
81
- batchCount = 0;
82
- }
83
- }
84
-
85
- if (batchCount > 0) {
86
- await batch.commit();
87
- console.log(`💾 Committed final batch of ${batchCount} products`);
88
- }
89
-
90
- console.log('✅ Migration complete!');
91
- console.log(`📊 Summary:`);
92
- console.log(` - Products processed: ${totalProcessed}`);
93
- console.log(` - Unique products created: ${createdCount}`);
94
- console.log(` - Average technologies per product: ${(createdCount > 0 ? totalProcessed / createdCount : 0).toFixed(2)}`);
95
-
96
- return {
97
- totalProcessed,
98
- uniqueCreated: createdCount,
99
- };
100
- }
101
-
102
- /**
103
- * Run migration (for testing)
104
- */
105
- if (require.main === module) {
106
- (async () => {
107
- try {
108
- await migrateProductsToTopLevel(admin.firestore());
109
- process.exit(0);
110
- } catch (error) {
111
- console.error('❌ Migration failed:', error);
112
- process.exit(1);
113
- }
114
- })();
115
- }
116
-