From 3951d41815b3f5e4b5fc28fbcd353bfe7fcbc386 Mon Sep 17 00:00:00 2001 From: winter Date: Sun, 4 Aug 2024 09:49:19 +0800 Subject: [PATCH] fix --- .../com/iformall/domain/po/WxEnergyFees.java | 2 +- .../service/helper/WxRentContractHelper.java | 177 ++++++++++++------ .../impl/WxPropertyContractServiceImpl.java | 2 +- 3 files changed, 123 insertions(+), 58 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxEnergyFees.java b/mallinkService/src/main/java/com/iformall/domain/po/WxEnergyFees.java index 386e051bf..a97967256 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxEnergyFees.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxEnergyFees.java @@ -133,7 +133,7 @@ public class WxEnergyFees extends TenantEntity { if (this.timeUnit.intValue() == EnumFeesStandardsTimeUnit.DAY.getCode().intValue()) { BigDecimal priceD = new BigDecimal(this.price); priceD = priceD.multiply(new BigDecimal(count)); - return WxRentContractHelper.getNeedPay(null,decimalSize,new BigDecimal(0),priceD,start,end,priceCalcute,monthDays); + return WxRentContractHelper.getNeedPay(null,decimalSize,priceD,start,end,priceCalcute,monthDays); }else { //按月计算 BigDecimal priceMonth = new BigDecimal(this.price); diff --git a/mallinkService/src/main/java/com/iformall/service/helper/WxRentContractHelper.java b/mallinkService/src/main/java/com/iformall/service/helper/WxRentContractHelper.java index 5e8470000..661bad261 100644 --- a/mallinkService/src/main/java/com/iformall/service/helper/WxRentContractHelper.java +++ b/mallinkService/src/main/java/com/iformall/service/helper/WxRentContractHelper.java @@ -361,7 +361,7 @@ public class WxRentContractHelper { if (wxRentContract.getPriceUnit().equals(EnumPriceUnit.D.getCode())){ BigDecimal priceD = new BigDecimal(price); - String needpayD = WxRentContractHelper.getNeedPay(freeDays,Constant.default_long_decimal_size,new BigDecimal(0),priceD,startDate,endDate,priceCalcute,wxRentContract.getMonthAverageDays()); + String needpayD = WxRentContractHelper.getNeedPay(freeDays,Constant.default_long_decimal_size,priceD,startDate,endDate,priceCalcute,wxRentContract.getMonthAverageDays()); //取整 //needpay = new Double(needpayD).longValue(); //四舍五入 @@ -429,7 +429,6 @@ public class WxRentContractHelper { return false; } - /** * 按月计租 根据每月的日期总数计算needpay * @param monthPrice @@ -444,25 +443,12 @@ public class WxRentContractHelper { BigDecimal total = new BigDecimal(0); int[] diff; - List allDaysFrees = DateUtils.getAllDays(start, end); - if (null == allDaysFrees) { - return "0"; - } - List validDays = new ArrayList(); - validDays.addAll(allDaysFrees); - if (null != freeDays && freeDays.size() > 0 ) { - allDaysFrees.retainAll(freeDays); - } - if (null != freeDays && freeDays.size() > 0 && null != allDaysFrees && allDaysFrees.size() > 0 ) { - validDays.removeAll(allDaysFrees); - } - if (validDays.size() <= 0 ) { - return "0"; - } - - //同一天 if(sd.format(start).equals(sd.format(end))){ + List validDays = getValidDays(start,end,freeDays); + if (validDays.size() <= 0 ) { + return "0"; + } if (validDays.contains(start)) { int dayCount = getRealDays(dayPriceCalcute, monthAvageDays, start); return price.divide(new BigDecimal(dayCount),decimalSize,BigDecimal.ROUND_HALF_UP).toPlainString(); @@ -473,6 +459,10 @@ public class WxRentContractHelper { //同月 if(sdM.format(start).equals(sdM.format(end))){ + List validDays = getValidDays(start,end,freeDays); + if (validDays.size() <= 0 ) { + return "0"; + } NeedPayDTO np = getMonthPay(start, end, price, decimalSize, validDays, dayPriceCalcute, monthAvageDays); return np.getMoney().toPlainString(); } @@ -481,6 +471,10 @@ public class WxRentContractHelper { instance.setTime(start); instance = EnumContractReceivePeriodUnit.getAfterCalendarDay(instance, receivePeriod, dayType); if(sd.format(instance.getTime()).equals(sd.format(end))){ + List validDays = getValidDays(start,end,freeDays); + if (validDays.size() <= 0 ) { + return "0"; + } //不是一个月的。但是按整月算的 int months = getMonths(sdM.format(start)+"-01",sdM.format(DateUtils.getDaySet(end,Calendar.DATE,1))+"-01"); for (int i = 0 ; i < months; i++) { @@ -494,34 +488,68 @@ public class WxRentContractHelper { //开始到这个月底 Date lastMonthDay = DateUtils.getLastDayForMonth(start); - NeedPayDTO np = getMonthPay(start, lastMonthDay, price, decimalSize, validDays, dayPriceCalcute, monthAvageDays); + List currValidDays = getValidDays(start,lastMonthDay,freeDays); + if (currValidDays.size() <= 0 ) { + return "0"; + } + NeedPayDTO np = getMonthPay(start, lastMonthDay, price, decimalSize, currValidDays, dayPriceCalcute, monthAvageDays); total = total.add(np.getMoney()); + System.out.println("首1月>>>>"+DateUtils.date2String(start)+">>>"+DateUtils.date2String(lastMonthDay)+">>>>"+total.toPlainString()); //中间月份 Date newStartDate = DateUtils.getDaySet(lastMonthDay,Calendar.DATE,1); int months = getMonths(sdM.format(newStartDate)+"-01",sdM.format(end)+"-01"); for (int i = 0 ; i < months; i++) { Date currentMonthEnd = DateUtils.getLastDayForMonth(newStartDate); - NeedPayDTO _np = getMonthPay(newStartDate, currentMonthEnd, price, decimalSize, validDays, dayPriceCalcute, monthAvageDays); - newStartDate = DateUtils.getDaySet(currentMonthEnd,Calendar.DATE,1); - total = total.add(_np.getMoney()); + List _validDays = getValidDays(newStartDate,currentMonthEnd,freeDays); + if (_validDays.size() <= 0 ) { + }else { + NeedPayDTO _np = getMonthPay(newStartDate, currentMonthEnd, price, decimalSize, _validDays, dayPriceCalcute, monthAvageDays); + System.out.println(i+2+"月>>>>"+DateUtils.date2String(newStartDate)+">>>>"+DateUtils.date2String(currentMonthEnd)+">>>>"+_np.getMoney().toPlainString()); + newStartDate = DateUtils.getDaySet(currentMonthEnd,Calendar.DATE,1); + total = total.add(_np.getMoney()); + } } //最后一个月 if (newStartDate.before(end)) { - NeedPayDTO enp = getMonthPay(DateUtils.getFirstDayForCurrMonth(end), end, price, decimalSize, validDays, dayPriceCalcute, monthAvageDays); + Date last = DateUtils.getFirstDayForCurrMonth(end); + List lastValidDays = getValidDays(last,end,freeDays); + if (lastValidDays.size() <= 0 ) { + return "0"; + } + NeedPayDTO enp = getMonthPay(last, end, price, decimalSize, lastValidDays, dayPriceCalcute, monthAvageDays); total = total.add(enp.getMoney()); + System.out.println("末月>>>>"+DateUtils.date2String(last)+">>>"+DateUtils.date2String(end)+">>>>"+enp.getMoney().toPlainString()); } return total.toPlainString(); } + private static List getValidDays(Date start,Date end,List freeDays) { + List allDaysFrees = DateUtils.getAllDays(start, end); + if (null == allDaysFrees) { + return null; + } + List validDays = new ArrayList(); + validDays.addAll(allDaysFrees); + if (null != freeDays && freeDays.size() > 0 ) { + allDaysFrees.retainAll(freeDays); + } + if (null != freeDays && freeDays.size() > 0 && null != allDaysFrees && allDaysFrees.size() > 0 ) { + validDays.removeAll(allDaysFrees); + } + if (validDays.size() <= 0 ) { + return null; + } + return validDays; + } private static NeedPayDTO getMonthPay(Date start,Date end, BigDecimal priceMonth,Integer decimalSize,List validDays,Integer dayPriceCalcute,Integer monthAvageDays) { NeedPayDTO np = new NeedPayDTO(); //当月实际天数 int md = DateUtils.getMonthDayCount(start);; //在有效的时间里面有多少天 - int ms = getDays(end,validDays); + int ms = getDays(start,end,validDays); //计算天数 int dayCount = getRealDays(dayPriceCalcute, monthAvageDays, start); @@ -582,7 +610,7 @@ public class WxRentContractHelper { * @param end * @return */ - public static String getNeedPay(List freeDays,Integer decimalSize,BigDecimal monthPrice,BigDecimal dayPrice,Date start,Date end,EnumRentDayPriceCalcute priceCalcute,Integer monthDays){ + public static String getNeedPay(List freeDays,Integer decimalSize,BigDecimal dayPrice,Date start,Date end,EnumRentDayPriceCalcute priceCalcute,Integer monthDays){ SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdM = new SimpleDateFormat("yyyy-MM"); BigDecimal total; @@ -607,12 +635,7 @@ public class WxRentContractHelper { } int dayCount = getRealMonthDays(priceCalcute,monthDays,start); - BigDecimal price; - if(monthPrice.compareTo(new BigDecimal(0)) > 0){ - price = monthPrice.divide(new BigDecimal(dayCount),decimalSize,BigDecimal.ROUND_HALF_UP); - }else{ - price = dayPrice; - } + BigDecimal price = dayPrice; //同一天 if(sd.format(start).equals(sd.format(end))){ @@ -624,48 +647,45 @@ public class WxRentContractHelper { } //同月 if(sdM.format(start).equals(sdM.format(end))){ - //diff = DateUtils.getDiff(start,end); - //return new BigDecimal((diff[1]+1)).multiply(price).setScale(decimalSize, BigDecimal.ROUND_HALF_UP).toPlainString(); - return new BigDecimal(validDays.size()).multiply(price).setScale(decimalSize, BigDecimal.ROUND_HALF_UP).toPlainString(); + int ds = getDays(start,end,validDays); + int mds = DateUtils.getMonthDayCount(start); + //重新计算每一天的单价 + //BigDecimal _price = dayPrice.multiply(new BigDecimal(dayCount)).divide(new BigDecimal(mds),decimalSize, BigDecimal.ROUND_HALF_UP); + //return new BigDecimal(ds).multiply(_price).toPlainString(); + return dayPrice.multiply(new BigDecimal(dayCount)).multiply(new BigDecimal(ds)).divide(new BigDecimal(mds),decimalSize, BigDecimal.ROUND_HALF_UP).toPlainString(); } //当月截止 Date currEnd = DateUtils.getLastDayForMonth(start); - //diff = DateUtils.getDiff(start,currEnd); - //total = new BigDecimal((diff[1]+1)).multiply(price).setScale(decimalSize, BigDecimal.ROUND_HALF_UP); - int ds = getDays(currEnd,validDays); - total = new BigDecimal(ds).multiply(price).setScale(decimalSize, BigDecimal.ROUND_HALF_UP); + int ds = getDays(start,currEnd,validDays); + //重新计算每一天的单价 + int mds = DateUtils.getMonthDayCount(start); + //BigDecimal price0 = dayPrice.multiply(new BigDecimal(dayCount)).divide(new BigDecimal(mds),decimalSize, BigDecimal.ROUND_HALF_UP); + //total = new BigDecimal(ds).multiply(price0); + total = dayPrice.multiply(new BigDecimal(dayCount)).multiply(new BigDecimal(ds)).divide(new BigDecimal(mds),decimalSize, BigDecimal.ROUND_HALF_UP); int warnCount = 0; while (true){ Date monthStartDate = DateUtils.getDaySet(currEnd,Calendar.DATE,1); dayCount = getRealMonthDays(priceCalcute,monthDays,monthStartDate); - //dayCount = DateUtils.getMonthDayCount(monthStartDate); - if(monthPrice.compareTo(new BigDecimal(0)) > 0){ - price = monthPrice.divide(new BigDecimal(dayCount),decimalSize,BigDecimal.ROUND_HALF_UP); - }else{ - price = dayPrice; - } - + //重新计算每一天的单价 + int _mds = DateUtils.getMonthDayCount(monthStartDate); + //BigDecimal _price = dayPrice.multiply(new BigDecimal(dayCount)).divide(new BigDecimal(_mds),decimalSize, BigDecimal.ROUND_HALF_UP); //最后一个月 if(sdM.format(monthStartDate).equals(sdM.format(end))){ - int ms = getDays(end,validDays); - //diff = DateUtils.getDiff(monthStartDate,end); - //total = total.add(price.multiply(new BigDecimal((diff[1]+1))).setScale(decimalSize, BigDecimal.ROUND_HALF_UP)); - total = total.add(price.multiply(new BigDecimal(ms)).setScale(decimalSize, BigDecimal.ROUND_HALF_UP)); + int ms = getDays(monthStartDate,end,validDays); + total = total.add(dayPrice.multiply(new BigDecimal(dayCount)).multiply(new BigDecimal(ms)).divide(new BigDecimal(_mds),decimalSize, BigDecimal.ROUND_HALF_UP)); break; }else{ currEnd = DateUtils.getLastDayForMonth(monthStartDate); - //diff = DateUtils.getDiff(monthStartDate,currEnd); - //total = total.add(price.multiply(new BigDecimal((diff[1]+1))).setScale(decimalSize, BigDecimal.ROUND_HALF_UP)); - int ms = getDays(currEnd,validDays); - total = total.add(price.multiply(new BigDecimal(ms)).setScale(decimalSize, BigDecimal.ROUND_HALF_UP)); + int ms = getDays(monthStartDate,currEnd,validDays); + total = total.add(dayPrice.multiply(new BigDecimal(dayCount)).multiply(new BigDecimal(ms)).divide(new BigDecimal(_mds),decimalSize, BigDecimal.ROUND_HALF_UP)); } //预警 if(warnCount >= 1000){ Logger logger = LoggerFactory.getLogger(WxRentContractServiceImpl.class); - logger.error("getNeedPay() warnCount max error !!! monthPrice:{},dayPrice:{},start:{},end:{}",monthPrice,dayPrice,sd.format(start),sd.format(end)); + logger.error("getNeedPay() warnCount max error !!! dayPrice:{},start:{},end:{}",dayPrice,sd.format(start),sd.format(end)); break; } warnCount ++; @@ -673,13 +693,28 @@ public class WxRentContractHelper { return total.setScale(decimalSize, BigDecimal.ROUND_HALF_UP).toPlainString(); } - private static int getDays(Date end,List allDays) { + private static int getDays(Date start,Date end,List allDays) { if (null == allDays || allDays.size() <= 0 ) { return 0; } + + //如果可用区间的最大闭start小 + if (start.after(allDays.get(allDays.size()-1))) { + return 0; + } + List _tempList = new ArrayList(); _tempList.addAll(allDays); Date _end = DateUtils.getDayBegin(end); + + //如果可用区间的最大闭end小,相当于这一期是尾 + if (end.after(allDays.get(allDays.size()-1))) { + int ret = allDays.size(); + allDays.clear(); + return ret; + } + + for (int i = 0 ; i < _tempList.size(); i ++) { Date a = _tempList.get(i); if (a.equals(_end)) { @@ -693,4 +728,34 @@ public class WxRentContractHelper { } return 0; } + + public static void main(String[] args) { + Date start = DateUtils.str2Date("2024-08-05 00:00:00").getTime(); + Date end = DateUtils.str2Date("2025-11-04 23:59:59").getTime(); + + Date d1 = DateUtils.str2Date("2024-07-31 00:00:00").getTime(); + Date d2 = DateUtils.str2Date("2024-08-03 00:00:00").getTime(); + Date d3 = DateUtils.str2Date("2024-08-06 00:00:00").getTime(); + Date d4 = DateUtils.str2Date("2024-08-31 00:00:00").getTime(); + Date d5 = DateUtils.str2Date("2024-09-01 00:00:00").getTime(); + Date d6 = DateUtils.str2Date("2024-09-11 00:00:00").getTime(); + Date d7 = DateUtils.str2Date("2024-09-30 00:00:00").getTime(); + + List freeDays = new ArrayList(); + freeDays.add(d1); + freeDays.add(d2); + freeDays.add(d3); + freeDays.add(d4); + freeDays.add(d5); + freeDays.add(d6); + freeDays.add(d7); + + //String dayMoney = getNeedPay(freeDays, 2, new BigDecimal(10), start, end, EnumRentDayPriceCalcute.AVERAGE_DAYS, 30); + //System.out.println(dayMoney); + + String monthMoney = getMonthNeedPay(freeDays, 2, new BigDecimal(2000), start, end, EnumContractReceivePeriodUnit.QUARTER.getCode(), 1, EnumRentDayPriceCalcute.AVERAGE_DAYS.getCode(), 30); + System.out.println(monthMoney); + + } + } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxPropertyContractServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxPropertyContractServiceImpl.java index 03b5692f2..bafb7fbd1 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxPropertyContractServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxPropertyContractServiceImpl.java @@ -906,7 +906,7 @@ public class WxPropertyContractServiceImpl implements WxPropertyContractService //按日 if (wxRentContract.getPriceUnit().equals(EnumPriceUnit.D.getCode())){ BigDecimal priceD = new BigDecimal(price); - String needpayD = WxRentContractHelper.getNeedPay(null,wxRentContract.getDecimalSize(),new BigDecimal(0),priceD,startDate,endDate,dayPrice,wxRentContract.getMonthAverageDays()); + String needpayD = WxRentContractHelper.getNeedPay(null,wxRentContract.getDecimalSize(),priceD,startDate,endDate,dayPrice,wxRentContract.getMonthAverageDays()); needpay = needpayD; //按月计算 }else{