package com.matrix.system.hive.service.imp; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import com.matrix.component.asyncmessage.AsyncMessageManager; import com.matrix.core.constance.MatrixConstance; import com.matrix.core.exception.GlobleException; import com.matrix.core.pojo.PaginationVO; import com.matrix.core.tools.LogUtil; import com.matrix.core.tools.WebUtil; import com.matrix.system.app.dto.OrderListDto; import com.matrix.system.app.vo.OrderDetailAchieveItemVo; import com.matrix.system.app.vo.OrderDetailItemVo; import com.matrix.system.app.vo.OrderDetailVo; import com.matrix.system.app.vo.RankingVo; import com.matrix.system.common.bean.BusParameterSettings; import com.matrix.system.common.bean.SysUsers; import com.matrix.system.common.constance.AppConstance; import com.matrix.system.common.dao.BusParameterSettingsDao; import com.matrix.system.common.dao.SysUsersDao; import com.matrix.system.common.service.OperationLogService; import com.matrix.system.constance.Dictionary; import com.matrix.system.enums.BooleanEnum; import com.matrix.system.enums.OperationButtonEnum; import com.matrix.system.enums.OperationFunctionEnum; import com.matrix.system.hive.bean.*; import com.matrix.system.hive.dao.*; import com.matrix.system.hive.dto.GoodsSealLimitDto; import com.matrix.system.hive.dto.MoneyCardOperationDto; import com.matrix.system.hive.dto.ProjUseOperationDto; import com.matrix.system.hive.dto.SysOrderItemDto; import com.matrix.system.hive.plugin.util.CollectionUtils; import com.matrix.system.hive.pojo.CzXkVo; import com.matrix.system.hive.service.*; import com.matrix.system.padApi.dto.PadOrderListDto; import com.matrix.system.padApi.vo.PadOrderDetailVo; import com.matrix.system.score.service.ScoreVipDetailService; import com.matrix.system.shopXcx.mqTask.AsyncMessageRouting; import com.matrix.system.wechart.templateMsg.UniformMsgParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * @date 2016-07-03 20:53 */ @Service("sysOrderService") public class SysOrderServiceImpl implements SysOrderService { @Autowired private SysOrderDao sysOrderDao; @Autowired private SysOrderItemDao orderItemDao; @Autowired private SysProjUseService sysProjUseService; @Autowired SysVipInfoDao sysVipInfoDao; @Autowired SysOutStoreService sysOutStoreService; @Autowired SysOutStoreItemDao sysOutStoreItemDao; @Autowired MoneyCardUseFlowDao moneyCardUseFlowDao; @Autowired ScoreVipDetailService scoreVipDetailService; @Autowired BusParameterSettingsDao busParameterSettingsDao; @Autowired SysVipLevelDao sysVipLevelDao; @Autowired ShoppingGoodsDao shoppingGoodsDao; @Autowired ShoppingGoodsAssembleDao shoppingGoodsAssembleDao; @Autowired MoneyCardUseDao moneyCardUseDao; @Autowired MoneyCardAssembleDao moneyCardAssembleDao; @Autowired SysUsersDao shopStaffInfoDao; @Autowired private AchieveNewService achieveNewService; @Autowired private AchieveNewDao achieveNewDao; @Autowired private ShoppingGoodsService shoppingGoodsService; @Autowired private SysOrderFlowDao sysOrderFlowDao; @Autowired BusParameterSettingsDao parameterSettingsDao; @Autowired private AsyncMessageManager asyncMessageManager; @Autowired private OperationLogService operationLogService; @Autowired private SysVipInfoService sysVipInfoService; @Autowired private SysOrderServiceHelper sysOrderServiceHelper; @Autowired MoneyCardUseService moneyCardUseService; //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓业务代码区↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ @Override @Transactional(rollbackFor = Exception.class) public SysOrder checkAndSaveOrder(SysOrder sysOrder) { if (Objects.isNull(sysOrder.getId())) { LogUtil.info("新增正向订单"); return sysOrderServiceHelper.saveOrder(sysOrder); } else { LogUtil.info("修改订单"); return sysOrderServiceHelper.modifyOrder(sysOrder); } } /** * 取消订单 * * @param id * @return */ @Override @Transactional(rollbackFor = Exception.class) public void cancelOrder(Long id) { SysOrder order = sysOrderDao.selectById(id); if (order.getStatu().equals(Dictionary.ORDER_STATU_DFK)) { //待付款订单取消 cancelDFKOrder(order); } else { //已付款订单取消 cancelYFKOrder(order); } } /** * 已付款订单取消 * * @param order */ private void cancelYFKOrder(SysOrder order) { SysUsers sysUsers = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); //一个订单只能被取消一次 if (Dictionary.ORDER_STATU_YQX.equals(order.getStatu())) { throw new GlobleException("订单已取消"); } //储值卡退款 sysOrderServiceHelper.returnMoneyCardPay(order); //套餐项目取消 List sysOrderItems = orderItemDao.selectByOrderId(order.getId()); for (SysOrderItem orderItem : sysOrderItems) { // 充值卡类型退款 if (Dictionary.SHOPPING_GOODS_TYPE_CZK.equals(orderItem.getType())) { //删除购买的充值卡 moneyCardUseService.deleteByOrderItemId(orderItem.getId()); } else if (Dictionary.SHOPPING_GOODS_TYPE_XM.equals(orderItem.getType()) || Dictionary.SHOPPING_GOODS_TYPE_TC.equals(orderItem.getType())) { // 项目套餐退款 // 删除套餐项目使用情况 sysProjUseService.deleteByOrderItemId(orderItem.getId()); } } //删除出库单,恢复库存 SysOutStore sysOutStore = new SysOutStore(); sysOutStore.setOrderId(order.getId()); List sysOutStores = sysOutStoreService.findByModel(sysOutStore); if (sysOutStores.size() == 1) { sysOutStore = sysOutStores.get(0); sysOutStoreService.cancelOutStore(sysOutStore.getId()); } // 删除业绩 achieveNewService.removeByOrderId(order.getId()); // 删除收款记录 sysOrderFlowDao.deleteByOrderId(order.getId()); //删除积分 scoreVipDetailService.removeByBusinessId(order.getVipId(), order.getId()); // 取消订单 order.setStatu(Dictionary.ORDER_STATU_YQX); sysOrderDao.update(order); //保存单据日志 operationLogService.saveOperation(order.getCompanyId(), order.getShopId(), sysUsers.getSuId(), OperationFunctionEnum.ORDER, OperationButtonEnum.CANCEL, order.getId(), order.getOrderNo(), order.getVipId(), "已付款取消订单"); } /** * 待付款订单取消 * * @param order */ private void cancelDFKOrder(SysOrder order) { SysUsers sysUsers = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); order.setStatu(Dictionary.ORDER_STATU_YQX); order.setArrears(0D); //发送微信公众号提醒 UniformMsgParam uniformMsgParam = new UniformMsgParam(order.getCompanyId(), UniformMsgParam.GZH_DDQX); uniformMsgParam.put("orderId", order.getId()); asyncMessageManager.sendMsg(AsyncMessageRouting.SEND_UNIFORM_TEMPLATE_MSG, uniformMsgParam); sysOrderDao.update(order); //保存单据日志 operationLogService.saveOperation(order.getCompanyId(), order.getShopId(), sysUsers.getSuId(), OperationFunctionEnum.ORDER, OperationButtonEnum.CANCEL, order.getId(), order.getOrderNo(), order.getVipId(), "未付款取消订单"); } /** * jyy 收款 */ @Override @Transactional(rollbackFor = Exception.class) public void payOrder(SysOrder pageOrder) throws GlobleException { //校验订单是否满足收款条件 checkOrderAblePay(pageOrder); // 更新订单主表信息 payEndUpdateOrderInfo(pageOrder); //添加支付流水 sysOrderServiceHelper.addOrderFlow(pageOrder, false); //扣除储值卡余额 sysOrderServiceHelper.cardPaySk(pageOrder); // 设置会员充值卡使用情况 sysOrderServiceHelper.addMoneyCardUse(pageOrder); // 改变客户项目套餐使用情况 sysOrderServiceHelper.addTaocanProj(pageOrder); // 新增出库单 sysOrderServiceHelper.addOutStore(pageOrder); // 设置业绩 achieveNewService.addAchaeveByOrder(pageOrder); //设置会员积分 sysOrderServiceHelper.addVipScore(pageOrder); //保存订单收款日志 saveOrderSkLog(pageOrder); } /** * 保存订单收款日志 * * @param pageOrder */ private void saveOrderSkLog(SysOrder pageOrder) { SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); operationLogService.saveOperation(pageOrder.getCompanyId(), pageOrder.getShopId(), user.getSuId(), OperationFunctionEnum.ORDER, OperationButtonEnum.ORDER_SK, pageOrder.getId(), pageOrder.getOrderNo(), pageOrder.getVipId()); } /** * 付款后更新订单信息 * * @param pageOrder */ private void payEndUpdateOrderInfo(SysOrder pageOrder) { LogUtil.info("付款更新订单信息 id={}", pageOrder.getId()); SysUsers user = (SysUsers) WebUtil.getSession().getAttribute(MatrixConstance.LOGIN_KEY); pageOrder.setCashierId(user.getSuId()); pageOrder.setPayTime(new Date()); pageOrder.setStatu(Dictionary.ORDER_STATU_YFK); List flows = pageOrder.getFlows(); BigDecimal cashPayAmount = flows.stream() .filter(item -> (!item.getPayMethod().equals("储值卡")) && (!item.getPayMethod().equals("欠款"))) .map(SysOrderFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal cardPayAmount = flows.stream() .filter(item -> item.getPayMethod().equals("储值卡")) .map(SysOrderFlow::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); pageOrder.setCardPay(cardPayAmount.doubleValue()); pageOrder.setCashPay(cashPayAmount.doubleValue()); for (SysOrderFlow flow : pageOrder.getFlows()) { //欠款处理 if (SysOrderFlow.PAY_METHOD_ARREARS.equals(flow.getPayMethod())) { pageOrder.setStatu(Dictionary.ORDER_STATU_QK); pageOrder.setArrears(flow.getAmount().doubleValue()); } } double sum = flows.stream().mapToDouble(item -> item.getAmount().doubleValue()).sum(); if (sum > 0 && cardPayAmount.doubleValue() == 0 && cashPayAmount.doubleValue() == 0 && pageOrder.getArrears() == 0) { throw new GlobleException("订单更新失败,支付金额计算错误,请联系管理员"); } sysOrderDao.update(pageOrder); // 设置用户为成交客户 sysVipInfoService.updateDealStatus(pageOrder.getVipId(), BooleanEnum.TRUE.getValue()); } /** * 检查订单是否满足支付条件 * * @param pageOrder */ private void checkOrderAblePay(SysOrder pageOrder) { SysOrder checkOrder = sysOrderDao.selectById(pageOrder.getId()); //状态校验 if (!Dictionary.ORDER_STATU_DFK.equals(checkOrder.getStatu())) { throw new GlobleException("该订单已经收过款,请刷新页面再试!"); } //检查交易限制调整 GoodsSealLimitDto goodsSealLimitDto = new GoodsSealLimitDto(); goodsSealLimitDto.setVipId(pageOrder.getVipId()); goodsSealLimitDto.setSysOrderItemDtoList(Lists.newArrayList()); pageOrder.getItems().forEach(e -> { goodsSealLimitDto.getSysOrderItemDtoList().add(BeanUtil.copyProperties(e, SysOrderItemDto.class)); }); shoppingGoodsService.checkGoodsSealLimit(goodsSealLimitDto); //检查业绩设置 checkOrderAchieve(pageOrder); LogUtil.info("订单满足支付条件 id={}", pageOrder.getId()); } /** * 检查业绩设置是否合理 * 1、每个订单明细都要有至少一个对应的业绩 * 2、每个订单明细的同类型业绩金额之和不能大于明细支付金额 * * @param pageOrder */ private void checkOrderAchieve(SysOrder pageOrder) { pageOrder.getItems().forEach(item -> { if (CollectionUtil.isEmpty(item.getAchieveList())) { ShoppingGoods shopGoods = shoppingGoodsDao.selectById(item.getGoodsId()); throw GlobleException.instance(shopGoods.getName() + "缺少设置业绩"); } //按业绩类型分组后比较支付金额与业绩金额是否相等 Map> achieveTypeMap = item.getAchieveList().stream().collect(Collectors.groupingBy(AchieveNew::getAchieveType)); Set>> entries = achieveTypeMap.entrySet(); entries.forEach(entrie -> { double sum = entrie.getValue().stream().mapToDouble(AchieveNew::getGoodsCash).sum(); //todo 目前使用js计算金额可能存在精度的误差展示用0.1屏蔽 if (Math.abs(sum - (item.getZkPrice() * item.getCount())) > 0.1) { ShoppingGoods shopGoods = shoppingGoodsDao.selectById(item.getGoodsId()); throw GlobleException.instance(shopGoods.getName() + "," + entrie.getKey() + "业绩金额与收款金额不一致"); } }); }); } /** * 补交 * * @author:姜友瑶 * @date 2016年9月19日 */ @Transactional(rollbackFor = Exception.class) @Override public void updateAfterMoney(SysOrder pageOrder) { SysOrder sourceOrder = sysOrderDao.selectById(pageOrder.getId()); //添加支付流水 sysOrderServiceHelper.addOrderFlow(pageOrder, true); //扣除储值卡余额 sysOrderServiceHelper.cardPaySk(pageOrder); double refundTotal = 0D; double cardPayTotal = 0D; double cashPayTotal = 0D; for (SysOrderFlow flow : pageOrder.getFlows()) { // 若使用储值卡付款 if (SysOrderFlow.PAY_METHOD_CARD.equals(flow.getPayMethod())) { cardPayTotal += flow.getAmount().doubleValue(); } else { cashPayTotal += flow.getAmount().doubleValue(); } refundTotal += flow.getAmount().doubleValue(); } if (refundTotal == pageOrder.getArrears()) { sourceOrder.setStatu(Dictionary.ORDER_STATU_YFK); } else { sourceOrder.setStatu(Dictionary.ORDER_STATU_QK); } sourceOrder.setArrears(sourceOrder.getArrears() - refundTotal); sourceOrder.setCardPay(sourceOrder.getCardPay() == null ? 0 : sourceOrder.getCardPay() + cardPayTotal); sourceOrder.setCashPay(sourceOrder.getCashPay() == null ? 0 : sourceOrder.getCashPay() + cashPayTotal); sysOrderDao.update(sourceOrder); } /** * 会员卡充值 * * @param czVo */ @Override @Transactional(rollbackFor = Exception.class) public SysOrder moneyCardCz(CzXkVo czVo) { // 新增一个充值订单 SysOrder order = sysOrderServiceHelper.createCzOrder(czVo); //新增会员卡金额 MoneyCardUse cardUser = moneyCardUseDao.selectVipCard(czVo.getVipId()); MoneyCardOperationDto moneyCardOperationDto = new MoneyCardOperationDto(); moneyCardOperationDto.setRealMoney(czVo.getBjmoney()); moneyCardOperationDto.setGiftMoney(czVo.getGiftMoney()); moneyCardOperationDto.setCarUseId(cardUser.getId()); moneyCardOperationDto.setOrderId(order.getId()); moneyCardOperationDto.setOrderNo(order.getOrderNo()); moneyCardOperationDto.setType(MoneyCardUseFlow.USE_TYPE_CZ); SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); moneyCardOperationDto.setUpdateUser(user.getSuId()); moneyCardUseService.changeMoneyCard(Arrays.asList(moneyCardOperationDto)); // 更新订单主表信息 payEndUpdateOrderInfo(order); //添加支付流水 sysOrderServiceHelper.addOrderFlow(order, false); // 设置业绩 achieveNewService.addAchaeveByOrder(order); //设置会员积分 sysOrderServiceHelper.addVipScore(order); return order; } @Override public SysOrder findSysOrderTjByVipId(Long vipId) { return sysOrderDao.selectVipOrderInfoTotal(vipId); } @Override public List findApiOrderListInPage(OrderListDto orderListDto, PaginationVO pageVo) { return sysOrderDao.selectApiOrderListInPage(orderListDto, pageVo); } @Override public List findPadApiOrderListInPage(PadOrderListDto orderListDto, PaginationVO pageVo) { List padOrderDetailVos = sysOrderDao.selectPadApiOrderListInPage(orderListDto, pageVo); if(CollUtil.isNotEmpty(padOrderDetailVos)){ for(PadOrderDetailVo padOrderDetailVo : padOrderDetailVos){ padOrderDetailVo.setItems(orderItemDao.selectApiOrderDetailItemsByOrderId(Long.parseLong(padOrderDetailVo.getOrderId()))); } } return padOrderDetailVos; } @Override public int findApiOrderListTotal(OrderListDto orderListDto) { return sysOrderDao.selectApiOrderListTotal(orderListDto); } @Override public int findPadApiOrderListTotal(PadOrderListDto orderListDto) { return sysOrderDao.selectPadApiOrderListTotal(orderListDto); } @Override public OrderDetailVo findApiOrderDetailByOrderId(Long orderId) { OrderDetailVo orderDetail = sysOrderDao.selectApiOrderDetailById(orderId); if (orderDetail == null) { throw new GlobleException("该订单不存在"); } List items = orderItemDao.selectApiOrderDetailItemsByOrderId(orderId); if (CollectionUtils.isNotEmpty(items)) { for (OrderDetailItemVo item : items) { List achieveItems = achieveNewDao.selectApiOrderItemAchieve(item.getId()); item.setAchieves(achieveItems); } } orderDetail.setItems(items); return orderDetail; } @Override public List findApiShopAchieveRanking(SysOrder sysOrder) { return sysOrderDao.selectShopAchieveRanking(sysOrder); } @Transactional(rollbackFor = Exception.class) @Override public void orderTk(SysOrder sysOrder) { //创建并保存退款订单 sysOrder = sysOrderServiceHelper.createTkOrder(sysOrder); // 添加订单收款流水 sysOrderServiceHelper.addOrderFlow(sysOrder, false); //退款退套餐退项目 refundProjUse(sysOrder); //删除积分 SysOrder oldOrder = sysOrderDao.selectById(sysOrder.getOldOrderId()); scoreVipDetailService.removeByBusinessId(oldOrder.getVipId(), oldOrder.getId()); // 设置业绩 achieveNewService.addAchaeveByOrder(sysOrder); SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); //保存单据日志 operationLogService.saveOperation(sysOrder.getCompanyId(), sysOrder.getShopId(), user.getSuId(), OperationFunctionEnum.ORDER, OperationButtonEnum.ORDER_TK, sysOrder.getId(), sysOrder.getOrderNo(), sysOrder.getVipId()); } /** * 退款退项目,套餐,卡项 * * @param sysOrder */ private void refundProjUse(SysOrder sysOrder) { SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); //记录需要退库存的产品 List returnGoodsList = new ArrayList<>(); //需要退的套餐和项目 List projUseDtoList = Lists.newArrayList(); //需要退的储值卡 List moneyCardOperationDtos = Lists.newArrayList(); for (SysOrderItem item : sysOrder.getItems()) { if (Dictionary.SHOPPING_GOODS_TYPE_JJCP.equals(item.getType()) && Dictionary.FLAG_YES_Y.equals(item.getIsReturnStore())) { returnGoodsList.add(item); } else if (Dictionary.SHOPPING_GOODS_TYPE_TC.equals(item.getType()) || Dictionary.SHOPPING_GOODS_TYPE_XM.equals(item.getType())) { ProjUseOperationDto dto = new ProjUseOperationDto(); dto.setGoodsId(item.getGoodsId()); dto.setCount(item.getRefundCount()); dto.setOrderItemId(item.getOldItemId()); dto.setUpdateUserId(user.getSuId()); projUseDtoList.add(dto); }else if (Dictionary.SHOPPING_GOODS_TYPE_CZK.equals(item.getType())) { MoneyCardOperationDto moneyCardOperationDto = new MoneyCardOperationDto(); moneyCardOperationDto.setOrderId(sysOrder.getId()); moneyCardOperationDto.setOrderNo(sysOrder.getOrderNo()); moneyCardOperationDto.setOrderItemId(item.getOldItemId()); moneyCardOperationDto.setType(MoneyCardUseFlow.USE_TYPE_ORDRE_TK); moneyCardOperationDto.setUpdateUser(user.getSuId()); moneyCardOperationDto.setOrderNo(sysOrder.getOrderNo()); moneyCardOperationDto.setRealMoney(item.getZkPrice()); moneyCardOperationDtos.add(moneyCardOperationDto); } } BusParameterSettings manageStockSetting = busParameterSettingsDao.selectCompanyParamByCode(AppConstance.WAREHOUSE_MANAGE_STOCK, sysOrder.getCompanyId()); // if (AppConstance.IS_Y.equals(manageStockSetting.getParamValue())) { if (BooleanEnum.TRUE.getValue() == manageStockSetting.getIntParamValue()) { // 家居产品退库存 if (CollectionUtils.isNotEmpty(returnGoodsList)) { LogUtil.info("订单退款:退产品库存:{}", JSON.toJSONString(returnGoodsList)); sysOrderServiceHelper.refundInstore(returnGoodsList); } } if(CollUtil.isNotEmpty(projUseDtoList)){ LogUtil.info("订单退款:退套餐项目:{}", JSON.toJSONString(projUseDtoList)); sysProjUseService.projectTk(projUseDtoList); } if(CollUtil.isNotEmpty(moneyCardOperationDtos)){ LogUtil.info("订单退款:储值卡:{}", JSON.toJSONString(moneyCardOperationDtos)); moneyCardUseService.moneyCardTk(moneyCardOperationDtos); } } @Override public BigDecimal findVipArrearsByVipId(Long vipId) { return sysOrderDao.selectArrearsByVipId(vipId); } //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓===增删改查代码区↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ @Override public int add(SysOrder sysOrder) { return sysOrderDao.insert(sysOrder); } @Override public int modify(SysOrder sysOrder) { return sysOrderDao.update(sysOrder); } @Override public int remove(List list) { return sysOrderDao.deleteByIds(list); } @Override @Transactional public int removeById(Long id) { orderItemDao.deleteByOrderId(id); return sysOrderDao.deleteById(id); } @Override public List findInPage(SysOrder sysOrder, PaginationVO pageVo) { if (pageVo != null) { pageVo.setSort("desc"); pageVo.setSort("orderTime"); } return sysOrderDao.selectInPage(sysOrder, pageVo); } @Override public List findByModel(SysOrder sysOrder) { return sysOrderDao.selectByModel(sysOrder); } @Override public int findTotal(SysOrder sysOrder) { return sysOrderDao.selectInPageCount(sysOrder); } @Override public SysOrder findById(Long id) { return sysOrderDao.selectById(id); } }