fix: 公积金基数上下限独立于社保
问题:SocialYearStandard 只有一套 baseMin/baseMax,社保和公积金 共用,但公积金下限通常是最低工资标准(如北京2420),远低于社保 下限(如北京6326)。 修复: - SocialYearStandard 新增 housingBaseMin/housingBaseMax 字段 - clampHousingFundBase 优先用公积金专用上下限,为0时回退到社保 - calcHousingFund 同样优先用公积金专用上下限 - 前端公积金年度标准表单加公积金基数上下限输入 - 前端公积金当前标准展示用公积金专用上下限 同时修复 blank_employees/blank_all 模式跳过试用期工资覆盖 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -522,6 +522,8 @@ model SocialYearStandard {
|
||||
// 公积金比例(type=HOUSING 时使用)
|
||||
housingOrg Float @default(12)
|
||||
housingEmp Float @default(12)
|
||||
housingBaseMin Float @default(0) // 公积金基数下限(0 时 fallback 到 baseMin)
|
||||
housingBaseMax Float @default(0) // 公积金基数上限(0 时 fallback 到 baseMax)
|
||||
|
||||
// 最低工资标准(按参保城市,每年调整)
|
||||
minWage Float @default(0) // 当地月最低工资标准(0=不检查)
|
||||
|
||||
@@ -205,6 +205,8 @@ const yearStandardSchema = z.object({
|
||||
extraInsurances: z.any().optional(),
|
||||
housingOrg: z.number().optional(),
|
||||
housingEmp: z.number().optional(),
|
||||
housingBaseMin: z.number().min(0).optional(),
|
||||
housingBaseMax: z.number().min(0).optional(),
|
||||
minWage: z.number().min(0).optional(),
|
||||
})
|
||||
|
||||
|
||||
@@ -39,7 +39,12 @@ async function clampHousingFundBase(orgId: string, base: number, city?: string,
|
||||
where: { accountId, isCurrent: true },
|
||||
orderBy: { effectiveFrom: 'desc' },
|
||||
})
|
||||
if (standard) return Math.min(Math.max(base, standard.baseMin), standard.baseMax)
|
||||
if (standard) {
|
||||
// 公积金专用上下限(housingBaseMin/Max),为0时回退到社保的 baseMin/baseMax
|
||||
const min = standard.housingBaseMin > 0 ? standard.housingBaseMin : standard.baseMin
|
||||
const max = standard.housingBaseMax > 0 ? standard.housingBaseMax : standard.baseMax
|
||||
return Math.min(Math.max(base, min), max)
|
||||
}
|
||||
}
|
||||
// 回退到旧配置表
|
||||
const config = await prisma.housingFundConfig.findFirst({
|
||||
|
||||
@@ -139,7 +139,10 @@ export function calcSocialInsurance(base: number, config: any) {
|
||||
}
|
||||
|
||||
export function calcHousingFund(base: number, config: any) {
|
||||
const actualBase = Math.min(Math.max(base, config.baseMin), config.baseMax)
|
||||
// 公积金专用上下限(housingBaseMin/Max),为0时回退到社保的 baseMin/baseMax
|
||||
const min = (config.housingBaseMin && config.housingBaseMin > 0) ? config.housingBaseMin : config.baseMin
|
||||
const max = (config.housingBaseMax && config.housingBaseMax > 0) ? config.housingBaseMax : config.baseMax
|
||||
const actualBase = Math.min(Math.max(base, min), max)
|
||||
const housingEmp = actualBase * config.housingEmp / 100
|
||||
const housingOrg = actualBase * config.housingOrg / 100
|
||||
return { actualBase, housingEmp, housingOrg }
|
||||
|
||||
@@ -52,6 +52,7 @@ export function AccountCard({
|
||||
// 公积金字段
|
||||
accountType: account.accountType || 'BASIC',
|
||||
housingOrg: 12, housingEmp: 12,
|
||||
housingBaseMin: 0, housingBaseMax: 0,
|
||||
})
|
||||
|
||||
// 查询当前年度标准(展开时才查询)
|
||||
@@ -331,8 +332,8 @@ export function AccountCard({
|
||||
)}
|
||||
<div className="grid md:grid-cols-4 gap-3 text-sm">
|
||||
<div className="flex justify-between border-b pb-1.5"><span className="text-gray-500">账户类型</span><span className="font-medium">{config.accountType === 'SUPPLEMENTARY' ? '补充公积金' : '基本公积金'}</span></div>
|
||||
<div className="flex justify-between border-b pb-1.5"><span className="text-gray-500">缴费基数下限</span><span className="font-medium">¥{fmt(config.baseMin)}</span></div>
|
||||
<div className="flex justify-between border-b pb-1.5"><span className="text-gray-500">缴费基数上限</span><span className="font-medium">¥{fmt(config.baseMax)}</span></div>
|
||||
<div className="flex justify-between border-b pb-1.5"><span className="text-gray-500">缴费基数下限</span><span className="font-medium">¥{fmt(config.housingBaseMin > 0 ? config.housingBaseMin : config.baseMin)}</span></div>
|
||||
<div className="flex justify-between border-b pb-1.5"><span className="text-gray-500">缴费基数上限</span><span className="font-medium">¥{fmt(config.housingBaseMax > 0 ? config.housingBaseMax : config.baseMax)}</span></div>
|
||||
<div className="flex justify-between border-b pb-1.5"><span className="text-gray-500">公积金(企业)</span><span className="font-medium">{config.housingOrg}%</span></div>
|
||||
<div className="flex justify-between border-b pb-1.5"><span className="text-gray-500">公积金(个人)</span><span className="font-medium">{config.housingEmp}%</span></div>
|
||||
</div>
|
||||
@@ -610,6 +611,8 @@ export function AccountCard({
|
||||
</div>
|
||||
<div><Label>公积金(企业%)</Label><Input type="number" step="0.1" value={newVersion.housingOrg} onChange={(e) => setNewVersion({ ...newVersion, housingOrg: Number(e.target.value) })} /></div>
|
||||
<div><Label>公积金(个人%)</Label><Input type="number" step="0.1" value={newVersion.housingEmp} onChange={(e) => setNewVersion({ ...newVersion, housingEmp: Number(e.target.value) })} /></div>
|
||||
<div><Label>公积金基数下限</Label><Input type="number" value={newVersion.housingBaseMin} onChange={(e) => setNewVersion({ ...newVersion, housingBaseMin: Number(e.target.value) })} placeholder="0=用社保下限" /><p className="text-xs text-gray-400 mt-1">0 时使用缴费基数下限</p></div>
|
||||
<div><Label>公积金基数上限</Label><Input type="number" value={newVersion.housingBaseMax} onChange={(e) => setNewVersion({ ...newVersion, housingBaseMax: Number(e.target.value) })} placeholder="0=用社保上限" /><p className="text-xs text-gray-400 mt-1">0 时使用缴费基数上限</p></div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user