| package com.mzl.flower.service.payment; | 
|   | 
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 
| import com.mzl.flower.base.interceptor.CodeDecorator; | 
| import com.mzl.flower.component.SequenceNo; | 
| import com.mzl.flower.config.exception.ValidationException; | 
| import com.mzl.flower.config.security.SecurityUtils; | 
| import com.mzl.flower.constant.Constants; | 
| import com.mzl.flower.dto.request.payment.*; | 
| import com.mzl.flower.dto.response.payment.OrderItemSalesNewDTO; | 
| import com.mzl.flower.dto.response.payment.OrderItemSalesNewListDTO; | 
| import com.mzl.flower.dto.response.payment.OrderStatusCountDTO; | 
| import com.mzl.flower.dto.response.system.CodeValueDTO; | 
| import com.mzl.flower.entity.payment.*; | 
| import com.mzl.flower.entity.supplier.Station; | 
| import com.mzl.flower.mapper.payment.*; | 
| import com.mzl.flower.mapper.supplier.StationMapper; | 
| import com.mzl.flower.service.BaseService; | 
| import com.mzl.flower.service.system.CodeService; | 
| import com.mzl.flower.utils.ExcelExportUtil; | 
| import com.mzl.flower.utils.UUIDGenerator; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.springframework.beans.BeanUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Service; | 
| import org.springframework.transaction.annotation.Transactional; | 
|   | 
| import javax.servlet.http.HttpServletResponse; | 
| import java.math.BigDecimal; | 
| import java.net.URLEncoder; | 
| import java.time.LocalDateTime; | 
| import java.util.ArrayList; | 
| import java.util.HashMap; | 
| import java.util.List; | 
| import java.util.Map; | 
|   | 
| @Slf4j | 
| @Service | 
| @Transactional | 
| public class OrderItemSalesService extends BaseService { | 
|   | 
|     @Autowired | 
|     private OrderItemSalesMapper orderItemSalesMapper; | 
|   | 
|     @Autowired | 
|     private OrderMapper orderMapper; | 
|   | 
|     @Autowired | 
|     private OrderItemMapper orderItemMapper; | 
|   | 
|     @Autowired | 
|     private UserPaymentV3Service paymentV3Service; | 
|   | 
|     @Autowired | 
|     private SequenceNo sequenceNo; | 
|   | 
|     @Autowired | 
|     private StationMapper stationMapper; | 
|   | 
|     @Autowired | 
|     private CodeService codeService; | 
|   | 
|     @Autowired | 
|     private CodeDecorator codeDecorator; | 
|   | 
|     @Autowired | 
|     private OrderItemCheckMapper orderItemCheckMapper; | 
|   | 
|     @Autowired | 
|     private DeliveryOrderService deliveryOrderService; | 
|   | 
|     public String createSales(OrderItemSalesCreateDTO dto){ | 
|         Integer num = dto.getNum(); | 
|         if(num == null || num == 0){ | 
|             throw new ValidationException("申请数量不能为空"); | 
|         } | 
|   | 
|         OrderItem oi = orderItemMapper.selectById(dto.getOrderItemId()); | 
|         if(oi == null){ | 
|             throw new ValidationException("订单商品不存在"); | 
|         } | 
|   | 
|         OrderItemCheck c = orderItemCheckMapper.selectOne(new QueryWrapper<OrderItemCheck>() | 
|                 .eq("order_item_id", oi.getId()) | 
|                 .eq("type", Constants.CHECK_TYPE.lack.name()) | 
|                 .eq("audit_status", Constants.CHECK_AUDIT_STATUS.AGREED.name()) | 
|         ); | 
|         int totalNum = oi.getNum(); | 
|         if(c != null){//需要减去缺货的数量 | 
|             totalNum -= c.getNum(); | 
|         } | 
|         if(num > totalNum){ | 
|             throw new ValidationException("申请数量不能超过总数"); | 
|         } | 
|   | 
|         //收货前可以申请售后,售后最多申请两次 | 
|         Order o = orderMapper.selectById(oi.getOrderId()); | 
|         String status = o.getStatus(); | 
|         if(!Constants.ORDER_STATUS.RECEIVE.name().equals(status)){ | 
|             throw new ValidationException("无法申请售后"); | 
|         } | 
|   | 
|         String userId = SecurityUtils.getUserId(); | 
|         int count = orderItemSalesMapper.selectCount(new QueryWrapper<OrderItemSales>() | 
|                 .eq("order_item_id", oi.getId()) | 
|                 .eq("status", Constants.ORDER_SALES_STATUS.AGREED.name()) | 
|         ); | 
|         if(count >= 2){ | 
|             throw new ValidationException("售后申请超过限额"); | 
|         } | 
|   | 
|         String title = count > 0 ? "第二次售后" : ""; | 
|   | 
|         count = orderItemSalesMapper.selectCount(new QueryWrapper<OrderItemSales>() | 
|                 .eq("order_item_id", oi.getId()) | 
|                 .eq("status", Constants.ORDER_SALES_STATUS.PENDING.name()) | 
|         ); | 
|         if(count > 0){ | 
|             throw new ValidationException("有未处理售后,无法申请"); | 
|         } | 
|   | 
|         OrderItemSales s = new OrderItemSales(); | 
|         s.setId(UUIDGenerator.getUUID()); | 
|         s.setOrderId(oi.getOrderId()); | 
|         s.setOrderItemId(oi.getId()); | 
|         s.setSalesNo(getSalesNo()); | 
|         s.setNum(num); | 
|         s.setTitle(title); | 
|         s.setPictures(toJSONString(dto.getPictureList())); | 
|         s.setVideos(toJSONString(dto.getVideoList())); | 
|         s.setReason(dto.getReason()); | 
|         s.setStatus(Constants.ORDER_SALES_STATUS.PENDING.name()); | 
|         s.create(userId); | 
|         s.setSalesType(dto.getSalesType()); | 
|         orderItemSalesMapper.insert(s); | 
|   | 
|         return s.getId(); | 
|     } | 
|   | 
|     private String getSalesNo(){ | 
|         String seq  = sequenceNo.getSeqNo(SequenceNo.ORDER_ITEM_SALES); | 
|         return "SH" + format(LocalDateTime.now(), "yyyyMMdd") + seq; | 
|     } | 
|   | 
|     public void cancelSales(String id){ | 
|         OrderItemSales s = orderItemSalesMapper.selectById(id); | 
|         String userId = SecurityUtils.getUserId(); | 
|         if(!userId.equals(s.getCreateBy())){ | 
|             throw new ValidationException("无权操作"); | 
|         } | 
|   | 
|         String status = s.getStatus(); | 
|         if(!Constants.SALES_STATUS.PENDING.name().equals(status)){ | 
|             throw new ValidationException("已处理完成不用取消"); | 
|         } | 
|   | 
|         s.setStatus(Constants.SALES_STATUS.CANCEL.name()); | 
|         s.update(userId); | 
|         orderItemSalesMapper.updateById(s); | 
|     } | 
|   | 
|     public List<OrderStatusCountDTO> getSalesStatusCount(OrderItemSalesQueryDTO dto) { | 
|         dto.setOrderStartDate(parseLocalDateTime(dto.getOrderStartDateStr(), true)); | 
|         dto.setOrderEndDate(parseLocalDateTime(dto.getOrderEndDateStr(), false)); | 
|         dto.setSalesStartDate(parseLocalDateTime(dto.getSalesStartDateStr(), true)); | 
|         dto.setSalesEndDate(parseLocalDateTime(dto.getSalesEndDateStr(), false)); | 
|   | 
|         List<CodeValueDTO> ls = codeService.searchValue("ORDER_SALES_STATUS"); | 
|         List<OrderStatusCountDTO> ll = orderItemSalesMapper.getSalesStatusCount(dto); | 
|         Map<String, Integer> llMap = new HashMap<>(); | 
|         if (ll != null && ll.size() > 0) { | 
|             for (OrderStatusCountDTO c : ll) { | 
|                 llMap.put(c.getValue(), c.getOrderCount()); | 
|             } | 
|         } | 
|   | 
|         List<OrderStatusCountDTO> rr = new ArrayList<>(); | 
|         for (CodeValueDTO c : ls) { | 
|             OrderStatusCountDTO r = new OrderStatusCountDTO(); | 
|             r.setValue(c.getValue()); | 
|             r.setLabel(c.getLabel()); | 
|             Integer count = llMap.get(r.getValue()); | 
|             r.setOrderCount(count == null ? 0 : count); | 
|   | 
|             rr.add(r); | 
|         } | 
|   | 
|         return rr; | 
|     } | 
|   | 
|     public Page<OrderItemSalesNewListDTO> selectSalesList(Page page, OrderItemSalesQueryDTO dto){ | 
|         dto.setOrderStartDate(parseLocalDateTime(dto.getOrderStartDateStr(), true)); | 
|         dto.setOrderEndDate(parseLocalDateTime(dto.getOrderEndDateStr(), false)); | 
|         dto.setSalesStartDate(parseLocalDateTime(dto.getSalesStartDateStr(), true)); | 
|         dto.setSalesEndDate(parseLocalDateTime(dto.getSalesEndDateStr(), false)); | 
|   | 
|         List<OrderItemSalesNewListDTO> ls = orderItemSalesMapper.selectItemSalesList(page, dto); | 
|   | 
|         page.setRecords(ls); | 
|         return page; | 
|     } | 
|   | 
|     public void exportSalesList(HttpServletResponse response, OrderItemSalesQueryDTO dto){ | 
|         dto.setOrderStartDate(parseLocalDateTime(dto.getOrderStartDateStr(), true)); | 
|         dto.setOrderEndDate(parseLocalDateTime(dto.getOrderEndDateStr(), false)); | 
|         dto.setSalesStartDate(parseLocalDateTime(dto.getSalesStartDateStr(), true)); | 
|         dto.setSalesEndDate(parseLocalDateTime(dto.getSalesEndDateStr(), false)); | 
|   | 
|         List<OrderItemSalesNewListDTO> ls = orderItemSalesMapper.selectItemSalesList(null, dto); | 
|         codeDecorator.decorate(ls); | 
|   | 
|         String[] rowsName = new String[]{"序号", "集货站", "商品名称", "商品单位", "商品颜色", "商品等级" | 
|                 , "商品分类", "收货人", "收货人手机号码", "收货地址", "商品数量", "供应商名称", "商品售价" | 
|                 , "总金额", "订单号", "售后单号", "标题", "申请数量", "理由", "实际退款", "审核结果" | 
|                 , "申请时间", "平台回复"}; | 
|         List<Object[]> dataList = new ArrayList<>(); | 
|   | 
|         int sn = 1; | 
|         for (OrderItemSalesNewListDTO d : ls) { | 
|             Object[] objs = new Object[rowsName.length]; | 
|             int a = 0; | 
|             objs[a++] = sn; | 
|             objs[a++] = d.getStationName(); | 
|             objs[a++] = d.getFlowerName(); | 
|             objs[a++] = d.getFlowerUnit(); | 
|             objs[a++] = d.getFlowerColor(); | 
|             objs[a++] = d.getFlowerLevelStr(); | 
|             objs[a++] = d.getFlowerCategory(); | 
|             objs[a++] = d.getCustomer(); | 
|             objs[a++] = d.getCustomerTel(); | 
|             objs[a++] = d.getCustomerProvince() + d.getCustomerCity() + d.getCustomerRegion() + d.getCustomerAddress(); | 
|             objs[a++] = d.getFlowerNum(); | 
|             objs[a++] = d.getSupplierName(); | 
|             objs[a++] = d.getPrice(); | 
|             objs[a++] = d.getTotal(); | 
|             objs[a++] = d.getOrderNo(); | 
|             objs[a++] = d.getSalesNo(); | 
|             objs[a++] = d.getTitle(); | 
|             objs[a++] = d.getNum(); | 
|             objs[a++] = d.getReason(); | 
|             objs[a++] = d.getTotalFee(); | 
|             objs[a++] = d.getStatusStr(); | 
|             objs[a++] = format(d.getCreateTime(), "yyyy-MM-dd HH:mm:ss"); | 
|             objs[a++] = d.getRemarks(); | 
|   | 
|             dataList.add(objs); | 
|   | 
|             sn++; | 
|         } | 
|   | 
|         ExcelExportUtil excelExportUtil = new ExcelExportUtil("售后申请列表", rowsName, dataList, response); | 
|         try { | 
|             response.addHeader("filename", URLEncoder.encode("售后申请列表.xls", "UTF-8")); | 
|             response.addHeader("Access-Control-Expose-Headers", "filename"); | 
|             excelExportUtil.export(); | 
|         } catch (Exception e) { | 
|             log.error(e.getMessage(), e); | 
|         } | 
|     } | 
|   | 
|     public OrderItemSalesNewDTO getSalesInfo(String id){ | 
|         OrderItemSalesNewDTO rr = new OrderItemSalesNewDTO(); | 
|         OrderItemSales sl = orderItemSalesMapper.selectById(id); | 
|         if(sl == null){ | 
|             throw new ValidationException("售后单不存在"); | 
|         } | 
|   | 
|         BeanUtils.copyProperties(sl, rr); | 
|         rr.setPictureList(parseArray(sl.getPictures(), String.class)); | 
|         rr.setVideoList(parseArray(sl.getVideos(), String.class)); | 
|   | 
|         Order o = orderMapper.selectById(sl.getOrderId()); | 
|         rr.setOrderNo(o.getOrderNo()); | 
|         rr.setCustomer(o.getCustomer()); | 
|         rr.setCustomerTel(o.getCustomerTel()); | 
|         rr.setCustomerProvince(o.getCustomerProvince()); | 
|         rr.setCustomerCity(o.getCustomerCity()); | 
|         rr.setCustomerRegion(o.getCustomerRegion()); | 
|         rr.setCustomerAddress(o.getCustomerAddress()); | 
|         rr.setOrderTime(o.getCreateTime()); | 
|   | 
|         OrderItem oi = orderItemMapper.selectById(sl.getOrderItemId()); | 
|         rr.setFlowerName(oi.getFlowerName()); | 
|         rr.setFlowerUnit(oi.getFlowerUnit()); | 
|         rr.setFlowerColor(oi.getFlowerColor()); | 
|         rr.setFlowerCover(oi.getFlowerCover()); | 
|         rr.setFlowerLevel(oi.getFlowerLevel()); | 
|         rr.setFlowerCategory(oi.getFlowerCategory()); | 
|         rr.setFlowerNum(oi.getNum()); | 
|         rr.setSupplierName(oi.getSupplierName()); | 
|         rr.setPrice(oi.getPrice()); | 
|         rr.setTotal(oi.getTotal()); | 
|         rr.setSupplierPrice(oi.getSupplierPrice()); | 
|         rr.setMarkupPartner(oi.getMarkupPartner()); | 
|         rr.setRealPrice(oi.getRealPrice()); | 
|         rr.setRealTotal(oi.getRealTotal()); | 
|   | 
|         Long stationId = oi.getStationId(); | 
|         if(stationId != null) { | 
|             Station s = stationMapper.selectById(oi.getStationId()); | 
|             rr.setStationName(s.getName()); | 
|         } | 
|   | 
|         List<OrderItemCheck> cLs = orderItemCheckMapper.selectList(new QueryWrapper<OrderItemCheck>() | 
|                 .eq("order_item_id", oi.getId()) | 
|                 .eq("audit_status", Constants.CHECK_AUDIT_STATUS.AGREED.name()) | 
|         ); | 
|         int reduceNum = 0; | 
|         BigDecimal reduceAmount = new BigDecimal(0); | 
|         int replaceNum = 0; | 
|         if(cLs != null && cLs.size() > 0){ | 
|             for(OrderItemCheck c : cLs){ | 
|                 if(Constants.CHECK_TYPE.reduce.name().equals(c.getType())){ | 
|                     reduceNum += c.getNum(); | 
|                     reduceAmount = reduceAmount.add(c.getDeductAmount()); | 
|                 } else if(Constants.CHECK_TYPE.replace.name().equals(c.getType())){ | 
|                     replaceNum += c.getNum(); | 
|                 } | 
|             } | 
|         } | 
|         rr.setReduceNum(reduceNum); | 
|         rr.setReduceAmount(reduceAmount); | 
|         rr.setReplaceNum(replaceNum); | 
|   | 
|         return rr; | 
|     } | 
|   | 
|     public OrderItem doAudit(OrderItemSalesAuditDTO dto, String status){ | 
|         OrderItemSales sl = orderItemSalesMapper.selectById(dto.getId()); | 
|         if(sl == null){ | 
|             throw new ValidationException("售后单不存在"); | 
|         } | 
|         if(!Constants.ORDER_SALES_STATUS.PENDING.name().equals(sl.getStatus())){ | 
|             throw new ValidationException("不可操作"); | 
|         } | 
|   | 
|         OrderItem oi = orderItemMapper.selectById(sl.getOrderItemId()); | 
|         if(oi == null){ | 
|             throw new ValidationException("订单商品不存在"); | 
|         } | 
|   | 
|         BigDecimal feeSupplier = getAmount(dto.getFeeSupplier()); | 
|         BigDecimal supplierTotal = oi.getSupplierPrice().multiply(new BigDecimal(sl.getNum())); | 
|         if(feeSupplier.doubleValue() > supplierTotal.doubleValue()){ | 
|             throw new ValidationException("供应商扣款金额不能大于商品申请数量的供应商售价"); | 
|         } | 
|   | 
|         BigDecimal feePartner = getAmount(dto.getFeePartner()); | 
|         BigDecimal feePlatform = getAmount(dto.getFeePlatform()); | 
|         BigDecimal feePlatformPack = getAmount(dto.getFeePlatformPack()); | 
|         BigDecimal feePlatformCheck = getAmount(dto.getFeePlatformCheck()); | 
|         BigDecimal feePlatformTransport = getAmount(dto.getFeePlatformTransport()); | 
|   | 
|         BigDecimal totalFee = feeSupplier.add(feePartner).add(feePlatform).add(feePlatformPack) | 
|                 .add(feePlatformCheck).add(feePlatformTransport); | 
|   | 
|         BigDecimal st = oi.getRealPrice().multiply(new BigDecimal(sl.getNum()));//申请售后的花的金额,使用券后的单价 | 
|         if(totalFee.doubleValue() > st.doubleValue()){ | 
|             throw new ValidationException("退款金额不能大于商品申请数量的售价"); | 
|         } | 
|   | 
|         List<OrderItemSales> ls = orderItemSalesMapper.selectList(new QueryWrapper<OrderItemSales>() | 
|                 .eq("order_item_id", oi.getId()) | 
|                 .eq("status", Constants.ORDER_SALES_STATUS.AGREED.name()) | 
|         ); | 
|         BigDecimal preFee = new BigDecimal(0); | 
|         if(ls != null && ls.size() > 0){ | 
|             for(OrderItemSales s : ls){ | 
|                 preFee = preFee.add(s.getTotalFee()); | 
|             } | 
|         } | 
|         preFee = preFee.add(totalFee); | 
|         if(preFee.doubleValue() > oi.getRealTotal().doubleValue()){//使用券后的总价 | 
|             throw new ValidationException("退款总金额不能大于商品总价"); | 
|         } | 
|   | 
|         BigDecimal deduct = deliveryOrderService.calculateOrderItemDeduct(sl.getOrderItemId());//质检已扣款金额 | 
|         preFee = preFee.add(deduct); | 
|         if(preFee.doubleValue() > oi.getRealTotal().doubleValue()){ | 
|             throw new ValidationException("退款总金额(包含质检退款)不能大于商品总价"); | 
|         } | 
|   | 
|         sl.setRemarks(dto.getRemarks()); | 
|         sl.setFeeSupplier(feeSupplier); | 
|         sl.setFeePartner(feePartner); | 
|         sl.setFeePlatform(feePlatform); | 
|         sl.setFeePlatformPack(feePlatformPack); | 
|         sl.setFeePlatformCheck(feePlatformCheck); | 
|         sl.setFeePlatformTransport(feePlatformTransport); | 
|         sl.setTotalFee(totalFee); | 
|         sl.setStatus(status); | 
|         sl.setAuditTime(LocalDateTime.now()); | 
|         sl.update(SecurityUtils.getUserId()); | 
|   | 
|         if(Constants.ORDER_SALES_STATUS.AGREED.name().equals(sl.getStatus())){ | 
|             if(totalFee.doubleValue() > 0) { | 
|                 Order o = orderMapper.selectById(sl.getOrderId()); | 
|                 String refundId = paymentV3Service.refundOrderSub(o, totalFee); | 
|                 sl.setRefundId(refundId); | 
|             } | 
|         } | 
|   | 
|         orderItemSalesMapper.updateById(sl); | 
|   | 
|         return oi; | 
|     } | 
| } |