QueryOweFeeImpl.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. package com.java110.fee.bmo.impl;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.java110.core.factory.Java110ThreadPoolFactory;
  4. import com.java110.core.smo.IComputeFeeSMO;
  5. import com.java110.dto.RoomDto;
  6. import com.java110.dto.fee.FeeConfigDto;
  7. import com.java110.dto.fee.FeeDto;
  8. import com.java110.dto.owner.OwnerCarDto;
  9. import com.java110.dto.owner.OwnerDto;
  10. import com.java110.dto.parking.ParkingSpaceDto;
  11. import com.java110.fee.bmo.IQueryOweFee;
  12. import com.java110.intf.community.IParkingSpaceInnerServiceSMO;
  13. import com.java110.intf.community.IRoomInnerServiceSMO;
  14. import com.java110.intf.fee.IFeeConfigInnerServiceSMO;
  15. import com.java110.intf.fee.IFeeInnerServiceSMO;
  16. import com.java110.intf.user.IOwnerCarInnerServiceSMO;
  17. import com.java110.intf.user.IOwnerInnerServiceSMO;
  18. import com.java110.utils.cache.MappingCache;
  19. import com.java110.utils.constant.ResponseConstant;
  20. import com.java110.utils.exception.ListenerExecuteException;
  21. import com.java110.utils.util.Assert;
  22. import com.java110.utils.util.DateUtil;
  23. import com.java110.utils.util.StringUtil;
  24. import com.java110.vo.ResultVo;
  25. import org.slf4j.Logger;
  26. import org.slf4j.LoggerFactory;
  27. import org.springframework.beans.factory.annotation.Autowired;
  28. import org.springframework.http.ResponseEntity;
  29. import org.springframework.stereotype.Service;
  30. import java.math.BigDecimal;
  31. import java.math.RoundingMode;
  32. import java.util.ArrayList;
  33. import java.util.Calendar;
  34. import java.util.Date;
  35. import java.util.HashMap;
  36. import java.util.List;
  37. import java.util.Map;
  38. @Service
  39. public class QueryOweFeeImpl implements IQueryOweFee {
  40. private final static Logger logger = LoggerFactory.getLogger(QueryOweFeeImpl.class);
  41. @Autowired
  42. private IFeeInnerServiceSMO feeInnerServiceSMOImpl;
  43. @Autowired
  44. private IOwnerCarInnerServiceSMO ownerCarInnerServiceSMOImpl;
  45. @Autowired
  46. private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl;
  47. @Autowired
  48. private IParkingSpaceInnerServiceSMO parkingSpaceInnerServiceSMOImpl;
  49. @Autowired
  50. private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
  51. @Autowired
  52. private IOwnerInnerServiceSMO ownerInnerServiceSMOImpl;
  53. @Autowired
  54. private IComputeFeeSMO computeFeeSMOImpl;
  55. //域
  56. public static final String DOMAIN_COMMON = "DOMAIN.COMMON";
  57. //键
  58. public static final String TOTAL_FEE_PRICE = "TOTAL_FEE_PRICE";
  59. //键
  60. public static final String RECEIVED_AMOUNT_SWITCH = "RECEIVED_AMOUNT_SWITCH";
  61. @Override
  62. public ResponseEntity<String> query(FeeDto feeDto) {
  63. //查询费用信息arrearsEndTime
  64. feeDto.setArrearsEndTime(DateUtil.getCurrentDate());
  65. feeDto.setState(FeeDto.STATE_DOING);
  66. List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
  67. if (feeDtos == null || feeDtos.size() < 1) {
  68. feeDtos = new ArrayList<>();
  69. return ResultVo.createResponseEntity(feeDtos);
  70. }
  71. List<FeeDto> tmpFeeDtos = new ArrayList<>();
  72. for (FeeDto tmpFeeDto : feeDtos) {
  73. computeFeeSMOImpl.computeEveryOweFee(tmpFeeDto);//计算欠费金额
  74. //如果金额为0 就排除
  75. if (tmpFeeDto.getFeePrice() > 0 && tmpFeeDto.getEndTime().getTime() <= DateUtil.getCurrentDate().getTime()) {
  76. tmpFeeDtos.add(tmpFeeDto);
  77. }
  78. }
  79. return ResultVo.createResponseEntity(tmpFeeDtos);
  80. }
  81. @Override
  82. public ResponseEntity<String> queryAllOwneFee(FeeDto feeDto) {
  83. ResponseEntity<String> responseEntity = null;
  84. if (!freshFeeDtoParam(feeDto)) {
  85. return ResultVo.createResponseEntity(1, 0, new JSONArray());
  86. }
  87. if (FeeConfigDto.BILL_TYPE_EVERY.equals(feeDto.getBillType())) {
  88. responseEntity = computeEveryOweFee(feeDto);
  89. } else {
  90. responseEntity = computeBillOweFee(feeDto);
  91. }
  92. return responseEntity;
  93. }
  94. @Override
  95. public ResponseEntity<String> listFeeObj(FeeDto feeDto) {
  96. List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
  97. if (feeDtos == null || feeDtos.size() < 1) {
  98. return ResultVo.success();
  99. }
  100. feeDto = feeDtos.get(0);
  101. if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) { //房屋相关
  102. RoomDto roomDto = new RoomDto();
  103. roomDto.setRoomId(feeDto.getPayerObjId());
  104. roomDto.setCommunityId(feeDto.getCommunityId());
  105. List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
  106. if (roomDtos == null || roomDtos.size() != 1) {
  107. throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "未查到房屋信息,查询多条数据");
  108. }
  109. roomDto = roomDtos.get(0);
  110. feeDto.setPayerObjName(roomDto.getFloorNum() + "栋" + roomDto.getUnitNum() + "单元" + roomDto.getRoomNum() + "室");
  111. feeDto.setBuiltUpArea(roomDto.getBuiltUpArea());
  112. } else if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {//车位相关
  113. OwnerCarDto ownerCarDto = new OwnerCarDto();
  114. ownerCarDto.setCommunityId(feeDto.getCommunityId());
  115. ownerCarDto.setCarId(feeDto.getPayerObjId());
  116. List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
  117. Assert.listOnlyOne(ownerCarDtos, "未找到车辆信息");
  118. ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
  119. parkingSpaceDto.setCommunityId(feeDto.getCommunityId());
  120. parkingSpaceDto.setPsId(ownerCarDtos.get(0).getPsId());
  121. List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
  122. if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) { //数据有问题
  123. throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "未查到停车位信息,查询多条数据");
  124. }
  125. ownerCarDto = ownerCarDtos.get(0);
  126. parkingSpaceDto = parkingSpaceDtos.get(0);
  127. feeDto.setPayerObjName(ownerCarDto.getCarNum() + "(" + parkingSpaceDto.getAreaNum() + "停车场" + parkingSpaceDto.getNum() + "车位)");
  128. feeDto.setBuiltUpArea(parkingSpaceDto.getArea());
  129. }
  130. double feePrice = computeFeeSMOImpl.getFeePrice(feeDto);
  131. feeDto.setFeePrice(feePrice);
  132. //应收款取值
  133. String val = MappingCache.getValue(DOMAIN_COMMON, TOTAL_FEE_PRICE);
  134. feeDto.setVal(val);
  135. String received_amount_switch = MappingCache.getValue(DOMAIN_COMMON, RECEIVED_AMOUNT_SWITCH);
  136. if (StringUtil.isEmpty(received_amount_switch)) {
  137. feeDto.setReceivedAmountSwitch("1");//默认启用实收款输入框
  138. } else {
  139. feeDto.setReceivedAmountSwitch(received_amount_switch);
  140. }
  141. return ResultVo.createResponseEntity(feeDto);
  142. }
  143. @Override
  144. public ResponseEntity<String> querys(FeeDto feeDto) {
  145. RoomDto roomDto = new RoomDto();
  146. roomDto.setCommunityId(feeDto.getCommunityId());
  147. roomDto.setRoomId(feeDto.getPayerObjId());
  148. List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
  149. if (roomDtos == null || roomDtos.size() < 1) {
  150. return ResultVo.createResponseEntity(ResultVo.CODE_OK, "成功", new JSONArray());
  151. }
  152. //查询费用信息arrearsEndTime
  153. List<RoomDto> tmpRoomDtos = new ArrayList<>();
  154. List<RoomDto> tempRooms = new ArrayList<>();
  155. int threadNum = 20;
  156. for (int roomIndex = 0; roomIndex < roomDtos.size(); roomIndex++) {
  157. tempRooms.add(roomDtos.get(roomIndex));
  158. if (roomIndex % threadNum == 0 && roomIndex != 0) {
  159. tmpRoomDtos.addAll(doGetTmpRoomDto(tempRooms, feeDto, threadNum));
  160. tempRooms = new ArrayList();
  161. }
  162. }
  163. if (tempRooms.size() > 0) {
  164. tmpRoomDtos.addAll(doGetTmpRoomDto(tempRooms, feeDto, tempRooms.size()));
  165. }
  166. return ResultVo.createResponseEntity(tmpRoomDtos);
  167. }
  168. private List<RoomDto> doGetTmpRoomDto(List<RoomDto> roomDtos, FeeDto feeDto, int threadNum) {
  169. Java110ThreadPoolFactory java110ThreadPoolFactory = null;
  170. try {
  171. java110ThreadPoolFactory = Java110ThreadPoolFactory.getInstance().createThreadPool(threadNum);
  172. for (RoomDto roomDto1 : roomDtos) {
  173. java110ThreadPoolFactory.submit(() -> {
  174. return getTmpRoomDtos(roomDto1, feeDto);
  175. });
  176. }
  177. return java110ThreadPoolFactory.get();
  178. }finally {
  179. if(java110ThreadPoolFactory != null){
  180. java110ThreadPoolFactory.stop();
  181. }
  182. }
  183. }
  184. private RoomDto getTmpRoomDtos(RoomDto tmpRoomDto, FeeDto feeDto) {
  185. FeeDto tmpFeeDto = null;
  186. tmpFeeDto = new FeeDto();
  187. tmpFeeDto.setArrearsEndTime(DateUtil.getCurrentDate());
  188. tmpFeeDto.setState(FeeDto.STATE_DOING);
  189. tmpFeeDto.setPayerObjId(tmpRoomDto.getRoomId());
  190. tmpFeeDto.setPayerObjType(FeeDto.PAYER_OBJ_TYPE_ROOM);
  191. List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
  192. if (feeDtos == null || feeDtos.size() < 1) {
  193. return null;
  194. }
  195. List<FeeDto> tmpFeeDtos = new ArrayList<>();
  196. for (FeeDto tempFeeDto : feeDtos) {
  197. computeFeeSMOImpl.computeEveryOweFee(tempFeeDto, tmpRoomDto);//计算欠费金额
  198. //如果金额为0 就排除
  199. if (tempFeeDto.getFeePrice() > 0 && tempFeeDto.getEndTime().getTime() <= DateUtil.getCurrentDate().getTime()) {
  200. tmpFeeDtos.add(tempFeeDto);
  201. }
  202. }
  203. if (tmpFeeDtos.size() < 1) {
  204. return null;
  205. }
  206. tmpRoomDto.setFees(tmpFeeDtos);
  207. return tmpRoomDto;
  208. }
  209. private boolean freshFeeDtoParam(FeeDto feeDto) {
  210. if (StringUtil.isEmpty(feeDto.getPayerObjId())) {
  211. return true;
  212. }
  213. if (!feeDto.getPayerObjId().contains("-")) {
  214. return false;
  215. }
  216. if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) {
  217. String[] nums = feeDto.getPayerObjId().split("-");
  218. if (nums.length != 3) {
  219. return false;
  220. }
  221. RoomDto roomDto = new RoomDto();
  222. roomDto.setFloorNum(nums[0]);
  223. roomDto.setUnitNum(nums[1]);
  224. roomDto.setRoomNum(nums[2]);
  225. roomDto.setCommunityId(feeDto.getCommunityId());
  226. List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
  227. if (roomDtos == null || roomDtos.size() < 1) {
  228. return false;
  229. }
  230. feeDto.setPayerObjId(roomDtos.get(0).getRoomId());
  231. } else {
  232. String[] nums = feeDto.getPayerObjId().split("-");
  233. if (nums.length != 2) {
  234. return false;
  235. }
  236. ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
  237. parkingSpaceDto.setAreaNum(nums[0]);
  238. parkingSpaceDto.setNum(nums[1]);
  239. parkingSpaceDto.setCommunityId(feeDto.getCommunityId());
  240. List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
  241. if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) {
  242. return false;
  243. }
  244. feeDto.setPayerObjId(parkingSpaceDtos.get(0).getPsId());
  245. }
  246. return true;
  247. }
  248. /**
  249. * 账单费用
  250. *
  251. * @param feeDto
  252. * @return
  253. */
  254. private ResponseEntity<String> computeBillOweFee(FeeDto feeDto) {
  255. int count = feeInnerServiceSMOImpl.computeBillOweFeeCount(feeDto);
  256. List<FeeDto> feeDtos = null;
  257. if (count > 0) {
  258. feeDtos = feeInnerServiceSMOImpl.computeBillOweFee(feeDto);
  259. } else {
  260. feeDtos = new ArrayList<>();
  261. }
  262. return ResultVo.createResponseEntity((int) Math.ceil((double) count / (double) feeDto.getRow()), count, feeDtos);
  263. }
  264. /**
  265. * 实时费用
  266. *
  267. * @param feeDto
  268. * @return
  269. */
  270. private ResponseEntity<String> computeEveryOweFee(FeeDto feeDto) {
  271. int count = feeInnerServiceSMOImpl.computeEveryOweFeeCount(feeDto);
  272. List<FeeDto> feeDtos = null;
  273. if (count > 0) {
  274. feeDtos = feeInnerServiceSMOImpl.computeEveryOweFee(feeDto);
  275. computeFeePrices(feeDtos);
  276. } else {
  277. feeDtos = new ArrayList<>();
  278. }
  279. return ResultVo.createResponseEntity((int) Math.ceil((double) count / (double) feeDto.getRow()), count, feeDtos);
  280. }
  281. private void computeFeePrices(List<FeeDto> feeDtos) {
  282. List<FeeDto> roomFees = new ArrayList<>();
  283. List<FeeDto> psFees = new ArrayList<>();
  284. List<String> roomIds = new ArrayList<>();
  285. List<String> psIds = new ArrayList<>();
  286. for (FeeDto fee : feeDtos) {
  287. // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间
  288. if ("3333".equals(fee.getPayerObjType())) { //房屋相关
  289. roomFees.add(fee);
  290. roomIds.add(fee.getPayerObjId());
  291. } else if ("6666".equals(fee.getPayerObjType())) {//车位相关
  292. psFees.add(fee);
  293. psIds.add(fee.getPayerObjId());
  294. }
  295. }
  296. if (roomFees.size() > 0) {
  297. computeRoomFee(roomFees, roomIds);
  298. }
  299. if (psFees.size() > 0) {
  300. computePsFee(psFees, psIds);
  301. }
  302. }
  303. /**
  304. * 计算停车费
  305. *
  306. * @param psFees
  307. */
  308. private void computePsFee(List<FeeDto> psFees, List<String> psIds) {
  309. ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
  310. parkingSpaceDto.setCommunityId(psFees.get(0).getCommunityId());
  311. parkingSpaceDto.setPsIds(psIds.toArray(new String[psIds.size()]));
  312. List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
  313. if (parkingSpaceDtos == null || parkingSpaceDtos.size() < 1) { //数据有问题
  314. return;
  315. }
  316. for (ParkingSpaceDto tmpParkingSpaceDto : parkingSpaceDtos) {
  317. for (FeeDto feeDto : psFees) {
  318. dealFeePs(tmpParkingSpaceDto, feeDto);
  319. }
  320. }
  321. OwnerDto ownerDto = new OwnerDto();
  322. ownerDto.setOwnerIds(psIds.toArray(new String[psIds.size()]));
  323. ownerDto.setCommunityId(psFees.get(0).getCommunityId());
  324. List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwnersByParkingSpace(ownerDto);
  325. for (OwnerDto tmpOwnerDto : ownerDtos) {
  326. for (FeeDto feeDto : psFees) {
  327. dealFeeOwner(tmpOwnerDto, feeDto);
  328. }
  329. }
  330. }
  331. private void dealFeePs(ParkingSpaceDto tmpParkingSpaceDto, FeeDto feeDto) {
  332. // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间
  333. Map<String, Object> targetEndDateAndOweMonth = getTargetEndDateAndOweMonth(feeDto);
  334. Date targetEndDate = (Date) targetEndDateAndOweMonth.get("targetEndDate");
  335. double oweMonth = (double) targetEndDateAndOweMonth.get("oweMonth");
  336. if (!tmpParkingSpaceDto.getPsId().equals(feeDto.getPayerObjId())) {
  337. return;
  338. }
  339. feeDto.setRoomName(tmpParkingSpaceDto.getAreaNum() + "停车场" + tmpParkingSpaceDto.getNum() + "车位");
  340. String computingFormula = feeDto.getComputingFormula();
  341. double feePrice = 0.00;
  342. if ("1001".equals(computingFormula)) { //面积*单价+附加费
  343. BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
  344. BigDecimal builtUpArea = new BigDecimal(Double.parseDouble(tmpParkingSpaceDto.getArea()));
  345. BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
  346. feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  347. } else if ("2002".equals(computingFormula)) { // 固定费用
  348. BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
  349. feePrice = additionalAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  350. } else if ("4004".equals(computingFormula)) {
  351. feePrice = Double.parseDouble(feeDto.getAmount());
  352. } else if ("5005".equals(computingFormula)) {
  353. if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
  354. feePrice = -1.00;
  355. } else {
  356. BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
  357. BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
  358. BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
  359. BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
  360. BigDecimal sub = curDegree.subtract(preDegree);
  361. feePrice = sub.multiply(squarePrice)
  362. .add(additionalAmount)
  363. .setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  364. }
  365. } else {
  366. feePrice = 0.00;
  367. }
  368. feeDto.setFeePrice(feePrice);
  369. // double month = dayCompare(feeDto.getEndTime(), DateUtil.getCurrentDate());
  370. BigDecimal price = new BigDecimal(feeDto.getFeePrice());
  371. price = price.multiply(new BigDecimal(oweMonth));
  372. feeDto.setAmountOwed(price.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue() + "");
  373. feeDto.setDeadlineTime(targetEndDate);
  374. //动态费用
  375. if ("4004".equals(computingFormula)) {
  376. feeDto.setAmountOwed(feeDto.getFeePrice() + "");
  377. feeDto.setDeadlineTime(DateUtil.getCurrentDate());
  378. }
  379. }
  380. /**
  381. * 计算房屋费
  382. *
  383. * @param roomFees
  384. */
  385. private void computeRoomFee(List<FeeDto> roomFees, List<String> roomIds) {
  386. RoomDto roomDto = new RoomDto();
  387. roomDto.setCommunityId(roomFees.get(0).getCommunityId());
  388. roomDto.setRoomIds(roomIds.toArray(new String[roomIds.size()]));
  389. List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
  390. if (roomDtos == null || roomDtos.size() < 1) { //数据有问题
  391. return;
  392. }
  393. for (RoomDto tmpRoomDto : roomDtos) {
  394. for (FeeDto feeDto : roomFees) {
  395. dealFeeRoom(tmpRoomDto, feeDto);
  396. }
  397. }
  398. OwnerDto ownerDto = new OwnerDto();
  399. ownerDto.setRoomIds(roomIds.toArray(new String[roomIds.size()]));
  400. ownerDto.setCommunityId(roomFees.get(0).getCommunityId());
  401. List<OwnerDto> ownerDtos = ownerInnerServiceSMOImpl.queryOwners(ownerDto);
  402. for (OwnerDto tmpOwnerDto : ownerDtos) {
  403. for (FeeDto feeDto : roomFees) {
  404. dealFeeOwner(tmpOwnerDto, feeDto);
  405. }
  406. }
  407. }
  408. private void dealFeeOwner(OwnerDto tmpOwnerDto, FeeDto feeDto) {
  409. if (!tmpOwnerDto.getRoomId().equals(feeDto.getPayerObjId())) {
  410. return;
  411. }
  412. feeDto.setOwnerName(tmpOwnerDto.getName());
  413. feeDto.setOwnerTel(tmpOwnerDto.getLink());
  414. }
  415. private void dealFeeRoom(RoomDto tmpRoomDto, FeeDto feeDto) {
  416. Map<String, Object> targetEndDateAndOweMonth = getTargetEndDateAndOweMonth(feeDto);
  417. Date targetEndDate = (Date) targetEndDateAndOweMonth.get("targetEndDate");
  418. double oweMonth = (double) targetEndDateAndOweMonth.get("oweMonth");
  419. if (!tmpRoomDto.getRoomId().equals(feeDto.getPayerObjId())) {
  420. return;
  421. }
  422. feeDto.setRoomName(tmpRoomDto.getFloorNum() + "栋" + tmpRoomDto.getUnitNum() + "单元" + tmpRoomDto.getRoomNum() + "室");
  423. String computingFormula = feeDto.getComputingFormula();
  424. double feePrice = 0.00;
  425. if ("1001".equals(computingFormula)) { //面积*单价+附加费
  426. BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
  427. BigDecimal builtUpArea = new BigDecimal(Double.parseDouble(tmpRoomDto.getBuiltUpArea()));
  428. BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
  429. feePrice = squarePrice.multiply(builtUpArea).add(additionalAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  430. } else if ("2002".equals(computingFormula)) { // 固定费用
  431. BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
  432. feePrice = additionalAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  433. } else if ("4004".equals(computingFormula)) {
  434. feePrice = Double.parseDouble(feeDto.getAmount());
  435. } else if ("5005".equals(computingFormula)) {
  436. if (StringUtil.isEmpty(feeDto.getCurDegrees())) {
  437. feePrice = -1.00;
  438. } else {
  439. BigDecimal curDegree = new BigDecimal(Double.parseDouble(feeDto.getCurDegrees()));
  440. BigDecimal preDegree = new BigDecimal(Double.parseDouble(feeDto.getPreDegrees()));
  441. BigDecimal squarePrice = new BigDecimal(Double.parseDouble(feeDto.getSquarePrice()));
  442. BigDecimal additionalAmount = new BigDecimal(Double.parseDouble(feeDto.getAdditionalAmount()));
  443. BigDecimal sub = curDegree.subtract(preDegree);
  444. feePrice = sub.multiply(squarePrice)
  445. .add(additionalAmount)
  446. .setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  447. }
  448. } else {
  449. feePrice = 0.00;
  450. }
  451. feeDto.setFeePrice(feePrice);
  452. //double month = dayCompare(feeDto.getEndTime(), DateUtil.getCurrentDate());
  453. BigDecimal price = new BigDecimal(feeDto.getFeePrice());
  454. price = price.multiply(new BigDecimal(oweMonth));
  455. feeDto.setAmountOwed(price.setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue() + "");
  456. feeDto.setDeadlineTime(targetEndDate);
  457. //动态费用
  458. if ("4004".equals(computingFormula)) {
  459. feeDto.setAmountOwed(feeDto.getFeePrice() + "");
  460. feeDto.setDeadlineTime(DateUtil.getCurrentDate());
  461. }
  462. }
  463. /**
  464. * 计算2个日期之间相差的 以年、月、日为单位,各自计算结果是多少
  465. * 比如:2011-02-02 到 2017-03-02
  466. * 以年为单位相差为:6年
  467. * 以月为单位相差为:73个月
  468. * 以日为单位相差为:2220天
  469. *
  470. * @param fromDate
  471. * @param toDate
  472. * @return
  473. */
  474. public static double dayCompare(Date fromDate, Date toDate) {
  475. Calendar from = Calendar.getInstance();
  476. from.setTime(fromDate);
  477. Calendar to = Calendar.getInstance();
  478. to.setTime(toDate);
  479. long t1 = from.getTimeInMillis();
  480. long t2 = to.getTimeInMillis();
  481. double days = (t2 - t1) * 1.00 / (24 * 60 * 60 * 1000);
  482. BigDecimal tmpDays = new BigDecimal(days);
  483. BigDecimal monthDay = new BigDecimal(30);
  484. return tmpDays.divide(monthDay, 2, RoundingMode.HALF_UP).doubleValue();
  485. }
  486. private Map getTargetEndDateAndOweMonth(FeeDto feeDto) {
  487. Date targetEndDate = null;
  488. double oweMonth = 0.0;
  489. Map<String, Object> targetEndDateAndOweMonth = new HashMap<>();
  490. if (FeeDto.STATE_FINISH.equals(feeDto.getState())) {
  491. targetEndDate = feeDto.getEndTime();
  492. targetEndDateAndOweMonth.put("oweMonth", oweMonth);
  493. targetEndDateAndOweMonth.put("targetEndDate", targetEndDate);
  494. return targetEndDateAndOweMonth;
  495. }
  496. if (FeeDto.FEE_FLAG_ONCE.equals(feeDto.getFeeFlag())) {
  497. if (!StringUtil.isEmpty(feeDto.getCurDegrees())) {
  498. targetEndDate = feeDto.getCurReadingTime();
  499. } else if (feeDto.getImportFeeEndTime() == null) {
  500. targetEndDate = feeDto.getConfigEndTime();
  501. } else {
  502. targetEndDate = feeDto.getImportFeeEndTime();
  503. }
  504. //判断当前费用是不是导入费用
  505. oweMonth = 1.0;
  506. } else {
  507. //当前时间
  508. Date billEndTime = DateUtil.getCurrentDate();
  509. //开始时间
  510. Date startDate = feeDto.getStartTime();
  511. //到期时间
  512. Date endDate = feeDto.getEndTime();
  513. if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDto.getPayerObjType())) {
  514. OwnerCarDto ownerCarDto = new OwnerCarDto();
  515. ownerCarDto.setCommunityId(feeDto.getCommunityId());
  516. ownerCarDto.setCarId(feeDto.getPayerObjId());
  517. List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
  518. if (ownerCarDtos == null || ownerCarDtos.size() != 1) {
  519. targetEndDateAndOweMonth.put("oweMonth", 0);
  520. targetEndDateAndOweMonth.put("targetEndDate", "");
  521. return targetEndDateAndOweMonth;
  522. }
  523. targetEndDate = ownerCarDtos.get(0).getEndTime();
  524. //说明没有欠费
  525. if (endDate.getTime() >= targetEndDate.getTime()) {
  526. // 目标到期时间 - 到期时间 = 欠费月份
  527. oweMonth = 0;
  528. targetEndDateAndOweMonth.put("oweMonth", oweMonth);
  529. targetEndDateAndOweMonth.put("targetEndDate", targetEndDate);
  530. return targetEndDateAndOweMonth;
  531. }
  532. }
  533. //缴费周期
  534. long paymentCycle = Long.parseLong(feeDto.getPaymentCycle());
  535. // 当前时间 - 开始时间 = 月份
  536. double mulMonth = 0.0;
  537. mulMonth = dayCompare(startDate, billEndTime);
  538. // 月份/ 周期 = 轮数(向上取整)
  539. double round = 0.0;
  540. if ("1200".equals(feeDto.getPaymentCd())) { // 预付费
  541. round = Math.floor(mulMonth / paymentCycle) + 1;
  542. } else { //后付费
  543. round = Math.floor(mulMonth / paymentCycle);
  544. }
  545. // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间
  546. targetEndDate = getTargetEndTime(round * paymentCycle, startDate);
  547. //费用 快结束了
  548. if (feeDto.getConfigEndTime().getTime() < targetEndDate.getTime()) {
  549. targetEndDate = feeDto.getConfigEndTime();
  550. }
  551. //说明没有欠费
  552. if (endDate.getTime() < targetEndDate.getTime()) {
  553. // 目标到期时间 - 到期时间 = 欠费月份
  554. oweMonth = dayCompare(endDate, targetEndDate);
  555. }
  556. if (feeDto.getEndTime().getTime() > targetEndDate.getTime()) {
  557. targetEndDate = feeDto.getEndTime();
  558. }
  559. }
  560. targetEndDateAndOweMonth.put("oweMonth", oweMonth);
  561. targetEndDateAndOweMonth.put("targetEndDate", targetEndDate);
  562. return targetEndDateAndOweMonth;
  563. }
  564. private Date getTargetEndTime(double v, Date startDate) {
  565. Calendar endDate = Calendar.getInstance();
  566. endDate.setTime(startDate);
  567. endDate.add(Calendar.MONTH, (int) v);
  568. return endDate.getTime();
  569. }
  570. }