PayFeeMonthHelp.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. package com.java110.fee.feeMonth;
  2. import com.java110.core.factory.GenerateCodeFactory;
  3. import com.java110.core.smo.IComputeFeeSMO;
  4. import com.java110.dto.fee.FeeAttrDto;
  5. import com.java110.dto.fee.FeeDetailDto;
  6. import com.java110.dto.fee.FeeDto;
  7. import com.java110.dto.payFee.PayFeeDetailMonthDto;
  8. import com.java110.dto.payFee.PayFeeMonthOwnerDto;
  9. import com.java110.intf.community.IRoomInnerServiceSMO;
  10. import com.java110.intf.fee.IPayFeeDetailMonthInnerServiceSMO;
  11. import com.java110.po.payFee.PayFeeDetailMonthPo;
  12. import com.java110.utils.util.DateUtil;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Service;
  15. import java.math.BigDecimal;
  16. import java.util.*;
  17. @Service
  18. public class PayFeeMonthHelp implements IPayFeeMonthHelp {
  19. @Autowired
  20. private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
  21. @Autowired
  22. private IComputeFeeSMO computeFeeSMOImpl;
  23. @Autowired
  24. private IPayFeeDetailMonthInnerServiceSMO payFeeDetailMonthInnerServiceSMOImpl;
  25. public PayFeeMonthOwnerDto generatorOwnerRoom(FeeDto feeDto) {
  26. PayFeeMonthOwnerDto payFeeMonthOwnerDto = new PayFeeMonthOwnerDto();
  27. payFeeMonthOwnerDto.setOwnerId(FeeAttrDto.getFeeAttrValue(feeDto, FeeAttrDto.SPEC_CD_OWNER_ID));
  28. payFeeMonthOwnerDto.setOwnerName(FeeAttrDto.getFeeAttrValue(feeDto, FeeAttrDto.SPEC_CD_OWNER_NAME));
  29. payFeeMonthOwnerDto.setLink(FeeAttrDto.getFeeAttrValue(feeDto, FeeAttrDto.SPEC_CD_OWNER_LINK));
  30. payFeeMonthOwnerDto.setObjName(FeeAttrDto.getFeeAttrValue(feeDto, FeeAttrDto.SPEC_CD_PAY_OBJECT_NAME));
  31. payFeeMonthOwnerDto.setObjId(feeDto.getPayerObjId());
  32. return payFeeMonthOwnerDto;
  33. }
  34. /**
  35. * 计算每月单价
  36. *
  37. * @param feeDto
  38. * @return
  39. */
  40. public Double getMonthFeePrice(FeeDto feeDto) {
  41. Map feePriceAll = computeFeeSMOImpl.getFeePrice(feeDto);
  42. Double feePrice = Double.parseDouble(feePriceAll.get("feePrice").toString());
  43. //todo 如果是一次性费用 除以
  44. // if (!FeeDto.FEE_FLAG_ONCE.equals(feeDto.getPayerObjType())) {
  45. // return feePrice;
  46. // }
  47. // double maxMonth = Math.ceil(computeFeeSMOImpl.dayCompare(feeDto.getStartTime(), feeDto.getEndTime()));
  48. // if (maxMonth <= 0) {
  49. // return feePrice;
  50. //
  51. // }
  52. // BigDecimal feePriceDec = new BigDecimal(feePrice).divide(new BigDecimal(maxMonth), 2, BigDecimal.ROUND_HALF_UP);
  53. // feePrice = feePriceDec.doubleValue();
  54. return feePrice;
  55. }
  56. @Override
  57. public Double getDiscountAmount(Double feePrice, double receivedAmount, Date curDate, FeeDto feeDto) {
  58. //todo 这种情况下应该 优惠为0
  59. if (curDate.getTime() >= feeDto.getEndTime().getTime()) {
  60. return 0.00;
  61. }
  62. BigDecimal discountAmountDec = new BigDecimal(feePrice).subtract(new BigDecimal(receivedAmount)).setScale(4, BigDecimal.ROUND_HALF_UP);
  63. return discountAmountDec.doubleValue();
  64. }
  65. /**
  66. * 处理已经交过费的记录处理
  67. *
  68. * @param feeDto
  69. * @param payFeeMonthOwnerDto
  70. */
  71. @Override
  72. public void waitDispersedFeeDetail(FeeDto feeDto, PayFeeMonthOwnerDto payFeeMonthOwnerDto) {
  73. PayFeeDetailMonthDto payFeeDetailMonthDto = new PayFeeDetailMonthDto();
  74. payFeeDetailMonthDto.setCommunityId(feeDto.getCommunityId());
  75. payFeeDetailMonthDto.setFeeId(feeDto.getFeeId());
  76. List<FeeDetailDto> feeDetailDtos = payFeeDetailMonthInnerServiceSMOImpl.getWaitDispersedFeeDetail(payFeeDetailMonthDto);
  77. if (feeDetailDtos == null || feeDetailDtos.size() < 1) {
  78. return;
  79. }
  80. for (FeeDetailDto feeDetailDto : feeDetailDtos) {
  81. // todo 逐条去离散
  82. doDispersedFeeDetail(feeDetailDto, feeDto, payFeeMonthOwnerDto);
  83. }
  84. }
  85. /**
  86. * 处理 欠费 离散
  87. *
  88. * @param feeDto
  89. * @param payFeeMonthOwnerDto
  90. * @param feePrice
  91. * @param deadlineTime
  92. */
  93. @Override
  94. public void waitDispersedOweFee(FeeDto feeDto, PayFeeMonthOwnerDto payFeeMonthOwnerDto, Double feePrice, Date deadlineTime) {
  95. // todo 费用已经结束
  96. if (FeeDto.STATE_FINISH.equals(feeDto.getState())) {
  97. return;
  98. }
  99. // todo 清理 detailId 为-1 的数据
  100. PayFeeDetailMonthPo payFeeDetailMonthPo = new PayFeeDetailMonthPo();
  101. payFeeDetailMonthPo.setCommunityId(feeDto.getCommunityId());
  102. payFeeDetailMonthPo.setFeeId(feeDto.getFeeId());
  103. payFeeDetailMonthPo.setDetailId("-1");
  104. payFeeDetailMonthInnerServiceSMOImpl.deletePayFeeDetailMonth(payFeeDetailMonthPo);
  105. List<PayFeeDetailMonthPo> payFeeDetailMonthPos = new ArrayList<>();
  106. // todo 处理 开始时间和结束时间
  107. Date startTime = DateUtil.timeToDate(feeDto.getEndTime());
  108. Date endTime = DateUtil.timeToDate(deadlineTime);
  109. BigDecimal receivableAmount = new BigDecimal(feePrice);
  110. BigDecimal dayReceivableAmount = null;
  111. //todo 一次性费用 日应收计算
  112. if (FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
  113. int day = DateUtil.daysBetween(endTime, startTime);
  114. if (day < 1) {
  115. day = 1;
  116. }
  117. dayReceivableAmount = receivableAmount.divide(new BigDecimal(day), 4, BigDecimal.ROUND_HALF_UP);// 日 应收
  118. }
  119. // todo 寻找第一个自然月 一日
  120. Calendar firstMonthDayCal = Calendar.getInstance();
  121. firstMonthDayCal.setTime(startTime);
  122. firstMonthDayCal.add(Calendar.MONTH, 1);
  123. firstMonthDayCal.set(Calendar.DAY_OF_MONTH, 1);
  124. Date firstMonthDayTime = firstMonthDayCal.getTime();
  125. Date startMonthDayTime = startTime;
  126. // todo 循环,只到 firstMonthDayTime 大于 endTime
  127. int curDay = 0;
  128. int curMonthMaxDay = 30;
  129. BigDecimal curMonthReceivableAmount = null;
  130. while (firstMonthDayTime.getTime() < endTime.getTime()) {
  131. curDay = DateUtil.daysBetween(firstMonthDayTime, startMonthDayTime);
  132. //todo 周期性费用 日应收重新算
  133. if (!FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
  134. // todo 计算当月天数
  135. Calendar calendar = Calendar.getInstance();
  136. calendar.setTime(startMonthDayTime);
  137. curMonthMaxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
  138. dayReceivableAmount = receivableAmount.divide(new BigDecimal(curMonthMaxDay), 4, BigDecimal.ROUND_HALF_UP);// 日 实收
  139. }
  140. // todo 计算 应收
  141. curMonthReceivableAmount = new BigDecimal(curDay).multiply(dayReceivableAmount).setScale(4, BigDecimal.ROUND_HALF_UP);
  142. // todo 保存数据到pay_fee_detail_month
  143. toSavePayFeeDetailMonth(curMonthReceivableAmount.doubleValue(), 0, null, feeDto, payFeeMonthOwnerDto, payFeeDetailMonthPos, startMonthDayTime,deadlineTime);
  144. // todo 将startTime 修改为 下月1日时间
  145. startMonthDayTime = firstMonthDayTime;
  146. firstMonthDayCal.add(Calendar.MONTH, 1);
  147. firstMonthDayTime = firstMonthDayCal.getTime();
  148. }
  149. //todo 最后处理 最后 startMonthDayTime 到endTime 的
  150. if (startMonthDayTime.getTime() >= endTime.getTime()) {
  151. payFeeDetailMonthInnerServiceSMOImpl.savePayFeeDetailMonths(payFeeDetailMonthPos);
  152. return;
  153. }
  154. curDay = DateUtil.daysBetween(endTime, startMonthDayTime);
  155. //todo 周期性费用 日应收重新算
  156. if (!FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
  157. // todo 计算当月天数
  158. Calendar calendar = Calendar.getInstance();
  159. calendar.setTime(startMonthDayTime);
  160. curMonthMaxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
  161. dayReceivableAmount = receivableAmount.divide(new BigDecimal(curMonthMaxDay), 4, BigDecimal.ROUND_HALF_UP);// 日 实收
  162. }
  163. // todo 计算 应收
  164. curMonthReceivableAmount = new BigDecimal(curDay).multiply(dayReceivableAmount).setScale(4, BigDecimal.ROUND_HALF_UP);
  165. // todo 保存数据到pay_fee_detail_month
  166. toSavePayFeeDetailMonth(curMonthReceivableAmount.doubleValue(), 0, null, feeDto, payFeeMonthOwnerDto, payFeeDetailMonthPos, startMonthDayTime,deadlineTime);
  167. payFeeDetailMonthInnerServiceSMOImpl.savePayFeeDetailMonths(payFeeDetailMonthPos);
  168. }
  169. private void doDispersedFeeDetail(FeeDetailDto feeDetailDto, FeeDto feeDto, PayFeeMonthOwnerDto payFeeMonthOwnerDto) {
  170. List<PayFeeDetailMonthPo> payFeeDetailMonthPos = new ArrayList<>();
  171. // todo 去除 开始时间和 结束时间的 小时 分钟 秒
  172. Date startTime = DateUtil.timeToDate(feeDetailDto.getStartTime());
  173. Date endTime = DateUtil.timeToDate(feeDetailDto.getEndTime());
  174. int day = DateUtil.daysBetween(endTime, startTime);
  175. if (day < 1) {
  176. day = 1;
  177. }
  178. BigDecimal receivableAmount = new BigDecimal(Double.parseDouble(feeDetailDto.getReceivableAmount()));
  179. BigDecimal receivedAmount = new BigDecimal(Double.parseDouble(feeDetailDto.getReceivedAmount()));
  180. BigDecimal dayReceivableAmount = receivableAmount.divide(new BigDecimal(day), 4, BigDecimal.ROUND_HALF_UP);// 日 应收
  181. BigDecimal dayReceivedAmount = receivedAmount.divide(new BigDecimal(day), 4, BigDecimal.ROUND_HALF_UP);// 日 实收
  182. // todo 寻找第一个自然月 一日
  183. Calendar firstMonthDayCal = Calendar.getInstance();
  184. firstMonthDayCal.setTime(startTime);
  185. firstMonthDayCal.add(Calendar.MONTH, 1);
  186. firstMonthDayCal.set(Calendar.DAY_OF_MONTH, 1);
  187. Date firstMonthDayTime = firstMonthDayCal.getTime();
  188. Date startMonthDayTime = startTime;
  189. // todo 循环,只到 firstMonthDayTime 大于 endTime
  190. int curDay = 0;
  191. BigDecimal curMonthReceivableAmount = null;
  192. BigDecimal curMonthReceivedAmount = null;
  193. while (firstMonthDayTime.getTime() < endTime.getTime()) {
  194. curDay = DateUtil.daysBetween(firstMonthDayTime, startMonthDayTime);
  195. // todo 计算 应收
  196. curMonthReceivableAmount = new BigDecimal(curDay).multiply(dayReceivableAmount).setScale(4, BigDecimal.ROUND_HALF_UP);
  197. // todo 计算 实收
  198. curMonthReceivedAmount = new BigDecimal(curDay).multiply(dayReceivedAmount).setScale(4, BigDecimal.ROUND_HALF_UP);
  199. // todo 保存数据到pay_fee_detail_month
  200. toSavePayFeeDetailMonth(curMonthReceivableAmount.doubleValue(), curMonthReceivedAmount.doubleValue(), feeDetailDto, feeDto, payFeeMonthOwnerDto, payFeeDetailMonthPos, startMonthDayTime,endTime);
  201. // todo 将startTime 修改为 下月1日时间
  202. startMonthDayTime = firstMonthDayTime;
  203. firstMonthDayCal.add(Calendar.MONTH, 1);
  204. firstMonthDayTime = firstMonthDayCal.getTime();
  205. }
  206. //todo 最后处理 最后 startMonthDayTime 到endTime 的
  207. if (startMonthDayTime.getTime() >= endTime.getTime()) {
  208. payFeeDetailMonthInnerServiceSMOImpl.savePayFeeDetailMonths(payFeeDetailMonthPos);
  209. return;
  210. }
  211. curDay = DateUtil.daysBetween(endTime, startMonthDayTime);
  212. // todo 计算 应收
  213. curMonthReceivableAmount = new BigDecimal(curDay).multiply(dayReceivableAmount).setScale(4, BigDecimal.ROUND_HALF_UP);
  214. // todo 计算 实收
  215. curMonthReceivedAmount = new BigDecimal(curDay).multiply(dayReceivedAmount).setScale(4, BigDecimal.ROUND_HALF_UP);
  216. // todo 保存数据到pay_fee_detail_month
  217. toSavePayFeeDetailMonth(curMonthReceivableAmount.doubleValue(), curMonthReceivedAmount.doubleValue(), feeDetailDto, feeDto, payFeeMonthOwnerDto, payFeeDetailMonthPos, startMonthDayTime,endTime);
  218. payFeeDetailMonthInnerServiceSMOImpl.savePayFeeDetailMonths(payFeeDetailMonthPos);
  219. }
  220. /**
  221. * 保存数据
  222. *
  223. * @param receivableAmount
  224. * @param receivedAmount
  225. * @param feeDetailDto
  226. * @param feeDto
  227. */
  228. private void toSavePayFeeDetailMonth(double receivableAmount,
  229. double receivedAmount,
  230. FeeDetailDto feeDetailDto,
  231. FeeDto feeDto,
  232. PayFeeMonthOwnerDto payFeeMonthOwnerDto,
  233. List<PayFeeDetailMonthPo> payFeeDetailMonthPos,
  234. Date curTime,
  235. Date deadlineTime) {
  236. Calendar calendar = Calendar.getInstance();
  237. calendar.setTime(curTime);
  238. PayFeeDetailMonthPo tmpPayFeeDetailMonthPo = new PayFeeDetailMonthPo();
  239. tmpPayFeeDetailMonthPo.setFeeId(feeDto.getFeeId());
  240. tmpPayFeeDetailMonthPo.setCommunityId(feeDto.getCommunityId());
  241. if (feeDetailDto == null) {
  242. tmpPayFeeDetailMonthPo.setDetailId("-1");
  243. } else { // todo 交费记录 保存时
  244. tmpPayFeeDetailMonthPo.setDetailId(feeDetailDto.getDetailId());
  245. }
  246. tmpPayFeeDetailMonthPo.setDetailYear(calendar.get(Calendar.YEAR) + "");
  247. tmpPayFeeDetailMonthPo.setDetailMonth((calendar.get(Calendar.MONTH) + 1) + "");
  248. tmpPayFeeDetailMonthPo.setReceivableAmount(receivableAmount + "");
  249. tmpPayFeeDetailMonthPo.setReceivedAmount(receivedAmount + "");
  250. tmpPayFeeDetailMonthPo.setDiscountAmount(
  251. getDiscountAmount(Double.parseDouble(tmpPayFeeDetailMonthPo.getReceivableAmount()),
  252. Double.parseDouble(tmpPayFeeDetailMonthPo.getReceivedAmount()),
  253. calendar.getTime(), feeDto) + "");
  254. tmpPayFeeDetailMonthPo.setMonthId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_monthId,true));
  255. tmpPayFeeDetailMonthPo.setRemark("程序计算生成");
  256. tmpPayFeeDetailMonthPo.setObjName(payFeeMonthOwnerDto.getObjName());
  257. tmpPayFeeDetailMonthPo.setObjId(payFeeMonthOwnerDto.getObjId());
  258. tmpPayFeeDetailMonthPo.setOwnerId(payFeeMonthOwnerDto.getOwnerId());
  259. tmpPayFeeDetailMonthPo.setOwnerName(payFeeMonthOwnerDto.getOwnerName());
  260. tmpPayFeeDetailMonthPo.setLink(payFeeMonthOwnerDto.getLink());
  261. tmpPayFeeDetailMonthPo.setCurMonthTime(DateUtil.getFormatTimeStringB(calendar.getTime()));
  262. tmpPayFeeDetailMonthPo.setDeadlineTime(DateUtil.getFormatTimeStringA(deadlineTime));
  263. if (feeDetailDto == null) {
  264. tmpPayFeeDetailMonthPo.setPayFeeTime(null);
  265. } else { // todo 交费记录 保存时
  266. tmpPayFeeDetailMonthPo.setPayFeeTime(DateUtil.getFormatTimeStringA(feeDetailDto.getCreateTime()));
  267. }
  268. tmpPayFeeDetailMonthPo.setState("W"); // todo 这里暂时写死,目前用不到,算是预留字段
  269. tmpPayFeeDetailMonthPo.setFeeName(feeDto.getFeeName());
  270. tmpPayFeeDetailMonthPo.setConfigId(feeDto.getConfigId());
  271. payFeeDetailMonthPos.add(tmpPayFeeDetailMonthPo);
  272. }
  273. }