|
@@ -29,6 +29,8 @@ public class PeriodCalculationUtil {
|
|
|
public static final String PERIOD_TYPE_HALFYEAR = "612"; // 按半年支付
|
|
public static final String PERIOD_TYPE_HALFYEAR = "612"; // 按半年支付
|
|
|
public static final String PERIOD_TYPE_YEAR = "613"; // 按年支付
|
|
public static final String PERIOD_TYPE_YEAR = "613"; // 按年支付
|
|
|
|
|
|
|
|
|
|
+ public static final String PERIOD_TYPE_TWOYEAR = "614"; // 按2年支付
|
|
|
|
|
+
|
|
|
// 日期格式化器(复用避免重复创建)
|
|
// 日期格式化器(复用避免重复创建)
|
|
|
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyyMM");
|
|
private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyyMM");
|
|
@@ -63,6 +65,8 @@ public class PeriodCalculationUtil {
|
|
|
* 613 按年支付 4592 开通日期后的完整一年 isNaturalMonth=false CALC_METHOD_1STYEAR=4637 userMonthDay=false 或者 CALC_METHOD_1STYEAR=4638 userMonthDay=true monthDayType=0 startMonth=0
|
|
* 613 按年支付 4592 开通日期后的完整一年 isNaturalMonth=false CALC_METHOD_1STYEAR=4637 userMonthDay=false 或者 CALC_METHOD_1STYEAR=4638 userMonthDay=true monthDayType=0 startMonth=0
|
|
|
*
|
|
*
|
|
|
*
|
|
*
|
|
|
|
|
+ * 614 按两年付 4603/4604/4605
|
|
|
|
|
+ *
|
|
|
*CALC_METHOD_1STYEAR
|
|
*CALC_METHOD_1STYEAR
|
|
|
* 4637 (拆机时实际计费天数/当年天数(如365))*年费用
|
|
* 4637 (拆机时实际计费天数/当年天数(如365))*年费用
|
|
|
* 4638 先算月再算天
|
|
* 4638 先算月再算天
|
|
@@ -116,6 +120,7 @@ public class PeriodCalculationUtil {
|
|
|
case "4596":
|
|
case "4596":
|
|
|
case "4593":
|
|
case "4593":
|
|
|
case "4590":
|
|
case "4590":
|
|
|
|
|
+ case "4603":
|
|
|
monthDayType = -1;
|
|
monthDayType = -1;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
@@ -123,18 +128,19 @@ public class PeriodCalculationUtil {
|
|
|
case "4597":
|
|
case "4597":
|
|
|
case "4594":
|
|
case "4594":
|
|
|
case "4591":
|
|
case "4591":
|
|
|
|
|
+ case "4604":
|
|
|
monthDayType = -2;
|
|
monthDayType = -2;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//按年支付
|
|
//按年支付
|
|
|
- if (ruleCate.equals("613")) {
|
|
|
|
|
|
|
+ if (ruleCate.equals(PERIOD_TYPE_YEAR)) {
|
|
|
isNaturalMonth = false;//不需要切换到 1月1日
|
|
isNaturalMonth = false;//不需要切换到 1月1日
|
|
|
userMonthDay = !"4637".equals(CALC_METHOD_1STYEAR);
|
|
userMonthDay = !"4637".equals(CALC_METHOD_1STYEAR);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//按半年支付
|
|
//按半年支付
|
|
|
- if (ruleCate.equals("612")) {
|
|
|
|
|
|
|
+ if (ruleCate.equals(PERIOD_TYPE_HALFYEAR)) {
|
|
|
isNaturalMonth = false;//不需要切换到 1月1日 或者 7月1日
|
|
isNaturalMonth = false;//不需要切换到 1月1日 或者 7月1日
|
|
|
}
|
|
}
|
|
|
if (CALC_METHOD_1STPERIOD.equals("4601"))
|
|
if (CALC_METHOD_1STPERIOD.equals("4601"))
|
|
@@ -178,7 +184,9 @@ public class PeriodCalculationUtil {
|
|
|
LOGGERU.info("周期开始日期--计算前:" + contractStartDate);
|
|
LOGGERU.info("周期开始日期--计算前:" + contractStartDate);
|
|
|
|
|
|
|
|
// 1. 参数校验:避免空指针和非法参数
|
|
// 1. 参数校验:避免空指针和非法参数
|
|
|
- validateParams(ruleCate, contractStartDate, periodBeginDate, periodEndDate);
|
|
|
|
|
|
|
+ if (validateParams(ruleCate, contractStartDate, periodBeginDate, periodEndDate) == false) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
List<Period> periodList = new ArrayList<>();
|
|
List<Period> periodList = new ArrayList<>();
|
|
|
// 2. 一次性收费:直接生成单个周期
|
|
// 2. 一次性收费:直接生成单个周期
|
|
@@ -265,6 +273,15 @@ public class PeriodCalculationUtil {
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
|
|
+ case PERIOD_TYPE_TWOYEAR://2年
|
|
|
|
|
+ if (isNaturalMonth) {
|
|
|
|
|
+ currLastDay = getNaturalYearLastDay(periodBeginDate);
|
|
|
|
|
+ totalPeriodDays = periodBeginDate.lengthOfYear();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ currLastDay = getActualTWOYearFirstEndDay(contractStartDate, periodBeginDate, periodEndDate);
|
|
|
|
|
+ totalPeriodDays = getActualYearTotalDays(contractStartDate, periodBeginDate);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
default:
|
|
default:
|
|
|
throw new IllegalArgumentException("不支持的周期类型:" + ruleCate);
|
|
throw new IllegalArgumentException("不支持的周期类型:" + ruleCate);
|
|
|
}
|
|
}
|
|
@@ -321,6 +338,7 @@ public class PeriodCalculationUtil {
|
|
|
startDate = periodEnd.plusDays(1);
|
|
startDate = periodEnd.plusDays(1);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
LOGGERU.info("周期列表个数:" + periodList.size());
|
|
LOGGERU.info("周期列表个数:" + periodList.size());
|
|
|
LOGGERU.info("周期列表:" + JSON.toJSONString(periodList));
|
|
LOGGERU.info("周期列表:" + JSON.toJSONString(periodList));
|
|
|
return periodList;
|
|
return periodList;
|
|
@@ -461,27 +479,34 @@ public class PeriodCalculationUtil {
|
|
|
/**
|
|
/**
|
|
|
* 参数校验:防止空指针和非法日期范围
|
|
* 参数校验:防止空指针和非法日期范围
|
|
|
*/
|
|
*/
|
|
|
- private static void validateParams(
|
|
|
|
|
|
|
+ private static boolean validateParams(
|
|
|
String ruleCate,
|
|
String ruleCate,
|
|
|
LocalDate contractStartDate,
|
|
LocalDate contractStartDate,
|
|
|
LocalDate periodBeginDate,
|
|
LocalDate periodBeginDate,
|
|
|
LocalDate periodEndDate
|
|
LocalDate periodEndDate
|
|
|
) {
|
|
) {
|
|
|
if (StringUtils.isBlank(ruleCate)) {
|
|
if (StringUtils.isBlank(ruleCate)) {
|
|
|
- throw new IllegalArgumentException("周期类型(ruleCate)不能为空");
|
|
|
|
|
|
|
+ LOGGERU.info("周期类型(ruleCate)不能为空");
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
if (contractStartDate == null) {
|
|
if (contractStartDate == null) {
|
|
|
- throw new IllegalArgumentException("合同开始日期(contractStartDate)不能为空");
|
|
|
|
|
|
|
+ LOGGERU.info("合同开始日期(contractStartDate)不能为空");
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
if (periodBeginDate == null) {
|
|
if (periodBeginDate == null) {
|
|
|
- throw new IllegalArgumentException("服务开始日期(periodBeginDate)不能为空");
|
|
|
|
|
|
|
+ LOGGERU.info("服务开始日期(periodBeginDate)不能为空");
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
if (periodEndDate == null) {
|
|
if (periodEndDate == null) {
|
|
|
- throw new IllegalArgumentException("服务结束日期(periodEndDate)不能为空");
|
|
|
|
|
|
|
+ LOGGERU.info("服务结束日期(periodEndDate)不能为空");
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
if (periodBeginDate.isAfter(periodEndDate)) {
|
|
if (periodBeginDate.isAfter(periodEndDate)) {
|
|
|
- throw new IllegalArgumentException("服务开始日期不能晚于服务结束日期");
|
|
|
|
|
|
|
+ LOGGERU.info("服务开始日期不能晚于服务结束日期");
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------ 私有工具方法:自然月模式计算 ------------------------------
|
|
// ------------------------------ 私有工具方法:自然月模式计算 ------------------------------
|
|
@@ -576,9 +601,7 @@ public class PeriodCalculationUtil {
|
|
|
while (endDay.isBefore(periodBeginDate)) {
|
|
while (endDay.isBefore(periodBeginDate)) {
|
|
|
endDay = endDay.plusMonths(3);
|
|
endDay = endDay.plusMonths(3);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
endDay = endDay.minusDays(1);
|
|
endDay = endDay.minusDays(1);
|
|
|
-
|
|
|
|
|
} else {
|
|
} else {
|
|
|
//endDay = contractStartDate.plusMonths(3).minusDays(1);
|
|
//endDay = contractStartDate.plusMonths(3).minusDays(1);
|
|
|
return null;
|
|
return null;
|
|
@@ -614,7 +637,9 @@ public class PeriodCalculationUtil {
|
|
|
while (endDay.isBefore(periodBeginDate)) {
|
|
while (endDay.isBefore(periodBeginDate)) {
|
|
|
endDay = endDay.plusMonths(6);
|
|
endDay = endDay.plusMonths(6);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
endDay = endDay.minusDays(1);
|
|
endDay = endDay.minusDays(1);
|
|
|
|
|
+
|
|
|
} else {
|
|
} else {
|
|
|
//endDay = contractStartDate.plusMonths(6).minusDays(1);
|
|
//endDay = contractStartDate.plusMonths(6).minusDays(1);
|
|
|
return null;
|
|
return null;
|
|
@@ -657,6 +682,26 @@ public class PeriodCalculationUtil {
|
|
|
return endDay.isAfter(periodEndDate) ? periodEndDate : endDay;
|
|
return endDay.isAfter(periodEndDate) ? periodEndDate : endDay;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private static LocalDate getActualTWOYearFirstEndDay(
|
|
|
|
|
+ LocalDate contractStartDate,
|
|
|
|
|
+ LocalDate periodBeginDate,
|
|
|
|
|
+ LocalDate periodEndDate
|
|
|
|
|
+ ) {
|
|
|
|
|
+ LocalDate endDay;
|
|
|
|
|
+ if (contractStartDate.isAfter(periodBeginDate)) {
|
|
|
|
|
+ endDay = contractStartDate.minusDays(1);
|
|
|
|
|
+ } else if (contractStartDate.isBefore(periodBeginDate)) {
|
|
|
|
|
+ endDay = contractStartDate.plusMonths(24);
|
|
|
|
|
+ while (endDay.isBefore(periodBeginDate)) {
|
|
|
|
|
+ endDay = endDay.plusMonths(24);
|
|
|
|
|
+ }
|
|
|
|
|
+ endDay = endDay.minusDays(1);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return endDay.isAfter(periodEndDate) ? periodEndDate : endDay;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 实际年:完整周期总天数
|
|
* 实际年:完整周期总天数
|
|
|
*/
|
|
*/
|
|
@@ -705,6 +750,9 @@ public class PeriodCalculationUtil {
|
|
|
case PERIOD_TYPE_YEAR:
|
|
case PERIOD_TYPE_YEAR:
|
|
|
// 年周期:当前日期加 1 年
|
|
// 年周期:当前日期加 1 年
|
|
|
return currentStart.plus(1, ChronoUnit.YEARS);
|
|
return currentStart.plus(1, ChronoUnit.YEARS);
|
|
|
|
|
+ case PERIOD_TYPE_TWOYEAR:
|
|
|
|
|
+ // 2 年周期:当前日期加 2 年
|
|
|
|
|
+ return currentStart.plus(2, ChronoUnit.YEARS);
|
|
|
default:
|
|
default:
|
|
|
// 不支持的周期类型:抛出异常并提示具体类型
|
|
// 不支持的周期类型:抛出异常并提示具体类型
|
|
|
throw new IllegalArgumentException("不支持的周期类型:" + periodType);
|
|
throw new IllegalArgumentException("不支持的周期类型:" + periodType);
|
|
@@ -823,7 +871,7 @@ public class PeriodCalculationUtil {
|
|
|
* @param period 周期类型字符串,表示不同的周期类型
|
|
* @param period 周期类型字符串,表示不同的周期类型
|
|
|
* @return 对应的月数如果输入的周期类型不匹配已知类型,则返回0
|
|
* @return 对应的月数如果输入的周期类型不匹配已知类型,则返回0
|
|
|
*/
|
|
*/
|
|
|
- private static int GetPeriodMonth(String period) {
|
|
|
|
|
|
|
+ public static int GetPeriodMonth(String period) {
|
|
|
switch (period) {
|
|
switch (period) {
|
|
|
case PERIOD_TYPE_MONTH:
|
|
case PERIOD_TYPE_MONTH:
|
|
|
// 当周期类型为月时,返回1个月
|
|
// 当周期类型为月时,返回1个月
|
|
@@ -837,6 +885,9 @@ public class PeriodCalculationUtil {
|
|
|
case PERIOD_TYPE_YEAR:
|
|
case PERIOD_TYPE_YEAR:
|
|
|
// 当周期类型为年时,返回12个月
|
|
// 当周期类型为年时,返回12个月
|
|
|
return 12;
|
|
return 12;
|
|
|
|
|
+ case PERIOD_TYPE_TWOYEAR:
|
|
|
|
|
+ // 当周期类型为2年时,返回24个月
|
|
|
|
|
+ return 24;
|
|
|
default:
|
|
default:
|
|
|
// 当周期类型不匹配已知类型时,返回0
|
|
// 当周期类型不匹配已知类型时,返回0
|
|
|
return 0;
|
|
return 0;
|