|
|
@@ -7,6 +7,7 @@ import com.actionsoft.bpms.server.UserContext;
|
|
|
import com.actionsoft.bpms.util.DBSql;
|
|
|
import com.actionsoft.sdk.local.SDK;
|
|
|
import com.actionsoft.sdk.local.api.Logger;
|
|
|
+import com.awspaas.user.apps.donenow_ctt.PeriodCalculationUtil;
|
|
|
import com.awspaas.user.apps.donenow_ctt.cttConstant;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
|
@@ -128,25 +129,46 @@ public class contractService {
|
|
|
|
|
|
String contractNo = contractBO.getString("NO");
|
|
|
if (StringUtils.isBlank(contractNo) || contractNo.indexOf("XHT") != 0) {
|
|
|
- contractNo = SDK.getRuleAPI().executeAtScript("@sequenceYear(@companyId_contract,5)");
|
|
|
- String DISTRICT_ID = DBSql.getString("select DISTRICT_ID from BO_EU_DNCRM_ACCOUNT where ID=?", new Object[]{contractBO.getString("ACCOUNT_ID")});
|
|
|
- String cssx = "SH";//城市缩写
|
|
|
- if (StringUtils.isNotBlank(DISTRICT_ID)) {
|
|
|
- RowMap city = DBSql.getMap("SELECT EXTTEXT1,EXTTEXT2 FROM BO_ACT_DICT_KV_ITEM WHERE DICTKEY = 'GB.ADDR' AND ITEMNO= ?", new Object[]{DISTRICT_ID});
|
|
|
- if (city != null) {
|
|
|
- cssx = city.getString("EXTTEXT1");
|
|
|
- if (!cssx.contains("市")) {
|
|
|
- cssx = city.getString("EXTTEXT2");
|
|
|
+
|
|
|
+ //框架协议子合同编号:框架协议合同编码-S001
|
|
|
+ String FRAMEWORK = contractBO.getString("FRAMEWORK");
|
|
|
+ if (StringUtils.isNotBlank(FRAMEWORK)) {
|
|
|
+
|
|
|
+ String orgContractNo = DBSql.getString("select NO from BO_EU_DNCTT_CONTRACT where ID=? ORDER BY NO DESC", new Object[]{FRAMEWORK});
|
|
|
+ List<String> noList = DBSql.getList("select NO from BO_EU_DNCTT_CONTRACT where FRAMEWORK=? order by NO desc", String.class, new Object[]{FRAMEWORK});
|
|
|
+ if (noList.size() > 0) {
|
|
|
+ String lastNo = noList.get(0);
|
|
|
+ lastNo = lastNo.replace(orgContractNo + "-S", "");
|
|
|
+ // lastNo 去除前面的0
|
|
|
+ lastNo = lastNo.replaceAll("^0+", "");
|
|
|
+ contractNo = orgContractNo + "-S" + String.format("%03d", Integer.parseInt(lastNo) + 1);
|
|
|
+ contractBO.set("NO", contractNo);
|
|
|
+ } else {
|
|
|
+ contractNo = orgContractNo + "-SOO1";
|
|
|
+ contractBO.set("NO", contractNo);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ contractNo = SDK.getRuleAPI().executeAtScript("@sequenceYear(@companyId_contract,5)");
|
|
|
+ String DISTRICT_ID = DBSql.getString("select DISTRICT_ID from BO_EU_DNCRM_ACCOUNT where ID=?", new Object[]{contractBO.getString("ACCOUNT_ID")});
|
|
|
+ String cssx = "SH";//城市缩写
|
|
|
+ if (StringUtils.isNotBlank(DISTRICT_ID)) {
|
|
|
+ RowMap city = DBSql.getMap("SELECT EXTTEXT1,EXTTEXT2 FROM BO_ACT_DICT_KV_ITEM WHERE DICTKEY = 'GB.ADDR' AND ITEMNO= ?", new Object[]{DISTRICT_ID});
|
|
|
+ if (city != null) {
|
|
|
+ cssx = city.getString("EXTTEXT1");
|
|
|
+ if (!cssx.contains("市")) {
|
|
|
+ cssx = city.getString("EXTTEXT2");
|
|
|
+ }
|
|
|
+ //如果 cssx="上海市" 则输出 SH
|
|
|
+ cssx = getCityAbbreviation(cssx);
|
|
|
}
|
|
|
- //如果 cssx="上海市" 则输出 SH
|
|
|
- cssx = getCityAbbreviation(cssx);
|
|
|
}
|
|
|
+ contractNo = "XHT-" + cssx + "-" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + "-" + contractNo;
|
|
|
+ contractBO.set("NO", contractNo);
|
|
|
}
|
|
|
- contractNo = "XHT-" + cssx + "-" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + "-" + contractNo;
|
|
|
- contractBO.set("NO", contractNo);
|
|
|
}
|
|
|
|
|
|
- if (idApply) SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_APPLY", contractBO);//更新合同
|
|
|
+ if (idApply)
|
|
|
+ SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_APPLY", contractBO);//更新合同
|
|
|
else {
|
|
|
dn.recordFormChanges.record(uc, contractBO, "合同编辑");
|
|
|
SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT", contractBO);
|
|
|
@@ -340,11 +362,16 @@ public class contractService {
|
|
|
List<BO> serviceList = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE").connection(conn).addQuery("CONTRACT_ID =", contract.get("ID")).list();
|
|
|
|
|
|
for (BO service : serviceList) {
|
|
|
- AddServiceServiceBundleOne(uc, conn, contract, service);
|
|
|
+ // AddServiceServiceBundleOne(uc, conn, contract, service);
|
|
|
|
|
|
- ServiceAutoRenew(uc, service, END_DATE, conn);
|
|
|
- }
|
|
|
+ //新增服务周期
|
|
|
+ AddService(uc, conn, contract, service);
|
|
|
+
|
|
|
+ // ServiceAutoRenew(uc, service, END_DATE, conn);
|
|
|
|
|
|
+ //修改合同结束日期
|
|
|
+ ServiceAdjustEndDate(uc, service, END_DATE, conn);
|
|
|
+ }
|
|
|
|
|
|
conn.commit();
|
|
|
return true;
|
|
|
@@ -412,6 +439,15 @@ public class contractService {
|
|
|
|
|
|
|
|
|
if (!PERIOD_END.isEqual(END_DATE)) {
|
|
|
+
|
|
|
+ BigDecimal SERVICE_UNIT_COST = service.get("UNIT_COST", BigDecimal.class);//服务单元成本
|
|
|
+ //需要采购
|
|
|
+ if (service.getString("NEED_PURCHASE").equals("1")) {
|
|
|
+ BigDecimal prate = GetPeriodRate(service.getString("PERIOD_TYPE"), service.getString("PURCHASE_PERIOD_TYPE"));
|
|
|
+ SERVICE_UNIT_COST = SERVICE_UNIT_COST.multiply(prate);
|
|
|
+ }
|
|
|
+ BigDecimal SERVICE_TOTAL_COST = multiply(SERVICE_UNIT_COST, service.get("QUANTITY"));//服务总成本
|
|
|
+
|
|
|
if (PERIOD_END.isBefore(END_DATE)) {
|
|
|
contractServiceLogger.info("服务周期延长--" + service.getString("NAME"));
|
|
|
//延长
|
|
|
@@ -421,7 +457,8 @@ public class contractService {
|
|
|
LocalDate period_begin_date = getLocalDate(servicePeriod.get("PERIOD_BEGIN_DATE"));
|
|
|
LocalDate period_end_date = getLocalDate(servicePeriod.get("PERIOD_END_DATE"));
|
|
|
|
|
|
- String maxPeriod = servicePeriod.getString("PERIOD_TYPE");
|
|
|
+ String maxPeriod = service.getString("PERIOD_TYPE");
|
|
|
+
|
|
|
LocalDate firstPeriodEnd = getNextPeriodStart(period_begin_date, maxPeriod).minusDays(1);//本周期结束时间
|
|
|
LocalDate SATRT_DATE = null;
|
|
|
if (period_end_date.isBefore(firstPeriodEnd)) {
|
|
|
@@ -433,10 +470,20 @@ public class contractService {
|
|
|
SATRT_DATE = firstPeriodEnd.plusDays(1);
|
|
|
}
|
|
|
servicePeriod.set("PERIOD_END_DATE", new_period_end_date);
|
|
|
+
|
|
|
+ /*
|
|
|
BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, new_period_end_date), GetPeriodDays(period_begin_date, period_end_date));
|
|
|
servicePeriod.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), periodRate));
|
|
|
servicePeriod.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), periodRate));
|
|
|
servicePeriod.set("PARTYA_PERIOD_PRICE", multiply(servicePeriod.get("PARTYA_PERIOD_PRICE"), periodRate));
|
|
|
+ */
|
|
|
+
|
|
|
+ BigDecimal periodRate = divideToBigDecimal(DateRateCalculator(period_begin_date, new_period_end_date, false), (GetPeriodMonth(maxPeriod)));
|
|
|
+
|
|
|
+ servicePeriod.set("PERIOD_PRICE", multiply(service.get("TOTAL_COST"), periodRate));
|
|
|
+ servicePeriod.set("PERIOD_COST", multiply(SERVICE_TOTAL_COST, periodRate));
|
|
|
+ servicePeriod.set("PARTYA_PERIOD_PRICE", multiply(service.get("PARTYA_TOTAL_PRICE"), periodRate));
|
|
|
+
|
|
|
servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
|
|
|
SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriod, conn);
|
|
|
} else {
|
|
|
@@ -457,8 +504,10 @@ public class contractService {
|
|
|
BigDecimal periodRate = BigDecimal.ONE;
|
|
|
LocalDate periodEnd = getNextPeriodStart(SATRT_DATE, maxPeriod).minusDays(1);//本周期结束时间
|
|
|
if (periodEnd.isAfter(END_DATE)) {//如果结束日期大于合同结束日期,则计算结束日期和合同结束日期的差值,并计算该差值占整周期的比例
|
|
|
- periodRate = divideToBigDecimal(GetPeriodDays(SATRT_DATE, END_DATE), GetPeriodDays(SATRT_DATE, periodEnd));
|
|
|
+ // periodRate = divideToBigDecimal(GetPeriodDays(SATRT_DATE, END_DATE), GetPeriodDays(SATRT_DATE, periodEnd));
|
|
|
periodEnd = END_DATE;
|
|
|
+
|
|
|
+ periodRate = divideToBigDecimal(DateRateCalculator(SATRT_DATE, periodEnd, false), (GetPeriodMonth(maxPeriod)));
|
|
|
}
|
|
|
BO csp = new BO();//服务周期
|
|
|
csp.setAll(servicePeriod.asMap());
|
|
|
@@ -467,9 +516,9 @@ public class contractService {
|
|
|
BigDecimal period_price = multiply(service.get("UNIT_PRICE"), service.get("QUANTITY"));
|
|
|
period_price = periodRate.multiply(period_price);
|
|
|
csp.set("PERIOD_PRICE", period_price);
|
|
|
- BigDecimal period_cost = multiply(service.get("UNIT_COST"), service.get("QUANTITY"));
|
|
|
- period_cost = periodRate.multiply(period_cost);
|
|
|
- csp.set("PERIOD_COST", period_cost);
|
|
|
+
|
|
|
+ csp.set("PERIOD_COST", periodRate.multiply(SERVICE_TOTAL_COST));
|
|
|
+
|
|
|
csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
|
|
|
|
|
|
csp.set("PARTYA_PERIOD_PRICE", multiply(service.get("PARTYA_TOTAL_PRICE"), periodRate));
|
|
|
@@ -506,10 +555,19 @@ public class contractService {
|
|
|
servicePeriod.set("PERIOD_END_DATE", END_DATE);
|
|
|
LocalDate period_begin_date = getLocalDate(servicePeriod.get("PERIOD_BEGIN_DATE"));
|
|
|
LocalDate period_end_date = getLocalDate(servicePeriod.get("PERIOD_END_DATE"));
|
|
|
+ /*
|
|
|
BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, END_DATE), GetPeriodDays(period_begin_date, period_end_date));
|
|
|
servicePeriod.set("PERIOD_PRICE", multiply(servicePeriod.get("PERIOD_PRICE"), periodRate));
|
|
|
servicePeriod.set("PERIOD_COST", multiply(servicePeriod.get("PERIOD_COST"), periodRate));
|
|
|
servicePeriod.set("PARTYA_PERIOD_PRICE", multiply(servicePeriod.get("PARTYA_PERIOD_PRICE"), periodRate));
|
|
|
+ */
|
|
|
+
|
|
|
+ BigDecimal periodRate = divideToBigDecimal(DateRateCalculator(period_begin_date, END_DATE, false), (GetPeriodMonth(service.getString("PERIOD_TYPE"))));
|
|
|
+
|
|
|
+ servicePeriod.set("PERIOD_PRICE", multiply(service.get("TOTAL_COST"), periodRate));
|
|
|
+ servicePeriod.set("PERIOD_COST", multiply(SERVICE_TOTAL_COST, periodRate));
|
|
|
+ servicePeriod.set("PARTYA_PERIOD_PRICE", multiply(service.get("PARTYA_TOTAL_PRICE"), periodRate));
|
|
|
+
|
|
|
servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
|
|
|
SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", servicePeriod, conn);
|
|
|
|
|
|
@@ -524,9 +582,99 @@ public class contractService {
|
|
|
}
|
|
|
|
|
|
DBSql.update(conn, "update BO_EU_DNCTT_CONTRACT_SERVICE set PERIOD=?,ADJUST_PERIOD=? where ID=? and BINDID=?", new Object[]{PERIOD, ADJUST_PERIOD, service.get("ID"), service.get("BINDID")});
|
|
|
- }
|
|
|
|
|
|
|
|
|
+ //付款计划延期
|
|
|
+ if (PERIOD_END.isBefore(END_DATE)) {
|
|
|
+ contractServiceLogger.info("服务周期延长--" + service.getString("NAME"));
|
|
|
+ //延长
|
|
|
+ List<BO> payPeriodList = SDK.getBOAPI().query("BO_EU_DNIVT_ORDER_PAYMENT_PLAN").connection(conn).addQuery("CONTRACT_SERVICE_ID =", service.getId()).addQuery("PLAN_DATE >=", LocalDateYYYYMMDD(PERIOD_END)).orderBy("PLAN_DATE").desc().list();
|
|
|
+
|
|
|
+ BO payPeriod = payPeriodList.get(0);
|
|
|
+ LocalDate period_begin_date = getLocalDate(payPeriod.get("PLAN_DATE"));
|
|
|
+ LocalDate period_end_date = getLocalDate(PERIOD_END);//上次结束日期
|
|
|
+
|
|
|
+ String maxPeriod = service.getString("PURCHASE_PERIOD_TYPE");//采购周期类型
|
|
|
+
|
|
|
+ LocalDate firstPeriodEnd = getNextPeriodStart(period_begin_date, maxPeriod).minusDays(1);//本周期结束时间
|
|
|
+ LocalDate SATRT_DATE = null;
|
|
|
+ if (period_end_date.isBefore(firstPeriodEnd)) {
|
|
|
+ LocalDate new_period_end_date;
|
|
|
+ if (END_DATE.isBefore(firstPeriodEnd)) {
|
|
|
+ new_period_end_date = END_DATE;
|
|
|
+ } else {
|
|
|
+ new_period_end_date = firstPeriodEnd;
|
|
|
+ SATRT_DATE = firstPeriodEnd.plusDays(1);
|
|
|
+ }
|
|
|
+ // BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, new_period_end_date), GetPeriodDays(period_begin_date, period_end_date));
|
|
|
+ // payPeriod.set("PLAN_AMOUNT", multiply(payPeriod.get("PLAN_AMOUNT"), periodRate));//计划付款金额
|
|
|
+
|
|
|
+ BigDecimal periodRate = divideToBigDecimal(DateRateCalculator(period_begin_date, new_period_end_date, false), (GetPeriodMonth(maxPeriod)));
|
|
|
+
|
|
|
+ payPeriod.set("PLAN_AMOUNT", multiply(SERVICE_TOTAL_COST, periodRate));//计划付款金额
|
|
|
+ payPeriod.set("REMAIN_AMOUNT", payPeriod.get("PLAN_AMOUNT", BigDecimal.class).subtract(payPeriod.get("PAY_AMOUNT", BigDecimal.class)));//剩余金额
|
|
|
+ SDK.getBOAPI().update("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", payPeriod, conn);
|
|
|
+ } else {
|
|
|
+ SATRT_DATE = period_end_date.plusDays(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SATRT_DATE != null && SATRT_DATE.isBefore(END_DATE)) {
|
|
|
+
|
|
|
+ //循环添加全部周期
|
|
|
+ while (!SATRT_DATE.isAfter(END_DATE)) {
|
|
|
+ BigDecimal periodRate = BigDecimal.ONE;
|
|
|
+ LocalDate periodEnd = getNextPeriodStart(SATRT_DATE, maxPeriod).minusDays(1);//本周期结束时间
|
|
|
+ if (periodEnd.isAfter(END_DATE)) {//如果结束日期大于合同结束日期,则计算结束日期和合同结束日期的差值,并计算该差值占整周期的比例
|
|
|
+ //periodRate = divideToBigDecimal(GetPeriodDays(SATRT_DATE, END_DATE), GetPeriodDays(SATRT_DATE, periodEnd));
|
|
|
+ periodEnd = END_DATE;
|
|
|
+
|
|
|
+ periodRate = divideToBigDecimal(DateRateCalculator(SATRT_DATE, END_DATE, false), (GetPeriodMonth(maxPeriod)));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ ProcessInstance processInstance = SDK.getProcessAPI().createProcessInstance("obj_5cb4ae4a42944fd0a9a284ff4c64c65d", uc.getUID(), "付款计划");
|
|
|
+ BO csp = new BO();//服务周期
|
|
|
+ csp.setAll(payPeriod.asMap());
|
|
|
+ csp.setBindId(processInstance.getId());
|
|
|
+ csp.set("PLAN_DATE", SATRT_DATE);
|
|
|
+ csp.set("PLAN_AMOUNT", periodRate.multiply(SERVICE_TOTAL_COST));
|
|
|
+ csp.set("REMAIN_AMOUNT", csp.get("PLAN_AMOUNT"));
|
|
|
+ SDK.getBOAPI().create("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", csp, processInstance, uc);
|
|
|
+
|
|
|
+
|
|
|
+ if (periodEnd != null) {
|
|
|
+ SATRT_DATE = periodEnd.plusDays(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (PERIOD_END.isAfter(END_DATE)) {
|
|
|
+ contractServiceLogger.info("服务周期缩短--" + service.getString("NAME"));
|
|
|
+ //缩短
|
|
|
+
|
|
|
+ List<BO> payPeriodList = SDK.getBOAPI().query("BO_EU_DNIVT_ORDER_PAYMENT_PLAN").connection(conn).addQuery("CONTRACT_SERVICE_ID =", service.getId()).addQuery("PLAN_DATE >=", LocalDateYYYYMMDD(PERIOD_END)).orderBy("PLAN_DATE").asc().list();
|
|
|
+
|
|
|
+ BO payPeriod = payPeriodList.get(0);
|
|
|
+ LocalDate period_begin_date = getLocalDate(payPeriod.get("PLAN_DATE"));
|
|
|
+
|
|
|
+ // BigDecimal periodRate = divideToBigDecimal(GetPeriodDays(period_begin_date, END_DATE), GetPeriodDays(period_begin_date, PERIOD_END));
|
|
|
+ // payPeriod.set("PLAN_AMOUNT", multiply(payPeriod.get("PLAN_AMOUNT"), periodRate));//计划付款金额
|
|
|
+
|
|
|
+ BigDecimal periodRate = divideToBigDecimal(DateRateCalculator(period_begin_date, END_DATE, false), (GetPeriodMonth(service.getString("PURCHASE_PERIOD_TYPE"))));
|
|
|
+ payPeriod.set("PLAN_AMOUNT", multiply(SERVICE_TOTAL_COST, periodRate));//计划付款金额
|
|
|
+
|
|
|
+ payPeriod.set("REMAIN_AMOUNT", payPeriod.get("PLAN_AMOUNT", BigDecimal.class).subtract(payPeriod.get("PAY_AMOUNT", BigDecimal.class)));//剩余金额
|
|
|
+ SDK.getBOAPI().update("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", payPeriod, conn);
|
|
|
+
|
|
|
+ for (BO period : payPeriodList) {
|
|
|
+ //删除
|
|
|
+ if (period.getString("ID").equals(payPeriod.getString("ID")) == false) {
|
|
|
+
|
|
|
+ DBSql.update(conn, "DELETE FROM BO_EU_DNIVT_ORDER_PAYMENT_PLAN WHERE ID=?", new Object[]{period.getString("ID")});
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
}
|
|
|
@@ -679,8 +827,13 @@ public class contractService {
|
|
|
|
|
|
// 合同周期更长,服务周期使用合同周期,单价和成本根据周期倍数翻倍
|
|
|
if (rate.compareTo(BigDecimal.ONE) > 0) {
|
|
|
- unit_cost = unit_cost.multiply(rate);
|
|
|
- service.set("UNIT_COST", unit_cost);
|
|
|
+
|
|
|
+ //是否需要采购
|
|
|
+ if (service.getString("NEED_PURCHASE").equals("1") == false) {
|
|
|
+ unit_cost = unit_cost.multiply(rate);
|
|
|
+ service.set("UNIT_COST", unit_cost);
|
|
|
+ }
|
|
|
+
|
|
|
unit_price = unit_price.multiply(rate);
|
|
|
service.set("UNIT_PRICE", unit_price);
|
|
|
// service.set("PERIOD_TYPE", contract.getString("PERIOD_TYPE"));//计费周期更新
|
|
|
@@ -698,7 +851,10 @@ public class contractService {
|
|
|
contractServiceLogger.info("计算-service-ADJUSTED_PRICE");
|
|
|
service.set("TOTAL_PRICE", multiply(service.get("QUANTITY"), service.get("UNIT_PRICE")));//总价
|
|
|
service.set("ADJUSTED_PRICE", multiply(service.get("QUANTITY"), service.get("UNIT_PRICE")));//总价
|
|
|
- service.set("TOTAL_COST", multiply(service.get("QUANTITY"), service.get("UNIT_COST")));//总价
|
|
|
+
|
|
|
+ //是否需要采购
|
|
|
+ if (service.getString("NEED_PURCHASE").equals("1") == false)
|
|
|
+ service.set("TOTAL_COST", multiply(service.get("QUANTITY"), service.get("UNIT_COST")));//总价
|
|
|
|
|
|
SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE", service, conn);//保存
|
|
|
|
|
|
@@ -736,10 +892,23 @@ public class contractService {
|
|
|
//如果不是从一号开始,则需要调整到从1号开始
|
|
|
if (StringUtils.isNotBlank(BILL_METHOD_ID) && BILL_METHOD_ID.equals("4601") && START_DATE.getDayOfMonth() != 1) {
|
|
|
//本月底日期
|
|
|
+ /*
|
|
|
LocalDate currMontLastDay = START_DATE.with(TemporalAdjusters.lastDayOfMonth());
|
|
|
- if (currMontLastDay.isBefore(END_DATE)) START_DATE = currMontLastDay.plusDays(1);//周期开始日期
|
|
|
+ if (currMontLastDay.isBefore(END_DATE))
|
|
|
+ START_DATE = currMontLastDay.plusDays(1);//周期开始日期
|
|
|
+
|
|
|
+ */
|
|
|
+
|
|
|
+ START_DATE = START_DATE.with(TemporalAdjusters.firstDayOfMonth());
|
|
|
}
|
|
|
|
|
|
+ BigDecimal SERVICE_UNIT_COST = service.get("UNIT_COST", BigDecimal.class);//服务单元成本
|
|
|
+ //需要采购
|
|
|
+ if (service.getString("NEED_PURCHASE").equals("1")) {
|
|
|
+ BigDecimal prate = GetPeriodRate(service.getString("PERIOD_TYPE"), service.getString("PURCHASE_PERIOD_TYPE"));
|
|
|
+ SERVICE_UNIT_COST = SERVICE_UNIT_COST.multiply(prate);
|
|
|
+ }
|
|
|
+ BigDecimal SERVICE_TOTAL_COST = multiply(SERVICE_UNIT_COST, service.get("QUANTITY"));//服务总成本
|
|
|
|
|
|
//2025年10月15日 一次性收费服务
|
|
|
if (service.getString("PERIOD_TYPE").equals(cttConstant.PERIOD_TYPE_ONE_TIME)) {
|
|
|
@@ -753,7 +922,7 @@ public class contractService {
|
|
|
csp.set("QUANTITY", service.get("QUANTITY"));
|
|
|
BigDecimal period_price = multiply(service.get("UNIT_PRICE"), service.get("QUANTITY"));
|
|
|
csp.set("PERIOD_PRICE", period_price);
|
|
|
- BigDecimal period_cost = multiply(service.get("UNIT_COST"), service.get("QUANTITY"));
|
|
|
+ BigDecimal period_cost = multiply(SERVICE_UNIT_COST, service.get("QUANTITY"));
|
|
|
csp.set("PERIOD_COST", period_cost);
|
|
|
csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
|
|
|
csp.set("PARTYA_PERIOD_PRICE", service.get("PARTYA_TOTAL_PRICE"));//三方合同甲方含税总价
|
|
|
@@ -794,12 +963,17 @@ public class contractService {
|
|
|
if (!isStartOfPeriod) {
|
|
|
BigDecimal periodRate;
|
|
|
//如果生效日期在合同开始日期之前
|
|
|
+ /*
|
|
|
if (EFFECTIVE_DATE.isBefore(START_DATE)) {
|
|
|
int priodDays = GetPeriodDays(getPreviousPeriodStart(end.plusDays(1), String.valueOf(maxPeriod)), end);
|
|
|
periodRate = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, end), priodDays);
|
|
|
} else {
|
|
|
periodRate = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, end), GetPeriodDays(start, end)); // 首周期占整周期比例
|
|
|
- }
|
|
|
+ }*/
|
|
|
+
|
|
|
+ //计算日期之间的比例值
|
|
|
+ periodRate = divideToBigDecimal(DateRateCalculator(EFFECTIVE_DATE, end, false), (GetPeriodMonth(String.valueOf(maxPeriod))));
|
|
|
+
|
|
|
BO csa = new BO();//合同服务调整
|
|
|
csa.set("CONTRACT_ID", contract.get("ID"));
|
|
|
csa.set("OBJECT_ID", service.get("OBJECT_ID"));
|
|
|
@@ -820,7 +994,7 @@ public class contractService {
|
|
|
csa.setBindId(service.getString("BINDID"));
|
|
|
|
|
|
//服务周期成本
|
|
|
- csa.set("PERIOD_COST", multiply(service.get("TOTAL_COST"), periodRate));
|
|
|
+ csa.set("PERIOD_COST", multiply(SERVICE_TOTAL_COST, periodRate));
|
|
|
SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", csa, uc, conn);
|
|
|
|
|
|
// 插入服务调整表包含的服务ctt_contract_service_adjust_bundle_service
|
|
|
@@ -854,8 +1028,11 @@ public class contractService {
|
|
|
BigDecimal periodRate = BigDecimal.ONE;
|
|
|
LocalDate periodEnd = getNextPeriodStart(start, String.valueOf(maxPeriod)).minusDays(1);//本周期结束时间
|
|
|
if (periodEnd.isAfter(END_DATE)) {//如果结束日期大于合同结束日期,则计算结束日期和合同结束日期的差值,并计算该差值占整周期的比例
|
|
|
- periodRate = divideToBigDecimal(GetPeriodDays(start, END_DATE), GetPeriodDays(start, periodEnd));
|
|
|
+ // periodRate = divideToBigDecimal(GetPeriodDays(start, END_DATE), GetPeriodDays(start, periodEnd));
|
|
|
+
|
|
|
periodEnd = END_DATE;
|
|
|
+ //计算日期之间的比例值
|
|
|
+ periodRate = divideToBigDecimal(DateRateCalculator(start, periodEnd, false), (GetPeriodMonth(String.valueOf(maxPeriod))));
|
|
|
}
|
|
|
|
|
|
BO csp = new BO();//服务周期
|
|
|
@@ -873,10 +1050,7 @@ public class contractService {
|
|
|
period_price = periodRate.multiply(period_price);
|
|
|
csp.set("PERIOD_PRICE", period_price);
|
|
|
|
|
|
- contractServiceLogger.info("计算-csp-PERIOD_COST");
|
|
|
- BigDecimal period_cost = multiply(service.get("UNIT_COST"), service.get("QUANTITY"));
|
|
|
- period_cost = periodRate.multiply(period_cost);
|
|
|
- csp.set("PERIOD_COST", period_cost);
|
|
|
+ csp.set("PERIOD_COST", periodRate.multiply(SERVICE_TOTAL_COST));
|
|
|
|
|
|
csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
|
|
|
|
|
|
@@ -919,6 +1093,282 @@ public class contractService {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加合同服务
|
|
|
+ * @param uc
|
|
|
+ * @param contract
|
|
|
+ * @param service
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean AddService(UserContext uc, Connection conn, RowMap contract, BO service) {
|
|
|
+ // 1、合同开始日期或结束日期变化
|
|
|
+ LocalDate START_DATE = getLocalDate(contract.get("START_DATE"));//服务开始日期
|
|
|
+ LocalDate END_DATE = getLocalDate(contract.get("END_DATE"));//合同结束日期
|
|
|
+ LocalDate EFFECTIVE_DATE = getLocalDate(service.get("EFFECTIVE_DATE"));//服务生效日期
|
|
|
+
|
|
|
+ //已经审批并提交则不能重新生成服务
|
|
|
+ if (DBSql.getInt("SELECT count(1) FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND BINDID=? and CONTRACT_ID=? and CONTRACT_SERVICE_ID=? ", new Object[]{service.get("BINDID"), contract.get("ID"), service.get("ID")}) > 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //删除历史数据
|
|
|
+ List<String> cspIdList = DBSql.getList(conn, "select ID from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where BINDID=? and CONTRACT_ID=? and OBJECT_ID=? and CONTRACT_SERVICE_ID=?", String.class, new Object[]{service.get("BINDID"), contract.get("ID"), service.get("OBJECT_ID"), service.get("ID")});
|
|
|
+ for (String cspId : cspIdList) {
|
|
|
+ DBSql.update(conn, "delete from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE where BINDID=? and CONTRACT_SERVICE_PERIOD_ID=? ", new Object[]{service.get("BINDID"), cspId});
|
|
|
+ }
|
|
|
+ DBSql.update(conn, "delete from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where BINDID=? and CONTRACT_ID=? and OBJECT_ID=? and CONTRACT_SERVICE_ID=?", new Object[]{service.get("BINDID"), contract.get("ID"), service.get("OBJECT_ID"), service.get("ID")});
|
|
|
+
|
|
|
+
|
|
|
+ String PERIOD_TYPE = service.getString("PERIOD_TYPE");//服务周期类型
|
|
|
+ String vendor_account_id = DBSql.getString(conn, "select VENDOR_ACCOUNT_ID from BO_EU_DNIVT_SERVICE where ID=?", new Object[]{service.getString("OBJECT_ID")});//供应商账号
|
|
|
+
|
|
|
+ BigDecimal SERVICE_UNIT_COST = service.get("UNIT_COST", BigDecimal.class);//服务单元成本
|
|
|
+ //需要采购
|
|
|
+ if (service.getString("NEED_PURCHASE").equals("1")) {
|
|
|
+ BigDecimal prate = GetPeriodRate(service.getString("PERIOD_TYPE"), service.getString("PURCHASE_PERIOD_TYPE"));
|
|
|
+ SERVICE_UNIT_COST = SERVICE_UNIT_COST.multiply(prate);
|
|
|
+ }
|
|
|
+ BigDecimal SERVICE_TOTAL_COST = multiply(SERVICE_UNIT_COST, service.get("QUANTITY"));//服务总成本
|
|
|
+
|
|
|
+ BigDecimal SERVICE_UNIT_PRICE = service.get("UNIT_PRICE", BigDecimal.class);
|
|
|
+ BigDecimal SERVICE_TOTAL_PRICE = multiply(SERVICE_UNIT_PRICE, service.get("QUANTITY"));
|
|
|
+
|
|
|
+ List<String> sbsList = null;
|
|
|
+ String serviceIds = DBSql.getString("select SERVICE_ID from BO_EU_DNIVT_SERVICE_BUNDLE where ID=?", new Object[]{service.get("OBJECT_ID")});
|
|
|
+ if (StringUtils.isNotBlank(serviceIds)) {
|
|
|
+ sbsList = Arrays.asList(serviceIds.split(","));
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取服务周期
|
|
|
+ List<PeriodCalculationUtil.Period> periodList = PeriodCalculationUtil.getPeriodList(PERIOD_TYPE, START_DATE, EFFECTIVE_DATE, END_DATE, true, true, -1);
|
|
|
+
|
|
|
+ String PERIOD = periodList.get(0).getPeriodBeginDateStr() + "~" + periodList.get(periodList.size() - 1).getPeriodEndDateStr();
|
|
|
+
|
|
|
+ for (PeriodCalculationUtil.Period period : periodList) {
|
|
|
+
|
|
|
+ BO csp = new BO();//服务周期
|
|
|
+ csp.set("CONTRACT_ID", contract.get("ID"));
|
|
|
+ csp.set("OBJECT_ID", service.get("OBJECT_ID"));
|
|
|
+ csp.set("OBJECT_TYPE", service.get("OBJECT_TYPE"));
|
|
|
+ csp.set("CONTRACT_SERVICE_ID", service.get("ID"));
|
|
|
+
|
|
|
+ csp.set("PERIOD_BEGIN_DATE", period.getPeriodBeginDateStr());
|
|
|
+ csp.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
|
|
|
+
|
|
|
+ csp.set("QUANTITY", service.get("QUANTITY"));
|
|
|
+
|
|
|
+ csp.set("PERIOD_PRICE", period.getRate().multiply(SERVICE_TOTAL_PRICE));
|
|
|
+
|
|
|
+ csp.set("PERIOD_COST", period.getRate().multiply(SERVICE_TOTAL_COST));
|
|
|
+
|
|
|
+ csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
|
|
|
+
|
|
|
+ csp.set("PARTYA_PERIOD_PRICE", multiply(service.get("PARTYA_TOTAL_PRICE"), period.getRate()));//三方合同甲方含税总价
|
|
|
+
|
|
|
+ csp.set("VENDOR_ACCOUNT_ID", vendor_account_id);
|
|
|
+ csp.setBindId(service.getString("BINDID"));
|
|
|
+ SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", csp, uc, conn);
|
|
|
+
|
|
|
+
|
|
|
+ if (service.getString("OBJECT_TYPE").equals("2"))//服务包
|
|
|
+ {
|
|
|
+ //本周期成本
|
|
|
+ String prorated_cost_change = DBSql.getString(conn, "select UNIT_COST from BO_EU_DNIVT_SERVICE where ID=?", new Object[]{service.getString("OBJECT_ID")});//供应商账号
|
|
|
+ if (sbsList != null) {
|
|
|
+ for (String sbs : sbsList) {
|
|
|
+ BO cspbs = new BO();
|
|
|
+ cspbs.set("CONTRACT_SERVICE_PERIOD_ID", csp.getId());
|
|
|
+ cspbs.set("SERVICE_ID", sbs);
|
|
|
+ cspbs.set("VENDOR_ACCOUNT_ID", vendor_account_id);
|
|
|
+ cspbs.set("PERIOD_COST", prorated_cost_change);
|
|
|
+ cspbs.setBindId(service.getString("BINDID"));
|
|
|
+ SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", cspbs, uc, conn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //更新合同服务上的
|
|
|
+ DBSql.update(conn, "update BO_EU_DNCTT_CONTRACT_SERVICE set PERIOD=?,ADJUST_PERIOD=? where ID=? and BINDID=?", new Object[]{PERIOD, StringUtils.EMPTY, service.get("ID"), service.get("BINDID")});
|
|
|
+ service.set("PERIOD", PERIOD);
|
|
|
+ service.set("ADJUST_PERIOD", StringUtils.EMPTY);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调整服务的结束日期(延长周期或是缩短周期)
|
|
|
+ * @param uc
|
|
|
+ * @param service
|
|
|
+ * @param END_DATE
|
|
|
+ * @param conn
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean ServiceAdjustEndDate(UserContext uc, BO service, LocalDate END_DATE, Connection conn) {
|
|
|
+
|
|
|
+ String PERIOD_TYPE = service.getString("PERIOD_TYPE");//服务周期类型
|
|
|
+ //已经审批并提交则不能重新生成服务
|
|
|
+ if (DBSql.getInt("SELECT count(1) FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL AND BINDID=? and CONTRACT_ID=? and CONTRACT_SERVICE_ID=? AND PERIOD_END_DATE>=?", new Object[]{service.get("BINDID"), service.get("CONTRACT_ID"), service.get("ID"), LocalDateYYYYMMDD(END_DATE)}) > 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取最后一笔
|
|
|
+ RowMap lastPeriod = DBSql.getMap(conn, "select * from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where CONTRACT_ID=? and CONTRACT_SERVICE_ID=? and PERIOD_BEGIN_DATE<=? order by PERIOD_BEGIN_DATE desc", new Object[]{service.get("CONTRACT_ID"), service.get("ID"), LocalDateYYYYMMDD(END_DATE)});
|
|
|
+
|
|
|
+ if (lastPeriod != null) {
|
|
|
+ LocalDate lastPeriodBeginDate = getLocalDate(lastPeriod.get("PERIOD_BEGIN_DATE"));
|
|
|
+ LocalDate lastPeriodEndDate = getLocalDate(lastPeriod.get("PERIOD_END_DATE"));
|
|
|
+
|
|
|
+ //删除 新结束日期之后的服务周期
|
|
|
+ List<String> periodIds = DBSql.getList(conn, "select ID from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where CONTRACT_ID=? and CONTRACT_SERVICE_ID=? AND PERIOD_BEGIN_DATE>?", String.class, new Object[]{service.get("CONTRACT_ID"), service.get("ID"), LocalDateYYYYMMDD(END_DATE)});
|
|
|
+ if (periodIds.isEmpty() == false && periodIds.size() > 0) {
|
|
|
+ DBSql.update(conn, "delete from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where CONTRACT_ID=? and CONTRACT_SERVICE_ID=? AND PERIOD_BEGIN_DATE>?", new Object[]{service.get("CONTRACT_ID"), service.get("ID"), LocalDateYYYYMMDD(END_DATE)});
|
|
|
+
|
|
|
+ for (String periodId : periodIds) {
|
|
|
+ DBSql.update(conn, "DELETE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE WHERE CONTRACT_SERVICE_PERIOD_ID=?", new Object[]{periodId});
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //修改周期
|
|
|
+ if (END_DATE.equals(lastPeriodEndDate) == false) {
|
|
|
+ //获取服务周期
|
|
|
+ List<PeriodCalculationUtil.Period> periodList = PeriodCalculationUtil.getAdjustPeriodList(PERIOD_TYPE, lastPeriodBeginDate, lastPeriodEndDate, true, END_DATE);
|
|
|
+ BigDecimal SERVICE_UNIT_COST = service.get("UNIT_COST", BigDecimal.class);//服务单元成本
|
|
|
+ //需要采购
|
|
|
+ if (service.getString("NEED_PURCHASE").equals("1")) {
|
|
|
+ BigDecimal prate = GetPeriodRate(service.getString("PERIOD_TYPE"), service.getString("PURCHASE_PERIOD_TYPE"));
|
|
|
+ SERVICE_UNIT_COST = SERVICE_UNIT_COST.multiply(prate);
|
|
|
+ }
|
|
|
+ BigDecimal SERVICE_TOTAL_COST = multiply(SERVICE_UNIT_COST, service.get("QUANTITY"));//服务总成本
|
|
|
+
|
|
|
+ BigDecimal SERVICE_UNIT_PRICE = service.get("UNIT_PRICE", BigDecimal.class);
|
|
|
+ BigDecimal SERVICE_TOTAL_PRICE = multiply(SERVICE_UNIT_PRICE, service.get("QUANTITY"));
|
|
|
+
|
|
|
+ List<String> sbsList = null;
|
|
|
+ String serviceIds = DBSql.getString("select SERVICE_ID from BO_EU_DNIVT_SERVICE_BUNDLE where ID=?", new Object[]{service.get("OBJECT_ID")});
|
|
|
+ if (StringUtils.isNotBlank(serviceIds)) {
|
|
|
+ sbsList = Arrays.asList(serviceIds.split(","));
|
|
|
+ }
|
|
|
+
|
|
|
+ String vendor_account_id = lastPeriod.getString("VENDOR_ACCOUNT_ID");
|
|
|
+
|
|
|
+ for (PeriodCalculationUtil.Period period : periodList) {
|
|
|
+
|
|
|
+ //第一个周期 更新
|
|
|
+ if (period.getPeriodBeginDateStr().equals(LocalDateYYYYMMDD(lastPeriodBeginDate))) {
|
|
|
+
|
|
|
+ BO lastPeriodBO = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", lastPeriod.getString("ID"));
|
|
|
+ lastPeriodBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
|
|
|
+ lastPeriodBO.set("PERIOD_PRICE", period.getRate().multiply(SERVICE_TOTAL_PRICE));
|
|
|
+ lastPeriodBO.set("PERIOD_COST", period.getRate().multiply(SERVICE_TOTAL_COST));
|
|
|
+ lastPeriodBO.set("PERIOD_ADJUSTED_PRICE", lastPeriodBO.get("PERIOD_PRICE"));
|
|
|
+ lastPeriodBO.set("PARTYA_PERIOD_PRICE", multiply(service.get("PARTYA_TOTAL_PRICE"), period.getRate()));//三方合同甲方含税总价
|
|
|
+ SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", lastPeriodBO, conn);
|
|
|
+ } else {
|
|
|
+ //新增
|
|
|
+ BO csp = new BO();//服务周期
|
|
|
+ csp.set("CONTRACT_ID", service.get("CONTRACT_ID"));
|
|
|
+ csp.set("OBJECT_ID", service.get("OBJECT_ID"));
|
|
|
+ csp.set("OBJECT_TYPE", service.get("OBJECT_TYPE"));
|
|
|
+ csp.set("CONTRACT_SERVICE_ID", service.get("ID"));
|
|
|
+
|
|
|
+ csp.set("PERIOD_BEGIN_DATE", period.getPeriodBeginDateStr());
|
|
|
+ csp.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
|
|
|
+
|
|
|
+ csp.set("QUANTITY", service.get("QUANTITY"));
|
|
|
+
|
|
|
+ csp.set("PERIOD_PRICE", period.getRate().multiply(SERVICE_TOTAL_PRICE));
|
|
|
+
|
|
|
+ csp.set("PERIOD_COST", period.getRate().multiply(SERVICE_TOTAL_COST));
|
|
|
+
|
|
|
+ csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
|
|
|
+
|
|
|
+ csp.set("PARTYA_PERIOD_PRICE", multiply(service.get("PARTYA_TOTAL_PRICE"), period.getRate()));//三方合同甲方含税总价
|
|
|
+
|
|
|
+ csp.set("VENDOR_ACCOUNT_ID", vendor_account_id);
|
|
|
+ csp.setBindId(service.getString("BINDID"));
|
|
|
+ SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", csp, uc, conn);
|
|
|
+
|
|
|
+
|
|
|
+ if (service.getString("OBJECT_TYPE").equals("2"))//服务包
|
|
|
+ {
|
|
|
+ //本周期成本
|
|
|
+ String prorated_cost_change = DBSql.getString(conn, "select UNIT_COST from BO_EU_DNIVT_SERVICE where ID=?", new Object[]{service.getString("OBJECT_ID")});//供应商账号
|
|
|
+ if (sbsList != null) {
|
|
|
+ for (String sbs : sbsList) {
|
|
|
+ BO cspbs = new BO();
|
|
|
+ cspbs.set("CONTRACT_SERVICE_PERIOD_ID", csp.getId());
|
|
|
+ cspbs.set("SERVICE_ID", sbs);
|
|
|
+ cspbs.set("VENDOR_ACCOUNT_ID", vendor_account_id);
|
|
|
+ cspbs.set("PERIOD_COST", prorated_cost_change);
|
|
|
+ cspbs.setBindId(service.getString("BINDID"));
|
|
|
+ SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", cspbs, uc, conn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ RowMap lastPayPeriod = DBSql.getMap(conn, "select * from BO_EU_DNIVT_ORDER_PAYMENT_PLAN where CONTRACT_SERVICE_ID=? and PERIOD_BEGIN_DATE<=? order by PLAN_DATE desc", new Object[]{service.get("ID"), LocalDateYYYYMMDD(END_DATE)});
|
|
|
+ if (lastPayPeriod != null) {
|
|
|
+
|
|
|
+ PERIOD_TYPE = service.getString("PURCHASE_PERIOD_TYPE");//采购周期类型
|
|
|
+ LocalDate lastPeriodBeginDate = getLocalDate(lastPayPeriod.get("PERIOD_BEGIN_DATE"));
|
|
|
+ LocalDate lastPeriodEndDate = getLocalDate(lastPayPeriod.get("PERIOD_END_DATE"));
|
|
|
+
|
|
|
+ DBSql.update(conn, "DELETE FROM BO_EU_DNIVT_ORDER_PAYMENT_PLAN WHERE CONTRACT_SERVICE_ID=? and PERIOD_BEGIN_DATE>? and (PLAN_AMOUNT=0 or PLAN_AMOUNT is NULL)", new Object[]{service.getString("ID"), LocalDateYYYYMMDD(END_DATE)});
|
|
|
+
|
|
|
+ BigDecimal SERVICE_UNIT_COST = service.get("UNIT_COST", BigDecimal.class);//服务单元成本
|
|
|
+ BigDecimal SERVICE_TOTAL_COST = multiply(SERVICE_UNIT_COST, service.get("QUANTITY"));//服务总成本
|
|
|
+
|
|
|
+ String CONTRACT_COST_ID = lastPayPeriod.getString("CONTRACT_COST_ID");
|
|
|
+ String PAY_DESC = lastPayPeriod.getString("PAY_DESC");
|
|
|
+ String ACCOUNT_PAYEE = lastPayPeriod.getString("ACCOUNT_PAYEE");
|
|
|
+
|
|
|
+ List<PeriodCalculationUtil.Period> periodList = PeriodCalculationUtil.getAdjustPeriodList(PERIOD_TYPE, lastPeriodBeginDate, lastPeriodEndDate, true, END_DATE);
|
|
|
+ for (PeriodCalculationUtil.Period period : periodList) {
|
|
|
+
|
|
|
+ //第一个周期 更新
|
|
|
+ if (period.getPeriodBeginDateStr().equals(LocalDateYYYYMMDD(lastPeriodBeginDate))) {
|
|
|
+
|
|
|
+ BO lastPeriodBO = SDK.getBOAPI().get("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", lastPayPeriod.getString("ID"));
|
|
|
+ lastPeriodBO.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
|
|
|
+ lastPeriodBO.set("PLAN_AMOUNT", period.getRate().multiply(SERVICE_TOTAL_COST));
|
|
|
+ lastPeriodBO.set("REMAIN_AMOUNT", lastPeriodBO.get("PLAN_AMOUNT"));
|
|
|
+ SDK.getBOAPI().update("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", lastPeriodBO, conn);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ ProcessInstance processInstance = SDK.getProcessAPI().createProcessInstance("obj_5cb4ae4a42944fd0a9a284ff4c64c65d", uc.getUID(), "付款计划");
|
|
|
+
|
|
|
+ BO paymentPlan = new BO();
|
|
|
+ paymentPlan.setBindId(processInstance.getId());
|
|
|
+ paymentPlan.set("ORDER_ID", null);
|
|
|
+ paymentPlan.set("PLAN_DATE", period.getPeriodBeginDateStr());
|
|
|
+ paymentPlan.set("PLAN_AMOUNT", period.getRate().multiply(SERVICE_TOTAL_COST));
|
|
|
+ paymentPlan.set("REMAIN_AMOUNT", paymentPlan.get("PLAN_AMOUNT"));
|
|
|
+ paymentPlan.set("CONTRACT_COST_ID", CONTRACT_COST_ID);
|
|
|
+ paymentPlan.set("CONTRACT_SERVICE_ID", service.getId());
|
|
|
+ paymentPlan.set("PAY_DESC", PAY_DESC);
|
|
|
+ paymentPlan.set("PERIOD_BEGIN_DATE", period.getPeriodBeginDateStr());
|
|
|
+ paymentPlan.set("PERIOD_END_DATE", period.getPeriodEndDateStr());
|
|
|
+ paymentPlan.set("ACCOUNT_PAYEE", ACCOUNT_PAYEE);//收款单位
|
|
|
+
|
|
|
+ SDK.getBOAPI().create("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", paymentPlan, processInstance, uc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 调整服务
|
|
|
* @param uc
|
|
|
@@ -927,6 +1377,9 @@ public class contractService {
|
|
|
* @return
|
|
|
*/
|
|
|
public boolean EditServiceServiceBundle(UserContext uc, Connection conn, RowMap contract, BO editService) {
|
|
|
+
|
|
|
+ //2025年10月30日 计算有问题 后续 在修改
|
|
|
+
|
|
|
//2、服务调整:生效日期在合同开始日期和合同结束日期之间;已审批服务周期之后的日期;
|
|
|
// 3、服务周期分为调整前和调整后两个周期;生效日期之后按照新的数量、单价重新生成服务周期;
|
|
|
contractServiceLogger.info("调整服务");
|
|
|
@@ -954,13 +1407,23 @@ public class contractService {
|
|
|
BO contractServiceBO = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_SERVICE", editService.getString("CONTRACT_SERVICE_ID"));
|
|
|
|
|
|
String maxPeriod = editService.getString("PERIOD_TYPE");
|
|
|
+
|
|
|
+ BigDecimal SERVICE_UNIT_COST = editService.get("UNIT_COST", BigDecimal.class);//服务单元成本
|
|
|
+ //需要采购
|
|
|
+ if (editService.getString("NEED_PURCHASE").equals("1")) {
|
|
|
+ BigDecimal prate = GetPeriodRate(editService.getString("PERIOD_TYPE"), editService.getString("PURCHASE_PERIOD_TYPE"));
|
|
|
+ SERVICE_UNIT_COST = SERVICE_UNIT_COST.multiply(prate);
|
|
|
+ }
|
|
|
+ BigDecimal SERVICE_TOTAL_COST = multiply(SERVICE_UNIT_COST, editService.get("QUANTITY"));//服务总成本
|
|
|
+
|
|
|
+
|
|
|
//一次性收费服务
|
|
|
if (editService.getString("PERIOD_TYPE").equals(cttConstant.PERIOD_TYPE_ONE_TIME)) {
|
|
|
BO servicePeriod = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD").connection(conn).addQuery("CONTRACT_SERVICE_ID =", editService.getString("CONTRACT_SERVICE_ID")).detail();
|
|
|
servicePeriod.set("PERIOD_BEGIN_DATE", EFFECTIVE_DATE);
|
|
|
servicePeriod.set("QUANTITY", editService.get("QUANTITY"));
|
|
|
servicePeriod.set("PERIOD_PRICE", editService.get("TOTAL_PRICE"));
|
|
|
- servicePeriod.set("PERIOD_COST", editService.get("TOTAL_COST"));
|
|
|
+ servicePeriod.set("PERIOD_COST", SERVICE_TOTAL_COST);
|
|
|
|
|
|
servicePeriod.set("PARTYA_PERIOD_PRICE", editService.get("PARTYA_TOTAL_PRICE"));//三方合同甲方含税总价
|
|
|
|
|
|
@@ -1019,7 +1482,7 @@ public class contractService {
|
|
|
BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, period_end_date), priodDays);
|
|
|
|
|
|
servicePeriodAdj.set("PERIOD_PRICE", multiply(editService.get("TOTAL_PRICE"), periodRateAdj));
|
|
|
- servicePeriodAdj.set("PERIOD_COST", multiply(editService.get("TOTAL_COST"), periodRateAdj));
|
|
|
+ servicePeriodAdj.set("PERIOD_COST", multiply(SERVICE_TOTAL_COST, periodRateAdj));
|
|
|
servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
|
|
|
|
|
|
//三方合同甲方含税总价
|
|
|
@@ -1069,7 +1532,7 @@ public class contractService {
|
|
|
|
|
|
servicePeriod.set("QUANTITY", editService.get("QUANTITY"));
|
|
|
servicePeriod.set("PERIOD_PRICE", multiply(editService.get("TOTAL_PRICE"), periodRate));
|
|
|
- servicePeriod.set("PERIOD_COST", multiply(editService.get("TOTAL_COST"), periodRate));
|
|
|
+ servicePeriod.set("PERIOD_COST", multiply(SERVICE_TOTAL_COST, periodRate));
|
|
|
servicePeriod.set("PERIOD_ADJUSTED_PRICE", servicePeriod.get("PERIOD_PRICE"));
|
|
|
//三方合同甲方含税总价
|
|
|
servicePeriod.set("PARTYA_PERIOD_PRICE", multiply(editService.get("PARTYA_TOTAL_PRICE"), periodRate));
|
|
|
@@ -1122,7 +1585,7 @@ public class contractService {
|
|
|
int priodDays = GetPeriodDays(getPreviousPeriodStart(period_end_date.plusDays(1), editService.getString("PERIOD_TYPE")), period_end_date);
|
|
|
BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, period_end_date), priodDays);
|
|
|
servicePeriodAdj.set("PERIOD_PRICE", multiply(editService.get("TOTAL_PRICE"), periodRateAdj));
|
|
|
- servicePeriodAdj.set("PERIOD_COST", multiply(editService.get("TOTAL_COST"), periodRateAdj));
|
|
|
+ servicePeriodAdj.set("PERIOD_COST", multiply(SERVICE_TOTAL_COST, periodRateAdj));
|
|
|
servicePeriodAdj.set("PERIOD_ADJUSTED_PRICE", servicePeriodAdj.get("PERIOD_PRICE"));
|
|
|
//三方合同甲方含税总价
|
|
|
servicePeriodAdj.set("PARTYA_PERIOD_PRICE", multiply(editService.get("PARTYA_TOTAL_PRICE"), periodRateAdj));
|
|
|
@@ -1191,7 +1654,7 @@ public class contractService {
|
|
|
LocalDate start = getPreviousPeriodStart(last_period_end_date.plusDays(1), editService.getString("PERIOD_TYPE"));
|
|
|
BigDecimal periodRateAdj = divideToBigDecimal(GetPeriodDays(EFFECTIVE_DATE, last_period_end_date), GetPeriodDays(start, last_period_end_date)); // 首周期占整周期比例
|
|
|
servicePeriodAdj.set("PERIOD_PRICE", multiply(editService.get("TOTAL_PRICE"), periodRateAdj));
|
|
|
- servicePeriodAdj.set("PERIOD_COST", multiply(editService.get("TOTAL_COST"), periodRateAdj));
|
|
|
+ servicePeriodAdj.set("PERIOD_COST", multiply(SERVICE_TOTAL_COST, periodRateAdj));
|
|
|
|
|
|
servicePeriodAdj.set("PARTYA_PERIOD_PRICE", multiply(editService.get("PARTYA_TOTAL_PRICE"), periodRateAdj));
|
|
|
|
|
|
@@ -1249,9 +1712,8 @@ public class contractService {
|
|
|
period_price = periodRate.multiply(period_price);
|
|
|
csp.set("PERIOD_PRICE", period_price);
|
|
|
contractServiceLogger.info("计算-csp-PERIOD_COST");
|
|
|
- BigDecimal period_cost = multiply(editService.get("UNIT_COST"), editService.get("QUANTITY"));
|
|
|
- period_cost = periodRate.multiply(period_cost);
|
|
|
- csp.set("PERIOD_COST", period_cost);
|
|
|
+
|
|
|
+ csp.set("PERIOD_COST", periodRate.multiply(SERVICE_TOTAL_COST));
|
|
|
csp.set("PERIOD_ADJUSTED_PRICE", csp.get("PERIOD_PRICE"));
|
|
|
|
|
|
csp.set("PARTYA_PERIOD_PRICE", multiply(editService.get("PARTYA_TOTAL_PRICE"), periodRate));//三方合同甲方含税总价
|
|
|
@@ -1389,10 +1851,20 @@ public class contractService {
|
|
|
contractCost.put("serviceID", serviceID);
|
|
|
contractCost.put("CONTRACT_ID", contract.getString("ID"));
|
|
|
contractCost.put("QUANTITY", service.getString("QUANTITY"));
|
|
|
- contractCost.put("PURCHASE_PERIOD_TYPE", service.getString("PURCHASE_PERIOD_TYPE"));
|
|
|
+
|
|
|
contractCost.put("UNIT_PRICE", String.valueOf(unitPriceMap.get(serviceID)));
|
|
|
contractCost.put("UNIT_COST", String.valueOf(unitCostMap.get(serviceID)));
|
|
|
|
|
|
+ //采购
|
|
|
+ contractCost.put("PURCHASE_PERIOD_TYPE", service.getString("PURCHASE_PERIOD_TYPE"));//采购周期
|
|
|
+ String PURCHASE_START_DATE = service.getString("PURCHASE_START_DATE");
|
|
|
+ if (StringUtils.isBlank(PURCHASE_START_DATE))
|
|
|
+ PURCHASE_START_DATE = contract.getString("START_DATE");
|
|
|
+ contractCost.put("PURCHASE_START_DATE", PURCHASE_START_DATE);//采购开始日期
|
|
|
+ contractCost.put("CONTRACT_START_DATE", contract.getString("START_DATE"));
|
|
|
+ contractCost.put("CONTRACT_END_DATE", contract.getString("END_DATE"));//采购结束日期
|
|
|
+
|
|
|
+
|
|
|
PRODUCT_ID = AddContractServiceProduct(uc, conn, contractCost);
|
|
|
} else {
|
|
|
//是否 删除 contractCostId 没有采购 没有拣货时可删除
|
|
|
@@ -1415,10 +1887,20 @@ public class contractService {
|
|
|
contractCost.put("serviceID", service.getString("OBJECT_ID"));
|
|
|
contractCost.put("CONTRACT_ID", contract.getString("ID"));
|
|
|
contractCost.put("QUANTITY", service.getString("QUANTITY"));
|
|
|
- contractCost.put("PURCHASE_PERIOD_TYPE", service.getString("PURCHASE_PERIOD_TYPE"));
|
|
|
+
|
|
|
contractCost.put("UNIT_PRICE", service.getString("UNIT_PRICE"));
|
|
|
contractCost.put("UNIT_COST", service.getString("UNIT_COST"));
|
|
|
|
|
|
+ //采购
|
|
|
+ contractCost.put("PURCHASE_PERIOD_TYPE", service.getString("PURCHASE_PERIOD_TYPE"));//采购周期
|
|
|
+
|
|
|
+ String PURCHASE_START_DATE = service.getString("PURCHASE_START_DATE");
|
|
|
+ if (StringUtils.isBlank(PURCHASE_START_DATE))
|
|
|
+ PURCHASE_START_DATE = contract.getString("START_DATE");
|
|
|
+
|
|
|
+ contractCost.put("CONTRACT_START_DATE", contract.getString("START_DATE"));
|
|
|
+ contractCost.put("CONTRACT_END_DATE", contract.getString("END_DATE"));//采购结束日期
|
|
|
+
|
|
|
PRODUCT_ID = AddContractServiceProduct(uc, conn, contractCost);
|
|
|
} else {
|
|
|
//是否 删除 contractCostId
|
|
|
@@ -1500,40 +1982,26 @@ public class contractService {
|
|
|
contractCost.set("IS_SERVICE_PRODUCT", 1);
|
|
|
//单价
|
|
|
contractCost.set("UNIT_COST", service.get("UNIT_COST"));
|
|
|
-
|
|
|
//成本
|
|
|
contractCost.set("UNIT_PRICE", service.get("UNIT_PRICE"));
|
|
|
|
|
|
- //数量
|
|
|
- // int quantity = DBSql.getInt(conn, "SELECT COUNT(1) as CNT FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID='" + service.get("SERVICE_ID") + "'", "CNT"); //周期数量
|
|
|
+ BigDecimal EXTENDED_COST = divideToBigDecimal(service.get("UNIT_COST"), contractCost.get("QUANTITY"));
|
|
|
|
|
|
- try {
|
|
|
- /*
|
|
|
- String PURCHASE_PERIOD_TYPE = service.get("PURCHASE_PERIOD_TYPE");//采购周期
|
|
|
- RowMap contractServicePeriod = DBSql.getMap("SELECT MIN(PERIOD_BEGIN_DATE) AS PERIOD_BEGIN_DATE,MAX(PERIOD_END_DATE) AS PERIOD_END_DATE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID=?", new Object[]{service.get("SERVICE_ID")});//服务开始和结束日期
|
|
|
- LocalDate beginDate = getLocalDate(contractServicePeriod.get("PERIOD_BEGIN_DATE"));
|
|
|
- LocalDate endDate = getLocalDate(contractServicePeriod.get("PERIOD_END_DATE"));
|
|
|
- //计算周期个数
|
|
|
- if (StringUtils.isNotBlank(PURCHASE_PERIOD_TYPE) && beginDate != null && endDate != null)
|
|
|
- quantity = calculatePeriods(PURCHASE_PERIOD_TYPE, beginDate, endDate);
|
|
|
+ contractServiceLogger.info("计算合同成本周期:" + service);
|
|
|
|
|
|
- */
|
|
|
+ // 需要通过采购计算总成本
|
|
|
+ List<PeriodCalculationUtil.Period> periodList = PeriodCalculationUtil.getPeriodList(service.get("PURCHASE_PERIOD_TYPE"), LocalDate.parse(service.get("CONTRACT_START_DATE").substring(0, 10)), LocalDate.parse(service.get("PURCHASE_START_DATE").substring(0, 10)), LocalDate.parse(service.get("CONTRACT_END_DATE").substring(0, 10)), service.get("PURCHASE_PERIOD_TYPE").equals("610"), true, -1);
|
|
|
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
+ BigDecimal rate = periodList.stream().map(period -> period.getRate()).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ EXTENDED_COST = EXTENDED_COST.multiply(rate);
|
|
|
+ contractCost.set("EXTENDED_COST", EXTENDED_COST);
|
|
|
|
|
|
- //contractCost.set("QUANTITY", quantity);
|
|
|
-
|
|
|
- //总成本
|
|
|
- contractCost.set("EXTENDED_COST", DBSql.getDouble(conn, "SELECT SUM(PERIOD_COST) as COST FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID='" + service.get("SERVICE_ID") + "'", "COST"));
|
|
|
+ //单元成本
|
|
|
+ contractCost.set("UNIT_COST", divideToBigDecimal(contractCost.get("EXTENDED_COST"), contractCost.get("QUANTITY")));
|
|
|
|
|
|
//总价格
|
|
|
contractCost.set("EXTENDED_PRICE", DBSql.getDouble(conn, "SELECT SUM(PERIOD_ADJUSTED_PRICE) as PRICE FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE CONTRACT_SERVICE_ID='" + service.get("SERVICE_ID") + "'", "PRICE"));
|
|
|
|
|
|
- //单价=总价格➗数量
|
|
|
- contractCost.set("UNIT_COST", divideToBigDecimal(contractCost.get("EXTENDED_COST"), contractCost.get("QUANTITY")));
|
|
|
- //成本=总成本➗数量
|
|
|
contractCost.set("UNIT_PRICE", divideToBigDecimal(contractCost.get("EXTENDED_PRICE"), contractCost.get("QUANTITY")));
|
|
|
|
|
|
if (contractCost.isNew()) {
|
|
|
@@ -1859,6 +2327,71 @@ public class contractService {
|
|
|
return num.divide(den, 10, RoundingMode.HALF_UP); // 保留 10 位小数
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算日期区间的比例值
|
|
|
+ * @param start 起始日期
|
|
|
+ * @param end 结束日期
|
|
|
+ * @param use30DaysPerMonth 是否按每月30天计算(true=固定30天,false=实际天数)
|
|
|
+ * @return 比例值(起始月剩余比例 + 中间完整月数 + 结束月已过比例)
|
|
|
+ */
|
|
|
+ public static BigDecimal DateRateCalculator(LocalDate start, LocalDate end, boolean use30DaysPerMonth) {
|
|
|
+ // 校验日期合法性:start不能晚于end
|
|
|
+ if (start.isAfter(end)) {
|
|
|
+ return BigDecimal.ZERO; // 或抛出异常
|
|
|
+ }
|
|
|
+
|
|
|
+ int startYear = start.getYear();
|
|
|
+ int startMonth = start.getMonthValue();
|
|
|
+ int endYear = end.getYear();
|
|
|
+ int endMonth = end.getMonthValue();
|
|
|
+
|
|
|
+ // 情况1:start和end在同一个月
|
|
|
+ if (startYear == endYear && startMonth == endMonth) {
|
|
|
+ int totalDaysInMonth = use30DaysPerMonth ? 30 : start.lengthOfMonth();
|
|
|
+ int daysBetween = end.getDayOfMonth() - start.getDayOfMonth() + 1; // 包含首尾
|
|
|
+ return BigDecimal.valueOf(daysBetween).divide(BigDecimal.valueOf(totalDaysInMonth), 10, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 情况2:start和end在不同月份
|
|
|
+ // 1. 起始月剩余比例:(当月剩余天数)÷ 当月总天数
|
|
|
+ int startMonthTotalDays = use30DaysPerMonth ? 30 : start.lengthOfMonth();
|
|
|
+ int startRemainingDays = startMonthTotalDays - start.getDayOfMonth() + 1; // 包含start当天
|
|
|
+ BigDecimal startRatio = BigDecimal.valueOf(startRemainingDays).divide(BigDecimal.valueOf(startMonthTotalDays), 10, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ // 2. 中间完整月数:start的下一个月 到 end的上一个月之间的完整月份
|
|
|
+ int fullMonths = 0;
|
|
|
+ int currentYear = startYear;
|
|
|
+ int currentMonth = startMonth + 1;
|
|
|
+ if (currentMonth > 12) { // 处理跨年(如12月→次年1月)
|
|
|
+ currentMonth = 1;
|
|
|
+ currentYear++;
|
|
|
+ }
|
|
|
+ int endPrevYear = endYear;
|
|
|
+ int endPrevMonth = endMonth - 1;
|
|
|
+ if (endPrevMonth < 1) { // 处理跨年(如1月→上年12月)
|
|
|
+ endPrevMonth = 12;
|
|
|
+ endPrevYear--;
|
|
|
+ }
|
|
|
+ // 累加中间完整月数
|
|
|
+ while (currentYear < endPrevYear || (currentYear == endPrevYear && currentMonth <= endPrevMonth)) {
|
|
|
+ fullMonths++;
|
|
|
+ currentMonth++;
|
|
|
+ if (currentMonth > 12) {
|
|
|
+ currentMonth = 1;
|
|
|
+ currentYear++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 结束月已过比例:(当月已过天数)÷ 当月总天数
|
|
|
+ int endMonthTotalDays = use30DaysPerMonth ? 30 : end.lengthOfMonth();
|
|
|
+ int endPassedDays = end.getDayOfMonth(); // 从1日到end当天的天数
|
|
|
+ BigDecimal endRatio = BigDecimal.valueOf(endPassedDays).divide(BigDecimal.valueOf(endMonthTotalDays), 10, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ // 总和:起始比例 + 完整月数 + 结束比例
|
|
|
+ return startRatio.add(BigDecimal.valueOf(fullMonths)).add(endRatio);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 相除
|
|
|
* @param numerator
|