| 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.config.exception.ValidationException; | 
| import com.mzl.flower.constant.Constants; | 
| import com.mzl.flower.dto.request.payment.BillQueryDTO; | 
| import com.mzl.flower.dto.response.payment.BillDTO; | 
| import com.mzl.flower.dto.response.payment.BillListDTO; | 
| import com.mzl.flower.entity.payment.*; | 
| import com.mzl.flower.mapper.payment.*; | 
| import com.mzl.flower.service.BaseService; | 
| 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 java.math.BigDecimal; | 
| import java.time.LocalDate; | 
| import java.time.LocalDateTime; | 
| import java.util.*; | 
|   | 
| @Slf4j | 
| @Service | 
| @Transactional | 
| public class BillService extends BaseService { | 
|   | 
|     @Autowired | 
|     private BillMapper billMapper; | 
|   | 
|     @Autowired | 
|     private OrderService orderService; | 
|   | 
|     @Autowired | 
|     private OrderMapper orderMapper; | 
|   | 
|     @Autowired | 
|     private OrderItemMapper orderItemMapper; | 
|   | 
|     @Autowired | 
|     private OrderItemSalesMapper orderItemSalesMapper; | 
|   | 
|     @Autowired | 
|     private OrderItemSettlementMapper orderItemSettlementMapper; | 
|   | 
|     public Page<BillListDTO> selectBillList(Page page, BillQueryDTO dto){ | 
|         dto.setStart(parseLocalDate(dto.getStartDate())); | 
|         dto.setEnd(parseLocalDate(dto.getEndDate())); | 
|   | 
|         List<BillListDTO> ls = billMapper.selectBillList(page, dto); | 
|   | 
|         page.setRecords(ls); | 
|   | 
|         return page; | 
|     } | 
|   | 
|     public BillListDTO getBillStatistics(BillQueryDTO dto){ | 
|         dto.setStart(parseLocalDate(dto.getStartDate())); | 
|         dto.setEnd(parseLocalDate(dto.getEndDate())); | 
|   | 
|         List<BillListDTO> ls = billMapper.selectBillList(null, dto); | 
|         BillListDTO r = new BillListDTO(); | 
|         if(ls != null && ls.size() > 0){ | 
|             for(BillListDTO b : ls){ | 
|                 r.setNum(r.getNum() + b.getNum()); | 
|                 r.setOrderAmount(r.getOrderAmount().add(b.getOrderAmount())); | 
|                 r.setSupplierAmount(r.getSupplierAmount().add(b.getSupplierAmount())); | 
|                 r.setPackingFee(r.getPackingFee().add(b.getPackingFee())); | 
|                 r.setTransportFee(r.getTransportFee().add(b.getTransportFee())); | 
|                 r.setMarkupOne(r.getMarkupOne().add(b.getMarkupOne())); | 
|                 r.setMarkupTwo(r.getMarkupTwo().add(b.getMarkupTwo())); | 
|                 r.setMarkupPartner(r.getMarkupPartner().add(b.getMarkupPartner())); | 
|                 r.setDeductAmount(r.getDeductAmount().add(b.getDeductAmount())); | 
|                 r.setSalesAmount(r.getSalesAmount().add(b.getSalesAmount())); | 
|                 r.setProfitAmount(r.getProfitAmount().add(b.getProfitAmount())); | 
|                 r.setMemberCouponAmount(r.getMemberCouponAmount().add(b.getMemberCouponAmount())); | 
|             } | 
|         } | 
|   | 
|         return r; | 
|     } | 
|   | 
|     public BillDTO getBill(String id){ | 
|         Bill bill = billMapper.selectById(id); | 
|         if(bill == null){ | 
|             throw new ValidationException("账单不存在"); | 
|         } | 
|   | 
|         BillDTO dto = new BillDTO(); | 
|         BeanUtils.copyProperties(bill, dto); | 
|   | 
|         /*OrderQueryDTO q = new OrderQueryDTO(); | 
|         q.setBillId(id); | 
|         List<OrderListDTO> orders = orderService.getOrderList(null, q); | 
|         dto.setOrders(orders);*/ | 
|   | 
|         return dto; | 
|     } | 
|   | 
|     public void generateBill(LocalDate date){ | 
|         int count = billMapper.selectCount(new QueryWrapper<Bill>().eq("bill_date", date).eq("deleted", 0)); | 
|         if(count > 0){ | 
|             log.warn(date + "已生成账单"); | 
|             return; | 
|         } | 
|         LocalDateTime startTime = date.atTime(0, 0, 0); | 
|         LocalDateTime endTime = startTime.plusDays(1); | 
|         List<Order> ls = orderMapper.getOrderForBill(startTime, endTime); | 
|         if(ls == null || ls.size() == 0){ | 
|             log.warn(date + "无任何已收货订单"); | 
|             return; | 
|         } | 
|   | 
|         List<String> orderIdsAll = new ArrayList<>(); | 
|         List<String> orderIdsPartner = new ArrayList<>(); | 
|         List<String> orderIdsPersonal = new ArrayList<>(); | 
|         Map<String, Order> orderMap = new HashMap<>(); | 
|         for(Order o : ls){ | 
|             String orderId = o.getId(); | 
|             orderIdsAll.add(orderId); | 
|             orderMap.put(orderId, o); | 
|   | 
|             Long partnerId = o.getPartnerId(); | 
|             if(partnerId != null){ | 
|                 orderIdsPartner.add(orderId); | 
|             } else { | 
|                 orderIdsPersonal.add(orderId); | 
|             } | 
|         } | 
|   | 
|         List<OrderItem> orderItems = orderItemMapper.selectList(new QueryWrapper<OrderItem>() | 
|                 .in("order_id", orderIdsAll)); | 
|         Map<String, List<OrderItem>> orderItemMap = new HashMap<>(); | 
|         for(OrderItem oi : orderItems){ | 
|             String orderId = oi.getOrderId(); | 
|             List<OrderItem> items = orderItemMap.computeIfAbsent(orderId, k -> new ArrayList<>()); | 
|             items.add(oi); | 
|         } | 
|   | 
|         //账单售后 | 
|         /*List<OrderItemSales> sLs = orderItemSalesMapper.selectList(new QueryWrapper<OrderItemSales>() | 
|                 .in("order_id", orderIdsAll));*/ | 
|         List<OrderItemSettlement> sLs = orderItemSettlementMapper.selectList(new QueryWrapper<OrderItemSettlement>() | 
|                 .in("order_id", orderIdsAll)); | 
|         Map<String, BigDecimal> salesMap = new HashMap<>(); | 
|         Map<String, BigDecimal> deductMap = new HashMap<>(); | 
|         if(sLs != null && sLs.size() > 0){ | 
|             for(OrderItemSettlement s : sLs){//同一个订单的同一个商品可能会多次理赔 | 
|                 salesMap.put(s.getOrderItemId(), s.getSalesFeePlatform()); | 
|                 deductMap.put(s.getOrderItemId(), s.getLackFeePlatform()); | 
|             } | 
|         } | 
|   | 
|   | 
|         String type = Constants.BILL_TYPE.partner.name();//账单类型 | 
|         calculate(date, type, orderIdsPartner, orderMap, orderItemMap, salesMap, deductMap); | 
|   | 
|         type = Constants.BILL_TYPE.personal.name();//账单类型 | 
|         calculate(date, type, orderIdsPersonal, orderMap, orderItemMap, salesMap, deductMap); | 
|     } | 
|   | 
|     public Bill calculate(LocalDate date, String type, List<String> orderIds, Map<String, Order> orderMap | 
|             , Map<String, List<OrderItem>> orderItemMap, Map<String, BigDecimal> salesMap | 
|             , Map<String, BigDecimal> deductMap){ | 
|         Bill bill = new Bill(); | 
|         bill.setId(UUIDGenerator.getUUID()); | 
|   | 
|         BigDecimal orderAmount = new BigDecimal(0);//花款(售价) | 
|         BigDecimal supplierAmount = new BigDecimal(0);//花款(底价) | 
|         Integer num = 0;//发货数 | 
|         BigDecimal packingFee = new BigDecimal(0);//打包费 | 
|         BigDecimal transportFee = new BigDecimal(0);//运费 | 
|         BigDecimal markupOne = new BigDecimal(0);//区间加价 | 
|         BigDecimal markupTwo = new BigDecimal(0);//二次加价 | 
|         BigDecimal markupPartner = new BigDecimal(0);//合伙人加价 | 
|         BigDecimal deductAmount = new BigDecimal(0);//质检退款(缺货) | 
|         BigDecimal salesAmount = new BigDecimal(0);//售后退款 | 
|         BigDecimal memberCouponAmount = new BigDecimal(0);//优惠券金额 | 
|         for(String orderId : orderIds){ | 
|             Order o = orderMap.get(orderId); | 
|             orderAmount = orderAmount.add(o.getTotalAmount()); | 
|             packingFee = packingFee.add(o.getPackingFee()); | 
|             transportFee = transportFee.add(o.getTransportFee()); | 
|             List<OrderItem> items = orderItemMap.get(orderId); | 
|             for(OrderItem oi : items){ | 
|                 Integer n = oi.getNum(); | 
|                 supplierAmount = supplierAmount.add(oi.getSupplierPrice().multiply(new BigDecimal(n))); | 
|                 markupOne = markupOne.add(getAmount(oi.getMarkupOne()).multiply(new BigDecimal(n))); | 
|                 markupTwo = markupTwo.add(getAmount(oi.getMarkupTwo()).multiply(new BigDecimal(n))); | 
|                 markupPartner = markupPartner.add(getAmount(oi.getMarkupPartner()).multiply(new BigDecimal(n))); | 
|   | 
|                 salesAmount = salesAmount.add(getAmount(salesMap.get(oi.getId()))); | 
|                 deductAmount = deductAmount.add(getAmount(deductMap.get(oi.getId()))); | 
|                 num += n; | 
|             } | 
|   | 
|             memberCouponAmount = memberCouponAmount.add(getAmount(o.getMemberCouponAmount())); | 
|   | 
|             o.setBillId(bill.getId()); | 
|             orderMapper.updateById(o); | 
|         } | 
|   | 
|         bill.setType(type); | 
|         bill.setOrderAmount(orderAmount); | 
|         bill.setSupplierAmount(supplierAmount); | 
|         bill.setNum(num); | 
|         bill.setPackingFee(packingFee); | 
|         bill.setTransportFee(transportFee); | 
|         bill.setMarkupOne(markupOne); | 
|         bill.setMarkupTwo(markupTwo); | 
|         bill.setMarkupPartner(markupPartner); | 
|         bill.setDeductAmount(deductAmount); | 
|         bill.setSalesAmount(salesAmount); | 
|         bill.setMemberCouponAmount(memberCouponAmount); | 
|         bill.setBillDate(date); | 
|   | 
|         //合伙人:利润=售价-底价(花农上架价格)-打包、运费(订单管理手输)-合伙人加价-平台罚款-质检(缺货)-优惠券 | 
|         //散户:利润=售价-底价(花农上架价格)-运费-平台罚款-质检(缺货)-优惠券 | 
|         //其实都一样的计算方式 | 
|         BigDecimal profitAmount = orderAmount.subtract(supplierAmount) | 
|                 .subtract(markupPartner).subtract(salesAmount).subtract(packingFee).subtract(transportFee) | 
|                 .subtract(deductAmount).subtract(memberCouponAmount);//利润合计 | 
|         bill.setProfitAmount(profitAmount); | 
|   | 
|         bill.create(); | 
|   | 
|         billMapper.insert(bill); | 
|   | 
|         return bill; | 
|     } | 
| } |