@mychoice/mychoice-sdk-modules 2.2.29 → 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 CHANGED
@@ -218,40 +218,84 @@ const BlockVehLinks = () => {
218
218
  const { vehicleState: { items: vehicles } } = mychoiceSdkStore.useStoreFormCarVehicle();
219
219
  const { driverState: { items: drivers } } = mychoiceSdkStore.useStoreFormCarDriverBase();
220
220
  const { discountState: { vehlinks, occVehlinks, inValidation }, dispatchDiscountState } = mychoiceSdkStore.useStoreFormCarDiscount();
221
- // Spec: 2 drivers / 2 vehicles — ask only for Vehicle1; system assigns the other driver as PO on Vehicle2.
222
- const isTwoByTwo = drivers.length === 2 && vehicles.length === 2;
221
+ const equalCounts = drivers.length === vehicles.length;
222
+ const askedVehicleCount = equalCounts ? vehicles.length - 1 : vehicles.length;
223
223
  const assignPrimary = (driverIndex, vehicleIndex) => {
224
224
  dispatchDiscountState({
225
225
  type: mychoiceSdkStore.StoreFormCarDiscountActionTypes.FormCarDiscountVehlinkSelect,
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
- if (!isTwoByTwo)
241
+ if (!equalCounts || drivers.length <= 1)
242
+ return;
243
+ const askedDrivers = new Set();
244
+ for (let vehicleIndex = 0; vehicleIndex < askedVehicleCount; vehicleIndex += 1) {
245
+ const po = primaryOf(vehicleIndex);
246
+ if (po < 0)
247
+ return;
248
+ askedDrivers.add(po);
249
+ }
250
+ if (askedDrivers.size !== askedVehicleCount)
251
+ return;
252
+ const remainingDriver = drivers.findIndex((_, driverIndex) => !askedDrivers.has(driverIndex));
253
+ if (remainingDriver < 0)
231
254
  return;
232
- const v1 = vehlinks.find((l) => l.vehicleIndex === 0 && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
233
- if (!v1 || v1.driverIndex < 0)
255
+ const lastVehicleIndex = vehicles.length - 1;
256
+ if (primaryOf(lastVehicleIndex) === remainingDriver)
257
+ return;
258
+ assignPrimary(remainingDriver, lastVehicleIndex);
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)
234
268
  return;
235
- const otherDriverIndex = drivers.findIndex((_, index) => index !== v1.driverIndex);
236
- if (otherDriverIndex < 0)
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)
237
276
  return;
238
- const v2 = vehlinks.find((l) => l.vehicleIndex === 1 && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
239
- if (v2?.driverIndex === otherDriverIndex)
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)
240
291
  return;
241
- assignPrimary(otherDriverIndex, 1);
242
- }, [isTwoByTwo, vehlinks, drivers]);
292
+ assignPrimary(unusedDriver, target);
293
+ }, [vehlinks, drivers, vehicles]);
243
294
  if (drivers.length <= 1) {
244
295
  return null;
245
296
  }
246
297
  const handlePrimaryDriverChange = (vehicleIndex) => ({ value }) => {
247
- const driverIndex = Number(value);
248
- assignPrimary(driverIndex, vehicleIndex);
249
- if (isTwoByTwo && vehicleIndex === 0) {
250
- const otherDriverIndex = drivers.findIndex((_, index) => index !== driverIndex);
251
- if (otherDriverIndex >= 0) {
252
- assignPrimary(otherDriverIndex, 1);
253
- }
254
- }
298
+ assignPrimary(value === '' ? -1 : Number(value), vehicleIndex);
255
299
  };
256
300
  const handleOccDriverChange = (driverIndex) => ({ value }) => {
257
301
  dispatchDiscountState({
@@ -269,24 +313,34 @@ const BlockVehLinks = () => {
269
313
  const unassignedDrivers = drivers
270
314
  .map((driver, index) => ({ driver, index }))
271
315
  .filter(({ index }) => !primaryDriverIndices.includes(index));
272
- const vehiclesToAsk = isTwoByTwo ? vehicles.slice(0, 1) : vehicles;
316
+ const vehiclesToAsk = vehicles.slice(0, askedVehicleCount);
317
+ const { vehicleIndex: systemAllocatedVehicleIndex } = getTwoDriverSystemAllocation();
318
+ const primaryQuestionsAnswered = vehiclesToAsk.every((_vehicle, vehicleIndex) => vehlinks.some((l) => l.vehicleIndex === vehicleIndex
319
+ && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn
320
+ && l.driverIndex >= 0));
321
+ const primaryQuestionsAreUnique = new Set(primaryDriverIndices).size >= vehicles.length;
322
+ const shouldAskOccasional = drivers.length > vehicles.length
323
+ && vehicles.length > 1
324
+ && primaryQuestionsAnswered
325
+ && primaryQuestionsAreUnique;
273
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;
274
329
  const { year, make, model } = vehicle;
275
330
  const selectedPrimary = vehlinks.find((l) => l.vehicleIndex === vehicleIndex && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn);
276
331
  const isPrimaryAnswered = selectedPrimary !== undefined && selectedPrimary.driverIndex >= 0;
277
- // Show all drivers so the user can freely reselect / re-order primaries.
332
+ const previousPrimaryDriverIndices = new Set(vehlinks
333
+ .filter((l) => l.vehicleIndex < vehicleIndex
334
+ && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn
335
+ && l.driverIndex >= 0)
336
+ .map((l) => l.driverIndex));
337
+ const canRepeatPrimary = vehicles.length > drivers.length;
278
338
  const primaryOptions = drivers
279
- .map((driver, driverIndex) => ({ name: driver.firstName, value: driverIndex }));
280
- const isDuplicatePrimary = !isTwoByTwo
281
- && isPrimaryAnswered
282
- && drivers.length >= vehicles.length
283
- && vehlinks.some((l) => l.vehicleIndex !== vehicleIndex
284
- && l.priority === mychoiceSdkComponents.DriverPriorityTypes.Prn
285
- && l.driverIndex === selectedPrimary?.driverIndex);
286
- return (jsxRuntime.jsx(SelectFormBox, { title: `Who is the principal driver of the ${year} ${make} ${model}?`, onChange: handlePrimaryDriverChange(vehicleIndex), options: primaryOptions, defaultValue: isPrimaryAnswered ? selectedPrimary.driverIndex : '', name: `vehlink-${vehicleIndex}`, placeholder: "Select from the list", autoSelectIfValueIsOutOfOptions: false, error: (!isPrimaryAnswered && inValidation) || isDuplicatePrimary, errorMessage: isDuplicatePrimary
287
- ? 'This driver is already the primary driver of another vehicle. Each vehicle should have a different primary driver.'
288
- : '' }, `vehlink-${vehicleIndex}`));
289
- }), drivers.length > vehicles.length && vehicles.length > 1
339
+ .map((driver, driverIndex) => ({ name: driver.firstName, value: driverIndex }))
340
+ .filter(({ value }) => canRepeatPrimary
341
+ || !previousPrimaryDriverIndices.has(value));
342
+ return (jsxRuntime.jsx(SelectFormBox, { title: `Who is the principal driver of the ${year} ${make} ${model}?`, onChange: handlePrimaryDriverChange(vehicleIndex), options: primaryOptions, defaultValue: isPrimaryAnswered ? selectedPrimary.driverIndex : '', name: `vehlink-${vehicleIndex}`, placeholder: "Select from the list", autoSelectIfValueIsOutOfOptions: false, error: !isPrimaryAnswered && inValidation }, `vehlink-${vehicleIndex}`));
343
+ }), shouldAskOccasional
290
344
  && unassignedDrivers.map(({ driver, index: driverIndex }) => {
291
345
  const selectedVehicle = occVehlinks.find((l) => l.driverIndex === driverIndex);
292
346
  const vehicleOptions = vehicles.map((vehicle, vehicleIndex) => ({
@@ -1224,6 +1278,10 @@ const SectionDriverInfo = () => {
1224
1278
  month: birthMonth,
1225
1279
  year: birthYear,
1226
1280
  };
1281
+ const policyEffectiveDate = discountState.policyStartYear && discountState.policyStartMonth
1282
+ && discountState.policyStartDay
1283
+ ? `${discountState.policyStartYear}-${discountState.policyStartMonth}-${discountState.policyStartDay}`
1284
+ : discountState.policyStart;
1227
1285
  React.useEffect(() => {
1228
1286
  if (discountState.quoterInfo.firstName !== driverState.items[0].firstName) {
1229
1287
  dispatchDiscountState({
@@ -1248,19 +1306,19 @@ const SectionDriverInfo = () => {
1248
1306
  if (dateType === mychoiceSdkComponents.DateTypes.Day) {
1249
1307
  dispatchDriverInfoState({
1250
1308
  type: mychoiceSdkStore.StoreFormCarDriverInfoActionTypes.FormCarDriverBirthDaySelect,
1251
- payload: { birthDay: value, config: configState },
1309
+ payload: { birthDay: value, config: configState, appType },
1252
1310
  });
1253
1311
  }
1254
1312
  if (dateType === mychoiceSdkComponents.DateTypes.Month) {
1255
1313
  dispatchDriverInfoState({
1256
1314
  type: mychoiceSdkStore.StoreFormCarDriverInfoActionTypes.FormCarDriverBirthMonthSelect,
1257
- payload: { birthMonth: value, config: configState },
1315
+ payload: { birthMonth: value, config: configState, appType },
1258
1316
  });
1259
1317
  }
1260
1318
  if (dateType === mychoiceSdkComponents.DateTypes.Year) {
1261
1319
  dispatchDriverInfoState({
1262
1320
  type: mychoiceSdkStore.StoreFormCarDriverInfoActionTypes.FormCarDriverBirthYearSelect,
1263
- payload: { birthYear: value, config: configState },
1321
+ payload: { birthYear: value, config: configState, appType },
1264
1322
  });
1265
1323
  }
1266
1324
  };
@@ -1282,11 +1340,13 @@ const SectionDriverInfo = () => {
1282
1340
  payload: { applicantRelationship: value },
1283
1341
  });
1284
1342
  };
1285
- 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('', 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) }))] }));
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) }))] }));
1286
1344
  };
1287
1345
 
1288
1346
  // Max months between consecutive Ontario GDL licence classes (spec 1-2 e/f)
1289
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;
1290
1350
  const SectionDriverLicence = () => {
1291
1351
  const { appConfigState: { appType }, } = mychoiceSdkStore.useStoreAppConfig();
1292
1352
  const [driverEducation, setDriverEducation] = React.useState(false);
@@ -1312,7 +1372,11 @@ const SectionDriverLicence = () => {
1312
1372
  ? (!!ontarioQ1Date && mychoiceSdkComponents.checkDateIsSpecial(ontarioQ1Date, configState.minDates.g.specialDate))
1313
1373
  : mychoiceSdkComponents.checkDateIsSpecial(defaultMinDate, configState.minDates.g.specialDate);
1314
1374
  const driverName = firstName || driverNameDefault;
1375
+ const { policyStart, policyStartYear, policyStartMonth, policyStartDay, } = discountState;
1315
1376
  const today = mychoiceSdkComponents.getFormattedDate('', 'yyyy-MM-dd');
1377
+ const policyEffectiveDate = policyStartYear && policyStartMonth && policyStartDay
1378
+ ? `${policyStartYear}-${policyStartMonth}-${policyStartDay}`
1379
+ : policyStart || today;
1316
1380
  const { g, g1, g2, minLicenceAge } = configState.licenceConfig;
1317
1381
  const licenceTypeOptions = [
1318
1382
  { value: g.name, name: g.title },
@@ -1348,36 +1412,6 @@ const SectionDriverLicence = () => {
1348
1412
  }
1349
1413
  }
1350
1414
  }, [g2LicenceYear, g2LicenceMonth, licenceType, useOntarioFlow]);
1351
- // If the user picks their birth month in their 16th year and birthDay > 1,
1352
- // selecting that month would imply a date before their actual birthday (since dates are assumed
1353
- // as the 1st). Auto-advance the Q1 month to birthMonth + 1.
1354
- React.useEffect(() => {
1355
- if (!useOntarioFlow || !birthDate || !ontarioQ1Year || !ontarioQ1Month)
1356
- return;
1357
- const birthDayNum = parseInt(birthDay || '1', 10);
1358
- if (birthDayNum <= 1)
1359
- return;
1360
- const birthYearNum = parseInt(birthYear || '0', 10);
1361
- if (parseInt(ontarioQ1Year, 10) !== birthYearNum + 16 || ontarioQ1Month !== birthMonth)
1362
- return;
1363
- const q1SlotForCorrection = mychoiceSdkComponents.DriverLicenceTypes.G1;
1364
- let correctedMonth = parseInt(birthMonth || '1', 10) + 1;
1365
- let correctedYear = birthYearNum + 16;
1366
- if (correctedMonth > 12) {
1367
- correctedMonth = 1;
1368
- correctedYear += 1;
1369
- }
1370
- dispatchDriverLicenceState({
1371
- type: mychoiceSdkStore.StoreFormCarDriverLicenceActionTypes.FormCarDriverLicenceMonthSelect,
1372
- payload: { value: String(correctedMonth).padStart(2, '0'), config: configState, type: q1SlotForCorrection },
1373
- });
1374
- if (correctedYear !== birthYearNum + 16) {
1375
- dispatchDriverLicenceState({
1376
- type: mychoiceSdkStore.StoreFormCarDriverLicenceActionTypes.FormCarDriverLicenceYearSelect,
1377
- payload: { value: String(correctedYear), config: configState, type: q1SlotForCorrection },
1378
- });
1379
- }
1380
- }, [ontarioQ1Year, ontarioQ1Month]);
1381
1415
  // ── helpers ────────────────────────────────────────────────
1382
1416
  const getMinDate = (type) => {
1383
1417
  switch (type) {
@@ -1418,11 +1452,11 @@ const SectionDriverLicence = () => {
1418
1452
  });
1419
1453
  // Build a YYYY-MM-01 string from stored year/month, returns '' if either missing
1420
1454
  const toDate = (year, month) => (year && month ? `${year}-${month}-01` : '');
1421
- const validateLicenceDate = (year, month, minDate) => {
1422
- const dateStr = toDate(year, month);
1455
+ const validateLicenceDate = (year, month, minDate, dateOverride) => {
1456
+ const dateStr = dateOverride || toDate(year, month);
1423
1457
  if (!dateStr)
1424
1458
  return '';
1425
- if (mychoiceSdkComponents.compareDates(dateStr, today) > 0)
1459
+ if (mychoiceSdkComponents.compareDates(dateStr, policyEffectiveDate) > 0)
1426
1460
  return 'License dates cannot be in the future';
1427
1461
  if (minDate && mychoiceSdkComponents.compareDates(dateStr, minDate) < 0) {
1428
1462
  return 'This license date must be equal or later than the prior license date. Please check your selection';
@@ -1441,11 +1475,11 @@ const SectionDriverLicence = () => {
1441
1475
  return '';
1442
1476
  };
1443
1477
  // In the Ontario flow, firstLicenceAge is never entered, so gOneMin is stale/empty.
1444
- // Compute min from DOB + 16, capped to today so minDate never exceeds maxDate.
1478
+ // Compute the minimum from DOB + 16 and validate it against the policy effective date.
1445
1479
  const getG1MinDate = () => {
1446
1480
  if (useOntarioFlow && birthDate) {
1447
1481
  const computed = mychoiceSdkComponents.addYearsToDate(birthDate, 16);
1448
- return mychoiceSdkComponents.compareDates(computed, today) > 0 ? today : computed;
1482
+ return mychoiceSdkComponents.compareDates(computed, policyEffectiveDate) > 0 ? policyEffectiveDate : computed;
1449
1483
  }
1450
1484
  return gOneMin;
1451
1485
  };
@@ -1523,18 +1557,30 @@ const SectionDriverLicence = () => {
1523
1557
  const q1Year = getLicenceYear(q1SlotType);
1524
1558
  const q1Month = getLicenceMonth(q1SlotType);
1525
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;
1526
1574
  // ── path booleans ──
1527
- const showG2Date = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1 && receivedG2 === true;
1575
+ const showG2Question = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1 && canHaveG2;
1576
+ const showG2Date = showG2Question && receivedG2 === true;
1528
1577
  // G question shows after G2 date entered (G1→G2 path) OR after No-G2 answer (G1→No G2 path)
1529
1578
  const showGQuestionAfterG1 = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1
1579
+ && canHaveG
1530
1580
  && (receivedG2 === false || showG2Date);
1581
+ const showGQuestionAfterG2 = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2 && canHaveG;
1531
1582
  const showGDateAfterG1 = showGQuestionAfterG1 && receivedG === true;
1532
- const showGDateAfterG2 = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G2 && receivedG === true;
1533
- const g2Date = toDate(g2LicenceYear, g2LicenceMonth);
1534
- const gDate = toDate(gLicenceYear, gLicenceMonth);
1535
- // Thresholds per the licensing flow: G1 < 5 years (4y11m = 59 months); G2/G < 3 years (2y11m = 35 months).
1536
- const policyStart = discountState.policyStart || today;
1537
- const q1MonthsFromEffective = q1Date ? mychoiceSdkComponents.getDifferenceInMonths(policyStart, q1Date) : Infinity;
1583
+ const showGDateAfterG2 = showGQuestionAfterG2 && receivedG === true;
1538
1584
  // G1 branch: ask once, based on the first licence date (< 5 years / 60 months).
1539
1585
  const showDtcG1Only = firstClass === mychoiceSdkComponents.DriverLicenceTypes.G1
1540
1586
  && !!q1Date
@@ -1550,39 +1596,46 @@ const SectionDriverLicence = () => {
1550
1596
  // ── Validation error messages ──
1551
1597
  const q1MinDate = getG1MinDate();
1552
1598
  const q1ChronoError = driverState.inValidation
1553
- ? validateLicenceDate(q1Year, q1Month, q1MinDate)
1599
+ ? validateLicenceDate(q1Year, q1Month, q1MinDate, q1BirthdayDate)
1554
1600
  : '';
1555
- const q1FutureError = q1Date && mychoiceSdkComponents.compareDates(q1Date, today) > 0
1601
+ const q1FutureError = q1BirthdayDate && mychoiceSdkComponents.compareDates(q1BirthdayDate, policyEffectiveDate) > 0
1556
1602
  ? 'License dates cannot be in the future' : '';
1557
1603
  const q1Error = q1FutureError || q1ChronoError || getDateErrorMessage(['01', q1Month, q1Year], driverState.inValidation);
1558
1604
  const g2ChronoError = driverState.inValidation
1559
- ? validateLicenceDate(g2LicenceYear, g2LicenceMonth, q1Date)
1605
+ ? validateLicenceDate(g2LicenceYear, g2LicenceMonth, q1BirthdayDate)
1560
1606
  : '';
1561
- const g260MonthError = validate60Months(q1Year, q1Month, g2LicenceYear, g2LicenceMonth);
1562
- const g2FutureError = g2Date && mychoiceSdkComponents.compareDates(g2Date, today) > 0 ? 'License dates cannot be in the future' : '';
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' : '';
1563
1609
  const g2Error = g2FutureError || g260MonthError || g2ChronoError || getDateErrorMessage(['01', g2LicenceMonth, g2LicenceYear], driverState.inValidation);
1564
1610
  // G preceding date: G2 date if on G1→G2→G path, else Q1 date
1565
- const gPrecedingDate = showGDateAfterG1 && showG2Date ? g2Date : q1Date;
1611
+ const gPrecedingDate = showGDateAfterG1 && showG2Date ? g2Date : q1BirthdayDate;
1566
1612
  const gChronoError = driverState.inValidation
1567
1613
  ? validateLicenceDate(gLicenceYear, gLicenceMonth, gPrecedingDate)
1568
1614
  : '';
1569
- const g60MonthError = validate60Months(q1Year, q1Month, gLicenceYear, gLicenceMonth);
1570
- const gFutureError = gDate && mychoiceSdkComponents.compareDates(gDate, today) > 0 ? 'License dates cannot be in the future' : '';
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' : '';
1571
1617
  const gError = gFutureError || g60MonthError || gChronoError || getDateErrorMessage(['01', gLicenceMonth, gLicenceYear], driverState.inValidation);
1572
- // ── Min dates (always capped to today so minDate never exceeds maxDate) ──
1573
- const g2MinRaw = q1Date && mychoiceSdkComponents.compareDates(q1Date, gTwoMin) > 0 ? q1Date : gTwoMin;
1574
- const g2MinDate = mychoiceSdkComponents.compareDates(g2MinRaw, today) > 0 ? today : 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;
1575
1621
  const gMinRaw = gPrecedingDate && mychoiceSdkComponents.compareDates(gPrecedingDate, gMin) > 0 ? gPrecedingDate : gMin;
1576
- const gMinDate = mychoiceSdkComponents.compareDates(gMinRaw, today) > 0 ? today : 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);
1577
1630
  const getMax60Date = (refDate) => {
1578
1631
  if (!refDate)
1579
- return today;
1632
+ return policyEffectiveDate;
1580
1633
  const max60 = mychoiceSdkComponents.addMonthsToDate(refDate, ON_MAX_MONTHS_BETWEEN_CLASSES);
1581
- return mychoiceSdkComponents.compareDates(today, max60) > 0 ? max60 : today;
1634
+ return mychoiceSdkComponents.compareDates(policyEffectiveDate, max60) > 0 ? max60 : policyEffectiveDate;
1582
1635
  };
1583
- const g2MaxDate = getMax60Date(q1Date);
1584
- const gMaxDate = getMax60Date(q1Date);
1585
- 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: today, 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 5 years?` })), 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: g2MinDate, 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: gMinDate, 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?` })), 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: gMinDate, 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)." })] }));
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)." })] }));
1586
1639
  }
1587
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
1588
1641
  ? `${driverName} was licenced in ${Number(birthYear) + Number(firstLicenceAge)} - ${Number(birthYear) + Number(firstLicenceAge) + 1}`
@@ -1770,7 +1823,7 @@ you had insurance. If this is correct, please continue with the form.`);
1770
1823
  const firstInsuredMinDate = listedYear && listedMonth
1771
1824
  ? mychoiceSdkComponents.addDaysToDate(`${listedYear}-${listedMonth}-01`, birthDay ? +birthDay + 1 : 1)
1772
1825
  : mychoiceSdkComponents.getMinDate(birthDate, firstLicenceAge);
1773
- const twentyYearsAgo = mychoiceSdkComponents.getMinDateByYears(mychoiceSdkComponents.getFormattedDate('', 'yyyy-MM-dd'), 20);
1826
+ const twentyYearsAgo = mychoiceSdkComponents.subYearsFromDate('', 20);
1774
1827
  let lastPolicyEndMinDate = twentyYearsAgo;
1775
1828
  if (firstInsuredMinDate && mychoiceSdkComponents.compareDates(firstInsuredMinDate, twentyYearsAgo) > 0) {
1776
1829
  lastPolicyEndMinDate = firstInsuredMinDate;