@mychoice/mychoice-sdk-modules 2.2.30 → 2.2.31
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/cjs/index.js +111 -66
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +111 -66
- package/dist/esm/index.js.map +1 -1
- package/package.json +4 -4
package/dist/cjs/index.js
CHANGED
|
@@ -226,10 +226,20 @@ const BlockVehLinks = () => {
|
|
|
226
226
|
payload: { driverIndex, vehicleIndex },
|
|
227
227
|
});
|
|
228
228
|
};
|
|
229
|
+
const primaryOf = (vehicleIndex) => vehlinks.find((l) => l.vehicleIndex === vehicleIndex && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn)?.driverIndex ?? -1;
|
|
230
|
+
const getTwoDriverSystemAllocation = () => {
|
|
231
|
+
if (drivers.length !== 2 || vehicles.length !== 3)
|
|
232
|
+
return { driverIndex: -1, vehicleIndex: -1 };
|
|
233
|
+
const firstTwo = [primaryOf(0), primaryOf(1)];
|
|
234
|
+
if (firstTwo.some((driverIndex) => driverIndex < 0) || new Set(firstTwo).size === drivers.length) {
|
|
235
|
+
return { driverIndex: -1, vehicleIndex: -1 };
|
|
236
|
+
}
|
|
237
|
+
const driverIndex = drivers.findIndex((_driver, index) => !firstTwo.includes(index));
|
|
238
|
+
return { driverIndex, vehicleIndex: 2 };
|
|
239
|
+
};
|
|
229
240
|
React.useEffect(() => {
|
|
230
241
|
if (!equalCounts || drivers.length <= 1)
|
|
231
242
|
return;
|
|
232
|
-
const primaryOf = (vehicleIndex) => vehlinks.find((l) => l.vehicleIndex === vehicleIndex && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn)?.driverIndex ?? -1;
|
|
233
243
|
const askedDrivers = new Set();
|
|
234
244
|
for (let vehicleIndex = 0; vehicleIndex < askedVehicleCount; vehicleIndex += 1) {
|
|
235
245
|
const po = primaryOf(vehicleIndex);
|
|
@@ -247,6 +257,40 @@ const BlockVehLinks = () => {
|
|
|
247
257
|
return;
|
|
248
258
|
assignPrimary(remainingDriver, lastVehicleIndex);
|
|
249
259
|
}, [equalCounts, askedVehicleCount, vehlinks, drivers, vehicles]);
|
|
260
|
+
React.useEffect(() => {
|
|
261
|
+
const { driverIndex, vehicleIndex } = getTwoDriverSystemAllocation();
|
|
262
|
+
if (driverIndex >= 0 && vehicleIndex >= 0 && primaryOf(vehicleIndex) !== driverIndex) {
|
|
263
|
+
assignPrimary(driverIndex, vehicleIndex);
|
|
264
|
+
}
|
|
265
|
+
}, [vehlinks, drivers, vehicles]);
|
|
266
|
+
React.useEffect(() => {
|
|
267
|
+
if (vehicles.length <= drivers.length || drivers.length <= 1)
|
|
268
|
+
return;
|
|
269
|
+
for (let vehicleIndex = 0; vehicleIndex < vehicles.length; vehicleIndex += 1) {
|
|
270
|
+
if (primaryOf(vehicleIndex) < 0)
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const usedDrivers = new Set(vehicles.map((_, vehicleIndex) => primaryOf(vehicleIndex)));
|
|
274
|
+
const unusedDriver = drivers.findIndex((_, driverIndex) => !usedDrivers.has(driverIndex));
|
|
275
|
+
if (unusedDriver < 0)
|
|
276
|
+
return;
|
|
277
|
+
// Target the last vehicle whose PO is a duplicate, so we never strand another driver.
|
|
278
|
+
const poCounts = new Map();
|
|
279
|
+
vehicles.forEach((_v, vehicleIndex) => {
|
|
280
|
+
const po = primaryOf(vehicleIndex);
|
|
281
|
+
poCounts.set(po, (poCounts.get(po) ?? 0) + 1);
|
|
282
|
+
});
|
|
283
|
+
let target = -1;
|
|
284
|
+
for (let vehicleIndex = vehicles.length - 1; vehicleIndex >= 0; vehicleIndex -= 1) {
|
|
285
|
+
if ((poCounts.get(primaryOf(vehicleIndex)) ?? 0) > 1) {
|
|
286
|
+
target = vehicleIndex;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (target < 0)
|
|
291
|
+
return;
|
|
292
|
+
assignPrimary(unusedDriver, target);
|
|
293
|
+
}, [vehlinks, drivers, vehicles]);
|
|
250
294
|
if (drivers.length <= 1) {
|
|
251
295
|
return null;
|
|
252
296
|
}
|
|
@@ -270,6 +314,7 @@ const BlockVehLinks = () => {
|
|
|
270
314
|
.map((driver, index) => ({ driver, index }))
|
|
271
315
|
.filter(({ index }) => !primaryDriverIndices.includes(index));
|
|
272
316
|
const vehiclesToAsk = vehicles.slice(0, askedVehicleCount);
|
|
317
|
+
const { vehicleIndex: systemAllocatedVehicleIndex } = getTwoDriverSystemAllocation();
|
|
273
318
|
const primaryQuestionsAnswered = vehiclesToAsk.every((_vehicle, vehicleIndex) => vehlinks.some((l) => l.vehicleIndex === vehicleIndex
|
|
274
319
|
&& l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn
|
|
275
320
|
&& l.driverIndex >= 0));
|
|
@@ -279,6 +324,8 @@ const BlockVehLinks = () => {
|
|
|
279
324
|
&& primaryQuestionsAnswered
|
|
280
325
|
&& primaryQuestionsAreUnique;
|
|
281
326
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(LabelFormBox, { title: "Since there are multiple drivers in this quote, please tell us who drives which vehicle the most. Please provide an answer that most accurately describes your situation." }), vehiclesToAsk.map((vehicle, vehicleIndex) => {
|
|
327
|
+
if (vehicleIndex === systemAllocatedVehicleIndex)
|
|
328
|
+
return null;
|
|
282
329
|
const { year, make, model } = vehicle;
|
|
283
330
|
const selectedPrimary = vehlinks.find((l) => l.vehicleIndex === vehicleIndex && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
|
|
284
331
|
const isPrimaryAnswered = selectedPrimary !== undefined && selectedPrimary.driverIndex >= 0;
|
|
@@ -287,8 +334,7 @@ const BlockVehLinks = () => {
|
|
|
287
334
|
&& l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn
|
|
288
335
|
&& l.driverIndex >= 0)
|
|
289
336
|
.map((l) => l.driverIndex));
|
|
290
|
-
const
|
|
291
|
-
const canRepeatPrimary = vehicles.length > drivers.length && allDriversHavePrimary;
|
|
337
|
+
const canRepeatPrimary = vehicles.length > drivers.length;
|
|
292
338
|
const primaryOptions = drivers
|
|
293
339
|
.map((driver, driverIndex) => ({ name: driver.firstName, value: driverIndex }))
|
|
294
340
|
.filter(({ value }) => canRepeatPrimary
|
|
@@ -1232,6 +1278,10 @@ const SectionDriverInfo = () => {
|
|
|
1232
1278
|
month: birthMonth,
|
|
1233
1279
|
year: birthYear,
|
|
1234
1280
|
};
|
|
1281
|
+
const policyEffectiveDate = discountState.policyStartYear && discountState.policyStartMonth
|
|
1282
|
+
&& discountState.policyStartDay
|
|
1283
|
+
? `${discountState.policyStartYear}-${discountState.policyStartMonth}-${discountState.policyStartDay}`
|
|
1284
|
+
: discountState.policyStart;
|
|
1235
1285
|
React.useEffect(() => {
|
|
1236
1286
|
if (discountState.quoterInfo.firstName !== driverState.items[0].firstName) {
|
|
1237
1287
|
dispatchDiscountState({
|
|
@@ -1256,19 +1306,19 @@ const SectionDriverInfo = () => {
|
|
|
1256
1306
|
if (dateType === mychoiceSdkComponents.DateTypes.Day) {
|
|
1257
1307
|
dispatchDriverInfoState({
|
|
1258
1308
|
type: mychoiceSdkStore.StoreFormCarDriverInfoActionTypes.FormCarDriverBirthDaySelect,
|
|
1259
|
-
payload: { birthDay: value, config: configState },
|
|
1309
|
+
payload: { birthDay: value, config: configState, appType },
|
|
1260
1310
|
});
|
|
1261
1311
|
}
|
|
1262
1312
|
if (dateType === mychoiceSdkComponents.DateTypes.Month) {
|
|
1263
1313
|
dispatchDriverInfoState({
|
|
1264
1314
|
type: mychoiceSdkStore.StoreFormCarDriverInfoActionTypes.FormCarDriverBirthMonthSelect,
|
|
1265
|
-
payload: { birthMonth: value, config: configState },
|
|
1315
|
+
payload: { birthMonth: value, config: configState, appType },
|
|
1266
1316
|
});
|
|
1267
1317
|
}
|
|
1268
1318
|
if (dateType === mychoiceSdkComponents.DateTypes.Year) {
|
|
1269
1319
|
dispatchDriverInfoState({
|
|
1270
1320
|
type: mychoiceSdkStore.StoreFormCarDriverInfoActionTypes.FormCarDriverBirthYearSelect,
|
|
1271
|
-
payload: { birthYear: value, config: configState },
|
|
1321
|
+
payload: { birthYear: value, config: configState, appType },
|
|
1272
1322
|
});
|
|
1273
1323
|
}
|
|
1274
1324
|
};
|
|
@@ -1290,11 +1340,13 @@ const SectionDriverInfo = () => {
|
|
|
1290
1340
|
payload: { applicantRelationship: value },
|
|
1291
1341
|
});
|
|
1292
1342
|
};
|
|
1293
|
-
return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [mychoiceCls && jsxRuntime.jsx("h2", { className: "section-title", children: "Time for a micro autobiography \u2013 tell us about you." }), jsxRuntime.jsx(InputFormBox, { name: "firstName", title: "What is your legal first name?", onChange: handleFirstNameChange, defaultValue: firstName, description: "The name on a policy should match the one on your official driver\u2019s licence.", placeholder: "Driver First Name", error: !firstName && driverState.inValidation, errorMessage: getErrorMessage(firstName, driverState.inValidation) }), jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.maritalStatusOptions, name: "maritalStatus", onChange: handleMaritalStatusChange, defaultValue: getSelectedOption(mychoiceSdkComponents.maritalStatusOptions, maritalStatus), title: "What is your marital status?", placeholder: "Select from the list", description: "If you are married, it may have a positive effect on your car insurance premiums and coverage. In some provinces, the law now considers same-sex partners to have a common-law marriage, so you will need to check your local regulations. If you are divorced or widowed, select single.", autoSelectIfValueIsOutOfOptions: false, error: !maritalStatus && driverState.inValidation, errorMessage: getErrorMessage(maritalStatus, driverState.inValidation) }), jsxRuntime.jsx(DateSelectFormBox, { name: "dateOfBirth", dateNames: ['birthYear', 'birthMonth', 'birthDay'], onDateChange: handleDateOfBirthChange, defaultValue: defaultDateOfBirth, title: "When were you born?", description: "Insurers generally consider your age and driving experience when calculating a vehicle insurance quote. The safest drivers are often those who are over thirty, but each insurer will have their own parameters. The youngest and oldest drivers have the greatest liability reflected in their premiums due to inexperience or health complications, respectively.", errorMessage: getDateErrorMessage([birthDay || '', birthMonth || '', birthYear || ''], driverState.inValidation), error: driverState.inValidation, maxDate: mychoiceSdkComponents.subYearsFromDate(
|
|
1343
|
+
return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [mychoiceCls && jsxRuntime.jsx("h2", { className: "section-title", children: "Time for a micro autobiography \u2013 tell us about you." }), jsxRuntime.jsx(InputFormBox, { name: "firstName", title: "What is your legal first name?", onChange: handleFirstNameChange, defaultValue: firstName, description: "The name on a policy should match the one on your official driver\u2019s licence.", placeholder: "Driver First Name", error: !firstName && driverState.inValidation, errorMessage: getErrorMessage(firstName, driverState.inValidation) }), jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.maritalStatusOptions, name: "maritalStatus", onChange: handleMaritalStatusChange, defaultValue: getSelectedOption(mychoiceSdkComponents.maritalStatusOptions, maritalStatus), title: "What is your marital status?", placeholder: "Select from the list", description: "If you are married, it may have a positive effect on your car insurance premiums and coverage. In some provinces, the law now considers same-sex partners to have a common-law marriage, so you will need to check your local regulations. If you are divorced or widowed, select single.", autoSelectIfValueIsOutOfOptions: false, error: !maritalStatus && driverState.inValidation, errorMessage: getErrorMessage(maritalStatus, driverState.inValidation) }), jsxRuntime.jsx(DateSelectFormBox, { name: "dateOfBirth", dateNames: ['birthYear', 'birthMonth', 'birthDay'], onDateChange: handleDateOfBirthChange, defaultValue: defaultDateOfBirth, title: "When were you born?", description: "Insurers generally consider your age and driving experience when calculating a vehicle insurance quote. The safest drivers are often those who are over thirty, but each insurer will have their own parameters. The youngest and oldest drivers have the greatest liability reflected in their premiums due to inexperience or health complications, respectively.", errorMessage: getDateErrorMessage([birthDay || '', birthMonth || '', birthYear || ''], driverState.inValidation), error: driverState.inValidation, maxDate: mychoiceSdkComponents.subYearsFromDate(policyEffectiveDate, configState.licenceConfig.minLicenceAge || 16), isDay: true }), jsxRuntime.jsx(SwitchButtonBox, { name: "occupation", items: mychoiceSdkComponents.occupationOptions, onChange: handleOccupationChange, defaultValue: getSelectedOption(mychoiceSdkComponents.occupationOptions, occupation), title: "Are you currently employed or unemployed?", description: "Your employment status reflects your driving frequency, and insurers consider this in your policy." }), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.genderOptions, onChange: handleGenderChange, name: "gender", defaultValue: getSelectedOption(mychoiceSdkComponents.genderOptions, gender), title: "What is your gender?", description: "The gender on the policy should match your official driver\u2019s licence. Some insurers analyze a driver's sex when creating a policy. Men are typically considered higher risk than female drivers, but the statistics supporting this idea vary from province to province. On average, men and women pay roughly the same for insurance, though." }), driverState.activeIndex > 0 && (jsxRuntime.jsx(SelectFormBox, { options: mychoiceSdkComponents.applicantRelationshipOptions, name: "applicantRelationship", onChange: handleApplicantRelationshipChange, defaultValue: getSelectedOption(mychoiceSdkComponents.applicantRelationshipOptions, applicantRelationship), title: "Relationship to applicant", placeholder: "Select...", autoSelectIfValueIsOutOfOptions: false, error: !applicantRelationship && driverState.inValidation, errorMessage: getErrorMessage(applicantRelationship, driverState.inValidation) }))] }));
|
|
1294
1344
|
};
|
|
1295
1345
|
|
|
1296
1346
|
// Max months between consecutive Ontario GDL licence classes (spec 1-2 e/f)
|
|
1297
1347
|
const ON_MAX_MONTHS_BETWEEN_CLASSES = 60;
|
|
1348
|
+
const ON_MIN_MONTHS_G1_TO_G2 = 8;
|
|
1349
|
+
const ON_MIN_MONTHS_G1_TO_G = 20;
|
|
1298
1350
|
const SectionDriverLicence = () => {
|
|
1299
1351
|
const { appConfigState: { appType }, } = mychoiceSdkStore.useStoreAppConfig();
|
|
1300
1352
|
const [driverEducation, setDriverEducation] = React.useState(false);
|
|
@@ -1320,7 +1372,11 @@ const SectionDriverLicence = () => {
|
|
|
1320
1372
|
? (!!ontarioQ1Date && mychoiceSdkComponents.checkDateIsSpecial(ontarioQ1Date, configState.minDates.g.specialDate))
|
|
1321
1373
|
: mychoiceSdkComponents.checkDateIsSpecial(defaultMinDate, configState.minDates.g.specialDate);
|
|
1322
1374
|
const driverName = firstName || driverNameDefault;
|
|
1375
|
+
const { policyStart, policyStartYear, policyStartMonth, policyStartDay, } = discountState;
|
|
1323
1376
|
const today = mychoiceSdkComponents.getFormattedDate('', 'yyyy-MM-dd');
|
|
1377
|
+
const policyEffectiveDate = policyStartYear && policyStartMonth && policyStartDay
|
|
1378
|
+
? `${policyStartYear}-${policyStartMonth}-${policyStartDay}`
|
|
1379
|
+
: policyStart || today;
|
|
1324
1380
|
const { g, g1, g2, minLicenceAge } = configState.licenceConfig;
|
|
1325
1381
|
const licenceTypeOptions = [
|
|
1326
1382
|
{ value: g.name, name: g.title },
|
|
@@ -1356,36 +1412,6 @@ const SectionDriverLicence = () => {
|
|
|
1356
1412
|
}
|
|
1357
1413
|
}
|
|
1358
1414
|
}, [g2LicenceYear, g2LicenceMonth, licenceType, useOntarioFlow]);
|
|
1359
|
-
// If the user picks their birth month in their 16th year and birthDay > 1,
|
|
1360
|
-
// selecting that month would imply a date before their actual birthday (since dates are assumed
|
|
1361
|
-
// as the 1st). Auto-advance the Q1 month to birthMonth + 1.
|
|
1362
|
-
React.useEffect(() => {
|
|
1363
|
-
if (!useOntarioFlow || !birthDate || !ontarioQ1Year || !ontarioQ1Month)
|
|
1364
|
-
return;
|
|
1365
|
-
const birthDayNum = parseInt(birthDay || '1', 10);
|
|
1366
|
-
if (birthDayNum <= 1)
|
|
1367
|
-
return;
|
|
1368
|
-
const birthYearNum = parseInt(birthYear || '0', 10);
|
|
1369
|
-
if (parseInt(ontarioQ1Year, 10) !== birthYearNum + 16 || ontarioQ1Month !== birthMonth)
|
|
1370
|
-
return;
|
|
1371
|
-
const q1SlotForCorrection = mychoiceSdkComponents.DriverLicenceTypes.G1;
|
|
1372
|
-
let correctedMonth = parseInt(birthMonth || '1', 10) + 1;
|
|
1373
|
-
let correctedYear = birthYearNum + 16;
|
|
1374
|
-
if (correctedMonth > 12) {
|
|
1375
|
-
correctedMonth = 1;
|
|
1376
|
-
correctedYear += 1;
|
|
1377
|
-
}
|
|
1378
|
-
dispatchDriverLicenceState({
|
|
1379
|
-
type: mychoiceSdkStore.StoreFormCarDriverLicenceActionTypes.FormCarDriverLicenceMonthSelect,
|
|
1380
|
-
payload: { value: String(correctedMonth).padStart(2, '0'), config: configState, type: q1SlotForCorrection },
|
|
1381
|
-
});
|
|
1382
|
-
if (correctedYear !== birthYearNum + 16) {
|
|
1383
|
-
dispatchDriverLicenceState({
|
|
1384
|
-
type: mychoiceSdkStore.StoreFormCarDriverLicenceActionTypes.FormCarDriverLicenceYearSelect,
|
|
1385
|
-
payload: { value: String(correctedYear), config: configState, type: q1SlotForCorrection },
|
|
1386
|
-
});
|
|
1387
|
-
}
|
|
1388
|
-
}, [ontarioQ1Year, ontarioQ1Month]);
|
|
1389
1415
|
// ── helpers ────────────────────────────────────────────────
|
|
1390
1416
|
const getMinDate = (type) => {
|
|
1391
1417
|
switch (type) {
|
|
@@ -1426,11 +1452,11 @@ const SectionDriverLicence = () => {
|
|
|
1426
1452
|
});
|
|
1427
1453
|
// Build a YYYY-MM-01 string from stored year/month, returns '' if either missing
|
|
1428
1454
|
const toDate = (year, month) => (year && month ? `${year}-${month}-01` : '');
|
|
1429
|
-
const validateLicenceDate = (year, month, minDate) => {
|
|
1430
|
-
const dateStr = toDate(year, month);
|
|
1455
|
+
const validateLicenceDate = (year, month, minDate, dateOverride) => {
|
|
1456
|
+
const dateStr = dateOverride || toDate(year, month);
|
|
1431
1457
|
if (!dateStr)
|
|
1432
1458
|
return '';
|
|
1433
|
-
if (mychoiceSdkComponents.compareDates(dateStr,
|
|
1459
|
+
if (mychoiceSdkComponents.compareDates(dateStr, policyEffectiveDate) > 0)
|
|
1434
1460
|
return 'License dates cannot be in the future';
|
|
1435
1461
|
if (minDate && mychoiceSdkComponents.compareDates(dateStr, minDate) < 0) {
|
|
1436
1462
|
return 'This license date must be equal or later than the prior license date. Please check your selection';
|
|
@@ -1449,11 +1475,11 @@ const SectionDriverLicence = () => {
|
|
|
1449
1475
|
return '';
|
|
1450
1476
|
};
|
|
1451
1477
|
// In the Ontario flow, firstLicenceAge is never entered, so gOneMin is stale/empty.
|
|
1452
|
-
// Compute
|
|
1478
|
+
// Compute the minimum from DOB + 16 and validate it against the policy effective date.
|
|
1453
1479
|
const getG1MinDate = () => {
|
|
1454
1480
|
if (useOntarioFlow && birthDate) {
|
|
1455
1481
|
const computed = mychoiceSdkComponents.addYearsToDate(birthDate, 16);
|
|
1456
|
-
return mychoiceSdkComponents.compareDates(computed,
|
|
1482
|
+
return mychoiceSdkComponents.compareDates(computed, policyEffectiveDate) > 0 ? policyEffectiveDate : computed;
|
|
1457
1483
|
}
|
|
1458
1484
|
return gOneMin;
|
|
1459
1485
|
};
|
|
@@ -1531,18 +1557,30 @@ const SectionDriverLicence = () => {
|
|
|
1531
1557
|
const q1Year = getLicenceYear(q1SlotType);
|
|
1532
1558
|
const q1Month = getLicenceMonth(q1SlotType);
|
|
1533
1559
|
const q1Date = toDate(q1Year, q1Month);
|
|
1560
|
+
const g2Date = toDate(g2LicenceYear, g2LicenceMonth);
|
|
1561
|
+
const gDate = toDate(gLicenceYear, gLicenceMonth);
|
|
1562
|
+
// Thresholds per the licensing flow: G1 < 5 years (4y11m = 59 months); G2/G < 3 years (2y11m = 35 months).
|
|
1563
|
+
const q1BirthdayDate = birthDate
|
|
1564
|
+
&& q1Year === String(Number(birthYear) + 16)
|
|
1565
|
+
&& q1Month === birthMonth
|
|
1566
|
+
? `${q1Year}-${birthMonth}-${birthDay}`
|
|
1567
|
+
: q1Date;
|
|
1568
|
+
const q1MonthsFromEffective = q1BirthdayDate
|
|
1569
|
+
? mychoiceSdkComponents.getDifferenceInMonths(policyEffectiveDate, q1BirthdayDate)
|
|
1570
|
+
: Infinity;
|
|
1571
|
+
// A G2 requires at least 8 months after G1; a G requires another 12 months.
|
|
1572
|
+
const canHaveG2 = !!q1Date && q1MonthsFromEffective >= ON_MIN_MONTHS_G1_TO_G2;
|
|
1573
|
+
const canHaveG = !!q1Date && q1MonthsFromEffective >= ON_MIN_MONTHS_G1_TO_G;
|
|
1534
1574
|
// ── path booleans ──
|
|
1535
|
-
const
|
|
1575
|
+
const showG2Question = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1 && canHaveG2;
|
|
1576
|
+
const showG2Date = showG2Question && receivedG2 === true;
|
|
1536
1577
|
// G question shows after G2 date entered (G1→G2 path) OR after No-G2 answer (G1→No G2 path)
|
|
1537
1578
|
const showGQuestionAfterG1 = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1
|
|
1579
|
+
&& canHaveG
|
|
1538
1580
|
&& (receivedG2 === false || showG2Date);
|
|
1581
|
+
const showGQuestionAfterG2 = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2 && canHaveG;
|
|
1539
1582
|
const showGDateAfterG1 = showGQuestionAfterG1 && receivedG === true;
|
|
1540
|
-
const showGDateAfterG2 =
|
|
1541
|
-
const g2Date = toDate(g2LicenceYear, g2LicenceMonth);
|
|
1542
|
-
const gDate = toDate(gLicenceYear, gLicenceMonth);
|
|
1543
|
-
// Thresholds per the licensing flow: G1 < 5 years (4y11m = 59 months); G2/G < 3 years (2y11m = 35 months).
|
|
1544
|
-
const policyStart = discountState.policyStart || today;
|
|
1545
|
-
const q1MonthsFromEffective = q1Date ? mychoiceSdkComponents.getDifferenceInMonths(policyStart, q1Date) : Infinity;
|
|
1583
|
+
const showGDateAfterG2 = showGQuestionAfterG2 && receivedG === true;
|
|
1546
1584
|
// G1 branch: ask once, based on the first licence date (< 5 years / 60 months).
|
|
1547
1585
|
const showDtcG1Only = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1
|
|
1548
1586
|
&& !!q1Date
|
|
@@ -1558,39 +1596,46 @@ const SectionDriverLicence = () => {
|
|
|
1558
1596
|
// ── Validation error messages ──
|
|
1559
1597
|
const q1MinDate = getG1MinDate();
|
|
1560
1598
|
const q1ChronoError = driverState.inValidation
|
|
1561
|
-
? validateLicenceDate(q1Year, q1Month, q1MinDate)
|
|
1599
|
+
? validateLicenceDate(q1Year, q1Month, q1MinDate, q1BirthdayDate)
|
|
1562
1600
|
: '';
|
|
1563
|
-
const q1FutureError =
|
|
1601
|
+
const q1FutureError = q1BirthdayDate && mychoiceSdkComponents.compareDates(q1BirthdayDate, policyEffectiveDate) > 0
|
|
1564
1602
|
? 'License dates cannot be in the future' : '';
|
|
1565
1603
|
const q1Error = q1FutureError || q1ChronoError || getDateErrorMessage(['01', q1Month, q1Year], driverState.inValidation);
|
|
1566
1604
|
const g2ChronoError = driverState.inValidation
|
|
1567
|
-
? validateLicenceDate(g2LicenceYear, g2LicenceMonth,
|
|
1605
|
+
? validateLicenceDate(g2LicenceYear, g2LicenceMonth, q1BirthdayDate)
|
|
1568
1606
|
: '';
|
|
1569
|
-
const g260MonthError = validate60Months(
|
|
1570
|
-
const g2FutureError = g2Date && mychoiceSdkComponents.compareDates(g2Date,
|
|
1607
|
+
const g260MonthError = validate60Months(q1BirthdayDate?.slice(0, 4), q1BirthdayDate?.slice(5, 7), g2LicenceYear, g2LicenceMonth);
|
|
1608
|
+
const g2FutureError = g2Date && mychoiceSdkComponents.compareDates(g2Date, policyEffectiveDate) > 0 ? 'License dates cannot be in the future' : '';
|
|
1571
1609
|
const g2Error = g2FutureError || g260MonthError || g2ChronoError || getDateErrorMessage(['01', g2LicenceMonth, g2LicenceYear], driverState.inValidation);
|
|
1572
1610
|
// G preceding date: G2 date if on G1→G2→G path, else Q1 date
|
|
1573
|
-
const gPrecedingDate = showGDateAfterG1 && showG2Date ? g2Date :
|
|
1611
|
+
const gPrecedingDate = showGDateAfterG1 && showG2Date ? g2Date : q1BirthdayDate;
|
|
1574
1612
|
const gChronoError = driverState.inValidation
|
|
1575
1613
|
? validateLicenceDate(gLicenceYear, gLicenceMonth, gPrecedingDate)
|
|
1576
1614
|
: '';
|
|
1577
|
-
const g60MonthError = validate60Months(
|
|
1578
|
-
const gFutureError = gDate && mychoiceSdkComponents.compareDates(gDate,
|
|
1615
|
+
const g60MonthError = validate60Months(q1BirthdayDate?.slice(0, 4), q1BirthdayDate?.slice(5, 7), gLicenceYear, gLicenceMonth);
|
|
1616
|
+
const gFutureError = gDate && mychoiceSdkComponents.compareDates(gDate, policyEffectiveDate) > 0 ? 'License dates cannot be in the future' : '';
|
|
1579
1617
|
const gError = gFutureError || g60MonthError || gChronoError || getDateErrorMessage(['01', gLicenceMonth, gLicenceYear], driverState.inValidation);
|
|
1580
|
-
// ── Min dates (
|
|
1581
|
-
const g2MinRaw =
|
|
1582
|
-
const g2MinDate = mychoiceSdkComponents.compareDates(g2MinRaw,
|
|
1618
|
+
// ── Min dates (capped to the policy effective date so a future policy remains selectable) ──
|
|
1619
|
+
const g2MinRaw = q1BirthdayDate && mychoiceSdkComponents.compareDates(q1BirthdayDate, gTwoMin) > 0 ? q1BirthdayDate : gTwoMin;
|
|
1620
|
+
const g2MinDate = mychoiceSdkComponents.compareDates(g2MinRaw, policyEffectiveDate) > 0 ? policyEffectiveDate : g2MinRaw;
|
|
1583
1621
|
const gMinRaw = gPrecedingDate && mychoiceSdkComponents.compareDates(gPrecedingDate, gMin) > 0 ? gPrecedingDate : gMin;
|
|
1584
|
-
const gMinDate = mychoiceSdkComponents.compareDates(gMinRaw,
|
|
1622
|
+
const gMinDate = mychoiceSdkComponents.compareDates(gMinRaw, policyEffectiveDate) > 0 ? policyEffectiveDate : gMinRaw;
|
|
1623
|
+
const getMonthPickerMinDate = (minDate) => {
|
|
1624
|
+
if (!minDate || mychoiceSdkComponents.getFormattedDate(minDate, 'dd') === '01')
|
|
1625
|
+
return minDate;
|
|
1626
|
+
return mychoiceSdkComponents.addMonthsToDate(minDate, 1);
|
|
1627
|
+
};
|
|
1628
|
+
const g2PickerMinDate = getMonthPickerMinDate(g2MinDate);
|
|
1629
|
+
const gPickerMinDate = getMonthPickerMinDate(gMinDate);
|
|
1585
1630
|
const getMax60Date = (refDate) => {
|
|
1586
1631
|
if (!refDate)
|
|
1587
|
-
return
|
|
1632
|
+
return policyEffectiveDate;
|
|
1588
1633
|
const max60 = mychoiceSdkComponents.addMonthsToDate(refDate, ON_MAX_MONTHS_BETWEEN_CLASSES);
|
|
1589
|
-
return mychoiceSdkComponents.compareDates(
|
|
1634
|
+
return mychoiceSdkComponents.compareDates(policyEffectiveDate, max60) > 0 ? max60 : policyEffectiveDate;
|
|
1590
1635
|
};
|
|
1591
|
-
const g2MaxDate = getMax60Date(
|
|
1592
|
-
const gMaxDate = getMax60Date(
|
|
1593
|
-
return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [jsxRuntime.jsx(DateSelectFormBox, { name: "firstLicenceDate", dateNames: ['firstLicenceYear', 'firstLicenceMonth'], onDateChange: handleLicenceDateChange(q1SlotType), defaultValue: getDefaultLicenceDate(q1SlotType), title: `When did ${driverName} first receive their drivers license in Canada?`, description: "Select the year and month in which you received your first license to drive an automobile in Canada. This would include a beginners, intermediate or full license.", errorMessage: q1Error, error: driverState.inValidation, minDate: q1MinDate, maxDate:
|
|
1636
|
+
const g2MaxDate = getMax60Date(q1BirthdayDate);
|
|
1637
|
+
const gMaxDate = getMax60Date(q1BirthdayDate);
|
|
1638
|
+
return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [jsxRuntime.jsx(DateSelectFormBox, { name: "firstLicenceDate", dateNames: ['firstLicenceYear', 'firstLicenceMonth'], onDateChange: handleLicenceDateChange(q1SlotType), defaultValue: getDefaultLicenceDate(q1SlotType), title: `When did ${driverName} first receive their drivers license in Canada?`, description: "Select the year and month in which you received your first license to drive an automobile in Canada. This would include a beginners, intermediate or full license.", errorMessage: q1Error, error: driverState.inValidation, minDate: q1MinDate, maxDate: policyEffectiveDate, disabled: !birthDate }), q1Date && (jsxRuntime.jsx(SelectFormBox, { options: isOnlyG ? ontarioOnlyGOptions : ontarioFirstClassOptions, name: "firstLicenceClass", onChange: handleLicenceTypeChange, defaultValue: getSelectedOption(isOnlyG ? ontarioOnlyGOptions : ontarioFirstClassOptions, firstClass), title: "What class of license was it?", placeholder: "Select from the list", description: "Drivers licensed in Ontario under the graduated licensing program would select G1 Beginner. If the driver was licensed outside Ontario or granted an exception for having driving experience from another jurisdiction then select the license class they first received. Select class G Full or equivalent if the driver was licensed in Ontario before 1994 or was licensed in another province. G equivalent classes in Canada are class 5.", autoSelectIfValueIsOutOfOptions: false })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showDtcG1Only && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), showG2Question && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedG2Change, name: "receivedG2", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG2), title: `Did ${driverName} receive a G2 license?` })), showG2Date && (jsxRuntime.jsx(DateSelectFormBox, { name: "g2LicenceDate", dateNames: ['g2LicenceYear', 'g2LicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G2), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G2), title: `When did ${driverName} receive this G2 license?`, errorMessage: g2Error, error: driverState.inValidation, minDate: g2PickerMinDate, maxDate: g2MaxDate })), showGQuestionAfterG1 && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` })), showGDateAfterG1 && (jsxRuntime.jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gPickerMinDate, maxDate: gMaxDate }))] })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showDtcG2Only && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), showGQuestionAfterG2 && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleReceivedGChange, name: "receivedG", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, receivedG), title: `Did ${driverName} receive a G license?` })), showGDateAfterG2 && (jsxRuntime.jsx(DateSelectFormBox, { name: "gLicenceDate", dateNames: ['gLicenceYear', 'gLicenceMonth'], onDateChange: handleLicenceDateChange(mychoiceSdkComponents.DriverLicenceTypes.G), defaultValue: getDefaultLicenceDate(mychoiceSdkComponents.DriverLicenceTypes.G), title: `When did ${driverName} receive this G license?`, errorMessage: gError, error: driverState.inValidation, minDate: gPickerMinDate, maxDate: gMaxDate }))] })), firstClass === mychoiceSdkComponents.DriverLicenceTypes.G && !isOnlyG && showDtcGFull && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), isOnlyG && showDtcGFull && (jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handleTrainingChange, name: "passedDriverTraining", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, passedDriverTraining), title: `Has ${driverName} completed a gov't approved drivers education course within the past 3 years?` })), jsxRuntime.jsx(SwitchButtonBox, { items: mychoiceSdkComponents.yesNoOptions, onChange: handlePreviousLicenceChange, name: "previousLicence", defaultValue: getSelectedOption(mychoiceSdkComponents.yesNoOptions, previousLicence), title: `Has ${driverName} ever had a full license anywhere else in Canada or USA?`, description: "If you have driving experience outside Canada or the United States, it may lower your premium. Your insurer may require proof of insurance in these other locations or some proof of driving experience from the country you indicate (like a copy of a previous driver's licence)." })] }));
|
|
1594
1639
|
}
|
|
1595
1640
|
return (jsxRuntime.jsxs("div", { className: `form-section ${mychoiceCls}`, children: [jsxRuntime.jsx(InputFormBox, { name: "firstLicenceAge", title: getLicenceAgeTitle(), onChange: handleLicenceAgeChange, type: mychoiceSdkComponents.InputTypes.Number, defaultValue: firstLicenceAge, description: configState.toolTip.licenceAge, hintMessage: birthDate
|
|
1596
1641
|
? `${driverName} was licenced in ${Number(birthYear) + Number(firstLicenceAge)} - ${Number(birthYear) + Number(firstLicenceAge) + 1}`
|