feat:独生子女年度清算应发、实发计算逻辑修复
This commit is contained in:
+7
-25
@@ -403,7 +403,7 @@ public class OnlyChildFeeService {
|
|||||||
/**
|
/**
|
||||||
* 保存领取人首次实际发放月份,各年度共用,并重算未确认草稿。
|
* 保存领取人首次实际发放月份,各年度共用,并重算未确认草稿。
|
||||||
* @param d 领取人、当前办理年度和首次实际发放月份
|
* @param d 领取人、当前办理年度和首次实际发放月份
|
||||||
* 起发前及停发当月起为零,发放期间每月10元;单月人工修订优先,已确认批次禁止修改。
|
* 起发前为零、起发后每月10元,不按待遇停发月自动清零实发;单月人工修订优先,已确认批次禁止修改。
|
||||||
*/
|
*/
|
||||||
public void paymentStart(JSONObject d) {
|
public void paymentStart(JSONObject d) {
|
||||||
access("settlement"); lock();
|
access("settlement"); lock();
|
||||||
@@ -444,32 +444,14 @@ public class OnlyChildFeeService {
|
|||||||
// 先读取单月修订记录,再按首次发放月份计算默认实发。
|
// 先读取单月修订记录,再按首次发放月份计算默认实发。
|
||||||
JSONObject actual = get("M:" + user + ":" + period);
|
JSONObject actual = get("M:" + user + ":" + period);
|
||||||
if (actual != null && !Boolean.TRUE.equals(actual.getBool("automatic"))) return actual;
|
if (actual != null && !Boolean.TRUE.equals(actual.getBool("automatic"))) return actual;
|
||||||
// 到龄或资格终止当月自动停发;真实多发由上方的单月修订记录保留。
|
|
||||||
if (automaticPaymentStopped(q, month(period))) {
|
|
||||||
return new JSONObject().set("userId", user).set("month", period).set("automatic", true)
|
|
||||||
.set("paid", BigDecimal.ZERO).set("source", "按停发月份自动停发");
|
|
||||||
}
|
|
||||||
if (baseline == null) return actual;
|
if (baseline == null) return actual;
|
||||||
// 各年度共用首次发放月份,仅在尚未停发的期间自动计发。
|
// 待遇停发只影响应发,不能据此认定工资已停发;保留实发差额供管理员登记扣回。
|
||||||
YearMonth start = month(baseline.getStr("actualStartMonth"));
|
YearMonth start = month(baseline.getStr("actualStartMonth"));
|
||||||
return new JSONObject().set("userId", user).set("month", period).set("automatic", true)
|
return new JSONObject().set("userId", user).set("month", period).set("automatic", true)
|
||||||
.set("paid", month(period).isBefore(start) ? BigDecimal.ZERO : TEN)
|
.set("paid", month(period).isBefore(start) ? BigDecimal.ZERO : TEN)
|
||||||
.set("source", "按首次实际发放月份" + start + "自动计算");
|
.set("source", "按首次实际发放月份" + start + "自动计算");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean automaticPaymentStopped(JSONObject q, YearMonth period) {
|
|
||||||
// 资料更正按生效月份分段,不能用更正后的停发月倒改此前的默认实发。
|
|
||||||
JSONArray history = q.getJSONArray("benefitHistory");
|
|
||||||
if (history != null) {
|
|
||||||
for (int i = 0; i < history.size(); i++) {
|
|
||||||
JSONObject version = history.getJSONObject(i);
|
|
||||||
if (period.isBefore(month(version.getStr("untilMonth")))) return automaticPaymentStopped(version, period);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Boolean.FALSE.equals(q.getBool("eligible")) || !period.isBefore(month(q.getStr("stopMonth")))
|
|
||||||
|| (q.getStr("endMonth") != null && !period.isBefore(month(q.getStr("endMonth"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 11、12月归属下一年度清算,每批覆盖上一年11月至当年10月。
|
// 11、12月归属下一年度清算,每批覆盖上一年11月至当年10月。
|
||||||
private int settlementYear(YearMonth period) {
|
private int settlementYear(YearMonth period) {
|
||||||
return period.getMonthValue() >= 11 ? period.getYear() + 1 : period.getYear();
|
return period.getMonthValue() >= 11 ? period.getYear() + 1 : period.getYear();
|
||||||
@@ -478,7 +460,7 @@ public class OnlyChildFeeService {
|
|||||||
private void refreshDraft(JSONObject draft) {
|
private void refreshDraft(JSONObject draft) {
|
||||||
int year = draft.getInt("year");
|
int year = draft.getInt("year");
|
||||||
draft.set("rows", calculate(year)).set("periodStart", YearMonth.of(year - 1, 11).toString())
|
draft.set("rows", calculate(year)).set("periodStart", YearMonth.of(year - 1, 11).toString())
|
||||||
.set("periodEnd", YearMonth.of(year, 10).toString()).set("automaticStop", true).set("qualificationStartSynced", true);
|
.set("periodEnd", YearMonth.of(year, 10).toString()).set("automaticStop", false).set("qualificationStartSynced", true);
|
||||||
put("B:" + year, "BATCH", null, String.valueOf(year), draft);
|
put("B:" + year, "BATCH", null, String.valueOf(year), draft);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,7 +499,7 @@ public class OnlyChildFeeService {
|
|||||||
.set("source", actual == null ? null : actual.getStr("source")).set("recovered", deducted).set("pending", remaining)
|
.set("source", actual == null ? null : actual.getStr("source")).set("recovered", deducted).set("pending", remaining)
|
||||||
.set("note", m.equals(q.getStr("stopMonth")) ? "满18周岁当月停发" : ""));
|
.set("note", m.equals(q.getStr("stopMonth")) ? "满18周岁当月停发" : ""));
|
||||||
}
|
}
|
||||||
// 已在往期停发且本期无应发、真实实发或扣回记录的人员,不重复进入年度清算。
|
// 往期已停发但本期仍有实发的人员继续清算,仅排除本期应发、实发及扣回均为零的人员。
|
||||||
if (end.compareTo(periodStart.toString()) < 0 && expected.signum() == 0 && paid.signum() == 0 && back.signum() == 0) continue;
|
if (end.compareTo(periodStart.toString()) < 0 && expected.signum() == 0 && paid.signum() == 0 && back.signum() == 0) continue;
|
||||||
rows.add(new JSONObject(q.toString()).set("actualStartMonth", baseline == null ? null : baseline.getStr("actualStartMonth"))
|
rows.add(new JSONObject(q.toString()).set("actualStartMonth", baseline == null ? null : baseline.getStr("actualStartMonth"))
|
||||||
.set("months", months).set("due", expected).set("paid", complete ? paid : null)
|
.set("months", months).set("due", expected).set("paid", complete ? paid : null)
|
||||||
@@ -535,10 +517,10 @@ public class OnlyChildFeeService {
|
|||||||
access("settlement", "changes"); lock();
|
access("settlement", "changes"); lock();
|
||||||
require(year >= 1900 && year <= 9999, "年度无效");
|
require(year >= 1900 && year <= 9999, "年度无效");
|
||||||
JSONObject b = get("B:" + year);
|
JSONObject b = get("B:" + year);
|
||||||
// 自动停发及起发月同步只重算未确认草稿,已确认批次的金额及期间保持冻结。
|
// 重算曾按待遇停发月清零实发的未确认草稿;已确认批次的金额及期间保持冻结。
|
||||||
if (b != null && "草稿".equals(b.getStr("status"))
|
if (b != null && "草稿".equals(b.getStr("status"))
|
||||||
&& (!YearMonth.of(year - 1, 11).toString().equals(b.getStr("periodStart"))
|
&& (!YearMonth.of(year - 1, 11).toString().equals(b.getStr("periodStart"))
|
||||||
|| !Boolean.TRUE.equals(b.getBool("automaticStop"))
|
|| !Boolean.FALSE.equals(b.getBool("automaticStop"))
|
||||||
|| !Boolean.TRUE.equals(b.getBool("qualificationStartSynced")))) refreshDraft(b);
|
|| !Boolean.TRUE.equals(b.getBool("qualificationStartSynced")))) refreshDraft(b);
|
||||||
if (b != null && b.getStr("periodStart") == null) {
|
if (b != null && b.getStr("periodStart") == null) {
|
||||||
b.set("periodStart", YearMonth.of(year, 1).toString()).set("periodEnd", YearMonth.of(year, 10).toString());
|
b.set("periodStart", YearMonth.of(year, 1).toString()).set("periodEnd", YearMonth.of(year, 10).toString());
|
||||||
@@ -564,7 +546,7 @@ public class OnlyChildFeeService {
|
|||||||
boolean pending = false;
|
boolean pending = false;
|
||||||
for (int i = 0; i < rows.size(); i++) pending |= rows.getJSONObject(i).getBigDecimal("pending", BigDecimal.ZERO).signum() > 0;
|
for (int i = 0; i < rows.size(); i++) pending |= rows.getJSONObject(i).getBigDecimal("pending", BigDecimal.ZERO).signum() > 0;
|
||||||
JSONObject b = new JSONObject().set("year", year).set("id", year + "年11月").set("rows", rows)
|
JSONObject b = new JSONObject().set("year", year).set("id", year + "年11月").set("rows", rows)
|
||||||
.set("periodStart", YearMonth.of(year - 1, 11).toString()).set("periodEnd", YearMonth.of(year, 10).toString()).set("automaticStop", true).set("qualificationStartSynced", true)
|
.set("periodStart", YearMonth.of(year - 1, 11).toString()).set("periodEnd", YearMonth.of(year, 10).toString()).set("automaticStop", false).set("qualificationStartSynced", true)
|
||||||
.set("status", confirm ? (pending ? "已确认" : "已完成") : "草稿")
|
.set("status", confirm ? (pending ? "已确认" : "已完成") : "草稿")
|
||||||
.set("operator", SecurityUtil.getUserId()).set("time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
.set("operator", SecurityUtil.getUserId()).set("time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||||
put("B:" + year, "BATCH", null, String.valueOf(year), b);
|
put("B:" + year, "BATCH", null, String.valueOf(year), b);
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ new Vue({
|
|||||||
row.actualStartMonth=previous;
|
row.actualStartMonth=previous;
|
||||||
if(!selected||selected===previous)return;
|
if(!selected||selected===previous)return;
|
||||||
this.perform(async()=>{
|
this.perform(async()=>{
|
||||||
try{await this.$confirm('将首次实际发放月份设为 '+selected+'。更改后,各年度未确认的实发记录会重新计算,停发当月起默认实发为0;单月修订和已确认快照保留。是否确认?','确认起发月份',{type:'warning',confirmButtonText:'确认保存',cancelButtonText:'取消'});}
|
try{await this.$confirm('将首次实际发放月份设为 '+selected+'。更改后,各年度未确认的实发记录按起发前0元、起发后每月10元重新计算,待遇停发月份只影响应发;单月修订和已确认快照保留。是否确认?','确认起发月份',{type:'warning',confirmButtonText:'确认保存',cancelButtonText:'取消'});}
|
||||||
catch(e){return;}
|
catch(e){return;}
|
||||||
await this.request('paymentStart',{data:JSON.stringify({userId:row.userId,year:Number(this.year),actualStartMonth:selected})});
|
await this.request('paymentStart',{data:JSON.stringify({userId:row.userId,year:Number(this.year),actualStartMonth:selected})});
|
||||||
await this.fetchSettlement();this.expandedRowKeys=[row.userId];
|
await this.fetchSettlement();this.expandedRowKeys=[row.userId];
|
||||||
|
|||||||
Reference in New Issue
Block a user