GenerateBillProTemplate.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. package com.java110.job.task.fee;
  2. import com.java110.core.factory.GenerateCodeFactory;
  3. import com.java110.core.smo.IComputeFeeSMO;
  4. import com.java110.dto.RoomDto;
  5. import com.java110.dto.community.CommunityDto;
  6. import com.java110.dto.fee.*;
  7. import com.java110.dto.logSystemError.LogSystemErrorDto;
  8. import com.java110.dto.owner.OwnerCarDto;
  9. import com.java110.dto.owner.OwnerRoomRelDto;
  10. import com.java110.dto.task.TaskDto;
  11. import com.java110.intf.community.IParkingSpaceInnerServiceSMO;
  12. import com.java110.intf.community.IRoomInnerServiceSMO;
  13. import com.java110.intf.fee.IFeeConfigInnerServiceSMO;
  14. import com.java110.intf.fee.IFeeDetailInnerServiceSMO;
  15. import com.java110.intf.fee.IFeeInnerServiceSMO;
  16. import com.java110.intf.user.IOwnerCarInnerServiceSMO;
  17. import com.java110.intf.user.IOwnerRoomRelInnerServiceSMO;
  18. import com.java110.job.quartz.TaskSystemQuartz;
  19. import com.java110.po.logSystemError.LogSystemErrorPo;
  20. import com.java110.service.smo.ISaveSystemErrorSMO;
  21. import com.java110.utils.constant.ResponseConstant;
  22. import com.java110.utils.exception.TaskTemplateException;
  23. import com.java110.utils.util.DateUtil;
  24. import com.java110.utils.util.ExceptionUtil;
  25. import com.java110.utils.util.StringUtil;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.stereotype.Component;
  28. import java.math.BigDecimal;
  29. import java.util.Calendar;
  30. import java.util.Date;
  31. import java.util.List;
  32. import java.util.Map;
  33. /**
  34. * @ClassName GenerateOwnerBillTemplate
  35. * @Description TODO 房屋费用账单生成
  36. * @Author wuxw
  37. * @Date 2020/6/4 8:33
  38. * @Version 1.0
  39. * add by wuxw 2020/6/4
  40. **/
  41. @Component
  42. public class GenerateBillProTemplate extends TaskSystemQuartz {
  43. private static final String TASK_ATTR_BILL_TYPE = "10002"; // 出账类型
  44. private static final String TASK_ATTR_VALUE_MONTH = "002"; //按月出账
  45. private static final String TASK_ATTR_VALUE_DAY = "003"; //按日出账
  46. private static final String TASK_ATTR_VALUE_YEAR = "001"; //按年出账
  47. private static final String TASK_ATTR_VALUE_ONCE_MONTH = "005"; //一次性按月出账
  48. @Autowired
  49. private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl;
  50. @Autowired
  51. private IFeeInnerServiceSMO feeInnerServiceSMOImpl;
  52. @Autowired
  53. private IFeeDetailInnerServiceSMO feeDetailInnerServiceSMOImpl;
  54. @Autowired
  55. private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
  56. @Autowired
  57. private IOwnerRoomRelInnerServiceSMO ownerRoomRelInnerServiceSMOImpl;
  58. @Autowired
  59. private IParkingSpaceInnerServiceSMO parkingSpaceInnerServiceSMOImpl;
  60. @Autowired
  61. private IOwnerCarInnerServiceSMO ownerCarInnerServiceSMOImpl;
  62. @Autowired
  63. private IComputeFeeSMO computeFeeSMOImpl;
  64. @Autowired
  65. private ISaveSystemErrorSMO saveSystemErrorSMOImpl;
  66. @Override
  67. protected void process(TaskDto taskDto) throws Exception {
  68. // 获取小区
  69. List<CommunityDto> communityDtos = getAllCommunity();
  70. for (CommunityDto communityDto : communityDtos) {
  71. try {
  72. GenerateBill(taskDto, communityDto);
  73. }catch (Throwable e){
  74. LogSystemErrorPo logSystemErrorPo = new LogSystemErrorPo();
  75. logSystemErrorPo.setErrId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_errId));
  76. logSystemErrorPo.setErrType(LogSystemErrorDto.ERR_TYPE_JOB);
  77. logSystemErrorPo.setMsg(ExceptionUtil.getStackTrace(e));
  78. saveSystemErrorSMOImpl.saveLog(logSystemErrorPo);
  79. logger.error("费用出账失败" + communityDto.getCommunityId(), e);
  80. }
  81. }
  82. }
  83. /**
  84. * 根据小区生成账单
  85. *
  86. * @param communityDto
  87. */
  88. private void GenerateBill(TaskDto taskDto, CommunityDto communityDto) {
  89. //查询费用项
  90. FeeConfigDto feeConfigDto = new FeeConfigDto();
  91. feeConfigDto.setCommunityId(communityDto.getCommunityId());
  92. feeConfigDto.setBillType(getCurTaskAttr(taskDto, TASK_ATTR_BILL_TYPE).getValue());
  93. if (StringUtil.isEmpty(feeConfigDto.getBillType())) {
  94. throw new IllegalArgumentException("配置错误 未拿到属性值");
  95. }
  96. List<FeeConfigDto> feeConfigDtos = feeConfigInnerServiceSMOImpl.queryFeeConfigs(feeConfigDto);
  97. for (FeeConfigDto tmpFeeConfigDto : feeConfigDtos) {
  98. try {
  99. GenerateBillByFeeConfig(taskDto, tmpFeeConfigDto);
  100. } catch (Throwable e) {
  101. LogSystemErrorPo logSystemErrorPo = new LogSystemErrorPo();
  102. logSystemErrorPo.setErrId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_errId));
  103. logSystemErrorPo.setErrType(LogSystemErrorDto.ERR_TYPE_JOB);
  104. logSystemErrorPo.setMsg(ExceptionUtil.getStackTrace(e));
  105. saveSystemErrorSMOImpl.saveLog(logSystemErrorPo);
  106. logger.error("费用出账失败" + tmpFeeConfigDto.getConfigId(), e);
  107. }
  108. }
  109. }
  110. /**
  111. * 按费用项来出账
  112. *
  113. * @param taskDto
  114. * @param feeConfigDto
  115. */
  116. private void GenerateBillByFeeConfig(TaskDto taskDto, FeeConfigDto feeConfigDto) throws Exception {
  117. //当前费用项是否
  118. BillDto tmpBillDto = new BillDto();
  119. tmpBillDto.setCurBill("T");
  120. tmpBillDto.setConfigId(feeConfigDto.getConfigId());
  121. tmpBillDto.setCommunityId(feeConfigDto.getCommunityId());
  122. Date startTime = getDefaultStartTime(feeConfigDto.getBillType());
  123. tmpBillDto.setCurBillTime(DateUtil.getFormatTimeString(startTime, DateUtil.DATE_FORMATE_STRING_A));
  124. List<BillDto> billDtos = feeInnerServiceSMOImpl.queryBills(tmpBillDto);
  125. //Assert.listOnlyOne(billDtos, "当前存在多个有效账单" + feeConfigDto.getConfigId());
  126. if (billDtos != null && billDtos.size() > 0) {
  127. throw new TaskTemplateException(ResponseConstant.RESULT_CODE_ERROR, "已经出过账了");
  128. }
  129. String billId = GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_billId);
  130. BillDto billDto = new BillDto();
  131. billDto.setBillId(billId);
  132. billDto.setBillName(feeConfigDto.getFeeName() + "-" + DateUtil.getFormatTimeString(new Date(), DateUtil.DATE_FORMATE_STRING_H));
  133. billDto.setBillTime(DateUtil.getFormatTimeString(new Date(), DateUtil.DATE_FORMATE_STRING_B));
  134. billDto.setCommunityId(feeConfigDto.getCommunityId());
  135. billDto.setConfigId(feeConfigDto.getConfigId());
  136. billDto.setCurBill("T");
  137. //查询历史有效账单
  138. tmpBillDto = new BillDto();
  139. tmpBillDto.setCurBill("T");
  140. tmpBillDto.setConfigId(feeConfigDto.getConfigId());
  141. tmpBillDto.setCommunityId(feeConfigDto.getCommunityId());
  142. billDtos = feeInnerServiceSMOImpl.queryBills(tmpBillDto);
  143. startTime = (billDtos == null || billDtos.size() < 1) ? getDefaultStartTime(feeConfigDto.getBillType())
  144. : DateUtil.getDateFromString(billDtos.get(0).getBillTime(), DateUtil.DATE_FORMATE_STRING_A);
  145. FeeDto feeDto = new FeeDto();
  146. feeDto.setConfigId(feeConfigDto.getConfigId());
  147. feeDto.setCommunityId(feeConfigDto.getCommunityId());
  148. List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
  149. //没有关联费用不做出账
  150. if (feeDto == null || feeDtos.size() < 1) {
  151. return;
  152. }
  153. billDto.setReceivable("0");
  154. billDto.setReceipts("0");
  155. billDto.setCurReceivable("0");
  156. for (FeeDto tmpFeeDto : feeDtos) {
  157. try {
  158. generateFee(startTime, tmpFeeDto, billDto, feeConfigDto);
  159. } catch (Throwable e) {
  160. LogSystemErrorPo logSystemErrorPo = new LogSystemErrorPo();
  161. logSystemErrorPo.setErrId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_errId));
  162. logSystemErrorPo.setErrType(LogSystemErrorDto.ERR_TYPE_JOB);
  163. logSystemErrorPo.setMsg(ExceptionUtil.getStackTrace(e));
  164. saveSystemErrorSMOImpl.saveLog(logSystemErrorPo);
  165. logger.error("生成费用失败", e);
  166. }
  167. }
  168. //生成本次账单
  169. Date billEndTime = DateUtil.getCurrentDate();
  170. billDto.setRemark(DateUtil.getFormatTimeString(startTime, DateUtil.DATE_FORMATE_STRING_A) +
  171. "-" + DateUtil.getFormatTimeString(billEndTime, DateUtil.DATE_FORMATE_STRING_A) + "账单数据");
  172. feeInnerServiceSMOImpl.insertBill(billDto);
  173. }
  174. /**
  175. * 生成 费用
  176. *
  177. * @param feeDto
  178. */
  179. private void generateFee(Date startTime, FeeDto feeDto, BillDto billDto, FeeConfigDto feeConfigDto) {
  180. if (FeeDto.STATE_FINISH.equals(feeDto.getState())) { //判断是否缴费结束
  181. return;
  182. }
  183. // 当前时间 - 开始时间 = 月份
  184. // 月份/ 周期 = 轮数(向上取整)
  185. // 轮数 * 周期 * 30 + 开始时间 = 目标 到期时间
  186. // 到期时间 >= 目标到期时间===>结束
  187. // 目标到期时间 - 到期时间 = 欠费月份
  188. // 月份 * 每月单价 = 欠费金额
  189. Map<String, Object> targetEndDateAndOweMonth = computeFeeSMOImpl.getTargetEndDateAndOweMonth(feeDto);
  190. Date targetEndDate = (Date) targetEndDateAndOweMonth.get("targetEndDate");
  191. double oweMonth = (double) targetEndDateAndOweMonth.get("oweMonth");
  192. //当前时间
  193. Date billEndTime = DateUtil.getCurrentDate();
  194. //缴费周期
  195. long paymentCycle = Long.parseLong(feeConfigDto.getPaymentCycle());
  196. //说明没有欠费
  197. if (oweMonth <= 0.0) {
  198. return;
  199. }
  200. Map feePriceAll = computeFeeSMOImpl.getFeePrice(feeDto);
  201. feeDto.setFeePrice(Double.parseDouble(feePriceAll.get("feePrice").toString()));
  202. if (feeDto.getFeePrice() <= 0) {
  203. return;//这个没有欠费可算
  204. }
  205. BillOweFeeDto billOweFeeDto = new BillOweFeeDto();
  206. billOweFeeDto.setOweId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_oweId));
  207. billOweFeeDto.setFeeId(feeDto.getFeeId());
  208. billOweFeeDto.setBillId(billDto.getBillId());
  209. BigDecimal curFeePrice = new BigDecimal(feeDto.getFeePrice());
  210. curFeePrice = curFeePrice.multiply(new BigDecimal(paymentCycle));
  211. billOweFeeDto.setAmountOwed(curFeePrice.doubleValue() + "");
  212. BigDecimal feePrice = new BigDecimal(feeDto.getFeePrice());
  213. feePrice = feePrice.multiply(new BigDecimal(oweMonth));
  214. billOweFeeDto.setBillAmountOwed(feePrice.doubleValue() + "");
  215. billOweFeeDto.setFeeEndTime(DateUtil.getFormatTimeString(feeDto.getEndTime(), DateUtil.DATE_FORMATE_STRING_A));
  216. billOweFeeDto.setCommunityId(feeDto.getCommunityId());
  217. billOweFeeDto.setPayerObjType(feeDto.getPayerObjType());
  218. billOweFeeDto.setState("1000");
  219. billOweFeeDto.setDeadlineTime(DateUtil.getFormatTimeString(targetEndDate, DateUtil.DATE_FORMATE_STRING_A));
  220. if (FeeDto.PAYER_OBJ_TYPE_ROOM.equals(feeDto.getPayerObjType())) {
  221. getRoomInfo(billOweFeeDto, feeDto);
  222. } else {
  223. getParkingSpaceInfo(billOweFeeDto, feeDto);
  224. }
  225. feeInnerServiceSMOImpl.insertBillOweFees(billOweFeeDto);
  226. double recFee = StringUtil.isEmpty(billDto.getReceivable()) ? 0.0 : Double.parseDouble(billDto.getReceivable());
  227. BigDecimal recFeeBig = new BigDecimal(recFee);
  228. BigDecimal newRecFee = recFeeBig.add(feePrice);
  229. //应收
  230. billDto.setReceivable(newRecFee.doubleValue() + "");
  231. //当期应收
  232. double curRecFee = StringUtil.isEmpty(billDto.getCurReceivable()) ? 0.0 : Double.parseDouble(billDto.getCurReceivable());
  233. BigDecimal curRecFeeBig = new BigDecimal(curRecFee);
  234. BigDecimal curNewRecFee = curRecFeeBig.add(curFeePrice);
  235. billDto.setCurReceivable(curNewRecFee.doubleValue() + "");
  236. FeeDetailDto feeDetailDto = new FeeDetailDto();
  237. feeDetailDto.setFeeId(feeDto.getFeeId());
  238. feeDetailDto.setCommunityId(feeDto.getCommunityId());
  239. feeDetailDto.setStartTime(startTime);
  240. feeDetailDto.setEndTime(billEndTime);
  241. List<FeeDetailDto> feeDetailDtos = feeDetailInnerServiceSMOImpl.queryFeeDetails(feeDetailDto);
  242. double curReceiptFee = StringUtil.isEmpty(billDto.getReceipts()) ? 0.0 : Double.parseDouble(billDto.getReceipts());
  243. BigDecimal curReceipts = new BigDecimal(curReceiptFee);
  244. if (feeDetailDtos != null && feeDetailDtos.size() > 0) {
  245. for (FeeDetailDto tmpFeeDetailDto : feeDetailDtos) {
  246. BigDecimal recAmount = new BigDecimal(Double.parseDouble(tmpFeeDetailDto.getReceivedAmount()));
  247. curReceipts = recAmount.add(curReceipts);
  248. }
  249. }
  250. billDto.setReceipts(curReceipts.doubleValue() + "");
  251. }
  252. /**
  253. * 查询车位信息
  254. *
  255. * @param billOweFeeDto
  256. * @param feeDto
  257. */
  258. private void getParkingSpaceInfo(BillOweFeeDto billOweFeeDto, FeeDto feeDto) {
  259. OwnerCarDto ownerCarDto = new OwnerCarDto();
  260. ownerCarDto.setWithOwner(true);
  261. ownerCarDto.setCarId(feeDto.getPayerObjId());
  262. ownerCarDto.setCommunityId(feeDto.getCommunityId());
  263. List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
  264. if (ownerCarDtos == null || ownerCarDtos.size() < 1) {
  265. //房屋可能被删除了
  266. billOweFeeDto.setOwnerId("1");
  267. billOweFeeDto.setOwnerName("未知");
  268. billOweFeeDto.setOwnerTel("19999999999");
  269. return;
  270. }
  271. billOweFeeDto.setPayerObjName(ownerCarDtos.get(0).getCarNum());
  272. billOweFeeDto.setOwnerId(ownerCarDtos.get(0).getOwnerId());
  273. billOweFeeDto.setOwnerName(ownerCarDtos.get(0).getOwnerName());
  274. billOweFeeDto.setOwnerTel(ownerCarDtos.get(0).getLink());
  275. }
  276. /**
  277. * 查询房屋信息
  278. *
  279. * @param billOweFeeDto
  280. * @param feeDto
  281. */
  282. private void getRoomInfo(BillOweFeeDto billOweFeeDto, FeeDto feeDto) {
  283. RoomDto roomDto = new RoomDto();
  284. roomDto.setRoomId(feeDto.getPayerObjId());
  285. roomDto.setCommunityId(feeDto.getCommunityId());
  286. List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
  287. if (roomDtos == null || roomDtos.size() < 1) {
  288. //房屋可能被删除了
  289. billOweFeeDto.setOweId("1");
  290. billOweFeeDto.setOwnerId("-1");
  291. billOweFeeDto.setOwnerName("未知");
  292. billOweFeeDto.setOwnerTel("19999999999");
  293. billOweFeeDto.setPayerObjName("未知");
  294. return;
  295. }
  296. RoomDto tmpRoomDto = roomDtos.get(0);
  297. if (RoomDto.ROOM_TYPE_ROOM.equals(tmpRoomDto.getRoomType())) {
  298. billOweFeeDto.setPayerObjName(tmpRoomDto.getFloorNum() + "栋" + tmpRoomDto.getUnitNum() + "单元" + tmpRoomDto.getRoomNum() + "室");
  299. } else {
  300. billOweFeeDto.setPayerObjName(tmpRoomDto.getFloorNum() + "栋" + tmpRoomDto.getRoomNum() + "室");
  301. }
  302. OwnerRoomRelDto ownerRoomRelDto = new OwnerRoomRelDto();
  303. ownerRoomRelDto.setByOwnerInfo(true);
  304. ownerRoomRelDto.setRoomId(tmpRoomDto.getRoomId());
  305. List<OwnerRoomRelDto> ownerRoomRelDtos = ownerRoomRelInnerServiceSMOImpl.queryOwnerRoomRels(ownerRoomRelDto);
  306. if (ownerRoomRelDtos == null || ownerRoomRelDtos.size() < 1) {
  307. //房屋可能被删除了
  308. billOweFeeDto.setOweId("1");
  309. billOweFeeDto.setOwnerId("-1");
  310. billOweFeeDto.setOwnerName("未知");
  311. billOweFeeDto.setOwnerTel("19999999999");
  312. return;
  313. }
  314. billOweFeeDto.setOwnerId(ownerRoomRelDtos.get(0).getOwnerId());
  315. billOweFeeDto.setOwnerName(ownerRoomRelDtos.get(0).getOwnerName());
  316. billOweFeeDto.setOwnerTel(ownerRoomRelDtos.get(0).getLink());
  317. }
  318. private Date getDefaultStartTime(String billType) {
  319. Calendar calendar = Calendar.getInstance();
  320. calendar.setTime(new Date());
  321. if (billType.equals(TASK_ATTR_VALUE_MONTH)) {
  322. calendar.add(Calendar.MONTH, -1);
  323. return calendar.getTime();
  324. }
  325. if (billType.equals(TASK_ATTR_VALUE_DAY)) {
  326. calendar.add(Calendar.DATE, -1);
  327. return calendar.getTime();
  328. }
  329. if (billType.equals(TASK_ATTR_VALUE_DAY)) {
  330. calendar.add(Calendar.DATE, -1);
  331. return calendar.getTime();
  332. }
  333. if (billType.equals(TASK_ATTR_VALUE_YEAR)) {
  334. calendar.add(Calendar.YEAR, -1);
  335. return calendar.getTime();
  336. }
  337. return calendar.getTime();
  338. }
  339. }