@casomoltd/nhs-pay (英语)
国民保健体系的薪级表——变革纲领外加医疗和牙科——包括养恤金等级、地区、健康、健康、社会和健康分类补充,以及一个基于以下因素的带回家计算器: @casomoltd/paye-calc在1995年、2008年和2015年各节中,一位会员的NHS养恤金:最终工资和职业平均, McCloud 补救窗口,无论基于哪一种基数、提前退休和迟退休因数,还是整个抽取的免税现金.
见 docs/pay-frameworks.md 用于域模型——支付框架(AfC,医疗,牙科,VSM),共享比例表解析器核心,以及消费者边界所在位置.
关于卡索莫
卡索莫是一个 英国注册有限公司 创建和指挥 大卫·穆罕默德它建立重点软件工具和提供工程咨询。 这个库授权 NHS 计算器和解释器使用 casomo.co.uk (英语) - 不同者正在显示 带回家 收入(税后、北爱尔兰和养恤金),而不仅仅是大多数公布来源的总数.
- 组合 —— 说 casomo.co.uk (英语)
- 咨询 —— 说 casomoltd.com (英语)
安装
npm install @casomoltd/nhs-pay
Npm 登记簿上的公示——无认证或 .npmrc 需要配置 .
要求数 @casomoltd/paye-calc 作为对等依赖; 它接受的范围是 peerDependencies 内 package.json。 。 。 .
使用量
查查乐队的工资范围
import {AFC_CURRENT_YEAR, getAfcScales} from '@casomoltd/nhs-pay';
// A scale belongs to a pay year and a nation; neither has a default.
const {bands} = getAfcScales(AFC_CURRENT_YEAR, 'england');
const band5 = bands.find((b) => b.band === '5')!;
console.log(band5.salary.min); // entry salary
console.log(band5.salary.max); // top of band
console.log(band5.points); // all pay points
计算第5行护士的回家费用
import {
AFC_CURRENT_YEAR,
getAfcScales,
getPensionTiers,
nationToTaxRegion,
nhsTakeHome,
pensionTierRate,
} from '@casomoltd/nhs-pay';
import {taxYear} from '@casomoltd/paye-calc';
const year = AFC_CURRENT_YEAR;
const {bands} = getAfcScales(year, 'england');
const band5 = bands.find((b) => b.band === '5')!;
const salary = band5.salary.min;
// The contribution tiers are their own dataset, fetched by year and nation.
const tax = taxYear(year);
const rate = pensionTierRate(salary, getPensionTiers(tax, 'england'));
// The tax year and region are required: a default would silently tax a
// Scottish member at rUK rates.
const thp = nhsTakeHome(
salary, rate / 100, tax, nationToTaxRegion('england'),
);
console.log(thp.net); // annual net
console.log(thp.incomeTax); // annual tax
console.log(thp.nationalInsurance); // annual NI
console.log(thp.pensionDeduction); // annual pension
应用 HCAS 补充
import {
AFC_CURRENT_YEAR,
getAfcScales,
calculateHcasSupplement,
} from '@casomoltd/nhs-pay';
const {bands, hcas} = getAfcScales(AFC_CURRENT_YEAR, 'england');
const base = bands[0].salary.min;
const supplement = calculateHcasSupplement(
base, hcas.innerLondon,
);
console.log(base + supplement); // London-adjusted
显示格式薪给
import {fmtSalary, fmtPct} from '@casomoltd/nhs-pay';
fmtSalary(31049); // '£31,049'
fmtPct(8.3); // '8.3%'
医生或牙医回家
医学和牙医的成绩与AFC一样,通过每个家庭的解决方案解决. getMedicalScales(year, nation) 列出为一个国家和年份公布的成绩; fromPoint 构建一个 Post (毛额,养恤金等级,税收,NI,带回家) 从一个点.
import {getMedicalScales, medicalResolver} from '@casomoltd/nhs-pay';
const grades = getMedicalScales('2026-27', 'england');
const consultant = grades.find((g) => g.grade === 'consultant')!;
const top = consultant.points.at(-1)!;
const post = medicalResolver.fromPoint(
'consultant', top, 'england', '2026-27',
);
console.log(post.salary); // basic pay
console.log(post.pensionRate); // member contribution %
console.log(post.takeHome.net); // annual net after tax + NI + pension
console.log(consultant.source.reference); // the circular it came from
fromPoint 这一点本身。 还有 fromScalePoint(grade, label, …) 对于只持有标签的呼叫者来说,但标签并不识别每个尺度上的分数——英格兰的顾问比额表是20个薪给步骤超过5个门槛标签,所以 'Threshold 4' 6个人的名字 和那个电话扔 AmbiguousScalePoint 而不是选择一个.
getDentalScales 编号 : dentalResolver 给有薪牙医分数的这个 两者都响亮地失败(ScaleUnavailable用于未公布的国家/年份或级别,而不是默认.
成员养恤金各款的价值
import {
PAST_YEARS, SECTIONS, isoDate, memberBenefits,
} from '@casomoltd/nhs-pay';
import {definedBenefitInput, taxYearEnd} from '@casomoltd/paye-calc';
// Built once from the member; `today` pins the date the figures
// are as at, so they reproduce.
const benefits = memberBenefits(
{
dateOfBirth: isoDate('1979-01-01'),
service: [
{section: SECTIONS.s1995, joined: isoDate('2004-04-01'),
left: isoDate('2022-03-31')},
{section: SECTIONS.s2015, joined: isoDate('2022-04-01'),
left: null},
],
pay: {
declared: [],
current: {todaysMoney: 51932, asAt: isoDate('2026-09-01')},
ladder: null, // or the member's AfC band points and current point
partTime: false, // true: pay above is for fewer than full-time hours
},
statement: null, // or a 2015 Section balance off a statement
},
// `published` prices the past on each year's Revaluation Order,
// as an Annual Benefit Statement does; `assumed` on the CPI below.
{assumedCpi: 0.02, pastYears: PAST_YEARS.published},
new Date(2026, 8, 23),
);
benefits.remedy; // true: in service by 31 March 2012 and after 2015
benefits.now(); // held today, the remedy window on the legacy basis
// Asked once per election the member is compared on: both bases here,
// because they have a remedy window. Every section is drawn on one date.
for (const kind of benefits.elections) {
const position = benefits.at({
leaving: isoDate('2039-09-30'),
drawing: isoDate('2039-09-30'),
remedy: {kind},
cash: {kind: 'maximum'},
});
position.awards; // one per section and basis, each factored
position.section2015; // the 2015 Section's ledgers, estimated history, curve
position.crystallised; // the pension and automatic lump sum, summed
position.cash; // the cash taken across the whole
}
// One tax year's pension input, for the annual allowance: 2027 is
// 2026-27 (paye-calc's `taxYearEnd`), for the same leaving and election,
// valued in that year's cash at 2% CPI.
const period = benefits.pensionInputPeriod(taxYearEnd(2027), {
leaving: isoDate('2039-09-30'), remedy: {kind: 'legacy-basis'},
}, 0.02);
const input = definedBenefitInput(period); // the year's input amount
每一节都保留自己的规则——分母、工资标准、养恤金年龄、一次总付、因素——因此,任何呼叫者都无法将它们合并为计划所缺乏的一个。 薪酬来自会员的薪酬途径(promotionalIndex 是GAD的曲线背后。 服务 : BenefitNotModelled (单位:千美元) code (一) 支线; NOT_MODELLED 链接每个代码到问题跟踪它。 见 成员各科的福利 为模型。 每项安排的养恤金投入如何估价 一年养恤金投入。 。 。 .
2015年项目a
堕地. projectPension 这个平价问题一直保留到 21号; 对于跨节的成员,使用 memberBenefits 见上文.
import {
COMMUTATION_FACTOR,
LUMP_SUM_ALLOWANCE,
commute,
projectPension,
} from '@casomoltd/nhs-pay';
const projection = projectPension({
kind: 'statement',
accruedPension: 5000, // from the Annual Benefit Statement
statementDate: new Date(2026, 2, 31), // the date it names
currentSalary: 54000,
dateOfBirth: new Date(1990, 0, 1),
exitDate: new Date(2035, 0, 1),
retirementDate: new Date(2053, 0, 1), // before NPA → ERF
npa: 67,
assumedCpi: 0.02,
});
console.log(projection.annualPension); // after ERF/LRF
console.log(projection.factorType); // 'erf'
console.log(projection.curve); // chart-ready points
// Commutation takes the whole {nominal, real, asAt} figure, not
// one side of it: the lump sum allowance is a cash amount tested
// on a date, so a dateless number could not say which ruler it
// was in. Every limit is required for the same reason — a
// default would answer a question the caller did not ask.
const {lumpSum, residualPension, limit} = commute(
projection.annualPension,
1, // take the permitted maximum
{
commutationFactor: COMMUTATION_FACTOR,
allowance: {
amount: LUMP_SUM_ALLOWANCE,
asAt: new Date(2026, 2, 31),
},
// The run's OWN price series, so the allowance is carried
// forward at the rate the pension was projected at.
prices: projection.prices,
},
);
console.log(lumpSum.real, lumpSum.nominal); // both rulers
// The maximum, and which cap stopped it — PER RULER.
console.log(limit.real.amount, limit.real.binding);
console.log(limit.nominal.amount, limit.nominal.binding);
最大值为 下调 两个盖子,和 两者都是法定的:福利资本值的25%,以及一次性津贴。 计划本身对互换的贡献是12:1的利率,而别无其他,所以消费者不得将25%归结于计划—— LUMP_SUM_CAPS.Scheme 说出歧视者的名字,而不是规则的作者. binding 说哪个盖子阻止了它,所以消费者可以解释数字而不是重述规则.
为什么这个名字是原样的, 以及当它改变时会移动到哪里: 免税现金的两个上限。 。 。 .
有一个 每个标尺一个限制, 没有单一的旗帜,因为两者可以真正不同意: real 是零消费物价指数运行的模型,而津贴则在消费物价指数中结转,因此,在交叉时,津贴在今天的货币中绑定,而计划四肢仍然用现金绑定。 在屏幕上显示属于标尺的极限 。 见 免税现金的两个上限。 。 。 .
没有说明数字, kind: 'estimation' 从 a 累积 joinDate 换句话说 ERF/LRF因子从GAD综合因子工作手册(2023年6月30日发)中逐字转录,并附有GAD本身的四舍五入规则;除印刷表格外的退休日期 RetirementFactorOutOfRange。 。 。 .
如何运作
docs/how-it-works.md ——这个库所执行的模式:它走过的再现过程,一个计划年和一个退出日期对它意味着什么,为什么现金和今天的钱是两跑而不是一跑并是一个减缩器,以及它所做的每一个假设,都宣布了. 在信任一个人物之前读一下.
API 参考
docs/api.md ——按域排列的每一个导出,都有打字签名和短音. 通过检查时间的漂移门与代码同步. 代理人可能更喜欢运出 dist/*.d.ts,每个模块都带有完整的JSDoc.
数据来源
AFC 薪级表
| 年份 | 国家 | 来源 |
|---|---|---|
| 2025-26 (简体中文) | 英格兰、北爱尔兰、威尔士 | NHS 雇主薪资表 2025/26 |
| 2026-27 (中文(简体) ) | 英国,NI | NHS 雇主薪资表 2026/27 |
对照 NHSPRB 第39次报告(2026年),表A25(AfC 2025/26英格兰、北爱尔兰、威尔士的数据).
NHS养恤金
| 数据 | 来源 |
|---|---|
| 9月 消费物价指数+在职率 | HM 财务重估令,每年一次 |
| 2015年挪威人民援助会科应计费率 | NHSBSA 2015 成员指南(V13) |
| 1995年和2008年各款分母、薪酬措施、一笔总付 | SI 1995/300和SI 2008/653,作为 how-it-works.md 引用他们 |
| McCloud 补救资格和窗口 | 2022年《公务员养恤金和司法办公室法》第1至2节;由SI 2023/985退回 |
| ERF / LRF 系数: 0-420, 0-421, 1-401, 1-402, 1-407, 2-416 | GAD NHS EW 综合要素手册 |
| 晋升工资指数 | 性别与发展,2020年估值假设摘要,第3页 |
| 折合率(12英镑: 1英镑) | NHSBSA关键说明——2015年计划估算(V2) |
| 允许最高(三肢以下) | 附表29 2004年《财政法》第2段 |
适用金额、确定的利益、, (A + (B × C)) / 4 | 附表29 2004年《财政法》第2 C段 |
| 相关估值因素(20) | 2004年《财政法》第276条 |
一次总付津贴LUMP_SUM_ALLOWANCE(已冻结) | ITEPA 2003 第637P条 |
逐行对决真实的 年度养恤金报表 (2015年科,更新至31/03/2025,姓名和会籍编号已校正),对照由科室手工制作的十年预测.
二者均存档并清点于 docs/source-archive.md,链接在标题中 tests/golden-abs.test.ts ——除这些说法外,还有理由,即引文属于其中,不能偏离引文.
声明是真理的来源,图书馆从不重复它:输入它的数字,要求它自己的日期,你被完全交还它所说的话. 见 两个统治者,一个模式 如何生产现金和今天的钱 哪个系列应用已公布的命令 以及为什么今天的钱从不拿.
这个承诺是准确的 对于一个陈述移交 日期. 通过未注明日期的数字,反而提出了另一个问题——"这是我今天的平衡"——然后,图书馆必须倒向到年底工作,按照自己的重新估价规则,而不是计划. 对于在一年结束时离职的成员,两者不同;见 向后读取语句 应用 SAME 规则 因为它的大小 和为什么通过日期避免它.
苏格兰
苏格兰独立谈判自己的AFC奖项,与英格兰的基薪完全不同. 每个纳税年度分别储存比额表表 getAfcScales(year, 'scotland') 返回苏格兰数字。 苏格兰也有结构上的差异: Band 2有2分(在英格兰为vs 1), Bands 8a–9各有2分(vs 3).
资料来源: PCS(AFC)2026/1 (中文(简体) ) - 苏格兰卫生工作人员管理局通知(2026年1月23日)。 附件B为两年费率表;附件C以递增方式列出递增,并证实附件B点的点数.
苏格兰2025-26年的定居点为4.25%,但有通货膨胀保证——在上升的历年,至少比平均消费物价指数高出一个百分点. 2025年消费物价指数确认为3.4%,因此启动担保并修订为4.4%,拖欠时间可追溯到2025年4月1日. 2026-27的3.75%随后适用于修改后的基数,因此两年都动了. 两者均取自附件B,而不是MSG综合表,后者仍然印出4.25%的原始比率.
威尔士
威尔士有自己的薪级,两年都从中转出: AFC(W)02/2025 (2025年5月29日)和 阿联理事会(W)02/2026 (2026年2月12日),各附件1.
威尔士是 没有 英格兰的桌子上加了一层 这两道梯子在每道由上而下相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去 一层地抬起梯子下部而不能起起顶. 威尔士还搭载了两个乐队2分,英格兰有1分.
分点标签出自每个通则自己的"数年后才有资格获得薪酬递增"一栏,因此它们由威尔士人来源声明,而不是从英格兰的桌子上借出,它们并不总是同意英格兰对同一支乐队的看法.
生活工资下限是真实的,但是是分开的:这是提高最低点的预付款,因此2026/27提高标准明确不适用于最低点. WALES_LIVING_WAGE 将公布的数字——年底和按小时计算的费率——作为参考;没有从中得出一个尺度,也没有从另一个尺度中得出。 资料来源: AFC(W) 01/2026 (2026年1月6日) (中文(简体) ).
乐队一号在两年内公布(24,833英镑后为26,300英镑)并关闭给新入会者. 没有 AFC_BANDS苏格兰也有同样的漏洞.
威尔士的两年都是在NHS威尔士网络地产停业(2026年9月2日)期间被转录而来,因此这些通函取自NHS威尔士雇主的抄本而不是出版商自己的. 每个文件的字节被对照从中下载的副本检查 www.nhs.wales 前一天, 在停电前, 而且两者都匹配。 上面的链接是出版商的,这是这些文件的住址.
其他数据
| 数据 | 来源 |
|---|---|
| 养恤金缴款率2025/26 | NHSBSA 缴款率 |
| 所得税/北爱尔兰税率 | gov.uk(通过付费计算) |
| 国民生活工资 | nLW费率 |
| HCAS PCT 区 | NHS 雇主 附件8 |
医疗和牙科工资表
医生和牙医根据《改革议程》中单独的一套工资通知支付工资——每个国家一份。 这个库为它们编码,这样它就能制取 带回家 (不仅仅是毛) 用于医学和牙科年级, 这是大多数公布的来源省略.
| 国家 | 圆形 | 年份 | 来源 |
|---|---|---|---|
| 英国 | PC(M&D) 1/2026 R2 | 第2026/27号决议 | NHS 雇主 |
| 苏格兰 | PCS(DD)2026/01号 | 2026/27(仅培训年级) | NHS 苏格兰 |
| 苏格兰 | PCS(DD)2025/01+增编 | 2025/26(完整回合) | NHS 苏格兰 |
| 威尔士 | 并发( W) 01/2026 (英语) | 第2026/27号决议 | NHS 威尔士 |
| 威尔士 | 并发( W) 01/2025 (英语) | 2025/26 (英语) | NHS 威尔士 |
| 北爱尔兰 | HSC( TC8) 05/2025 | 2025/26 (英语) | DoH NI (英语) |
威尔士的2026/27回合提高3.5%(有薪牙医3.75%),并去掉了关闭的协理专家(MC01)代码,因此该分数只在2025/26年解决.
NI 2025/26 养恤金成员等级(HSC——不同的门槛值) 财务报告和审定财务报表 国家卫生与健康调查的费率来源于 HSC 养恤金。 。 。 .
数据如何模拟
循环在结构上差异很大(节点训练点,顾问阈值,SAS体验波段,GP范围,牙齿脊椎),因此数据被构建为三层,从统一域模型中去掉抄录忠心:
- 逐字记录 (单位:千美元)
src/circulars/*.ts)——每个PDF中一个文件,每个表格以1:1的出处顺序以一行形状来收录该表格的自列,在引用附件/节/页的评论下. 通知中的每个表格要么是转录的,要么是 记录有原因 因为跳过它,所以没有什么是默默地掉下来的,并且每个文件diffs 与 PDF 从上到下. - 翻译层 (单位:千美元)
src/medical-scales.ts, (中文(简体) ),src/dental-scales.ts) ——选择哪个尺度将计算器输入,并将每个逐字记录行映射到一个犬形尺度点. 默认情况下包括:封闭到新进入的年级、下放培训的变体、全科医生登记员和社区牙科服务都设有电线. - Canonical 域名 (单位:千美元)
getMedicalScales编号 :getDentalScales+ 键medicalResolver编号 :dentalResolver() 制服(grade, nation, year) → scale points视图,形状与 AFC 解析器相同.
范围. (a) 国家 每一个基本薪金表,包括仍然付给在职者的封闭到新进入职等,加上 (b) 国家 以年度英镑表示的收入影响补助(临床影响/优秀奖、公共卫生和强度补助)。 纯费用表(英里、收费)和自营职业的GDS/UDA牙医合同收入都超出范围.
未公布的数据会响亮失败 . 英格兰和威尔士公布完整2026/27轮. 苏格兰的2026/27循环提高培训等级,因此其顾问/SAS/GP/牙科分级表决定2025/26回合(PCS(DD)2025/01)完成,直到苏格兰政府公布非培训提升;北爱尔兰的最新通知是2025/26通。 每个职等在所列举年份解决 latestYearFor(grade, nation) 数据从不默不作声地转发,对一个未公布的(年份、国家)的查询,而不是忽略另一个国家或年份的数字.
测试固定装置
tests/working-week.test.ts 将AFC周及其365/7年 与苏格兰的每分每分每分 每分每分每分每分每分每分每分 每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分每分一份工资工资工资,以及每分每分每分每分每分每分每分每分每分每分每分每分.
tests/fixtures/band-take-home.csv - 涵盖所有4个民族(英格兰、苏格兰、威尔士、北爱尔兰)的5、7、8a个波段的黄金值行,两个纳税年、3个高考区和兼职(0.6 FTE)。 毛额数字取自 getAfcScales(year, nation) 使用上述来源。 养恤金、税收、NI和净值按下列方法计算: nhsTakeHome 应对照:
- NHS 雇主薪资表 2025/26 财务报告和审定财务报表 第2026/27号决议 英格兰/荷兰毛额
- PCS(AFC)2026/1 (中文(简体) ) 附件B,苏格兰毛额
- NHSBSA 养恤金缴款率 2025/26 养恤金等级比率
纳税年份
AFC 规模+养恤金覆盖面(所有四个国家):
| 年份 | 缩放 | 养恤金 |
|---|---|---|
| 2023-24 (英语) | 对 | 对 |
| 2024-25 (英语) | 对 | 对 |
| 2025-26 (简体中文) | 对 | 对 |
| 2026-27 (中文(简体) ) | 对 | 对 |
医疗和牙科覆盖率为人均覆盖率(英格兰/威尔士2026/27;苏格兰2026/27培训年级,其余2025/26;NI2025/26)——见 医疗和牙科工资表。 。 。 .
发展
npm run check # lint + typecheck + knip + jscpd
# + api-docs drift gate + test
npm run build # compile to dist/
npm test # vitest
npm run test:watch # vitest watch mode
许可证
AGPL-3.0-仅见 自由主义. 版权 2026 Casomo Ltd.
没有任何关联例外: 将这个库与你自己的代码合并, 合并的作品也是AGPL, 让人们通过网络使用它, 迫使您提供它的来源 。 收费不是引发这种情况的原因,不收费也不是豁免。 商业许可证可用于需要关闭的用途——通过 casomoltd.com (英语)。 。 。 .