@seethruhead/cra-payroll 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cra-payroll.js +43 -33
  2. package/package.json +1 -1
@@ -79322,8 +79322,9 @@ var parseResults = (text, config2, periodsPerYear) => t3(extractAll(text), ({ va
79322
79322
  ei: values.ei ?? 0,
79323
79323
  totalDeductions: values.totalDeductions ?? 0,
79324
79324
  net: values.net ?? 0,
79325
- rrspEmployee: rrspPerPeriod(config2.annualSalary, config2.rrspEmployeePercent, periodsPerYear),
79326
- rrspEmployer: rrspPerPeriod(config2.annualSalary, config2.rrspEmployerPercent, periodsPerYear)
79325
+ rrspMatched: rrspPerPeriod(config2.annualSalary, config2.rrspMatchPercent, periodsPerYear),
79326
+ rrspUnmatched: rrspPerPeriod(config2.annualSalary, config2.rrspUnmatchedPercent, periodsPerYear),
79327
+ rrspEmployer: rrspPerPeriod(config2.annualSalary, config2.rrspMatchPercent, periodsPerYear)
79327
79328
  }));
79328
79329
  // src/cra.ts
79329
79330
  var CRA_URL = "https://apps.cra-arc.gc.ca/ebci/rhpd/beta/entry";
@@ -79369,7 +79370,7 @@ var fillSalaryInfo = async (session, config2, salaryPerPeriod, rrspEmployerPerPe
79369
79370
  if (salary.isErr())
79370
79371
  return salary;
79371
79372
  log(`salary: ${salaryPerPeriod}/period`);
79372
- if (config2.rrspEmployerPercent > 0) {
79373
+ if (config2.rrspMatchPercent > 0) {
79373
79374
  log("setting employer RRSP...");
79374
79375
  const check = await session.checkCheckboxByLabel("Employer's contributions to the employee's RRSP");
79375
79376
  if (check.isErr())
@@ -79381,7 +79382,7 @@ var fillSalaryInfo = async (session, config2, salaryPerPeriod, rrspEmployerPerPe
79381
79382
  else
79382
79383
  log(`employer RRSP: ${rrspEmployerPerPeriod}/period`);
79383
79384
  }
79384
- if (config2.rrspEmployeePercent > 0) {
79385
+ if (parseFloat(rrspEmployeePerPeriod) > 0) {
79385
79386
  log("setting employee RRSP...");
79386
79387
  const check = await session.checkCheckboxByLabel("Employee's contributions to RRSPs or RPPs or PRPPs");
79387
79388
  if (check.isErr())
@@ -79447,8 +79448,9 @@ var calculatePayroll = async (config2, headless = false) => {
79447
79448
  if (!periodsPerYear)
79448
79449
  return $err(`Unknown pay period: "${config2.payPeriod}"`);
79449
79450
  const salaryPerPeriod = (config2.annualSalary / periodsPerYear).toFixed(2);
79450
- const rrspEmployeePerPeriod = (config2.annualSalary * (config2.rrspEmployeePercent / 100) / periodsPerYear).toFixed(2);
79451
- const rrspEmployerPerPeriod = (config2.annualSalary * (config2.rrspEmployerPercent / 100) / periodsPerYear).toFixed(2);
79451
+ const totalEmployeeRrspPercent = config2.rrspMatchPercent + config2.rrspUnmatchedPercent;
79452
+ const rrspEmployeePerPeriod = (config2.annualSalary * (totalEmployeeRrspPercent / 100) / periodsPerYear).toFixed(2);
79453
+ const rrspEmployerPerPeriod = (config2.annualSalary * (config2.rrspMatchPercent / 100) / periodsPerYear).toFixed(2);
79452
79454
  const sessionResult = await launchSession(headless);
79453
79455
  if (sessionResult.isErr())
79454
79456
  return $err(sessionResult.error);
@@ -79512,7 +79514,8 @@ var buildRow = (period, active, maxed, cum) => t3({ ded: periodDeductions(active
79512
79514
  row: {
79513
79515
  period,
79514
79516
  grossIncome: active.grossIncome,
79515
- rrspEmployee: active.rrspEmployee,
79517
+ rrspMatched: active.rrspMatched,
79518
+ rrspUnmatched: active.rrspUnmatched,
79516
79519
  rrspEmployer: active.rrspEmployer,
79517
79520
  ...taxes,
79518
79521
  ...ded,
@@ -79527,7 +79530,8 @@ var buildRow = (period, active, maxed, cum) => t3({ ded: periodDeductions(active
79527
79530
  var sumField = (rows, field) => round2(t7(rows, (r2) => r2[field]));
79528
79531
  var sumTotals = (rows) => ({
79529
79532
  grossIncome: sumField(rows, "grossIncome"),
79530
- rrspEmployee: sumField(rows, "rrspEmployee"),
79533
+ rrspMatched: sumField(rows, "rrspMatched"),
79534
+ rrspUnmatched: sumField(rows, "rrspUnmatched"),
79531
79535
  rrspEmployer: sumField(rows, "rrspEmployer"),
79532
79536
  federalTax: sumField(rows, "federalTax"),
79533
79537
  provincialTax: sumField(rows, "provincialTax"),
@@ -79563,7 +79567,7 @@ import { existsSync as existsSync3, renameSync, unlinkSync, chmodSync } from "fs
79563
79567
  // package.json
79564
79568
  var package_default = {
79565
79569
  name: "@seethruhead/cra-payroll",
79566
- version: "0.2.2",
79570
+ version: "0.3.0",
79567
79571
  description: "Calculate Canadian payroll deductions using CRA's Payroll Deductions Online Calculator",
79568
79572
  type: "module",
79569
79573
  bin: {
@@ -79732,8 +79736,8 @@ Province: ${config2.province}
79732
79736
  Year: ${config2.year}
79733
79737
  Annual Salary: $${money(config2.annualSalary)}
79734
79738
  Pay Period: ${config2.payPeriod}
79735
- RRSP (Employee): ${config2.rrspEmployeePercent}%
79736
- RRSP (Employer): ${config2.rrspEmployerPercent}%${when(showCppEi, `CPP Maxed Out: ${config2.cppMaxedOut ? "Yes" : "No"}
79739
+ RRSP (Matched): ${config2.rrspMatchPercent}%${config2.rrspUnmatchedPercent > 0 ? `
79740
+ RRSP (Unmatched): ${config2.rrspUnmatchedPercent}%` : ""}${when(showCppEi, `CPP Maxed Out: ${config2.cppMaxedOut ? "Yes" : "No"}
79737
79741
  EI Maxed Out: ${config2.eiMaxedOut ? "Yes" : "No"}`)}
79738
79742
  ${line("─", 40)}
79739
79743
  Calculating via CRA PDOC...
@@ -79742,9 +79746,11 @@ Calculating via CRA PDOC...
79742
79746
  // src/views/single.ts
79743
79747
  var f = (n5) => money(n5).padStart(10);
79744
79748
  var W = 42;
79745
- var renderSingleResult = (r2) => `Results (per pay period)
79749
+ var renderSingleResult = (r2) => {
79750
+ const totalEmployeeRrsp = r2.rrspMatched + r2.rrspUnmatched;
79751
+ return `Results (per pay period)
79746
79752
  ${line("═", W)}
79747
- Gross Income: $${f(r2.grossIncome)}${when(r2.rrspEmployee, ` RRSP (Employee): -$${f(r2.rrspEmployee)}`)}${when(r2.rrspEmployer, ` RRSP (Employer): -$${f(r2.rrspEmployer)}`)}
79753
+ Gross Income: $${f(r2.grossIncome)}${when(r2.rrspMatched, ` RRSP (Matched): -$${f(r2.rrspMatched)}`)}${when(r2.rrspUnmatched, ` RRSP (Unmatched): -$${f(r2.rrspUnmatched)}`)}${when(r2.rrspEmployer, ` RRSP (Employer): -$${f(r2.rrspEmployer)}`)}
79748
79754
  ${line("─", W)}
79749
79755
  Federal Tax: -$${f(r2.federalTax)}
79750
79756
  Provincial Tax: -$${f(r2.provincialTax)}
@@ -79753,12 +79759,15 @@ ${line("─", W)}
79753
79759
  ${line("─", W)}
79754
79760
  Total Deductions: -$${f(r2.totalDeductions)}
79755
79761
  ${line("═", W)}
79756
- Net Pay: $${f(r2.net)}${when(r2.rrspEmployee, ` (after RRSP): $${f(r2.net - r2.rrspEmployee)}`)}`;
79762
+ Net Pay: $${f(r2.net)}${when(totalEmployeeRrsp, ` (after RRSP): $${f(r2.net - totalEmployeeRrsp)}`)}`;
79763
+ };
79757
79764
 
79758
79765
  // src/views/table.ts
79759
79766
  var col = (v, w) => typeof v === "number" ? money(v).padStart(w) : v.padStart(w);
79760
79767
  var renderRow = (r2) => `${r2.label} │ ${col(r2.gross, 10)} │ ${col(r2.fedTax, 10)} │ ${col(r2.provTax, 10)} │ ${col(r2.cpp, 10)} │ ${col(r2.cpp2, 6)} │ ${col(r2.ei, 10)} │ ${col(r2.netPay, 10)}${r2.rrspEmp !== undefined ? ` │ ${col(r2.rrspEmp, 10)} │ ${col(r2.takeHome, 10)}` : ""} │ ${col(r2.cumCppEi, 10)}${r2.suffix ?? ""}`;
79761
- var showRrsp = (totals) => totals.rrspEmployee > 0 || totals.rrspEmployer > 0;
79768
+ var totalEmployeeRrsp = (r2) => r2.rrspMatched + r2.rrspUnmatched;
79769
+ var totalEmployeeRrspTotals = (t8) => t8.rrspMatched + t8.rrspUnmatched;
79770
+ var showRrsp = (totals) => totals.rrspMatched > 0 || totals.rrspUnmatched > 0 || totals.rrspEmployer > 0;
79762
79771
  var rrspFields = (show, fields) => show ? fields : {};
79763
79772
  var annotate = (r2, first2) => r2.cpp === 0 && r2.cpp2 === 0 && r2.ei === 0 ? " ✓ maxed" : r2.cpp < first2.cpp || r2.ei < first2.ei ? " ← partial" : "";
79764
79773
  var toRow = (r2, first2, rrsp) => ({
@@ -79770,7 +79779,7 @@ var toRow = (r2, first2, rrsp) => ({
79770
79779
  cpp2: r2.cpp2,
79771
79780
  ei: r2.ei,
79772
79781
  netPay: r2.netPay,
79773
- ...rrspFields(rrsp, { rrspEmp: r2.rrspEmployee, takeHome: r2.netPay - r2.rrspEmployee }),
79782
+ ...rrspFields(rrsp, { rrspEmp: totalEmployeeRrsp(r2), takeHome: r2.netPay - totalEmployeeRrsp(r2) }),
79774
79783
  cumCppEi: r2.cumulativeCpp + r2.cumulativeCpp2 + r2.cumulativeEi,
79775
79784
  suffix: annotate(r2, first2)
79776
79785
  });
@@ -79795,7 +79804,7 @@ var totalsRow = (totals, rrsp) => ({
79795
79804
  cpp2: totals.cpp2,
79796
79805
  ei: totals.ei,
79797
79806
  netPay: totals.netPay,
79798
- ...rrspFields(rrsp, { rrspEmp: totals.rrspEmployee, takeHome: totals.netPay - totals.rrspEmployee }),
79807
+ ...rrspFields(rrsp, { rrspEmp: totalEmployeeRrspTotals(totals), takeHome: totals.netPay - totalEmployeeRrspTotals(totals) }),
79799
79808
  cumCppEi: ""
79800
79809
  });
79801
79810
  var renderTable = (yearly, periodsPerYear, year = 2026) => t3(yearly, (ctx) => ({ ...ctx, rrsp: showRrsp(ctx.totals) }), (ctx) => ({ ...ctx, header: renderRow(headerRow(ctx.rrsp)) }), (ctx) => ({ ...ctx, bodyRows: ctx.rows.map((r2) => renderRow(toRow(r2, ctx.rows[0], ctx.rrsp))) }), (ctx) => ({ ...ctx, totalsStr: renderRow(totalsRow(ctx.totals, ctx.rrsp)), W: ctx.header.length }), (ctx) => `Per-Paycheck Table (${year})
@@ -79813,10 +79822,11 @@ ${line("═", ctx.W)}${when(ctx.rrsp, `
79813
79822
  var W2 = 42;
79814
79823
  var renderBreakdown = (label, totals, divisor = 1) => {
79815
79824
  const f2 = (n5) => money(n5 / divisor).padStart(10);
79825
+ const totalEmployeeRrsp2 = totals.rrspMatched + totals.rrspUnmatched;
79816
79826
  return `
79817
79827
  ${label}
79818
79828
  ${line("═", W2)}
79819
- Gross Income: $${f2(totals.grossIncome)}${when(totals.rrspEmployee, ` RRSP (Employee): -$${f2(totals.rrspEmployee)}`)}${when(totals.rrspEmployer && divisor === 1, ` RRSP (Employer): -$${f2(totals.rrspEmployer)}`)}
79829
+ Gross Income: $${f2(totals.grossIncome)}${when(totals.rrspMatched, ` RRSP (Matched): -$${f2(totals.rrspMatched)}`)}${when(totals.rrspUnmatched, ` RRSP (Unmatched): -$${f2(totals.rrspUnmatched)}`)}${when(totals.rrspEmployer && divisor === 1, ` RRSP (Employer): -$${f2(totals.rrspEmployer)}`)}
79820
79830
  ${line("─", W2)}
79821
79831
  Federal Tax: -$${f2(totals.federalTax)}
79822
79832
  Provincial Tax: -$${f2(totals.provincialTax)}
@@ -79825,7 +79835,7 @@ ${line("─", W2)}
79825
79835
  ${line("─", W2)}
79826
79836
  Total Deductions: -$${f2(totals.totalDeductions)}
79827
79837
  ${line("═", W2)}
79828
- Net Pay: $${f2(totals.netPay)}${when(totals.rrspEmployee, ` (after RRSP): $${money((totals.netPay - totals.rrspEmployee) / divisor).padStart(10)}`)}`;
79838
+ Net Pay: $${f2(totals.netPay)}${when(totalEmployeeRrsp2, ` (after RRSP): $${money((totals.netPay - totalEmployeeRrsp2) / divisor).padStart(10)}`)}`;
79829
79839
  };
79830
79840
  var renderAnnual = (totals) => renderBreakdown("Annual Totals", totals);
79831
79841
  var renderMonthly = (totals) => renderBreakdown("Monthly Averages", totals, 12);
@@ -79861,8 +79871,8 @@ var { values } = parseArgs({
79861
79871
  province: { type: "string", short: "p" },
79862
79872
  "pay-period": { type: "string" },
79863
79873
  year: { type: "string", short: "y" },
79864
- "rrsp-employee": { type: "string" },
79865
- "rrsp-employer": { type: "string" },
79874
+ "rrsp-match": { type: "string" },
79875
+ "rrsp-unmatched": { type: "string" },
79866
79876
  "cpp-maxed": { type: "boolean", default: false },
79867
79877
  "ei-maxed": { type: "boolean", default: false },
79868
79878
  table: { type: "boolean", short: "t", default: false },
@@ -79891,8 +79901,8 @@ if (values.help) {
79891
79901
  -p, --province <name> Province of employment
79892
79902
  -y, --year <year> Tax year (default: current year)
79893
79903
  --pay-period <type> Pay period (e.g. "Semi-monthly (24 pay periods a year)")
79894
- --rrsp-employee <pct> Employee RRSP contribution % (default: 4)
79895
- --rrsp-employer <pct> Employer RRSP match % (default: 4)
79904
+ --rrsp-match <pct> RRSP match % (employee + employer both contribute this, default: 4)
79905
+ --rrsp-unmatched <pct> Additional unmatched employee RRSP % (default: 0)
79896
79906
  --cpp-maxed CPP contributions maxed out for the year
79897
79907
  --ei-maxed EI premiums maxed out for the year
79898
79908
  -t, --table Show per-paycheck table for the year (tracks CPP/EI max)
@@ -79910,8 +79920,8 @@ if (values.help) {
79910
79920
  "annualSalary": 100000,
79911
79921
  "payPeriod": "Semi-monthly (24 pay periods a year)",
79912
79922
  "year": 2026,
79913
- "rrspEmployeePercent": 4,
79914
- "rrspEmployerPercent": 4,
79923
+ "rrspMatchPercent": 4,
79924
+ "rrspUnmatchedPercent": 0,
79915
79925
  "cppMaxedOut": false,
79916
79926
  "eiMaxedOut": false
79917
79927
  }
@@ -80046,12 +80056,12 @@ var resolveConfig = async (vals, fileConfig, isPiped) => {
80046
80056
  const payPeriod = await resolveField("pay-period", vals["pay-period"], fileConfig.payPeriod, "Semi-monthly (24 pay periods a year)", () => promptChoice("Pay period:", PAY_PERIODS2, "Semi-monthly (24 pay periods a year)"), isPiped);
80047
80057
  if (payPeriod.isErr())
80048
80058
  return $err(payPeriod.error);
80049
- const rrspEmployee = await resolveField("rrsp-employee", vals["rrsp-employee"] !== undefined ? parseFloat(vals["rrsp-employee"]) : undefined, fileConfig.rrspEmployeePercent, 4, () => promptNumber("Employee RRSP contribution (%)", 4), isPiped);
80050
- if (rrspEmployee.isErr())
80051
- return $err(rrspEmployee.error);
80052
- const rrspEmployer = await resolveField("rrsp-employer", vals["rrsp-employer"] !== undefined ? parseFloat(vals["rrsp-employer"]) : undefined, fileConfig.rrspEmployerPercent, 4, () => promptNumber("Employer RRSP match (%)", 4), isPiped);
80053
- if (rrspEmployer.isErr())
80054
- return $err(rrspEmployer.error);
80059
+ const rrspMatch = await resolveField("rrsp-match", vals["rrsp-match"] !== undefined ? parseFloat(vals["rrsp-match"]) : undefined, fileConfig.rrspMatchPercent, 4, () => promptNumber("RRSP match % (employee + employer both contribute)", 4), isPiped);
80060
+ if (rrspMatch.isErr())
80061
+ return $err(rrspMatch.error);
80062
+ const rrspUnmatched = await resolveField("rrsp-unmatched", vals["rrsp-unmatched"] !== undefined ? parseFloat(vals["rrsp-unmatched"]) : undefined, fileConfig.rrspUnmatchedPercent, 0, () => promptNumber("Additional unmatched employee RRSP %", 0), isPiped);
80063
+ if (rrspUnmatched.isErr())
80064
+ return $err(rrspUnmatched.error);
80055
80065
  const cppMaxedOut = vals["cpp-maxed"] === true ? true : fileConfig.cppMaxedOut ?? false;
80056
80066
  const eiMaxedOut = vals["ei-maxed"] === true ? true : fileConfig.eiMaxedOut ?? false;
80057
80067
  return $ok({
@@ -80059,8 +80069,8 @@ var resolveConfig = async (vals, fileConfig, isPiped) => {
80059
80069
  annualSalary: salary.value,
80060
80070
  payPeriod: payPeriod.value,
80061
80071
  year: year.value,
80062
- rrspEmployeePercent: rrspEmployee.value,
80063
- rrspEmployerPercent: rrspEmployer.value,
80072
+ rrspMatchPercent: rrspMatch.value,
80073
+ rrspUnmatchedPercent: rrspUnmatched.value,
80064
80074
  cppMaxedOut,
80065
80075
  eiMaxedOut
80066
80076
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seethruhead/cra-payroll",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Calculate Canadian payroll deductions using CRA's Payroll Deductions Online Calculator",
5
5
  "type": "module",
6
6
  "bin": {