@blackcode_sa/metaestetics-api 1.13.5 → 1.13.6
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 +20 -1
- package/dist/admin/index.d.ts +20 -1
- package/dist/admin/index.js +217 -1
- package/dist/admin/index.mjs +217 -1
- package/package.json +121 -121
- package/src/__mocks__/firstore.ts +10 -10
- package/src/admin/aggregation/README.md +79 -79
- package/src/admin/aggregation/appointment/README.md +128 -128
- package/src/admin/aggregation/appointment/appointment.aggregation.service.ts +1984 -1984
- package/src/admin/aggregation/appointment/index.ts +1 -1
- package/src/admin/aggregation/clinic/README.md +52 -52
- package/src/admin/aggregation/clinic/clinic.aggregation.service.ts +966 -703
- package/src/admin/aggregation/clinic/index.ts +1 -1
- package/src/admin/aggregation/forms/README.md +13 -13
- package/src/admin/aggregation/forms/filled-forms.aggregation.service.ts +322 -322
- package/src/admin/aggregation/forms/index.ts +1 -1
- package/src/admin/aggregation/index.ts +8 -8
- package/src/admin/aggregation/patient/README.md +27 -27
- package/src/admin/aggregation/patient/index.ts +1 -1
- package/src/admin/aggregation/patient/patient.aggregation.service.ts +141 -141
- package/src/admin/aggregation/practitioner/README.md +42 -42
- package/src/admin/aggregation/practitioner/index.ts +1 -1
- package/src/admin/aggregation/practitioner/practitioner.aggregation.service.ts +433 -433
- package/src/admin/aggregation/practitioner-invite/index.ts +1 -1
- package/src/admin/aggregation/practitioner-invite/practitioner-invite.aggregation.service.ts +961 -961
- package/src/admin/aggregation/procedure/README.md +43 -43
- package/src/admin/aggregation/procedure/index.ts +1 -1
- package/src/admin/aggregation/procedure/procedure.aggregation.service.ts +702 -702
- package/src/admin/aggregation/reviews/index.ts +1 -1
- package/src/admin/aggregation/reviews/reviews.aggregation.service.ts +689 -689
- package/src/admin/analytics/analytics.admin.service.ts +278 -278
- package/src/admin/analytics/index.ts +2 -2
- package/src/admin/booking/README.md +125 -125
- package/src/admin/booking/booking.admin.ts +1037 -1037
- package/src/admin/booking/booking.calculator.ts +712 -712
- package/src/admin/booking/booking.types.ts +59 -59
- package/src/admin/booking/index.ts +3 -3
- package/src/admin/booking/timezones-problem.md +185 -185
- package/src/admin/calendar/README.md +7 -7
- package/src/admin/calendar/calendar.admin.service.ts +345 -345
- package/src/admin/calendar/index.ts +1 -1
- package/src/admin/documentation-templates/document-manager.admin.ts +260 -260
- package/src/admin/documentation-templates/index.ts +1 -1
- package/src/admin/free-consultation/free-consultation-utils.admin.ts +148 -148
- package/src/admin/free-consultation/index.ts +1 -1
- package/src/admin/index.ts +81 -81
- package/src/admin/logger/index.ts +78 -78
- package/src/admin/mailing/README.md +95 -95
- package/src/admin/mailing/appointment/appointment.mailing.service.ts +732 -732
- package/src/admin/mailing/appointment/index.ts +1 -1
- package/src/admin/mailing/appointment/templates/patient/appointment-confirmed.html +40 -40
- package/src/admin/mailing/base.mailing.service.ts +208 -208
- package/src/admin/mailing/index.ts +3 -3
- package/src/admin/mailing/practitionerInvite/existing-practitioner-invite.mailing.ts +611 -611
- package/src/admin/mailing/practitionerInvite/index.ts +2 -2
- package/src/admin/mailing/practitionerInvite/practitionerInvite.mailing.ts +395 -395
- package/src/admin/mailing/practitionerInvite/templates/existing-practitioner-invitation.template.ts +155 -155
- package/src/admin/mailing/practitionerInvite/templates/invitation.template.ts +101 -101
- package/src/admin/mailing/practitionerInvite/templates/invite-accepted-notification.template.ts +228 -228
- package/src/admin/mailing/practitionerInvite/templates/invite-rejected-notification.template.ts +242 -242
- package/src/admin/notifications/index.ts +1 -1
- package/src/admin/notifications/notifications.admin.ts +710 -710
- package/src/admin/requirements/README.md +128 -128
- package/src/admin/requirements/index.ts +1 -1
- package/src/admin/requirements/patient-requirements.admin.service.ts +475 -475
- package/src/admin/users/index.ts +1 -1
- package/src/admin/users/user-profile.admin.ts +405 -405
- package/src/backoffice/constants/certification.constants.ts +13 -13
- package/src/backoffice/constants/index.ts +1 -1
- package/src/backoffice/errors/backoffice.errors.ts +181 -181
- package/src/backoffice/errors/index.ts +1 -1
- package/src/backoffice/expo-safe/README.md +26 -26
- package/src/backoffice/expo-safe/index.ts +41 -41
- package/src/backoffice/index.ts +5 -5
- package/src/backoffice/services/FIXES_README.md +102 -102
- package/src/backoffice/services/README.md +57 -57
- package/src/backoffice/services/analytics.service.proposal.md +863 -863
- package/src/backoffice/services/analytics.service.summary.md +143 -143
- package/src/backoffice/services/brand.service.ts +256 -256
- package/src/backoffice/services/category.service.ts +384 -384
- package/src/backoffice/services/constants.service.ts +385 -385
- package/src/backoffice/services/documentation-template.service.ts +202 -202
- package/src/backoffice/services/index.ts +10 -10
- package/src/backoffice/services/migrate-products.ts +116 -116
- package/src/backoffice/services/product.service.ts +553 -553
- package/src/backoffice/services/requirement.service.ts +235 -235
- package/src/backoffice/services/subcategory.service.ts +461 -461
- package/src/backoffice/services/technology.service.ts +1151 -1151
- package/src/backoffice/types/README.md +12 -12
- package/src/backoffice/types/admin-constants.types.ts +69 -69
- package/src/backoffice/types/brand.types.ts +29 -29
- package/src/backoffice/types/category.types.ts +67 -67
- package/src/backoffice/types/documentation-templates.types.ts +28 -28
- package/src/backoffice/types/index.ts +10 -10
- package/src/backoffice/types/procedure-product.types.ts +38 -38
- package/src/backoffice/types/product.types.ts +240 -240
- package/src/backoffice/types/requirement.types.ts +63 -63
- package/src/backoffice/types/static/README.md +18 -18
- package/src/backoffice/types/static/blocking-condition.types.ts +21 -21
- package/src/backoffice/types/static/certification.types.ts +37 -37
- package/src/backoffice/types/static/contraindication.types.ts +19 -19
- package/src/backoffice/types/static/index.ts +6 -6
- package/src/backoffice/types/static/pricing.types.ts +16 -16
- package/src/backoffice/types/static/procedure-family.types.ts +14 -14
- package/src/backoffice/types/static/treatment-benefit.types.ts +22 -22
- package/src/backoffice/types/subcategory.types.ts +34 -34
- package/src/backoffice/types/technology.types.ts +168 -168
- package/src/backoffice/validations/index.ts +1 -1
- package/src/backoffice/validations/schemas.ts +164 -164
- package/src/config/__mocks__/firebase.ts +99 -99
- package/src/config/firebase.ts +78 -78
- package/src/config/index.ts +9 -9
- package/src/errors/auth.error.ts +6 -6
- package/src/errors/auth.errors.ts +200 -200
- package/src/errors/clinic.errors.ts +32 -32
- package/src/errors/firebase.errors.ts +47 -47
- package/src/errors/user.errors.ts +99 -99
- package/src/index.backup.ts +407 -407
- package/src/index.ts +6 -6
- package/src/locales/en.ts +31 -31
- package/src/recommender/admin/index.ts +1 -1
- package/src/recommender/admin/services/recommender.service.admin.ts +5 -5
- package/src/recommender/front/index.ts +1 -1
- package/src/recommender/front/services/onboarding.service.ts +5 -5
- package/src/recommender/front/services/recommender.service.ts +3 -3
- package/src/recommender/index.ts +1 -1
- package/src/services/PATIENTAUTH.MD +197 -197
- package/src/services/README.md +106 -106
- package/src/services/__tests__/auth/auth.mock.test.ts +17 -17
- package/src/services/__tests__/auth/auth.setup.ts +293 -293
- package/src/services/__tests__/auth.service.test.ts +346 -346
- package/src/services/__tests__/base.service.test.ts +77 -77
- package/src/services/__tests__/user.service.test.ts +528 -528
- package/src/services/analytics/ARCHITECTURE.md +199 -199
- package/src/services/analytics/CLOUD_FUNCTIONS.md +225 -225
- package/src/services/analytics/GROUPED_ANALYTICS.md +501 -501
- package/src/services/analytics/QUICK_START.md +393 -393
- package/src/services/analytics/README.md +304 -304
- package/src/services/analytics/SUMMARY.md +141 -141
- package/src/services/analytics/TRENDS.md +380 -380
- package/src/services/analytics/USAGE_GUIDE.md +518 -518
- package/src/services/analytics/analytics-cloud.service.ts +222 -222
- package/src/services/analytics/analytics.service.ts +2142 -2142
- package/src/services/analytics/index.ts +4 -4
- package/src/services/analytics/review-analytics.service.ts +941 -941
- package/src/services/analytics/utils/appointment-filtering.utils.ts +138 -138
- package/src/services/analytics/utils/cost-calculation.utils.ts +182 -182
- package/src/services/analytics/utils/grouping.utils.ts +434 -434
- package/src/services/analytics/utils/stored-analytics.utils.ts +347 -347
- package/src/services/analytics/utils/time-calculation.utils.ts +186 -186
- package/src/services/analytics/utils/trend-calculation.utils.ts +200 -200
- package/src/services/appointment/README.md +17 -17
- package/src/services/appointment/appointment.service.ts +2558 -2558
- package/src/services/appointment/index.ts +1 -1
- package/src/services/appointment/utils/appointment.utils.ts +552 -552
- package/src/services/appointment/utils/extended-procedure.utils.ts +314 -314
- package/src/services/appointment/utils/form-initialization.utils.ts +225 -225
- package/src/services/appointment/utils/recommended-procedure.utils.ts +195 -195
- package/src/services/appointment/utils/zone-management.utils.ts +353 -353
- package/src/services/appointment/utils/zone-photo.utils.ts +152 -152
- package/src/services/auth/auth.service.ts +989 -989
- package/src/services/auth/auth.v2.service.ts +961 -961
- package/src/services/auth/index.ts +7 -7
- package/src/services/auth/utils/error.utils.ts +90 -90
- package/src/services/auth/utils/firebase.utils.ts +49 -49
- package/src/services/auth/utils/index.ts +21 -21
- package/src/services/auth/utils/practitioner.utils.ts +125 -125
- package/src/services/base.service.ts +41 -41
- package/src/services/calendar/calendar.service.ts +1077 -1077
- package/src/services/calendar/calendar.v2.service.ts +1683 -1683
- package/src/services/calendar/calendar.v3.service.ts +313 -313
- package/src/services/calendar/externalCalendar.service.ts +178 -178
- package/src/services/calendar/index.ts +5 -5
- package/src/services/calendar/synced-calendars.service.ts +743 -743
- package/src/services/calendar/utils/appointment.utils.ts +265 -265
- package/src/services/calendar/utils/calendar-event.utils.ts +646 -646
- package/src/services/calendar/utils/clinic.utils.ts +237 -237
- package/src/services/calendar/utils/docs.utils.ts +157 -157
- package/src/services/calendar/utils/google-calendar.utils.ts +697 -697
- package/src/services/calendar/utils/index.ts +8 -8
- package/src/services/calendar/utils/patient.utils.ts +198 -198
- package/src/services/calendar/utils/practitioner.utils.ts +221 -221
- package/src/services/calendar/utils/synced-calendar.utils.ts +472 -472
- package/src/services/clinic/README.md +204 -204
- package/src/services/clinic/__tests__/clinic-admin.service.test.ts +287 -287
- package/src/services/clinic/__tests__/clinic-group.service.test.ts +352 -352
- package/src/services/clinic/__tests__/clinic.service.test.ts +354 -354
- package/src/services/clinic/billing-transactions.service.ts +217 -217
- package/src/services/clinic/clinic-admin.service.ts +202 -202
- package/src/services/clinic/clinic-group.service.ts +310 -310
- package/src/services/clinic/clinic.service.ts +708 -708
- package/src/services/clinic/index.ts +5 -5
- package/src/services/clinic/practitioner-invite.service.ts +519 -519
- package/src/services/clinic/utils/admin.utils.ts +551 -551
- package/src/services/clinic/utils/clinic-group.utils.ts +646 -646
- package/src/services/clinic/utils/clinic.utils.ts +949 -949
- package/src/services/clinic/utils/filter.utils.d.ts +23 -23
- package/src/services/clinic/utils/filter.utils.ts +446 -446
- package/src/services/clinic/utils/index.ts +11 -11
- package/src/services/clinic/utils/photos.utils.ts +188 -188
- package/src/services/clinic/utils/search.utils.ts +84 -84
- package/src/services/clinic/utils/tag.utils.ts +124 -124
- package/src/services/documentation-templates/documentation-template.service.ts +537 -537
- package/src/services/documentation-templates/filled-document.service.ts +587 -587
- package/src/services/documentation-templates/index.ts +2 -2
- package/src/services/index.ts +14 -14
- package/src/services/media/index.ts +1 -1
- package/src/services/media/media.service.ts +418 -418
- package/src/services/notifications/__tests__/notification.service.test.ts +242 -242
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/notification.service.ts +215 -215
- package/src/services/patient/README.md +48 -48
- package/src/services/patient/To-Do.md +43 -43
- package/src/services/patient/__tests__/patient.service.test.ts +294 -294
- package/src/services/patient/index.ts +2 -2
- package/src/services/patient/patient.service.ts +883 -883
- package/src/services/patient/patientRequirements.service.ts +285 -285
- package/src/services/patient/utils/aesthetic-analysis.utils.ts +176 -176
- package/src/services/patient/utils/clinic.utils.ts +80 -80
- package/src/services/patient/utils/docs.utils.ts +142 -142
- package/src/services/patient/utils/index.ts +9 -9
- package/src/services/patient/utils/location.utils.ts +126 -126
- package/src/services/patient/utils/medical-stuff.utils.ts +143 -143
- package/src/services/patient/utils/medical.utils.ts +458 -458
- package/src/services/patient/utils/practitioner.utils.ts +260 -260
- package/src/services/patient/utils/profile.utils.ts +510 -510
- package/src/services/patient/utils/sensitive.utils.ts +260 -260
- package/src/services/patient/utils/token.utils.ts +211 -211
- package/src/services/practitioner/README.md +145 -145
- package/src/services/practitioner/index.ts +1 -1
- package/src/services/practitioner/practitioner.service.ts +1742 -1742
- package/src/services/procedure/README.md +163 -163
- package/src/services/procedure/index.ts +1 -1
- package/src/services/procedure/procedure.service.ts +2200 -2200
- package/src/services/reviews/index.ts +1 -1
- package/src/services/reviews/reviews.service.ts +734 -734
- package/src/services/user/index.ts +1 -1
- package/src/services/user/user.service.ts +489 -489
- package/src/services/user/user.v2.service.ts +466 -466
- package/src/types/analytics/analytics.types.ts +597 -597
- package/src/types/analytics/grouped-analytics.types.ts +173 -173
- package/src/types/analytics/index.ts +4 -4
- package/src/types/analytics/stored-analytics.types.ts +137 -137
- package/src/types/appointment/index.ts +480 -480
- package/src/types/calendar/index.ts +258 -258
- package/src/types/calendar/synced-calendar.types.ts +66 -66
- package/src/types/clinic/index.ts +498 -498
- package/src/types/clinic/practitioner-invite.types.ts +91 -91
- package/src/types/clinic/preferences.types.ts +159 -159
- package/src/types/clinic/to-do +3 -3
- package/src/types/documentation-templates/index.ts +308 -308
- package/src/types/index.ts +47 -47
- package/src/types/notifications/README.md +77 -77
- package/src/types/notifications/index.ts +286 -286
- package/src/types/patient/aesthetic-analysis.types.ts +66 -66
- package/src/types/patient/allergies.ts +58 -58
- package/src/types/patient/index.ts +275 -275
- package/src/types/patient/medical-info.types.ts +152 -152
- package/src/types/patient/patient-requirements.ts +92 -92
- package/src/types/patient/token.types.ts +61 -61
- package/src/types/practitioner/index.ts +206 -206
- package/src/types/procedure/index.ts +181 -181
- package/src/types/profile/index.ts +39 -39
- package/src/types/reviews/index.ts +132 -132
- package/src/types/tz-lookup.d.ts +4 -4
- package/src/types/user/index.ts +38 -38
- package/src/utils/TIMESTAMPS.md +176 -176
- package/src/utils/TimestampUtils.ts +241 -241
- package/src/utils/index.ts +1 -1
- package/src/validations/appointment.schema.ts +574 -574
- package/src/validations/calendar.schema.ts +225 -225
- package/src/validations/clinic.schema.ts +494 -494
- package/src/validations/common.schema.ts +25 -25
- package/src/validations/documentation-templates/index.ts +1 -1
- package/src/validations/documentation-templates/template.schema.ts +220 -220
- package/src/validations/documentation-templates.schema.ts +10 -10
- package/src/validations/index.ts +20 -20
- package/src/validations/media.schema.ts +10 -10
- package/src/validations/notification.schema.ts +90 -90
- package/src/validations/patient/aesthetic-analysis.schema.ts +55 -55
- package/src/validations/patient/medical-info.schema.ts +125 -125
- package/src/validations/patient/patient-requirements.schema.ts +84 -84
- package/src/validations/patient/token.schema.ts +29 -29
- package/src/validations/patient.schema.ts +217 -217
- package/src/validations/practitioner.schema.ts +222 -222
- package/src/validations/procedure-product.schema.ts +41 -41
- package/src/validations/procedure.schema.ts +124 -124
- package/src/validations/profile-info.schema.ts +41 -41
- package/src/validations/reviews.schema.ts +195 -195
- package/src/validations/schemas.ts +104 -104
- package/src/validations/shared.schema.ts +78 -78
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
import {
|
|
2
|
-
collection,
|
|
3
|
-
getDocs,
|
|
4
|
-
query,
|
|
5
|
-
orderBy,
|
|
6
|
-
limit,
|
|
7
|
-
startAfter,
|
|
8
|
-
where,
|
|
9
|
-
DocumentSnapshot,
|
|
10
|
-
QueryConstraint,
|
|
11
|
-
} from 'firebase/firestore';
|
|
12
|
-
import { BaseService } from '../base.service';
|
|
13
|
-
import {
|
|
14
|
-
BillingTransaction,
|
|
15
|
-
BillingTransactionType,
|
|
16
|
-
CLINIC_GROUPS_COLLECTION,
|
|
17
|
-
} from '../../types/clinic';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Service for managing billing transactions
|
|
21
|
-
* Provides read-only access to billing transaction history
|
|
22
|
-
*/
|
|
23
|
-
export class BillingTransactionsService extends BaseService {
|
|
24
|
-
private readonly BILLING_TRANSACTIONS_COLLECTION = 'billingTransactions';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Get billing transactions for a clinic group with pagination
|
|
28
|
-
* @param clinicGroupId - The clinic group ID
|
|
29
|
-
* @param options - Query options
|
|
30
|
-
* @returns Promise with transactions and pagination info
|
|
31
|
-
*/
|
|
32
|
-
async getBillingTransactions(
|
|
33
|
-
clinicGroupId: string,
|
|
34
|
-
options: {
|
|
35
|
-
limit?: number;
|
|
36
|
-
startAfter?: DocumentSnapshot;
|
|
37
|
-
transactionType?: BillingTransactionType;
|
|
38
|
-
} = {},
|
|
39
|
-
): Promise<{
|
|
40
|
-
transactions: BillingTransaction[];
|
|
41
|
-
lastDoc: DocumentSnapshot | null;
|
|
42
|
-
hasMore: boolean;
|
|
43
|
-
}> {
|
|
44
|
-
try {
|
|
45
|
-
const { limit: queryLimit = 50, startAfter: startAfterDoc, transactionType } = options;
|
|
46
|
-
|
|
47
|
-
// Build query constraints
|
|
48
|
-
const constraints: QueryConstraint[] = [];
|
|
49
|
-
|
|
50
|
-
// Add transaction type filter if specified
|
|
51
|
-
if (transactionType) {
|
|
52
|
-
constraints.push(where('type', '==', transactionType));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Add ordering
|
|
56
|
-
constraints.push(orderBy('timestamp', 'desc')); // Most recent first
|
|
57
|
-
|
|
58
|
-
// Add pagination
|
|
59
|
-
if (startAfterDoc) {
|
|
60
|
-
constraints.push(startAfter(startAfterDoc));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
constraints.push(limit(queryLimit + 1)); // Get one extra to check if there are more
|
|
64
|
-
|
|
65
|
-
// Execute query
|
|
66
|
-
const transactionsRef = collection(
|
|
67
|
-
this.db,
|
|
68
|
-
CLINIC_GROUPS_COLLECTION,
|
|
69
|
-
clinicGroupId,
|
|
70
|
-
this.BILLING_TRANSACTIONS_COLLECTION,
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const q = query(transactionsRef, ...constraints);
|
|
74
|
-
const querySnapshot = await getDocs(q);
|
|
75
|
-
|
|
76
|
-
// Process results
|
|
77
|
-
const docs = querySnapshot.docs;
|
|
78
|
-
const hasMore = docs.length > queryLimit;
|
|
79
|
-
const transactions = docs.slice(0, queryLimit).map(doc => ({
|
|
80
|
-
id: doc.id,
|
|
81
|
-
...doc.data(),
|
|
82
|
-
})) as BillingTransaction[];
|
|
83
|
-
|
|
84
|
-
const lastDoc = transactions.length > 0 ? docs[transactions.length - 1] : null;
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
transactions,
|
|
88
|
-
lastDoc,
|
|
89
|
-
hasMore,
|
|
90
|
-
};
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error(
|
|
93
|
-
`Error fetching billing transactions for clinic group ${clinicGroupId}:`,
|
|
94
|
-
error,
|
|
95
|
-
);
|
|
96
|
-
throw new Error(
|
|
97
|
-
`Failed to fetch billing transactions: ${
|
|
98
|
-
error instanceof Error ? error.message : 'Unknown error'
|
|
99
|
-
}`,
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Get recent billing transactions (last 10)
|
|
106
|
-
* @param clinicGroupId - The clinic group ID
|
|
107
|
-
* @returns Promise with recent transactions
|
|
108
|
-
*/
|
|
109
|
-
async getRecentBillingTransactions(clinicGroupId: string): Promise<BillingTransaction[]> {
|
|
110
|
-
const result = await this.getBillingTransactions(clinicGroupId, { limit: 10 });
|
|
111
|
-
return result.transactions;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Get billing transactions by type
|
|
116
|
-
* @param clinicGroupId - The clinic group ID
|
|
117
|
-
* @param transactionType - The transaction type to filter by
|
|
118
|
-
* @param options - Additional query options
|
|
119
|
-
* @returns Promise with filtered transactions
|
|
120
|
-
*/
|
|
121
|
-
async getBillingTransactionsByType(
|
|
122
|
-
clinicGroupId: string,
|
|
123
|
-
transactionType: BillingTransactionType,
|
|
124
|
-
options: {
|
|
125
|
-
limit?: number;
|
|
126
|
-
startAfter?: DocumentSnapshot;
|
|
127
|
-
} = {},
|
|
128
|
-
): Promise<{
|
|
129
|
-
transactions: BillingTransaction[];
|
|
130
|
-
lastDoc: DocumentSnapshot | null;
|
|
131
|
-
hasMore: boolean;
|
|
132
|
-
}> {
|
|
133
|
-
return this.getBillingTransactions(clinicGroupId, {
|
|
134
|
-
...options,
|
|
135
|
-
transactionType,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Get subscription-related transactions only
|
|
141
|
-
* @param clinicGroupId - The clinic group ID
|
|
142
|
-
* @param options - Query options
|
|
143
|
-
* @returns Promise with subscription transactions
|
|
144
|
-
*/
|
|
145
|
-
async getSubscriptionTransactions(
|
|
146
|
-
clinicGroupId: string,
|
|
147
|
-
options: {
|
|
148
|
-
limit?: number;
|
|
149
|
-
startAfter?: DocumentSnapshot;
|
|
150
|
-
} = {},
|
|
151
|
-
): Promise<{
|
|
152
|
-
transactions: BillingTransaction[];
|
|
153
|
-
lastDoc: DocumentSnapshot | null;
|
|
154
|
-
hasMore: boolean;
|
|
155
|
-
}> {
|
|
156
|
-
try {
|
|
157
|
-
const { limit: queryLimit = 50, startAfter: startAfterDoc } = options;
|
|
158
|
-
|
|
159
|
-
// Subscription-related transaction types
|
|
160
|
-
const subscriptionTypes = [
|
|
161
|
-
BillingTransactionType.SUBSCRIPTION_CREATED,
|
|
162
|
-
BillingTransactionType.SUBSCRIPTION_ACTIVATED,
|
|
163
|
-
BillingTransactionType.SUBSCRIPTION_RENEWED,
|
|
164
|
-
BillingTransactionType.SUBSCRIPTION_UPDATED,
|
|
165
|
-
BillingTransactionType.SUBSCRIPTION_CANCELED,
|
|
166
|
-
BillingTransactionType.SUBSCRIPTION_REACTIVATED,
|
|
167
|
-
BillingTransactionType.SUBSCRIPTION_DELETED,
|
|
168
|
-
];
|
|
169
|
-
|
|
170
|
-
const constraints: QueryConstraint[] = [
|
|
171
|
-
where('type', 'in', subscriptionTypes),
|
|
172
|
-
orderBy('timestamp', 'desc'),
|
|
173
|
-
];
|
|
174
|
-
|
|
175
|
-
if (startAfterDoc) {
|
|
176
|
-
constraints.push(startAfter(startAfterDoc));
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
constraints.push(limit(queryLimit + 1));
|
|
180
|
-
|
|
181
|
-
const transactionsRef = collection(
|
|
182
|
-
this.db,
|
|
183
|
-
CLINIC_GROUPS_COLLECTION,
|
|
184
|
-
clinicGroupId,
|
|
185
|
-
this.BILLING_TRANSACTIONS_COLLECTION,
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
const q = query(transactionsRef, ...constraints);
|
|
189
|
-
const querySnapshot = await getDocs(q);
|
|
190
|
-
|
|
191
|
-
const docs = querySnapshot.docs;
|
|
192
|
-
const hasMore = docs.length > queryLimit;
|
|
193
|
-
const transactions = docs.slice(0, queryLimit).map(doc => ({
|
|
194
|
-
id: doc.id,
|
|
195
|
-
...doc.data(),
|
|
196
|
-
})) as BillingTransaction[];
|
|
197
|
-
|
|
198
|
-
const lastDoc = transactions.length > 0 ? docs[transactions.length - 1] : null;
|
|
199
|
-
|
|
200
|
-
return {
|
|
201
|
-
transactions,
|
|
202
|
-
lastDoc,
|
|
203
|
-
hasMore,
|
|
204
|
-
};
|
|
205
|
-
} catch (error) {
|
|
206
|
-
console.error(
|
|
207
|
-
`Error fetching subscription transactions for clinic group ${clinicGroupId}:`,
|
|
208
|
-
error,
|
|
209
|
-
);
|
|
210
|
-
throw new Error(
|
|
211
|
-
`Failed to fetch subscription transactions: ${
|
|
212
|
-
error instanceof Error ? error.message : 'Unknown error'
|
|
213
|
-
}`,
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
collection,
|
|
3
|
+
getDocs,
|
|
4
|
+
query,
|
|
5
|
+
orderBy,
|
|
6
|
+
limit,
|
|
7
|
+
startAfter,
|
|
8
|
+
where,
|
|
9
|
+
DocumentSnapshot,
|
|
10
|
+
QueryConstraint,
|
|
11
|
+
} from 'firebase/firestore';
|
|
12
|
+
import { BaseService } from '../base.service';
|
|
13
|
+
import {
|
|
14
|
+
BillingTransaction,
|
|
15
|
+
BillingTransactionType,
|
|
16
|
+
CLINIC_GROUPS_COLLECTION,
|
|
17
|
+
} from '../../types/clinic';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Service for managing billing transactions
|
|
21
|
+
* Provides read-only access to billing transaction history
|
|
22
|
+
*/
|
|
23
|
+
export class BillingTransactionsService extends BaseService {
|
|
24
|
+
private readonly BILLING_TRANSACTIONS_COLLECTION = 'billingTransactions';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get billing transactions for a clinic group with pagination
|
|
28
|
+
* @param clinicGroupId - The clinic group ID
|
|
29
|
+
* @param options - Query options
|
|
30
|
+
* @returns Promise with transactions and pagination info
|
|
31
|
+
*/
|
|
32
|
+
async getBillingTransactions(
|
|
33
|
+
clinicGroupId: string,
|
|
34
|
+
options: {
|
|
35
|
+
limit?: number;
|
|
36
|
+
startAfter?: DocumentSnapshot;
|
|
37
|
+
transactionType?: BillingTransactionType;
|
|
38
|
+
} = {},
|
|
39
|
+
): Promise<{
|
|
40
|
+
transactions: BillingTransaction[];
|
|
41
|
+
lastDoc: DocumentSnapshot | null;
|
|
42
|
+
hasMore: boolean;
|
|
43
|
+
}> {
|
|
44
|
+
try {
|
|
45
|
+
const { limit: queryLimit = 50, startAfter: startAfterDoc, transactionType } = options;
|
|
46
|
+
|
|
47
|
+
// Build query constraints
|
|
48
|
+
const constraints: QueryConstraint[] = [];
|
|
49
|
+
|
|
50
|
+
// Add transaction type filter if specified
|
|
51
|
+
if (transactionType) {
|
|
52
|
+
constraints.push(where('type', '==', transactionType));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Add ordering
|
|
56
|
+
constraints.push(orderBy('timestamp', 'desc')); // Most recent first
|
|
57
|
+
|
|
58
|
+
// Add pagination
|
|
59
|
+
if (startAfterDoc) {
|
|
60
|
+
constraints.push(startAfter(startAfterDoc));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
constraints.push(limit(queryLimit + 1)); // Get one extra to check if there are more
|
|
64
|
+
|
|
65
|
+
// Execute query
|
|
66
|
+
const transactionsRef = collection(
|
|
67
|
+
this.db,
|
|
68
|
+
CLINIC_GROUPS_COLLECTION,
|
|
69
|
+
clinicGroupId,
|
|
70
|
+
this.BILLING_TRANSACTIONS_COLLECTION,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const q = query(transactionsRef, ...constraints);
|
|
74
|
+
const querySnapshot = await getDocs(q);
|
|
75
|
+
|
|
76
|
+
// Process results
|
|
77
|
+
const docs = querySnapshot.docs;
|
|
78
|
+
const hasMore = docs.length > queryLimit;
|
|
79
|
+
const transactions = docs.slice(0, queryLimit).map(doc => ({
|
|
80
|
+
id: doc.id,
|
|
81
|
+
...doc.data(),
|
|
82
|
+
})) as BillingTransaction[];
|
|
83
|
+
|
|
84
|
+
const lastDoc = transactions.length > 0 ? docs[transactions.length - 1] : null;
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
transactions,
|
|
88
|
+
lastDoc,
|
|
89
|
+
hasMore,
|
|
90
|
+
};
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error(
|
|
93
|
+
`Error fetching billing transactions for clinic group ${clinicGroupId}:`,
|
|
94
|
+
error,
|
|
95
|
+
);
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Failed to fetch billing transactions: ${
|
|
98
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
99
|
+
}`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get recent billing transactions (last 10)
|
|
106
|
+
* @param clinicGroupId - The clinic group ID
|
|
107
|
+
* @returns Promise with recent transactions
|
|
108
|
+
*/
|
|
109
|
+
async getRecentBillingTransactions(clinicGroupId: string): Promise<BillingTransaction[]> {
|
|
110
|
+
const result = await this.getBillingTransactions(clinicGroupId, { limit: 10 });
|
|
111
|
+
return result.transactions;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Get billing transactions by type
|
|
116
|
+
* @param clinicGroupId - The clinic group ID
|
|
117
|
+
* @param transactionType - The transaction type to filter by
|
|
118
|
+
* @param options - Additional query options
|
|
119
|
+
* @returns Promise with filtered transactions
|
|
120
|
+
*/
|
|
121
|
+
async getBillingTransactionsByType(
|
|
122
|
+
clinicGroupId: string,
|
|
123
|
+
transactionType: BillingTransactionType,
|
|
124
|
+
options: {
|
|
125
|
+
limit?: number;
|
|
126
|
+
startAfter?: DocumentSnapshot;
|
|
127
|
+
} = {},
|
|
128
|
+
): Promise<{
|
|
129
|
+
transactions: BillingTransaction[];
|
|
130
|
+
lastDoc: DocumentSnapshot | null;
|
|
131
|
+
hasMore: boolean;
|
|
132
|
+
}> {
|
|
133
|
+
return this.getBillingTransactions(clinicGroupId, {
|
|
134
|
+
...options,
|
|
135
|
+
transactionType,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get subscription-related transactions only
|
|
141
|
+
* @param clinicGroupId - The clinic group ID
|
|
142
|
+
* @param options - Query options
|
|
143
|
+
* @returns Promise with subscription transactions
|
|
144
|
+
*/
|
|
145
|
+
async getSubscriptionTransactions(
|
|
146
|
+
clinicGroupId: string,
|
|
147
|
+
options: {
|
|
148
|
+
limit?: number;
|
|
149
|
+
startAfter?: DocumentSnapshot;
|
|
150
|
+
} = {},
|
|
151
|
+
): Promise<{
|
|
152
|
+
transactions: BillingTransaction[];
|
|
153
|
+
lastDoc: DocumentSnapshot | null;
|
|
154
|
+
hasMore: boolean;
|
|
155
|
+
}> {
|
|
156
|
+
try {
|
|
157
|
+
const { limit: queryLimit = 50, startAfter: startAfterDoc } = options;
|
|
158
|
+
|
|
159
|
+
// Subscription-related transaction types
|
|
160
|
+
const subscriptionTypes = [
|
|
161
|
+
BillingTransactionType.SUBSCRIPTION_CREATED,
|
|
162
|
+
BillingTransactionType.SUBSCRIPTION_ACTIVATED,
|
|
163
|
+
BillingTransactionType.SUBSCRIPTION_RENEWED,
|
|
164
|
+
BillingTransactionType.SUBSCRIPTION_UPDATED,
|
|
165
|
+
BillingTransactionType.SUBSCRIPTION_CANCELED,
|
|
166
|
+
BillingTransactionType.SUBSCRIPTION_REACTIVATED,
|
|
167
|
+
BillingTransactionType.SUBSCRIPTION_DELETED,
|
|
168
|
+
];
|
|
169
|
+
|
|
170
|
+
const constraints: QueryConstraint[] = [
|
|
171
|
+
where('type', 'in', subscriptionTypes),
|
|
172
|
+
orderBy('timestamp', 'desc'),
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
if (startAfterDoc) {
|
|
176
|
+
constraints.push(startAfter(startAfterDoc));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
constraints.push(limit(queryLimit + 1));
|
|
180
|
+
|
|
181
|
+
const transactionsRef = collection(
|
|
182
|
+
this.db,
|
|
183
|
+
CLINIC_GROUPS_COLLECTION,
|
|
184
|
+
clinicGroupId,
|
|
185
|
+
this.BILLING_TRANSACTIONS_COLLECTION,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const q = query(transactionsRef, ...constraints);
|
|
189
|
+
const querySnapshot = await getDocs(q);
|
|
190
|
+
|
|
191
|
+
const docs = querySnapshot.docs;
|
|
192
|
+
const hasMore = docs.length > queryLimit;
|
|
193
|
+
const transactions = docs.slice(0, queryLimit).map(doc => ({
|
|
194
|
+
id: doc.id,
|
|
195
|
+
...doc.data(),
|
|
196
|
+
})) as BillingTransaction[];
|
|
197
|
+
|
|
198
|
+
const lastDoc = transactions.length > 0 ? docs[transactions.length - 1] : null;
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
transactions,
|
|
202
|
+
lastDoc,
|
|
203
|
+
hasMore,
|
|
204
|
+
};
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error(
|
|
207
|
+
`Error fetching subscription transactions for clinic group ${clinicGroupId}:`,
|
|
208
|
+
error,
|
|
209
|
+
);
|
|
210
|
+
throw new Error(
|
|
211
|
+
`Failed to fetch subscription transactions: ${
|
|
212
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
213
|
+
}`,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|