AutomaticPay.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package com.pj.project.tb_account;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.date.DateUtil;
  4. import cn.hutool.core.util.NumberUtil;
  5. import cn.hutool.core.util.RandomUtil;
  6. import cn.hutool.core.util.StrUtil;
  7. import cn.hutool.log.StaticLog;
  8. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  9. import com.pj.api.wx.bo.PriceBO;
  10. import com.pj.constants.business.CarEnum;
  11. import com.pj.constants.business.FeeTypeEnum;
  12. import com.pj.constants.business.GoodsEnum;
  13. import com.pj.constants.business.PayEnum;
  14. import com.pj.current.config.SystemObject;
  15. import com.pj.project.sync.SyncService;
  16. import com.pj.project.sync.request.item.IOrderItem;
  17. import com.pj.project.sync.response.IOrderPriceRes;
  18. import com.pj.project.sync.response.item.OrderPriceResultItem;
  19. import com.pj.project.sync.response.item.PriceDetailItem;
  20. import com.pj.project.tb_business.TbBusiness;
  21. import com.pj.project.tb_business.TbBusinessService;
  22. import com.pj.project.tb_business_car.TbBusinessCar;
  23. import com.pj.project.tb_business_car.TbBusinessCarService;
  24. import com.pj.project.tb_business_item.TbBusinessItem;
  25. import com.pj.project.tb_business_item.TbBusinessItemService;
  26. import com.pj.project.tb_car_weight.TbCarWeight;
  27. import com.pj.project.tb_car_weight.TbCarWeightService;
  28. import com.pj.project.tb_costomer.TbCostomer;
  29. import com.pj.project.tb_costomer.TbCostomerService;
  30. import com.pj.project.tb_deduction_bind.TbDeductionBind;
  31. import com.pj.project.tb_deduction_bind.TbDeductionBindService;
  32. import com.pj.project.tb_deduction_record.TbDeductionRecord;
  33. import com.pj.project.tb_fee_details.TbFeeDetails;
  34. import com.pj.project.tb_fee_details.TbFeeDetailsService;
  35. import com.pj.project.tb_fee_statistics.TbFeeStatisticsService;
  36. import com.pj.project.tb_goods.TbGoods;
  37. import com.pj.project.tb_goods.TbGoodsService;
  38. import com.pj.project.tb_invoice_order.TbInvoiceOrder;
  39. import com.pj.project.tb_invoice_order.TbInvoiceOrderService;
  40. import com.pj.project.tb_item.TbItem;
  41. import com.pj.project.tb_item.TbItemService;
  42. import com.pj.utils.AesUtil;
  43. import com.pj.utils.cache.RedisUtil;
  44. import com.pj.utils.sg.NbUtil;
  45. import lombok.extern.slf4j.Slf4j;
  46. import org.springframework.context.annotation.Lazy;
  47. import org.springframework.scheduling.annotation.Async;
  48. import org.springframework.stereotype.Component;
  49. import org.springframework.transaction.annotation.Transactional;
  50. import javax.annotation.Resource;
  51. import java.math.BigDecimal;
  52. import java.time.LocalDateTime;
  53. import java.time.format.DateTimeFormatter;
  54. import java.util.ArrayList;
  55. import java.util.Collections;
  56. import java.util.Date;
  57. import java.util.List;
  58. import java.util.stream.Collectors;
  59. /**
  60. * 预充值自动缴费
  61. */
  62. @Component
  63. @Transactional(rollbackFor = Exception.class)
  64. @Slf4j
  65. public class AutomaticPay {
  66. @Resource
  67. TbBusinessCarService tbBusinessCarService;
  68. @Resource
  69. TbBusinessService tbBusinessService;
  70. @Resource
  71. TbBusinessItemService tbBusinessItemService;
  72. @Resource
  73. TbFeeDetailsService tbFeeDetailsService;
  74. @Resource
  75. TbAccountService tbAccountService;
  76. @Resource
  77. TbInvoiceOrderService invoiceOrderService;
  78. @Resource
  79. private TbFeeStatisticsService tbFeeStatisticsService;
  80. @Resource
  81. private SyncService syncService;
  82. @Resource
  83. private TbCostomerService tbCostomerService;
  84. @Resource
  85. private TbItemService tbItemService;
  86. @Resource
  87. private TbCarWeightService tbCarWeightService;
  88. /**
  89. * 生成扣费记录
  90. */
  91. public TbDeductionRecord createTbDeductionRecord(TbFeeDetails feeDetails, BigDecimal originalMoney, BigDecimal balance,
  92. String customerId, String customerName, String plate, String businessCarId, FeeTypeEnum feeTypeEnum) {
  93. TbDeductionRecord deductionRecord = BeanUtil.toBean(feeDetails, TbDeductionRecord.class);
  94. BigDecimal itemPrice = feeDetails.getItemPrice();
  95. String no = feeDetails.getBusinessNo();
  96. String preNo = DateUtil.format(new Date(), "yyyyMMddHHmm") + RandomUtil.randomString(5);
  97. deductionRecord
  98. .setPreOrderNum(preNo)
  99. .setCustomerId(customerId)
  100. .setCustomerName(customerName)
  101. .setDeductMoney(itemPrice)
  102. .setBusinessNo(no).setWeight(feeDetails.getWeight())
  103. .setOriginalMoney(originalMoney).setBusinessId(feeDetails.getBusinessId())
  104. .setTotalMoney(originalMoney.subtract(itemPrice)).setBusinessCarId(businessCarId)
  105. .setFeeDetailsId(feeDetails.getId()).setItemName(feeDetails.getItemName())
  106. .setItemTypeId(feeDetails.getItemTypeId()).setItemTypeName(feeDetails.getItemTypeName())
  107. .setReviewStatus(0).setFeeType(feeTypeEnum.getCode()).setFeeTypeName(feeTypeEnum.getDesc())
  108. .setCarNo(plate).setBusinessItemId(feeDetails.getBusinessItemId())
  109. .setFeeDetailsId(feeDetails.getId());
  110. deductionRecord.insert();
  111. feeDetails.setPreOrderNum(preNo);
  112. tbFeeDetailsService.updateById(feeDetails);
  113. return deductionRecord;
  114. }
  115. /**
  116. * 支付停车费和业务费
  117. *
  118. * @param businessList
  119. * @return
  120. */
  121. public boolean payBusinessAndPartMoney(List<TbBusiness> businessList,
  122. TbBusinessCar tbBusinessCar,
  123. IOrderPriceRes partMoneyRes, BigDecimal businessMoney, List<TbCarWeight> carWeights) {
  124. Date now = new Date();
  125. String customerId = tbBusinessCar.getCustomerId();
  126. if (StrUtil.isEmpty(customerId)) {
  127. return false;
  128. }
  129. TbAccount tbAccount = tbAccountService.getAccountByCustomerId(customerId);
  130. //原金额
  131. BigDecimal originalMoney = tbAccount.getTotalMoney();
  132. //停车费扣除
  133. BigDecimal partMoney = partMoneyRes.getTotalOrderPrice();
  134. //业务费用
  135. // BigDecimal businessMoney = businessRes.getTotalOrderPrice();
  136. //过磅费
  137. BigDecimal weightMoney = BigDecimal.ZERO;
  138. for (TbCarWeight carWeight : carWeights) {
  139. weightMoney = weightMoney.add(carWeight.getWeightPrice());
  140. }
  141. //总费用
  142. BigDecimal totalMoney = partMoney.add(businessMoney).add(weightMoney);
  143. if (totalMoney.compareTo(originalMoney) > 0) {
  144. return false;//不够交
  145. }
  146. log.info("payment============:{}",partMoney);
  147. log.info("businessMoney=========:{}",businessMoney);
  148. log.info("totalMoney==========:{}",totalMoney);
  149. //余额
  150. BigDecimal balance = originalMoney.subtract(totalMoney);
  151. log.info("Balance: " + balance);
  152. tbAccount.setTotalMoney(balance);
  153. //更新账户余额
  154. tbAccountService.updateById(tbAccount);
  155. TbCostomer tbCostomer = tbCostomerService.getById(customerId);
  156. String customerName = tbCostomer.getName();
  157. //地磅费统计
  158. if (weightMoney.doubleValue() > 0) {
  159. tbBusinessCar.setNetweightMoney(weightMoney).setPayNetweightMoney(1);
  160. TbItem tbItem = tbItemService.findByAliasName(SystemObject.config.getWeighbridge());
  161. for (TbCarWeight carWeight : carWeights) {
  162. TbFeeDetails details = tbFeeDetailsService.saveCarWeightDetails("",carWeight.getWeightPrice(), carWeight.getCalculateId(), carWeight.getNo(), tbBusinessCar, customerName, customerName, tbItem, PayEnum.PayType.PER_PAY);
  163. createTbDeductionRecord(details, originalMoney, BigDecimal.ZERO, customerId, customerName,
  164. tbBusinessCar.getCarNo(), tbBusinessCar.getId(), FeeTypeEnum.WEIGHT_FEE);
  165. carWeight.setPayStatus(1).setPayTime(now).setPayType(PayEnum.PayType.PER_PAY.getCode());
  166. tbCarWeightService.updateById(carWeight);
  167. originalMoney=originalMoney.subtract(carWeight.getWeightPrice());
  168. }
  169. }
  170. //需要交停车费且未交的话
  171. if (partMoney.compareTo(BigDecimal.ZERO) > 0) {
  172. String businessIds = businessList.stream().filter(tbBusiness -> tbBusiness.getGoodsName().contains("停车"))
  173. .map(TbBusiness::getId).collect(Collectors.joining(","));
  174. String uniqExpenseId = partMoneyRes.getUniqueExpenseId();
  175. String calculateId = partMoneyRes.getCalculateId();
  176. String carDesc = partMoneyRes.getCarDesc();
  177. String hourDesc = partMoneyRes.getHourDesc();
  178. List<PriceDetailItem> items = partMoneyRes.getFireResult().get(0).getPriceDetail();
  179. if (partMoneyRes.getTotalOrderPrice().intValue() > 0) {
  180. items = partMoneyRes.getFireResult().get(0).getPriceDetail();
  181. }
  182. PriceBO priceBO = new PriceBO();
  183. List<PriceBO> priceBOList = new ArrayList<>();
  184. priceBO.setId(tbBusinessCar.getId()).setP(partMoney).setCalculateId(calculateId)
  185. .setCarDesc(carDesc).setHourDesc(hourDesc).setBusinessId(businessIds)
  186. .setUniqExpenseId(uniqExpenseId);
  187. priceBOList.add(priceBO);
  188. for (PriceDetailItem item : items) {
  189. if (item.getKey().toLowerCase().trim().equals("standard")) {
  190. priceBO.setStandard(new BigDecimal(item.getValue()));
  191. } else if (item.getKey().trim().equals("extraPrice")) {
  192. priceBO.setExtraPrice(new BigDecimal(item.getValue()));
  193. }
  194. }
  195. String plate = tbBusinessCar.getCarNo();
  196. tbBusinessCar.setPay(1).setPayType(CarEnum.PayTypeEnum.HAS_PAY_TYPE.getType())
  197. .setPayTime(now).setMoney(partMoney.add(tbBusinessCar.getMoney()));
  198. tbBusinessCarService.updateById(tbBusinessCar);
  199. TbBusiness tbBusiness = businessList.get(0);
  200. String businessNo = tbBusiness.getNo();
  201. List<TbFeeDetails> parkFeeDetailsList = tbFeeDetailsService.chargeParkFee(priceBOList, null, null, now, PayEnum.PayType.PER_PAY);
  202. //停车费明细
  203. for (TbFeeDetails tbFeeDetails : parkFeeDetailsList) {
  204. tbFeeDetails.setBusinessNo(businessNo);
  205. TbDeductionRecord record = this.createTbDeductionRecord(tbFeeDetails, originalMoney, BigDecimal.ZERO,
  206. customerId, customerName, plate, tbBusinessCar.getId(), FeeTypeEnum.PARK_FEE);
  207. invoiceOrderService.addInvoiceOrder("停车业务", businessNo, tbBusinessCar.getCarNo(), tbBusiness.getId(), tbBusinessCar.getCustomerId(), tbBusiness.getCustomerName(), tbBusiness.getCustomerName(), tbFeeDetails.getItemPrice(), tbFeeDetails, record);
  208. originalMoney = originalMoney.subtract(tbFeeDetails.getItemPrice());
  209. }
  210. }
  211. //业务费用
  212. for (TbBusiness tbBusiness : businessList) {
  213. List<TbBusinessItem> items = tbBusinessItemService.findByBusinessId(tbBusiness.getId());
  214. items = items.stream().filter(item -> item.getPayStatus() == 0).collect(Collectors.toList());
  215. for (TbBusinessItem item : items) {
  216. if (item.getPayStatus() == 1) {//已支付的
  217. continue;
  218. }
  219. //支付金额累加
  220. if (!StrUtil.equals(item.getItemAlias(), SystemObject.config.getPartItemAlias())) {
  221. List<IOrderItem> orderItems = new ArrayList<>();
  222. tbBusinessItemService.buildExpenses(Collections.singletonList(item), orderItems);
  223. if (orderItems.isEmpty()) {
  224. continue;
  225. }
  226. IOrderPriceRes res = syncService.orderPriceCal(orderItems);
  227. BigDecimal price = res.getTotalOrderPrice();
  228. item.setTotal(price);
  229. tbBusiness.setPayMoney(tbBusiness.getPayMoney().add(price));
  230. int feeType = item.getPayType();
  231. FeeTypeEnum feeTypeEnum = FeeTypeEnum.getEnum(feeType);
  232. TbFeeDetails details = tbFeeDetailsService.savePrePayDetails(res, item, tbBusinessCar, tbBusiness, tbBusiness.getCustomerName(), tbBusiness.getPickCustomerName(), feeTypeEnum);
  233. log.info("originalMoney:{}",originalMoney);
  234. TbDeductionRecord record = createTbDeductionRecord(details, originalMoney, BigDecimal.ZERO, customerId, tbBusiness.getCustomerName(),
  235. tbBusinessCar.getCarNo(), tbBusinessCar.getId(), feeTypeEnum);
  236. invoiceOrderService.addInvoiceOrder(tbBusiness.getGoodsName(), tbBusiness.getNo(), tbBusiness.getCarNoStr(), tbBusiness.getId(),
  237. tbBusiness.getCustomerId(), tbBusiness.getCustomerName(), tbBusiness.getCustomerName(), res.getTotalOrderPrice(), details, record);
  238. originalMoney=originalMoney.subtract(details.getItemPrice());
  239. log.info("after originalMoney:{}",originalMoney);
  240. } else {
  241. tbBusiness.setPayMoney(tbBusiness.getPayMoney().add(partMoney)).setItemPrice(BigDecimal.ZERO);
  242. }
  243. item.setPayStatus(1).setPayTime(now);
  244. if (StrUtil.equals(SystemObject.config.getWeighbridge(), item.getItemAlias())) {
  245. tbBusinessCar.setPayNetweightMoney(1);
  246. }
  247. tbBusinessItemService.updateById(item);
  248. double itemPrice = items.stream().collect(Collectors.summarizingDouble(t -> t.getTotal().doubleValue())).getSum();
  249. tbBusiness.setPayStatus(PayEnum.PayStatusEnum.HAS_PAY_CONFIRM.getCode()).setPayTime(now);
  250. BigDecimal totalPrice = tbBusiness.getItemPrice();
  251. if (totalPrice.doubleValue() > 0.6) {
  252. tbBusiness.setItemPrice(tbBusiness.getItemPrice().add(BigDecimal.valueOf(itemPrice)));
  253. } else {
  254. tbBusiness.setItemPrice(BigDecimal.valueOf(itemPrice));
  255. }
  256. tbBusinessService.updateById(tbBusiness);
  257. if (StrUtil.equals(item.getItemAlias(), SystemObject.config.getWeighbridge())) {
  258. tbBusinessCar.setNetweightMoney(item.getTotal());
  259. tbBusinessCarService.updateById(tbBusinessCar);
  260. }
  261. }
  262. }
  263. //todo 构造统计数据
  264. tbFeeStatisticsService.addOrUpdateStatistic(now, PayEnum.PayType.PER_PAY.getCode());//更新当前日期的日统计
  265. return true;
  266. }
  267. }