|
|
|
@@ -0,0 +1,506 @@ |
|
|
|
package com.iformall.service.helper; |
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.math.RoundingMode; |
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Calendar; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
import org.apache.commons.collections4.CollectionUtils; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.joda.time.DateTime; |
|
|
|
import org.joda.time.Months; |
|
|
|
import org.joda.time.format.DateTimeFormat; |
|
|
|
import org.joda.time.format.DateTimeFormatter; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSONArray; |
|
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
|
import com.iformall.domain.dto.NeedPayDTO; |
|
|
|
import com.iformall.domain.po.WxEnergyFees; |
|
|
|
import com.iformall.domain.po.WxPropertyContract; |
|
|
|
import com.iformall.domain.po.WxRentContract; |
|
|
|
import com.iformall.domain.vo.BillTimeVo; |
|
|
|
import com.iformall.domain.vo.WxBillFeesStandardsListVo; |
|
|
|
import com.iformall.enums.EnumFeesShopTimeType; |
|
|
|
import com.iformall.enums.EnumFeesStandardsCalcuteUnit; |
|
|
|
import com.iformall.enums.EnumPriceUnit; |
|
|
|
import com.iformall.enums.EnumRentContractAdjustPeriod; |
|
|
|
import com.iformall.enums.EnumRentContractAdjustRatioWay; |
|
|
|
import com.iformall.enums.EnumRentContractAgilPriceUnit; |
|
|
|
import com.iformall.enums.EnumRentContractAgilTimeUnit; |
|
|
|
import com.iformall.enums.EnumRentContractRentInputWay; |
|
|
|
import com.iformall.enums.EnumRentContractType; |
|
|
|
import com.iformall.enums.EnumRentDayPriceCalcute; |
|
|
|
import com.iformall.enums.EnumYesOrNo; |
|
|
|
import com.iformall.service.impl.WxRentContractServiceImpl; |
|
|
|
import com.iformall.utils.Constant; |
|
|
|
import com.iformall.utils.DateUtils; |
|
|
|
|
|
|
|
public class WxRentContractAgileHelper { |
|
|
|
|
|
|
|
|
|
|
|
public static List<Date> getYearsBeginList(Date startDate,Date endDate ) { |
|
|
|
int years = DateUtils.getBetweenYears(startDate,endDate); |
|
|
|
List<Date> yearList = new ArrayList<Date>(); |
|
|
|
for (int i = 0; i < years; i++) { |
|
|
|
Calendar instance = Calendar.getInstance(); |
|
|
|
instance.setTime(startDate); |
|
|
|
instance.set(Calendar.MILLISECOND, 0); |
|
|
|
instance.add(Calendar.MONTH, 12 * i); |
|
|
|
Date _startDate = instance.getTime(); |
|
|
|
yearList.add(_startDate); |
|
|
|
} |
|
|
|
return yearList; |
|
|
|
} |
|
|
|
|
|
|
|
public static List<BillTimeVo> initBillTimeList(List<Date> yearList,Date start,Date end,EnumFeesShopTimeType calcuteRule, |
|
|
|
EnumRentContractAgilTimeUnit timeUnit,int time,int payPeriod){ |
|
|
|
List<BillTimeVo> list = new ArrayList<>(); |
|
|
|
int count = 0; |
|
|
|
List<Date> yearsBeginList = new ArrayList<Date>(); |
|
|
|
yearsBeginList.addAll(yearList); |
|
|
|
if (yearsBeginList.size() > 0) { |
|
|
|
yearsBeginList.remove(0); |
|
|
|
} |
|
|
|
BillTimeVo receiveDate = null; |
|
|
|
while (true) { |
|
|
|
BillTimeVo timeVo = new BillTimeVo(); |
|
|
|
|
|
|
|
//账单日 |
|
|
|
Calendar instance = Calendar.getInstance(); |
|
|
|
instance.setTime(start); |
|
|
|
instance.set(Calendar.MILLISECOND, 0); |
|
|
|
//开始时间 |
|
|
|
timeVo.setStartDate(instance.getTime()); |
|
|
|
|
|
|
|
//结束时间 |
|
|
|
instance.clear(); |
|
|
|
instance.setTime(start); |
|
|
|
instance.set(Calendar.MILLISECOND, 0); |
|
|
|
instance = EnumRentContractAgilTimeUnit.getAfterCalendarDay(instance, time, timeUnit); |
|
|
|
//instance.add(dayType, receivePeriod); |
|
|
|
//instance.add(Calendar.DATE, -1); |
|
|
|
timeVo.setEndDate(instance.getTime()); |
|
|
|
|
|
|
|
//自然月,应该是从本月开始到本月结束 |
|
|
|
if(calcuteRule == EnumFeesShopTimeType.NATURE_PERIOD){ |
|
|
|
timeVo.setEndDate(EnumRentContractAgilTimeUnit.getAfterCalendarNarDay(timeVo.getStartDate(), time, timeUnit)); |
|
|
|
} |
|
|
|
|
|
|
|
//如果是到了每年的截止时间,第一年忽略(是开始时间) |
|
|
|
boolean isYearCut = false;//是不是有截断 |
|
|
|
if (null != yearsBeginList && yearsBeginList.size() > 0 ) { |
|
|
|
Date yearStartDate = yearsBeginList.get(0); |
|
|
|
//如果开始时间到了年的截止 |
|
|
|
if (timeVo.getStartDate().equals(yearStartDate)) { |
|
|
|
yearsBeginList.remove(yearStartDate); |
|
|
|
}else if (timeVo.getStartDate().after(yearStartDate)) { |
|
|
|
//do nothing |
|
|
|
}else if (timeVo.getStartDate().before(yearStartDate)) { |
|
|
|
Date yearStartDateEnd = DateUtils.getDayEnd(yearStartDate); |
|
|
|
if (timeVo.getEndDate().after(yearStartDateEnd)) { |
|
|
|
timeVo.setEndDate(DateUtils.getDaySet(yearStartDateEnd,Calendar.DATE,-1)); |
|
|
|
yearsBeginList.remove(yearStartDate); |
|
|
|
isYearCut = true; |
|
|
|
}else if(timeVo.getEndDate().equals(yearStartDateEnd)) { |
|
|
|
yearsBeginList.remove(yearStartDate); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(timeVo.getEndDate().after(end)){ |
|
|
|
Calendar endinstance = Calendar.getInstance(); |
|
|
|
endinstance.setTime(end); |
|
|
|
endinstance.set(Calendar.MILLISECOND, 0); |
|
|
|
timeVo.setEndDate(endinstance.getTime()); |
|
|
|
} |
|
|
|
|
|
|
|
list.add(timeVo); |
|
|
|
|
|
|
|
receiveDate = getReceiveDate(receiveDate,timeVo.getStartDate(), timeVo.getEndDate(), payPeriod,calcuteRule,time,timeUnit); |
|
|
|
timeVo.setReceiveDate(receiveDate.getStartDate()); |
|
|
|
|
|
|
|
|
|
|
|
//next |
|
|
|
start = DateUtils.getDaySet(timeVo.getEndDate(),Calendar.SECOND,1); |
|
|
|
|
|
|
|
if(start.after(end)) { |
|
|
|
break; |
|
|
|
} |
|
|
|
count ++; |
|
|
|
|
|
|
|
//预警 |
|
|
|
if(count >= 1000){ |
|
|
|
Logger logger = LoggerFactory.getLogger(WxRentContractServiceImpl.class); |
|
|
|
logger.error("initBillTimeList() warnCount max error !!!"); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
return list; |
|
|
|
} |
|
|
|
|
|
|
|
public static BillTimeVo getReceiveDate(BillTimeVo currentReceiveDate,Date start,Date end,int payPeriodRate, |
|
|
|
EnumFeesShopTimeType calcuteRule,Integer time,EnumRentContractAgilTimeUnit timeUnit) { |
|
|
|
if (null != currentReceiveDate) { |
|
|
|
if ((currentReceiveDate.getStartDate().equals(start) || currentReceiveDate.getStartDate().before(start) ) && |
|
|
|
(currentReceiveDate.getEndDate().equals(end) || currentReceiveDate.getEndDate().after(end) )) { |
|
|
|
return currentReceiveDate; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Calendar instance = Calendar.getInstance(); |
|
|
|
instance.setTime(start); |
|
|
|
instance.set(Calendar.MILLISECOND, 0); |
|
|
|
BillTimeVo vo = new BillTimeVo(); |
|
|
|
//按月计租 |
|
|
|
if (calcuteRule == EnumFeesShopTimeType.PERIOD) { |
|
|
|
//按月 |
|
|
|
if (timeUnit == EnumRentContractAgilTimeUnit.MONTH) { |
|
|
|
vo.setStartDate(instance.getTime()); |
|
|
|
Date endDate = EnumRentContractAgilTimeUnit.getAfterCalendarDay(instance, time*payPeriodRate, EnumRentContractAgilTimeUnit.MONTH).getTime(); |
|
|
|
vo.setEndDate(endDate); |
|
|
|
return vo; |
|
|
|
//自然季度 |
|
|
|
}else if(timeUnit == EnumRentContractAgilTimeUnit.QUATOR){ |
|
|
|
//如果开始日期是1号,则从开始日期算起,,如果不是,则从结束日期算起 |
|
|
|
int day = instance.get(Calendar.DAY_OF_MONTH); |
|
|
|
if (day == 1) { |
|
|
|
vo.setStartDate(instance.getTime()); |
|
|
|
Date endDate = EnumRentContractAgilTimeUnit.getAfterCalendarNarDay(instance.getTime(), time*payPeriodRate, EnumRentContractAgilTimeUnit.QUATOR); |
|
|
|
vo.setEndDate(endDate); |
|
|
|
return vo; |
|
|
|
}else { |
|
|
|
Date startDate = null; |
|
|
|
//如果是第一期,则取当前的周期 |
|
|
|
if (null == currentReceiveDate) { |
|
|
|
startDate = EnumRentContractAgilTimeUnit.getAfterCalendarNarDay(end, 0, EnumRentContractAgilTimeUnit.QUATOR); |
|
|
|
startDate = DateUtils.getSecondsTimeAfter(1, startDate); |
|
|
|
}else { |
|
|
|
startDate = EnumRentContractAgilTimeUnit.getAfterCalendarNarDay(end, -1*time*payPeriodRate, EnumRentContractAgilTimeUnit.QUATOR); |
|
|
|
} |
|
|
|
startDate = DateUtils.getFirstDayForCurrMonth(startDate); |
|
|
|
vo.setStartDate(startDate); |
|
|
|
vo.setEndDate(end); |
|
|
|
return vo; |
|
|
|
} |
|
|
|
}else if(timeUnit == EnumRentContractAgilTimeUnit.HALF_YEAR) { |
|
|
|
vo.setStartDate(instance.getTime()); |
|
|
|
Date endDate = EnumRentContractAgilTimeUnit.getAfterCalendarDay(instance, 6*time*payPeriodRate, EnumRentContractAgilTimeUnit.MONTH).getTime(); |
|
|
|
vo.setEndDate(endDate); |
|
|
|
return vo; |
|
|
|
}else if(timeUnit == EnumRentContractAgilTimeUnit.YEAR) { |
|
|
|
vo.setStartDate(instance.getTime()); |
|
|
|
Date endDate = EnumRentContractAgilTimeUnit.getAfterCalendarDay(instance, 12*time*payPeriodRate, EnumRentContractAgilTimeUnit.MONTH).getTime(); |
|
|
|
vo.setEndDate(endDate); |
|
|
|
return vo; |
|
|
|
}else { |
|
|
|
vo.setStartDate(start); |
|
|
|
vo.setEndDate(end); |
|
|
|
return vo; |
|
|
|
} |
|
|
|
}else if (calcuteRule == EnumFeesShopTimeType.NATURE_PERIOD) { |
|
|
|
//自然月 |
|
|
|
int day = instance.get(Calendar.DAY_OF_MONTH); |
|
|
|
if (day == 1) { |
|
|
|
vo.setStartDate(instance.getTime()); |
|
|
|
Date endDate = EnumRentContractAgilTimeUnit.getAfterCalendarNarDay(instance.getTime(), time*payPeriodRate, timeUnit); |
|
|
|
vo.setEndDate(endDate); |
|
|
|
return vo; |
|
|
|
}else { |
|
|
|
Date startDate = null; |
|
|
|
//如果是第一期,则取当前的周期 |
|
|
|
if (null == currentReceiveDate) { |
|
|
|
startDate = EnumRentContractAgilTimeUnit.getAfterCalendarNarDay(end, 0, timeUnit); |
|
|
|
startDate = DateUtils.getSecondsTimeAfter(1, startDate); |
|
|
|
}else { |
|
|
|
startDate = EnumRentContractAgilTimeUnit.getAfterCalendarNarDay(end, -1*time*payPeriodRate, timeUnit); |
|
|
|
} |
|
|
|
startDate = DateUtils.getFirstDayForCurrMonth(start); |
|
|
|
vo.setStartDate(startDate); |
|
|
|
vo.setEndDate(end); |
|
|
|
return vo; |
|
|
|
} |
|
|
|
}else { |
|
|
|
vo.setStartDate(start); |
|
|
|
vo.setEndDate(end); |
|
|
|
return vo; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//查询月账单需要支付的金额 |
|
|
|
public static String getNeedPayMoney(List<Date> freeDays,Integer decimalSize,EnumRentContractAgilPriceUnit priceUnit, |
|
|
|
String price,String rentArea,Date startDate,Date endDate,EnumRentDayPriceCalcute dayPriceRule,Integer monthAverageDays, |
|
|
|
Integer time,EnumRentContractAgilTimeUnit timeUnit){ |
|
|
|
String needpay; |
|
|
|
if (priceUnit == EnumRentContractAgilPriceUnit.RENT_PERIOD){ |
|
|
|
return price; |
|
|
|
}else if (priceUnit == EnumRentContractAgilPriceUnit.DAY){ |
|
|
|
BigDecimal priceD = new BigDecimal(price); |
|
|
|
String needpayD = WxRentContractHelper.getNeedPay(freeDays,Constant.default_long_decimal_size,priceD,startDate,endDate,dayPriceRule,monthAverageDays); |
|
|
|
needpay = new BigDecimal(needpayD).setScale(decimalSize, RoundingMode.HALF_UP).toPlainString(); |
|
|
|
}else if (priceUnit == EnumRentContractAgilPriceUnit.MM_DAY) { |
|
|
|
BigDecimal priceD = new BigDecimal(price).multiply(new BigDecimal(rentArea)); |
|
|
|
String needpayD = WxRentContractHelper.getNeedPay(freeDays,Constant.default_long_decimal_size,priceD,startDate,endDate,dayPriceRule,monthAverageDays); |
|
|
|
needpay = new BigDecimal(needpayD).setScale(decimalSize, RoundingMode.HALF_UP).toPlainString(); |
|
|
|
}else{ |
|
|
|
BigDecimal priceD = new BigDecimal(price); |
|
|
|
if (priceUnit == EnumRentContractAgilPriceUnit.MM_MONTH) { |
|
|
|
priceD = priceD.multiply(new BigDecimal(rentArea)); |
|
|
|
}else if (priceUnit == EnumRentContractAgilPriceUnit.QUATOR) { |
|
|
|
priceD = new BigDecimal(price).divide(new BigDecimal(3),Constant.default_long_decimal_size,RoundingMode.HALF_UP); |
|
|
|
}else if (priceUnit == EnumRentContractAgilPriceUnit.HALF_YEAR) { |
|
|
|
priceD = new BigDecimal(price).divide(new BigDecimal(6),Constant.default_long_decimal_size,RoundingMode.HALF_UP); |
|
|
|
}else if (priceUnit == EnumRentContractAgilPriceUnit.YEAR) { |
|
|
|
priceD = new BigDecimal(price).divide(new BigDecimal(12),Constant.default_long_decimal_size,RoundingMode.HALF_UP); |
|
|
|
} |
|
|
|
//判断是否满足整月 |
|
|
|
needpay = new BigDecimal(getMonthNeedPay(freeDays,Constant.default_long_decimal_size,priceD, startDate, endDate, |
|
|
|
timeUnit,time,dayPriceRule,monthAverageDays)).setScale(decimalSize, RoundingMode.HALF_UP).toPlainString(); |
|
|
|
} |
|
|
|
return needpay; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 按月计租 根据每月的日期总数计算needpay |
|
|
|
* @param monthPrice |
|
|
|
* @param start |
|
|
|
* @param end |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
private static String getMonthNeedPay(List<Date> freeDays,Integer decimalSize,BigDecimal price,Date start,Date end, |
|
|
|
EnumRentContractAgilTimeUnit timeUnit,int time,EnumRentDayPriceCalcute dayPriceRule,Integer monthAvageDays){ |
|
|
|
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd"); |
|
|
|
SimpleDateFormat sdM = new SimpleDateFormat("yyyy-MM"); |
|
|
|
SimpleDateFormat sdD = new SimpleDateFormat("d"); |
|
|
|
BigDecimal total = new BigDecimal(0); |
|
|
|
int[] diff; |
|
|
|
|
|
|
|
//同一天 |
|
|
|
if(sd.format(start).equals(sd.format(end))){ |
|
|
|
List<Date> validDays = getValidDays(start,end,freeDays); |
|
|
|
if (null == validDays || validDays.size() <= 0 ) { |
|
|
|
return "0"; |
|
|
|
} |
|
|
|
if (validDays.contains(start)) { |
|
|
|
int dayCount = getRealDays(dayPriceRule.getCode(), monthAvageDays, start); |
|
|
|
return price.divide(new BigDecimal(dayCount),decimalSize,BigDecimal.ROUND_HALF_UP).toPlainString(); |
|
|
|
}else { |
|
|
|
return "0"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//同月 |
|
|
|
if(sdM.format(start).equals(sdM.format(end))){ |
|
|
|
List<Date> validDays = getValidDays(start,end,freeDays); |
|
|
|
if (null == validDays || validDays.size() <= 0 ) { |
|
|
|
return "0"; |
|
|
|
} |
|
|
|
NeedPayDTO np = getCurrentMonthPay(start, end, price, decimalSize, validDays, dayPriceRule.getCode(), monthAvageDays); |
|
|
|
return np.getMoney().toPlainString(); |
|
|
|
} |
|
|
|
|
|
|
|
//正好是一个周期开始 |
|
|
|
boolean isPeriodStart = false; |
|
|
|
//如果是按自然季度,如果start不是1号,则也不是一个周期 |
|
|
|
if (timeUnit == EnumRentContractAgilTimeUnit.QUATOR) { |
|
|
|
String startday = sdD.format(start); |
|
|
|
if ("1".equals(startday)) { |
|
|
|
isPeriodStart = true; |
|
|
|
} |
|
|
|
}else { |
|
|
|
isPeriodStart = true; |
|
|
|
} |
|
|
|
if (isPeriodStart) { |
|
|
|
Calendar instance = Calendar.getInstance(); |
|
|
|
instance.setTime(start); |
|
|
|
instance = EnumRentContractAgilTimeUnit.getAfterCalendarDay(instance, time, timeUnit); |
|
|
|
if(sd.format(instance.getTime()).equals(sd.format(end))){ |
|
|
|
List<Date> validDays = getValidDays(start,end,freeDays); |
|
|
|
if (null == validDays || validDays.size() <= 0 ) { |
|
|
|
return "0"; |
|
|
|
} |
|
|
|
//如果该周期内是全部有效的,则用月份*金额 |
|
|
|
int allDays = DateUtils.daysBetween(start,end)+1; |
|
|
|
boolean isFull = false; |
|
|
|
if (allDays == validDays.size()) { |
|
|
|
isFull = true; |
|
|
|
} |
|
|
|
//不是一个月的。但是按整月算的 |
|
|
|
int months = getMonths(sdM.format(start)+"-01",sdM.format(DateUtils.getDaySet(end,Calendar.DATE,1))+"-01"); |
|
|
|
if (isFull) { |
|
|
|
return price.multiply(new BigDecimal(months)).toPlainString(); |
|
|
|
} |
|
|
|
//计费每个周期开始时间 |
|
|
|
Calendar periodStart = Calendar.getInstance(); |
|
|
|
periodStart.setTime(start); |
|
|
|
for (int i = 0 ; i < months; i++) { |
|
|
|
//每个计费1个月结束时间,可能是跨月的 |
|
|
|
Date periodEnd = EnumRentContractAgilTimeUnit.getAfterCalendarDay(periodStart, i+1, EnumRentContractAgilTimeUnit.MONTH).getTime(); |
|
|
|
|
|
|
|
//当前开始时间到当前月底 |
|
|
|
Date currentMonthEnd = DateUtils.getLastDayForMonth(start); |
|
|
|
NeedPayDTO np = getCurrentMonthPay(start, currentMonthEnd, price, decimalSize, validDays, dayPriceRule.getCode(), monthAvageDays); |
|
|
|
total = total.add(np.getMoney()); |
|
|
|
|
|
|
|
if(periodEnd.after(currentMonthEnd)) { |
|
|
|
start = DateUtils.getDaySet(currentMonthEnd,Calendar.DATE,1); |
|
|
|
NeedPayDTO lnp = getCurrentMonthPay(start, periodEnd, price, decimalSize, validDays, dayPriceRule.getCode(), monthAvageDays); |
|
|
|
total = total.add(lnp.getMoney()); |
|
|
|
}else { |
|
|
|
start = DateUtils.getDaySet(currentMonthEnd,Calendar.DATE,1); |
|
|
|
periodStart.setTime(start); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
return total.toPlainString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//开始到这个月底 |
|
|
|
Date lastMonthDay = DateUtils.getLastDayForMonth(start); |
|
|
|
List<Date> currValidDays = getValidDays(start,lastMonthDay,freeDays); |
|
|
|
if (null == currValidDays || currValidDays.size() <= 0 ) { |
|
|
|
}else { |
|
|
|
NeedPayDTO np = getCurrentMonthPay(start, lastMonthDay, price, decimalSize, currValidDays, dayPriceRule.getCode(), monthAvageDays); |
|
|
|
total = total.add(np.getMoney()); |
|
|
|
System.out.println("首1月>>>>"+DateUtils.date2String(start)+">>>"+DateUtils.date2String(lastMonthDay)+">>>>"+total.toPlainString()); |
|
|
|
} |
|
|
|
|
|
|
|
//中间月份 |
|
|
|
Date newStartDate = DateUtils.getDaySet(lastMonthDay,Calendar.SECOND,1); |
|
|
|
int months = getMonths(sdM.format(newStartDate)+"-01",sdM.format(end)+"-01"); |
|
|
|
for (int i = 0 ; i < months; i++) { |
|
|
|
Date currentMonthEnd = DateUtils.getLastDayForMonth(newStartDate); |
|
|
|
List<Date> _validDays = getValidDays(newStartDate,currentMonthEnd,freeDays); |
|
|
|
if (null == _validDays ||_validDays.size() <= 0 ) { |
|
|
|
}else { |
|
|
|
NeedPayDTO _np = getCurrentMonthPay(newStartDate, currentMonthEnd, price, decimalSize, _validDays, dayPriceRule.getCode(), monthAvageDays); |
|
|
|
System.out.println(i+2+"月>>>>"+DateUtils.date2String(newStartDate)+">>>>"+DateUtils.date2String(currentMonthEnd)+">>>>"+_np.getMoney().toPlainString()); |
|
|
|
newStartDate = DateUtils.getDaySet(currentMonthEnd,Calendar.SECOND,1); |
|
|
|
total = total.add(_np.getMoney()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//最后一个月 |
|
|
|
if (newStartDate.before(end)) { |
|
|
|
List<Date> lastValidDays = getValidDays(newStartDate,end,freeDays); |
|
|
|
if (null == lastValidDays || lastValidDays.size() <= 0 ) { |
|
|
|
}else { |
|
|
|
NeedPayDTO enp = getCurrentMonthPay(newStartDate, end, price, decimalSize, lastValidDays, dayPriceRule.getCode(), monthAvageDays); |
|
|
|
total = total.add(enp.getMoney()); |
|
|
|
System.out.println("末月>>>>"+DateUtils.date2String(newStartDate)+">>>"+DateUtils.date2String(end)+">>>>"+enp.getMoney().toPlainString()); |
|
|
|
} |
|
|
|
} |
|
|
|
return total.toPlainString(); |
|
|
|
} |
|
|
|
|
|
|
|
public static List<Date> getValidDays(Date start,Date end,List<Date> freeDays) { |
|
|
|
List<Date> allDays = DateUtils.getAllDays(start, end); |
|
|
|
if (null == allDays) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
List<Date> validDays = new ArrayList<Date>(); |
|
|
|
validDays.addAll(allDays); |
|
|
|
if (null != freeDays) { |
|
|
|
List<Date> currfreeDays = (List<Date>) CollectionUtils.intersection(allDays, freeDays); |
|
|
|
if (null != currfreeDays) { |
|
|
|
validDays.removeAll(currfreeDays); |
|
|
|
} |
|
|
|
} |
|
|
|
return validDays; |
|
|
|
} |
|
|
|
|
|
|
|
//查询当前月内的金额 |
|
|
|
private static NeedPayDTO getCurrentMonthPay(Date start,Date end, BigDecimal priceMonth,Integer decimalSize,List<Date> validDays,Integer dayPriceCalcute,Integer monthAvageDays) { |
|
|
|
NeedPayDTO np = new NeedPayDTO(); |
|
|
|
//当月实际天数 |
|
|
|
int md = DateUtils.getMonthDayCount(start);; |
|
|
|
//在有效的时间里面有多少天 |
|
|
|
int ms = getDays(start,end,validDays); |
|
|
|
|
|
|
|
//计算天数 |
|
|
|
int dayCount = getRealDays(dayPriceCalcute, monthAvageDays, start); |
|
|
|
int sed = DateUtils.daysBetween(start,end)+1; |
|
|
|
|
|
|
|
//满月 |
|
|
|
if (md == sed) { |
|
|
|
//如果有免租的,则按天算 |
|
|
|
if (ms == md) { |
|
|
|
np.setFullMonth(true); |
|
|
|
np.setMoney(priceMonth); |
|
|
|
}else { |
|
|
|
np.setFullMonth(false); |
|
|
|
np.setMoney(new BigDecimal(ms).multiply(priceMonth).divide(new BigDecimal(dayCount),decimalSize,BigDecimal.ROUND_HALF_UP)); |
|
|
|
} |
|
|
|
}else { |
|
|
|
np.setFullMonth(false); |
|
|
|
np.setMoney(new BigDecimal(ms).multiply(priceMonth).divide(new BigDecimal(dayCount),decimalSize,BigDecimal.ROUND_HALF_UP)); |
|
|
|
} |
|
|
|
return np; |
|
|
|
} |
|
|
|
|
|
|
|
private static int getRealDays(Integer dayPriceCalcute,Integer monthAvageDays,Date start) { |
|
|
|
//是不是按实际天数来计算 |
|
|
|
boolean isRealDays = true; |
|
|
|
if (dayPriceCalcute.intValue() == EnumRentDayPriceCalcute.REAL_DAYS.getCode().intValue()) { |
|
|
|
}else { |
|
|
|
isRealDays = false; |
|
|
|
} |
|
|
|
if (isRealDays) { |
|
|
|
return DateUtils.getMonthDayCount(start); |
|
|
|
}else { |
|
|
|
return monthAvageDays; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private static int getDays(Date start,Date end,List<Date> allDays) { |
|
|
|
if (null == allDays || allDays.size() <= 0 ) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
//如果可用区间的最大比start小 |
|
|
|
if (start.after(allDays.get(allDays.size()-1))) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
List<Date> _tempList = new ArrayList<Date>(); |
|
|
|
_tempList.addAll(allDays); |
|
|
|
Date _end = DateUtils.getDayBegin(end); |
|
|
|
|
|
|
|
//如果可用区间的最大闭end小,相当于这一期是尾 |
|
|
|
Date allDayEnd = DateUtils.getDayBegin(allDays.get(allDays.size()-1)); |
|
|
|
if (end.after(allDayEnd)) { |
|
|
|
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)) { |
|
|
|
allDays.remove(a); |
|
|
|
return i+1; |
|
|
|
}else if (a.after(_end)) { |
|
|
|
return i; |
|
|
|
}else { |
|
|
|
allDays.remove(a); |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
public static int getMonths(String startStr,String endStr){ |
|
|
|
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd"); |
|
|
|
DateTime start = formatter.parseDateTime(startStr); |
|
|
|
DateTime end = formatter.parseDateTime(endStr); |
|
|
|
int months = Months.monthsBetween(start, end).getMonths(); |
|
|
|
return months; |
|
|
|
} |
|
|
|
} |