package com.java110.fee.cmd.fee; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.java110.core.annotation.Java110Cmd; import com.java110.core.context.ICmdDataFlowContext; import com.java110.core.event.cmd.AbstractServiceCmdListener; import com.java110.core.event.cmd.CmdEvent; import com.java110.core.factory.GenerateCodeFactory; import com.java110.core.smo.IComputeFeeSMO; import com.java110.dto.account.AccountDto; import com.java110.dto.couponUser.CouponUserDto; import com.java110.dto.fee.FeeDetailDto; import com.java110.dto.fee.FeeDto; import com.java110.dto.feeDiscount.ComputeDiscountDto; import com.java110.intf.acct.IAccountInnerServiceSMO; import com.java110.intf.acct.ICouponUserV1InnerServiceSMO; import com.java110.intf.community.IRepairUserInnerServiceSMO; import com.java110.intf.community.IRoomInnerServiceSMO; import com.java110.intf.fee.*; import com.java110.intf.user.IOwnerCarInnerServiceSMO; import com.java110.utils.cache.CommonCache; import com.java110.utils.constant.ResponseConstant; import com.java110.utils.exception.CmdException; import com.java110.utils.exception.ListenerExecuteException; import com.java110.utils.util.Assert; import com.java110.utils.util.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 类表述:删除 * 服务编码:feePrintPage.deleteFeePrintPage * 请求路劲:/app/feePrintPage.DeleteFeePrintPage * add by 吴学文 at 2021-09-16 22:26:04 mail: 928255095@qq.com * open source address: https://gitee.com/wuxw7/MicroCommunity * 官网:http://www.homecommunity.cn * 温馨提示:如果您对此文件进行修改 请不要删除原有作者及注释信息,请补充您的 修改的原因以及联系邮箱如下 * // modify by 张三 at 2021-09-12 第10行在某种场景下存在某种bug 需要修复,注释10至20行 加入 20行至30行 */ @Java110Cmd(serviceCode = "fee.payFeePre") public class PayFeePreCmd extends AbstractServiceCmdListener { private static Logger logger = LoggerFactory.getLogger(PayFeePreCmd.class); @Autowired private IFeeInnerServiceSMO feeInnerServiceSMOImpl; @Autowired private IRoomInnerServiceSMO roomInnerServiceSMOImpl; @Autowired private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl; @Autowired private IFeeDiscountInnerServiceSMO feeDiscountInnerServiceSMOImpl; @Autowired private IFeeAttrInnerServiceSMO feeAttrInnerServiceSMOImpl; @Autowired private IRepairUserInnerServiceSMO repairUserInnerServiceSMO; @Autowired private IOwnerCarInnerServiceSMO ownerCarInnerServiceSMOImpl; @Autowired private IApplyRoomDiscountInnerServiceSMO applyRoomDiscountInnerServiceSMOImpl; @Autowired private IFeeDetailInnerServiceSMO iFeeDetailInnerServiceSMO; @Autowired private IComputeFeeSMO computeFeeSMOImpl; @Autowired private ICouponUserV1InnerServiceSMO couponUserV1InnerServiceSMOImpl; @Autowired private IAccountInnerServiceSMO accountInnerServiceSMOImpl; @Override public void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) { Assert.jsonObjectHaveKey(reqJson, "communityId", "请求报文中未包含communityId节点"); Assert.jsonObjectHaveKey(reqJson, "cycles", "请求报文中未包含cycles节点"); Assert.jsonObjectHaveKey(reqJson, "receivedAmount", "请求报文中未包含receivedAmount节点"); Assert.jsonObjectHaveKey(reqJson, "feeId", "请求报文中未包含feeId节点"); Assert.jsonObjectHaveKey(reqJson, "appId", "请求报文中未包含appId节点"); Assert.hasLength(reqJson.getString("communityId"), "小区ID不能为空"); Assert.hasLength(reqJson.getString("cycles"), "周期不能为空"); Assert.hasLength(reqJson.getString("receivedAmount"), "实收金额不能为空"); Assert.hasLength(reqJson.getString("feeId"), "费用ID不能为空"); Assert.hasLength(reqJson.getString("appId"), "appId不能为空"); } @Override public void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException { logger.debug("ServiceDataFlowEvent : {}", event); String appId = cmdDataFlowContext.getReqHeaders().get("app-id"); reqJson.put("appId", appId); FeeDto feeDto = new FeeDto(); feeDto.setFeeId(reqJson.getString("feeId")); feeDto.setCommunityId(reqJson.getString("communityId")); List feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto); if (feeDtos == null || feeDtos.size() != 1) { throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "查询费用信息失败,未查到数据或查到多条数据"); } feeDto = feeDtos.get(0); Map feePriceAll = computeFeeSMOImpl.getFeePrice(feeDto); BigDecimal receivableAmount = new BigDecimal(feePriceAll.get("feePrice").toString()); BigDecimal cycles = new BigDecimal(Double.parseDouble(reqJson.getString("cycles"))); double tmpReceivableAmount = cycles.multiply(receivableAmount).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue(); JSONObject paramOut = new JSONObject(); paramOut.put("receivableAmount", tmpReceivableAmount); paramOut.put("oId", GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_oId)); //实收金额 BigDecimal tmpReceivedAmout = new BigDecimal(tmpReceivableAmount); //判断是否有折扣情况 double discountPrice = judgeDiscount(reqJson); tmpReceivedAmout = tmpReceivedAmout.subtract(new BigDecimal(discountPrice)).setScale(2, BigDecimal.ROUND_HALF_EVEN); //2.0 考虑账户抵消 double accountPrice = judgeAccount(reqJson); tmpReceivedAmout = tmpReceivedAmout.subtract(new BigDecimal(accountPrice)).setScale(2, BigDecimal.ROUND_HALF_EVEN); //3.0 考虑优惠卷 double couponPrice = checkCouponUser(reqJson); tmpReceivedAmout = tmpReceivedAmout.subtract(new BigDecimal(couponPrice)).setScale(2, BigDecimal.ROUND_HALF_EVEN); double receivedAmount = tmpReceivedAmout.doubleValue(); //所有 优惠折扣计算完后,如果总金额小于等于0,则返回总扣款为0 if (receivedAmount <= 0) { receivedAmount = 0.0; } paramOut.put("receivedAmount", receivedAmount); ResponseEntity responseEntity = new ResponseEntity<>(paramOut.toJSONString(), HttpStatus.OK); CommonCache.setValue("payFeePre" + paramOut.getString("oId"), reqJson.toJSONString(), 24 * 60 * 60); cmdDataFlowContext.setResponseEntity(responseEntity); } /** * 考虑账户抵消 * @param reqJson */ private double judgeAccount(JSONObject reqJson) { if(!reqJson.containsKey("deductionAmount")){ reqJson.put("deductionAmount",0.0); return 0.0; } double deductionAmount = reqJson.getDouble("deductionAmount"); if(deductionAmount <= 0){ reqJson.put("deductionAmount",0.0); return 0.0; } if(!reqJson.containsKey("selectUserAccount")){ reqJson.put("deductionAmount",0.0); return 0.0; } JSONArray selectUserAccount = reqJson.getJSONArray("selectUserAccount"); if(selectUserAccount == null || selectUserAccount.size() <1){ reqJson.put("deductionAmount",0.0); return 0.0; } List acctIds = new ArrayList<>(); for(int userAccountIndex = 0 ;userAccountIndex < selectUserAccount.size(); userAccountIndex++){ acctIds.add(selectUserAccount.getJSONObject(userAccountIndex).getString("acctId")); } AccountDto accountDto = new AccountDto(); accountDto.setAcctIds(acctIds.toArray(new String[acctIds.size()])); List accountDtos = accountInnerServiceSMOImpl.queryAccounts(accountDto); if(accountDtos == null || accountDtos.size() < 1){ reqJson.put("deductionAmount",0.0); return 0.0; } BigDecimal totalAccountAmount = new BigDecimal(0); for(AccountDto tmpAccountDto: accountDtos){ totalAccountAmount = totalAccountAmount.add(new BigDecimal(tmpAccountDto.getAmount())); } deductionAmount = totalAccountAmount.subtract(new BigDecimal(deductionAmount)).doubleValue(); if(deductionAmount < 0){ reqJson.put("deductionAmount",totalAccountAmount.doubleValue()); reqJson.put("selectUserAccount",accountDtos); return totalAccountAmount.doubleValue(); } reqJson.put("deductionAmount",deductionAmount); reqJson.put("selectUserAccount",accountDtos); return deductionAmount; } private double checkCouponUser(JSONObject paramObj) { JSONArray couponList = paramObj.getJSONArray("couponList"); BigDecimal couponPrice = new BigDecimal(0.0); List couponIds = new ArrayList(); if (couponList == null || couponList.size() < 1) { paramObj.put("couponPrice", couponPrice.doubleValue()); paramObj.put("couponUserDtos", new ArrayList()); //这里考虑空 return couponPrice.doubleValue(); } for (int couponIndex = 0; couponIndex < couponList.size(); couponIndex++) { couponIds.add(couponList.getJSONObject(couponIndex).getString("couponId")); } CouponUserDto couponUserDto = new CouponUserDto(); couponUserDto.setCouponIds(couponIds.toArray(new String[couponIds.size()])); List couponUserDtos = couponUserV1InnerServiceSMOImpl.queryCouponUsers(couponUserDto); if (couponUserDtos == null || couponUserDtos.size() < 1) { paramObj.put("couponPrice", couponPrice.doubleValue()); return couponPrice.doubleValue(); } for (CouponUserDto couponUser : couponUserDtos) { //不计算已过期购物券金额 if (couponUser.getEndTime().compareTo(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_B)) >= 0) { couponPrice.add(new BigDecimal(Double.parseDouble(couponUser.getActualPrice()))); } } paramObj.put("couponPrice", couponPrice.doubleValue()); paramObj.put("couponUserDtos", couponUserDtos); return couponPrice.doubleValue(); } private double judgeDiscount(JSONObject paramObj) { FeeDetailDto feeDetailDto = new FeeDetailDto(); feeDetailDto.setCommunityId(paramObj.getString("communityId")); feeDetailDto.setFeeId(paramObj.getString("feeId")); feeDetailDto.setCycles(paramObj.getString("cycles")); feeDetailDto.setPayerObjId(paramObj.getString("payerObjId")); feeDetailDto.setPayerObjType(paramObj.getString("payerObjType")); String endTime = paramObj.getString("endTime"); //获取缴费到期时间 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { feeDetailDto.setStartTime(simpleDateFormat.parse(endTime)); } catch (ParseException e) { throw new CmdException(e.getLocalizedMessage()); } feeDetailDto.setRow(20); feeDetailDto.setPage(1); List computeDiscountDtos = feeDiscountInnerServiceSMOImpl.computeDiscount(feeDetailDto); if (computeDiscountDtos == null || computeDiscountDtos.size() < 1) { paramObj.put("discountPrice",0.0); return 0.0; } BigDecimal discountPrice = new BigDecimal(0); for (ComputeDiscountDto computeDiscountDto : computeDiscountDtos) { discountPrice = discountPrice.add(new BigDecimal(computeDiscountDto.getDiscountPrice())); } paramObj.put("discountPrice",discountPrice.doubleValue()); paramObj.put("computeDiscountDtos", computeDiscountDtos); return discountPrice.doubleValue(); } }