wuxw
2024-02-26 17bfc74d3531f606034bd70ecc33ce97cb81e17f
service-fee/src/main/java/com/java110/fee/cmd/fee/PayFeeCmd.java
@@ -19,10 +19,8 @@
import com.java110.dto.repair.RepairDto;
import com.java110.dto.repair.RepairUserDto;
import com.java110.dto.user.UserDto;
import com.java110.intf.acct.IAccountDetailInnerServiceSMO;
import com.java110.fee.smo.impl.FeeReceiptInnerServiceSMOImpl;
import com.java110.intf.acct.IAccountInnerServiceSMO;
import com.java110.intf.acct.ICouponUserDetailV1InnerServiceSMO;
import com.java110.intf.acct.ICouponUserV1InnerServiceSMO;
import com.java110.intf.community.*;
import com.java110.intf.fee.*;
import com.java110.intf.fee.IFeeAccountDetailServiceSMO;
@@ -39,16 +37,12 @@
import com.java110.po.owner.RepairUserPo;
import com.java110.po.payFee.PayFeeDetailDiscountPo;
import com.java110.utils.cache.CommonCache;
import com.java110.utils.constant.CommonConstant;
import com.java110.utils.constant.FeeFlagTypeConstant;
import com.java110.utils.constant.ResponseConstant;
import com.java110.utils.exception.CmdException;
import com.java110.utils.exception.ListenerExecuteException;
import com.java110.utils.lock.DistributedLock;
import com.java110.utils.util.Assert;
import com.java110.utils.util.BeanConvertUtil;
import com.java110.utils.util.DateUtil;
import com.java110.utils.util.StringUtil;
import com.java110.utils.util.*;
import com.java110.vo.ResultVo;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@@ -82,16 +76,10 @@
    private IFeeAttrInnerServiceSMO feeAttrInnerServiceSMOImpl;
    @Autowired
    private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
    @Autowired
    private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl;
    @Autowired
    private IOwnerCarInnerServiceSMO ownerCarInnerServiceSMOImpl;
    @Autowired
    private IFeeReceiptDetailInnerServiceSMO feeReceiptDetailInnerServiceSMOImpl;
    @Autowired
    private IRepairUserInnerServiceSMO repairUserInnerServiceSMO;
@@ -104,9 +92,6 @@
    @Autowired
    private IParkingSpaceInnerServiceSMO parkingSpaceInnerServiceSMOImpl;
    @Autowired
    private IAccountDetailInnerServiceSMO accountDetailInnerServiceSMOImpl;
    @Autowired
    private IAccountInnerServiceSMO accountInnerServiceSMOImpl;
@@ -124,12 +109,6 @@
    private IRepairUserV1InnerServiceSMO repairUserNewV1InnerServiceSMOImpl;
    @Autowired
    private ICouponUserV1InnerServiceSMO couponUserV1InnerServiceSMOImpl;
    @Autowired
    private ICouponUserDetailV1InnerServiceSMO couponUserDetailV1InnerServiceSMOImpl;
    @Autowired
    private IOwnerCarNewV1InnerServiceSMO ownerCarNewV1InnerServiceSMOImpl;
    @Autowired
@@ -138,6 +117,11 @@
    @Autowired
    private IUserV1InnerServiceSMO userV1InnerServiceSMOImpl;
    @Autowired
    private FeeReceiptInnerServiceSMOImpl feeReceiptInnerServiceSMOImpl;
    @Autowired
    private IFeeDiscountInnerServiceSMO feeDiscountInnerServiceSMOImpl;
    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
@@ -145,12 +129,10 @@
        Assert.jsonObjectHaveKey(reqJson, "cycles", "请求报文中未包含cycles节点");
        Assert.jsonObjectHaveKey(reqJson, "receivedAmount", "请求报文中未包含receivedAmount节点");
        Assert.jsonObjectHaveKey(reqJson, "feeId", "请求报文中未包含feeId节点");
        Assert.hasLength(reqJson.getString("communityId"), "小区ID不能为空");
        Assert.hasLength(reqJson.getString("cycles"), "周期不能为空");
        Assert.hasLength(reqJson.getString("receivedAmount"), "实收金额不能为空");
        Assert.hasLength(reqJson.getString("feeId"), "费用ID不能为空");
        //判断是否 费用状态为缴费结束
        FeeDto feeDto = new FeeDto();
        feeDto.setFeeId(reqJson.getString("feeId"));
@@ -175,18 +157,18 @@
        if (feeConfigDtos == null || feeConfigDtos.size() != 1) {
            throw new IllegalArgumentException("费用项不存在");
        }
        /*//一次性费用 和间接性费用
        //一次性费用 和间接性费用
        Date maxEndTime = feeDtos.get(0).getDeadlineTime();
        //周期性费用
        if (maxEndTime == null || FeeDto.FEE_FLAG_CYCLE.equals(feeConfigDtos.get(0).getFeeFlag())) {
            maxEndTime = DateUtil.getDateFromStringA(feeConfigDtos.get(0).getEndTime());
        }*/
        Date maxEndTime = null;
        if (!StringUtil.isEmpty(feeDto.getFeeFlag()) && feeDto.getFeeFlag().equals(FeeDto.FEE_FLAG_CYCLE)) { //周期性费用
            maxEndTime = DateUtil.getDateFromStringA(feeConfigDtos.get(0).getEndTime());
        } else { //一次性费用 和间接性费用
            maxEndTime = feeDtos.get(0).getDeadlineTime();
        }
//        Date maxEndTime = null;
//        if (!StringUtil.isEmpty(feeDto.getFeeFlag()) && feeDto.getFeeFlag().equals(FeeDto.FEE_FLAG_CYCLE)) { //周期性费用
//            maxEndTime = DateUtil.getDateFromStringA(feeConfigDtos.get(0).getEndTime());
//        } else { //一次性费用 和间接性费用
//            maxEndTime = feeDtos.get(0).getDeadlineTime();
//        }
        if (maxEndTime != null && endTime != null && !FeeDto.FEE_FLAG_ONCE.equals(feeConfigDtos.get(0).getFeeFlag())) {
            Date newDate = DateUtil.stepMonth(endTime, reqJson.getDouble("cycles").intValue());
@@ -200,6 +182,8 @@
        for (int paramIndex = 0; paramIndex < params.size(); paramIndex++) {
            JSONObject param = params.getJSONObject(paramIndex);
            String maximumNumber = param.getString("maximumNumber");
            Assert.hasKeyAndValue(param, "discountId", "未包含优惠ID");
            Assert.hasKeyAndValue(param, "discountPrice", "未包含优惠金额");
        }
        //todo 是否按缴费时间段缴费
@@ -211,6 +195,7 @@
    @Java110Transactional
    public void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject paramObj) throws CmdException {
        logger.debug("paramObj : {}", paramObj);
        String payOrderId = paramObj.getString("payOrderId");
        String userId = cmdDataFlowContext.getReqHeaders().get("user-id");
        UserDto userDto = new UserDto();
@@ -220,6 +205,9 @@
        String cycles = paramObj.getString("cycles");
        Date endTime = null;
        //todo 生成收据编号
        String receiptCode = feeReceiptInnerServiceSMOImpl.generatorReceiptCode(paramObj.getString("communityId"));
        PayFeePo payFeePo = null;
        String requestId = DistributedLock.getLockUUID();
@@ -236,11 +224,15 @@
            payFeePo = BeanConvertUtil.covertBean(fee, PayFeePo.class);
            PayFeeDetailPo payFeeDetailPo = BeanConvertUtil.covertBean(feeDetail, PayFeeDetailPo.class);
            payFeeDetailPo.setReceivableAmount(feeDetail.getString("totalFeePrice"));
            //判断是否有赠送规则
            hasDiscount(paramObj, payFeePo, payFeeDetailPo);
            //todo 缓存收据编号
            CommonCache.setValue(payFeeDetailPo.getDetailId() + CommonCache.RECEIPT_CODE, receiptCode, CommonCache.DEFAULT_EXPIRETIME_TWO_MIN);
            //todo 判断是否有折扣规则
            hasDiscount(paramObj, payFeePo, payFeeDetailPo,feeInfo);
            // todo 处理用户账户
            dealUserAccount(paramObj, payFeeDetailPo);
            String oId = Java110TransactionalFactory.getOId();
            if (StringUtil.isEmpty(oId)) {
@@ -248,8 +240,13 @@
            }
            payFeeDetailPo.setPayOrderId(oId);
            // todo 如果 扫码枪支付 输入支付订单ID
            if (!StringUtil.isEmpty(payOrderId)) {
                payFeeDetailPo.setPayOrderId(payOrderId);
            }
            payFeeDetailPo.setCashierId(userDtos.get(0).getUserId());
            payFeeDetailPo.setCashierName(userDtos.get(0).getName());
            payFeeDetailPo.setOpenInvoice("N");
            int flag = payFeeDetailNewV1InnerServiceSMOImpl.savePayFeeDetailNew(payFeeDetailPo);
            if (flag < 1) {
                throw new CmdException("缴费失败");
@@ -266,22 +263,14 @@
        } finally {
            DistributedLock.releaseDistributedLock(key, requestId);
        }
        //账户处理
        //todo 账户处理
        dealAccount(paramObj);
        //折扣管理
        if (paramObj.containsKey("selectDiscount")) {
            JSONObject discountBusiness = null;
            JSONArray selectDiscounts = paramObj.getJSONArray("selectDiscount");
            for (int discountIndex = 0; discountIndex < selectDiscounts.size(); discountIndex++) {
                JSONObject param = selectDiscounts.getJSONObject(discountIndex);
                addPayFeeDetailDiscount(paramObj, param);
            }
        }
        //为停车费单独处理
        //todo 为停车费单独处理
        updateCarEndTime(paramObj);
        //处理报修单
        //todo 处理报修单
        doDealRepairOrder(paramObj);
@@ -299,6 +288,7 @@
            }
        }
        //根据明细ID 查询收据信息
        FeeReceiptDetailDto feeReceiptDetailDto = new FeeReceiptDetailDto();
        feeReceiptDetailDto.setDetailId(paramObj.getString("detailId"));
@@ -310,7 +300,7 @@
    private void dealUserAccount(JSONObject paramObj, PayFeeDetailPo payFeeDetailPo) {
        //判断选择的账号
        JSONArray jsonArray = paramObj.getJSONArray("selectUserAccount");
        if (jsonArray == null || jsonArray.size() < 1) {
        if (ListUtil.isNull(jsonArray)) {
            return;
        }
@@ -403,6 +393,7 @@
                BigDecimal receivedAmountDec = new BigDecimal(payFeeDetailPo.getReceivedAmount());
                receivedAmountDec = receivedAmountDec.subtract(cashSum);
                payFeeDetailPo.setReceivedAmount(receivedAmountDec.doubleValue() + "");
                payFeeDetailPo.setAcctAmount(cashSum.doubleValue() + "");
            }
        }
    }
@@ -415,22 +406,23 @@
     * @param payFeeDetailPo
     * @throws ParseException
     */
    private void hasDiscount(JSONObject paramObj, PayFeePo payFeePo, PayFeeDetailPo payFeeDetailPo) throws ParseException {
    private void hasDiscount(JSONObject paramObj, PayFeePo payFeePo, PayFeeDetailPo payFeeDetailPo,FeeDto feeDto) throws ParseException {
        if (!paramObj.containsKey("selectDiscount")) {
            return;
        }
        JSONArray selectDiscount = paramObj.getJSONArray("selectDiscount");
        JSONArray selectDiscounts = paramObj.getJSONArray("selectDiscount");
        if (selectDiscount == null || selectDiscount.size() < 1) {
        if (ListUtil.isNull(selectDiscounts)) {
            return;
        }
        for (int index = 0; index < selectDiscount.size(); index++) {
            JSONObject paramJson = selectDiscount.getJSONObject(index);
        Map feePriceMap = computeFeeSMOImpl.getFeePrice(feeDto);
        for (int index = 0; index < selectDiscounts.size(); index++) {
            JSONObject paramJson = selectDiscounts.getJSONObject(index);
            if (!"102020008".equals(paramJson.getString("ruleId"))) { //赠送规则
                continue;
            }
            JSONArray feeDiscountSpecs = paramJson.getJSONArray("feeDiscountSpecs");
            if (feeDiscountSpecs == null || feeDiscountSpecs.size() < 1) {
            if (ListUtil.isNull(feeDiscountSpecs)) {
                continue;
            }
            for (int specIndex = 0; specIndex < feeDiscountSpecs.size(); specIndex++) {
@@ -447,8 +439,18 @@
                cal.add(Calendar.MONTH, Integer.parseInt(specValue));
                payFeeDetailPo.setEndTime(df.format(cal.getTime()));
                payFeePo.setEndTime(df.format(cal.getTime()));
                BigDecimal value = new BigDecimal(payFeeDetailPo.getGiftAmount());
                value = value.add(new BigDecimal(specValue).multiply(new BigDecimal((double)feePriceMap.get("feePrice"))));
                payFeeDetailPo.setGiftAmount(value.doubleValue() + "");
            }
        }
        for (int discountIndex = 0; discountIndex < selectDiscounts.size(); discountIndex++) {
            JSONObject param = selectDiscounts.getJSONObject(discountIndex);
            addPayFeeDetailDiscount(paramObj, param, payFeeDetailPo);
        }
    }
    /**
@@ -663,7 +665,7 @@
     * @param paramInJson 接口调用放传入入参
     * @return 订单服务能够接受的报文
     */
    public void addPayFeeDetailDiscount(JSONObject paramInJson, JSONObject discountJson) {
    public void addPayFeeDetailDiscount(JSONObject paramInJson, JSONObject discountJson, PayFeeDetailPo payFeeDetailPo) {
        JSONObject businessFee = new JSONObject();
        businessFee.put("detailDiscountId", GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_detailDiscountId));
        businessFee.put("discountPrice", discountJson.getString("discountPrice"));
@@ -677,6 +679,32 @@
        if (fage < 1) {
            throw new CmdException("更新费用信息失败");
        }
        FeeDiscountDto feeDiscountDto = new FeeDiscountDto();
        feeDiscountDto.setDiscountId(discountJson.getString("discountId"));
        List<FeeDiscountDto> feeDiscountDtos = feeDiscountInnerServiceSMOImpl.queryFeeDiscounts(feeDiscountDto);
        if (ListUtil.isNull(feeDiscountDtos)) {
            return;
        }
        //todo 打折或者空置房打折
        if (FeeDiscountRuleDto.DISCOUNT_SMALL_TYPE_DISCOUNT.equals(feeDiscountDtos.get(0).getDiscountSmallType())
                || FeeDiscountRuleDto.DISCOUNT_SMALL_TYPE_APPLY_DISCOUNT.equals(feeDiscountDtos.get(0).getDiscountSmallType())
        ) {
            BigDecimal value = new BigDecimal(payFeeDetailPo.getDiscountAmount());
            value = value.add(new BigDecimal(discountJson.getString("discountPrice")));
            payFeeDetailPo.setDiscountAmount(value.doubleValue() + "");
        } else if (FeeDiscountRuleDto.DISCOUNT_SMALL_TYPE_DEDUCTION.equals(feeDiscountDtos.get(0).getDiscountSmallType())
                || FeeDiscountRuleDto.DISCOUNT_SMALL_TYPE_APPLY_DEDUCTION.equals(feeDiscountDtos.get(0).getDiscountSmallType())) {
            BigDecimal value = new BigDecimal(payFeeDetailPo.getDeductionAmount());
            value = value.add(new BigDecimal(discountJson.getString("discountPrice")));
            payFeeDetailPo.setDeductionAmount(value.doubleValue() + "");
        } else if (FeeDiscountRuleDto.DISCOUNT_SMALL_TYPE_LATE.equals(feeDiscountDtos.get(0).getDiscountSmallType())) {
            BigDecimal value = new BigDecimal(payFeeDetailPo.getLateAmount());
            value = value.add(new BigDecimal(discountJson.getString("discountPrice")));
            payFeeDetailPo.setLateAmount(value.doubleValue() + "");
        }
    }
@@ -698,14 +726,14 @@
        feeDto.setFeeId(paramInJson.getString("feeId"));
        feeDto.setCommunityId(paramInJson.getString("communityId"));
        List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
        if (feeDtos == null || feeDtos.size() != 1) {
            throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "查询费用信息失败,未查到数据或查到多条数据");
        if (ListUtil.isNull(feeDtos)) {
            throw new CmdException("查询费用信息失败,未查到数据或查到多条数据");
        }
        if (!businessFeeDetail.containsKey("state") || StringUtil.isEmpty(businessFeeDetail.getString("state"))) {
            businessFeeDetail.put("state", "1400");
        }
        feeDto = feeDtos.get(0);
        businessFeeDetail.put("startTime", DateUtil.getFormatTimeString(feeDto.getEndTime(), DateUtil.DATE_FORMATE_STRING_A));
        businessFeeDetail.put("startTime", DateUtil.getFormatTimeStringA(feeDto.getEndTime()));
        int hours = 0;
        Date targetEndTime = null;
        BigDecimal cycles = null;
@@ -793,7 +821,7 @@
            }
        }
        businessFeeDetail.put("endTime", DateUtil.getFormatTimeString(targetEndTime, DateUtil.DATE_FORMATE_STRING_A));
        businessFeeDetail.put("endTime", DateUtil.getFormatTimeStringA(targetEndTime));
        paramInJson.put("feeInfo", feeDto);
        return businessFeeDetail;
@@ -1059,6 +1087,11 @@
            return;
        }
        //todo 如果是同一天不创建
        if (DateUtil.getFormatTimeStringB(endTime).equals(reqJson.getString("customStartTime"))) {
            return;
        }
        FeeDto feeInfo = (FeeDto) reqJson.get("feeInfo");
        String payObjNameRemark = "房屋";
        if (FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeInfo.getPayerObjType())) {
@@ -1077,6 +1110,8 @@
        tmpPayFeeDetailPo.setStartTime(DateUtil.getFormatTimeStringB(endTime));
        tmpPayFeeDetailPo.setEndTime(reqJson.getString("customStartTime"));
        tmpPayFeeDetailPo.setState(FeeDetailDto.STATE_OWE);
        tmpPayFeeDetailPo.setOpenInvoice("N");
        tmpPayFeeDetailPo.setRemark("按缴费时间段缴费,这部分费用按欠费的方式重新生成,请在" + payObjNameRemark + "上查看");
        int flag = payFeeDetailNewV1InnerServiceSMOImpl.savePayFeeDetailNew(tmpPayFeeDetailPo);
@@ -1124,7 +1159,7 @@
            tmpFeeAttrPos.add(tmpFeeAttrPo);
        }
        //todo 没有结束时间时
        if(!hasDeadLineTime){
        if (!hasDeadLineTime) {
            tmpFeeAttrPo = new FeeAttrPo();
            tmpFeeAttrPo.setAttrId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_attrId, true));
            tmpFeeAttrPo.setFeeId(tmpPayFeePo.getFeeId());