| | |
| | | |
| | | import static org.junit.Assert.assertTrue; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.java110.dto.RoomAttrDto; |
| | | import com.java110.dto.community.CommunityDto; |
| | | import com.java110.core.factory.PlutusFactory; |
| | | import com.java110.dto.fee.FeeDto; |
| | | import com.java110.dto.owner.OwnerCarDto; |
| | | import com.java110.utils.constant.FeeConfigConstant; |
| | | import com.java110.utils.util.DateUtil; |
| | | import com.java110.utils.util.MoneyUtil; |
| | | import com.java110.utils.util.StringUtil; |
| | | import org.bouncycastle.util.encoders.Base64; |
| | | import org.junit.Test; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.time.temporal.ChronoUnit; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Unit test for simple App. |
| | | */ |
| | | public class AppTest |
| | | { |
| | | public class AppTest { |
| | | /** |
| | | * Rigorous Test :-) |
| | | */ |
| | | @Test |
| | | public void should() |
| | | { |
| | | |
| | | String value = "0.51*R+0.03 * L +0.77"; |
| | | |
| | | value = value.replace("\n", "") |
| | | .replace("\r", "") |
| | | .trim(); |
| | | if (value.contains("C")) { //处理小区面积 |
| | | |
| | | |
| | | } else if (value.contains("F")) { //处理楼栋 |
| | | |
| | | } else if (value.contains("U")) { //处理单元 |
| | | } else if (value.contains("RL")) { |
| | | |
| | | } else if (value.contains("R")) { //处理 房屋面积 |
| | | value = value.replace("R", "100"); |
| | | } else if (value.contains("X")) {// 处理 房屋系数 |
| | | value = value.replace("X", "1"); |
| | | } |
| | | if (value.contains("L")) {//处理房屋层数 |
| | | System.out.printf("L"); |
| | | value = value.replace("L", "1"); |
| | | } |
| | | |
| | | System.out.printf("value="+value); |
| | | public void should() { |
| | | String str = "18983ssssssss"; |
| | | String strq[] = str.split("18983"); |
| | | System.out.println(strq[1]); |
| | | } |
| | | |
| | | /** |
| | | * 修正递增 开始时间 |
| | | * 如果设置的 递增开始时间和建账时间不是同一天 强制修正下 |
| | | * @param rateStartTime |
| | | * @param startTime |
| | | * @return |
| | | */ |
| | | private Date correctByFeeStartTime(Date rateStartTime, Date startTime) { |
| | | Calendar rateCalendar = Calendar.getInstance(); |
| | | rateCalendar.setTime(rateStartTime); |
| | | int rateDay = rateCalendar.get(Calendar.DAY_OF_MONTH); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(startTime); |
| | | int day = calendar.get(Calendar.DAY_OF_MONTH); |
| | | if(rateDay == day){ |
| | | return rateStartTime; |
| | | } |
| | | |
| | | rateCalendar = Calendar.getInstance(); |
| | | rateCalendar.setTime(rateStartTime); |
| | | rateCalendar.add(Calendar.MONTH,1); |
| | | rateCalendar.set(Calendar.DAY_OF_MONTH,day); |
| | | return rateCalendar.getTime(); |
| | | } |
| | | |
| | | public Map getTargetEndDateAndOweMonth(FeeDto feeDto, OwnerCarDto ownerCarDto) { |
| | | Date targetEndDate = null; |
| | | double oweMonth = 0.0; |
| | | |
| | | Map<String, Object> targetEndDateAndOweMonth = new HashMap<>(); |
| | | //todo 判断当前费用是否已结束 |
| | | if (FeeDto.STATE_FINISH.equals(feeDto.getState())) { |
| | | targetEndDate = feeDto.getEndTime(); |
| | | targetEndDateAndOweMonth.put("oweMonth", oweMonth); |
| | | targetEndDateAndOweMonth.put("targetEndDate", targetEndDate); |
| | | return targetEndDateAndOweMonth; |
| | | } |
| | | |
| | | //todo 考虑费用项 费用提前生成 |
| | | Calendar preEndTimeCal = Calendar.getInstance(); |
| | | preEndTimeCal.setTime(feeDto.getEndTime()); |
| | | if (StringUtil.isNumber(feeDto.getPrepaymentPeriod())) { |
| | | preEndTimeCal.add(Calendar.DAY_OF_MONTH, Integer.parseInt(feeDto.getPrepaymentPeriod()) * -1); |
| | | } |
| | | Date preEndTime = preEndTimeCal.getTime(); |
| | | |
| | | //todo 当前费用为一次性费用 |
| | | Date maxEndTime = feeDto.getConfigEndTime(); |
| | | if (FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) { |
| | | //先取 deadlineTime |
| | | if (feeDto.getDeadlineTime() != null) { |
| | | targetEndDate = feeDto.getDeadlineTime(); |
| | | } else if (!StringUtil.isEmpty(feeDto.getCurDegrees())) { |
| | | targetEndDate = feeDto.getCurReadingTime(); |
| | | } else if (feeDto.getImportFeeEndTime() == null) { |
| | | targetEndDate = maxEndTime; |
| | | } else { |
| | | targetEndDate = feeDto.getImportFeeEndTime(); |
| | | } |
| | | //说明欠费 |
| | | if (preEndTime.getTime() < DateUtil.getCurrentDate().getTime()) { |
| | | // 目标到期时间 - 到期时间 = 欠费月份 |
| | | oweMonth = 1.0; |
| | | } |
| | | } else if (FeeDto.FEE_FLAG_CYCLE_ONCE.equals(feeDto.getFeeFlag())) { |
| | | if (feeDto.getDeadlineTime() != null) { |
| | | maxEndTime = feeDto.getDeadlineTime(); |
| | | } |
| | | Date billEndTime = DateUtil.getCurrentDate(); |
| | | //建账时间 |
| | | Date startDate = feeDto.getStartTime(); |
| | | //计费起始时间 |
| | | Date endDate = feeDto.getEndTime(); |
| | | //缴费周期 |
| | | long paymentCycle = Long.parseLong(feeDto.getPaymentCycle()); |
| | | // 当前时间 - 开始时间 = 月份 |
| | | double mulMonth = 0.0; |
| | | mulMonth = dayCompare(startDate, billEndTime); |
| | | |
| | | // 月份/ 周期 = 轮数(向上取整) |
| | | double round = 0.0; |
| | | if ("1200".equals(feeDto.getPaymentCd())) { // 1200预付费 |
| | | round = Math.floor(mulMonth / paymentCycle) + 1; |
| | | } else { //2100后付费 |
| | | round = Math.floor(mulMonth / paymentCycle); |
| | | } |
| | | // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间 |
| | | targetEndDate = getTargetEndTime(round * paymentCycle, startDate);//目标结束时间 |
| | | |
| | | //todo 如果 到了 预付期 产生下个周期的费用 |
| | | if (DateUtil.getFormatTimeStringB(targetEndDate).equals(DateUtil.getFormatTimeStringB(endDate)) |
| | | && DateUtil.getCurrentDate().getTime() > preEndTime.getTime() |
| | | ) { |
| | | targetEndDate = getTargetEndTime((round + 1) * paymentCycle, startDate);//目标结束时间 |
| | | } |
| | | |
| | | |
| | | //todo 费用项的结束时间<缴费的结束时间 费用快结束了 取费用项的结束时间 |
| | | if (maxEndTime.getTime() < targetEndDate.getTime()) { |
| | | targetEndDate = maxEndTime; |
| | | } |
| | | //说明欠费 |
| | | if (endDate.getTime() < targetEndDate.getTime()) { |
| | | // 目标到期时间 - 到期时间 = 欠费月份 |
| | | oweMonth = dayCompare(endDate, targetEndDate); |
| | | } |
| | | |
| | | if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) { |
| | | targetEndDate = feeDto.getEndTime(); |
| | | } |
| | | } else { // todo 周期性费用 |
| | | //当前时间 |
| | | Date billEndTime = DateUtil.getCurrentDate(); |
| | | //建账时间 |
| | | Date startDate = feeDto.getStartTime(); |
| | | //计费起始时间 |
| | | Date endDate = feeDto.getEndTime(); |
| | | //缴费周期 |
| | | long paymentCycle = Long.parseLong(feeDto.getPaymentCycle()); |
| | | // 当前时间 - 开始时间 = 月份 |
| | | double mulMonth = 0.0; |
| | | mulMonth = dayCompare(endDate, billEndTime); |
| | | |
| | | // 月份/ 周期 = 轮数(向上取整) |
| | | double round = 0.0; |
| | | if ("1200".equals(feeDto.getPaymentCd())) { // 1200预付费 |
| | | round = Math.floor(mulMonth / paymentCycle) + 1; |
| | | } else { //2100后付费 |
| | | round = Math.floor(mulMonth / paymentCycle); |
| | | } |
| | | // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间 |
| | | targetEndDate = getTargetEndTime(round * paymentCycle, endDate);//目标结束时间 |
| | | |
| | | //todo 如果 到了 预付期 产生下个周期的费用 |
| | | if (DateUtil.getFormatTimeStringB(targetEndDate).equals(DateUtil.getFormatTimeStringB(endDate)) |
| | | && DateUtil.getCurrentDate().getTime() > preEndTime.getTime() |
| | | ) { |
| | | targetEndDate = getTargetEndTime((round + 1) * paymentCycle, startDate);//目标结束时间 |
| | | } |
| | | |
| | | //费用项的结束时间<缴费的结束时间 费用快结束了 取费用项的结束时间 |
| | | if (maxEndTime.getTime() < targetEndDate.getTime()) { |
| | | targetEndDate = maxEndTime; |
| | | } |
| | | //说明欠费 |
| | | if (endDate.getTime() < targetEndDate.getTime()) { |
| | | // 目标到期时间 - 到期时间 = 欠费月份 |
| | | oweMonth = dayCompare(endDate, targetEndDate); |
| | | } |
| | | |
| | | if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) { |
| | | targetEndDate = feeDto.getEndTime(); |
| | | } |
| | | } |
| | | |
| | | targetEndDateAndOweMonth.put("oweMonth", oweMonth); |
| | | targetEndDateAndOweMonth.put("targetEndDate", targetEndDate); |
| | | return targetEndDateAndOweMonth; |
| | | } |
| | | |
| | | public Date getTargetEndTime(double month, Date startDate) { |
| | | Calendar endDate = Calendar.getInstance(); |
| | | endDate.setTime(startDate); |
| | | |
| | | Double intMonth = Math.floor(month); |
| | | endDate.add(Calendar.MONTH, intMonth.intValue()); |
| | | double doubleMonth = month - intMonth; |
| | | if (doubleMonth <= 0) { |
| | | return endDate.getTime(); |
| | | } |
| | | int futureDay = endDate.getActualMaximum(Calendar.DAY_OF_MONTH); |
| | | Double hour = doubleMonth * futureDay * 24; |
| | | endDate.add(Calendar.HOUR_OF_DAY, hour.intValue()); |
| | | return endDate.getTime(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 计算 fromDate 2023-01-12 toDate 2023-09-15 |
| | | * 2023-01-12--->2023-01-01 ---> 2023-09-01 ------> 2023-09-15 |
| | | * fromDate ---> fromDateFirstDate ---> toDateFirstDate ----> toDate |
| | | * |
| | | * @param fromDate |
| | | * @param toDate |
| | | * @return |
| | | */ |
| | | public double dayCompare(Date fromDate, Date toDate) { |
| | | |
| | | |
| | | //todo 需要计算三端时间 相加即可 |
| | | Date fromDateFirstDate = fromDate; // 第一个1日 |
| | | |
| | | Date toDateFirstDate = toDate; // 最后一个1日 |
| | | |
| | | boolean firstDay = true; |
| | | |
| | | //todo 1.0 计算 fromDateFirstDate |
| | | Calendar fromDateCal = Calendar.getInstance(); |
| | | fromDateCal.setTime(fromDate); |
| | | fromDateCal.set(Calendar.DAY_OF_MONTH, 1); |
| | | if (fromDate.getTime() > fromDateCal.getTime().getTime()) { |
| | | fromDateCal.add(Calendar.MONTH, 1); |
| | | firstDay = false; |
| | | fromDateFirstDate = fromDateCal.getTime(); |
| | | } |
| | | |
| | | //todo 2.0 计算 toDateFirstDate |
| | | Calendar toDateCal = Calendar.getInstance(); |
| | | toDateCal.setTime(toDate); |
| | | toDateCal.set(Calendar.DAY_OF_MONTH, 1); |
| | | if (toDate.getTime() > toDateCal.getTime().getTime()) { |
| | | toDateFirstDate = toDateCal.getTime(); |
| | | } |
| | | |
| | | // todo 3.0 计算整数月 fromDateFirstDate ---> toDateFirstDate |
| | | Calendar from = Calendar.getInstance(); |
| | | from.setTime(fromDateFirstDate); |
| | | Calendar to = Calendar.getInstance(); |
| | | to.setTime(toDateFirstDate); |
| | | //比较月份差 可能有整数 也会负数 |
| | | int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH); |
| | | //比较年差 |
| | | int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12; |
| | | //真实 相差月份 |
| | | result = result + month; |
| | | |
| | | //todo 3.1 如果 fromDate 和toDate 是同一天 则直接返回整月,不再计算 4.0 和5.0 |
| | | if (DateUtil.sameMonthDay(fromDate, toDate)) { |
| | | return firstDay ? result : result + 1; |
| | | } |
| | | |
| | | // todo 4.0 计算 fromDate ---> fromDateFirstDate 的月份 |
| | | double days = (fromDateFirstDate.getTime() - fromDate.getTime()) * 1.00 / (24 * 60 * 60 * 1000); |
| | | BigDecimal tmpDays = new BigDecimal(days); //相差天数 |
| | | BigDecimal monthDay = new BigDecimal(DateUtil.getMonthDay(fromDate)); |
| | | BigDecimal resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)); |
| | | |
| | | // todo 5.0 计算 toDateFirstDate ----> toDate 月份 |
| | | days = (toDate.getTime() - toDateFirstDate.getTime()) * 1.00 / (24 * 60 * 60 * 1000); |
| | | tmpDays = new BigDecimal(days); //相差天数 |
| | | monthDay = new BigDecimal(DateUtil.getMonthDay(toDate)); |
| | | resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(resMonth); |
| | | |
| | | return resMonth.doubleValue(); |
| | | |
| | | } |
| | | |
| | | public double dayCompare1(Date fromDate, Date toDate) { |
| | | double resMonth = 0.0; |
| | | Calendar from = Calendar.getInstance(); |
| | | from.setTime(fromDate); |
| | | Calendar to = Calendar.getInstance(); |
| | | to.setTime(toDate); |
| | | //比较月份差 可能有整数 也会负数 |
| | | int result = to.get(Calendar.MONTH) - from.get(Calendar.MONTH); |
| | | //比较年差 |
| | | int month = (to.get(Calendar.YEAR) - from.get(Calendar.YEAR)) * 12; |
| | | |
| | | //真实 相差月份 |
| | | result = result + month; |
| | | |
| | | //开始时间 2021-06-01 2021-08-05 result = 2 2021-08-01 |
| | | Calendar newFrom = Calendar.getInstance(); |
| | | newFrom.setTime(fromDate); |
| | | newFrom.add(Calendar.MONTH, result); |
| | | //如果加月份后 大于了当前时间 默认加 月份 -1 情况 12-19 21-01-10 |
| | | //这个是神的逻辑一定好好理解 |
| | | if (newFrom.getTime().getTime() > toDate.getTime()) { |
| | | newFrom.setTime(fromDate); |
| | | result = result - 1; |
| | | newFrom.add(Calendar.MONTH, result); |
| | | } |
| | | |
| | | // t1 2021-08-01 t2 2021-08-05 |
| | | long t1 = newFrom.getTime().getTime(); |
| | | long t2 = to.getTime().getTime(); |
| | | //相差毫秒 |
| | | double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000); |
| | | BigDecimal tmpDays = new BigDecimal(days); //相差天数 |
| | | BigDecimal monthDay = null; |
| | | Calendar newFromMaxDay = Calendar.getInstance(); |
| | | newFromMaxDay.set(newFrom.get(Calendar.YEAR), newFrom.get(Calendar.MONTH), 1, 0, 0, 0); |
| | | newFromMaxDay.add(Calendar.MONTH, 1); //下个月1号 |
| | | //在当前月中 这块有问题 |
| | | if (toDate.getTime() < newFromMaxDay.getTime().getTime()) { |
| | | monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH)); |
| | | return tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).doubleValue(); |
| | | } |
| | | // 上月天数 |
| | | days = (newFromMaxDay.getTimeInMillis() - t1) * 1.00 / (24 * 60 * 60 * 1000); |
| | | tmpDays = new BigDecimal(days); |
| | | monthDay = new BigDecimal(newFrom.getActualMaximum(Calendar.DAY_OF_MONTH)); |
| | | BigDecimal preRresMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP); |
| | | |
| | | //下月天数 |
| | | days = (t2 - newFromMaxDay.getTimeInMillis()) * 1.00 / (24 * 60 * 60 * 1000); |
| | | tmpDays = new BigDecimal(days); |
| | | monthDay = new BigDecimal(newFromMaxDay.getActualMaximum(Calendar.DAY_OF_MONTH)); |
| | | resMonth = tmpDays.divide(monthDay, 4, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(result)).add(preRresMonth).doubleValue(); |
| | | return resMonth; |
| | | } |
| | | |
| | | } |