sahab-utils 1.3.0 → 1.6.0

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.
@@ -1,661 +1,963 @@
1
- import { DocumentReference, GeoPoint, Timestamp } from 'firebase/firestore';
2
- export type GeoPointType = GeoPoint;
3
- export type TimestampType = Timestamp;
4
- export type DistenceDueration = {
5
- distance: string;
6
- duration: string;
7
- };
8
- export declare enum CarSize {
9
- X_SMALL = 0,
10
- SMALL = 1,
11
- MEDIUM = 2,
12
- LARGE = 3,
13
- X_LARGE = 4
14
- }
15
- export type Car = {
16
- carId: string;
17
- manufacturer: string;
18
- model: string;
19
- size: CarSize;
20
- year: string;
21
- color: string;
22
- plateLetters: string;
23
- plateNumber: string;
24
- imageUrl?: string;
25
- };
26
- export type ClientLocation = {
27
- locationId: string;
28
- name: string;
29
- latitude: number;
30
- longitude: number;
31
- isPrimary?: boolean;
32
- };
33
- export type Client = {
34
- uid: string;
35
- phoneNumber: string;
36
- firstName?: string;
37
- lastName?: string;
38
- email?: string;
39
- balance?: number;
40
- rating?: number;
41
- imageUrl?: string;
42
- isTest?: boolean;
43
- isEmailVerified?: boolean;
44
- language?: string;
45
- checkoutCustomerId?: string;
46
- latitude?: number;
47
- longitude?: number;
48
- joinDate?: Date;
49
- locations?: ClientLocation[];
50
- version?: string;
51
- tapCustomerId?: string;
52
- };
53
- export type Price = {
54
- size: CarSize;
55
- price: number;
56
- };
57
- export declare enum OrderStatus {
58
- PENDING = 0,// 0
59
- CONFIRMED = 1,// 1
60
- REJECTED = 2,// 2
61
- EXPIRED = 3,// 3
62
- IN_PROGRESS = 4,// 4
63
- COMPLETED = 5,// 5
64
- CANCELLED = 6,// 6
65
- RATED = 7,// 7
66
- STARTED = 8
67
- }
68
- export declare enum OrderPaymentType {
69
- APPLE_PAY = 0,
70
- CREDIT = 1,
71
- CASH = 2,
72
- GOOGLE_PAY = 3,
73
- SAMSUNG_PAY = 4,
74
- STC_PAY = 5,
75
- TABBY = 6,
76
- TAMARA = 7
77
- }
78
- export type Location = {
79
- geohash?: string;
80
- northeast: GeoPointType;
81
- southwest: GeoPointType;
82
- };
83
- export type Order = {
84
- orderId?: string;
85
- clientRef?: DocumentReference;
86
- clientId?: string;
87
- client?: Client;
88
- providerRef?: DocumentReference;
89
- providerId?: string;
90
- servedBy?: DocumentReference;
91
- servedByName?: string;
92
- createdDate?: TimestampType;
93
- orderDate?: TimestampType;
94
- services?: CarService[];
95
- location?: GeoPointType;
96
- locationUrl?: string;
97
- willClientBeThere?: boolean;
98
- paymentType?: OrderPaymentType;
99
- clientRating?: number;
100
- providerRating?: number;
101
- orderStatus?: OrderStatus;
102
- staticMap?: any;
103
- isPaid?: boolean;
104
- rejectedBy?: string[];
105
- finishDate?: TimestampType;
106
- arrivalDate?: TimestampType;
107
- canceledDate?: TimestampType;
108
- paymentAmount?: number;
109
- sahabPercentage?: number;
110
- sahabClientPercentage?: number;
111
- sahabOnlinePercentage?: number;
112
- sahabProviderPercentage?: number;
113
- sahabExtraPaymentAmount?: number;
114
- paymentId?: string;
115
- paymentCancelationId?: string;
116
- paymentRefundId?: string;
117
- paymentCaptureId?: string;
118
- canceledBy?: 'provider' | 'client';
119
- movementsCreated?: boolean;
120
- orderNote?: string;
121
- cancelReason?: string;
122
- isDismissed?: boolean;
123
- isLate?: boolean;
124
- promoCode?: Discount;
125
- isTest?: boolean;
126
- clientNumber?: string;
127
- usedBalance?: number;
128
- isDummyOrder?: boolean;
129
- ratingNote?: string;
130
- isAddonStructure?: boolean;
131
- isMonthlyPackage?: boolean;
132
- isPaymentSettled?: boolean;
133
- notificationTaskId?: string;
134
- providerName?: {
135
- ar: string;
136
- en: string;
137
- };
138
- providerPhoneNumber?: string;
139
- providerLogoUrl?: string;
140
- paymentGateway?: 'PAYLINK' | 'CHECKOUT' | 'TAP';
141
- visitDates?: number[];
142
- };
143
- export type ReduxOrder = {
144
- orderId?: string;
145
- clientId?: string;
146
- client?: Client;
147
- servedByPath?: string;
148
- providerId?: string;
149
- servedByName?: string;
150
- createdDate?: TimestampType;
151
- orderDate?: TimestampType;
152
- canceledDate?: TimestampType;
153
- services?: CarService[];
154
- location?: GeoPointType;
155
- locationUrl?: string;
156
- willClientBeThere?: boolean;
157
- paymentType?: OrderPaymentType;
158
- clientRating?: number;
159
- providerRating?: number;
160
- orderStatus?: OrderStatus;
161
- staticMap?: any;
162
- isPaid?: boolean;
163
- rejectedBy?: string[];
164
- finishDate?: TimestampType;
165
- arrivalDate?: TimestampType;
166
- paymentAmount?: number;
167
- sahabPercentage?: number;
168
- sahabClientPercentage?: number;
169
- sahabOnlinePercentage?: number;
170
- sahabProviderPercentage?: number;
171
- sahabExtraPaymentAmount?: number;
172
- paymentId?: string;
173
- paymentCancelationId?: string;
174
- paymentRefundId?: string;
175
- paymentCaptureId?: string;
176
- canceledBy?: 'provider' | 'client';
177
- movementsCreated?: boolean;
178
- orderNote?: string;
179
- cancelReason?: string;
180
- isDismissed?: boolean;
181
- isLate?: boolean;
182
- promoCode?: Discount;
183
- clientNumber?: string;
184
- isTest?: boolean;
185
- usedBalance?: number;
186
- isDummyOrder?: boolean;
187
- ratingNote?: string;
188
- isAddonStructure?: boolean;
189
- isMonthlyPackage?: boolean;
190
- isPaymentSettled?: boolean;
191
- notificationTaskId?: string;
192
- providerName?: {
193
- ar: string;
194
- en: string;
195
- };
196
- providerPhoneNumber?: string;
197
- providerLogoUrl?: string;
198
- };
199
- export type MoneyMovement = {
200
- movementId: string;
201
- amount: number;
202
- orderId?: string;
203
- date: TimestampType;
204
- movementType: MovementType;
205
- createdBy?: string;
206
- };
207
- export declare enum MovementType {
208
- CLIENT_ORDER_PAYMENT = 0,
209
- CLIENT_BALANCE_TOP_UP = 1,
210
- PROVIDER_NEGATIVE_BALANCE_PAYMENT = 2,
211
- PROVIDER_POSITIVE_BALANCE_PAYMENT = 3,
212
- ORDER_REFUND = 4,
213
- SAHAB_PAYMENT_TO_PROVIDER = 5,
214
- SAHAB_RECEIVE_FROM_PROVIDER = 6,
215
- USING_BALANCE = 7
216
- }
217
- export declare enum ComplaintType {
218
- BUG = 0,
219
- COMPLAINT = 1
220
- }
221
- export declare enum ComplaintStatus {
222
- PENDING = 0,
223
- IN_REVIEW = 1,
224
- RESOLVED = 2
225
- }
226
- export type Complaint = {
227
- complaintId: string;
228
- complaintNumber: string;
229
- desc: string;
230
- createdDate: TimestampType;
231
- status: ComplaintStatus;
232
- type: ComplaintType;
233
- resolvedBy?: string;
234
- resolveDate?: string;
235
- };
236
- export type City = {
237
- cityId?: string;
238
- cityName: string;
239
- countryName: string;
240
- cityName_ar: string;
241
- countryName_ar: string;
242
- locationBounds?: Location;
243
- coordinates?: GeoPointType;
244
- g?: {
245
- geohash: string;
246
- geopoint: GeoPointType;
247
- };
248
- providerUid?: string;
249
- };
250
- export type Driver = {
251
- type?: 'driver';
252
- driverId?: string;
253
- providerUid?: string;
254
- firstName?: string;
255
- lastName?: string;
256
- phoneNumber?: string;
257
- imageUrl?: string;
258
- language?: 'en' | 'ar';
259
- mainPushToken?: string;
260
- hmsPushToken?: string;
261
- cities?: City[];
262
- isAllowedToCross?: boolean;
263
- deactivated?: boolean;
264
- };
265
- export type ProviderCar = {
266
- carId?: string;
267
- providerRef?: DocumentReference;
268
- manufacturer?: string;
269
- model?: string;
270
- year?: string;
271
- color?: string;
272
- plateLetters?: string;
273
- plateNumber?: string;
274
- istimarahUrl?: string;
275
- fileType?: string;
276
- };
277
- export type Day = 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday';
278
- export type HH = '00' | '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23';
279
- export type MM = '00' | '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '30' | '31' | '32' | '33' | '34' | '35' | '36' | '37' | '38' | '39' | '40' | '41' | '42' | '43' | '44' | '45' | '46' | '47' | '48' | '49' | '50' | '51' | '52' | '53' | '54' | '55' | '56' | '57' | '58' | '59';
280
- export type Hour = `${HH}:${MM}`;
281
- export type WorkingHour = {
282
- start: Hour;
283
- end: Hour;
284
- };
285
- export type WorkingHours = {
286
- sunday: WorkingHour[];
287
- monday: WorkingHour[];
288
- tuesday: WorkingHour[];
289
- wednesday: WorkingHour[];
290
- thursday: WorkingHour[];
291
- friday: WorkingHour[];
292
- saturday: WorkingHour[];
293
- };
294
- export declare enum ReviewStatus {
295
- PENDING = 0,
296
- IN_REVIEW = 1,
297
- ACCEPTED = 2,
298
- DECLINED = 3
299
- }
300
- export declare enum RegistrationSection {
301
- OWNER_NAME = 0,
302
- CITY = 1,
303
- RULES = 2,
304
- BUSINESS_INFO = 3,
305
- DRIVERS_INFO = 4,
306
- VEHICLE_PERMIT = 5,
307
- VEHICLE_REGISTRATION = 6,
308
- SERVICES = 7,
309
- ADDONS = 8,
310
- WORKING_HOURS = 9,
311
- OVERVIEW = 10,
312
- STATUS = 11,
313
- DONE = 12
314
- }
315
- export type DeclineReason = {
316
- reasonDesc: {
317
- ar: string;
318
- en: string;
319
- };
320
- section: RegistrationSection;
321
- };
322
- export type ProviderService = {
323
- serviceId?: string;
324
- name?: {
325
- ar: string;
326
- en: string;
327
- };
328
- imageUrl?: string;
329
- providerId?: string;
330
- prices?: Price[];
331
- description?: {
332
- ar: string;
333
- en: string;
334
- };
335
- includedServices?: {
336
- ar: string;
337
- en: string;
338
- }[];
339
- hide?: boolean;
340
- time?: number;
341
- numberOfVisits?: number;
342
- };
343
- export type ProvidedService = {
344
- serviceId?: string;
345
- name?: {
346
- ar: string;
347
- en: string;
348
- };
349
- imageUrl?: string;
350
- providerId?: string;
351
- description?: {
352
- ar: string;
353
- en: string;
354
- };
355
- price: Price;
356
- isDone?: boolean;
357
- finishDate?: TimestampType;
358
- quantity?: number;
359
- type: 'service';
360
- time?: number;
361
- includedServices?: {
362
- ar: string;
363
- en: string;
364
- }[];
365
- numberOfVisits?: number;
366
- discount?: Discount;
367
- };
368
- export type ProviderAddon = {
369
- addonId?: string;
370
- providerId?: string;
371
- name?: {
372
- ar: string;
373
- en: string;
374
- };
375
- prices?: Price[];
376
- description?: {
377
- ar: string;
378
- en: string;
379
- };
380
- hide?: boolean;
381
- time?: number;
382
- };
383
- export type ProvidedAddon = {
384
- addonId?: string;
385
- providerId?: string;
386
- name?: {
387
- ar: string;
388
- en: string;
389
- };
390
- price?: Price;
391
- description?: {
392
- ar: string;
393
- en: string;
394
- };
395
- quantity?: number;
396
- type: 'addon';
397
- time?: number;
398
- isDone?: boolean;
399
- finishDate?: TimestampType;
400
- discount?: Discount;
401
- };
402
- export type Provider = {
403
- type?: 'provider';
404
- providerUid?: string;
405
- providerName?: {
406
- ar: string;
407
- en: string;
408
- };
409
- providerPhoneNumber?: string;
410
- providerCarNumber?: string;
411
- numberOfDrivers?: number;
412
- numberOfCars?: number;
413
- totalRating?: number;
414
- numberOfRaters?: number;
415
- logoUrl?: string;
416
- phoneNumber?: string;
417
- ownerFirstName?: string;
418
- ownerLastName?: string;
419
- services?: ProviderService[];
420
- addons?: ProviderAddon[];
421
- working247?: boolean;
422
- workingHoursV2?: WorkingHours;
423
- submitDate?: TimestampType;
424
- reviewStatus?: ReviewStatus;
425
- reviewedBy?: string;
426
- declineReasons?: DeclineReason[];
427
- acceptOrdersAutomatically?: boolean;
428
- freeWashes?: number;
429
- registrationSection?: RegistrationSection;
430
- currency?: string;
431
- mainPushToken?: string;
432
- hmsPushToken?: string;
433
- isTest?: boolean;
434
- language?: 'en' | 'ar';
435
- balance?: number;
436
- permitUrl?: string;
437
- permitType?: string;
438
- checkoutCustomerId?: string;
439
- ownerEmail?: string;
440
- isEmailVerified?: boolean;
441
- receiveOrders?: boolean;
442
- isAcceptingOrders?: boolean;
443
- ordersPercentage?: number;
444
- integrations?: {
445
- email?: string;
446
- isActive?: boolean;
447
- key: string;
448
- /** Tap (and other gateways): server-side API secret */
449
- secretKey?: string;
450
- /** Tap Connect marketplace payout destination id (sub-merchant) */
451
- tapDestinationId?: string;
452
- }[];
453
- };
454
- export type Card = {
455
- id?: string;
456
- issuer?: string;
457
- expiry_month?: string;
458
- expiry_year?: string;
459
- name?: string;
460
- scheme?: string;
461
- bin?: string;
462
- last4?: string;
463
- customer?: {
464
- id?: string;
465
- };
466
- default?: boolean;
467
- customer_id?: string;
468
- };
469
- export type CheckoutCustomer = {
470
- default?: string;
471
- email?: string;
472
- id?: string;
473
- name?: string;
474
- instruments?: Card[];
475
- metadata?: {
476
- iban?: string;
477
- providerUid?: string;
478
- };
479
- };
480
- export type CarService = {
481
- car?: Car;
482
- services: Array<ProvidedService | ProvidedAddon>;
483
- isDone?: boolean;
484
- };
485
- export type Discount = {
486
- promoCodeId?: string;
487
- promoCode?: string;
488
- validFrom?: TimestampType;
489
- validTo?: TimestampType;
490
- createdAt?: TimestampType;
491
- allowedOnce?: boolean;
492
- createdByProvider?: boolean;
493
- providerUid?: string;
494
- usedBy?: string[];
495
- amount?: number;
496
- isPercentage?: boolean;
497
- maxAmount?: number;
498
- isAutoApplied?: boolean;
499
- servicesIds?: string[];
500
- addonsIds?: string[];
501
- clientIds?: string[];
502
- createrEmail?: string;
503
- sahabPercentage?: number;
504
- providerPercentage?: number;
505
- };
506
- export type OrderReview = {
507
- ratingId: string;
508
- ratingNote: string;
509
- orderId: string;
510
- orderDate: TimestampType;
511
- createdDate: TimestampType;
512
- providerId: string;
513
- arrivalDate: string;
514
- finishDate: string;
515
- rating: number;
516
- clientId: string;
517
- };
518
- export type CountryCode = {
519
- code: string;
520
- dial_code: string;
521
- flag: string;
522
- name_en: string;
523
- name_ar: string;
524
- };
525
- export type LocationInfo = {
526
- city?: string;
527
- country?: string;
528
- postalCode?: string;
529
- line1: string;
530
- line2?: string;
531
- long_name?: string;
532
- latitude?: number;
533
- longitude?: number;
534
- };
535
- export type SavedLocation = {
536
- locationId: string;
537
- name: string;
538
- latitude: number;
539
- longitude: number;
540
- isPrimary?: boolean;
541
- };
542
- export type CheckoutCard = {
543
- id?: string;
544
- type?: string;
545
- fingerprint?: string;
546
- expiry_month?: string;
547
- expiry_year?: string;
548
- scheme?: string;
549
- scheme_local?: string;
550
- last4?: string;
551
- bin?: string;
552
- card_type?: string;
553
- card_category?: string;
554
- issuer?: string;
555
- issuer_country?: string;
556
- product_type?: string;
557
- };
558
- export type CheckoutToken = {
559
- type?: string;
560
- token?: string;
561
- expires_on?: string;
562
- expiry_month?: number;
563
- expiry_year?: number;
564
- scheme?: string;
565
- scheme_local?: string;
566
- last4?: string;
567
- bin?: string;
568
- card_type?: string;
569
- card_category?: string;
570
- issuer?: string;
571
- issuer_country?: string;
572
- product_id: string;
573
- product_type: string;
574
- billing_address?: {
575
- address_line1?: string;
576
- address_line2: string;
577
- city?: string;
578
- state?: string;
579
- zip?: string;
580
- country?: string;
581
- };
582
- phone?: {
583
- country_code?: string;
584
- number?: string;
585
- };
586
- name?: string;
587
- };
588
- export type SPECIFIED_TIME = 'anytime' | number;
589
- export type PlaceOrder = {
590
- clientID: string;
591
- providerId: string;
592
- orderMilllSec: number;
593
- orderNanoSec: number;
594
- services: CarService[];
595
- lat: number;
596
- long: number;
597
- willClientBeThere: boolean;
598
- paymentType: OrderPaymentType;
599
- isPaid: boolean;
600
- paymentId: string;
601
- isProviderTest: boolean;
602
- providerReceiveOrders: boolean;
603
- orderNote: string;
604
- promoCode: Discount;
605
- driverIds: string[];
606
- providerName: {
607
- ar: string;
608
- en: string;
609
- };
610
- paymentAmount: number;
611
- usedBalance: number;
612
- providerPhoneNumber: string;
613
- isAddonStructure: boolean;
614
- isMonthlyPackage: boolean;
615
- sahabExtraPaymentAmount: number;
616
- orderId?: string;
617
- paymentGateway?: 'PAYLINK' | 'CHECKOUT' | 'TAP';
618
- /** Mirrors Order economics for server-side Tap split; optional override of client fee % */
619
- sahabClientPercentage?: number;
620
- };
621
- export type WeatherData = {
622
- date: string;
623
- precipitationProbability: number;
624
- rainAccumulation: number;
625
- cloudCover: number;
626
- humidity: number;
627
- windSpeed: number;
628
- uvIndex: number;
629
- };
630
- export type PaymentConfigs = {
631
- isCashAllowed: boolean;
632
- isGooglePayAllowed?: boolean;
633
- /** Tap GoSell merchant id for card / Apple Pay SDK config (optional; falls back in app). */
634
- tapMerchantId?: string;
635
- paymentGateways: {
636
- key: string;
637
- isActive: boolean;
638
- priority: number;
639
- }[];
640
- };
641
- export type Slot = {
642
- id: string;
643
- time: number;
644
- selected: boolean;
645
- reserved: boolean;
646
- };
647
- export type Statement = {
648
- numberOfOrders: number;
649
- completedOrders: number;
650
- ratedOrders: number;
651
- cancelledOrders: number;
652
- cashOrders: number;
653
- creditOrders: number;
654
- applePayPayments: number;
655
- expiredOrders: number;
656
- confirmedOrders: number;
657
- lateOrders: number;
658
- ordersTotal: number;
659
- orders: Order[];
660
- statmentDate?: Date | string;
661
- };
1
+ import { DocumentReference, GeoPoint, Timestamp } from 'firebase/firestore';
2
+ export type GeoPointType = GeoPoint;
3
+ export type TimestampType = Timestamp;
4
+ export type DistenceDueration = {
5
+ distance: string;
6
+ duration: string;
7
+ };
8
+ export declare enum CarSize {
9
+ X_SMALL = 0,
10
+ SMALL = 1,
11
+ MEDIUM = 2,
12
+ LARGE = 3,
13
+ X_LARGE = 4
14
+ }
15
+ export type Car = {
16
+ carId: string;
17
+ manufacturer: string;
18
+ model: string;
19
+ size: CarSize;
20
+ year: string;
21
+ color: string;
22
+ plateLetters: string;
23
+ plateNumber: string;
24
+ imageUrl?: string;
25
+ };
26
+ export type ClientLocation = {
27
+ locationId: string;
28
+ name: string;
29
+ latitude: number;
30
+ longitude: number;
31
+ isPrimary?: boolean;
32
+ };
33
+ export type Client = {
34
+ uid: string;
35
+ phoneNumber: string;
36
+ firstName?: string;
37
+ lastName?: string;
38
+ email?: string;
39
+ balance?: number;
40
+ rating?: number;
41
+ imageUrl?: string;
42
+ isTest?: boolean;
43
+ isEmailVerified?: boolean;
44
+ language?: string;
45
+ checkoutCustomerId?: string;
46
+ latitude?: number;
47
+ longitude?: number;
48
+ joinDate?: Date;
49
+ locations?: ClientLocation[];
50
+ version?: string;
51
+ tapCustomerId?: string;
52
+ };
53
+ export type Price = {
54
+ size: CarSize;
55
+ price: number;
56
+ };
57
+ export declare enum OrderStatus {
58
+ PENDING = 0,// 0
59
+ CONFIRMED = 1,// 1
60
+ REJECTED = 2,// 2
61
+ EXPIRED = 3,// 3
62
+ IN_PROGRESS = 4,// 4
63
+ COMPLETED = 5,// 5
64
+ CANCELLED = 6,// 6
65
+ RATED = 7,// 7
66
+ STARTED = 8
67
+ }
68
+ export declare enum OrderPaymentType {
69
+ APPLE_PAY = 0,
70
+ CREDIT = 1,
71
+ CASH = 2,
72
+ GOOGLE_PAY = 3,
73
+ SAMSUNG_PAY = 4,
74
+ STC_PAY = 5,
75
+ TABBY = 6,
76
+ TAMARA = 7
77
+ }
78
+ export type Location = {
79
+ geohash?: string;
80
+ northeast: GeoPointType;
81
+ southwest: GeoPointType;
82
+ };
83
+ export type Order = {
84
+ orderId?: string;
85
+ clientRef?: DocumentReference;
86
+ clientId?: string;
87
+ client?: Client;
88
+ providerRef?: DocumentReference;
89
+ providerId?: string;
90
+ servedBy?: DocumentReference;
91
+ servedByName?: string;
92
+ createdDate?: TimestampType;
93
+ orderDate?: TimestampType;
94
+ services?: CarService[];
95
+ location?: GeoPointType;
96
+ locationUrl?: string;
97
+ willClientBeThere?: boolean;
98
+ paymentType?: OrderPaymentType;
99
+ clientRating?: number;
100
+ providerRating?: number;
101
+ orderStatus?: OrderStatus;
102
+ staticMap?: any;
103
+ isPaid?: boolean;
104
+ rejectedBy?: string[];
105
+ finishDate?: TimestampType;
106
+ arrivalDate?: TimestampType;
107
+ canceledDate?: TimestampType;
108
+ paymentAmount?: number;
109
+ sahabPercentage?: number;
110
+ sahabClientPercentage?: number;
111
+ sahabOnlinePercentage?: number;
112
+ sahabProviderPercentage?: number;
113
+ sahabExtraPaymentAmount?: number;
114
+ paymentId?: string;
115
+ paymentCancelationId?: string;
116
+ paymentRefundId?: string;
117
+ paymentCaptureId?: string;
118
+ canceledBy?: 'provider' | 'client';
119
+ movementsCreated?: boolean;
120
+ orderNote?: string;
121
+ cancelReason?: string;
122
+ isDismissed?: boolean;
123
+ isLate?: boolean;
124
+ promoCode?: Discount;
125
+ isTest?: boolean;
126
+ clientNumber?: string;
127
+ usedBalance?: number;
128
+ isDummyOrder?: boolean;
129
+ ratingNote?: string;
130
+ isAddonStructure?: boolean;
131
+ isMonthlyPackage?: boolean;
132
+ isPaymentSettled?: boolean;
133
+ notificationTaskId?: string;
134
+ providerName?: {
135
+ ar: string;
136
+ en: string;
137
+ };
138
+ providerPhoneNumber?: string;
139
+ providerLogoUrl?: string;
140
+ paymentGateway?: 'PAYLINK' | 'CHECKOUT' | 'TAP';
141
+ visitDates?: number[];
142
+ /**
143
+ * Cloud Tasks ids, written by the backend so a scheduled job can be cancelled.
144
+ *
145
+ * Already declared in cloudFun's local `Order`; added here because the customer app reads
146
+ * them too, and was doing so against a type that did not admit they exist.
147
+ */
148
+ arrivalExpirationTaskId?: string;
149
+ customerNotificationTaskId?: string;
150
+ /** Set on an order created by re-ordering, pointing at the one it was copied from. */
151
+ originalOrderId?: string;
152
+ };
153
+ export type ReduxOrder = {
154
+ orderId?: string;
155
+ clientId?: string;
156
+ client?: Client;
157
+ servedByPath?: string;
158
+ providerId?: string;
159
+ servedByName?: string;
160
+ createdDate?: TimestampType;
161
+ orderDate?: TimestampType;
162
+ canceledDate?: TimestampType;
163
+ services?: CarService[];
164
+ location?: GeoPointType;
165
+ locationUrl?: string;
166
+ willClientBeThere?: boolean;
167
+ paymentType?: OrderPaymentType;
168
+ clientRating?: number;
169
+ providerRating?: number;
170
+ orderStatus?: OrderStatus;
171
+ staticMap?: any;
172
+ isPaid?: boolean;
173
+ rejectedBy?: string[];
174
+ finishDate?: TimestampType;
175
+ arrivalDate?: TimestampType;
176
+ paymentAmount?: number;
177
+ sahabPercentage?: number;
178
+ sahabClientPercentage?: number;
179
+ sahabOnlinePercentage?: number;
180
+ sahabProviderPercentage?: number;
181
+ sahabExtraPaymentAmount?: number;
182
+ paymentId?: string;
183
+ paymentCancelationId?: string;
184
+ paymentRefundId?: string;
185
+ paymentCaptureId?: string;
186
+ canceledBy?: 'provider' | 'client';
187
+ movementsCreated?: boolean;
188
+ orderNote?: string;
189
+ cancelReason?: string;
190
+ isDismissed?: boolean;
191
+ isLate?: boolean;
192
+ promoCode?: Discount;
193
+ clientNumber?: string;
194
+ isTest?: boolean;
195
+ usedBalance?: number;
196
+ isDummyOrder?: boolean;
197
+ ratingNote?: string;
198
+ isAddonStructure?: boolean;
199
+ isMonthlyPackage?: boolean;
200
+ isPaymentSettled?: boolean;
201
+ notificationTaskId?: string;
202
+ providerName?: {
203
+ ar: string;
204
+ en: string;
205
+ };
206
+ providerPhoneNumber?: string;
207
+ providerLogoUrl?: string;
208
+ };
209
+ export type MoneyMovement = {
210
+ movementId: string;
211
+ amount: number;
212
+ orderId?: string;
213
+ date: TimestampType;
214
+ movementType: MovementType;
215
+ createdBy?: string;
216
+ };
217
+ export declare enum MovementType {
218
+ CLIENT_ORDER_PAYMENT = 0,
219
+ CLIENT_BALANCE_TOP_UP = 1,
220
+ PROVIDER_NEGATIVE_BALANCE_PAYMENT = 2,
221
+ PROVIDER_POSITIVE_BALANCE_PAYMENT = 3,
222
+ ORDER_REFUND = 4,
223
+ SAHAB_PAYMENT_TO_PROVIDER = 5,
224
+ SAHAB_RECEIVE_FROM_PROVIDER = 6,
225
+ USING_BALANCE = 7
226
+ }
227
+ export declare enum ComplaintType {
228
+ BUG = 0,
229
+ COMPLAINT = 1
230
+ }
231
+ export declare enum ComplaintStatus {
232
+ PENDING = 0,
233
+ IN_REVIEW = 1,
234
+ RESOLVED = 2
235
+ }
236
+ export type Complaint = {
237
+ complaintId: string;
238
+ complaintNumber: string;
239
+ desc: string;
240
+ createdDate: TimestampType;
241
+ status: ComplaintStatus;
242
+ type: ComplaintType;
243
+ resolvedBy?: string;
244
+ resolveDate?: string;
245
+ /**
246
+ * Who raised it and against whom.
247
+ *
248
+ * These are written by the customer app and read by the back office, but were missing from
249
+ * this type — so the app cast its way past the mismatch and the dashboard could not see the
250
+ * fields at all. Optional because older complaints predate them.
251
+ */
252
+ complaintClientId?: string;
253
+ complaintClientName?: string;
254
+ complaintProviderId?: string;
255
+ complaintProviderName?: string;
256
+ /**
257
+ * The order the complaint is about, when it is about one.
258
+ *
259
+ * Named "number" but holds the order's document id — the back office looks the order up with
260
+ * it directly. Kept as-is because existing complaints are stored this way.
261
+ */
262
+ orderNumber?: string;
263
+ /** Hidden from the customer's list without deleting the record. */
264
+ isDismissed?: boolean;
265
+ };
266
+ export type City = {
267
+ cityId?: string;
268
+ cityName: string;
269
+ countryName: string;
270
+ cityName_ar: string;
271
+ countryName_ar: string;
272
+ locationBounds?: Location;
273
+ coordinates?: GeoPointType;
274
+ g?: {
275
+ geohash: string;
276
+ geopoint: GeoPointType;
277
+ };
278
+ providerUid?: string;
279
+ };
280
+ export type Driver = {
281
+ type?: 'driver';
282
+ driverId?: string;
283
+ providerUid?: string;
284
+ firstName?: string;
285
+ lastName?: string;
286
+ phoneNumber?: string;
287
+ imageUrl?: string;
288
+ language?: 'en' | 'ar';
289
+ mainPushToken?: string;
290
+ hmsPushToken?: string;
291
+ cities?: City[];
292
+ isAllowedToCross?: boolean;
293
+ deactivated?: boolean;
294
+ };
295
+ export type ProviderCar = {
296
+ carId?: string;
297
+ providerRef?: DocumentReference;
298
+ manufacturer?: string;
299
+ model?: string;
300
+ year?: string;
301
+ color?: string;
302
+ plateLetters?: string;
303
+ plateNumber?: string;
304
+ istimarahUrl?: string;
305
+ fileType?: string;
306
+ };
307
+ export type Day = 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday';
308
+ export type HH = '00' | '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23';
309
+ export type MM = '00' | '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '30' | '31' | '32' | '33' | '34' | '35' | '36' | '37' | '38' | '39' | '40' | '41' | '42' | '43' | '44' | '45' | '46' | '47' | '48' | '49' | '50' | '51' | '52' | '53' | '54' | '55' | '56' | '57' | '58' | '59';
310
+ export type Hour = `${HH}:${MM}`;
311
+ export type WorkingHour = {
312
+ start: Hour;
313
+ end: Hour;
314
+ };
315
+ export type WorkingHours = {
316
+ sunday: WorkingHour[];
317
+ monday: WorkingHour[];
318
+ tuesday: WorkingHour[];
319
+ wednesday: WorkingHour[];
320
+ thursday: WorkingHour[];
321
+ friday: WorkingHour[];
322
+ saturday: WorkingHour[];
323
+ };
324
+ export declare enum ReviewStatus {
325
+ PENDING = 0,
326
+ IN_REVIEW = 1,
327
+ ACCEPTED = 2,
328
+ DECLINED = 3
329
+ }
330
+ export declare enum RegistrationSection {
331
+ OWNER_NAME = 0,
332
+ CITY = 1,
333
+ RULES = 2,
334
+ BUSINESS_INFO = 3,
335
+ DRIVERS_INFO = 4,
336
+ VEHICLE_PERMIT = 5,
337
+ VEHICLE_REGISTRATION = 6,
338
+ SERVICES = 7,
339
+ ADDONS = 8,
340
+ WORKING_HOURS = 9,
341
+ OVERVIEW = 10,
342
+ STATUS = 11,
343
+ DONE = 12
344
+ }
345
+ export type DeclineReason = {
346
+ reasonDesc: {
347
+ ar: string;
348
+ en: string;
349
+ };
350
+ section: RegistrationSection;
351
+ };
352
+ export type ProviderService = {
353
+ serviceId?: string;
354
+ name?: {
355
+ ar: string;
356
+ en: string;
357
+ };
358
+ imageUrl?: string;
359
+ providerId?: string;
360
+ prices?: Price[];
361
+ description?: {
362
+ ar: string;
363
+ en: string;
364
+ };
365
+ includedServices?: {
366
+ ar: string;
367
+ en: string;
368
+ }[];
369
+ hide?: boolean;
370
+ time?: number;
371
+ numberOfVisits?: number;
372
+ };
373
+ export type ProvidedService = {
374
+ serviceId?: string;
375
+ name?: {
376
+ ar: string;
377
+ en: string;
378
+ };
379
+ imageUrl?: string;
380
+ providerId?: string;
381
+ description?: {
382
+ ar: string;
383
+ en: string;
384
+ };
385
+ price: Price;
386
+ isDone?: boolean;
387
+ finishDate?: TimestampType;
388
+ quantity?: number;
389
+ type: 'service';
390
+ time?: number;
391
+ includedServices?: {
392
+ ar: string;
393
+ en: string;
394
+ }[];
395
+ numberOfVisits?: number;
396
+ discount?: Discount;
397
+ };
398
+ export type ProviderAddon = {
399
+ addonId?: string;
400
+ providerId?: string;
401
+ name?: {
402
+ ar: string;
403
+ en: string;
404
+ };
405
+ prices?: Price[];
406
+ description?: {
407
+ ar: string;
408
+ en: string;
409
+ };
410
+ hide?: boolean;
411
+ time?: number;
412
+ };
413
+ export type ProvidedAddon = {
414
+ addonId?: string;
415
+ providerId?: string;
416
+ name?: {
417
+ ar: string;
418
+ en: string;
419
+ };
420
+ price?: Price;
421
+ description?: {
422
+ ar: string;
423
+ en: string;
424
+ };
425
+ quantity?: number;
426
+ type: 'addon';
427
+ time?: number;
428
+ isDone?: boolean;
429
+ finishDate?: TimestampType;
430
+ discount?: Discount;
431
+ };
432
+ export type Provider = {
433
+ type?: 'provider';
434
+ providerUid?: string;
435
+ providerName?: {
436
+ ar: string;
437
+ en: string;
438
+ };
439
+ providerPhoneNumber?: string;
440
+ providerCarNumber?: string;
441
+ numberOfDrivers?: number;
442
+ numberOfCars?: number;
443
+ totalRating?: number;
444
+ numberOfRaters?: number;
445
+ logoUrl?: string;
446
+ phoneNumber?: string;
447
+ ownerFirstName?: string;
448
+ ownerLastName?: string;
449
+ services?: ProviderService[];
450
+ addons?: ProviderAddon[];
451
+ working247?: boolean;
452
+ workingHoursV2?: WorkingHours;
453
+ submitDate?: TimestampType;
454
+ reviewStatus?: ReviewStatus;
455
+ reviewedBy?: string;
456
+ declineReasons?: DeclineReason[];
457
+ acceptOrdersAutomatically?: boolean;
458
+ freeWashes?: number;
459
+ registrationSection?: RegistrationSection;
460
+ currency?: string;
461
+ mainPushToken?: string;
462
+ hmsPushToken?: string;
463
+ isTest?: boolean;
464
+ language?: 'en' | 'ar';
465
+ balance?: number;
466
+ permitUrl?: string;
467
+ permitType?: string;
468
+ checkoutCustomerId?: string;
469
+ ownerEmail?: string;
470
+ isEmailVerified?: boolean;
471
+ receiveOrders?: boolean;
472
+ isAcceptingOrders?: boolean;
473
+ ordersPercentage?: number;
474
+ integrations?: {
475
+ email?: string;
476
+ isActive?: boolean;
477
+ /** Canonical values from `INTEGRATION_KEYS`, e.g. `'TAP_PAYMENTS'`. */
478
+ key: string;
479
+ /** Tap (and other gateways): server-side API secret */
480
+ secretKey?: string;
481
+ /** Tap Connect marketplace payout destination id (sub-merchant). Set when the related `TapApplication` reaches `payout_enabled`. */
482
+ tapDestinationId?: string;
483
+ }[];
484
+ };
485
+ export declare const INTEGRATION_KEYS: {
486
+ readonly TAP_PAYMENTS: "TAP_PAYMENTS";
487
+ };
488
+ export type IntegrationKey = (typeof INTEGRATION_KEYS)[keyof typeof INTEGRATION_KEYS];
489
+ export type TapKycStatus = 'draft' | 'documents_uploaded' | 'lead_created' | 'account_created' | 'payout_enabled' | 'rejected';
490
+ export type TapDocumentPurpose = 'commercial_registration' | 'national_id' | 'bank_statement' | 'iban_certificate';
491
+ export type TapLicenseType = 'LLC' | 'SOLE_PROPRIETORSHIP' | 'JOINT_STOCK' | 'PARTNERSHIP' | 'OTHER';
492
+ export type TapApplicationFile = {
493
+ purpose: TapDocumentPurpose;
494
+ fileId: string;
495
+ title?: string;
496
+ /** epoch seconds */
497
+ uploadedAt: number;
498
+ /** epoch seconds, mirrors Tap's expires_at */
499
+ expiresAt?: number;
500
+ };
501
+ export type TapApplicationFormData = {
502
+ country: 'SA';
503
+ brand: {
504
+ websiteUrl: string;
505
+ nameEn: string;
506
+ nameAr: string;
507
+ };
508
+ entity: {
509
+ licenseNumber: string;
510
+ unifiedNumber: string;
511
+ licenseType: TapLicenseType;
512
+ legalNameEn: string;
513
+ };
514
+ bank: {
515
+ beneficiaryName: string;
516
+ iban: string;
517
+ };
518
+ walletName: string;
519
+ owner: {
520
+ firstName: string;
521
+ middleName?: string;
522
+ lastName: string;
523
+ email: string;
524
+ phoneCountryCode: string;
525
+ phoneNumber: string;
526
+ nationalId: string;
527
+ nationality: string;
528
+ idType: 'national_id' | 'passport';
529
+ };
530
+ };
531
+ export type TapApplicationError = {
532
+ code?: string;
533
+ message: string;
534
+ /** epoch seconds */
535
+ at: number;
536
+ endpoint: 'files' | 'lead' | 'account' | 'update_lead';
537
+ };
538
+ /**
539
+ * Stored at: `service_providers/{providerId}/tapApplications/{applicationId}`.
540
+ *
541
+ * One document per onboarding attempt. On rejection a new application may be created;
542
+ * history is preserved. Invariant: at most one non-terminal application per provider.
543
+ * Terminal states: `payout_enabled`, `rejected`.
544
+ */
545
+ export type TapApplication = {
546
+ id: string;
547
+ providerId: string;
548
+ /** epoch seconds */
549
+ createdAt: number;
550
+ /** epoch seconds */
551
+ updatedAt: number;
552
+ /** admin uid that initiated the application */
553
+ createdBy: string;
554
+ kycStatus: TapKycStatus;
555
+ payoutEnabled: boolean;
556
+ formData?: TapApplicationFormData;
557
+ files?: TapApplicationFile[];
558
+ tapLeadId?: string;
559
+ /** retailer.id from Tap; mirrored up to provider.integrations[TAP_PAYMENTS].tapDestinationId on payout_enabled */
560
+ tapDestinationId?: string;
561
+ /** epoch seconds — lead → account transition */
562
+ submittedAt?: number;
563
+ /** epoch seconds — set by webhook on payout_enabled */
564
+ approvedAt?: number;
565
+ /** epoch seconds */
566
+ rejectedAt?: number;
567
+ rejectionReason?: string;
568
+ lastError?: TapApplicationError;
569
+ /** echo of post.url sent on lead creation */
570
+ webhookUrl?: string;
571
+ };
572
+ export type Card = {
573
+ id?: string;
574
+ issuer?: string;
575
+ expiry_month?: string;
576
+ expiry_year?: string;
577
+ name?: string;
578
+ scheme?: string;
579
+ bin?: string;
580
+ last4?: string;
581
+ customer?: {
582
+ id?: string;
583
+ };
584
+ default?: boolean;
585
+ customer_id?: string;
586
+ };
587
+ export type CheckoutCustomer = {
588
+ default?: string;
589
+ email?: string;
590
+ id?: string;
591
+ name?: string;
592
+ instruments?: Card[];
593
+ metadata?: {
594
+ iban?: string;
595
+ providerUid?: string;
596
+ };
597
+ };
598
+ export type CarService = {
599
+ car?: Car;
600
+ services: Array<ProvidedService | ProvidedAddon>;
601
+ isDone?: boolean;
602
+ };
603
+ export type Discount = {
604
+ promoCodeId?: string;
605
+ promoCode?: string;
606
+ validFrom?: TimestampType;
607
+ validTo?: TimestampType;
608
+ createdAt?: TimestampType;
609
+ allowedOnce?: boolean;
610
+ createdByProvider?: boolean;
611
+ providerUid?: string;
612
+ usedBy?: string[];
613
+ amount?: number;
614
+ isPercentage?: boolean;
615
+ maxAmount?: number;
616
+ isAutoApplied?: boolean;
617
+ servicesIds?: string[];
618
+ addonsIds?: string[];
619
+ clientIds?: string[];
620
+ createrEmail?: string;
621
+ /** Percent of the discount funded by Sahab. 10 means 10%, not 50%.
622
+ * If only one of the two is set, the other side funds the remainder automatically. */
623
+ sahabPercentage?: number;
624
+ /** Percent of the discount funded by the Provider. 10 means 10%, not 50%.
625
+ * If only one of the two is set, the other side funds the remainder automatically. */
626
+ providerPercentage?: number;
627
+ /** Present only on "buy N, get one free" offers. Absent means an ordinary discount. */
628
+ loyalty?: LoyaltyOffer;
629
+ /**
630
+ * Restricts the offer to customers who have not ordered before.
631
+ *
632
+ * Sahab-only by nature: it is a platform acquisition offer, so `sahabPercentage` should be
633
+ * 100. Eligibility is decided by the server — the client cannot be trusted to report its own
634
+ * order history — and re-checked when the order is created.
635
+ *
636
+ * "Has not ordered before" means no order that is still live or already completed. An order
637
+ * the customer cancelled does not burn the offer, but one that is in flight does, which is
638
+ * what stops the same first-order discount being claimed on two carts at once.
639
+ */
640
+ firstOrderOnly?: boolean;
641
+ /**
642
+ * Providers this offer is valid at. Empty or absent means every provider.
643
+ *
644
+ * Distinct from `providerUid`, which marks an offer a *provider* created and funds. This is
645
+ * a Sahab offer that Sahab funds, restricted to a chosen set of carwashes.
646
+ */
647
+ providerUids?: string[];
648
+ /**
649
+ * Present only on the voucher issued for a gift. Absent means an ordinary discount.
650
+ *
651
+ * The back-pointer is what lets the order pipeline recognise a gift redemption without
652
+ * loading anything — used to keep the loyalty stamp away from the recipient, who did not pay
653
+ * for the wash.
654
+ */
655
+ gift?: {
656
+ giftId: string;
657
+ };
658
+ };
659
+ /**
660
+ * "Buy N washes, get one free" configuration, carried on the `Discount` that represents the
661
+ * offer.
662
+ *
663
+ * The reward is redeemed as an ordinary fixed-amount discount: at redemption the earned amount
664
+ * is written onto `order.promoCode.amount`, so it flows through `getSahabDiscountsAmount` /
665
+ * `getProviderDiscountsAmount` and the `sahabPercentage` / `providerPercentage` split exactly
666
+ * like any other promo. Nothing in the pricing pipeline needs to know loyalty exists.
667
+ */
668
+ export type LoyaltyOffer = {
669
+ /** Qualifying orders needed to earn one free wash. */
670
+ buyQuantity: number;
671
+ /**
672
+ * Minimum the customer must actually pay for an order to count as a stamp.
673
+ *
674
+ * Without it a customer can collect stamps on the cheapest possible wash and redeem against
675
+ * an expensive one.
676
+ */
677
+ minOrderAmount?: number;
678
+ /**
679
+ * Providers whose completed orders count toward this offer.
680
+ *
681
+ * Only meaningful for Sahab-created offers, which may span some or all providers. A
682
+ * provider-created offer is always scoped to its own `providerUid`, whatever this says.
683
+ * Absent or empty on a Sahab offer means every provider counts.
684
+ */
685
+ providerUids?: string[];
686
+ };
687
+ /**
688
+ * A customer's progress toward one loyalty offer.
689
+ *
690
+ * Server-owned: only cloud functions may write it, or a customer could award themselves washes.
691
+ * Rewards do not expire — the campaign's own `validFrom`/`validTo` bounds when stamps are
692
+ * earned, not how long an earned reward lasts.
693
+ */
694
+ export type LoyaltyProgress = {
695
+ clientId: string;
696
+ /** The offer this progress belongs to. */
697
+ promoCodeId: string;
698
+ /** Set for provider-scoped offers; absent when the offer spans providers. */
699
+ providerUid?: string;
700
+ /** Stamps collected toward the next reward. Resets to 0 each time one is earned. */
701
+ qualifyingCount: number;
702
+ /** Earned but not yet redeemed free washes. */
703
+ earnedRewards: number;
704
+ /** Orders already counted, so a status flapping COMPLETED->RATED cannot double-stamp. */
705
+ countedOrderIds: string[];
706
+ /**
707
+ * Gifts already counted, for stamps earned by *buying* a gift rather than by ordering.
708
+ *
709
+ * Kept separate from `countedOrderIds` because a gift has no order id at the moment it is
710
+ * paid for, and mixing the two id spaces would make a collision silently skip a stamp.
711
+ */
712
+ countedGiftIds?: string[];
713
+ updatedAt?: TimestampType;
714
+ };
715
+ /**
716
+ * One paid-for gift: a basket of services and addons bought by one customer for another.
717
+ *
718
+ * The voucher the recipient actually spends is an ordinary `Discount` carrying `gift.giftId`.
719
+ * This document owns everything the voucher deliberately does not — payment, delivery and
720
+ * lifecycle — so the voucher stays a pure pricing object that the calcs can read without
721
+ * knowing gifting exists.
722
+ *
723
+ * Server-owned. A client that could write this could issue itself free washes.
724
+ */
725
+ export type Gift = {
726
+ giftId: string;
727
+ status: GiftStatus;
728
+ /** Who paid. Loyalty stamps for this purchase go to them, not the recipient. */
729
+ giverUid: string;
730
+ giverName?: string;
731
+ /** E.164, normalised at write. The recipient may not have an account yet. */
732
+ recipientPhone: string;
733
+ /**
734
+ * Resolved at issuance, before the recipient has ever opened the app — Firebase Auth mints a
735
+ * stable uid for a phone number on demand, so the voucher can be scoped to them immediately.
736
+ */
737
+ recipientUid?: string;
738
+ /** Whether they were already a customer. Analytics, and useful to support. */
739
+ recipientHadAccount?: boolean;
740
+ providerUid: string;
741
+ providerName?: {
742
+ ar: string;
743
+ en: string;
744
+ };
745
+ /** The basket, priced at purchase. Multi-visit services are not giftable — see `ts/gifts.ts`. */
746
+ items: GiftItem[];
747
+ /** The size the giver chose. The recipient's car may differ; the cap is what transfers. */
748
+ carSize: CarSize;
749
+ /** What the giver paid — the whole basket. Also the voucher's cap. */
750
+ amount: number;
751
+ paymentId?: string;
752
+ /** The voucher issued once payment succeeded. */
753
+ promoCodeId?: string;
754
+ /** The order it was spent on. */
755
+ orderId?: string;
756
+ /** Optional note from the giver, shown to the recipient. */
757
+ message?: string;
758
+ createdAt?: TimestampType;
759
+ issuedAt?: TimestampType;
760
+ redeemedAt?: TimestampType;
761
+ /** Stamped at issuance so a later config change cannot shorten a gift already sold. */
762
+ expiresAt?: TimestampType;
763
+ notifiedAt?: TimestampType;
764
+ notifyChannel?: GiftNotifyChannel;
765
+ };
766
+ /** One line of a gifted basket, priced when the gift was bought. */
767
+ export type GiftItem = {
768
+ kind: 'service' | 'addon';
769
+ /** `serviceId` or `addonId` depending on `kind`. */
770
+ id: string;
771
+ name?: {
772
+ ar: string;
773
+ en: string;
774
+ };
775
+ price: number;
776
+ };
777
+ export declare enum GiftStatus {
778
+ /** Charge started, not yet confirmed. No voucher exists yet. */
779
+ PENDING_PAYMENT = "PENDING_PAYMENT",
780
+ /** Paid, voucher issued, waiting to be spent. */
781
+ ISSUED = "ISSUED",
782
+ /** Spent on an order. */
783
+ REDEEMED = "REDEEMED",
784
+ /** Passed `expiresAt` unspent. */
785
+ EXPIRED = "EXPIRED",
786
+ /** Refunded to the giver. Only reachable from ISSUED. */
787
+ REFUNDED = "REFUNDED",
788
+ /** The charge failed. No voucher was ever issued. */
789
+ FAILED = "FAILED"
790
+ }
791
+ export declare enum GiftNotifyChannel {
792
+ SMS = "SMS",
793
+ WHATSAPP = "WHATSAPP"
794
+ }
795
+ /** Back-office settings for gifting. */
796
+ export type GiftConfig = {
797
+ /**
798
+ * How long an issued gift stays spendable. Applied at issuance only.
799
+ *
800
+ * Bounded on read: a 0 would expire every gift the moment it was sold.
801
+ */
802
+ giftExpiryMonths?: number;
803
+ };
804
+ export type OrderReview = {
805
+ ratingId: string;
806
+ ratingNote: string;
807
+ orderId: string;
808
+ orderDate: TimestampType;
809
+ createdDate: TimestampType;
810
+ providerId: string;
811
+ arrivalDate: string;
812
+ finishDate: string;
813
+ rating: number;
814
+ clientId: string;
815
+ };
816
+ export type CountryCode = {
817
+ code: string;
818
+ dial_code: string;
819
+ flag: string;
820
+ name_en: string;
821
+ name_ar: string;
822
+ };
823
+ export type LocationInfo = {
824
+ city?: string;
825
+ country?: string;
826
+ postalCode?: string;
827
+ line1: string;
828
+ line2?: string;
829
+ long_name?: string;
830
+ latitude?: number;
831
+ longitude?: number;
832
+ };
833
+ export type SavedLocation = {
834
+ locationId: string;
835
+ name: string;
836
+ latitude: number;
837
+ longitude: number;
838
+ isPrimary?: boolean;
839
+ };
840
+ export type CheckoutCard = {
841
+ id?: string;
842
+ type?: string;
843
+ fingerprint?: string;
844
+ expiry_month?: string;
845
+ expiry_year?: string;
846
+ scheme?: string;
847
+ scheme_local?: string;
848
+ last4?: string;
849
+ bin?: string;
850
+ card_type?: string;
851
+ card_category?: string;
852
+ issuer?: string;
853
+ issuer_country?: string;
854
+ product_type?: string;
855
+ };
856
+ export type CheckoutToken = {
857
+ type?: string;
858
+ token?: string;
859
+ expires_on?: string;
860
+ expiry_month?: number;
861
+ expiry_year?: number;
862
+ scheme?: string;
863
+ scheme_local?: string;
864
+ last4?: string;
865
+ bin?: string;
866
+ card_type?: string;
867
+ card_category?: string;
868
+ issuer?: string;
869
+ issuer_country?: string;
870
+ product_id: string;
871
+ product_type: string;
872
+ billing_address?: {
873
+ address_line1?: string;
874
+ address_line2: string;
875
+ city?: string;
876
+ state?: string;
877
+ zip?: string;
878
+ country?: string;
879
+ };
880
+ phone?: {
881
+ country_code?: string;
882
+ number?: string;
883
+ };
884
+ name?: string;
885
+ };
886
+ export type SPECIFIED_TIME = 'anytime' | number;
887
+ export type PlaceOrder = {
888
+ clientID: string;
889
+ providerId: string;
890
+ orderMilllSec: number;
891
+ orderNanoSec: number;
892
+ services: CarService[];
893
+ lat: number;
894
+ long: number;
895
+ willClientBeThere: boolean;
896
+ paymentType: OrderPaymentType;
897
+ isPaid: boolean;
898
+ /** Set once the charge succeeds, not when the payload is first built. */
899
+ paymentId?: string;
900
+ isProviderTest: boolean;
901
+ providerReceiveOrders: boolean;
902
+ orderNote: string;
903
+ /** Absent when no discount applies. */
904
+ promoCode?: Discount;
905
+ driverIds: string[];
906
+ providerName: {
907
+ ar: string;
908
+ en: string;
909
+ };
910
+ paymentAmount: number;
911
+ usedBalance: number;
912
+ providerPhoneNumber: string;
913
+ isAddonStructure: boolean;
914
+ isMonthlyPackage: boolean;
915
+ sahabExtraPaymentAmount: number;
916
+ orderId?: string;
917
+ paymentGateway?: 'PAYLINK' | 'CHECKOUT' | 'TAP';
918
+ /** Explicit dates for a multi-visit package; the server derives them when omitted. */
919
+ visitDates?: number[];
920
+ /** Mirrors Order economics for server-side Tap split; optional override of client fee % */
921
+ sahabClientPercentage?: number;
922
+ };
923
+ export type WeatherData = {
924
+ date: string;
925
+ precipitationProbability: number;
926
+ rainAccumulation: number;
927
+ cloudCover: number;
928
+ humidity: number;
929
+ windSpeed: number;
930
+ uvIndex: number;
931
+ };
932
+ export type PaymentConfigs = {
933
+ isCashAllowed: boolean;
934
+ isGooglePayAllowed?: boolean;
935
+ /** Tap GoSell merchant id for card / Apple Pay SDK config (optional; falls back in app). */
936
+ tapMerchantId?: string;
937
+ paymentGateways: {
938
+ key: string;
939
+ isActive: boolean;
940
+ priority: number;
941
+ }[];
942
+ };
943
+ export type Slot = {
944
+ id: string;
945
+ time: number;
946
+ selected: boolean;
947
+ reserved: boolean;
948
+ };
949
+ export type Statement = {
950
+ numberOfOrders: number;
951
+ completedOrders: number;
952
+ ratedOrders: number;
953
+ cancelledOrders: number;
954
+ cashOrders: number;
955
+ creditOrders: number;
956
+ applePayPayments: number;
957
+ expiredOrders: number;
958
+ confirmedOrders: number;
959
+ lateOrders: number;
960
+ ordersTotal: number;
961
+ orders: Order[];
962
+ statmentDate?: Date | string;
963
+ };