richie-education 2.29.2 → 2.29.3-dev48
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/i18n/locales/ar-SA.json +193 -125
- package/i18n/locales/es-ES.json +193 -125
- package/i18n/locales/fa-IR.json +193 -125
- package/i18n/locales/fr-CA.json +193 -125
- package/i18n/locales/fr-FR.json +193 -125
- package/i18n/locales/ko-KR.json +193 -125
- package/i18n/locales/pt-PT.json +193 -125
- package/i18n/locales/ru-RU.json +193 -125
- package/i18n/locales/vi-VN.json +193 -125
- package/js/api/joanie.ts +42 -17
- package/js/api/lms/dummy.ts +1 -12
- package/js/components/ContractFrame/AbstractContractFrame.spec.tsx +16 -9
- package/js/components/ContractFrame/AbstractContractFrame.tsx +28 -23
- package/js/components/ContractFrame/LearnerContractFrame.tsx +2 -2
- package/js/components/ContractFrame/_styles.scss +6 -14
- package/js/components/ContractStatus/index.spec.tsx +1 -1
- package/js/components/ContractStatus/index.tsx +1 -1
- package/js/components/{SaleTunnel/CreditCardSelector → CreditCardSelector}/index.spec.tsx +15 -45
- package/js/components/{SaleTunnel/CreditCardSelector → CreditCardSelector}/index.tsx +19 -26
- package/js/components/DownloadContractButton/index.spec.tsx +1 -1
- package/js/components/Form/utils.ts +2 -1
- package/js/components/OpenEdxFullNameForm/index.spec.tsx +229 -0
- package/js/components/OpenEdxFullNameForm/index.tsx +7 -7
- package/js/components/PaymentInterfaces/LyraPopIn.tsx +2 -2
- package/js/components/PaymentInterfaces/PayplugLightbox.tsx +1 -1
- package/js/components/PaymentInterfaces/__mocks__/index.tsx +1 -4
- package/js/components/PaymentInterfaces/types.ts +5 -2
- package/js/components/PaymentScheduleGrid/_styles.scss +13 -0
- package/js/components/PaymentScheduleGrid/index.tsx +50 -70
- package/js/components/PurchaseButton/index.spec.tsx +84 -37
- package/js/components/PurchaseButton/index.tsx +9 -27
- package/js/components/SaleTunnel/AddressSelector/index.spec.tsx +2 -2
- package/js/components/SaleTunnel/CertificateSaleTunnel/index.tsx +2 -2
- package/js/components/SaleTunnel/CredentialSaleTunnel/index.tsx +6 -10
- package/js/components/SaleTunnel/GenericSaleTunnel.tsx +105 -48
- package/js/components/SaleTunnel/SaleTunnelInformation/index.tsx +16 -20
- package/js/components/SaleTunnel/SaleTunnelSavePaymentMethod/_styles.scss +12 -0
- package/js/components/SaleTunnel/SaleTunnelSavePaymentMethod/index.tsx +157 -0
- package/js/components/SaleTunnel/SaleTunnelSuccess/index.tsx +15 -29
- package/js/components/SaleTunnel/Sponsors/SaleTunnelSponsors.scss +4 -5
- package/js/components/SaleTunnel/Sponsors/SaleTunnelSponsors.tsx +39 -11
- package/js/components/SaleTunnel/SubscriptionButton/_styles.scss +7 -0
- package/js/components/SaleTunnel/SubscriptionButton/index.tsx +202 -0
- package/js/components/SaleTunnel/_styles.scss +16 -5
- package/js/components/SaleTunnel/hooks/useTerms.tsx +0 -77
- package/js/components/SaleTunnel/index.credential.spec.tsx +14 -25
- package/js/components/SaleTunnel/index.full-process.spec.tsx +114 -48
- package/js/components/SaleTunnel/index.spec.tsx +333 -717
- package/js/components/SaleTunnel/index.tsx +2 -1
- package/js/components/SignContractButton/index.omniscientOrders.spec.tsx +16 -11
- package/js/components/SignContractButton/index.spec.tsx +16 -20
- package/js/components/SignContractButton/index.tsx +3 -1
- package/js/hooks/useCreditCards/index.spec.tsx +70 -6
- package/js/hooks/useCreditCards/index.ts +49 -11
- package/js/hooks/useOrders/index.spec.tsx +322 -0
- package/js/hooks/{useOrders.ts → useOrders/index.ts} +40 -14
- package/js/hooks/usePaymentSchedule.tsx +23 -0
- package/js/hooks/useProductOrder/index.spec.tsx +77 -60
- package/js/hooks/useProductOrder/index.tsx +2 -2
- package/js/hooks/useResources/useResourcesRoot.ts +4 -3
- package/js/index.tsx +2 -0
- package/js/pages/DashboardCreditCardsManagement/CreditCardBrandLogo.spec.tsx +1 -1
- package/js/pages/DashboardCreditCardsManagement/CreditCardBrandLogo.tsx +4 -2
- package/js/pages/DashboardOrderLayout/index.spec.tsx +10 -1
- package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.spec.tsx +8 -5
- package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.spec.tsx +8 -9
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.spec.tsx +1 -1
- package/js/pages/TeacherDashboardCourseLearnersLayout/components/CourseLearnerDataGrid/index.tsx +1 -6
- package/js/settings/settings.prod.ts +0 -2
- package/js/settings/settings.test.ts +16 -2
- package/js/translations/ar-SA.json +1 -1
- package/js/translations/es-ES.json +1 -1
- package/js/translations/fa-IR.json +1 -1
- package/js/translations/fr-CA.json +1 -1
- package/js/translations/fr-FR.json +1 -1
- package/js/translations/ko-KR.json +1 -1
- package/js/translations/pt-PT.json +1 -1
- package/js/translations/ru-RU.json +1 -1
- package/js/translations/vi-VN.json +1 -1
- package/js/types/Joanie.ts +81 -32
- package/js/utils/OrderHelper/index.ts +46 -38
- package/js/utils/PaymentScheduleHelper/index.spec.tsx +78 -0
- package/js/utils/PaymentScheduleHelper/index.ts +30 -0
- package/js/utils/ProductHelper/index.spec.ts +322 -166
- package/js/utils/ProductHelper/index.ts +32 -0
- package/js/utils/test/factories/joanie.ts +72 -69
- package/js/widgets/Dashboard/components/DashboardItem/Contract/index.spec.tsx +2 -2
- package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.tsx +8 -18
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.spec.tsx +23 -0
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.tsx +23 -1
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +145 -34
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.tsx +175 -37
- package/js/widgets/Dashboard/components/DashboardItem/Order/CertificateItem/index.tsx +51 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/ContractItem/index.tsx +52 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemNotResumable.spec.tsx +109 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.spec.tsx +219 -5
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +111 -245
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.spec.tsx +61 -8
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.useUnionResource.cache.spec.tsx +17 -7
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemSavePaymentMethod.spec.tsx +116 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/Installment/index.tsx +175 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentDetailsModal/_styles.scss +7 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentDetailsModal/index.tsx +127 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderPaymentRetryModal/index.tsx +216 -0
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.spec.tsx +18 -71
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.tsx +40 -25
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateMessage/index.tsx +28 -22
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.spec.tsx +18 -73
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.tsx +32 -16
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrganizationBlock/index.tsx +150 -0
- package/js/widgets/Dashboard/components/DashboardOrderLoader/index.tsx +32 -14
- package/js/widgets/Dashboard/components/Signature/SignatureDummy.tsx +25 -3
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/EnrollableCourseRunList.tsx +2 -6
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx +7 -14
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.spec.tsx +7 -5
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.tsx +5 -7
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +242 -332
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +12 -13
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +10 -21
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.joanie.spec.tsx +2 -2
- package/package.json +45 -44
- package/scss/components/_index.scss +4 -2
- package/js/components/PaymentButton/_styles.scss +0 -27
- package/js/components/SaleTunnel/GenericPaymentButton/index.tsx +0 -340
- package/js/components/SaleTunnel/SaleTunnelNotValidated/index.tsx +0 -70
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/ProductSignatureHeader/index.tsx +0 -41
- /package/js/components/{SaleTunnel/CreditCardSelector → CreditCardSelector}/_styles.scss +0 -0
package/js/types/Joanie.ts
CHANGED
|
@@ -259,14 +259,42 @@ export interface EnrollmentLight {
|
|
|
259
259
|
|
|
260
260
|
// Order
|
|
261
261
|
export enum OrderState {
|
|
262
|
-
|
|
263
|
-
SUBMITTED = 'submitted',
|
|
262
|
+
ASSIGNED = 'assigned',
|
|
264
263
|
CANCELED = 'canceled',
|
|
264
|
+
COMPLETED = 'completed',
|
|
265
|
+
DRAFT = 'draft',
|
|
266
|
+
FAILED_PAYMENT = 'failed_payment',
|
|
267
|
+
NO_PAYMENT = 'no_payment',
|
|
265
268
|
PENDING = 'pending',
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
PENDING_PAYMENT = 'pending_payment',
|
|
270
|
+
SIGNING = 'signing',
|
|
271
|
+
TO_SAVE_PAYMENT_METHOD = 'to_save_payment_method',
|
|
272
|
+
TO_SIGN = 'to_sign',
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export const PURCHASABLE_ORDER_STATES = [
|
|
276
|
+
OrderState.DRAFT,
|
|
277
|
+
OrderState.ASSIGNED,
|
|
278
|
+
OrderState.TO_SIGN,
|
|
279
|
+
OrderState.SIGNING,
|
|
280
|
+
OrderState.TO_SAVE_PAYMENT_METHOD,
|
|
281
|
+
];
|
|
282
|
+
|
|
283
|
+
export const ACTIVE_ORDER_STATES = [
|
|
284
|
+
OrderState.PENDING,
|
|
285
|
+
OrderState.PENDING_PAYMENT,
|
|
286
|
+
OrderState.NO_PAYMENT,
|
|
287
|
+
OrderState.FAILED_PAYMENT,
|
|
288
|
+
OrderState.COMPLETED,
|
|
289
|
+
];
|
|
290
|
+
|
|
291
|
+
export const NOT_CANCELED_ORDER_STATES = [...ACTIVE_ORDER_STATES, ...PURCHASABLE_ORDER_STATES];
|
|
292
|
+
|
|
293
|
+
export const ENROLLABLE_ORDER_STATES = [
|
|
294
|
+
OrderState.COMPLETED,
|
|
295
|
+
OrderState.PENDING_PAYMENT,
|
|
296
|
+
OrderState.FAILED_PAYMENT,
|
|
297
|
+
];
|
|
270
298
|
|
|
271
299
|
export interface Order {
|
|
272
300
|
id: string;
|
|
@@ -286,6 +314,8 @@ export interface Order {
|
|
|
286
314
|
organization_id: Organization['id'];
|
|
287
315
|
organization: Organization;
|
|
288
316
|
order_group_id?: OrderGroup['id'];
|
|
317
|
+
payment_schedule?: PaymentSchedule;
|
|
318
|
+
credit_card_id?: CreditCard['id'];
|
|
289
319
|
}
|
|
290
320
|
|
|
291
321
|
export interface CredentialOrder extends Order {
|
|
@@ -293,20 +323,12 @@ export interface CredentialOrder extends Order {
|
|
|
293
323
|
enrollment: null;
|
|
294
324
|
}
|
|
295
325
|
|
|
296
|
-
export interface CredentialOrderWithPaymentInfo extends CredentialOrder {
|
|
297
|
-
payment_info: Payment;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
326
|
export interface CertificateOrder extends Order {
|
|
301
327
|
course: null;
|
|
302
328
|
enrollment: EnrollmentLight;
|
|
303
329
|
target_courses: never[];
|
|
304
330
|
}
|
|
305
331
|
|
|
306
|
-
export interface CertificateOrderWithPaymentInfo extends CertificateOrder {
|
|
307
|
-
payment_info: Payment;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
332
|
export type OrderLite = Pick<
|
|
311
333
|
Order,
|
|
312
334
|
| 'id'
|
|
@@ -325,9 +347,11 @@ export interface AbstractNestedOrder {
|
|
|
325
347
|
product_title: string;
|
|
326
348
|
owner_name: string;
|
|
327
349
|
state: OrderState;
|
|
350
|
+
course: Nullable<CourseLight>;
|
|
351
|
+
enrollment: Nullable<EnrollmentLight>;
|
|
328
352
|
}
|
|
329
353
|
export interface NestedCertificateOrder extends AbstractNestedOrder {
|
|
330
|
-
course:
|
|
354
|
+
course: null;
|
|
331
355
|
enrollment: EnrollmentLight;
|
|
332
356
|
}
|
|
333
357
|
export const isNestedCredentialOrder = (
|
|
@@ -338,10 +362,13 @@ export const isNestedCredentialOrder = (
|
|
|
338
362
|
|
|
339
363
|
export interface NestedCredentialOrder extends AbstractNestedOrder {
|
|
340
364
|
course: CourseLight;
|
|
341
|
-
enrollment:
|
|
365
|
+
enrollment: null;
|
|
342
366
|
}
|
|
343
367
|
|
|
344
|
-
export type OrderEnrollment = Pick<
|
|
368
|
+
export type OrderEnrollment = Pick<
|
|
369
|
+
Order,
|
|
370
|
+
'id' | 'state' | 'product_id' | 'certificate_id' | 'payment_schedule'
|
|
371
|
+
>;
|
|
345
372
|
|
|
346
373
|
export interface NestedCourseOrder {
|
|
347
374
|
id: Order['id'];
|
|
@@ -372,10 +399,10 @@ export interface OrderGroup {
|
|
|
372
399
|
}
|
|
373
400
|
|
|
374
401
|
export enum CreditCardBrand {
|
|
375
|
-
MASTERCARD = '
|
|
376
|
-
MAESTRO = '
|
|
377
|
-
VISA = '
|
|
378
|
-
CB = '
|
|
402
|
+
MASTERCARD = 'mastercard',
|
|
403
|
+
MAESTRO = 'maestro',
|
|
404
|
+
VISA = 'visa',
|
|
405
|
+
CB = 'cb',
|
|
379
406
|
}
|
|
380
407
|
|
|
381
408
|
// Credit Card
|
|
@@ -416,6 +443,22 @@ export interface OrderPaymentInfo {
|
|
|
416
443
|
payment_info: Payment;
|
|
417
444
|
}
|
|
418
445
|
|
|
446
|
+
export enum PaymentScheduleState {
|
|
447
|
+
PENDING = 'pending',
|
|
448
|
+
PAID = 'paid',
|
|
449
|
+
REFUSED = 'refused',
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export interface PaymentInstallment {
|
|
453
|
+
id: string;
|
|
454
|
+
amount: number;
|
|
455
|
+
currency: string;
|
|
456
|
+
due_date: string;
|
|
457
|
+
state: PaymentScheduleState;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export type PaymentSchedule = readonly PaymentInstallment[];
|
|
461
|
+
|
|
419
462
|
// - API
|
|
420
463
|
export interface AddressCreationPayload extends Omit<Address, 'id' | 'is_main'> {
|
|
421
464
|
is_main?: boolean;
|
|
@@ -424,7 +467,7 @@ export interface AddressCreationPayload extends Omit<Address, 'id' | 'is_main'>
|
|
|
424
467
|
interface AbstractOrderProductCreationPayload {
|
|
425
468
|
product_id: Product['id'];
|
|
426
469
|
order_group_id?: OrderGroup['id'];
|
|
427
|
-
|
|
470
|
+
billing_address: Omit<Address, 'id' | 'is_main'>;
|
|
428
471
|
}
|
|
429
472
|
|
|
430
473
|
interface OrderCertificateCreationPayload extends AbstractOrderProductCreationPayload {
|
|
@@ -436,15 +479,13 @@ export interface OrderCredentialCreationPayload extends AbstractOrderProductCrea
|
|
|
436
479
|
|
|
437
480
|
export type OrderCreationPayload = OrderCertificateCreationPayload | OrderCredentialCreationPayload;
|
|
438
481
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
}
|
|
482
|
+
export type OrderSubmitInstallmentPayment = {
|
|
483
|
+
credit_card_id?: string;
|
|
484
|
+
};
|
|
443
485
|
|
|
444
|
-
interface
|
|
486
|
+
interface OrderSetPaymentMethodPayload {
|
|
445
487
|
id: Order['id'];
|
|
446
|
-
|
|
447
|
-
credit_card_id?: CreditCard['id'];
|
|
488
|
+
credit_card_id: CreditCard['id'];
|
|
448
489
|
}
|
|
449
490
|
|
|
450
491
|
export interface PaginatedResourceQuery extends ResourcesQuery {
|
|
@@ -539,14 +580,15 @@ interface APIUser {
|
|
|
539
580
|
update(payload: Address): Promise<Address>;
|
|
540
581
|
};
|
|
541
582
|
creditCards: {
|
|
542
|
-
create(payload: Omit<CreditCard, 'id'>): Promise<CreditCard>;
|
|
543
583
|
delete(id: CreditCard['id']): Promise<void>;
|
|
584
|
+
get(): Promise<PaginatedResponse<CreditCard>>;
|
|
544
585
|
get(filters?: ResourcesQuery): Promise<CreditCard>;
|
|
545
586
|
get(): Promise<CreditCard[]>;
|
|
546
587
|
update(payload: CreditCard): Promise<CreditCard>;
|
|
588
|
+
tokenize(): Promise<Payment>;
|
|
547
589
|
};
|
|
548
590
|
orders: {
|
|
549
|
-
|
|
591
|
+
cancel(id: Order['id']): Promise<void>;
|
|
550
592
|
create(payload: OrderCreationPayload): Promise<CredentialOrder | CertificateOrder>;
|
|
551
593
|
get<Filters extends OrderResourcesQuery = OrderResourcesQuery>(
|
|
552
594
|
filters?: Filters,
|
|
@@ -556,8 +598,12 @@ interface APIUser {
|
|
|
556
598
|
invoice: {
|
|
557
599
|
download(payload: { order_id: Order['id']; invoice_reference: string }): Promise<File>;
|
|
558
600
|
};
|
|
559
|
-
submit(payload: OrderSubmitPayload): Promise<OrderPaymentInfo>;
|
|
560
601
|
submit_for_signature(id: string): Promise<ContractInvitationLinkResponse>;
|
|
602
|
+
submit_installment_payment(
|
|
603
|
+
id: string,
|
|
604
|
+
payload?: OrderSubmitInstallmentPayment,
|
|
605
|
+
): Promise<Payment>;
|
|
606
|
+
set_payment_method(payload: OrderSetPaymentMethodPayload): Promise<void>;
|
|
561
607
|
};
|
|
562
608
|
certificates: {
|
|
563
609
|
download(id: string): Promise<File>;
|
|
@@ -614,6 +660,9 @@ export interface API {
|
|
|
614
660
|
: Promise<PaginatedResponse<CourseListItem>>;
|
|
615
661
|
products: {
|
|
616
662
|
get(filters?: CourseProductQueryFilters): Promise<Nullable<CourseProductRelation>>;
|
|
663
|
+
paymentSchedule: {
|
|
664
|
+
get(filters?: CourseProductQueryFilters): Promise<Nullable<PaymentSchedule>>;
|
|
665
|
+
};
|
|
617
666
|
};
|
|
618
667
|
orders: {
|
|
619
668
|
get(
|
|
@@ -1,49 +1,52 @@
|
|
|
1
1
|
import {
|
|
2
|
-
OrderEnrollment,
|
|
3
2
|
ACTIVE_ORDER_STATES,
|
|
3
|
+
ENROLLABLE_ORDER_STATES,
|
|
4
|
+
NestedCourseOrder,
|
|
4
5
|
Order,
|
|
6
|
+
OrderEnrollment,
|
|
5
7
|
OrderState,
|
|
6
|
-
|
|
7
|
-
NestedCourseOrder,
|
|
8
|
+
PURCHASABLE_ORDER_STATES,
|
|
8
9
|
} from 'types/Joanie';
|
|
9
10
|
|
|
10
11
|
export enum OrderStatus {
|
|
12
|
+
ASSIGNED = 'assigned',
|
|
13
|
+
CANCELED = 'canceled',
|
|
14
|
+
COMPLETED = 'completed',
|
|
11
15
|
DRAFT = 'draft',
|
|
12
|
-
|
|
16
|
+
FAILED_PAYMENT = 'failed_payment',
|
|
17
|
+
NO_PAYMENT = 'no_payment',
|
|
18
|
+
PASSED = 'passed',
|
|
13
19
|
PENDING = 'pending',
|
|
14
|
-
|
|
15
|
-
WAITING_SIGNATURE = 'waiting_signature',
|
|
20
|
+
PENDING_PAYMENT = 'pending_payment',
|
|
16
21
|
WAITING_COUNTER_SIGNATURE = 'waiting_counter_signature',
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
WAITING_PAYMENT_METHOD = 'waiting_payment_method',
|
|
23
|
+
WAITING_SIGNATURE = 'waiting_signature',
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
/**
|
|
22
27
|
* Helper class for orders
|
|
23
28
|
*/
|
|
24
29
|
export class OrderHelper {
|
|
25
|
-
static getState(order: Order | NestedCourseOrder
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
if (OrderHelper.orderNeedsCounterSignature(order)) {
|
|
33
|
-
return OrderStatus.WAITING_COUNTER_SIGNATURE;
|
|
34
|
-
}
|
|
35
|
-
if (certificateId) {
|
|
36
|
-
return OrderStatus.COMPLETED;
|
|
37
|
-
} else {
|
|
38
|
-
return OrderStatus.ON_GOING;
|
|
39
|
-
}
|
|
30
|
+
static getState(order: Order | NestedCourseOrder) {
|
|
31
|
+
if (OrderHelper.allowEnrollment(order) && OrderHelper.orderNeedsCounterSignature(order)) {
|
|
32
|
+
return OrderStatus.WAITING_COUNTER_SIGNATURE;
|
|
33
|
+
}
|
|
34
|
+
if (order.state === OrderState.COMPLETED && order.certificate_id) {
|
|
35
|
+
return OrderStatus.PASSED;
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
const orderStatusMap = {
|
|
39
|
+
[OrderState.ASSIGNED]: OrderStatus.ASSIGNED,
|
|
40
|
+
[OrderState.CANCELED]: OrderStatus.CANCELED,
|
|
41
|
+
[OrderState.COMPLETED]: OrderStatus.COMPLETED,
|
|
43
42
|
[OrderState.DRAFT]: OrderStatus.DRAFT,
|
|
44
|
-
[OrderState.
|
|
43
|
+
[OrderState.FAILED_PAYMENT]: OrderStatus.FAILED_PAYMENT,
|
|
44
|
+
[OrderState.NO_PAYMENT]: OrderStatus.NO_PAYMENT,
|
|
45
45
|
[OrderState.PENDING]: OrderStatus.PENDING,
|
|
46
|
-
[OrderState.
|
|
46
|
+
[OrderState.PENDING_PAYMENT]: OrderStatus.PENDING_PAYMENT,
|
|
47
|
+
[OrderState.SIGNING]: OrderStatus.WAITING_SIGNATURE,
|
|
48
|
+
[OrderState.TO_SAVE_PAYMENT_METHOD]: OrderStatus.WAITING_PAYMENT_METHOD,
|
|
49
|
+
[OrderState.TO_SIGN]: OrderStatus.WAITING_SIGNATURE,
|
|
47
50
|
};
|
|
48
51
|
|
|
49
52
|
if (order.state in orderStatusMap) {
|
|
@@ -62,18 +65,8 @@ export class OrderHelper {
|
|
|
62
65
|
return orders.find(filter);
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*/
|
|
68
|
-
static orderNeedsSignature(
|
|
69
|
-
order: Order | NestedCourseOrder,
|
|
70
|
-
contractDefinition?: ContractDefinition,
|
|
71
|
-
) {
|
|
72
|
-
return (
|
|
73
|
-
order?.state === OrderState.VALIDATED &&
|
|
74
|
-
contractDefinition &&
|
|
75
|
-
!(order.contract && order.contract.student_signed_on)
|
|
76
|
-
);
|
|
68
|
+
static orderNeedsSignature(order: Order | NestedCourseOrder) {
|
|
69
|
+
return [OrderState.TO_SIGN, OrderState.SIGNING].includes(order.state);
|
|
77
70
|
}
|
|
78
71
|
|
|
79
72
|
/**
|
|
@@ -81,10 +74,25 @@ export class OrderHelper {
|
|
|
81
74
|
*/
|
|
82
75
|
static orderNeedsCounterSignature(order: Order | NestedCourseOrder) {
|
|
83
76
|
return (
|
|
84
|
-
order
|
|
77
|
+
ACTIVE_ORDER_STATES.includes(order.state) &&
|
|
85
78
|
order.contract &&
|
|
86
79
|
order.contract.student_signed_on &&
|
|
87
80
|
!order.contract.organization_signed_on
|
|
88
81
|
);
|
|
89
82
|
}
|
|
83
|
+
|
|
84
|
+
static allowEnrollment(order?: Order | NestedCourseOrder | OrderEnrollment) {
|
|
85
|
+
if (!order) return false;
|
|
86
|
+
return ENROLLABLE_ORDER_STATES.includes(order.state);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static isActive(order?: Order | NestedCourseOrder | OrderEnrollment) {
|
|
90
|
+
if (!order) return false;
|
|
91
|
+
return ACTIVE_ORDER_STATES.includes(order.state);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static isPurchasable(order?: Order | NestedCourseOrder | OrderEnrollment) {
|
|
95
|
+
if (!order) return true;
|
|
96
|
+
return PURCHASABLE_ORDER_STATES.includes(order.state);
|
|
97
|
+
}
|
|
90
98
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test suite for the helper `PaymentScheduleHelper`.
|
|
3
|
+
*/
|
|
4
|
+
import PaymentScheduleHelper from 'utils/PaymentScheduleHelper/index';
|
|
5
|
+
import { PaymentInstallmentFactory } from 'utils/test/factories/joanie';
|
|
6
|
+
import { PaymentScheduleState } from 'types/Joanie';
|
|
7
|
+
|
|
8
|
+
describe('PaymentScheduleHelper', () => {
|
|
9
|
+
describe('getFailedInstallment', () => {
|
|
10
|
+
it('should return undefined if payment_schedule is undefined', () => {
|
|
11
|
+
const foundInstallment = PaymentScheduleHelper.getFailedInstallment(undefined);
|
|
12
|
+
|
|
13
|
+
expect(foundInstallment).toBeUndefined();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return undefined if payment schedule does not have a failed installment', () => {
|
|
17
|
+
const schedule = PaymentInstallmentFactory({ state: PaymentScheduleState.PENDING }).many(3);
|
|
18
|
+
const foundInstallment = PaymentScheduleHelper.getFailedInstallment(schedule);
|
|
19
|
+
|
|
20
|
+
expect(foundInstallment).toBeUndefined();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should return the older failed installment', () => {
|
|
24
|
+
const schedule = [
|
|
25
|
+
PaymentInstallmentFactory({
|
|
26
|
+
state: PaymentScheduleState.PAID,
|
|
27
|
+
due_date: '2024-06-21',
|
|
28
|
+
}).one(),
|
|
29
|
+
PaymentInstallmentFactory({
|
|
30
|
+
state: PaymentScheduleState.REFUSED,
|
|
31
|
+
due_date: '2024-08-20',
|
|
32
|
+
}).one(),
|
|
33
|
+
PaymentInstallmentFactory({
|
|
34
|
+
state: PaymentScheduleState.REFUSED,
|
|
35
|
+
due_date: '2024-07-20',
|
|
36
|
+
}).one(),
|
|
37
|
+
];
|
|
38
|
+
const foundInstallment = PaymentScheduleHelper.getFailedInstallment(schedule);
|
|
39
|
+
|
|
40
|
+
expect(foundInstallment?.due_date).toBe(schedule[2].due_date);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('getPendingInstallment', () => {
|
|
45
|
+
it('should return undefined if payment_schedule is undefined', () => {
|
|
46
|
+
const foundInstallment = PaymentScheduleHelper.getPendingInstallment(undefined);
|
|
47
|
+
|
|
48
|
+
expect(foundInstallment).toBeUndefined();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return undefined if payment schedule does not have a pending installment', () => {
|
|
52
|
+
const schedule = PaymentInstallmentFactory({ state: PaymentScheduleState.PAID }).many(3);
|
|
53
|
+
const foundInstallment = PaymentScheduleHelper.getPendingInstallment(schedule);
|
|
54
|
+
|
|
55
|
+
expect(foundInstallment).toBeUndefined();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should return the older pending installment', () => {
|
|
59
|
+
const schedule = [
|
|
60
|
+
PaymentInstallmentFactory({
|
|
61
|
+
state: PaymentScheduleState.PAID,
|
|
62
|
+
due_date: '2024-06-21',
|
|
63
|
+
}).one(),
|
|
64
|
+
PaymentInstallmentFactory({
|
|
65
|
+
state: PaymentScheduleState.PENDING,
|
|
66
|
+
due_date: '2024-08-20',
|
|
67
|
+
}).one(),
|
|
68
|
+
PaymentInstallmentFactory({
|
|
69
|
+
state: PaymentScheduleState.PENDING,
|
|
70
|
+
due_date: '2024-07-20',
|
|
71
|
+
}).one(),
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
const foundInstallment = PaymentScheduleHelper.getPendingInstallment(schedule);
|
|
75
|
+
expect(foundInstallment?.due_date).toBe(schedule[2].due_date);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PaymentInstallment, PaymentSchedule, PaymentScheduleState } from 'types/Joanie';
|
|
2
|
+
import { Maybe } from 'types/utils';
|
|
3
|
+
|
|
4
|
+
export default class PaymentScheduleHelper {
|
|
5
|
+
static #sortByDueDateAsc(a: PaymentInstallment, b: PaymentInstallment) {
|
|
6
|
+
const dateA = new Date(a.due_date).getTime();
|
|
7
|
+
const dateB = new Date(b.due_date).getTime();
|
|
8
|
+
return dateA - dateB;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static #getInstallmentByState(
|
|
12
|
+
payment_schedule: Maybe<PaymentSchedule>,
|
|
13
|
+
state: PaymentScheduleState,
|
|
14
|
+
) {
|
|
15
|
+
if (!payment_schedule) return undefined;
|
|
16
|
+
|
|
17
|
+
const installments = [...payment_schedule];
|
|
18
|
+
return installments
|
|
19
|
+
?.sort(this.#sortByDueDateAsc)
|
|
20
|
+
.find((installment) => installment.state === state);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static getFailedInstallment(payment_schedule: Maybe<PaymentSchedule>) {
|
|
24
|
+
return this.#getInstallmentByState(payment_schedule, PaymentScheduleState.REFUSED);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static getPendingInstallment(payment_schedule: Maybe<PaymentSchedule>) {
|
|
28
|
+
return this.#getInstallmentByState(payment_schedule, PaymentScheduleState.PENDING);
|
|
29
|
+
}
|
|
30
|
+
}
|