瀏覽代碼

Merge branch 'master' of http://git.dayaedu.com/yonge/mec

# Conflicts:
#	mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
yonge 5 年之前
父節點
當前提交
7455bbaae1
共有 61 個文件被更改,包括 2527 次插入152 次删除
  1. 63 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/GoodsDao.java
  2. 46 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/GoodsProcurementDao.java
  3. 30 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SellOrderDao.java
  4. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentGoodsSellDao.java
  5. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherDao.java
  6. 36 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/GoodsBatchNoDto.java
  7. 23 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/GoodsSellDto.java
  8. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentGoodsSellDto.java
  9. 69 2
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Goods.java
  10. 193 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/GoodsProcurement.java
  11. 84 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SellOrder.java
  12. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentPaymentOrder.java
  13. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SubjectChange.java
  14. 5 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysPaymentConfig.java
  15. 26 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/AccountType.java
  16. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java
  17. 25 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/SellStatus.java
  18. 30 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/StockType.java
  19. 42 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/GoodsProcurementQueryInfo.java
  20. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/GoodsQueryInfo.java
  21. 36 0
      mec-biz/src/main/java/com/ym/mec/biz/event/StudentCourseChangeEvent.java
  22. 30 0
      mec-biz/src/main/java/com/ym/mec/biz/event/listener/StudentEventListener.java
  23. 33 0
      mec-biz/src/main/java/com/ym/mec/biz/event/source/StudentEventSource.java
  24. 19 0
      mec-biz/src/main/java/com/ym/mec/biz/service/GoodsProcurementService.java
  25. 67 3
      mec-biz/src/main/java/com/ym/mec/biz/service/GoodsService.java
  26. 27 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SellOrderService.java
  27. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/service/StudentGoodsSellService.java
  28. 13 6
      mec-biz/src/main/java/com/ym/mec/biz/service/SubjectChangeService.java
  29. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/SysPaymentConfigService.java
  30. 25 20
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  31. 47 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GoodsProcurementServiceImpl.java
  32. 355 13
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GoodsServiceImpl.java
  33. 81 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SellOrderServiceImpl.java
  34. 25 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentGoodsSellServiceImpl.java
  35. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentRouteOrderServiceImpl.java
  36. 132 28
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRepairServiceImpl.java
  37. 157 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SubjectChangeServiceImpl.java
  38. 7 6
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysPaymentConfigServiceImpl.java
  39. 0 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherAttendanceServiceImpl.java
  40. 160 11
      mec-biz/src/main/resources/config/mybatis/GoodsMapper.xml
  41. 147 0
      mec-biz/src/main/resources/config/mybatis/GoodsProcurementMapper.xml
  42. 155 21
      mec-biz/src/main/resources/config/mybatis/SellOrderMapper.xml
  43. 12 1
      mec-biz/src/main/resources/config/mybatis/StudentGoodsSellMapper.xml
  44. 4 0
      mec-biz/src/main/resources/config/mybatis/StudentPaymentOrderMapper.xml
  45. 4 3
      mec-biz/src/main/resources/config/mybatis/SubjectChangeMapper.xml
  46. 13 15
      mec-biz/src/main/resources/config/mybatis/SysPaymentConfigMapper.xml
  47. 5 0
      mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  48. 7 0
      mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java
  49. 10 0
      mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java
  50. 7 0
      mec-student/src/main/java/com/ym/mec/student/controller/RepairController.java
  51. 1 1
      mec-student/src/main/java/com/ym/mec/student/controller/SubjectChangeController.java
  52. 19 0
      mec-task/src/main/java/com/ym/mec/task/jobs/AutoAffirmReceiveTask.java
  53. 19 0
      mec-task/src/main/java/com/ym/mec/task/jobs/GoodsRepertoryFBIWarnTask.java
  54. 14 2
      mec-web/src/main/java/com/ym/mec/web/controller/AdapayController.java
  55. 18 1
      mec-web/src/main/java/com/ym/mec/web/controller/GoodsController.java
  56. 36 0
      mec-web/src/main/java/com/ym/mec/web/controller/GoodsProcurementContrller.java
  57. 9 1
      mec-web/src/main/java/com/ym/mec/web/controller/ImportController.java
  58. 29 0
      mec-web/src/main/java/com/ym/mec/web/controller/SellOrderController.java
  59. 17 0
      mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java
  60. 12 3
      mec-web/src/main/resources/columnMapper.ini
  61. 二進制
      mec-web/src/main/resources/excelTemplate/商品导入模板.xls

+ 63 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/GoodsDao.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.dal.dao;
 
+import com.ym.mec.biz.dal.dto.GoodsSellDto;
 import com.ym.mec.biz.dal.entity.Goods;
 import com.ym.mec.common.dal.BaseDAO;
 
@@ -47,9 +48,70 @@ public interface GoodsDao extends BaseDAO<Integer, Goods> {
     void batchInsert(@Param("goodsList") List<Goods> goodsList);
 
     /**
+     * @describe 批量更新商品
+     * @author Joburgess
+     * @date 2020.09.28
+     * @param goodsList:
+     * @return void
+     */
+    void batchUpdate(@Param("goodsList") List<Goods> goodsList);
+
+    /**
      * 获取商品列表
      * @param goodsIds
      * @return
      */
     List<Goods> getGoodies(@Param("goodsIds") List<Integer> goodsIds);
-}
+
+    /**
+     * @describe 查询附件商品列表中存在指定商品的商品
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsId:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.Goods>
+     */
+    List<Goods> getWithComplementGoodsAndStatus(@Param("goodsId") Integer goodsId,
+                                                @Param("status") Integer status);
+
+    /**
+     * @describe 锁定指定商品
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsIds:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.Goods>
+     */
+    List<Goods> lockGoods(@Param("goodsIds") List<Integer> goodsIds);
+
+    /**
+     * @describe 根据货号查找商品
+     * @author Joburgess
+     * @date 2020.10.10
+     * @param sn:
+     * @return com.ym.mec.biz.dal.entity.Goods
+     */
+    Goods findBySn(@Param("sn") String sn);
+
+    /**
+     * @describe 根据货号查找商品
+     * @author Joburgess
+     * @date 2020.09.28
+     * @param sns:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.Goods>
+     */
+    List<Goods> findBySns(@Param("sns") List<String> sns);
+
+    String getInnerRepertoryWarnName(@Param("innerRepertoryWarnNum") String innerRepertoryWarnNum);
+
+    String getOuterRepertoryWarnName(@Param("outerRepertoryWarnNum") String outerRepertoryWarnNum);
+
+    /**
+     * @describe 获取商品辅件列表
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/13
+     * @time 15:09
+     * @param goodsId:
+     * @return java.util.List<com.ym.mec.biz.dal.dto.GoodsSellDto>
+     */
+    List<GoodsSellDto> queryGoodsSellDtos(@Param("goodsId") String goodsId);
+}

+ 46 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/GoodsProcurementDao.java

@@ -0,0 +1,46 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.ym.mec.biz.dal.entity.GoodsProcurement;
+import com.ym.mec.common.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+public interface GoodsProcurementDao extends BaseDAO<Long, GoodsProcurement> {
+
+    int batchInsert(@Param("goodsProcurements") List<GoodsProcurement> goodsProcurements);
+
+    List<GoodsProcurement> queryGoodsProcurements(Map<String, Object> params);
+    int countGoodsProcurements(Map<String, Object> params);
+
+    /**
+     * @describe 获取有内部库存的清单
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsId:
+     * @return com.ym.mec.biz.dal.entity.GoodsProcurement
+     */
+    GoodsProcurement getWithStockSurplusProcurement(@Param("goodsId") Integer goodsId);
+
+    /**
+     * @describe 获取有税务库存的清单
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsId:
+     * @return com.ym.mec.biz.dal.entity.GoodsProcurement
+     */
+    GoodsProcurement getWithTaxStockSurplusProcurement(@Param("goodsId") Integer goodsId);
+
+    /**
+     * @describe 根据商品编号与批次号获取进货清单
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsId:
+     * @param batchNo:
+     * @return com.ym.mec.biz.dal.entity.GoodsProcurement
+     */
+    GoodsProcurement getWithGoodsAndBatchNo(@Param("goodsId") Integer goodsId,
+                                            @Param("batchNo") String batchNo);
+
+}

+ 30 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SellOrderDao.java

@@ -13,6 +13,8 @@ public interface SellOrderDao extends BaseDAO<Integer, SellOrder> {
 
     int batchInsert(@Param("sellOrders") List<SellOrder> sellOrders);
 
+    int batchUpdate(@Param("sellOrders") List<SellOrder> sellOrders);
+
     /**
      * 获取订单的销售列表
      *
@@ -122,9 +124,36 @@ public interface SellOrderDao extends BaseDAO<Integer, SellOrder> {
 
     /**
      * 获取声部更换的销售、总收入
+     *
      * @param startTime
      * @param endTime
      * @return
      */
     List<OperatingReport> getSubjectChangeMonthReport(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
-}
+
+    /**
+     * @param sellOrderIds:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.SellOrder>
+     * @describe 获取指定的销售记录
+     * @author Joburgess
+     * @date 2020.10.13
+     */
+    List<SellOrder> getSellOrders(@Param("sellOrderIds") List<Integer> sellOrderIds);
+
+    /**
+     * @describe 获取无批次号商品销售记录
+     * @author Joburgess
+     * @date 2020.10.13
+     * @return java.util.List<com.ym.mec.biz.dal.entity.SellOrder>
+     */
+    List<SellOrder> getNoneBatchNoSellOrders();
+
+
+    /**
+     * 获取订单组合商品的子商品
+     * @param orderId
+     * @param parentGoodsId
+     * @return
+     */
+    List<SellOrder> getSellOrderByParentGoodsId(@Param("orderId") Long orderId, @Param("parentGoodsId") Integer parentGoodsId);
+}

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentGoodsSellDao.java

@@ -46,4 +46,26 @@ public interface StudentGoodsSellDao extends BaseDAO<Integer, StudentGoodsSell>
     StudentGoodsSell findByOrderNo(@Param("orderNo") String orderNo);
 
     StudentGoodsSellDto getStudentGoodsSellDto(String orderNo);
+
+    /**
+     * @describe 获取到期未确认的订单
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/12
+     * @time 10:09
+     * @param autoAffirmReceiveTime:
+     * @return java.util.List<java.lang.String>
+     */
+    String queryNoAffirmOrderNo(String autoAffirmReceiveTime);
+
+    /**
+     * @describe 自动确认收货
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/12
+     * @time 10:15
+     * @param orderNo:
+     * @return void
+     */
+    void autoAffirmReceive(@Param("orderNo") String orderNo, @Param("status") String status);
 }

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherDao.java

@@ -474,4 +474,6 @@ public interface TeacherDao extends BaseDAO<Integer, Teacher> {
     int countStudent(Map<String, Object> params);
     
     List<TeacherDefaultSalaryDto> queryTeacherDefaultSalary(@Param("organIdList") String organIdList);
+
+    BasicUserDto findUserByPhone(String phone);
 }

+ 36 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/GoodsBatchNoDto.java

@@ -0,0 +1,36 @@
+package com.ym.mec.biz.dal.dto;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.10.12
+ */
+public class GoodsBatchNoDto {
+
+    private Integer goodsId;
+
+    private String batchNo;
+
+    public GoodsBatchNoDto() {
+    }
+
+    public GoodsBatchNoDto(Integer goodsId, String batchNo) {
+        this.goodsId = goodsId;
+        this.batchNo = batchNo;
+    }
+
+    public Integer getGoodsId() {
+        return goodsId;
+    }
+
+    public void setGoodsId(Integer goodsId) {
+        this.goodsId = goodsId;
+    }
+
+    public String getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(String batchNo) {
+        this.batchNo = batchNo;
+    }
+}

+ 23 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/GoodsSellDto.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.dal.dto;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 public class GoodsSellDto{
 	@ApiModelProperty(value = "商品数量", required = false)
@@ -26,6 +27,28 @@ public class GoodsSellDto{
 	@ApiModelProperty(value = "商品销售总价", required = false)
 	private BigDecimal totalGoodsPrice = BigDecimal.ZERO;
 
+    @ApiModelProperty(value = "辅件商品列表", required = false)
+    private String complementGoodsIdList;
+
+    public String getComplementGoodsIdList() {
+        return complementGoodsIdList;
+    }
+
+    public void setComplementGoodsIdList(String complementGoodsIdList) {
+        this.complementGoodsIdList = complementGoodsIdList;
+    }
+
+	@ApiModelProperty(value = "组合商品子商品", required = false)
+	private List<GoodsSellDto> goodsSellDtos;
+
+	public List<GoodsSellDto> getGoodsSellDtos() {
+		return goodsSellDtos;
+	}
+
+	public void setGoodsSellDtos(List<GoodsSellDto> goodsSellDtos) {
+		this.goodsSellDtos = goodsSellDtos;
+	}
+
 	public String getGoodsType() {
 		return goodsType;
 	}

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentGoodsSellDto.java

@@ -16,6 +16,16 @@ public class StudentGoodsSellDto extends StudentPaymentOrder {
 
     private BigDecimal marketAmount = BigDecimal.ZERO;
 
+    private Integer autoAffirmReceiveTime;
+
+    public Integer getAutoAffirmReceiveTime() {
+        return autoAffirmReceiveTime;
+    }
+
+    public void setAutoAffirmReceiveTime(Integer autoAffirmReceiveTime) {
+        this.autoAffirmReceiveTime = autoAffirmReceiveTime;
+    }
+
     public Integer getAuthorUser() {
         return authorUser;
     }

+ 69 - 2
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Goods.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.dal.entity;
 
 import com.ym.mec.biz.dal.enums.GoodsType;
+import com.ym.mec.biz.dal.enums.StockType;
 import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 
 import io.swagger.annotations.ApiModelProperty;
@@ -51,6 +52,9 @@ public class Goods {
 	@ApiModelProperty(value = "库存数量",required = false)
 	private Integer stockCount;
 
+	@ApiModelProperty(value = "税务库存")
+	private Integer taxStockCount;
+
 	/** 总销量数 */
 	@ApiModelProperty(value = "总销量数",required = false)
 	private Integer sellCount;
@@ -60,13 +64,16 @@ public class Goods {
 	private BigDecimal marketPrice;
 
 	/** 折扣价 */
-	@ApiModelProperty(value = "折扣价",required = false)
+	@ApiModelProperty(value = "商品零售价",required = false)
 	private BigDecimal discountPrice;
 
 	/** 团购价 */
 	@ApiModelProperty(value = "团购价",required = false)
 	private BigDecimal groupPurchasePrice;
 
+	@ApiModelProperty(value = "商品价格1")
+	private BigDecimal costPrice;
+
 	/** 协议成本价 */
 	@ApiModelProperty(value = "协议成本价",required = false)
 	private BigDecimal agreeCostPrice;
@@ -118,6 +125,42 @@ public class Goods {
 	@ApiModelProperty(value = "商品类型", required = false)
 	private GoodsType type;
 
+	@ApiModelProperty(value = "备查货号,进货渠道")
+	private String supplyChannel;
+
+	@ApiModelProperty(value = "客户端是否展示")
+	private YesOrNoEnum clientShow;
+
+	@ApiModelProperty(value = "库存类型")
+	private StockType stockType;
+
+	@ApiModelProperty(value = "库存预警")
+	private YesOrNoEnum stockWarning;
+
+	public YesOrNoEnum getStockWarning() {
+		return stockWarning;
+	}
+
+	public void setStockWarning(YesOrNoEnum stockWarning) {
+		this.stockWarning = stockWarning;
+	}
+
+	public YesOrNoEnum getClientShow() {
+		return clientShow;
+	}
+
+	public void setClientShow(YesOrNoEnum clientShow) {
+		this.clientShow = clientShow;
+	}
+
+	public StockType getStockType() {
+		return stockType;
+	}
+
+	public void setStockType(StockType stockType) {
+		this.stockType = stockType;
+	}
+
 	public BigDecimal getAgreeCostPrice() {
 		return agreeCostPrice;
 	}
@@ -134,7 +177,15 @@ public class Goods {
         this.subjectIds = subjectIds;
     }
 
-    public String getGoodsCategoryName() {
+	public BigDecimal getCostPrice() {
+		return costPrice;
+	}
+
+	public void setCostPrice(BigDecimal costPrice) {
+		this.costPrice = costPrice;
+	}
+
+	public String getGoodsCategoryName() {
 		return goodsCategoryName;
 	}
 
@@ -334,6 +385,22 @@ public class Goods {
 		this.goodsList = goodsList;
 	}
 
+	public Integer getTaxStockCount() {
+		return taxStockCount;
+	}
+
+	public void setTaxStockCount(Integer taxStockCount) {
+		this.taxStockCount = taxStockCount;
+	}
+
+	public String getSupplyChannel() {
+		return supplyChannel;
+	}
+
+	public void setSupplyChannel(String supplyChannel) {
+		this.supplyChannel = supplyChannel;
+	}
+
 	@Override
 	public String toString() {
 		return ToStringBuilder.reflectionToString(this);

+ 193 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/GoodsProcurement.java

@@ -0,0 +1,193 @@
+package com.ym.mec.biz.dal.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(goods_procurement):
+ */
+public class GoodsProcurement {
+
+	@ApiModelProperty(value = "编号")
+	private Long id;
+
+	@ApiModelProperty(value = "组合商品编号")
+	private Integer parentGoodsId;
+	
+	@ApiModelProperty(value = "商品编号")
+	private Integer goodsId;
+	
+	@ApiModelProperty(value = "商品分类")
+	private Integer goodsCategoryId;
+	
+	@ApiModelProperty(value = "进货渠道")
+	private String supplyChannel;
+	
+	@ApiModelProperty(value = "采购价一")
+	private java.math.BigDecimal discountPrice;
+	
+	@ApiModelProperty(value = "采购价二")
+	private java.math.BigDecimal agreeCostPrice;
+	
+	@ApiModelProperty(value = "内部库存")
+	private Integer stockCount;
+	
+	@ApiModelProperty(value = "税务库存")
+	private Integer taxStockCount;
+	
+	@ApiModelProperty(value = "进货人编号")
+	private Integer operatorId;
+
+	@ApiModelProperty(value = "批次号")
+	private String batchNo;
+
+	@ApiModelProperty(value = "内部库存售出数量")
+	private int stockSoldNum;
+
+	@ApiModelProperty(value = "税务库存售出数量")
+	private int taxStockSoldNum;
+	
+	/**  */
+	private java.util.Date createTime;
+	
+	/**  */
+	private java.util.Date updateTime;
+
+	public GoodsProcurement() {
+	}
+
+	public GoodsProcurement(Integer goodsId) {
+		this.goodsId = goodsId;
+	}
+
+	public GoodsProcurement(Integer parentGoodsId, Integer goodsId) {
+		this.parentGoodsId = parentGoodsId;
+		this.goodsId = goodsId;
+	}
+
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+
+	public Integer getParentGoodsId() {
+		return parentGoodsId;
+	}
+
+	public void setParentGoodsId(Integer parentGoodsId) {
+		this.parentGoodsId = parentGoodsId;
+	}
+
+	public void setGoodsId(Integer goodsId){
+		this.goodsId = goodsId;
+	}
+	
+	public Integer getGoodsId(){
+		return this.goodsId;
+	}
+			
+	public void setGoodsCategoryId(Integer goodsCategoryId){
+		this.goodsCategoryId = goodsCategoryId;
+	}
+	
+	public Integer getGoodsCategoryId(){
+		return this.goodsCategoryId;
+	}
+			
+	public void setSupplyChannel(String supplyChannel){
+		this.supplyChannel = supplyChannel;
+	}
+	
+	public String getSupplyChannel(){
+		return this.supplyChannel;
+	}
+			
+	public void setDiscountPrice(java.math.BigDecimal discountPrice){
+		this.discountPrice = discountPrice;
+	}
+	
+	public java.math.BigDecimal getDiscountPrice(){
+		return this.discountPrice;
+	}
+			
+	public void setAgreeCostPrice(java.math.BigDecimal agreeCostPrice){
+		this.agreeCostPrice = agreeCostPrice;
+	}
+	
+	public java.math.BigDecimal getAgreeCostPrice(){
+		return this.agreeCostPrice;
+	}
+			
+	public void setOperatorId(Integer operatorId){
+		this.operatorId = operatorId;
+	}
+	
+	public Integer getOperatorId(){
+		return this.operatorId;
+	}
+
+	public String getBatchNo() {
+		return batchNo;
+	}
+
+	public void setBatchNo(String batchNo) {
+		this.batchNo = batchNo;
+	}
+
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	public void setUpdateTime(java.util.Date updateTime){
+		this.updateTime = updateTime;
+	}
+	
+	public java.util.Date getUpdateTime(){
+		return this.updateTime;
+	}
+
+	public Integer getStockCount() {
+		return stockCount;
+	}
+
+	public void setStockCount(Integer stockCount) {
+		this.stockCount = stockCount;
+	}
+
+	public Integer getTaxStockCount() {
+		return taxStockCount;
+	}
+
+	public void setTaxStockCount(Integer taxStockCount) {
+		this.taxStockCount = taxStockCount;
+	}
+
+	public int getStockSoldNum() {
+		return stockSoldNum;
+	}
+
+	public void setStockSoldNum(int stockSoldNum) {
+		this.stockSoldNum = stockSoldNum;
+	}
+
+	public int getTaxStockSoldNum() {
+		return taxStockSoldNum;
+	}
+
+	public void setTaxStockSoldNum(int taxStockSoldNum) {
+		this.taxStockSoldNum = taxStockSoldNum;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 84 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SellOrder.java

@@ -1,6 +1,9 @@
 package com.ym.mec.biz.dal.entity;
 
+import com.ym.mec.biz.dal.enums.AccountType;
+import com.ym.mec.biz.dal.enums.SellStatus;
 import com.ym.mec.biz.dal.enums.SellTypeEnum;
+import com.ym.mec.biz.dal.enums.StockType;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import java.math.BigDecimal;
@@ -95,6 +98,12 @@ public class SellOrder {
     private SellTypeEnum type;
 
     /**
+     * 组合商品id
+     */
+    @ApiModelProperty(value="组合商品id")
+    private Integer parentGoodsId;
+
+    /**
     * 商品id
     */
     @ApiModelProperty(value="商品id")
@@ -135,6 +144,30 @@ public class SellOrder {
     private String merNo;
 
     /**
+     * 批次号
+     */
+    @ApiModelProperty(value="批次号")
+    private String batchNo;
+
+    /**
+    * 库存类型
+    */
+    @ApiModelProperty(value="库存类型")
+    private StockType stockType;
+
+    /**
+     * 账户类型
+     */
+    @ApiModelProperty(value = "账户类型")
+    private AccountType accountType;
+
+    /**
+     * 状态
+     */
+    @ApiModelProperty(value = "状态")
+    private SellStatus status;
+
+    /**
     * 交易时间
     */
     @ApiModelProperty(value="交易时间")
@@ -152,6 +185,17 @@ public class SellOrder {
     @ApiModelProperty(value="更新时间")
     private Date updateTime;
 
+    @ApiModelProperty(value = "收货状态,NO_RECEIVE 未确认,MANUAL_RECEIVE 手动确认,AUTO_RECEIVE 自动确认",required = true)
+    private String receiveStatus;
+
+    public String getReceiveStatus() {
+        return receiveStatus;
+    }
+
+    public void setReceiveStatus(String receiveStatus) {
+        this.receiveStatus = receiveStatus;
+    }
+
     public Integer getId() {
         return id;
     }
@@ -367,4 +411,44 @@ public class SellOrder {
     public void setEduTeacher(String eduTeacher) {
         this.eduTeacher = eduTeacher;
     }
+
+    public StockType getStockType() {
+        return stockType;
+    }
+
+    public void setStockType(StockType stockType) {
+        this.stockType = stockType;
+    }
+
+    public AccountType getAccountType() {
+        return accountType;
+    }
+
+    public void setAccountType(AccountType accountType) {
+        this.accountType = accountType;
+    }
+
+    public String getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(String batchNo) {
+        this.batchNo = batchNo;
+    }
+
+    public SellStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(SellStatus status) {
+        this.status = status;
+    }
+
+    public Integer getParentGoodsId() {
+        return parentGoodsId;
+    }
+
+    public void setParentGoodsId(Integer parentGoodsId) {
+        this.parentGoodsId = parentGoodsId;
+    }
 }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentPaymentOrder.java

@@ -107,6 +107,9 @@ public class StudentPaymentOrder {
 	//收款账户
 	private String merNos;
 
+	@ApiModelProperty(value = "收货状态,NO_RECEIVE 未确认,MANUAL_RECEIVE 手动确认,AUTO_RECEIVE 自动确认",required = true)
+	private String receiveStatus;
+
 	private PaymentChannelTypeEnum paymentChannelType;
 	
 	private SysUser user = new SysUser();
@@ -117,6 +120,14 @@ public class StudentPaymentOrder {
 	//课程优惠金额
 	private BigDecimal courseRemitFee;
 
+	public String getReceiveStatus() {
+		return receiveStatus;
+	}
+
+	public void setReceiveStatus(String receiveStatus) {
+		this.receiveStatus = receiveStatus;
+	}
+
 	public void setId(Long id){
 		this.id = id;
 	}

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SubjectChange.java

@@ -14,6 +14,9 @@ public class SubjectChange {
     @ApiModelProperty(value = "")
     private Integer id;
 
+    @ApiModelProperty(value = "原始订单id")
+    private Integer originalOrderId;
+
     @ApiModelProperty(value = "合作单位id")
     private Integer cooperationOrganId;
 
@@ -555,4 +558,12 @@ public class SubjectChange {
     public void setEduTeacher(String eduTeacher) {
         this.eduTeacher = eduTeacher;
     }
+
+    public Integer getOriginalOrderId() {
+        return originalOrderId;
+    }
+
+    public void setOriginalOrderId(Integer originalOrderId) {
+        this.originalOrderId = originalOrderId;
+    }
 }

+ 5 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysPaymentConfig.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.dal.entity;
 
+import com.ym.mec.biz.dal.enums.AccountType;
 import com.ym.mec.biz.dal.enums.PaymentChannelEnum;
 import io.swagger.annotations.ApiModelProperty;
 import java.util.Date;
@@ -51,8 +52,8 @@ public class SysPaymentConfig {
     /**
      * 账户类型
      */
-    @ApiModelProperty(value = "账户类型(0-内部、1-外部)")
-    private Integer accountType;
+    @ApiModelProperty(value = "账户类型")
+    private AccountType accountType;
 
 
     /**
@@ -239,11 +240,11 @@ public class SysPaymentConfig {
         this.routeScale = routeScale;
     }
 
-    public Integer getAccountType() {
+    public AccountType getAccountType() {
         return accountType;
     }
 
-    public void setAccountType(Integer accountType) {
+    public void setAccountType(AccountType accountType) {
         this.accountType = accountType;
     }
 }

+ 26 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/AccountType.java

@@ -0,0 +1,26 @@
+package com.ym.mec.biz.dal.enums;
+
+import com.ym.mec.common.enums.BaseEnum;
+
+
+public enum AccountType implements BaseEnum<Integer, AccountType> {
+    INTERNAL(0, "内部"),
+    EXTERNAL(1, "外部");
+
+    private Integer code;
+    private String msg;
+
+    AccountType(Integer code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    @Override
+    public Integer getCode() {
+        return code;
+    }
+}

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java

@@ -156,6 +156,7 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     SMS_REPAIR_UNSEND_COMPLETED("SMS_REPAIR_UNSEND_COMPLETED","乐器维修完成自取"),
     SMS_PAYMENT_DETAIL("SMS_PAYMENT_DETAIL","缴费项目缴费详情提醒"),
     SMS_PAYMENT_CREATE("SMS_PAYMENT_CREATE","缴费项目创建提醒"),
+    SMS_GOODS_REPERTORY_WARN("SMS_GOODS_REPERTORY_WARN","商品库存预警"),
     SMS_REPAIR_SEND_COMPLETED("SMS_REPAIR_SEND_COMPLETED","乐器维修完成邮寄");
 
 

+ 25 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/SellStatus.java

@@ -0,0 +1,25 @@
+package com.ym.mec.biz.dal.enums;
+
+import com.ym.mec.common.enums.BaseEnum;
+
+
+public enum SellStatus implements BaseEnum<Integer, SellStatus> {
+    NORMAL(0, "正常"),
+    REFUND(1, "已退货");
+    private Integer code;
+    private String msg;
+
+    SellStatus(Integer code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    @Override
+    public Integer getCode() {
+        return code;
+    }
+}

+ 30 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/StockType.java

@@ -0,0 +1,30 @@
+package com.ym.mec.biz.dal.enums;
+
+import com.ym.mec.common.enums.BaseEnum;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.10.10
+ **/
+public enum StockType implements BaseEnum<String, StockType> {
+    INTERNAL("INTERNAL", "内部"),
+    EXTERNAL("EXTERNAL", "外部"),
+    ALL("ALL", "内部、外部");
+
+    private String code;
+    private String msg;
+
+    StockType(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    @Override
+    public String getCode() {
+        return code;
+    }
+}

+ 42 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/GoodsProcurementQueryInfo.java

@@ -0,0 +1,42 @@
+package com.ym.mec.biz.dal.page;
+
+import com.ym.mec.common.page.QueryInfo;
+
+import java.util.Date;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.10.09
+ */
+public class GoodsProcurementQueryInfo extends QueryInfo {
+
+    private Integer goodsId;
+
+    private String enterStorageStartTime;
+
+    private String enterStorageEndTime;
+
+    public String getEnterStorageStartTime() {
+        return enterStorageStartTime;
+    }
+
+    public void setEnterStorageStartTime(String enterStorageStartTime) {
+        this.enterStorageStartTime = enterStorageStartTime;
+    }
+
+    public String getEnterStorageEndTime() {
+        return enterStorageEndTime;
+    }
+
+    public void setEnterStorageEndTime(String enterStorageEndTime) {
+        this.enterStorageEndTime = enterStorageEndTime;
+    }
+
+    public Integer getGoodsId() {
+        return goodsId;
+    }
+
+    public void setGoodsId(Integer goodsId) {
+        this.goodsId = goodsId;
+    }
+}

+ 22 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/GoodsQueryInfo.java

@@ -25,6 +25,20 @@ public class GoodsQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "商品类型", required = false)
     private GoodsType type;
 
+    @ApiModelProperty(value = "是否组合商品:0/1")
+    private Integer groupGoods;
+
+    @ApiModelProperty(value = "客户端是否展示:0否,1是")
+    private Integer clientShow;
+
+    public Integer getGroupGoods() {
+        return groupGoods;
+    }
+
+    public void setGroupGoods(Integer groupGoods) {
+        this.groupGoods = groupGoods;
+    }
+
     public GoodsType getType() {
         return type;
     }
@@ -64,4 +78,12 @@ public class GoodsQueryInfo extends QueryInfo {
     public void setStatus(YesOrNoEnum status) {
         this.status = status;
     }
+
+    public Integer getClientShow() {
+        return clientShow;
+    }
+
+    public void setClientShow(Integer clientShow) {
+        this.clientShow = clientShow;
+    }
 }

+ 36 - 0
mec-biz/src/main/java/com/ym/mec/biz/event/StudentCourseChangeEvent.java

@@ -0,0 +1,36 @@
+package com.ym.mec.biz.event;
+
+import com.ym.mec.biz.dal.enums.GroupType;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.09.24
+ */
+public class StudentCourseChangeEvent extends ApplicationEvent {
+
+    private Integer[] userIds;
+
+    private String groupId;
+
+    private GroupType groupType;
+
+    public StudentCourseChangeEvent(Object source, String groupId, GroupType groupType, Integer... userIds) {
+        super(source);
+        this.userIds = userIds;
+        this.groupId = groupId;
+        this.groupType = groupType;
+    }
+
+    public Integer[] getUserId() {
+        return userIds;
+    }
+
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public GroupType getGroupType() {
+        return groupType;
+    }
+}

+ 30 - 0
mec-biz/src/main/java/com/ym/mec/biz/event/listener/StudentEventListener.java

@@ -0,0 +1,30 @@
+package com.ym.mec.biz.event.listener;
+
+import com.ym.mec.biz.dal.dao.CourseScheduleDao;
+import com.ym.mec.biz.event.StudentCourseChangeEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.09.24
+ */
+@Component
+public class StudentEventListener{
+
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    private CourseScheduleDao courseScheduleDao;
+
+    @Async
+    @EventListener
+    public void onStudentCourseChangeEvent(StudentCourseChangeEvent studentCourseChangeEvent) {
+        courseScheduleDao.countGroupFinishCourse(studentCourseChangeEvent.getGroupId(), studentCourseChangeEvent.getGroupType().getCode());
+        logger.info("用户{}在{}({})团体的课程发生变化.", studentCourseChangeEvent.getUserId(), studentCourseChangeEvent.getGroupType().getDesc(), studentCourseChangeEvent.getGroupId());
+    }
+}

+ 33 - 0
mec-biz/src/main/java/com/ym/mec/biz/event/source/StudentEventSource.java

@@ -0,0 +1,33 @@
+package com.ym.mec.biz.event.source;
+
+import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.biz.event.StudentCourseChangeEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.09.24
+ */
+@Service
+public class StudentEventSource {
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Resource
+    private ApplicationContext applicationContext;
+
+    /**
+     * @describe 学生课程计划变更通知
+     * @author Joburgess
+     * @date 2020.09.24
+     * @param userIds: 用户编号
+     * @return void
+     */
+    public void studentCourseChange(String groupId, GroupType groupType, Integer... userIds) {
+        applicationContext.publishEvent(new StudentCourseChangeEvent(this, groupId, groupType, userIds));
+    }
+}

+ 19 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/GoodsProcurementService.java

@@ -0,0 +1,19 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.entity.GoodsProcurement;
+import com.ym.mec.biz.dal.page.GoodsProcurementQueryInfo;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.service.BaseService;
+
+public interface GoodsProcurementService extends BaseService<Long, GoodsProcurement> {
+
+    /**
+     * @describe 分页查询进货清单
+     * @author Joburgess
+     * @date 2020.10.09
+     * @param queryInfo:
+     * @return com.ym.mec.common.page.PageInfo<com.ym.mec.biz.dal.entity.GoodsProcurement>
+     */
+    PageInfo<GoodsProcurement> queryGoodsProcurements(GoodsProcurementQueryInfo queryInfo);
+
+}

+ 67 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/GoodsService.java

@@ -1,6 +1,11 @@
 package com.ym.mec.biz.service;
 
+import com.ym.mec.biz.dal.dto.GoodsBatchNoDto;
+import com.ym.mec.biz.dal.dto.GoodsSellDto;
 import com.ym.mec.biz.dal.entity.Goods;
+import com.ym.mec.biz.dal.entity.GoodsProcurement;
+import com.ym.mec.biz.dal.entity.SellOrder;
+import com.ym.mec.biz.dal.enums.AccountType;
 import com.ym.mec.common.service.BaseService;
 
 import org.apache.ibatis.annotations.Param;
@@ -11,6 +16,18 @@ import java.util.List;
 
 public interface GoodsService extends BaseService<Integer, Goods> {
 
+    void addGoodsProcurement(Goods goods, Integer operatorId);
+
+    /**
+     * @describe 更新商品状态
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsId:
+     * @param status:
+     * @return void
+     */
+    void updateGoodsStatus(Integer goodsId, Integer status);
+
     /**
      * 通过科目编号查询商品(教材、辅件)列表
      *
@@ -34,7 +51,6 @@ public interface GoodsService extends BaseService<Integer, Goods> {
      */
     List<Goods> findGoodsByIds(String ids);
 
-
     /**
      * 查询某种类型的商品
      * @param type
@@ -51,5 +67,53 @@ public interface GoodsService extends BaseService<Integer, Goods> {
      * @param file:
      * @return java.util.List<com.ym.mec.biz.dal.entity.Goods>
      */
-    List<Goods> importGoods(MultipartFile file) throws Exception;
-}
+    List<Goods> importGoods(MultipartFile file, Integer operatorId) throws Exception;
+
+    /**
+     * @describe 库存预警
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/10
+     * @time 11:30
+     * @return void
+     */
+    void repertoryWarn();
+
+    /**
+     * @describe 给超售商品分配批次
+     * @author Joburgess
+     * @date 2020.10.13
+     * @return void
+     */
+    void sellOrderBatchNoAllot();
+
+    /**
+     * @describe 扣减商品库存
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsIds: 销售商品编号列表
+     * @param accountType: 收款账户类型
+     * @return java.lang.String
+     */
+    List<SellOrder> subtractStock(List<Integer> goodsIds, AccountType accountType);
+
+    /**
+     * @describe 增加商品库存
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param sellOrderIds: 对应批次商品列表
+     * @return void
+     */
+    void increaseStock(List<SellOrder> sellOrderIds, AccountType accountType);
+
+    /**
+     * @describe 获取辅件商品列表
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/13
+     * @time 15:07
+     * @param goodsId:
+     * @return java.util.List<com.ym.mec.biz.dal.dto.GoodsSellDto>
+     */
+    List<GoodsSellDto> queryGoodsSellDtos(String goodsId);
+}

+ 27 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/SellOrderService.java

@@ -25,6 +25,7 @@ public interface SellOrderService extends BaseService<Integer, SellOrder> {
 
     /**
      * 将订单详情加入销售列表
+     *
      * @param orderDetails
      * @param studentPaymentOrder
      * @return
@@ -32,4 +33,30 @@ public interface SellOrderService extends BaseService<Integer, SellOrder> {
     List<SellOrder> addOrderDetail2SellOrder(List<StudentPaymentOrderDetail> orderDetails, StudentPaymentOrder studentPaymentOrder, MusicGroup musicGroup);
 
     void batchInsert(List<SellOrder> sellOrders);
+
+
+    /**
+     * 获取组合商品的相关商品
+     *
+     * @param orderId
+     * @param parentGoodsId
+     * @return
+     */
+    List<SellOrder> getSellOrderByParentGoodsId(Long orderId, Integer parentGoodsId);
+
+    /**
+     * 退货
+     *
+     * @param sellOrders
+     * @return
+     */
+    List<SellOrder> refund(List<SellOrder> sellOrders);
+
+    /**
+     * 根据订单id退货
+     *
+     * @param orderId
+     * @return
+     */
+    List<SellOrder> refundByOrderId(Long orderId);
 }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/StudentGoodsSellService.java

@@ -19,4 +19,15 @@ public interface StudentGoodsSellService extends BaseService<Integer, StudentGoo
      * @return java.lang.Object
      */
     PageInfo<StudentGoodsSellDto> queryStudentGoodsOrders(GoodsSellQueryInfo queryInfo);
+
+    /**
+     * @describe 确认收货
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/10
+     * @time 17:53
+     * @param orderNo:
+     * @return void
+     */
+    void affirmReceive(String orderNo);
 }

+ 13 - 6
mec-biz/src/main/java/com/ym/mec/biz/service/SubjectChangeService.java

@@ -1,18 +1,13 @@
 package com.ym.mec.biz.service;
 
-import com.ym.mec.biz.dal.dto.StudentVisitDto;
+import com.ym.mec.biz.dal.entity.SellOrder;
 import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
 import com.ym.mec.biz.dal.entity.SubjectChange;
-import com.ym.mec.biz.dal.page.StudentVisitQueryInfo;
 import com.ym.mec.biz.dal.page.SubjectChangeQueryInfo;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.BaseService;
-import com.ym.mec.util.collection.MapUtil;
-import com.ym.mec.util.date.DateUtil;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -72,4 +67,16 @@ public interface SubjectChangeService extends BaseService<Integer, SubjectChange
      * @return
      */
     SubjectChange updateCostMargin(Integer id,BigDecimal costMargin);
+
+
+    /**
+     * 添加
+     * @param orderId
+     * @param musicGroupId
+     * @param goodsIds
+     * @param totalAmount
+     * @param balance
+     * @return
+     */
+    List<SellOrder> addSellOrder(Long orderId, String musicGroupId, List<Integer> goodsIds, BigDecimal totalAmount, BigDecimal balance);
 }

+ 2 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/SysPaymentConfigService.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.service;
 
 import com.ym.mec.biz.dal.entity.SysPaymentConfig;
+import com.ym.mec.biz.dal.enums.AccountType;
 import com.ym.mec.biz.dal.enums.PaymentChannelEnum;
 import com.ym.mec.common.service.BaseService;
 
@@ -37,5 +38,5 @@ public interface SysPaymentConfigService extends BaseService<Integer, SysPayment
      * @param merNos
      * @return
      */
-    Boolean checkOutAccount(PaymentChannelEnum payType,String merNos);
+    AccountType checkAccountType(PaymentChannelEnum payType, String merNos);
 }

+ 25 - 20
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -138,17 +138,7 @@ import com.ym.mec.biz.dal.page.CourseScheduleQueryInfo;
 import com.ym.mec.biz.dal.page.EndCourseScheduleQueryInfo;
 import com.ym.mec.biz.dal.page.StudentCourseScheduleRecordQueryInfo;
 import com.ym.mec.biz.dal.page.VipGroupQueryInfo;
-import com.ym.mec.biz.service.ClassGroupService;
-import com.ym.mec.biz.service.ClassGroupTeacherMapperService;
-import com.ym.mec.biz.service.CourseHomeworkService;
-import com.ym.mec.biz.service.CourseScheduleService;
-import com.ym.mec.biz.service.CourseScheduleStudentPaymentService;
-import com.ym.mec.biz.service.CourseScheduleTeacherSalaryService;
-import com.ym.mec.biz.service.MusicGroupService;
-import com.ym.mec.biz.service.PracticeGroupService;
-import com.ym.mec.biz.service.SysConfigService;
-import com.ym.mec.biz.service.SysMessageService;
-import com.ym.mec.biz.service.VipGroupService;
+import com.ym.mec.common.constant.CommonConstants;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImGroupMember;
 import com.ym.mec.common.entity.ImGroupModel;
@@ -1410,6 +1400,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 		Map<Long, CourseSchedule> idCourseMap = courseSchedules.stream().collect(Collectors.toMap(CourseSchedule::getId, c -> c));
 		List<Long> courseIds = courseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
 		List<CourseSchedule> existCourses = courseScheduleDao.findByCourseScheduleIds(courseIds);
+
 		List<CourseScheduleModifyLog> scheduleModifyLogs = new ArrayList<>();
 		Date now=new Date();
 		for (CourseSchedule existCours : existCourses) {
@@ -1434,6 +1425,21 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 			scheduleModifyLog.setCurrentCourseSchedule(JSONObject.toJSONString(existCours));
 			scheduleModifyLogs.add(scheduleModifyLog);
 		}
+
+		Date startDateTime = existCourses.stream().min(Comparator.comparing(CourseSchedule::getStartClassTime)).get().getStartClassTime();
+		Date endDateTime = existCourses.stream().min(Comparator.comparing(CourseSchedule::getEndClassTime)).get().getEndClassTime();
+		if(PRACTICE.equals(existCourses.get(0).getGroupType())){
+			PracticeGroup practiceGroup = practiceGroupDao.get(Long.valueOf(existCourses.get(0).getMusicGroupId()));
+			if(practiceGroup.getType() != TRIAL){
+				if(DateUtil.minutesBetween(startDateTime,practiceGroup.getCoursesStartDate()) > 0){
+					throw new BizException("调整失败: 调整时间不得早于开课时间");
+				}
+				if(DateUtil.minutesBetween(practiceGroup.getCoursesExpireDate(),endDateTime) > 0){
+					throw new BizException("调整失败: 截止时间超过课程有效期");
+				}
+			}
+		}
+
 		checkNewCourseSchedules(existCourses, false);
 		courseScheduleDao.batchUpdate(existCourses);
 
@@ -1843,8 +1849,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                                 ||!preCourseSchedule.getEndClassTime().after(backCourseSchedule.getStartClassTime())) {
                             continue;
                         }
-                        if (!checkExistCourseSchedule
-                                && !courseScheduleIdsSet.contains(backCourseSchedule.getId())) {
+                        if (preCourseSchedule.equals(backCourseSchedule)) {
                             continue;
                         }
 
@@ -2311,13 +2316,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
         errInfo.append("安排的课程存在冲突,");
         errInfo.append("冲突课程为:");
 
-        if (Objects.isNull(preCourseSchedule.getId()) && Objects.isNull(backCourseSchedule.getId())) {
-            errInfo.setLength(0);
-            errInfo.append("您设置的循环周期存在时间冲突");
-            return errInfo.toString();
-        }
-
-        CourseSchedule courseSchedule = new CourseSchedule();
+        CourseSchedule courseSchedule = null;
         if (Objects.nonNull(preCourseSchedule.getId()) && existCourseScheduleIds.contains(preCourseSchedule.getId())) {
             courseSchedule = preCourseSchedule;
         }
@@ -2325,6 +2324,12 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             courseSchedule = backCourseSchedule;
         }
 
+		if (Objects.isNull(courseSchedule)) {
+			errInfo.setLength(0);
+			errInfo.append("您设置的循环周期存在时间冲突");
+			return errInfo.toString();
+		}
+
         String groupName = "";
 
         if (Objects.nonNull(courseSchedule.getId())) {

+ 47 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/GoodsProcurementServiceImpl.java

@@ -0,0 +1,47 @@
+package com.ym.mec.biz.service.impl;
+
+import java.util.*;
+
+import com.ym.mec.biz.dal.page.GoodsProcurementQueryInfo;
+import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.util.collection.MapUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.ym.mec.biz.dal.entity.GoodsProcurement;
+import com.ym.mec.biz.service.GoodsProcurementService;
+import com.ym.mec.biz.dal.dao.GoodsProcurementDao;
+import org.springframework.stereotype.Service;
+
+@Service
+public class GoodsProcurementServiceImpl extends BaseServiceImpl<Long, GoodsProcurement> implements GoodsProcurementService {
+	
+	@Autowired
+	private GoodsProcurementDao goodsProcurementDao;
+
+	@Override
+	public BaseDAO<Long, GoodsProcurement> getDAO() {
+		return goodsProcurementDao;
+	}
+
+	@Override
+	public PageInfo<GoodsProcurement> queryGoodsProcurements(GoodsProcurementQueryInfo queryInfo) {
+		PageInfo<GoodsProcurement> pageInfo = new PageInfo(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+
+		List<GoodsProcurement> dataList = null;
+		int count = goodsProcurementDao.countGoodsProcurements(params);
+		if (count > 0) {
+			pageInfo.setTotal(count);
+			params.put("offset", pageInfo.getOffset());
+			dataList = goodsProcurementDao.queryGoodsProcurements(params);
+		}
+		if (count == 0) {
+			dataList = new ArrayList();
+		}
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+}

+ 355 - 13
mec-biz/src/main/java/com/ym/mec/biz/service/impl/GoodsServiceImpl.java

@@ -1,18 +1,30 @@
 package com.ym.mec.biz.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.ym.mec.biz.dal.dao.GoodsDao;
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.*;
+import com.ym.mec.biz.dal.dto.BasicUserDto;
+import com.ym.mec.biz.dal.dto.GoodsBatchNoDto;
+import com.ym.mec.biz.dal.dto.GoodsSellDto;
 import com.ym.mec.biz.dal.entity.Goods;
-import com.ym.mec.biz.dal.enums.GoodsType;
-import com.ym.mec.biz.dal.enums.TemplateTypeEnum;
+import com.ym.mec.biz.dal.entity.GoodsProcurement;
+import com.ym.mec.biz.dal.entity.SellOrder;
+import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.service.GoodsService;
+import com.ym.mec.biz.service.SellOrderService;
+import com.ym.mec.biz.service.SysMessageService;
 import com.ym.mec.biz.service.UploadFileService;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.UploadReturnBean;
 import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.service.IdGeneratorService;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
 import com.ym.mec.util.excel.IniFileUtil;
 import com.ym.mec.util.excel.POIUtil;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.PictureData;
 import org.slf4j.Logger;
@@ -20,14 +32,17 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 @Service
 public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implements GoodsService {
@@ -37,6 +52,18 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 	private GoodsDao goodsDao;
 	@Autowired
 	private UploadFileService uploadFileService;
+	@Autowired
+	private IdGeneratorService idGeneratorService;
+	@Autowired
+	private GoodsProcurementDao goodsProcurementDao;
+	@Autowired
+	private SysConfigDao sysConfigDao;
+	@Autowired
+	private SysMessageService sysMessageService;
+	@Autowired
+	private TeacherDao teacherDao;
+	@Autowired
+	private SellOrderDao sellOrderDao;
 
 	@Override
 	public BaseDAO<Integer, Goods> getDAO() {
@@ -44,6 +71,72 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 	}
 
 	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void addGoodsProcurement(Goods goods, Integer operatorId) {
+		Goods existsGood = goodsDao.findBySn(goods.getSn());
+		if(Objects.nonNull(existsGood)){
+			if(Objects.nonNull(existsGood.getComplementGoodsIdList())){
+				throw new BizException("此货号组合商品已存在");
+			}
+			existsGood.setStockCount(existsGood.getStockCount()+goods.getStockCount());
+			existsGood.setTaxStockCount(existsGood.getTaxStockCount()+existsGood.getTaxStockCount());
+			goodsDao.update(existsGood);
+		}else{
+			goodsDao.insert(goods);
+			existsGood=goods;
+		}
+
+		if(StringUtils.isNotBlank(existsGood.getComplementGoodsIdList())){
+			String batchNo = idGeneratorService.generatorId("payment") + "";
+			GoodsProcurement gp = new GoodsProcurement();
+			gp.setGoodsId(existsGood.getId());
+			gp.setGoodsCategoryId(goods.getGoodsCategoryId());
+			gp.setSupplyChannel(goods.getSupplyChannel());
+			gp.setDiscountPrice(goods.getDiscountPrice());
+			gp.setAgreeCostPrice(goods.getAgreeCostPrice());
+			gp.setStockCount(goods.getStockCount());
+			gp.setTaxStockCount(goods.getTaxStockCount());
+			gp.setOperatorId(operatorId);
+			gp.setBatchNo(batchNo);
+			goodsProcurementDao.insert(gp);
+		}
+	}
+
+	@Override
+	public void updateGoodsStatus(Integer goodsId, Integer status) {
+		if(Objects.isNull(goodsId)){
+			throw new BizException("请指定商品");
+		}
+		if(Objects.isNull(status)){
+			throw new BizException("请指定状态");
+		}
+		Goods goods = goodsDao.get(goodsId);
+		if(Objects.isNull(goods)){
+			throw new BizException("商品不存在");
+		}
+		if(StringUtils.isBlank(goods.getComplementGoodsIdList())){
+			if(status==0){
+				List<Goods> goodsList = goodsDao.getWithComplementGoodsAndStatus(goodsId, 1);
+				if(!CollectionUtils.isEmpty(goodsList)){
+					String goodsNames = StringUtils.join(goodsList.stream().map(Goods::getName).collect(Collectors.toList()));
+					throw new BizException("{}等商品还在销售中", goodsNames);
+				}
+			}
+		}else{
+			if(status==1){
+				List<Integer> goodsIds = Arrays.stream(goods.getComplementGoodsIdList().split(",")).map(s -> Integer.valueOf(s)).collect(Collectors.toList());
+				List<Goods> goodList = goodsDao.getGoodies(goodsIds);
+				List<String> goodsNames = goodList.stream().filter(g -> YesOrNoEnum.NO.equals(g.getStatus())).map(Goods::getName).collect(Collectors.toList());
+				if(!CollectionUtils.isEmpty(goodsNames)){
+					throw new BizException("{}商品还未上架", StringUtils.join(goodsNames));
+				}
+			}
+		}
+		goods.setStatus(status==0?YesOrNoEnum.NO:YesOrNoEnum.YES);
+		goodsDao.update(goods);
+	}
+
+	@Override
 	public List<Goods> findGoodsBySubId(Integer subjectId,String type) {
 		return goodsDao.findGoodsBySubId(subjectId,type);
 	}
@@ -63,8 +156,8 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 	}
 
 	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public List<Goods> importGoods(MultipartFile file) throws Exception {
+	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+	public List<Goods> importGoods(MultipartFile file, Integer operatorId) throws Exception {
 		Map<String, List<Map<String, Object>>> sheetsListMap = POIUtil.importExcel(new ByteArrayInputStream(file.getBytes()), 2, file.getOriginalFilename());
 		InputStream inputStream = new ClassPathResource("columnMapper.ini").getInputStream();
 		Map<String,String> columns = IniFileUtil.readIniFile(inputStream, TemplateTypeEnum.GOODS.getMsg());
@@ -83,7 +176,7 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 						continue;
 					}
 					String columnValue = columns.get(s);
-					if(null == row.get(s) || StringUtils.isEmpty(row.get(s).toString())){
+					if(null == row.get(s) || StringUtils.isBlank(row.get(s).toString())){
 						LOGGER.error("商品导入异常:参数{}不可为空 param:{}",columnValue,objectMap);
 						continue valueIsNull;
 					}
@@ -127,13 +220,262 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 					goods = JSONObject.parseObject(objectMap.toJSONString(),Goods.class);
 					goodsList.add(goods);
 				} catch (Exception ex) {
-					throw new BizException("导入数据出错");
+					throw new BizException("导入数据出错", ex);
 				}
 			}
 		}
-		if(goodsList.size() != 0){
-			goodsDao.batchInsert(goodsList);
+		if(CollectionUtils.isEmpty(goodsList)){
+			return goodsList;
+		}
+
+		List<String> goodsSnList = goodsList.stream().map(Goods::getSn).collect(Collectors.toList());
+		List<Goods> existsGoods = goodsDao.findBySns(goodsSnList);
+		List<String> existsSns = existsGoods.stream().map(Goods::getSn).collect(Collectors.toList());
+
+		Map<String, List<Goods>> snGoodsMap = goodsList.stream().collect(Collectors.groupingBy(Goods::getSn));
+		for (Goods existsGood : existsGoods) {
+			List<Goods> goods = snGoodsMap.get(existsGood.getSn());
+			int stockCount = goods.stream().mapToInt(Goods::getStockCount).sum();
+			int taxStockCount = goods.stream().mapToInt(Goods::getTaxStockCount).sum();
+			existsGood.setStockCount((Objects.isNull(existsGood.getStockCount())?0:existsGood.getStockCount()) + stockCount);
+			existsGood.setTaxStockCount((Objects.isNull(existsGood.getTaxStockCount())?0:existsGood.getTaxStockCount()) + taxStockCount);
+		}
+
+		if(!CollectionUtils.isEmpty(existsGoods)){
+			goodsDao.batchUpdate(existsGoods);
+		}
+		List<Goods> newGoods = goodsList.stream().filter(g -> !existsSns.contains(g.getSn())).collect(Collectors.toList());
+		if(!CollectionUtils.isEmpty(newGoods)){
+			goodsDao.batchInsert(newGoods);
 		}
+
+		String batchNo = idGeneratorService.generatorId("payment") + "";
+		Map<String, Integer> existsSnIdMap = existsGoods.stream().collect(Collectors.toMap(Goods::getSn, g -> g.getId()));
+		Map<String, Integer> newSnIdMap = newGoods.stream().collect(Collectors.toMap(Goods::getSn, g -> g.getId()));
+		existsSnIdMap.putAll(newSnIdMap);
+
+		List<GoodsProcurement> goodsProcurements = new ArrayList<>();
+		for (Goods goods : goodsList) {
+			GoodsProcurement gp = new GoodsProcurement();
+			gp.setGoodsId(existsSnIdMap.get(goods.getSn()));
+			gp.setGoodsCategoryId(goods.getGoodsCategoryId());
+			gp.setSupplyChannel(goods.getSupplyChannel());
+			gp.setDiscountPrice(goods.getCostPrice()
+			);
+			gp.setAgreeCostPrice(goods.getAgreeCostPrice());
+			gp.setStockCount(goods.getStockCount());
+			gp.setTaxStockCount(goods.getTaxStockCount());
+			gp.setOperatorId(operatorId);
+			gp.setBatchNo(batchNo);
+			goodsProcurements.add(gp);
+		}
+		goodsProcurementDao.batchInsert(goodsProcurements);
+
+		sellOrderBatchNoAllot();
+
 		return goodsList;
 	}
-}
+
+	@Override
+	public void repertoryWarn() {
+		//预警手机号
+		String repertoryWarnPhone = sysConfigDao.findConfigValue("repertory_warn_phone");
+		if(StringUtils.isEmpty(repertoryWarnPhone)){
+			return;
+		}
+		BasicUserDto sysUser = teacherDao.findUserByPhone(repertoryWarnPhone);
+		if(sysUser == null || sysUser.getUserId() == null){
+			throw new BizException("库存预警手机号不存在");
+		}
+		Map<Integer, String> receivers = new HashMap<>(1);
+		receivers.put(sysUser.getUserId(), repertoryWarnPhone);
+		//内部库存预警
+		String innerRepertoryWarnNum = sysConfigDao.findConfigValue("inner_repertory_warn_num");
+		if(StringUtils.isNotEmpty(innerRepertoryWarnNum)){
+			String goodsNames = goodsDao.getInnerRepertoryWarnName(innerRepertoryWarnNum);
+			if(StringUtils.isNotEmpty(goodsNames)){
+				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.YIMEI, MessageTypeEnum.SMS_GOODS_REPERTORY_WARN, receivers, null, 0, null,null,
+						goodsNames,"内部");
+			}
+		}
+
+		//外部库存预警
+		String outerRepertoryWarnNum = sysConfigDao.findConfigValue("outer_repertory_warn_num");
+		if(StringUtils.isNotEmpty(outerRepertoryWarnNum)){
+			String goodsNames = goodsDao.getOuterRepertoryWarnName(outerRepertoryWarnNum);
+			if(StringUtils.isNotEmpty(goodsNames)){
+				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.YIMEI, MessageTypeEnum.SMS_GOODS_REPERTORY_WARN, receivers, null, 0, null,null,
+						goodsNames,"税务");
+			}
+		}
+	}
+
+	@Override
+	public void sellOrderBatchNoAllot() {
+		List<SellOrder> noneBatchNoSellOrders = sellOrderDao.getNoneBatchNoSellOrders();
+		if(CollectionUtils.isEmpty(noneBatchNoSellOrders)){
+			return;
+		}
+		List<SellOrder> updateSellOrders = new ArrayList<>();
+		for (SellOrder noneBatchNoSellOrder : noneBatchNoSellOrders) {
+			GoodsProcurement goodsProcurement = null;
+			if(StockType.INTERNAL.equals(noneBatchNoSellOrder.getStockType())||(StockType.ALL.equals(noneBatchNoSellOrder.getStockType())&&AccountType.INTERNAL.equals(noneBatchNoSellOrder.getAccountType()))){
+				goodsProcurement = goodsProcurementDao.getWithStockSurplusProcurement(noneBatchNoSellOrder.getGoodsId());
+				if(Objects.nonNull(goodsProcurement)){
+					goodsProcurement.setStockSoldNum(new AtomicInteger(goodsProcurement.getStockSoldNum()).incrementAndGet());
+				}
+			}else if(StockType.EXTERNAL.equals(noneBatchNoSellOrder.getStockType())||(StockType.ALL.equals(noneBatchNoSellOrder.getStockType())&&AccountType.EXTERNAL.equals(noneBatchNoSellOrder.getAccountType()))){
+				goodsProcurement = goodsProcurementDao.getWithTaxStockSurplusProcurement(noneBatchNoSellOrder.getGoodsId());
+				if(Objects.nonNull(goodsProcurement)){
+					goodsProcurement.setTaxStockSoldNum(new AtomicInteger(goodsProcurement.getTaxStockSoldNum()).incrementAndGet());
+				}
+			}
+
+			if(Objects.nonNull(goodsProcurement)){
+				goodsProcurementDao.update(goodsProcurement);
+				noneBatchNoSellOrder.setBatchNo(goodsProcurement.getBatchNo());
+				noneBatchNoSellOrder.setSellCost(goodsProcurement.getDiscountPrice());
+				updateSellOrders.add(noneBatchNoSellOrder);
+			}
+		}
+		if(!CollectionUtils.isEmpty(updateSellOrders)){
+			sellOrderDao.batchUpdate(updateSellOrders);
+		}
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+	public List<SellOrder> subtractStock(List<Integer> goodsIds, AccountType accountType) {
+		if(CollectionUtils.isEmpty(goodsIds)){
+			return Collections.emptyList();
+		}
+
+		List<Goods> tempGoodsList = goodsDao.lockGoods(new ArrayList<>(goodsIds));
+		Map<Integer, Goods> idTempGoodsMap = tempGoodsList.stream().collect(Collectors.toMap(Goods::getId, g -> g));
+		List<GoodsProcurement> goodsProcurements = new ArrayList<>();
+		for (Integer goodsId : goodsIds) {
+			Goods tempGoods = idTempGoodsMap.get(goodsId);
+			List<Goods> childGoods = new ArrayList<>();
+			if(StringUtils.isBlank(tempGoods.getComplementGoodsIdList())){
+				childGoods.add(tempGoods);
+			}else{
+				List<Integer> complementGoodsIds = Arrays.stream(tempGoods.getComplementGoodsIdList().split(",")).map(s -> Integer.valueOf(s)).collect(Collectors.toList());
+				childGoods = goodsDao.getGoodies(complementGoodsIds);
+			}
+			for (Goods goods : childGoods) {
+				GoodsProcurement goodsProcurement = null;
+				if(StockType.INTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.INTERNAL.equals(accountType))){
+					goodsProcurement = goodsProcurementDao.getWithStockSurplusProcurement(goods.getId());
+					goods.setStockCount(new AtomicInteger(goods.getStockCount()).decrementAndGet());
+					if(Objects.nonNull(goodsProcurement)){
+						goodsProcurement.setStockSoldNum(new AtomicInteger(goodsProcurement.getStockSoldNum()).incrementAndGet());
+					}
+				}else if(StockType.EXTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.EXTERNAL.equals(accountType))){
+					goodsProcurement = goodsProcurementDao.getWithTaxStockSurplusProcurement(goods.getId());
+					goods.setTaxStockCount(new AtomicInteger(goods.getTaxStockCount()).decrementAndGet());
+					if(Objects.nonNull(goodsProcurement)){
+						goodsProcurement.setTaxStockSoldNum(new AtomicInteger(goodsProcurement.getTaxStockSoldNum()).incrementAndGet());
+					}
+				}
+
+				goods.setSellCount(new AtomicInteger(goods.getSellCount()).incrementAndGet());
+
+				goodsDao.update(goods);
+				if(Objects.nonNull(goodsProcurement)){
+					goodsProcurementDao.update(goodsProcurement);
+				}else{
+					goodsProcurement = new GoodsProcurement(goods.getId());
+				}
+				if(StringUtils.isNotBlank(tempGoods.getComplementGoodsIdList())){
+					goodsProcurement.setParentGoodsId(tempGoods.getId());
+				}
+
+				goodsProcurements.add(goodsProcurement);
+			}
+		}
+
+		List<SellOrder> sellOrders = new ArrayList<>();
+
+		List<GoodsProcurement> singleGoodsList = goodsProcurements.stream().filter(g -> Objects.isNull(g.getParentGoodsId())&&Objects.nonNull(g.getBatchNo())).collect(Collectors.toList());
+		if(!CollectionUtils.isEmpty(singleGoodsList)){
+			Map<String, List<Integer>> batchNoGoodsIdMap = singleGoodsList.stream().collect(Collectors.groupingBy(GoodsProcurement::getBatchNo, Collectors.mapping(GoodsProcurement::getGoodsId, Collectors.toList())));
+			for (Map.Entry<String, List<Integer>> batchNoGoodsIdMapEntry : batchNoGoodsIdMap.entrySet()) {
+				Map<Integer, Long> goodsNumMap = batchNoGoodsIdMapEntry.getValue().stream().collect(Collectors.groupingBy(gid -> gid, Collectors.counting()));
+				for (Map.Entry<Integer, Long> goodsNumMapEntry : goodsNumMap.entrySet()) {
+					Goods goods = idTempGoodsMap.get(goodsNumMapEntry.getKey());
+					SellOrder sellOrder = new SellOrder();
+					sellOrder.setGoodsId(goodsNumMapEntry.getKey());
+					sellOrder.setNum(goodsNumMapEntry.getValue().intValue());
+					sellOrder.setStockType(goods.getStockType());
+					sellOrder.setAccountType(accountType);
+					sellOrder.setBatchNo(batchNoGoodsIdMapEntry.getKey());
+					GoodsProcurement goodsProcurement = goodsProcurementDao.getWithGoodsAndBatchNo(sellOrder.getGoodsId(), sellOrder.getBatchNo());
+					sellOrder.setSellCost(goodsProcurement.getDiscountPrice().multiply(new BigDecimal(sellOrder.getNum())));
+					sellOrders.add(sellOrder);
+				}
+			}
+		}
+
+		List<GoodsProcurement> groupGoodsList = goodsProcurements.stream().filter(g -> Objects.nonNull(g.getParentGoodsId())||Objects.isNull(g.getBatchNo())).collect(Collectors.toList());
+		if(!CollectionUtils.isEmpty(groupGoodsList)){
+			for (GoodsProcurement goodsProcurement : groupGoodsList) {
+				Goods goods = goodsDao.get(goodsProcurement.getGoodsId());
+				SellOrder sellOrder = new SellOrder();
+				sellOrder.setParentGoodsId(goodsProcurement.getParentGoodsId());
+				sellOrder.setGoodsId(goodsProcurement.getGoodsId());
+				sellOrder.setNum(1);
+				sellOrder.setStockType(goods.getStockType());
+				sellOrder.setAccountType(accountType);
+				sellOrder.setBatchNo(goodsProcurement.getBatchNo());
+				if(Objects.nonNull(goodsProcurement.getBatchNo())){
+					sellOrder.setSellCost(goodsProcurement.getDiscountPrice().multiply(new BigDecimal(sellOrder.getNum())));
+				}
+				sellOrders.add(sellOrder);
+			}
+		}
+
+		return sellOrders;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+	public void increaseStock(List<SellOrder> sellOrders, AccountType accountType) {
+		if(CollectionUtils.isEmpty(sellOrders)){
+			return;
+		}
+
+		Set<Integer> goodsIdList = new HashSet<>();
+		sellOrders.forEach(so -> {
+			if(Objects.nonNull(so.getParentGoodsId())){
+				goodsIdList.add(so.getParentGoodsId());
+			}else{
+				goodsIdList.add(so.getGoodsId());
+			}
+		});
+
+		for (SellOrder sellOrder : sellOrders) {
+			Goods goods = goodsDao.get(sellOrder.getGoodsId());
+			GoodsProcurement goodsProcurement = goodsProcurementDao.getWithGoodsAndBatchNo(sellOrder.getGoodsId(), sellOrder.getBatchNo());
+			if(StockType.INTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.INTERNAL.equals(accountType))){
+				goods.setStockCount(new AtomicInteger(goods.getStockCount()).addAndGet(sellOrder.getNum()));
+				if(Objects.nonNull(goodsProcurement)){
+					goodsProcurement.setStockSoldNum(new AtomicInteger(goodsProcurement.getStockSoldNum()).addAndGet(-sellOrder.getNum()));
+				}
+			}else if(StockType.EXTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.EXTERNAL.equals(accountType))){
+				goods.setTaxStockCount(new AtomicInteger(goods.getTaxStockCount()).addAndGet(sellOrder.getNum()));
+				if(Objects.nonNull(goodsProcurement)){
+					goodsProcurement.setTaxStockSoldNum(new AtomicInteger(goodsProcurement.getTaxStockSoldNum()).addAndGet(-sellOrder.getNum()));
+				}
+			}
+			goods.setSellCount(new AtomicInteger(goods.getSellCount()).addAndGet(-sellOrder.getNum()));
+
+			goodsDao.update(goods);
+			goodsProcurementDao.update(goodsProcurement);
+		}
+	}
+
+	@Override
+	public List<GoodsSellDto> queryGoodsSellDtos(String goodsId) {
+		return goodsDao.queryGoodsSellDtos(goodsId);
+	}
+}

+ 81 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SellOrderServiceImpl.java

@@ -7,16 +7,15 @@ import com.ym.mec.biz.dal.dao.MusicGroupDao;
 import com.ym.mec.biz.dal.dao.SellOrderDao;
 import com.ym.mec.biz.dal.dao.StudentPaymentOrderDao;
 import com.ym.mec.biz.dal.entity.*;
-import com.ym.mec.biz.dal.enums.GoodsType;
-import com.ym.mec.biz.dal.enums.KitGroupPurchaseTypeEnum;
-import com.ym.mec.biz.dal.enums.OrderDetailTypeEnum;
-import com.ym.mec.biz.dal.enums.SellTypeEnum;
+import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.service.*;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import org.apache.commons.lang3.StringUtils;
 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.*;
@@ -31,6 +30,12 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
     private StudentPaymentOrderDao studentPaymentOrderDao;
     @Autowired
     private MusicGroupDao musicGroupDao;
+    @Autowired
+    private SysPaymentConfigService sysPaymentConfigService;
+    @Autowired
+    private SysUserCashAccountService sysUserCashAccountService;
+    @Autowired
+    private GoodsService goodsService;
 
     @Override
     public BaseDAO<Integer, SellOrder> getDAO() {
@@ -67,6 +72,12 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
         BigDecimal hasRouteBalance = BigDecimal.ZERO;
         BigDecimal goodsTotalBalance = goodsTotalPrice.multiply(balance).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
         List<SellOrder> sellOrders = new ArrayList<>();
+
+        AccountType accountType = sysPaymentConfigService.checkAccountType(PaymentChannelEnum.valueOf(order.getPaymentChannel()), order.getMerNos());
+
+        //批次号 TODO
+        List<SellOrder> sellOrderList = goodsService.subtractStock(goodsIds, accountType);
+
         for (Integer goodsId : goodsIds) {
             SellOrder sellOrder = new SellOrder();
             BigDecimal goodsPrice = BigDecimal.ZERO;
@@ -106,6 +117,7 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
             sellOrder.setUserId(order.getUserId());
             sellOrder.setPaymentChannel(order.getPaymentChannel());
             sellOrder.setMerNo(order.getMerNos());
+            sellOrder.setAccountType(accountType);
             sellOrder.setSellTime(order.getCreateTime());
             sellOrder.setCreateIme(new Date());
             sellOrder.setUpdateTime(new Date());
@@ -116,6 +128,25 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
             } else {
                 sellOrder.setType(SellTypeEnum.OTHER);
             }
+
+            StockType goodsStockType = StockType.INTERNAL;
+            for (Goods goods : goodies) {
+                if (goods.getId().equals(goodsId)) {
+                    goodsStockType = goods.getStockType();
+                    break;
+                }
+            }
+            //库存类型
+            if (goodsStockType.equals(StockType.ALL) && accountType.equals(AccountType.INTERNAL)) {
+                sellOrder.setStockType(StockType.INTERNAL);
+            } else if (goodsStockType.equals(StockType.ALL) && accountType.equals(AccountType.EXTERNAL)) {
+                sellOrder.setStockType(StockType.EXTERNAL);
+            } else {
+                sellOrder.setStockType(goodsStockType);
+            }
+            //批次号 TODO
+            //goodsService.subtractStock();
+
             sellOrders.add(sellOrder);
             i++;
         }
@@ -138,8 +169,10 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
 
         int i = 1;
         BigDecimal detailRouteBalance = BigDecimal.ZERO;
-        for (StudentPaymentOrderDetail orderDetail : orderDetails) {
 
+        AccountType accountType = sysPaymentConfigService.checkAccountType(PaymentChannelEnum.valueOf(studentPaymentOrder.getPaymentChannel()), studentPaymentOrder.getMerNos());
+
+        for (StudentPaymentOrderDetail orderDetail : orderDetails) {
             BigDecimal detailBalance = orderDetail.getPrice().compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO :
                     orderDetail.getPrice().multiply(detailTotalBalance).divide(detailTotalPrice, 2, BigDecimal.ROUND_HALF_UP);
             if (i == orderDetails.size()) {
@@ -192,6 +225,7 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
                 sellOrder.setUserId(studentPaymentOrder.getUserId());
                 sellOrder.setPaymentChannel(studentPaymentOrder.getPaymentChannel());
                 sellOrder.setMerNo(studentPaymentOrder.getMerNos());
+                sellOrder.setAccountType(accountType);
                 sellOrder.setSellTime(studentPaymentOrder.getCreateTime());
                 sellOrder.setCreateIme(new Date());
                 sellOrder.setUpdateTime(new Date());
@@ -211,6 +245,16 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
                     sellOrder.setBalanceAmount(BigDecimal.ZERO);
                     sellOrder.setExpectAmount(BigDecimal.ZERO);
                 }
+                //库存类型
+                if (goods.getStockType().equals(StockType.ALL) && accountType.equals(AccountType.INTERNAL)) {
+                    sellOrder.setStockType(StockType.INTERNAL);
+                } else if (goods.getStockType().equals(StockType.ALL) && accountType.equals(AccountType.EXTERNAL)) {
+                    sellOrder.setStockType(StockType.EXTERNAL);
+                } else {
+                    sellOrder.setStockType(goods.getStockType());
+                }
+                //批次号 TODO
+
                 sellOrders.add(sellOrder);
             }
         }
@@ -225,4 +269,36 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
         sellOrderDao.batchInsert(sellOrders);
     }
 
+    @Override
+    public List<SellOrder> getSellOrderByParentGoodsId(Long orderId, Integer parentGoodsId) {
+        return sellOrderDao.getSellOrderByParentGoodsId(orderId, parentGoodsId);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public List<SellOrder> refund(List<SellOrder> sellOrders) {
+        for (SellOrder sellOrder : sellOrders) {
+            //1、更改销售列表状态
+            sellOrder.setStatus(SellStatus.REFUND);
+            sellOrder.setUpdateTime(new Date());
+            sellOrderDao.update(sellOrder);
+
+            //2、金额退到余额
+            if (sellOrder.getActualAmount().compareTo(BigDecimal.ZERO) > 0) {
+                sysUserCashAccountService.updateBalance(sellOrder.getUserId(), sellOrder.getActualAmount(), PlatformCashAccountDetailTypeEnum.REFUNDS, "订单:" + sellOrder.getOrderId() + " 商品id:" + sellOrder.getGoodsId() + "退货");
+            }
+        }
+        //3、退货
+        if (sellOrders.get(0).getAccountType() != null) {
+            goodsService.increaseStock(sellOrders, sellOrders.get(0).getAccountType());
+        }
+        return sellOrders;
+    }
+
+    @Override
+    public List<SellOrder> refundByOrderId(Long orderId) {
+        List<SellOrder> sellOrders = sellOrderDao.getSellOrderByParentGoodsId(orderId, null);
+        return refund(sellOrders);
+    }
+
 }

+ 25 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentGoodsSellServiceImpl.java

@@ -2,6 +2,7 @@ package com.ym.mec.biz.service.impl;
 
 
 import com.ym.mec.biz.dal.dao.StudentGoodsSellDao;
+import com.ym.mec.biz.dal.dao.SysConfigDao;
 import com.ym.mec.biz.dal.dto.StudentGoodsSellDto;
 import com.ym.mec.biz.dal.entity.StudentGoodsSell;
 import com.ym.mec.biz.dal.page.GoodsSellQueryInfo;
@@ -11,8 +12,10 @@ import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.util.collection.MapUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -24,6 +27,8 @@ public class StudentGoodsSellServiceImpl extends BaseServiceImpl<Integer, Studen
 	
 	@Autowired
 	private StudentGoodsSellDao studentGoodsSellDao;
+	@Autowired
+	private SysConfigDao sysConfigDao;
 
 	@Override
 	public BaseDAO<Integer, StudentGoodsSell> getDAO() {
@@ -42,6 +47,10 @@ public class StudentGoodsSellServiceImpl extends BaseServiceImpl<Integer, Studen
 			pageInfo.setTotal(count);
 			params.put("offset", pageInfo.getOffset());
 			dataList = studentGoodsSellDao.queryStudentGoodsOrders(params);
+			Integer autoAffirmReceiveTime = Integer.parseInt(sysConfigDao.findConfigValue("auto_affirm_receive_time"));
+			dataList.forEach(e->{
+				e.setAutoAffirmReceiveTime(autoAffirmReceiveTime);
+			});
 		}
 		if (count == 0) {
 			dataList = new ArrayList<>();
@@ -49,4 +58,20 @@ public class StudentGoodsSellServiceImpl extends BaseServiceImpl<Integer, Studen
 		pageInfo.setRows(dataList);
 		return pageInfo;
 	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void affirmReceive(String orderNo) {
+		String str = "MANUAL_RECEIVE";
+		//如果订单编号为空,那么自动确认
+		if(StringUtils.isEmpty(orderNo)){
+			String autoAffirmReceiveTime = sysConfigDao.findConfigValue("auto_affirm_receive_time");
+			//获取到期的订单编号
+			orderNo = studentGoodsSellDao.queryNoAffirmOrderNo(autoAffirmReceiveTime);
+			str = "AUTO_RECEIVE";
+		}
+		if(StringUtils.isNotEmpty(orderNo)){
+			studentGoodsSellDao.autoAffirmReceive(orderNo,str);
+		}
+	}
 }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentRouteOrderServiceImpl.java

@@ -150,10 +150,20 @@ public class StudentPaymentRouteOrderServiceImpl extends BaseServiceImpl<Long, S
                 sellOrder.setUserId(studentPaymentRouteOrderDto.getUserId());
                 sellOrder.setPaymentChannel(studentPaymentRouteOrderDto.getPaymentChannel());
                 sellOrder.setMerNo(studentPaymentRouteOrderDto.getMerNos());
+                sellOrder.setAccountType(AccountType.INTERNAL);
                 sellOrder.setSellTime(studentPaymentRouteOrderDto.getCreateTime());
                 sellOrder.setCreateIme(nowDate);
                 sellOrder.setUpdateTime(nowDate);
                 sellOrder.setType(SellTypeEnum.SCHOOL_BUY);
+
+                //库存类型
+                if(goods.getStockType().equals(StockType.ALL)){
+                    sellOrder.setStockType(StockType.INTERNAL);
+                }else {
+                    sellOrder.setStockType(goods.getStockType());
+                }
+                //批次号 TODO
+
                 sellOrders.add(sellOrder);
             }
             sellOrderDao.batchInsert(sellOrders);
@@ -185,6 +195,7 @@ public class StudentPaymentRouteOrderServiceImpl extends BaseServiceImpl<Long, S
         studentPaymentOrderDao.delete(orderId);
         studentPaymentRouteOrderDao.deleteByOrderNo(studentPaymentOrder.getOrderNo());
         sellOrderDao.deleteByOrderId(orderId);
+        //归还库存 TODO
         return true;
     }
 

+ 132 - 28
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRepairServiceImpl.java

@@ -7,6 +7,7 @@ import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.BasicUserDto;
+import com.ym.mec.biz.dal.dto.GoodsBatchNoDto;
 import com.ym.mec.biz.dal.dto.GoodsSellDto;
 import com.ym.mec.biz.dal.dto.RepairGoodsDto;
 import com.ym.mec.biz.dal.entity.*;
@@ -49,6 +50,8 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
     @Autowired
     private StudentPaymentOrderService studentPaymentOrderService;
     @Autowired
+    private SysPaymentConfigService sysPaymentConfigService;
+    @Autowired
     private MusicGroupDao musicGroupDao;
     @Autowired
     private SysUserCashAccountService sysUserCashAccountService;
@@ -133,6 +136,14 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         if (studentId == null) {
             throw new BizException("请指定学员");
         }
+        List<Integer> goodsIds = goodsSellDtos.stream().map(e -> e.getGoodsId()).collect(Collectors.toList());
+        Map<Integer, String> integerStringMap = getMap("goods", "id_", "type_", goodsIds, Integer.class, String.class);
+        goodsSellDtos.forEach(e->{
+            e.setGoodsType(integerStringMap.get(e.getGoodsId()));
+            if(StringUtils.isNotEmpty(e.getComplementGoodsIdList())){
+                e.setGoodsSellDtos(goodsService.queryGoodsSellDtos(e.getComplementGoodsIdList()));
+            }
+        });
         studentDao.lockUser(studentId);
         SysUser student = sysUserFeignService.queryUserById(studentId);
         //如果教务老师为空,代表学员自己创建的订单
@@ -154,7 +165,6 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
                 studentGoodsSell.setCooperationOrganId(musicGroup.getCooperationOrganId());
             }
         }
-        List<Integer> goodsIds = goodsSellDtos.stream().map(e -> e.getGoodsId()).collect(Collectors.toList());
 
         Map<Integer, BigDecimal> map = getMap("goods", "id_", "market_price_", goodsIds, Integer.class, BigDecimal.class);
         for (GoodsSellDto goodsSellDto : goodsSellDtos) {
@@ -737,12 +747,21 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         StudentGoodsSell studentGoodsSell = studentGoodsSellDao.findByOrderNo(orderNo);
         String goodsJson = studentGoodsSell.getGoodsJson();
         List<GoodsSellDto> goodsSellDtos = JSONObject.parseArray(goodsJson, GoodsSellDto.class);
+        //用户选择的商品
         Map<Integer, List<GoodsSellDto>> collect = goodsSellDtos.stream().collect(Collectors.groupingBy(GoodsSellDto::getGoodsId));
-        List<Integer> goodsId = goodsSellDtos.stream().map(e -> e.getGoodsId()).collect(Collectors.toList());
-        List<Goods> goodsByIds = goodsService.findGoodsByIds(StringUtils.join(goodsId, ","));
-        Map<Integer, List<Goods>> goodsMap = goodsByIds.stream().collect(Collectors.groupingBy(Goods::getId));
+        List<Integer> goodsIds = new ArrayList<>();
+        goodsSellDtos.forEach(e->{
+            for (int i = 0; i < e.getGoodsNum(); i++) {
+                goodsIds.add(e.getGoodsId());
+            }
+        });
+        AccountType accountType = AccountType.INTERNAL;
+        if(StringUtils.isNotEmpty(orderByOrderNo.getPaymentChannel())){
+            accountType = sysPaymentConfigService.checkAccountType(PaymentChannelEnum.valueOf(orderByOrderNo.getPaymentChannel()), orderByOrderNo.getMerNos());
+        }
+        //实际扣减的库存商品
+        List<SellOrder> sellOrderList = goodsService.subtractStock(goodsIds, accountType);
         Map<String, BigDecimal> costMap = new HashMap<>(2);
-        List<SellOrder> sellOrders = new ArrayList<>();
         BigDecimal balancePaymentAmount = orderByOrderNo.getBalancePaymentAmount();
         //可用余额
         BigDecimal usableBalance = balancePaymentAmount;
@@ -751,6 +770,10 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         BigDecimal usableMarketAmount = marketAmount;
         //包含减免余额的总金额
         BigDecimal totalAmount = goodsSellDtos.stream().map(e -> e.getTotalGoodsPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
+        //组合商品减免金额
+        Map<Integer,BigDecimal> parentGoodsCutTotalPriceMap = new HashMap<>();
+        //组合商品附加金额
+        Map<Integer,BigDecimal> parentGoodsAddTotalPriceMap = new HashMap<>();
         //应付总额
         BigDecimal totalActual = totalAmount.subtract(marketAmount);
         //可用应付
@@ -759,32 +782,116 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         BigDecimal realityAmount = totalActual.subtract(usableBalance);
         //可用实付总额
         BigDecimal usableAmount = realityAmount;
-        for (int i = 0; i < goodsId.size(); i++) {
-            Integer e = goodsId.get(i);
+        //可用组合商品总减免金额
+        BigDecimal usableParentGoodsCutTotalPrice;
+        //可用组合商品总附加金额
+        BigDecimal usableParentGoodsAddTotalPrice;
+
+        //获取组合商品列表
+        List<SellOrder> orderList = sellOrderList.stream().filter(sellOrder -> sellOrder.getParentGoodsId() != null).collect(Collectors.toList());
+        Map<Integer, List<SellOrder>> orderListMap = orderList.stream().collect(Collectors.groupingBy(SellOrder::getParentGoodsId));
+
+        //获取组合商品实际销售价,和单个商品总和价
+        for (Integer integer : orderListMap.keySet()) {
+            SellOrder sellOrder = orderListMap.get(integer).get(0);
+            //获取组合商品销售总价
+            GoodsSellDto goodsSellDto = collect.get(sellOrder.getParentGoodsId()).get(0);
+            BigDecimal parentTotalGoodsPrice = goodsSellDto.getTotalGoodsPrice().divide(new BigDecimal(goodsSellDto.getGoodsNum()));
+            BigDecimal totalGoodsPrice = BigDecimal.ZERO;
+            //获取单个商品销售总价
+            for (GoodsSellDto sellDto : goodsSellDto.getGoodsSellDtos()) {
+                totalGoodsPrice = totalGoodsPrice.add(sellDto.getTotalGoodsPrice());
+            }
+            //如果组合价大于预计总价
+            if (parentTotalGoodsPrice.compareTo(totalGoodsPrice) == 1){
+                parentGoodsAddTotalPriceMap.put(sellOrder.getParentGoodsId(),parentTotalGoodsPrice.subtract(totalGoodsPrice));
+            }else if(parentTotalGoodsPrice.compareTo(totalGoodsPrice) == -1){//小于
+                parentGoodsCutTotalPriceMap.put(sellOrder.getParentGoodsId(),totalGoodsPrice.subtract(parentTotalGoodsPrice));
+            }
+        }
+        //分配组合商品的中单个商品的价格
+        noFreeAmount:for (Integer parentGoodsId : orderListMap.keySet()) {
+
+            BigDecimal addTotalPrice = parentGoodsAddTotalPriceMap.get(parentGoodsId);
+            usableParentGoodsAddTotalPrice = addTotalPrice;
+            BigDecimal cutTotalPrice = parentGoodsCutTotalPriceMap.get(parentGoodsId);
+            usableParentGoodsCutTotalPrice = cutTotalPrice;
+
+            //获取组合商品销售总价
+            GoodsSellDto goodsSellDto = collect.get(parentGoodsId).get(0);
+            BigDecimal divide = goodsSellDto.getGoodsPrice();
+
+            //获取子商品明细map
+            List<GoodsSellDto> sellDtos = goodsSellDto.getGoodsSellDtos();
+            Map<Integer, List<GoodsSellDto>> subGoodsMap = sellDtos.stream().collect(Collectors.groupingBy(GoodsSellDto::getGoodsId));
+            List<Integer> integers = new ArrayList<>(subGoodsMap.keySet());
+            for (int i = 0; i < integers.size(); i++) {
+                GoodsSellDto sellDto = subGoodsMap.get(integers.get(i)).get(0);
+                //获取比例
+                BigDecimal ratioAmount = sellDto.getTotalGoodsPrice().divide(divide, 6, BigDecimal.ROUND_HALF_UP);
+
+                if(addTotalPrice.doubleValue() > 0l){
+                    //如果是最后一件商品
+                    if(i == integers.size() - 1){
+                        sellDto.setTotalGoodsPrice(sellDto.getTotalGoodsPrice().add(usableParentGoodsAddTotalPrice));
+                    }else {
+                        //获取分配的附加
+                        BigDecimal multiply = ratioAmount.multiply(addTotalPrice).setScale(2,BigDecimal.ROUND_HALF_UP);
+                        sellDto.setTotalGoodsPrice(sellDto.getTotalGoodsPrice().add(multiply));
+                        usableParentGoodsAddTotalPrice = usableParentGoodsAddTotalPrice.subtract(multiply);
+                    }
+                    sellDto.setGoodsPrice(sellDto.getTotalGoodsPrice());
+                }else if(cutTotalPrice.doubleValue() > 0l){
+                    //如果是最后一件商品
+                    if(i == integers.size() - 1){
+                        sellDto.setTotalGoodsPrice(sellDto.getTotalGoodsPrice().subtract(usableParentGoodsCutTotalPrice));
+                    }else {
+                        //获取分配的组合减免金额
+                        BigDecimal multiply = ratioAmount.multiply(cutTotalPrice).setScale(2,BigDecimal.ROUND_HALF_UP);
+                        sellDto.setTotalGoodsPrice(sellDto.getTotalGoodsPrice().subtract(multiply));
+                        usableParentGoodsCutTotalPrice = usableParentGoodsCutTotalPrice.subtract(multiply);
+                    }
+                    sellDto.setGoodsPrice(sellDto.getTotalGoodsPrice());
+                }else {
+                    continue noFreeAmount;
+                }
+            }
+        }
+        for (int i = 0; i < sellOrderList.size(); i++) {
+            SellOrder sellOrder = sellOrderList.get(i);
+            Integer e = null;
+            if(sellOrder.getParentGoodsId() != null){
+                e = sellOrder.getParentGoodsId();
+            }else {
+                e = sellOrder.getGoodsId();
+            }
             GoodsSellDto goodsSellDto = collect.get(e).get(0);
-            Goods goods = goodsMap.get(e).get(0);
-
-            costMap.put("sellCost", goods.getDiscountPrice());
-            if (goods.getAgreeCostPrice() != null) {
-                costMap.put("SellCost2", goods.getAgreeCostPrice());
+            List<GoodsSellDto> sellDtos = goodsSellDto.getGoodsSellDtos();
+            if(sellDtos != null && sellDtos.size() > 0){
+                Map<Integer, List<GoodsSellDto>> map = sellDtos.stream().collect(Collectors.groupingBy(GoodsSellDto::getGoodsId));
+                goodsSellDto = map.get(sellOrder.getGoodsId()).get(0);
             }
-            SellOrder sellOrder = new SellOrder();
             sellOrder.setOrganId(orderByOrderNo.getOrganId());
             sellOrder.setTransNo(orderByOrderNo.getTransNo());
             sellOrder.setOrderId(orderByOrderNo.getId());
             sellOrder.setOrderNo(orderByOrderNo.getOrderNo());
+            Goods goods = goodsService.get(e);
+            costMap.put("sellCost", goods.getDiscountPrice());
+            if (goods.getAgreeCostPrice() != null) {
+                costMap.put("SellCost2", goods.getAgreeCostPrice());
+            }
+            BigDecimal multiply2 = goodsSellDto.getGoodsPrice().multiply(new BigDecimal(sellOrder.getNum()));
             //获取比例
-            BigDecimal ratioAmount = goodsSellDto.getTotalGoodsPrice().divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
-
+            BigDecimal ratioAmount = multiply2.divide(totalAmount, 6, BigDecimal.ROUND_HALF_UP);
             //如果有减免金额
             if(marketAmount.doubleValue() > 0l){
                 //如果是最后一件商品
-                if(i == goodsId.size() - 1){
-                    goodsSellDto.setTotalGoodsPrice(goodsSellDto.getTotalGoodsPrice().subtract(usableMarketAmount));
+                if(i == sellOrderList.size() - 1){
+                    goodsSellDto.setTotalGoodsPrice(multiply2.subtract(usableMarketAmount));
                 }else {
                     //获取分配的减免金额
-                    BigDecimal multiply = ratioAmount.multiply(usableMarketAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
-                    goodsSellDto.setTotalGoodsPrice(goodsSellDto.getTotalGoodsPrice().subtract(multiply));
+                    BigDecimal multiply = ratioAmount.multiply(marketAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
+                    goodsSellDto.setTotalGoodsPrice(multiply2.subtract(multiply));
                     usableMarketAmount = usableMarketAmount.subtract(multiply);
                 }
             }
@@ -795,7 +902,7 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
                 sellOrder.setBalanceAmount(BigDecimal.ZERO);
             }else {
                 //如果是最后一件商品
-                if(i == goodsId.size() - 1){
+                if(i == sellOrderList.size() - 1){
                     sellOrder.setActualAmount(usableAmount);
                     sellOrder.setBalanceAmount(usableBalance);
                 }else {
@@ -811,22 +918,19 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
                 }
             }
             sellOrder.setExpectAmount(sellOrder.getActualAmount().add(sellOrder.getBalanceAmount()));
-            sellOrder.setSellCost(goods.getDiscountPrice());
             sellOrder.setSellCost2(JSONObject.toJSONString(costMap));
-            sellOrder.setType(SellTypeEnum.valueOf(goods.getType().getCode()));
-            sellOrder.setGoodsId(e);
-            sellOrder.setGoodsName(goods.getName());
-            sellOrder.setNum(goodsSellDto.getGoodsNum());
+            sellOrder.setType(SellTypeEnum.valueOf(goodsSellDto.getGoodsType()));
+            sellOrder.setGoodsId(sellOrder.getGoodsId());
+            sellOrder.setGoodsName(goodsSellDto.getGoodsName());
             sellOrder.setUserId(studentGoodsSell.getUserId());
             sellOrder.setPaymentChannel(orderByOrderNo.getPaymentChannel());
             sellOrder.setMerNo(orderByOrderNo.getMerNos());
             sellOrder.setSellTime(orderByOrderNo.getPayTime());
             sellOrder.setEduTeacherId(studentGoodsSell.getTeacherId());
             sellOrder.setCooperationOrganId(studentGoodsSell.getCooperationOrganId());
-            sellOrders.add(sellOrder);
         }
-        if(sellOrders.size() > 0){
-            sellOrderService.batchInsert(sellOrders);
+        if(sellOrderList.size() > 0){
+            sellOrderService.batchInsert(sellOrderList);
         }
     }
 

+ 157 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SubjectChangeServiceImpl.java

@@ -1,5 +1,6 @@
 package com.ym.mec.biz.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.StudentVisitDto;
@@ -26,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @Service
 public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectChange> implements SubjectChangeService {
@@ -62,6 +64,12 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
     private StudentRegistrationService studentRegistrationService;
     @Autowired
     private ContractService contractService;
+    @Autowired
+    private SysPaymentConfigService sysPaymentConfigService;
+    @Autowired
+    private StudentPaymentOrderDao studentPaymentOrderDao;
+    @Autowired
+    private SellOrderService sellOrderService;
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
@@ -213,11 +221,12 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
     @Transactional(rollbackFor = Exception.class)
     public SubjectChange addChange(SubjectChange subjectChange) {
         SubjectChange studentWaitPay = subjectChangeDao.getStudentWaitPay(subjectChange.getStudentId(), subjectChange.getMusicGroupId());
-        if(studentWaitPay != null){
+        if (studentWaitPay != null) {
             throw new BizException("已有未支付的声部更改,请勿重复创建");
         }
         Date nowDate = new Date();
         SubjectChange studentOriginal = getStudentOriginal(subjectChange.getStudentId(), subjectChange.getMusicGroupId());
+        subjectChange.setOriginalOrderId(studentOriginal.getOrderId());
         subjectChange.setOriginalCost(studentOriginal.getOriginalCost());
         subjectChange.setStatus(SubjectChangeStatusEnum.WAIT_PAY);
         MusicGroup musicGroup = musicGroupDao.get(subjectChange.getMusicGroupId());
@@ -257,6 +266,31 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
         subjectChange.setUpdateTime(nowDate);
         subjectChange.setVersion(0);
         subjectChangeDao.insert(subjectChange);
+
+        if (amountMargin.compareTo(BigDecimal.ZERO) <= 0 && StringUtils.isNotBlank(goodsIds)) {
+            String orderNo = idGeneratorService.generatorId("payment") + "";
+            StudentPaymentOrder studentPaymentOrder = new StudentPaymentOrder();
+            studentPaymentOrder.setUserId(subjectChange.getStudentId());
+            studentPaymentOrder.setGroupType(GroupType.SUBJECT_CHANGE);
+            studentPaymentOrder.setOrderNo(orderNo);
+            studentPaymentOrder.setType(OrderTypeEnum.SUBJECT_CHANGE);
+            studentPaymentOrder.setExpectAmount(BigDecimal.ZERO);
+            studentPaymentOrder.setActualAmount(BigDecimal.ZERO);
+            studentPaymentOrder.setBalancePaymentAmount(BigDecimal.ZERO);
+            studentPaymentOrder.setStatus(DealStatusEnum.SUCCESS);
+            studentPaymentOrder.setMusicGroupId(subjectChange.getId().toString());
+            studentPaymentOrder.setPaymentChannel("BALANCE");
+            studentPaymentOrder.setUpdateTime(nowDate);
+            studentPaymentOrder.setOrganId(subjectChange.getOrganId());
+            studentPaymentOrder.setRoutingOrganId(subjectChange.getOrganId());
+            studentPaymentOrderService.insert(studentPaymentOrder);
+            List<Integer> goodsIdList = Arrays.stream(goodsIds.split(",")).map(Integer::parseInt).collect(Collectors.toList());
+
+            //退原订单商品
+            sellOrderService.refundByOrderId(subjectChange.getOriginalOrderId().longValue());
+            //添加新订单
+            this.addSellOrder(studentPaymentOrder.getId(), subjectChange.getMusicGroupId(), goodsIdList, BigDecimal.ZERO, BigDecimal.ZERO);
+        }
         return subjectChange;
     }
 
@@ -311,6 +345,7 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
         subjectChange.setOrganId(musicGroup.getOrganId());
         subjectChange.setCooperationOrganId(musicGroup.getCooperationOrganId());
         subjectChange.setMusicGroupId(musicGroupId);
+        subjectChange.setOrderId(details.get(0).getPaymentOrderId().intValue());
         String accessoriesIds = "";
         BigDecimal accessoriesPrice = BigDecimal.ZERO;
         for (StudentPaymentOrderDetail detail : details) {
@@ -393,6 +428,20 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
             if (this.update(subjectChange) <= 0) {
                 throw new BizException("维修单更新失败");
             }
+            String goodsIds = "";
+            if (subjectChange.getChangeMusical() != null) {
+                goodsIds += subjectChange.getChangeMusical() + "";
+            }
+            if (subjectChange.getChangeAccessories() != null) {
+                goodsIds += StringUtils.isNotBlank(goodsIds) ? "," + subjectChange.getChangeAccessories() : subjectChange.getChangeAccessories();
+            }
+            if (StringUtils.isNotBlank(goodsIds)) {
+                List<Integer> goodsIdList = Arrays.stream(goodsIds.split(",")).map(Integer::parseInt).collect(Collectors.toList());
+                //退原订单商品
+                sellOrderService.refundByOrderId(subjectChange.getOriginalOrderId().longValue());
+                //添加新订单
+                this.addSellOrder(studentPaymentOrder.getId(), subjectChange.getMusicGroupId(), goodsIdList, studentPaymentOrder.getExpectAmount(), studentPaymentOrder.getBalancePaymentAmount());
+            }
 
             //插入交易明细
             BigDecimal amount = studentPaymentOrder.getActualAmount();
@@ -493,4 +542,111 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
         }
         return subjectChange;
     }
+
+    @Override
+    public List<SellOrder> addSellOrder(Long orderId, String musicGroupId, List<Integer> goodsIds, BigDecimal totalAmount, BigDecimal balance) {
+        if (goodsIds == null || goodsIds.size() <= 0) {
+            return null;
+        }
+        if (balance == null) {
+            balance = BigDecimal.ZERO;
+        }
+        StudentPaymentOrder order = studentPaymentOrderDao.get(orderId);
+        MusicGroup musicGroup = new MusicGroup();
+        if (StringUtils.isNotBlank(musicGroupId)) {
+            musicGroup = musicGroupDao.get(musicGroupId);
+        }
+        int goodsNum = goodsIds.size();
+        BigDecimal goodsTotalPrice = BigDecimal.ZERO;
+        List<Goods> goodies = goodsDao.getGoodies(goodsIds);
+        int i = 1;
+        for (Integer goodsId : goodsIds) {
+            for (Goods goods : goodies) {
+                if (goods.getId().equals(goodsId)) {
+                    goodsTotalPrice = goodsTotalPrice.add(goods.getGroupPurchasePrice());
+                    break;
+                }
+            }
+        }
+
+        BigDecimal hasRouteBalance = BigDecimal.ZERO;
+        BigDecimal goodsTotalBalance = balance == null ? BigDecimal.ZERO : balance;
+        List<SellOrder> sellOrders = new ArrayList<>();
+
+        AccountType accountType = sysPaymentConfigService.checkAccountType(PaymentChannelEnum.valueOf(order.getPaymentChannel()), order.getMerNos());
+
+        for (Integer goodsId : goodsIds) {
+            SellOrder sellOrder = new SellOrder();
+            BigDecimal goodsPrice = BigDecimal.ZERO;
+            Goods nowGoods = new Goods();
+            for (Goods goods : goodies) {
+                if (goods.getId().equals(goodsId)) {
+                    nowGoods = goods;
+                    break;
+                }
+            }
+            goodsPrice = nowGoods.getGroupPurchasePrice();
+
+            BigDecimal goodsBalance = goodsTotalBalance.multiply(goodsPrice).divide(goodsTotalPrice, 2, BigDecimal.ROUND_HALF_UP);
+            if (i == goodsNum) {
+                goodsBalance = goodsTotalBalance.subtract(hasRouteBalance);
+            }
+            hasRouteBalance = hasRouteBalance.add(goodsBalance);
+            sellOrder.setGoodsId(goodsId);
+            sellOrder.setGoodsName(nowGoods.getName());
+            sellOrder.setExpectAmount(goodsPrice);
+            sellOrder.setBalanceAmount(goodsBalance);
+            sellOrder.setActualAmount(goodsPrice.subtract(goodsBalance));
+            Map<String, BigDecimal> CostMap = new HashMap<>();
+            CostMap.put("sellCost", nowGoods.getDiscountPrice());
+            if (nowGoods.getAgreeCostPrice() != null) {
+                CostMap.put("SellCost2", nowGoods.getAgreeCostPrice());
+            }
+            sellOrder.setSellCost2(JSON.toJSONString(CostMap));
+
+            sellOrder.setOrganId(order.getOrganId());
+            sellOrder.setCooperationOrganId(musicGroup.getCooperationOrganId());
+            sellOrder.setTransNo(order.getTransNo());
+            sellOrder.setOrderId(order.getId());
+            sellOrder.setOrderNo(order.getOrderNo());
+            sellOrder.setSellCost(nowGoods.getDiscountPrice());
+            sellOrder.setNum(1);
+            sellOrder.setUserId(order.getUserId());
+            sellOrder.setPaymentChannel(order.getPaymentChannel());
+            sellOrder.setMerNo(order.getMerNos());
+            sellOrder.setAccountType(accountType);
+            sellOrder.setSellTime(order.getCreateTime());
+            sellOrder.setCreateIme(new Date());
+            sellOrder.setUpdateTime(new Date());
+            if (nowGoods.getType().equals(GoodsType.INSTRUMENT)) {
+                sellOrder.setType(SellTypeEnum.INSTRUMENT);
+            } else if (nowGoods.getType().equals(GoodsType.ACCESSORIES)) {
+                sellOrder.setType(SellTypeEnum.ACCESSORIES);
+            } else {
+                sellOrder.setType(SellTypeEnum.OTHER);
+            }
+
+            StockType goodsStockType = StockType.INTERNAL;
+            for (Goods goods : goodies) {
+                if (goods.getId().equals(goodsId)) {
+                    goodsStockType = goods.getStockType();
+                    break;
+                }
+            }
+            //库存类型
+            if (goodsStockType.equals(StockType.ALL) && accountType.equals(AccountType.INTERNAL)) {
+                sellOrder.setStockType(StockType.INTERNAL);
+            } else if (goodsStockType.equals(StockType.ALL) && accountType.equals(AccountType.EXTERNAL)) {
+                sellOrder.setStockType(StockType.EXTERNAL);
+            } else {
+                sellOrder.setStockType(goodsStockType);
+            }
+            //批次号 TODO
+
+            sellOrders.add(sellOrder);
+            i++;
+        }
+        sellOrderDao.batchInsert(sellOrders);
+        return sellOrders;
+    }
 }

+ 7 - 6
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysPaymentConfigServiceImpl.java

@@ -2,6 +2,7 @@ package com.ym.mec.biz.service.impl;
 
 import com.ym.mec.biz.dal.dao.SysPaymentConfigDao;
 import com.ym.mec.biz.dal.entity.SysPaymentConfig;
+import com.ym.mec.biz.dal.enums.AccountType;
 import com.ym.mec.biz.dal.enums.PaymentChannelEnum;
 import com.ym.mec.biz.service.SysPaymentConfigService;
 import com.ym.mec.common.dal.BaseDAO;
@@ -38,13 +39,13 @@ public class SysPaymentConfigServiceImpl extends BaseServiceImpl<Integer, SysPay
     }
 
     @Override
-    public Boolean checkOutAccount(PaymentChannelEnum payType, String merNos) {
-        if ((!payType.equals(PaymentChannelEnum.ADAPAY) && !payType.equals(PaymentChannelEnum.YQPAY)) || StringUtils.isBlank(merNos)) {
-            return false;
+    public AccountType checkAccountType(PaymentChannelEnum payType, String merNos) {
+        if (payType == null || (!payType.equals(PaymentChannelEnum.ADAPAY) && !payType.equals(PaymentChannelEnum.YQPAY)) || StringUtils.isBlank(merNos)) {
+            return AccountType.INTERNAL;
         }
         List<SysPaymentConfig> accounts = sysPaymentConfigDao.getOutAccounts(payType);
         String[] merNoArr = merNos.split(",");
-        boolean hasOutAccount = false;
+        AccountType accountType = AccountType.INTERNAL;
         NODE1:
         for (String merNo : merNoArr) {
             for (SysPaymentConfig account : accounts) {
@@ -55,11 +56,11 @@ public class SysPaymentConfigServiceImpl extends BaseServiceImpl<Integer, SysPay
                     accountNo = account.getYqMerNo();
                 }
                 if (accountNo.equals(merNo)) {
-                    hasOutAccount = true;
+                    accountType = AccountType.EXTERNAL;
                     break NODE1;
                 }
             }
         }
-        return hasOutAccount;
+        return accountType;
     }
 }

+ 0 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherAttendanceServiceImpl.java

@@ -579,9 +579,7 @@ public class TeacherAttendanceServiceImpl extends BaseServiceImpl<Long, TeacherA
 
 	@Override
 	public void pushTeacherExceptionAttendanceTask() {
-		//获取前一天的日期
 		Date date = new Date();
-//		String format = DateUtil.format(DateUtil.addDays(date,-1), DateUtil.DEFAULT_PATTERN);
 		String format = DateUtil.format(date, DateUtil.DEFAULT_PATTERN);
 		Set<Integer> teacherId = teacherAttendanceDao.queryTeacherExceptionAttendance(format);
 		if(teacherId == null || teacherId.size() == 0){

+ 160 - 11
mec-biz/src/main/resources/config/mybatis/GoodsMapper.xml

@@ -16,6 +16,7 @@
         <result column="specification_" property="specification"/>
         <result column="image_" property="image"/>
         <result column="stock_count_" property="stockCount"/>
+        <result column="tax_stock_count_" property="taxStockCount"/>
         <result column="sell_count_" property="sellCount"/>
         <result column="market_price_" property="marketPrice"/>
         <result column="discount_price_" property="discountPrice"/>
@@ -32,6 +33,10 @@
         <result column="update_time_" property="updateTime"/>
         <result column="complement_goods_id_list_" property="complementGoodsIdList"/>
         <result column="type_" property="type" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="supply_channel_" property="supplyChannel" />
+        <result column="stock_type_" property="stockType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="client_show_" property="clientShow" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="stock_warning_" property="stockWarning" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
     </resultMap>
 
     <!-- 根据主键查询一条记录 -->
@@ -48,23 +53,26 @@
     <insert id="insert" parameterType="com.ym.mec.biz.dal.entity.Goods" useGeneratedKeys="true" keyColumn="id"
             keyProperty="id">
         INSERT INTO goods
-        (goods_category_id_,sn_,name_,brand_,specification_,image_,stock_count_,sell_count_,market_price_,
+        (goods_category_id_,sn_,name_,brand_,specification_,image_,stock_count_,tax_stock_count_,sell_count_,market_price_,
         discount_price_,group_purchase_price_,brief_,desc_,is_new_,is_top_,status_,memo_,publish_time_,
-        complement_goods_id_list_,update_time_,create_time_,type_,agree_cost_price_)
-        VALUES(#{goodsCategoryId},#{sn},#{name},#{brand},#{specification},#{image},#{stockCount},#{sellCount},#{marketPrice},
+        complement_goods_id_list_,update_time_,create_time_,type_,agree_cost_price_,client_show_,stock_warning_)
+        VALUES(#{goodsCategoryId},#{sn},#{name},#{brand},#{specification},#{image},#{stockCount},#{taxStockCount},#{sellCount},#{marketPrice},
         #{discountPrice},#{groupPurchasePrice},#{brief},#{desc},
         #{isNew,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{isTop,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
-        #{memo},#{publishTime},#{complementGoodsIdList},now(),now(),#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{agreeCostPrice})
+        #{memo},#{publishTime},#{complementGoodsIdList},now(),now(),#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{agreeCostPrice},
+        #{clientShow,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{stockWarning,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler})
     </insert>
     <insert id="batchInsert">
         INSERT INTO goods
         (goods_category_id_,name_,brand_,specification_,image_,market_price_,
-        discount_price_,group_purchase_price_,desc_,update_time_,create_time_,type_,agree_cost_price_,sn_)
+        discount_price_,group_purchase_price_,brief_,desc_,update_time_,create_time_,type_,agree_cost_price_,sn_,
+        stock_count_,tax_stock_count_,client_show_,stock_warning_)
         VALUES
         <foreach collection="goodsList" separator="," item="goods">
             (#{goods.goodsCategoryId},#{goods.name},#{goods.brand},#{goods.specification},#{goods.image},#{goods.marketPrice},
-            #{goods.discountPrice},#{goods.groupPurchasePrice},#{goods.desc},now(),now(),
-            #{goods.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{goods.agreeCostPrice},#{goods.sn})
+            #{goods.discountPrice},#{goods.groupPurchasePrice},#{goods.brief},#{goods.desc},now(),now(),
+            #{goods.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{goods.agreeCostPrice},#{goods.sn},
+            #{goods.stockCount},#{goods.taxStockCount},#{goods.clientShow,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{goods.stockWarning,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler})
         </foreach>
     </insert>
     <!-- 根据主键查询一条记录 -->
@@ -116,9 +124,6 @@
             <if test="brief != null">
                 brief_ = #{brief},
             </if>
-            <if test="updateTime != null">
-                update_time_ = NOW(),
-            </if>
             <if test="discountPrice != null">
                 discount_price_ = #{discountPrice},
             </if>
@@ -137,10 +142,102 @@
             <if test="complementGoodsIdList != null">
                 complement_goods_id_list_ = #{complementGoodsIdList},
             </if>
+            <if test="taxStockCount != null">
+                tax_stock_count_ = #{taxStockCount},
+            </if>
+            <if test="clientShow != null">
+                client_show_ = #{clientShow,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            </if>
+            <if test="stockWarning != null">
+                stock_warning_ = #{stockWarning,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            </if>
+                update_time_ = NOW()
         </set>
         WHERE id_ = #{id}
     </update>
 
+    <update id="batchUpdate" parameterType="com.ym.mec.biz.dal.entity.Goods">
+        <foreach collection="goodsList" item="goods" separator=";">
+            UPDATE goods
+            <set>
+                <if test="goods.agreeCostPrice != null">
+                    agree_cost_price_ = #{goods.agreeCostPrice},
+                </if>
+                <if test="goods.specification != null">
+                    specification_ = #{goods.specification},
+                </if>
+                <if test="goods.status != null">
+                    status_ = #{goods.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="goods.isTop != null">
+                    is_top_ = #{goods.isTop,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="goods.type != null">
+                    type_ = #{goods.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="goods.sn != null">
+                    sn_ = #{goods.sn},
+                </if>
+                <if test="goods.marketPrice != null">
+                    market_price_ = #{goods.marketPrice},
+                </if>
+                <if test="goods.memo != null">
+                    memo_ = #{goods.memo},
+                </if>
+                <if test="goods.isNew != null">
+                    is_new_ = #{goods.isNew,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="goods.groupPurchasePrice != null">
+                    group_purchase_price_ = #{goods.groupPurchasePrice},
+                </if>
+                <if test="goods.name != null">
+                    name_ = #{goods.name},
+                </if>
+                <if test="goods.stockCount != null">
+                    stock_count_ = #{goods.stockCount},
+                </if>
+                <if test="goods.goodsCategoryId != null">
+                    goods_category_id_ = #{goods.goodsCategoryId},
+                </if>
+                <if test="goods.brand != null">
+                    brand_ = #{goods.brand},
+                </if>
+                <if test="goods.brief != null">
+                    brief_ = #{goods.brief},
+                </if>
+                <if test="goods.discountPrice != null">
+                    discount_price_ = #{goods.discountPrice},
+                </if>
+                <if test="goods.sellCount != null">
+                    sell_count_ = #{goods.sellCount},
+                </if>
+                <if test="goods.image != null">
+                    image_ = #{goods.image},
+                </if>
+                <if test="goods.desc != null">
+                    desc_ = #{goods.desc},
+                </if>
+                <if test="goods.publishTime != null">
+                    publish_time_ = #{goods.publishTime},
+                </if>
+                <if test="goods.complementGoodsIdList != null">
+                    complement_goods_id_list_ = #{goods.complementGoodsIdList},
+                </if>
+                <if test="goods.taxStockCount != null">
+                    tax_stock_count_ = #{goods.taxStockCount},
+                </if>
+                <if test="goods.clientShow != null">
+                    client_show_ = #{goods.clientShow,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="goods.stockWarning != null">
+                    stock_warning_ = #{goods.stockWarning,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                    update_time_ = NOW()
+            </set>
+            WHERE id_ = #{goods.id}
+        </foreach>
+    </update>
+
     <!-- 根据主键删除一条记录 -->
     <delete id="delete">
 		DELETE FROM goods WHERE id_ = #{id} 
@@ -151,7 +248,7 @@
         SELECT g.*,gc.name_ goods_category_name_ FROM goods g
         LEFT JOIN goods_category gc ON g.goods_category_id_ = gc.id_
         <include refid="queryGoodsPageSql"/>
-        ORDER BY g.id_
+        ORDER BY g.id_ DESC
         <include refid="global.limit"/>
     </select>
     <!-- 查询当前表的总记录数 -->
@@ -177,12 +274,25 @@
             <if test="status != null">
                 AND g.status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
             </if>
+            <if test="groupGoods!=null and groupGoods==0">
+                AND g.complement_goods_id_list_ IS NULL
+            </if>
+            <if test="groupGoods!=null and groupGoods==1">
+                AND g.complement_goods_id_list_ IS NOT NULL
+            </if>
+            <if test="clientShow!=null">
+                AND g.client_show_=#{clientShow}
+            </if>
+            <if test="search!=null and search!=''">
+                AND (g.sn_=#{search} OR g.id_=#{search} OR g.name_ LIKE CONCAT('%', #{search}, '%'))
+            </if>
         </where>
     </sql>
 
     <select id="findGoodsBySubId" resultMap="Goods">
         SELECT g.* FROM subject_goods_mapper sgm
         LEFT JOIN goods g ON sgm.goods_category_id_ = g.goods_category_id_
+        LEFT JOIN goods_procurement gp ON  g.id_=gp.goods_id_
         WHERE sgm.subject_id_ = #{subjectId} AND g.type_ = #{type} and g.status_ != 0
     </select>
 
@@ -202,4 +312,43 @@
             #{goodsId}
         </foreach>
     </select>
+
+    <select id="lockGoods" resultMap="Goods">
+        SELECT * FROM goods WHERE id_ IN
+        <foreach collection="goodsIds" item="goodsId" open="(" close=")" separator=",">
+            #{goodsId}
+        </foreach>
+    </select>
+
+    <select id="findBySn" resultMap="Goods">
+        SELECT * FROM goods WHERE sn_ = #{sn}
+    </select>
+
+    <select id="findBySns" resultMap="Goods">
+        SELECT * FROM goods WHERE sn_ IN
+        <foreach collection="sns" item="sn" separator="," open="(" close=")">
+            #{sn}
+        </foreach>
+    </select>
+    <select id="getInnerRepertoryWarnName" resultType="java.lang.String">
+        SELECT GROUP_CONCAT( DISTINCT name_) FROM goods WHERE stock_count_ &lt;= #{innerRepertoryWarnNum} AND stock_warning_ = 0 AND status_ = 1
+    </select>
+    <select id="getOuterRepertoryWarnName" resultType="java.lang.String">
+        SELECT GROUP_CONCAT( DISTINCT name_) FROM goods WHERE tax_stock_count_ &lt;= #{outerRepertoryWarnNum} AND stock_warning_ = 0 AND status_ = 1
+    </select>
+
+    <select id="getWithComplementGoodsAndStatus" resultMap="Goods">
+        SELECT * FROM goods WHERE status_ = #{status} AND FIND_IN_SET(#{goodsId}, complement_goods_id_list_)
+    </select>
+    <resultMap id="GoodsSellDtoMap" type="com.ym.mec.biz.dal.dto.GoodsSellDto">
+        <result property="goodsId" column="id_"/>
+        <result property="image" column="image_"/>
+        <result property="goodsName" column="name_"/>
+        <result property="goodsType" column="type_"/>
+        <result property="goodsPrice" column="market_price_"/>
+        <result property="totalGoodsPrice" column="market_price_"/>
+    </resultMap>
+    <select id="queryGoodsSellDtos" resultMap="GoodsSellDtoMap">
+        SELECT id_,image_,name_,type_,market_price_,market_price_ FROM goods WHERE FIND_IN_SET(id_,#{goodsId})
+    </select>
 </mapper>

+ 147 - 0
mec-biz/src/main/resources/config/mybatis/GoodsProcurementMapper.xml

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--
+这个文件是自动生成的。
+不要修改此文件。所有改动将在下次重新自动生成时丢失。
+-->
+<mapper namespace="com.ym.mec.biz.dal.dao.GoodsProcurementDao">
+	
+	<resultMap type="com.ym.mec.biz.dal.entity.GoodsProcurement" id="GoodsProcurement">
+		<result column="id_" property="id" />
+		<result column="goods_id_" property="goodsId" />
+		<result column="goods_category_id_" property="goodsCategoryId" />
+		<result column="supply_channel_" property="supplyChannel" />
+		<result column="discount_price_" property="discountPrice" />
+		<result column="agree_cost_price_" property="agreeCostPrice" />
+		<result column="stock_count_" property="stockCount" />
+		<result column="tax_stock_count_" property="taxStockCount" />
+		<result column="operator_id_" property="operatorId" />
+		<result column="batch_no_" property="batchNo" />
+		<result column="stock_sold_num_" property="stockSoldNum"/>
+		<result column="tax_stock_sold_num_" property="taxStockSoldNum"/>
+		<result column="create_time_" property="createTime" />
+		<result column="update_time_" property="updateTime" />
+	</resultMap>
+	
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="GoodsProcurement" >
+		SELECT * FROM goods_procurement WHERE id_ = #{id} 
+	</select>
+	
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="GoodsProcurement">
+		SELECT * FROM goods_procurement ORDER BY id_
+	</select>
+	
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.GoodsProcurement" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		INSERT INTO goods_procurement (goods_id_,goods_category_id_,supply_channel_,discount_price_,agree_cost_price_,stock_count_,tax_stock_count_,operator_id_,batch_no_,create_time_,update_time_)
+		VALUES(#{goodsId},#{goodsCategoryId},#{supplyChannel},#{discountPrice},#{agreeCostPrice},#{stockCount},#{taxStockCount},#{operatorId},#{batchNo},NOW(),NOW())
+	</insert>
+
+	<insert id="batchInsert" parameterType="com.ym.mec.biz.dal.entity.GoodsProcurement" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		INSERT INTO goods_procurement (goods_id_,goods_category_id_,supply_channel_,discount_price_,agree_cost_price_,stock_count_,tax_stock_count_,operator_id_,batch_no_,create_time_,update_time_)
+		VALUE
+		<foreach collection="goodsProcurements" item="gp" separator=",">
+			(#{gp.goodsId},#{gp.goodsCategoryId},#{gp.supplyChannel},#{gp.discountPrice},#{gp.agreeCostPrice},#{gp.stockCount},#{gp.taxStockCount},#{gp.operatorId},#{gp.batchNo},NOW(),NOW())
+		</foreach>
+	</insert>
+	
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.ym.mec.biz.dal.entity.GoodsProcurement">
+		UPDATE goods_procurement
+		<set>
+			<if test="operatorId != null">
+				operator_id_ = #{operatorId},
+			</if>
+			<if test="agreeCostPrice != null">
+				agree_cost_price_ = #{agreeCostPrice},
+			</if>
+			<if test="id != null">
+				id_ = #{id},
+			</if>
+			<if test="goodsCategoryId != null">
+				goods_category_id_ = #{goodsCategoryId},
+			</if>
+			<if test="taxStockCount != null">
+				tax_stock_count_ = #{taxStockCount},
+			</if>
+			<if test="supplyChannel != null">
+				supply_channel_ = #{supplyChannel},
+			</if>
+			<if test="discountPrice != null">
+				discount_price_ = #{discountPrice},
+			</if>
+			<if test="stockCount != null">
+				stock_count_ = #{stockCount},
+			</if>
+			<if test="goodsId != null">
+				goods_id_ = #{goodsId},
+			</if>
+			<if test="batchNo != null">
+				batch_no_ = #{batchNo},
+			</if>
+			<if test="stockSoldNum != null">
+				stock_sold_num_ = #{stockSoldNum},
+			</if>
+			<if test="taxStockSoldNum != null">
+				tax_stock_sold_num_ = #{taxStockSoldNum},
+			</if>
+				update_time_ = NOW(),
+		</set> WHERE id_ = #{id}
+	</update>
+	
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete" >
+		DELETE FROM goods_procurement WHERE id_ = #{id} 
+	</delete>
+
+	<sql id="queryCondition">
+		<where>
+			1=1
+			<if test="goodsId!=null">
+				AND goods_id_ = #{goodsId}
+			</if>
+			<if test="enterStorageStartTime!=null and enterStorageEndTime!=null">
+				AND DATE_FORMAT(create_time_, '%Y-%m-%d') BETWEEN #{enterStorageStartTime} AND #{enterStorageEndTime}
+			</if>
+			<if test="search!=null and search!=''">
+				AND supply_channel_ LIKE CONCAT('%', #{search}, '%')
+			</if>
+		</where>
+	</sql>
+
+	<select id="queryGoodsProcurements" resultMap="GoodsProcurement" parameterType="map">
+		SELECT * FROM goods_procurement
+		<include refid="queryCondition"></include>
+		ORDER BY id_ <include refid="global.limit"/>
+	</select>
+
+	<select id="countGoodsProcurements" resultType="int">
+		SELECT COUNT(*) FROM goods_procurement
+		<include refid="queryCondition"></include>
+	</select>
+	
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="GoodsProcurement" parameterType="map">
+		SELECT * FROM goods_procurement
+		ORDER BY id_ <include refid="global.limit"/>
+	</select>
+	
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM goods_procurement
+	</select>
+
+	<select id="getWithStockSurplusProcurement" resultMap="GoodsProcurement">
+		SELECT * FROM goods_procurement WHERE goods_id_ = #{goodsId} AND stock_count_>stock_sold_num_ ORDER BY create_time_ LIMIT 1
+	</select>
+
+	<select id="getWithTaxStockSurplusProcurement" resultMap="GoodsProcurement">
+		SELECT * FROM goods_procurement WHERE goods_id_ = #{goodsId} AND tax_stock_count_>tax_stock_sold_num_ ORDER BY create_time_ LIMIT 1
+	</select>
+
+	<select id="getWithGoodsAndBatchNo" resultMap="GoodsProcurement">
+		SELECT * FROM goods_procurement WHERE goods_id_ = #{goodsId} AND batch_no_=#{batchNo}
+	</select>
+</mapper>

+ 155 - 21
mec-biz/src/main/resources/config/mybatis/SellOrderMapper.xml

@@ -16,7 +16,8 @@
         <result column="expect_amount_" property="expectAmount"/>
         <result column="actual_amount_" property="actualAmount"/>
         <result column="balance_amount_" property="balanceAmount"/>
-        <result column="type_" property="type"/>
+        <result column="type_" property="type" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="parent_goods_id_" property="parentGoodsId"/>
         <result column="goods_id_" property="goodsId"/>
         <result column="goods_name_" property="goodsName"/>
         <result column="sell_cost_" property="sellCost"/>
@@ -29,16 +30,20 @@
         <result column="user_id_" property="userId"/>
         <result column="payment_channel_" property="paymentChannel"/>
         <result column="mer_no_" property="merNo"/>
+        <result column="status_" property="status" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="sell_time_" property="sellTime"/>
         <result column="create_ime_" property="createIme"/>
         <result column="update_time_" property="updateTime"/>
+        <result column="receive_status_" property="receiveStatus"/>
+        <result column="stock_type_" property="stockType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler" />
+        <result column="account_type_" property="accountType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler" />
     </resultMap>
     <sql id="Base_Column_List">
         <!--@mbg.generated-->
         id_, edu_teacher_id_,organ_id_, cooperation_organ_id_, trans_no_,order_id_, order_no_, expect_amount_,
-        actual_amount_,
-        balance_amount_, sell_cost_, sell_cost2_, type_, goods_id_,goods_name_, num_, user_id_, payment_channel_,
-        mer_no_, sell_time_, create_ime_, update_time_
+        actual_amount_,balance_amount_, sell_cost_, sell_cost2_, type_,parent_goods_id_, goods_id_,goods_name_, num_,
+        user_id_,
+        payment_channel_,mer_no_,batch_no_,stock_type_,account_type_,status_, sell_time_, create_ime_, update_time_
     </sql>
     <select id="get" parameterType="java.lang.Integer" resultMap="SellOrder">
         <!--@mbg.generated-->
@@ -56,15 +61,15 @@
             useGeneratedKeys="true">
         <!--@mbg.generated-->
         insert into sell_order (edu_teacher_id_,organ_id_, cooperation_organ_id_, trans_no_,order_id_, order_no_,
-        expect_amount_,
-        actual_amount_,
-        balance_amount_, type_, goods_id_,goods_name_, sell_cost_, sell_cost2_, num_, user_id_, payment_channel_,
-        mer_no_, sell_time_, create_ime_, update_time_)
+        expect_amount_,actual_amount_,balance_amount_, type_,parent_goods_id_, goods_id_,goods_name_, sell_cost_,
+        sell_cost2_, num_, user_id_, payment_channel_,
+        mer_no_,batch_no_,stock_type_,account_type_, sell_time_, create_ime_, update_time_)
         values (#{eduTeacherId},#{organId}, #{cooperationOrganId}, #{transNo}, #{orderNo},#{orderId}, #{expectAmount},
-        #{actualAmount},
-        #{balanceAmount}, #{type}, #{goodsId}, #{goodsName}, #{sellCost}, #{sellCost2}, #{num}, #{userId},
-        #{paymentChannel},
-        #{merNo}, #{sellTime}, #{createIme}, #{updateTime})
+        #{actualAmount}, #{balanceAmount}, #{type},#{parentGoodsId}, #{goodsId}, #{goodsName}, #{sellCost},
+        #{sellCost2}, #{num}, #{userId},
+        #{paymentChannel}, #{merNo},#{batchNo},
+        #{stockType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{accountType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+        #{sellTime}, #{createIme}, #{updateTime})
     </insert>
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.SellOrder">
         <!--@mbg.generated-->
@@ -98,7 +103,10 @@
                 balance_amount_ = #{balanceAmount},
             </if>
             <if test="type != null">
-                type_ = #{type},
+                type_ = #{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            </if>
+            <if test="parentGoodsId != null">
+                parent_goods_id_ = #{parentGoodsId},
             </if>
             <if test="goodsId != null">
                 goods_id_ = #{goodsId},
@@ -124,6 +132,18 @@
             <if test="merNo != null">
                 mer_no_ = #{merNo},
             </if>
+            <if test="batchNo != null">
+                batch_no_ = #{batchNo},
+            </if>
+            <if test="stockType != null">
+                stock_type_ = #{stockType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            </if>
+            <if test="accountType != null">
+                account_type_ = #{accountType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            </if>
+            <if test="status != null">
+                status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            </if>
             <if test="sellTime != null">
                 sell_time_ = #{sellTime},
             </if>
@@ -137,29 +157,118 @@
         where id_ = #{id}
     </update>
 
+    <update id="batchUpdate" parameterType="com.ym.mec.biz.dal.entity.SellOrder">
+        <foreach collection="sellOrders" item="sellOrder" separator=";">
+            update sell_order
+            <set>
+                <if test="sellOrder.eduTeacherId != null">
+                    edu_teacher_id_ = #{sellOrder.eduTeacherId},
+                </if>
+                <if test="sellOrder.organId != null">
+                    organ_id_ = #{sellOrder.organId},
+                </if>
+                <if test="sellOrder.cooperationOrganId != null">
+                    cooperation_organ_id_ = #{sellOrder.cooperationOrganId},
+                </if>
+                <if test="sellOrder.transNo != null">
+                    trans_no_ = #{sellOrder.transNo},
+                </if>
+                <if test="sellOrder.orderId != null">
+                    order_id_ = #{sellOrder.orderId},
+                </if>
+                <if test="sellOrder.orderNo != null">
+                    order_no_ = #{sellOrder.orderNo},
+                </if>
+                <if test="sellOrder.expectAmount != null">
+                    expect_amount_ = #{sellOrder.expectAmount},
+                </if>
+                <if test="sellOrder.actualAmount != null">
+                    actual_amount_ = #{sellOrder.actualAmount},
+                </if>
+                <if test="sellOrder.balanceAmount != null">
+                    balance_amount_ = #{sellOrder.balanceAmount},
+                </if>
+                <if test="sellOrder.type != null">
+                    type_ = #{sellOrder.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="sellOrder.parentGoodsId != null">
+                    parent_goods_id_ = #{sellOrder.parentGoodsId},
+                </if>
+                <if test="sellOrder.goodsId != null">
+                    goods_id_ = #{sellOrder.goodsId},
+                </if>
+                <if test="sellOrder.goodsName != null">
+                    goods_name_ = #{sellOrder.goodsName},
+                </if>
+                <if test="sellOrder.sellCost != null">
+                    sell_cost_ = #{sellOrder.sellCost},
+                </if>
+                <if test="sellOrder.sellCost2 != null">
+                    sell_cost2_ = #{sellOrder.sellCost2},
+                </if>
+                <if test="sellOrder.num != null">
+                    num_ = #{sellOrder.num},
+                </if>
+                <if test="sellOrder.userId != null">
+                    user_id_ = #{sellOrder.userId},
+                </if>
+                <if test="sellOrder.paymentChannel != null">
+                    payment_channel_ = #{sellOrder.paymentChannel},
+                </if>
+                <if test="sellOrder.merNo != null">
+                    mer_no_ = #{sellOrder.merNo},
+                </if>
+                <if test="sellOrder.batchNo != null">
+                    batch_no_ = #{sellOrder.batchNo},
+                </if>
+                <if test="sellOrder.stockType != null">
+                    stock_type_ = #{sellOrder.stockType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="sellOrder.accountType != null">
+                    account_type_ = #{sellOrder.accountType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="sellOrder.status != null">
+                    status_ = #{sellOrder.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+                </if>
+                <if test="sellOrder.sellTime != null">
+                    sell_time_ = #{sellOrder.sellTime},
+                </if>
+                <if test="sellOrder.createIme != null">
+                    create_ime_ = #{sellOrder.createIme},
+                </if>
+                    update_time_ = NOW()
+            </set>
+            where id_ = #{sellOrder.id}
+        </foreach>
+    </update>
+
     <insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id_">
         insert into sell_order (organ_id_, cooperation_organ_id_, trans_no_,order_id_, order_no_, expect_amount_,
-        actual_amount_,
-        balance_amount_, type_, goods_id_,goods_name_, sell_cost_, sell_cost2_, num_, user_id_, payment_channel_,
-        mer_no_, sell_time_,edu_teacher_id_, create_ime_, update_time_)
+        actual_amount_,balance_amount_, type_, parent_goods_id_, goods_id_,goods_name_, sell_cost_, sell_cost2_, num_,
+        user_id_, payment_channel_,
+        mer_no_,batch_no_,stock_type_,account_type_, sell_time_,edu_teacher_id_, create_ime_, update_time_)
         VALUE
         <foreach collection="sellOrders" separator="," item="sellOrder">
             (#{sellOrder.organId},#{sellOrder.cooperationOrganId},#{sellOrder.transNo},#{sellOrder.orderId},#{sellOrder.orderNo},
-            #{sellOrder.expectAmount},#{sellOrder.actualAmount},#{sellOrder.balanceAmount},#{sellOrder.type},#{sellOrder.goodsId},
+            #{sellOrder.expectAmount},#{sellOrder.actualAmount},#{sellOrder.balanceAmount},#{sellOrder.type},#{sellOrder.parentGoodsId},#{sellOrder.goodsId},
             #{sellOrder.goodsName},#{sellOrder.sellCost},#{sellOrder.sellCost2},#{sellOrder.num},#{sellOrder.userId},
-            #{sellOrder.paymentChannel},#{sellOrder.merNo},#{sellOrder.sellTime},#{sellOrder.eduTeacherId},NOW(),NOW())
+            #{sellOrder.paymentChannel},#{sellOrder.merNo},#{sellOrder.batchNo},
+            #{sellOrder.stockType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{sellOrder.accountType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+            #{sellOrder.sellTime},#{sellOrder.eduTeacherId},NOW(),NOW())
         </foreach>
     </insert>
 
 
     <!-- 分页查询 -->
     <select id="queryPage" resultMap="SellOrder" parameterType="map">
-        SELECT so.*,su.username_ user_name_,su.phone_,o.name_ organ_name_,co.name_ school_name_,t.real_name_ eduTeacher
+        SELECT so.*,su.username_ user_name_,su.phone_,o.name_ organ_name_,co.name_ school_name_,t.real_name_
+        eduTeacher,spo.receive_status_
         FROM sell_order so
         LEFT JOIN sys_user su ON so.user_id_ = su.id_
         LEFT JOIN organization o ON o.id_ = so.organ_id_
         LEFT JOIN cooperation_organ co ON co.id_= so.cooperation_organ_id_
         LEFT JOIN sys_user t ON t.id_ = so.edu_teacher_id_
+        LEFT JOIN student_payment_order spo ON so.order_id_ = spo.id_
         <include refid="queryPageSql"/>
         ORDER BY so.create_ime_ DESC
         <include refid="global.limit"/>
@@ -168,6 +277,7 @@
     <!-- 查询当前表的总记录数 -->
     <select id="queryCount" resultType="int">
         SELECT COUNT(*) FROM sell_order so
+        LEFT JOIN student_payment_order spo ON so.order_id_ = spo.id_
         <include refid="queryPageSql"/>
     </select>
 
@@ -185,8 +295,14 @@
             <if test="cooperationOrganId != null">
                 AND so.cooperation_organ_id_ = #{cooperationOrganId}
             </if>
+            <if test="status != null">
+                AND so.status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+            </if>
             <if test="type != null">
-                AND so.type_ = #{type}
+                AND so.type_ = #{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+            </if>
+            <if test="receiveStatus != null and receiveStatus != ''">
+                AND spo.receive_status_ = #{receiveStatus}
             </if>
             <if test="startTime != null">
                 AND so.sell_time_ >= #{startTime}
@@ -376,4 +492,22 @@
           AND sc.sell_time_ <= #{endTime}
         GROUP BY sc.organ_id_, sc.cooperation_organ_id_
         ]]></select>
-</mapper>
+
+    <select id="getSellOrders" resultMap="SellOrder">
+        SELECT * FROM sell_order WHERE id_ IN
+        <foreach collection="sellOrderIds" item="id" open="(" close=")" separator=",">
+            #{id}
+        </foreach>
+    </select>
+
+    <select id="getSellOrderByParentGoodsId" resultMap="SellOrder">
+        SELECT * FROM sell_order WHERE order_id_ = #{orderId}
+        <if test="parentGoodsId != null">
+            AND parent_goods_id_ = #{parentGoodsId}
+        </if>
+    </select>
+
+    <select id="getNoneBatchNoSellOrders" resultMap="SellOrder">
+        SELECT * FROM sell_order WHERE status_ = 0 AND stock_type_ IS NOT NULL AND batch_no_ IS NULL
+    </select>
+</mapper>

+ 12 - 1
mec-biz/src/main/resources/config/mybatis/StudentGoodsSellMapper.xml

@@ -75,7 +75,10 @@
 		update_time_ = NOW()
 		</set> WHERE id_ = #{id}
 	</update>
-	
+	<update id="autoAffirmReceive">
+		UPDATE student_payment_order SET receive_status_ = #{status},update_time_ = NOW() WHERE FIND_IN_SET(order_no_,#{orderNo})
+	</update>
+
 	<!-- 根据主键删除一条记录 -->
 	<delete id="delete" >
 		DELETE FROM student_goods_sell WHERE id_ = #{id} 
@@ -114,6 +117,9 @@
 			<if test="status != null">
 				AND spo.status_ = #{status}
 			</if>
+			<if test="receiveStatus != null and receiveStatus != ''">
+				AND spo.receive_status_ = #{receiveStatus}
+			</if>
 			<if test="search != null and search != ''">
 				AND (su.username_ LIKE CONCAT('%',#{search},'%') OR su.phone_ LIKE CONCAT('%',#{search},'%'))
 			</if>
@@ -136,4 +142,9 @@
 		LEFT JOIN student_goods_sell sgs ON spo.order_no_ = sgs.order_no_
 		WHERE spo.order_no_ = #{orderNo} LIMIT 1
 	</select>
+    <select id="queryNoAffirmOrderNo" resultType="java.lang.String">
+		SELECT GROUP_CONCAT(DISTINCT so.order_no_) FROM sell_order so
+		LEFT JOIN student_payment_order spo ON spo.order_no_ = so.order_no_
+		WHERE spo.status_ = 'SUCCESS' AND TIMESTAMPDIFF(HOUR,spo.pay_time_,NOW()) >= #{autoAffirmReceiveTime}
+	</select>
 </mapper>

+ 4 - 0
mec-biz/src/main/resources/config/mybatis/StudentPaymentOrderMapper.xml

@@ -33,6 +33,7 @@
         <result column="class_group_id_" property="classGroupId"/>
         <result column="pay_time_" property="payTime"/>
         <result column="version_" property="version"/>
+        <result column="receive_status_" property="receiveStatus"/>
     </resultMap>
 
     <resultMap type="com.ym.mec.biz.dal.entity.StudentPaymentOrder" extends="StudentPaymentOrder"
@@ -104,6 +105,9 @@
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.StudentPaymentOrder">
         UPDATE student_payment_order
         <set>
+            <if test="receiveStatus != null and receiveStatus != ''">
+                receive_status_ = #{receiveStatus},
+            </if>
             <if test="status != null">
                 status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
             </if>

+ 4 - 3
mec-biz/src/main/resources/config/mybatis/SubjectChangeMapper.xml

@@ -15,6 +15,7 @@
         <result column="cooperationOrganName" property="cooperationOrganName"/>
         <result column="music_group_id_" property="musicGroupId"/>
         <result column="musicGroupName" property="musicGroupName"/>
+        <result column="original_order_id_" property="originalOrderId"/>
         <result column="original_subject_id_" property="originalSubjectId"/>
         <result column="original_course_fee_" property="originalCourseFee"/>
         <result column="original_musical_" property="originalMusical"/>
@@ -49,7 +50,7 @@
     <sql id="Base_Column_List">
         <!--@mbg.generated-->
         id_,edu_teacher_id_,student_id_,organ_id_,cooperation_organ_id_,
-        music_group_id_,original_subject_id_,original_course_fee_, original_musical_,
+        music_group_id_,original_order_id_,original_subject_id_,original_course_fee_, original_musical_,
         original_musical_price_,
         original_accessories_,original_accessories_price_,kit_group_purchase_type_,change_subject_id_,
         change_course_fee_, change_musical_,
@@ -74,7 +75,7 @@
             useGeneratedKeys="true">
         <!--@mbg.generated-->
         insert into subject_change
-        (student_id_,edu_teacher_id_,organ_id_,cooperation_organ_id_,music_group_id_,original_subject_id_,original_course_fee_,
+        (student_id_,edu_teacher_id_,organ_id_,cooperation_organ_id_,music_group_id_,original_order_id_,original_subject_id_,original_course_fee_,
         original_musical_,
         original_musical_price_,original_accessories_,original_accessories_price_,original_cost_,kit_group_purchase_type_,
         change_subject_id_,change_course_fee_, change_musical_, change_musical_price_,
@@ -82,7 +83,7 @@
         course_margin_,cost_margin_,sell_amount_,order_id_,
         order_no_,trans_no_,status_,sell_time_, create_time_, update_time,version_)
         values
-        (#{studentId},#{eduTeacherId},#{organId},#{cooperationOrganId},#{musicGroupId},#{originalSubjectId},#{originalCourseFee},
+        (#{studentId},#{eduTeacherId},#{organId},#{cooperationOrganId},#{musicGroupId},#{originalOrderId},#{originalSubjectId},#{originalCourseFee},
         #{originalMusical},
         #{originalMusicalPrice},
         #{originalAccessories},

+ 13 - 15
mec-biz/src/main/resources/config/mybatis/SysPaymentConfigMapper.xml

@@ -5,8 +5,8 @@
         <!--@Table sys_payment_config-->
         <id column="id_" jdbcType="INTEGER" property="id"/>
         <result column="organ_id_" property="organId"/>
-        <result column="account_tyoe_" property="accountType"/>
-        <result column="pay_type_" property="payType"/>
+        <result column="account_type_" property="accountType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="pay_type_" property="payType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="yq_mer_no_" property="yqMerNo"/>
         <result column="hf_mer_no_" property="hfMerNo"/>
         <result column="type_" property="type"/>
@@ -75,7 +75,7 @@
                 #{organId},
             </if>
             <if test="accountType != null">
-                #{accountType},
+                #{accountType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
             </if>
             <if test="payType != null">
                 #{payType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
@@ -108,7 +108,7 @@
                 organ_id_ = #{organId},
             </if>
             <if test="accountType != null">
-                account_type_ = #{accountType},
+                account_type_ = #{accountType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
             </if>
             <if test="payType != null">
                 pay_type_ = #{payType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
@@ -189,16 +189,14 @@
     <!-- 获取所有账户类型为外部的账户 -->
     <select id="getOutAccounts" resultMap="SysPaymentConfig">
         SELECT * FROM sys_payment_config WHERE account_type_ = 1
-        <where>
-            <if test="payType != null">
-                AND pay_type_ = #{payType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
-            </if>
-            <if test='payType != null and payType.code.equals("YQPAY")'>
-                AND yq_mer_no_ != ''
-            </if>
-            <if test='payType != null and payType.code.equals("ADAPAY")'>
-                AND hf_mer_no_ !=''
-            </if>
-        </where>
+        <if test="payType != null">
+            AND pay_type_ = #{payType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+        </if>
+        <if test='payType != null and payType.code.equals("YQPAY")'>
+            AND yq_mer_no_ != ''
+        </if>
+        <if test='payType != null and payType.code.equals("ADAPAY")'>
+            AND hf_mer_no_ != ''
+        </if>
     </select>
 </mapper>

+ 5 - 0
mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml

@@ -1188,4 +1188,9 @@
 		</where>
 		GROUP BY t.`id_` 
     </select>
+    <select id="findUserByPhone" resultMap="com.ym.mec.biz.dal.dao.MusicGroupDao.BasicUserDto">
+        SELECT username_,id_ user_id_,avatar_ head_url_,
+        gender_,user_type_
+        FROM sys_user WHERE phone_ = #{phone}
+    </select>
 </mapper>

+ 7 - 0
mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java

@@ -137,4 +137,11 @@ public interface TaskRemoteService {
 	@GetMapping("task/operatingReport")
 	void operatingReport();
 
+	//商品库存预警
+	@GetMapping("task/repertoryWarn")
+    void goodsRepertoryFBIWarnTask();
+
+	//自动确认收货
+	@GetMapping("task/autoAffirmReceiveTask")
+    void autoAffirmReceiveTask();
 }

+ 10 - 0
mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java

@@ -170,4 +170,14 @@ public class TaskRemoteServiceFallback implements TaskRemoteService {
 	public void operatingReport() {
 		logger.info("经营报表生成失败");
 	}
+
+	@Override
+	public void goodsRepertoryFBIWarnTask() {
+		logger.info("商品库存预警推送失败");
+	}
+
+	@Override
+	public void autoAffirmReceiveTask() {
+		logger.info("确认收货执行失败");
+	}
 }

+ 7 - 0
mec-student/src/main/java/com/ym/mec/student/controller/RepairController.java

@@ -158,4 +158,11 @@ public class RepairController extends BaseController {
     public Object getStudentGoodsOrder(Integer goodsSellId) {
         return succeed(studentGoodsSellService.get(goodsSellId));
     }
+
+    @ApiOperation(value = "确认收货")
+    @PostMapping("/affirmReceive")
+    public Object affirmReceive(String orderNo) {
+        studentGoodsSellService.affirmReceive(orderNo);
+        return succeed();
+    }
 }

+ 1 - 1
mec-student/src/main/java/com/ym/mec/student/controller/SubjectChangeController.java

@@ -48,7 +48,7 @@ public class SubjectChangeController extends BaseController {
             @ApiImplicitParam(name = "金额", value = "amount", required = true, dataType = "BigDecimal"),
             @ApiImplicitParam(name = "是否使余额", value = "isUseBalancePayment", required = true, dataType = "Boolean")
     })
-    public HttpResponseResult<Map> payChaange(Integer id, BigDecimal amount, Boolean isUseBalancePayment, Boolean isRepay) throws Exception {
+    public HttpResponseResult<Map> payChange(Integer id, BigDecimal amount, Boolean isUseBalancePayment, Boolean isRepay) throws Exception {
         SubjectChange subjectChange = subjectChangeDao.get(id);
         if (!isRepay && subjectChange.getStatus().equals(SubjectChangeStatusEnum.ING)) {
             return failed(HttpStatus.CONTINUE, "您有待支付的订单");

+ 19 - 0
mec-task/src/main/java/com/ym/mec/task/jobs/AutoAffirmReceiveTask.java

@@ -0,0 +1,19 @@
+package com.ym.mec.task.jobs;
+
+import com.ym.mec.task.TaskRemoteService;
+import com.ym.mec.task.core.BaseTask;
+import com.ym.mec.task.core.TaskException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AutoAffirmReceiveTask extends BaseTask {
+
+	@Autowired
+	private TaskRemoteService taskRemoteService;
+
+	@Override
+	public void execute() throws TaskException {
+		taskRemoteService.autoAffirmReceiveTask();
+	}
+}

+ 19 - 0
mec-task/src/main/java/com/ym/mec/task/jobs/GoodsRepertoryFBIWarnTask.java

@@ -0,0 +1,19 @@
+package com.ym.mec.task.jobs;
+
+import com.ym.mec.task.TaskRemoteService;
+import com.ym.mec.task.core.BaseTask;
+import com.ym.mec.task.core.TaskException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class GoodsRepertoryFBIWarnTask extends BaseTask {
+
+	@Autowired
+	private TaskRemoteService taskRemoteService;
+
+	@Override
+	public void execute() throws TaskException {
+		taskRemoteService.goodsRepertoryFBIWarnTask();
+	}
+}

+ 14 - 2
mec-web/src/main/java/com/ym/mec/web/controller/AdapayController.java

@@ -19,6 +19,7 @@ import io.swagger.annotations.ApiOperation;
 import org.apache.commons.io.IOUtils;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -39,6 +40,9 @@ public class AdapayController extends BaseController {
     @Autowired
     private SysConfigDao sysConfigDao;
 
+    @Value("${spring.profiles.active:dev}")
+    private String profiles;
+
     @ApiOperation(value = "企业用户列表")
     @GetMapping("/queryPage")
     @PreAuthorize("@pcs.hasPermissions('adapay/queryPage')")
@@ -50,6 +54,9 @@ public class AdapayController extends BaseController {
     @PostMapping(value = "createMember")
     @PreAuthorize("@pcs.hasPermissions('adapay/createMember')")
     public HttpResponseResult<Map<String, Object>> createMember(HfMember member) throws Exception {
+        if (!profiles.equals("prod")) {
+            return failed("仅生产环境可用");
+        }
         if (member.getMultipartFile().isEmpty()) {
             return failed("证件压缩文件必传");
         }
@@ -75,6 +82,9 @@ public class AdapayController extends BaseController {
     @PostMapping(value = "updateMember")
     @PreAuthorize("@pcs.hasPermissions('adapay/updateMember')")
     public HttpResponseResult<Map<String, Object>> updateMember(HfMember member) throws Exception {
+        if (!profiles.equals("prod")) {
+            return failed("仅生产环境可用");
+        }
         if (member.getMultipartFile().isEmpty()) {
             return failed("证件压缩文件必传");
         }
@@ -101,6 +111,9 @@ public class AdapayController extends BaseController {
     @PostMapping(value = "createSettleAccount")
     @PreAuthorize("@pcs.hasPermissions('adapay/createSettleAccount')")
     public HttpResponseResult<Map<String, Object>> createSettleAccount(String memberId, String cardNo, String bankCode) throws Exception {
+        if (!profiles.equals("prod")) {
+            return failed("仅生产环境可用");
+        }
         try {
             return succeed(hfMemberService.createSettleAccount(memberId, cardNo, bankCode));
         } catch (Exception e) {
@@ -120,12 +133,11 @@ public class AdapayController extends BaseController {
     @GetMapping(value = "exportBill")
     @PreAuthorize("@pcs.hasPermissions('adapay/exportBill')")
     public void exportBill(Date startTime, Date endTime, HttpServletResponse response) throws Exception {
-
         long createdGte = startTime.getTime();
         long createdLte = DateUtil.getLastSecondWithDay(endTime).getTime();
         int pageIndex = 1;
         List<Map<String, Object>> data = new ArrayList<>();
-        while (true) {
+        while (profiles.equals("prod")) {
             Map<String, Object> paymentList = Payment.queryList(pageIndex, createdGte, createdLte);
             JSONArray payments = (JSONArray) paymentList.get("payments");
             if (!paymentList.get("status").equals("succeeded")) {

+ 18 - 1
mec-web/src/main/java/com/ym/mec/web/controller/GoodsController.java

@@ -1,5 +1,7 @@
 package com.ym.mec.web.controller;
 
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -25,12 +27,19 @@ public class GoodsController extends BaseController {
 
     @Autowired
     private GoodsService goodsService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
 
     @ApiOperation(value = "新增商品(教材、辅件)")
     @PostMapping("/add")
     @PreAuthorize("@pcs.hasPermissions('goods/add')")
     public Object add(Goods goods){
-        return succeed(goodsService.insert(goods));
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        goodsService.addGoodsProcurement(goods,sysUser.getId());
+        return succeed();
     }
 
     @ApiOperation(value = "删除商品(教材、辅件)")
@@ -47,6 +56,14 @@ public class GoodsController extends BaseController {
         return succeed();
     }
 
+    @ApiOperation(value = "修改商品件状态")
+    @PostMapping("/updateGoodsStatus")
+    @PreAuthorize("@pcs.hasPermissions('goods/updateGoodsStatus')")
+    public Object updateGoodsStatus(Integer goodsId, Integer status) {
+        goodsService.updateGoodsStatus(goodsId, status);
+        return succeed();
+    }
+
     @ApiOperation(value = "修改商品(教材、辅件)")
     @PostMapping("/update")
     @PreAuthorize("@pcs.hasPermissions('goods/update')")

+ 36 - 0
mec-web/src/main/java/com/ym/mec/web/controller/GoodsProcurementContrller.java

@@ -0,0 +1,36 @@
+package com.ym.mec.web.controller;
+
+import com.ym.mec.biz.dal.entity.GoodsProcurement;
+import com.ym.mec.biz.dal.page.GoodsProcurementQueryInfo;
+import com.ym.mec.biz.service.GoodsProcurementService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @Author Joburgess
+ * @Date 2020.10.09
+ */
+@Api(tags = "进货清单")
+@RestController
+@RequestMapping("goodsProcurement")
+public class GoodsProcurementContrller extends BaseController {
+
+    @Autowired
+    private GoodsProcurementService goodsProcurementService;
+
+    @ApiOperation(value = "分页查询进货清单")
+    @GetMapping("queryGoodsProcurements")
+    public HttpResponseResult<PageInfo<GoodsProcurement>> queryGoodsProcurements(GoodsProcurementQueryInfo queryInfo){
+        return succeed(goodsProcurementService.queryGoodsProcurements(queryInfo));
+    }
+
+}

+ 9 - 1
mec-web/src/main/java/com/ym/mec/web/controller/ImportController.java

@@ -1,5 +1,7 @@
 package com.ym.mec.web.controller;
 
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.entity.FinancialExpenditure;
 import com.ym.mec.biz.dal.entity.Goods;
 import com.ym.mec.biz.dal.enums.TemplateTypeEnum;
@@ -33,12 +35,18 @@ public class ImportController extends BaseController {
     private GoodsService goodsService;
     @Autowired
     private FinancialExpenditureService financialExpenditureService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
 
     @ApiOperation(value = "导入商品")
     @PostMapping(value = "goods")
     @PreAuthorize("@pcs.hasPermissions('import/goods')")
     public HttpResponseResult<List<Goods>> importGoods(@RequestParam("file") MultipartFile file) throws Exception {
-        return succeed(goodsService.importGoods(file));
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(goodsService.importGoods(file, sysUser.getId()));
     }
 
     @ApiOperation(value = "导入财务支出")

+ 29 - 0
mec-web/src/main/java/com/ym/mec/web/controller/SellOrderController.java

@@ -6,12 +6,15 @@ import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.EmployeeDao;
 import com.ym.mec.biz.dal.entity.Employee;
 import com.ym.mec.biz.dal.entity.SellOrder;
+import com.ym.mec.biz.dal.enums.SellStatus;
+import com.ym.mec.biz.dal.enums.SellTypeEnum;
 import com.ym.mec.biz.dal.page.RepairStudentQueryInfo;
 import com.ym.mec.biz.dal.page.SellOrderQueryInfo;
 import com.ym.mec.biz.service.SellOrderService;
 import com.ym.mec.biz.service.StudentRepairService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.util.date.DateUtil;
 import io.swagger.annotations.Api;
@@ -19,6 +22,7 @@ import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
 import org.snaker.engine.access.Page;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -26,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
@@ -80,4 +85,28 @@ public class SellOrderController extends BaseController {
         return succeed(sellOrder);
     }
 
+    @ApiOperation("退货")
+    @PostMapping(value = "/refund")
+    @PreAuthorize("@pcs.hasPermissions('sellOrder/refund')")
+    public HttpResponseResult<List<SellOrder>> refund(Integer id, Boolean reTry) {
+        SellOrder sellOrder = sellOrderService.get(id);
+
+        if (!sellOrder.getStatus().equals(SellStatus.NORMAL)) {
+            return failed("当前状态不能退货,请核查");
+        }
+        if (sellOrder.getType().equals(SellTypeEnum.SCHOOL_BUY)) {
+            return failed("学校采购不能退货");
+        }
+        if (sellOrder.getParentGoodsId() != null && (reTry == null || !reTry)) {
+            return failed(HttpStatus.CONTINUE, "组合商品,相关商品将一起退货");
+        }
+        List<SellOrder> sellOrders = new ArrayList<>();
+        if (sellOrder.getParentGoodsId() != null) {
+            sellOrders = sellOrderService.getSellOrderByParentGoodsId(sellOrder.getOrderId(), sellOrder.getParentGoodsId());
+        } else {
+            sellOrders.add(sellOrder);
+        }
+        return succeed(sellOrderService.refund(sellOrders));
+    }
+
 }

+ 17 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

@@ -73,6 +73,23 @@ public class TaskController extends BaseController {
 	@Autowired
 	private OperatingReportService operatingReportService;
 
+	@Autowired
+	private GoodsService goodsService;
+	@Autowired
+	private StudentGoodsSellService studentGoodsSellService;
+
+	@GetMapping(value = "/autoAffirmReceiveTask")
+	// 自动确认收货
+	public void affirmReceive(){
+		studentGoodsSellService.affirmReceive(null);
+	}
+
+	@GetMapping(value = "/repertoryWarn")
+	// 商品库存预警
+	public void repertoryWarn(){
+		goodsService.repertoryWarn();
+	}
+
 	@GetMapping(value = "/refreshUserMusicGroupPaymentStatusTask")
 	// 刷新学员乐团付费状态
 	public void refreshUserMusicGroupPaymentStatusTask(){

+ 12 - 3
mec-web/src/main/resources/columnMapper.ini

@@ -5,12 +5,21 @@
 商品类型 = type
 商品分类 = goodsCategoryName
 具体型号 = specification
-商品价格(元) = marketPrice
+商品市场价(元) = marketPrice
+商品零售价 = discountPrice
 商品团购价(元) = groupPurchasePrice
-商品采购价1(元) = discountPrice
+商品采购价1(元) = costPrice
 商品图片(插入一张图片) = image
 商品明细 = desc
 商品采购价2(元) = agreeCostPrice
+内部库存 = stockCount
+税务库存 = taxStockCount
+备查货号 = supplyChannel
+是否App展示 = clientShow
+库存类型 = stockType
+商品详情 = desc
+库存预警 = stockWarning
+
 
 [财务支出导入模板]
 财务流程编号 = financialProcessNo
@@ -23,4 +32,4 @@
 付款金额 = amount
 备注 = itemDetail
 付款时间 = paymentTime
-事由 = cause
+事由 = cause

二進制
mec-web/src/main/resources/excelTemplate/商品导入模板.xls