Browse Source

Merge branch 'master' into online1

# Conflicts:
#	mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
yonge 4 years ago
parent
commit
c48ae91ab5
74 changed files with 3659 additions and 421 deletions
  1. 73 2
      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. 0 9
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupStudentFeeDao.java
  4. 68 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SellOrderDao.java
  5. 45 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentGoodsSellDao.java
  6. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherDao.java
  7. 36 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/GoodsBatchNoDto.java
  8. 23 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/GoodsSellDto.java
  9. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentGoodsSellDto.java
  10. 58 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentPaymentOrderDto.java
  11. 69 2
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/Goods.java
  12. 193 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/GoodsProcurement.java
  13. 109 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SellOrder.java
  14. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentPaymentOrder.java
  15. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SubjectChange.java
  16. 5 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysPaymentConfig.java
  17. 26 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/AccountType.java
  18. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java
  19. 25 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/SellStatus.java
  20. 30 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/StockType.java
  21. 42 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/GoodsProcurementQueryInfo.java
  22. 22 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/GoodsQueryInfo.java
  23. 36 0
      mec-biz/src/main/java/com/ym/mec/biz/event/StudentCourseChangeEvent.java
  24. 30 0
      mec-biz/src/main/java/com/ym/mec/biz/event/listener/StudentEventListener.java
  25. 33 0
      mec-biz/src/main/java/com/ym/mec/biz/event/source/StudentEventSource.java
  26. 19 0
      mec-biz/src/main/java/com/ym/mec/biz/service/GoodsProcurementService.java
  27. 69 3
      mec-biz/src/main/java/com/ym/mec/biz/service/GoodsService.java
  28. 9 1
      mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupService.java
  29. 37 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SellOrderService.java
  30. 23 0
      mec-biz/src/main/java/com/ym/mec/biz/service/StudentGoodsSellService.java
  31. 14 6
      mec-biz/src/main/java/com/ym/mec/biz/service/SubjectChangeService.java
  32. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/SysPaymentConfigService.java
  33. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java
  34. 173 44
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  35. 47 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GoodsProcurementServiceImpl.java
  36. 482 13
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GoodsServiceImpl.java
  37. 31 3
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java
  38. 11 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/OperatingReportServiceImpl.java
  39. 4 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/PayServiceImpl.java
  40. 197 87
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SellOrderServiceImpl.java
  41. 50 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentGoodsSellServiceImpl.java
  42. 60 30
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentRouteOrderServiceImpl.java
  43. 176 63
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRepairServiceImpl.java
  44. 235 13
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SubjectChangeServiceImpl.java
  45. 7 6
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysPaymentConfigServiceImpl.java
  46. 0 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TeacherAttendanceServiceImpl.java
  47. 174 13
      mec-biz/src/main/resources/config/mybatis/GoodsMapper.xml
  48. 147 0
      mec-biz/src/main/resources/config/mybatis/GoodsProcurementMapper.xml
  49. 2 2
      mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentCalenderMapper.xml
  50. 0 4
      mec-biz/src/main/resources/config/mybatis/MusicGroupStudentFeeMapper.xml
  51. 246 36
      mec-biz/src/main/resources/config/mybatis/SellOrderMapper.xml
  52. 47 1
      mec-biz/src/main/resources/config/mybatis/StudentGoodsSellMapper.xml
  53. 3 1
      mec-biz/src/main/resources/config/mybatis/StudentPaymentOrderDetailMapper.xml
  54. 4 0
      mec-biz/src/main/resources/config/mybatis/StudentPaymentOrderMapper.xml
  55. 4 3
      mec-biz/src/main/resources/config/mybatis/SubjectChangeMapper.xml
  56. 13 15
      mec-biz/src/main/resources/config/mybatis/SysPaymentConfigMapper.xml
  57. 5 0
      mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  58. 7 0
      mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java
  59. 10 0
      mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java
  60. 61 0
      mec-student/src/main/java/com/ym/mec/student/controller/GoodsController.java
  61. 47 22
      mec-student/src/main/java/com/ym/mec/student/controller/MusicGroupController.java
  62. 26 9
      mec-student/src/main/java/com/ym/mec/student/controller/RepairController.java
  63. 1 1
      mec-student/src/main/java/com/ym/mec/student/controller/SubjectChangeController.java
  64. 19 0
      mec-task/src/main/java/com/ym/mec/task/jobs/AutoAffirmReceiveTask.java
  65. 19 0
      mec-task/src/main/java/com/ym/mec/task/jobs/GoodsRepertoryFBIWarnTask.java
  66. 14 2
      mec-web/src/main/java/com/ym/mec/web/controller/AdapayController.java
  67. 43 3
      mec-web/src/main/java/com/ym/mec/web/controller/GoodsController.java
  68. 36 0
      mec-web/src/main/java/com/ym/mec/web/controller/GoodsProcurementContrller.java
  69. 9 1
      mec-web/src/main/java/com/ym/mec/web/controller/ImportController.java
  70. 12 2
      mec-web/src/main/java/com/ym/mec/web/controller/MusicGroupController.java
  71. 29 0
      mec-web/src/main/java/com/ym/mec/web/controller/SellOrderController.java
  72. 17 0
      mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java
  73. 13 4
      mec-web/src/main/resources/columnMapper.ini
  74. BIN
      mec-web/src/main/resources/excelTemplate/商品导入模板.xls

+ 73 - 2
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;
 
@@ -44,7 +45,16 @@ public interface GoodsDao extends BaseDAO<Integer, Goods> {
      * @date 2020/9/4
      * @time 14:39
      */
-    void batchInsert(@Param("goodsList") List<Goods> goodsList);
+    void batchInsert(List<Goods> goodsList);
+
+    /**
+     * @describe 批量更新商品
+     * @author Joburgess
+     * @date 2020.09.28
+     * @param goodsList:
+     * @return void
+     */
+    void batchUpdate(@Param("goodsList") List<Goods> goodsList);
 
     /**
      * 获取商品列表
@@ -52,4 +62,65 @@ public interface GoodsDao extends BaseDAO<Integer, Goods> {
      * @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.10.15
+     * @param sn:
+     * @return com.ym.mec.biz.dal.entity.Goods
+     */
+    Goods lockBySn(@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);
+
+}

+ 0 - 9
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupStudentFeeDao.java

@@ -210,13 +210,4 @@ public interface MusicGroupStudentFeeDao extends BaseDAO<Long, MusicGroupStudent
 	 */
 	void updatePaymentStatus(@Param("calenderId") Long calenderId, @Param("paymentStatus") String paymentStatus);
 
-	/**
-	 * @describe 将缴费截止的缴费状态更改为未缴费
-	 * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
-	 * @author zouxuan
-	 * @date 2020/9/21
-	 * @time 14:34
-	 * @return void
-	 */
-    void updateFeeStatus();
 }

+ 68 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SellOrderDao.java

@@ -13,6 +13,10 @@ public interface SellOrderDao extends BaseDAO<Integer, SellOrder> {
 
     int batchInsert(@Param("sellOrders") List<SellOrder> sellOrders);
 
+    int batchUpdate(@Param("sellOrders") List<SellOrder> sellOrders);
+
+    List<SellOrder> lockSellOrders(@Param("sellOrderIds") List<Integer> sellOrderIds);
+
     /**
      * 获取订单的销售列表
      *
@@ -68,7 +72,7 @@ public interface SellOrderDao extends BaseDAO<Integer, SellOrder> {
     List<OperatingReport> getSporadicMonthReport(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
 
     /**
-     * 维修单和商品销售
+     * 维修单
      *
      * @param startTime
      * @param endTime
@@ -77,7 +81,7 @@ public interface SellOrderDao extends BaseDAO<Integer, SellOrder> {
     List<OperatingReport> getRepairGoodsSellGroupMonthReport(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
 
     /**
-     * 维修单和商品销售,总收入
+     * 维修单,总收入
      *
      * @param startTime
      * @param endTime
@@ -87,6 +91,15 @@ public interface SellOrderDao extends BaseDAO<Integer, SellOrder> {
 
 
     /**
+     * 商品销售
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    List<OperatingReport> getGoodsSellGroupMonthReport(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
+
+
+    /**
      * 根据订单号删除
      *
      * @param orderId
@@ -121,10 +134,61 @@ public interface SellOrderDao extends BaseDAO<Integer, SellOrder> {
     BigDecimal getOrderSellCost(@Param("orderId") Long orderId);
 
     /**
-     * 获取声部更换的销售、总收入
+     * 获取声部更换的销售、成本
+     *
      * @param startTime
      * @param endTime
      * @return
      */
     List<OperatingReport> getSubjectChangeMonthReport(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
-}
+
+    /**
+     * 获取声部更换的总收入
+     *
+     * @return
+     */
+    List<OperatingReport> getSubjectChangeGroupIncome(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
+
+    /**
+     * 统计退货的商品费用
+     *
+     * @return
+     */
+    List<OperatingReport> getRefundIncome(@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);
+
+    /**
+     * @return java.util.List<com.ym.mec.biz.dal.entity.SellOrder>
+     * @describe 获取无批次号商品销售记录编号列表
+     * @author Joburgess
+     * @date 2020.10.13
+     */
+    List<Integer> getNoneBatchNoSellOrderIds();
+
+
+    /**
+     * 获取订单组合商品的子商品
+     *
+     * @param orderId
+     * @param parentGoodsId
+     * @return
+     */
+    List<SellOrder> getSellOrderByParentGoodsId(@Param("orderId") Long orderId, @Param("parentGoodsId") Integer parentGoodsId);
+
+    /**
+     * 获取退货的sellOrder
+     *
+     * @param orderId
+     * @return
+     */
+    List<SellOrder> getRefundSellOrder(@Param("orderId") Long orderId);
+}

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

@@ -2,6 +2,7 @@ package com.ym.mec.biz.dal.dao;
 
 
 import com.ym.mec.biz.dal.dto.StudentGoodsSellDto;
+import com.ym.mec.biz.dal.dto.StudentPaymentOrderDto;
 import com.ym.mec.biz.dal.entity.StudentGoodsSell;
 import com.ym.mec.common.dal.BaseDAO;
 import org.apache.ibatis.annotations.Param;
@@ -46,4 +47,48 @@ 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);
+
+    /**
+     * @describe 获取学生端商品购买列表
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/14
+     * @time 17:50
+     * @param params:
+     * @return int
+     */
+    int countStudentPaymentOrders(Map<String, Object> params);
+
+    /**
+     * @describe 获取学生端商品购买列表
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/14
+     * @time 17:50
+     * @param params:
+     * @return java.util.List<com.ym.mec.biz.dal.dto.StudentPaymentOrderDto>
+     */
+    List<StudentPaymentOrderDto> queryStudentPaymentOrders(Map<String, Object> params);
 }

+ 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;
     }

+ 58 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentPaymentOrderDto.java

@@ -0,0 +1,58 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
+
+import java.math.BigDecimal;
+
+public class StudentPaymentOrderDto extends StudentPaymentOrder {
+
+    private String image;
+
+    private String goodsName;
+
+    private Integer goodsNum = 1;
+
+    private Integer autoAffirmReceiveTime;
+
+    private BigDecimal goodsAmount = BigDecimal.ZERO;
+
+    public BigDecimal getGoodsAmount() {
+        return goodsAmount;
+    }
+
+    public void setGoodsAmount(BigDecimal goodsAmount) {
+        this.goodsAmount = goodsAmount;
+    }
+
+    public Integer getAutoAffirmReceiveTime() {
+        return autoAffirmReceiveTime;
+    }
+
+    public void setAutoAffirmReceiveTime(Integer autoAffirmReceiveTime) {
+        this.autoAffirmReceiveTime = autoAffirmReceiveTime;
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    public void setImage(String image) {
+        this.image = image;
+    }
+
+    public String getGoodsName() {
+        return goodsName;
+    }
+
+    public void setGoodsName(String goodsName) {
+        this.goodsName = goodsName;
+    }
+
+    public Integer getGoodsNum() {
+        return goodsNum;
+    }
+
+    public void setGoodsNum(Integer goodsNum) {
+        this.goodsNum = goodsNum;
+    }
+}

+ 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);
+	}
+
+}

+ 109 - 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,37 @@ 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="退货时间")
+    private Date refundTime;
+
+    /**
     * 交易时间
     */
     @ApiModelProperty(value="交易时间")
@@ -152,6 +192,19 @@ public class SellOrder {
     @ApiModelProperty(value="更新时间")
     private Date updateTime;
 
+    @ApiModelProperty(value = "收货状态,NO_RECEIVE 未确认,MANUAL_RECEIVE 手动确认,AUTO_RECEIVE 自动确认",required = true)
+    private String receiveStatus;
+
+    private Boolean hasRoute = false;
+
+    public String getReceiveStatus() {
+        return receiveStatus;
+    }
+
+    public void setReceiveStatus(String receiveStatus) {
+        this.receiveStatus = receiveStatus;
+    }
+
     public Integer getId() {
         return id;
     }
@@ -367,4 +420,60 @@ 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;
+    }
+
+    public Date getRefundTime() {
+        return refundTime;
+    }
+
+    public void setRefundTime(Date refundTime) {
+        this.refundTime = refundTime;
+    }
+
+    public Boolean getHasRoute() {
+        return hasRoute;
+    }
+
+    public void setHasRoute(Boolean hasRoute) {
+        this.hasRoute = hasRoute;
+    }
 }

+ 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);
+
+}

+ 69 - 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,20 @@ import java.util.List;
 
 public interface GoodsService extends BaseService<Integer, Goods> {
 
+    void addGoods(Goods goods, Integer operatorId);
+
+    void addGoodsProcurement(GoodsProcurement goodsProcurement);
+
+    /**
+     * @describe 更新商品状态
+     * @author Joburgess
+     * @date 2020.10.12
+     * @param goodsId:
+     * @param status:
+     * @return void
+     */
+    void updateGoodsStatus(Integer goodsId, Integer status);
+
     /**
      * 通过科目编号查询商品(教材、辅件)列表
      *
@@ -34,7 +53,6 @@ public interface GoodsService extends BaseService<Integer, Goods> {
      */
     List<Goods> findGoodsByIds(String ids);
 
-
     /**
      * 查询某种类型的商品
      * @param type
@@ -51,5 +69,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);
+}

+ 9 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupService.java

@@ -97,12 +97,20 @@ public interface MusicGroupService extends BaseService<String, MusicGroup> {
 	boolean resumeMusicGroup(String musicGroupId);
 
 	/**
+	 * 延长缴费时间
+	 * @param musicGroupId 乐团编号
+	 * @param expireDate 延长缴费的截止日期
+	 * @return
+	 */
+	boolean extensionPaymentExpireDate(String musicGroupId, Date expireDate);
+
+	/**
 	 * 延长缴费
 	 * @param musicGroupId 乐团编号
 	 * @param expireDate 延长缴费的截止日期
 	 * @return
 	 */
-	boolean extensionPayment(String musicGroupId, Date expireDate);
+	boolean extensionApplyExpireDate(String musicGroupId, Date expireDate);
 
 	/**
 	 * 申请退团

+ 37 - 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,40 @@ 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
+     * @param reBackFee  是否退费
+     * @return
+     */
+    List<SellOrder> refund(List<SellOrder> sellOrders, Boolean reBackFee);
+
+    /**
+     * 根据订单id退货
+     *
+     * @param orderId
+     * @param reBackFee 是否退费
+     * @return
+     */
+    List<SellOrder> refundByOrderId(Long orderId, Boolean reBackFee);
+
+    /**
+     * 获取订单退货的sellOrder
+     * @param orderId
+     * @return
+     */
+    List<SellOrder> getRefundSellOrder(Long orderId);
+
 }

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

@@ -2,6 +2,7 @@ package com.ym.mec.biz.service;
 
 
 import com.ym.mec.biz.dal.dto.StudentGoodsSellDto;
+import com.ym.mec.biz.dal.dto.StudentPaymentOrderDto;
 import com.ym.mec.biz.dal.entity.StudentGoodsSell;
 import com.ym.mec.biz.dal.page.GoodsSellQueryInfo;
 import com.ym.mec.common.page.PageInfo;
@@ -19,4 +20,26 @@ 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);
+
+    /**
+     * @describe 获取学生端商品购买列表
+     * @apiNote 时光荏苒,认真工作的时间总是过得很快,而我、享受这一刻!
+     * @author zouxuan
+     * @date 2020/10/14
+     * @time 17:33
+     * @param queryInfo:
+     * @return com.ym.mec.common.page.PageInfo<com.ym.mec.biz.dal.dto.StudentGoodsSellDto>
+     */
+    PageInfo<StudentPaymentOrderDto> queryStudentPaymentOrders(GoodsSellQueryInfo queryInfo);
 }

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

@@ -1,18 +1,14 @@
 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.enums.KitGroupPurchaseTypeEnum;
 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 +68,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,KitGroupPurchaseTypeEnum kitGroupPurchaseType);
 }

+ 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);
 }

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java

@@ -1902,6 +1902,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
                 courseSchedule.setTeacherId(teacherId);
                 courseSchedule.setActualTeacherId(teacherId);
                 courseSchedule.setOrganId(musicGroup.getOrganId());
+                courseSchedule.setClassGroupType(classGroup.getType().getCode());
                 courseScheduleDao.insert(courseSchedule);
                 courseScheduleList.add(courseSchedule);
                 times++;

+ 173 - 44
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -1,20 +1,154 @@
 package com.ym.mec.biz.service.impl;
 
+import static com.ym.mec.biz.dal.enums.GroupType.MUSIC;
+import static com.ym.mec.biz.dal.enums.GroupType.PRACTICE;
+import static com.ym.mec.biz.dal.enums.GroupType.VIP;
+import static com.ym.mec.biz.dal.enums.PracticeGroupType.CHARGE;
+import static com.ym.mec.biz.dal.enums.PracticeGroupType.FREE;
+import static com.ym.mec.biz.dal.enums.PracticeGroupType.TRIAL;
+
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.collections.ListUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.auth.api.entity.SysUserRole;
-import com.ym.mec.biz.dal.dao.*;
-import com.ym.mec.biz.dal.dto.*;
-import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.dao.ClassGroupDao;
+import com.ym.mec.biz.dal.dao.ClassGroupStudentMapperDao;
+import com.ym.mec.biz.dal.dao.ClassGroupTeacherMapperDao;
+import com.ym.mec.biz.dal.dao.ClassGroupTeacherSalaryDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleComplaintsDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleEvaluateDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleModifyLogDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleReviewDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleStudentPaymentDao;
+import com.ym.mec.biz.dal.dao.CourseScheduleTeacherSalaryDao;
+import com.ym.mec.biz.dal.dao.CoursesGroupDao;
+import com.ym.mec.biz.dal.dao.CoursesGroupModifyLogDao;
+import com.ym.mec.biz.dal.dao.GroupDao;
+import com.ym.mec.biz.dal.dao.MusicGroupDao;
+import com.ym.mec.biz.dal.dao.PracticeGroupDao;
+import com.ym.mec.biz.dal.dao.SchoolDao;
+import com.ym.mec.biz.dal.dao.StudentAttendanceDao;
+import com.ym.mec.biz.dal.dao.SubjectDao;
+import com.ym.mec.biz.dal.dao.SysConfigDao;
+import com.ym.mec.biz.dal.dao.TeacherAttendanceDao;
+import com.ym.mec.biz.dal.dao.TeacherDao;
+import com.ym.mec.biz.dal.dao.TeacherDefaultMusicGroupSalaryDao;
+import com.ym.mec.biz.dal.dao.TeacherDefaultPracticeGroupSalaryDao;
+import com.ym.mec.biz.dal.dao.TeacherDefaultVipGroupSalaryDao;
+import com.ym.mec.biz.dal.dao.VipGroupDao;
+import com.ym.mec.biz.dal.dto.BatchInsertCoursesDto;
+import com.ym.mec.biz.dal.dto.ClassDateAdjustDto;
+import com.ym.mec.biz.dal.dto.CourseAttendanceDetailHeadInfoDto;
+import com.ym.mec.biz.dal.dto.CoursePostponeDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleEndDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleRateDto;
+import com.ym.mec.biz.dal.dto.CourseScheduleStudentDto;
+import com.ym.mec.biz.dal.dto.CourseTimeDto;
+import com.ym.mec.biz.dal.dto.CreateCourseScheduleDto;
+import com.ym.mec.biz.dal.dto.IntegerAndIntegerListDto;
+import com.ym.mec.biz.dal.dto.Mapper;
+import com.ym.mec.biz.dal.dto.StudentNameAndPhoneDto;
+import com.ym.mec.biz.dal.dto.TeacherAttendanceDto;
+import com.ym.mec.biz.dal.dto.TeacherClassCourseSchudeleDto;
+import com.ym.mec.biz.dal.dto.TeacherRemarkCommitDto;
+import com.ym.mec.biz.dal.dto.VipGroupApplyBaseInfoDto;
+import com.ym.mec.biz.dal.dto.VipGroupApplyDto;
+import com.ym.mec.biz.dal.dto.VipGroupCourseAdjustInfoDto;
+import com.ym.mec.biz.dal.entity.ClassGroup;
+import com.ym.mec.biz.dal.entity.ClassGroupStudentMapper;
+import com.ym.mec.biz.dal.entity.ClassGroupTeacherMapper;
+import com.ym.mec.biz.dal.entity.ClassGroupTeacherSalary;
+import com.ym.mec.biz.dal.entity.CourseGenerateDto;
+import com.ym.mec.biz.dal.entity.CourseSchedule;
 import com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType;
-import com.ym.mec.biz.dal.enums.*;
+import com.ym.mec.biz.dal.entity.CourseScheduleComplaints;
+import com.ym.mec.biz.dal.entity.CourseScheduleEvaluate;
+import com.ym.mec.biz.dal.entity.CourseScheduleModifyLog;
+import com.ym.mec.biz.dal.entity.CourseScheduleReview;
+import com.ym.mec.biz.dal.entity.CourseScheduleStudentPayment;
+import com.ym.mec.biz.dal.entity.CourseScheduleTeacherSalary;
+import com.ym.mec.biz.dal.entity.CoursesGroup;
+import com.ym.mec.biz.dal.entity.CoursesGroupModifyLog;
+import com.ym.mec.biz.dal.entity.Group;
+import com.ym.mec.biz.dal.entity.MusicGroup;
+import com.ym.mec.biz.dal.entity.PracticeGroup;
+import com.ym.mec.biz.dal.entity.School;
+import com.ym.mec.biz.dal.entity.StudentAttendance;
+import com.ym.mec.biz.dal.entity.StudentCourseScheduleRecordDto;
+import com.ym.mec.biz.dal.entity.Subject;
+import com.ym.mec.biz.dal.entity.SysConfig;
+import com.ym.mec.biz.dal.entity.Teacher;
+import com.ym.mec.biz.dal.entity.TeacherAttendance;
+import com.ym.mec.biz.dal.entity.TeacherDefaultMusicGroupSalary;
+import com.ym.mec.biz.dal.entity.TeacherDefaultPracticeGroupSalary;
+import com.ym.mec.biz.dal.entity.TeacherDefaultVipGroupSalary;
+import com.ym.mec.biz.dal.entity.VipGroup;
+import com.ym.mec.biz.dal.enums.AuditStatusEnum;
+import com.ym.mec.biz.dal.enums.ClassGroupStudentStatusEnum;
+import com.ym.mec.biz.dal.enums.ClassGroupTypeEnum;
+import com.ym.mec.biz.dal.enums.CourseStatusEnum;
+import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.biz.dal.enums.MessageTypeEnum;
+import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
+import com.ym.mec.biz.dal.enums.ParamEnum;
+import com.ym.mec.biz.dal.enums.SalarySettlementTypeEnum;
+import com.ym.mec.biz.dal.enums.StudentAttendanceStatusEnum;
+import com.ym.mec.biz.dal.enums.TeachModeEnum;
+import com.ym.mec.biz.dal.enums.TeachTypeEnum;
+import com.ym.mec.biz.dal.enums.VipGroupStatusEnum;
+import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 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.*;
+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.dal.BaseDAO;
 import com.ym.mec.common.entity.ImGroupMember;
 import com.ym.mec.common.entity.ImGroupModel;
@@ -28,30 +162,6 @@ import com.ym.mec.util.collection.ListUtil;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.json.JsonUtil;
-import org.apache.commons.collections.ListUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
-
-import java.lang.reflect.InvocationTargetException;
-import java.math.BigDecimal;
-import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.ym.mec.biz.dal.enums.GroupType.*;
-import static com.ym.mec.biz.dal.enums.PracticeGroupType.*;
 
 @Service
 public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSchedule> implements CourseScheduleService {
@@ -471,13 +581,13 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 
 					String dateYmdStr = DateUtil.dateToString(calendar.getTime(), DateUtil.ISO_EXPANDED_DATE_FORMAT);
 
-					dateYmdStr = dateYmdStr + " " + courseTimeDto.getStartClassTime();
-					Date courseStartTime = DateUtil.stringToDate(dateYmdStr, "yyyy-MM-dd HH:mm");
+					String startTimeStr = dateYmdStr + " " + courseTimeDto.getStartClassTime();
+					Date courseStartTime = DateUtil.stringToDate(startTimeStr, "yyyy-MM-dd HH:mm");
 					courseSchedule.setStartClassTime(courseStartTime);
 
 					if (StringUtils.isNotBlank(courseTimeDto.getEndClassTime())) {
-						dateYmdStr = dateYmdStr + " " + courseTimeDto.getEndClassTime();
-						Date courseEndTime = DateUtil.stringToDate(dateYmdStr, "yyyy-MM-dd HH:mm");
+						String endTimeStr = dateYmdStr + " " + courseTimeDto.getEndClassTime();
+						Date courseEndTime = DateUtil.stringToDate(endTimeStr, "yyyy-MM-dd HH:mm");
 						courseSchedule.setEndClassTime(courseEndTime);
 
 						if (courseEndTime.before(courseStartTime)) {
@@ -1300,6 +1410,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) {
@@ -1324,6 +1435,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);
 
@@ -1733,8 +1859,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;
                         }
 
@@ -2086,7 +2211,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 
         newNode:
         for (CourseSchedule newCourseSchedule : courseSchedules) {
-            for (CourseSchedule existCourseSchedule : existCourseSchedules) {
+            for (CourseSchedule existCourseSchedule : allCourseSchedules) {
                 if (newCourseSchedule.getEndClassTime().compareTo(existCourseSchedule.getStartClassTime()) <= 0) {
                     continue newNode;
                 }
@@ -2094,6 +2219,10 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                     continue;
                 }
 
+                if(newCourseSchedule.equals(existCourseSchedule)){
+                	continue;
+				}
+
                 boolean isTeacherRepeat = false;
                 boolean isStudentRepeat = false;
                 //检测老师冲突
@@ -2151,7 +2280,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                     continue;
                 }
 
-                if (existCourseSchedule.getClassGroupType().equals(ClassGroupTypeEnum.SNAP.getCode()) || existCourseSchedule.getClassGroupType().equals(ClassGroupTypeEnum.VIP.getCode())) {
+                if (ClassGroupTypeEnum.SNAP.getCode().equals(existCourseSchedule.getClassGroupType()) || ClassGroupTypeEnum.VIP.getCode().equals(existCourseSchedule.getClassGroupType())) {
                     throw new BizException(courseCheckInfo(newCourseSchedule, existCourseSchedule, existCourseScheduleIds, isTeacherRepeat?1:3));
                 }
 
@@ -2201,13 +2330,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;
         }
@@ -2215,6 +2338,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;
+	}
+}

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

@@ -1,16 +1,23 @@
 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.biz.dal.dao.*;
+import com.ym.mec.biz.dal.dto.BasicUserDto;
+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.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.StringUtils;
@@ -20,14 +27,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 +47,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 +66,94 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 	}
 
 	@Override
+	@Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
+	public void addGoods(Goods goods, Integer operatorId) {
+		if(StringUtils.isBlank(goods.getSn())){
+			throw new BizException("请指定商品货号");
+		}
+		Goods existsGood = goodsDao.lockBySn(goods.getSn());
+		if(Objects.nonNull(existsGood)){
+			throw new BizException("商品货号重复");
+		}else{
+			if(Objects.isNull(goods.getStockCount())){
+				goods.setStockCount(0);
+			}
+			if(Objects.isNull(goods.getTaxStockCount())){
+				goods.setTaxStockCount(0);
+			}
+			goods.setSellCount(0);
+			goodsDao.insert(goods);
+		}
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void addGoodsProcurement(GoodsProcurement goodsProcurement) {
+		Goods existsGood = goodsDao.get(goodsProcurement.getGoodsId());
+
+		if(Objects.isNull(existsGood)){
+			throw new BizException("商品不存在");
+		}
+
+		if(StringUtils.isNotBlank(existsGood.getComplementGoodsIdList())){
+			throw new BizException("此商品为组合商品");
+		}
+
+		if(Objects.isNull(goodsProcurement.getStockCount())){
+			goodsProcurement.setStockCount(0);
+		}
+		if(Objects.isNull(goodsProcurement.getTaxStockCount())){
+			goodsProcurement.setTaxStockCount(0);
+		}
+
+		existsGood.setStockCount(existsGood.getStockCount()+goodsProcurement.getStockCount());
+		existsGood.setTaxStockCount(existsGood.getTaxStockCount()+goodsProcurement.getTaxStockCount());
+		goodsDao.update(existsGood);
+
+		String batchNo = idGeneratorService.generatorId("payment") + "";
+		goodsProcurement.setBatchNo(batchNo);
+		goodsProcurement.setGoodsCategoryId(existsGood.getGoodsCategoryId());
+		goodsProcurementDao.insert(goodsProcurement);
+
+		sellOrderBatchNoAllot();
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	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 +173,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 +193,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;
 					}
@@ -96,6 +206,33 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 						}
 						continue;
 					}
+					if (columnValue.equals("stockType")) {
+						for (StockType stockType : StockType.values()) {
+							if (stockType.getMsg().equals(row.get(s).toString())) {
+								objectMap.put(columnValue, stockType);
+								break;
+							}
+						}
+						continue;
+					}
+					if (columnValue.equals("clientShow")) {
+						for (YesOrNoEnum yesOrNoEnum : YesOrNoEnum.values()) {
+							if (yesOrNoEnum.getMsg().equals(row.get(s).toString())) {
+								objectMap.put(columnValue, yesOrNoEnum);
+								break;
+							}
+						}
+						continue;
+					}
+					if (columnValue.equals("stockWarning")) {
+						for (YesOrNoEnum yesOrNoEnum : YesOrNoEnum.values()) {
+							if (yesOrNoEnum.getMsg().equals(row.get(s).toString())) {
+								objectMap.put(columnValue, yesOrNoEnum);
+								break;
+							}
+						}
+						continue;
+					}
 					if (columnValue.equals("goodsCategoryName")) {
 						Integer integer = map.get(row.get(s));
 						if(integer == null){
@@ -125,15 +262,347 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 				Goods goods = null;
 				try {
 					goods = JSONObject.parseObject(objectMap.toJSONString(),Goods.class);
+					goods.setSn(StringUtils.trim(goods.getSn()));
 					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);
+			Goods newGoods = goods.get(0);
+			if(Objects.nonNull(newGoods.getGoodsCategoryId())&&!newGoods.getGoodsCategoryId().equals(existsGood.getGoodsCategoryId())){
+				existsGood.setGoodsCategoryId(newGoods.getGoodsCategoryId());
+			}
+			if(Objects.nonNull(newGoods.getGoodsCategoryName())&&!newGoods.getGoodsCategoryName().equals(existsGood.getGoodsCategoryName())){
+				existsGood.setGoodsCategoryName(newGoods.getGoodsCategoryName());
+			}
+			if(Objects.nonNull(newGoods.getName())&&!newGoods.getName().equals(existsGood.getName())){
+				existsGood.setName(newGoods.getName());
+			}
+			if(Objects.nonNull(newGoods.getBrand())&&!newGoods.getBrand().equals(existsGood.getBrand())){
+				existsGood.setBrand(newGoods.getBrand());
+			}
+			if(Objects.nonNull(newGoods.getType())&&!newGoods.getType().equals(existsGood.getType())){
+				existsGood.setType(newGoods.getType());
+			}
+			if(Objects.nonNull(newGoods.getSpecification())&&!newGoods.getSpecification().equals(existsGood.getSpecification())){
+				existsGood.setSpecification(newGoods.getSpecification());
+			}
+			if(Objects.nonNull(newGoods.getMarketPrice())&&!newGoods.getMarketPrice().equals(existsGood.getMarketPrice())){
+				existsGood.setMarketPrice(newGoods.getMarketPrice());
+			}
+			if(Objects.nonNull(newGoods.getDiscountPrice())&&!newGoods.getDiscountPrice().equals(existsGood.getDiscountPrice())){
+				existsGood.setDiscountPrice(newGoods.getDiscountPrice());
+			}
+			if(Objects.nonNull(newGoods.getGroupPurchasePrice())&&!newGoods.getGroupPurchasePrice().equals(existsGood.getGroupPurchasePrice())){
+				existsGood.setGroupPurchasePrice(newGoods.getGroupPurchasePrice());
+			}
+			if(Objects.nonNull(newGoods.getImage())&&!newGoods.getImage().equals(existsGood.getImage())){
+				existsGood.setImage(newGoods.getImage());
+			}
+			if(Objects.nonNull(newGoods.getStockType())&&!newGoods.getStockType().equals(existsGood.getStockType())){
+				existsGood.setStockType(newGoods.getStockType());
+			}
+			if(Objects.nonNull(newGoods.getBrief())&&!newGoods.getBrief().equals(existsGood.getBrief())){
+				existsGood.setBrief(newGoods.getBrief());
+			}
+			if(Objects.nonNull(newGoods.getDesc())&&!newGoods.getDesc().equals(existsGood.getDesc())){
+				existsGood.setDesc(newGoods.getDesc());
+			}
+			if(Objects.nonNull(newGoods.getClientShow())&&!newGoods.getClientShow().equals(existsGood.getClientShow())){
+				existsGood.setClientShow(newGoods.getClientShow());
+			}
+			if(Objects.nonNull(newGoods.getStockWarning())&&!newGoods.getStockWarning().equals(existsGood.getStockWarning())){
+				existsGood.setStockWarning(newGoods.getStockWarning());
+			}
+		}
+
+		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);
 		}
+
+		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(), (v1, v2)->v1));
+		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);
+			String batchNo = idGeneratorService.generatorId("payment") + "";
+			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
+	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+	public void sellOrderBatchNoAllot() {
+		List<Integer> noneBatchNoSellOrderIds = sellOrderDao.getNoneBatchNoSellOrderIds();
+		if(CollectionUtils.isEmpty(noneBatchNoSellOrderIds)){
+			return;
+		}
+		List<SellOrder> noneBatchNoSellOrders = sellOrderDao.lockSellOrders(noneBatchNoSellOrderIds);
+		List<SellOrder> updateSellOrders = new ArrayList<>();
+		for (SellOrder noneBatchNoSellOrder : noneBatchNoSellOrders) {
+			if(SellStatus.REFUND.equals(noneBatchNoSellOrder.getStatus())){
+				continue;
+			}
+			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());
+				Map<String, BigDecimal> CostMap = new HashMap<>();
+				CostMap.put("sellCost", goodsProcurement.getDiscountPrice());
+				if (Objects.nonNull(goodsProcurement.getAgreeCostPrice())) {
+					CostMap.put("SellCost2", goodsProcurement.getAgreeCostPrice());
+				}
+				noneBatchNoSellOrder.setSellCost2(JSON.toJSONString(CostMap));
+				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 = goodsDao.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.setGoodsName(goods.getName());
+					if(StockType.INTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.INTERNAL.equals(accountType))){
+						sellOrder.setStockType(StockType.INTERNAL);
+					}else if(StockType.EXTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.EXTERNAL.equals(accountType))){
+						sellOrder.setStockType(StockType.EXTERNAL);
+					}
+					sellOrder.setGoodsName(goods.getName());
+					sellOrder.setAccountType(accountType);
+					sellOrder.setBatchNo(batchNoGoodsIdMapEntry.getKey());
+					GoodsProcurement goodsProcurement = goodsProcurementDao.getWithGoodsAndBatchNo(sellOrder.getGoodsId(), sellOrder.getBatchNo());
+					sellOrder.setSellCost(goodsProcurement.getDiscountPrice());
+					Map<String, BigDecimal> CostMap = new HashMap<>();
+					CostMap.put("sellCost", goodsProcurement.getDiscountPrice());
+					if (Objects.nonNull(goodsProcurement.getAgreeCostPrice())) {
+						CostMap.put("SellCost2", goodsProcurement.getAgreeCostPrice());
+					}
+					sellOrder.setSellCost2(JSON.toJSONString(CostMap));
+					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.setGoodsName(goods.getName());
+				if(StockType.INTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.INTERNAL.equals(accountType))){
+					sellOrder.setStockType(StockType.INTERNAL);
+				}else if(StockType.EXTERNAL.equals(goods.getStockType())||(StockType.ALL.equals(goods.getStockType())&&AccountType.EXTERNAL.equals(accountType))){
+					sellOrder.setStockType(StockType.EXTERNAL);
+				}
+				sellOrder.setGoodsName(goods.getName());
+				sellOrder.setAccountType(accountType);
+				sellOrder.setBatchNo(goodsProcurement.getBatchNo());
+				if(Objects.nonNull(goodsProcurement.getBatchNo())){
+					sellOrder.setSellCost(goodsProcurement.getDiscountPrice());
+					Map<String, BigDecimal> CostMap = new HashMap<>();
+					CostMap.put("sellCost", goodsProcurement.getDiscountPrice());
+					if (Objects.nonNull(goodsProcurement.getAgreeCostPrice())) {
+						CostMap.put("SellCost2", goodsProcurement.getAgreeCostPrice());
+					}
+					sellOrder.setSellCost2(JSON.toJSONString(CostMap));
+				}
+				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());
+			}
+		});
+
+		goodsDao.lockGoods(new ArrayList<>(goodsIdList));
+
+		for (SellOrder sellOrder : sellOrders) {
+			Goods goods = goodsDao.get(sellOrder.getGoodsId());
+			GoodsProcurement goodsProcurement = goodsProcurementDao.getWithGoodsAndBatchNo(sellOrder.getGoodsId(), sellOrder.getBatchNo());
+			if(StockType.INTERNAL.equals(sellOrder.getStockType())){
+				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(sellOrder.getStockType())){
+				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);
+	}
+}

+ 31 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java

@@ -26,6 +26,7 @@ import com.ym.mec.thirdparty.message.MessageSenderPluginContext.MessageSender;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.http.HttpUtil;
+
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -1294,7 +1295,7 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
     }
 
     @Override
-    public boolean extensionPayment(String musicGroupId, Date expireDate) {
+    public boolean extensionPaymentExpireDate(String musicGroupId, Date expireDate) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null) {
             throw new BizException("用户信息获取失败");
@@ -1305,7 +1306,7 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
         }
 
         if (musicGroup.getStatus() != MusicGroupStatusEnum.PAY) {
-            throw new BizException("乐团当前状态是{},延长缴费", musicGroup.getStatus().getMsg());
+            throw new BizException("乐团当前状态是{},不能延长缴费", musicGroup.getStatus().getMsg());
         }
 
         Date date = new Date();
@@ -1315,7 +1316,6 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
         }
 
         musicGroup.setPaymentExpireDate(expireDate);
-        musicGroup.setApplyExpireDate(expireDate);
         musicGroup.setUpdateTime(date);
         musicGroupDao.update(musicGroup);
         musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "延长缴费", sysUser.getId(), ""));
@@ -1330,6 +1330,34 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
     }
 
     @Override
+	public boolean extensionApplyExpireDate(String musicGroupId, Date expireDate) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("用户信息获取失败");
+        }
+        MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
+        if (musicGroup == null) {
+            throw new BizException("乐团找不到");
+        }
+
+        if (musicGroup.getStatus() != MusicGroupStatusEnum.APPLY && musicGroup.getStatus() != MusicGroupStatusEnum.PAY) {
+            throw new BizException("乐团当前状态是{},不能延长报名", musicGroup.getStatus().getMsg());
+        }
+
+        Date date = new Date();
+
+        if (date.after(expireDate)) {
+            throw new BizException("日期设置错误");
+        }
+
+        musicGroup.setApplyExpireDate(expireDate);
+        musicGroup.setUpdateTime(date);
+        musicGroupDao.update(musicGroup);
+        musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "延长报名时间", sysUser.getId(), ""));
+        return true;
+    }
+
+	@Override
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public boolean applyQuitMusicGroup(String musicGroupId) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();

+ 11 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/OperatingReportServiceImpl.java

@@ -121,15 +121,21 @@ public class OperatingReportServiceImpl extends BaseServiceImpl<Integer, Operati
         reports.addAll(sellOrderDao.getOutOrderMonthReport(startTime, endTime));
         //外部添加订单销售总收入
         reports.addAll(sellOrderDao.getOutOrderIncome(startTime, endTime));
-        //3.4、乐器维修、商品销售
+        //3.4、乐器维修
         reports.addAll(sellOrderDao.getRepairGoodsSellGroupMonthReport(startTime, endTime));
         reports.addAll(sellOrderDao.getRepairGoodsSellGroupIncome(startTime, endTime));
-        //3.5、零星支付充值
+        //3.5、商品销售
+        reports.addAll(sellOrderDao.getGoodsSellGroupMonthReport(startTime, endTime));
+        //3.6、零星支付充值
         reports.addAll(sellOrderDao.getRechargeMonthReport(startTime, endTime));
-        //3.6、零星收费(不是充值部分的)
+        //3.7、零星收费(不是充值部分的)
         reports.addAll(sellOrderDao.getSporadicMonthReport(startTime, endTime));
-        //乐器更换
-        //reports.addAll(sellOrderDao.getSubjectChangeMonthReport(startTime, endTime));
+        //3.8 声部更换的收入
+        reports.addAll(sellOrderDao.getSubjectChangeMonthReport(startTime, endTime));
+        reports.addAll(sellOrderDao.getSubjectChangeGroupIncome(startTime, endTime));
+        //3.9 退货部分的统计
+        reports.addAll(sellOrderDao.getRefundIncome(startTime, endTime));
+
         updateFee(organOperating, cooperationOperating, reports);
 
 //        Map<String, Object> params = new HashMap<>();

+ 4 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/PayServiceImpl.java

@@ -293,11 +293,11 @@ public class PayServiceImpl implements PayService {
         BigDecimal hasRouteMoney = BigDecimal.ZERO;
         List<Map<String, Object>> tempRoutingList = new ArrayList<>();
 
-        PaymentChannelEnum patType = null;
+        PaymentChannelEnum payType = null;
         boolean feeFlag = false;
         Set<String> routingMerNoSet = new HashSet<>();
         for (RouteScaleDto routeScaleDto : routeScaleDtos) {
-            patType = routeScaleDto.getPayType();
+            payType = routeScaleDto.getPayType();
             Map<String, Object> routingList = new HashMap<>();
             i++;
 
@@ -347,7 +347,7 @@ public class PayServiceImpl implements PayService {
             throw new BizException("调用支付接口失败");
         }
 
-        if (patType.equals(PaymentChannelEnum.YQPAY)) {
+        if (payType.equals(PaymentChannelEnum.YQPAY)) {
             if (tempRoutingList.size() == 1 && YqPayUtil.merNo.equals(tempRoutingList.get(0).get("routingMerNo").toString())) {
                 tempRoutingList = null;
             }
@@ -358,7 +358,7 @@ public class PayServiceImpl implements PayService {
         String routingMerNos = String.join(",", routingMerNoSet);
 
         unionPay.put("orderNo", orderNo);
-        unionPay.put("type", patType.getCode());
+        unionPay.put("type", payType.getCode());
         unionPay.put("payMap", payMap);
         unionPay.put("routingMerNos", routingMerNos);
         return unionPay;

+ 197 - 87
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SellOrderServiceImpl.java

@@ -1,25 +1,23 @@
 package com.ym.mec.biz.service.impl;
 
 
-import com.alibaba.fastjson.JSON;
 import com.ym.mec.biz.dal.dao.GoodsDao;
 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.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.*;
+import java.util.stream.Collectors;
 
 @Service
 public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> implements SellOrderService {
@@ -31,6 +29,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() {
@@ -58,7 +62,7 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
         for (Integer goodsId : goodsIds) {
             for (Goods goods : goodies) {
                 if (goods.getId().equals(goodsId)) {
-                    goodsTotalPrice = goodsTotalPrice.add(goods.getGroupPurchasePrice());
+                    goodsTotalPrice = goodsTotalPrice.add(goods.getDiscountPrice());
                     break;
                 }
             }
@@ -66,9 +70,11 @@ 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());
+
+        List<SellOrder> sellOrderList = goodsService.subtractStock(goodsIds, accountType);
+
         for (Integer goodsId : goodsIds) {
-            SellOrder sellOrder = new SellOrder();
             BigDecimal goodsPrice = BigDecimal.ZERO;
             Goods nowGoods = new Goods();
             for (Goods goods : goodies) {
@@ -77,50 +83,78 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
                     break;
                 }
             }
-            goodsPrice = nowGoods.getGroupPurchasePrice();
+            goodsPrice = nowGoods.getDiscountPrice();
 
             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());
+            i++;
+
+            int complementGoodsNum = nowGoods.getComplementGoodsIdList() == null ? 1 : nowGoods.getComplementGoodsIdList().split(",").length;
+            BigDecimal complementPrice = nowGoods.getDiscountPrice();
+            Map<Integer, BigDecimal> complementGoodsPrice = new HashMap<>();
+            complementGoodsPrice.put(nowGoods.getId(), nowGoods.getDiscountPrice());
+            if (nowGoods.getComplementGoodsIdList() != null) {
+                List<Goods> complementGoodies = goodsDao.findGoodsByIds(nowGoods.getComplementGoodsIdList());
+                complementGoodsPrice = complementGoodies.stream().collect(Collectors.toMap(Goods::getId, Goods::getDiscountPrice));
+                complementPrice = complementGoodies.stream().map(Goods::getDiscountPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
             }
-            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.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);
+
+            BigDecimal hasRouteSellOrderActualAmount = BigDecimal.ZERO;
+            BigDecimal hasRouteSellOrderBalance = BigDecimal.ZERO;
+            for (SellOrder sellOrder : sellOrderList) {
+                if (!goodsId.equals(sellOrder.getParentGoodsId()) && !goodsId.equals(sellOrder.getGoodsId())) {
+                    continue;
+                }
+                if (sellOrder.getHasRoute()) {
+                    continue;
+                }
+                BigDecimal sellOrderActualAmount = BigDecimal.ZERO;
+                BigDecimal sellOrderBalance = BigDecimal.ZERO;
+                if (complementPrice.compareTo(BigDecimal.ZERO) > 0) {
+                    sellOrderActualAmount = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(goodsPrice).divide(complementPrice, 2, BigDecimal.ROUND_HALF_UP);
+                    sellOrderBalance = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(goodsBalance).divide(complementPrice, 2, BigDecimal.ROUND_HALF_UP);
+                }
+
+                complementGoodsNum = complementGoodsNum - sellOrder.getNum();
+                if (complementGoodsNum <= 0) {
+                    sellOrderActualAmount = goodsPrice.subtract(hasRouteSellOrderActualAmount);
+                    sellOrderBalance = goodsBalance.subtract(hasRouteSellOrderBalance);
+                }
+                hasRouteSellOrderActualAmount = hasRouteSellOrderActualAmount.add(sellOrderActualAmount);
+                hasRouteSellOrderBalance = hasRouteSellOrderBalance.add(sellOrderBalance);
+
+                sellOrder.setExpectAmount(sellOrderActualAmount);
+                sellOrder.setBalanceAmount(sellOrderBalance);
+                sellOrder.setActualAmount(sellOrderActualAmount.subtract(sellOrderBalance));
+                sellOrder.setOrganId(order.getOrganId());
+                sellOrder.setCooperationOrganId(musicGroup.getCooperationOrganId());
+                sellOrder.setTransNo(order.getTransNo());
+                sellOrder.setOrderId(order.getId());
+                sellOrder.setOrderNo(order.getOrderNo());
+                sellOrder.setUserId(order.getUserId());
+                sellOrder.setPaymentChannel(order.getPaymentChannel());
+                sellOrder.setMerNo(order.getMerNos());
+                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);
+                }
+                sellOrder.setHasRoute(true);
+                if (complementGoodsNum <= 0) {
+                    break;
+                }
             }
-            sellOrders.add(sellOrder);
-            i++;
         }
-        sellOrderDao.batchInsert(sellOrders);
-        return sellOrders;
+        sellOrderDao.batchInsert(sellOrderList);
+        return sellOrderList;
     }
 
     @Override
@@ -138,8 +172,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()) {
@@ -152,6 +188,9 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
             BigDecimal routePrice = BigDecimal.ZERO;
             BigDecimal routeBalance = BigDecimal.ZERO;
             int j = 1;
+
+            List<Integer> goodsIds = orderDetail.getGoodsList().stream().map(Goods::getId).collect(Collectors.toList());
+            List<SellOrder> sellOrderList = goodsService.subtractStock(goodsIds, accountType);
             for (Goods goods : orderDetail.getGoodsList()) {
                 BigDecimal expectAmount = BigDecimal.ZERO;
                 BigDecimal balance = BigDecimal.ZERO;
@@ -167,52 +206,81 @@ public class SellOrderServiceImpl extends BaseServiceImpl<Integer, SellOrder> im
                 routeBalance = routeBalance.add(balance);
                 j++;
 
-                SellOrder sellOrder = new SellOrder();
-                Map<String, BigDecimal> CostMap = new HashMap<>();
-                CostMap.put("sellCost", goods.getDiscountPrice());
-                if (goods.getAgreeCostPrice() != null) {
-                    CostMap.put("SellCost2", goods.getAgreeCostPrice());
-                }
-                sellOrder.setOrganId(studentPaymentOrder.getOrganId());
-                sellOrder.setTransNo(studentPaymentOrder.getTransNo());
-                sellOrder.setOrderId(studentPaymentOrder.getId());
-                if (musicGroup != null) {
-                    sellOrder.setCooperationOrganId(musicGroup.getCooperationOrganId());
-                    sellOrder.setEduTeacherId(musicGroup.getEducationalTeacherId());
+                int complementGoodsNum = goods.getComplementGoodsIdList() == null ? 1 : goods.getComplementGoodsIdList().split(",").length;
+                BigDecimal complementPrice = goods.getGroupPurchasePrice();
+                Map<Integer, BigDecimal> complementGoodsPrice = new HashMap<>();
+                complementGoodsPrice.put(goods.getId(), goods.getGroupPurchasePrice());
+                if (goods.getComplementGoodsIdList() != null) {
+                    List<Goods> complementGoodies = goodsDao.findGoodsByIds(goods.getComplementGoodsIdList());
+                    complementGoodsPrice = complementGoodies.stream().collect(Collectors.toMap(Goods::getId, Goods::getGroupPurchasePrice));
+                    complementPrice = complementGoodies.stream().map(Goods::getGroupPurchasePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                 }
-                sellOrder.setOrderNo(studentPaymentOrder.getOrderNo());
-                sellOrder.setActualAmount(expectAmount.subtract(balance));
-                sellOrder.setBalanceAmount(balance);
-                sellOrder.setExpectAmount(expectAmount);
-                sellOrder.setSellCost(goods.getDiscountPrice());
-                sellOrder.setSellCost2(JSON.toJSONString(CostMap));
-                sellOrder.setGoodsId(goods.getId());
-                sellOrder.setGoodsName(goods.getName());
-                sellOrder.setNum(1);
-                sellOrder.setUserId(studentPaymentOrder.getUserId());
-                sellOrder.setPaymentChannel(studentPaymentOrder.getPaymentChannel());
-                sellOrder.setMerNo(studentPaymentOrder.getMerNos());
-                sellOrder.setSellTime(studentPaymentOrder.getCreateTime());
-                sellOrder.setCreateIme(new Date());
-                sellOrder.setUpdateTime(new Date());
-                if (goods.getType().equals(GoodsType.INSTRUMENT)) {
-                    sellOrder.setType(SellTypeEnum.INSTRUMENT);
-                } else if (goods.getType().equals(GoodsType.ACCESSORIES)) {
-                    sellOrder.setType(SellTypeEnum.ACCESSORIES);
-                } else {
-                    sellOrder.setType(SellTypeEnum.OTHER);
-                }
-                //租赁、免费的没有销售收入,有销售成本
-                if (orderDetail.getType().equals(OrderDetailTypeEnum.MUSICAL) &&
-                        (orderDetail.getKitGroupPurchaseType().equals(KitGroupPurchaseTypeEnum.LEASE) ||
-                                orderDetail.getKitGroupPurchaseType().equals(KitGroupPurchaseTypeEnum.FREE)
-                        )) {
-                    sellOrder.setActualAmount(BigDecimal.ZERO);
-                    sellOrder.setBalanceAmount(BigDecimal.ZERO);
-                    sellOrder.setExpectAmount(BigDecimal.ZERO);
+
+                BigDecimal hasRouteSellOrderExpectAmount = BigDecimal.ZERO;
+                BigDecimal hasRouteSellOrderBalance = BigDecimal.ZERO;
+                for (SellOrder sellOrder : sellOrderList) {
+                    if (!goods.getId().equals(sellOrder.getParentGoodsId()) && !goods.getId().equals(sellOrder.getGoodsId())) {
+                        continue;
+                    }
+                    if (sellOrder.getHasRoute()) {
+                        continue;
+                    }
+                    BigDecimal sellOrderExpectAmount = BigDecimal.ZERO;
+                    BigDecimal sellOrderBalance = BigDecimal.ZERO;
+                    if (complementPrice.compareTo(BigDecimal.ZERO) > 0) {
+                        sellOrderExpectAmount = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(expectAmount).divide(complementPrice, 2, BigDecimal.ROUND_HALF_UP);
+                        sellOrderBalance = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(balance).divide(complementPrice, 2, BigDecimal.ROUND_HALF_UP);
+                    }
+                    complementGoodsNum = complementGoodsNum - sellOrder.getNum();
+                    if (complementGoodsNum <= 0) {
+                        sellOrderExpectAmount = expectAmount.subtract(hasRouteSellOrderExpectAmount);
+                        sellOrderBalance = balance.subtract(hasRouteSellOrderBalance);
+                    }
+                    hasRouteSellOrderExpectAmount = hasRouteSellOrderExpectAmount.add(sellOrderExpectAmount);
+                    hasRouteSellOrderBalance = hasRouteSellOrderBalance.add(sellOrderBalance);
+
+                    sellOrder.setOrganId(studentPaymentOrder.getOrganId());
+                    sellOrder.setTransNo(studentPaymentOrder.getTransNo());
+                    sellOrder.setOrderId(studentPaymentOrder.getId());
+                    if (musicGroup != null) {
+                        sellOrder.setCooperationOrganId(musicGroup.getCooperationOrganId());
+                        sellOrder.setEduTeacherId(musicGroup.getEducationalTeacherId());
+                    }
+                    sellOrder.setOrderNo(studentPaymentOrder.getOrderNo());
+                    sellOrder.setActualAmount(sellOrderExpectAmount.subtract(sellOrderBalance));
+                    sellOrder.setBalanceAmount(sellOrderBalance);
+                    sellOrder.setExpectAmount(sellOrderExpectAmount);
+                    sellOrder.setNum(1);
+                    sellOrder.setUserId(studentPaymentOrder.getUserId());
+                    sellOrder.setPaymentChannel(studentPaymentOrder.getPaymentChannel());
+                    sellOrder.setMerNo(studentPaymentOrder.getMerNos());
+                    sellOrder.setSellTime(studentPaymentOrder.getCreateTime());
+                    sellOrder.setCreateIme(new Date());
+                    sellOrder.setUpdateTime(new Date());
+                    if (goods.getType().equals(GoodsType.INSTRUMENT)) {
+                        sellOrder.setType(SellTypeEnum.INSTRUMENT);
+                    } else if (goods.getType().equals(GoodsType.ACCESSORIES)) {
+                        sellOrder.setType(SellTypeEnum.ACCESSORIES);
+                    } else {
+                        sellOrder.setType(SellTypeEnum.OTHER);
+                    }
+                    //租赁、免费的没有销售收入,有销售成本
+                    if (orderDetail.getType().equals(OrderDetailTypeEnum.MUSICAL) &&
+                            (orderDetail.getKitGroupPurchaseType().equals(KitGroupPurchaseTypeEnum.LEASE) ||
+                                    orderDetail.getKitGroupPurchaseType().equals(KitGroupPurchaseTypeEnum.FREE)
+                            )) {
+                        sellOrder.setActualAmount(BigDecimal.ZERO);
+                        sellOrder.setBalanceAmount(BigDecimal.ZERO);
+                        sellOrder.setExpectAmount(BigDecimal.ZERO);
+                    }
+                    sellOrder.setHasRoute(true);
+                    if (complementGoodsNum <= 0) {
+                        break;
+                    }
                 }
-                sellOrders.add(sellOrder);
+
             }
+            sellOrders.addAll(sellOrderList);
         }
         if (sellOrders.size() > 0) {
             sellOrderDao.batchInsert(sellOrders);
@@ -225,4 +293,46 @@ 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, Boolean reBackFee) {
+        Date nowDate = new Date();
+        for (SellOrder sellOrder : sellOrders) {
+            //1、更改销售列表状态
+            sellOrder.setStatus(SellStatus.REFUND);
+            sellOrder.setUpdateTime(nowDate);
+            sellOrder.setRefundTime(nowDate);
+            sellOrderDao.update(sellOrder);
+
+            //2、金额退到余额
+            if (reBackFee && sellOrder.getExpectAmount().compareTo(BigDecimal.ZERO) > 0) {
+                sysUserCashAccountService.updateBalance(sellOrder.getUserId(), sellOrder.getExpectAmount(), 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, Boolean reBackFee) {
+        List<SellOrder> sellOrders = sellOrderDao.getSellOrderByParentGoodsId(orderId, null);
+        if (sellOrders.size() <= 0) {
+            return sellOrders;
+        }
+        return refund(sellOrders, reBackFee);
+    }
+
+    @Override
+    public List<SellOrder> getRefundSellOrder(Long orderId) {
+        return sellOrderDao.getRefundSellOrder(orderId);
+    }
+
 }

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

@@ -2,7 +2,9 @@ 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.dto.StudentPaymentOrderDto;
 import com.ym.mec.biz.dal.entity.StudentGoodsSell;
 import com.ym.mec.biz.dal.page.GoodsSellQueryInfo;
 import com.ym.mec.biz.service.StudentGoodsSellService;
@@ -11,8 +13,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 +28,8 @@ public class StudentGoodsSellServiceImpl extends BaseServiceImpl<Integer, Studen
 	
 	@Autowired
 	private StudentGoodsSellDao studentGoodsSellDao;
+	@Autowired
+	private SysConfigDao sysConfigDao;
 
 	@Override
 	public BaseDAO<Integer, StudentGoodsSell> getDAO() {
@@ -42,6 +48,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 +59,44 @@ 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);
+		}
+	}
+
+	@Override
+	public PageInfo<StudentPaymentOrderDto> queryStudentPaymentOrders(GoodsSellQueryInfo queryInfo) {
+		PageInfo<StudentPaymentOrderDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<>();
+		MapUtil.populateMap(params, queryInfo);
+		List<StudentPaymentOrderDto> dataList = null;
+		int count = studentGoodsSellDao.countStudentPaymentOrders(params);
+		if (count > 0) {
+			pageInfo.setTotal(count);
+			params.put("offset", pageInfo.getOffset());
+			dataList = studentGoodsSellDao.queryStudentPaymentOrders(params);
+			Integer autoAffirmReceiveTime = Integer.parseInt(sysConfigDao.findConfigValue("auto_affirm_receive_time"));
+			dataList.forEach(e->{
+				e.setAutoAffirmReceiveTime(autoAffirmReceiveTime);
+			});
+		}
+		if (count == 0) {
+			dataList = new ArrayList<>();
+		}
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+
 }

+ 60 - 30
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentRouteOrderServiceImpl.java

@@ -10,18 +10,22 @@ import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
 import com.ym.mec.biz.dal.entity.StudentPaymentRouteOrder;
 import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.StudentPaymentOrderQueryInfo;
+import com.ym.mec.biz.service.GoodsService;
+import com.ym.mec.biz.service.SellOrderService;
 import com.ym.mec.biz.service.StudentPaymentRouteOrderService;
 import com.ym.mec.common.dal.BaseDAO;
 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.util.collection.MapUtil;
+import org.apache.ibatis.javassist.expr.NewArray;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 public class StudentPaymentRouteOrderServiceImpl extends BaseServiceImpl<Long, StudentPaymentRouteOrder> implements StudentPaymentRouteOrderService {
@@ -38,6 +42,10 @@ public class StudentPaymentRouteOrderServiceImpl extends BaseServiceImpl<Long, S
     private SellOrderDao sellOrderDao;
     @Autowired
     private GoodsDao goodsDao;
+    @Autowired
+    private GoodsService goodsService;
+    @Autowired
+    private SellOrderService sellOrderService;
 
     @Override
     public BaseDAO<Long, StudentPaymentRouteOrder> getDAO() {
@@ -103,14 +111,18 @@ public class StudentPaymentRouteOrderServiceImpl extends BaseServiceImpl<Long, S
         studentPaymentRouteOrderDao.insert(studentPaymentRouteOrder);
 
         if (studentPaymentRouteOrderDto.getGoodies() != null && studentPaymentRouteOrderDto.getGoodies().size() > 0) {
-            List<SellOrder> sellOrders = new ArrayList<>();
             BigDecimal hasRouteAmount = BigDecimal.ZERO;
             BigDecimal goodsTotalPrice = BigDecimal.ZERO;
 
+            List<Integer> goodsIdList = new ArrayList<>();
             for (Map.Entry<Integer, Integer> goodsMap : studentPaymentRouteOrderDto.getGoodies().entrySet()) {
                 Goods goods = goodsDao.get(goodsMap.getKey());
                 goodsTotalPrice = goodsTotalPrice.add(goods.getGroupPurchasePrice().multiply(new BigDecimal(goodsMap.getValue())));
+                for (int i = 0; i < goodsMap.getValue(); i++) {
+                    goodsIdList.add(goodsMap.getKey());
+                }
             }
+            List<SellOrder> sellOrderList = goodsService.subtractStock(goodsIdList, AccountType.INTERNAL);
 
             int i = 1;
             for (Map.Entry<Integer, Integer> goodsMap : studentPaymentRouteOrderDto.getGoodies().entrySet()) {
@@ -126,37 +138,51 @@ public class StudentPaymentRouteOrderServiceImpl extends BaseServiceImpl<Long, S
                 hasRouteAmount = hasRouteAmount.add(actualAmount);
                 i++;
 
-                Map<String, BigDecimal> CostMap = new HashMap<>();
-                CostMap.put("sellCost", goods.getDiscountPrice());
-                if (goods.getAgreeCostPrice() != null) {
-                    CostMap.put("SellCost2", goods.getAgreeCostPrice());
+                int complementNum = goods.getComplementGoodsIdList() == null ? 1 : goods.getComplementGoodsIdList().split(",").length;
+                int goodsNum = goodsMap.getValue() * complementNum;
+                BigDecimal complementPrice = goods.getGroupPurchasePrice().multiply(new BigDecimal(goodsMap.getValue()));
+                Map<Integer, BigDecimal> complementGoodsPrice = new HashMap<>();
+                complementGoodsPrice.put(goods.getId(), goods.getGroupPurchasePrice());
+                if (goods.getComplementGoodsIdList() != null) {
+                    List<Goods> complementGoodies = goodsDao.findGoodsByIds(goods.getComplementGoodsIdList());
+                    complementGoodsPrice = complementGoodies.stream().collect(Collectors.toMap(Goods::getId, Goods::getGroupPurchasePrice));
+                    complementPrice = complementGoodies.stream().map(Goods::getGroupPurchasePrice).reduce(BigDecimal.ZERO, BigDecimal::add).multiply(new BigDecimal(goodsMap.getValue()));
                 }
 
-                SellOrder sellOrder = new SellOrder();
-                sellOrder.setSellTime(studentPaymentRouteOrderDto.getPayTime());
-                sellOrder.setOrganId(studentPaymentRouteOrderDto.getOrganId());
-                sellOrder.setCooperationOrganId(studentPaymentRouteOrderDto.getSchoolId());
-                sellOrder.setTransNo(studentPaymentRouteOrderDto.getTransNo());
-                sellOrder.setOrderId(studentPaymentRouteOrderDto.getId());
-                sellOrder.setOrderNo(orderNo);
-                sellOrder.setGoodsId(goods.getId());
-                sellOrder.setGoodsName(goods.getName());
-                sellOrder.setActualAmount(actualAmount);
-                sellOrder.setBalanceAmount(BigDecimal.ZERO);
-                sellOrder.setExpectAmount(actualAmount);
-                sellOrder.setSellCost(goods.getDiscountPrice());
-                sellOrder.setSellCost2(JSON.toJSONString(CostMap));
-                sellOrder.setNum(goodsMap.getValue());
-                sellOrder.setUserId(studentPaymentRouteOrderDto.getUserId());
-                sellOrder.setPaymentChannel(studentPaymentRouteOrderDto.getPaymentChannel());
-                sellOrder.setMerNo(studentPaymentRouteOrderDto.getMerNos());
-                sellOrder.setSellTime(studentPaymentRouteOrderDto.getCreateTime());
-                sellOrder.setCreateIme(nowDate);
-                sellOrder.setUpdateTime(nowDate);
-                sellOrder.setType(SellTypeEnum.SCHOOL_BUY);
-                sellOrders.add(sellOrder);
+                BigDecimal hasRouteSellOrderActualAmount = BigDecimal.ZERO;
+                for (SellOrder sellOrder : sellOrderList) {
+                    if (!goodsMap.getKey().equals(sellOrder.getParentGoodsId()) && !goodsMap.getKey().equals(sellOrder.getGoodsId())) {
+                        continue;
+                    }
+                    BigDecimal sellOrderActualAmount = BigDecimal.ZERO;
+                    if (complementPrice.compareTo(BigDecimal.ZERO) > 0) {
+                        sellOrderActualAmount = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(actualAmount).divide(complementPrice, 2, BigDecimal.ROUND_HALF_UP);
+                    }
+                    goodsNum = goodsNum - sellOrder.getNum();
+                    if (goodsNum <= 0) {
+                        sellOrderActualAmount = actualAmount.subtract(hasRouteSellOrderActualAmount);
+                    }
+                    hasRouteSellOrderActualAmount = hasRouteSellOrderActualAmount.add(sellOrderActualAmount);
+
+                    sellOrder.setSellTime(studentPaymentRouteOrderDto.getPayTime());
+                    sellOrder.setOrganId(studentPaymentRouteOrderDto.getOrganId());
+                    sellOrder.setCooperationOrganId(studentPaymentRouteOrderDto.getSchoolId());
+                    sellOrder.setTransNo(studentPaymentRouteOrderDto.getTransNo());
+                    sellOrder.setOrderId(studentPaymentRouteOrderDto.getId());
+                    sellOrder.setOrderNo(orderNo);
+                    sellOrder.setActualAmount(sellOrderActualAmount);
+                    sellOrder.setBalanceAmount(BigDecimal.ZERO);
+                    sellOrder.setExpectAmount(sellOrderActualAmount);
+                    sellOrder.setUserId(studentPaymentRouteOrderDto.getUserId());
+                    sellOrder.setPaymentChannel(studentPaymentRouteOrderDto.getPaymentChannel());
+                    sellOrder.setMerNo(studentPaymentRouteOrderDto.getMerNos());
+                    sellOrder.setSellTime(studentPaymentRouteOrderDto.getCreateTime());
+                    sellOrder.setCreateIme(nowDate);
+                    sellOrder.setUpdateTime(nowDate);
+                    sellOrder.setType(SellTypeEnum.SCHOOL_BUY);
+                }
             }
-            sellOrderDao.batchInsert(sellOrders);
+            sellOrderDao.batchInsert(sellOrderList);
         }
         return studentPaymentRouteOrderDto;
     }
@@ -184,7 +210,11 @@ public class StudentPaymentRouteOrderServiceImpl extends BaseServiceImpl<Long, S
         }
         studentPaymentOrderDao.delete(orderId);
         studentPaymentRouteOrderDao.deleteByOrderNo(studentPaymentOrder.getOrderNo());
-        sellOrderDao.deleteByOrderId(orderId);
+        //归还库存
+        List<SellOrder> sellOrders = sellOrderService.getSellOrderByParentGoodsId(orderId, null);
+        if (sellOrders.size() > 0) {
+            sellOrderDao.deleteByOrderId(orderId);
+        }
         return true;
     }
 

+ 176 - 63
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentRepairServiceImpl.java

@@ -49,6 +49,8 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
     @Autowired
     private StudentPaymentOrderService studentPaymentOrderService;
     @Autowired
+    private SysPaymentConfigService sysPaymentConfigService;
+    @Autowired
     private MusicGroupDao musicGroupDao;
     @Autowired
     private SysUserCashAccountService sysUserCashAccountService;
@@ -107,11 +109,11 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public Map addGoodsSellOrder(StudentGoodsSell studentGoodsSell) throws Exception {
         //关闭老订单
-        if(StringUtils.isNotEmpty(studentGoodsSell.getOrderNo())){
+        if (StringUtils.isNotEmpty(studentGoodsSell.getOrderNo())) {
             StudentPaymentOrder orderByOrderNo = studentPaymentOrderService.findOrderByOrderNo(studentGoodsSell.getOrderNo());
-            if(orderByOrderNo.getBalancePaymentAmount() != null){
+            if (orderByOrderNo.getBalancePaymentAmount() != null) {
                 studentGoodsSell.setIsUseBalancePayment(true);
-            }else {
+            } else {
                 studentGoodsSell.setIsUseBalancePayment(false);
             }
             orderByOrderNo.setStatus(DealStatusEnum.CLOSE);
@@ -120,44 +122,49 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
                 sysUserCashAccountService.updateBalance(orderByOrderNo.getUserId(), orderByOrderNo.getBalancePaymentAmount(), PlatformCashAccountDetailTypeEnum.REFUNDS, "关闭订单");
             }
             StudentGoodsSell byOrderNo = studentGoodsSellDao.findByOrderNo(studentGoodsSell.getOrderNo());
-            if(byOrderNo != null){
+            if (byOrderNo != null) {
                 studentGoodsSell = byOrderNo;
-                studentGoodsSell.setGoodsSellDtos(JSON.parseArray(byOrderNo.getGoodsJson(),GoodsSellDto.class));
+                studentGoodsSell.setGoodsSellDtos(JSON.parseArray(byOrderNo.getGoodsJson(), GoodsSellDto.class));
             }
         }
         Integer studentId = studentGoodsSell.getUserId();
         List<GoodsSellDto> goodsSellDtos = studentGoodsSell.getGoodsSellDtos();
-        if(goodsSellDtos == null || goodsSellDtos.size() == 0){
+        if (goodsSellDtos == null || goodsSellDtos.size() == 0) {
             throw new BizException("请选择需要购买的商品");
         }
         if (studentId == null) {
             throw new BizException("请指定学员");
         }
+
         studentDao.lockUser(studentId);
         SysUser student = sysUserFeignService.queryUserById(studentId);
         //如果教务老师为空,代表学员自己创建的订单
-        if(studentGoodsSell.getTeacherId() == null){
+        if (studentGoodsSell.getTeacherId() == null) {
             //获取学生关联的所有教务老师列表
             List<Integer> stuEducation = studentRepairDao.countStuEducation(studentId);
-            if (stuEducation != null && stuEducation.size() == 1){
+            if (stuEducation != null && stuEducation.size() == 1) {
                 //获取学员乐团关联的教务
                 MusicGroup musicGroup = musicGroupDao.getStuMusic(studentId);
                 studentGoodsSell.setTeacherId(stuEducation.get(0));
-                if(musicGroup != null){
+                if (musicGroup != null) {
                     studentGoodsSell.setCooperationOrganId(musicGroup.getCooperationOrganId());
                 }
             }
-        }else if(studentGoodsSell.getCooperationOrganId() == null){
+        } else if (studentGoodsSell.getCooperationOrganId() == null) {
             //获取教务老师,学员关联的乐团
-            MusicGroup musicGroup = musicGroupDao.getStuEduMusic(studentId,studentGoodsSell.getTeacherId());
-            if(musicGroup != null){
+            MusicGroup musicGroup = musicGroupDao.getStuEduMusic(studentId, studentGoodsSell.getTeacherId());
+            if (musicGroup != null) {
                 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);
+        Map<Integer, String> integerStringMap = getMap("goods", "id_", "type_", goodsIds, Integer.class, String.class);
+        Map<Integer, BigDecimal> map = getMap("goods", "id_", "discount_price_", goodsIds, Integer.class, BigDecimal.class);
         for (GoodsSellDto goodsSellDto : goodsSellDtos) {
+            goodsSellDto.setGoodsType(integerStringMap.get(goodsSellDto.getGoodsId()));
+            if (StringUtils.isNotEmpty(goodsSellDto.getComplementGoodsIdList())) {
+                goodsSellDto.setGoodsSellDtos(goodsService.queryGoodsSellDtos(goodsSellDto.getComplementGoodsIdList()));
+            }
             goodsSellDto.setGoodsPrice(map.get(goodsSellDto.getGoodsId()));
             goodsSellDto.setTotalGoodsPrice(map.get(goodsSellDto.getGoodsId()).multiply(new BigDecimal(goodsSellDto.getGoodsNum())));
         }
@@ -168,7 +175,7 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
             amount = amount.add(goodsSellDto.getTotalGoodsPrice());
         }
         amount = amount.subtract(studentGoodsSell.getMarketAmount());
-        if(amount.signum() < 0){
+        if (amount.signum() < 0) {
             throw new BizException("操作失败:订单金额异常");
         }
         studentGoodsSell.setOrganId(student.getOrganId());
@@ -250,12 +257,15 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         StudentGoodsSell studentGoodsSell = studentGoodsSellDao.get(goodsSellId);
         Integer studentId = studentGoodsSell.getUserId();
         studentDao.lockUser(studentId);
-//        SysUser student = sysUserFeignService.queryUserById(studentId);
-        List<GoodsSellDto> goodsSellDtos = JSONObject.parseArray(studentGoodsSell.getGoodsJson(),GoodsSellDto.class);
+        List<GoodsSellDto> goodsSellDtos = JSONObject.parseArray(studentGoodsSell.getGoodsJson(), GoodsSellDto.class);
         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);
+        Map<Integer, String> integerStringMap = getMap("goods", "id_", "type_", goodsIds, Integer.class, String.class);
+        Map<Integer, BigDecimal> map = getMap("goods", "id_", "discount_price_", goodsIds, Integer.class, BigDecimal.class);
         for (GoodsSellDto goodsSellDto : goodsSellDtos) {
+            goodsSellDto.setGoodsType(integerStringMap.get(goodsSellDto.getGoodsId()));
+            if (StringUtils.isNotEmpty(goodsSellDto.getComplementGoodsIdList())) {
+                goodsSellDto.setGoodsSellDtos(goodsService.queryGoodsSellDtos(goodsSellDto.getComplementGoodsIdList()));
+            }
             goodsSellDto.setGoodsPrice(map.get(goodsSellDto.getGoodsId()));
             goodsSellDto.setTotalGoodsPrice(map.get(goodsSellDto.getGoodsId()).multiply(new BigDecimal(goodsSellDto.getGoodsNum())));
         }
@@ -266,7 +276,7 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
             amount = amount.add(goodsSellDto.getTotalGoodsPrice());
         }
         amount = amount.subtract(studentGoodsSell.getMarketAmount());
-        if(amount.signum() < 0){
+        if (amount.signum() < 0) {
             throw new BizException("操作失败:订单金额异常");
         }
         String orderNo1 = studentGoodsSell.getOrderNo();
@@ -274,16 +284,16 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
 
         studentGoodsSell.setOrderNo(orderNo);
         StudentPaymentOrder studentPaymentOrder = null;
-        if(StringUtils.isNotEmpty(orderNo1)){
+        if (StringUtils.isNotEmpty(orderNo1)) {
             studentPaymentOrder = studentPaymentOrderService.findOrderByOrderNo(orderNo1);
-            if(studentPaymentOrder != null){
-                if(studentPaymentOrder.getStatus() == DealStatusEnum.SUCCESS){
+            if (studentPaymentOrder != null) {
+                if (studentPaymentOrder.getStatus() == DealStatusEnum.SUCCESS) {
                     throw new BizException("该订单已支付");
                 }
                 //关闭老订单
-                if(studentPaymentOrder.getBalancePaymentAmount() != null){
+                if (studentPaymentOrder.getBalancePaymentAmount() != null) {
                     studentGoodsSell.setIsUseBalancePayment(true);
-                }else {
+                } else {
                     studentGoodsSell.setIsUseBalancePayment(false);
                 }
                 studentPaymentOrder.setStatus(DealStatusEnum.CLOSE);
@@ -380,7 +390,7 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         if (StringUtils.isNotEmpty(goodsJson)) {
             List<RepairGoodsDto> repairGoodsDtos = JSONObject.parseArray(goodsJson, RepairGoodsDto.class);
             List<Integer> goodsIds = repairGoodsDtos.stream().map(e -> e.getId()).collect(Collectors.toList());
-            Map<Integer, BigDecimal> map = getMap("goods", "id_", "market_price_", goodsIds, Integer.class, BigDecimal.class);
+            Map<Integer, BigDecimal> map = getMap("goods", "id_", "discount_price_", goodsIds, Integer.class, BigDecimal.class);
             repairGoodsDtos.forEach(e -> {
                 e.setGroupPurchasePrice(map.get(e.getId()));
             });
@@ -716,7 +726,7 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         PageInfo<BasicUserDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
         Map<String, Object> params = new HashMap<>();
         MapUtil.populateMap(params, queryInfo);
-        params.put("teacherId",sysUser.getId());
+        params.put("teacherId", sysUser.getId());
 
         List<BasicUserDto> dataList = null;
         int count = studentRepairDao.countEduStudents(params);
@@ -732,17 +742,26 @@ public class StudentRepairServiceImpl extends BaseServiceImpl<Integer, StudentRe
         return pageInfo;
     }
 
-    public void saveSellOrder(String orderNo){
+    public void saveSellOrder(String orderNo) {
         StudentPaymentOrder orderByOrderNo = studentPaymentOrderService.findOrderByOrderNo(orderNo);
         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,12 @@ 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<>();
+        //组合商品实际总价
+        Map<Integer, BigDecimal> parentGoodsTotalPriceMap = new HashMap<>();
         //应付总额
         BigDecimal totalActual = totalAmount.subtract(marketAmount);
         //可用应付
@@ -759,50 +784,137 @@ 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());
+            }
+            parentGoodsTotalPriceMap.put(sellOrder.getParentGoodsId(), totalGoodsPrice);
+            //如果组合价大于预计总价
+            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());
+            BigDecimal divide = parentGoodsTotalPriceMap.get(parentGoodsId);
+            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 != null && 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 != null && 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 (marketAmount.doubleValue() > 0l) {
                 //如果是最后一件商品
-                if(i == goodsId.size() - 1){
-                    goodsSellDto.setTotalGoodsPrice(goodsSellDto.getTotalGoodsPrice().subtract(usableMarketAmount));
-                }else {
+                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);
                 }
             }
 
             //如果没有使用余额,那么实际金额和预计金额一致
-            if(balancePaymentAmount.doubleValue() == 0l){
+            if (balancePaymentAmount.doubleValue() == 0l) {
                 sellOrder.setActualAmount(goodsSellDto.getTotalGoodsPrice());
                 sellOrder.setBalanceAmount(BigDecimal.ZERO);
-            }else {
+            } else {
                 //如果是最后一件商品
-                if(i == goodsId.size() - 1){
+                if (i == sellOrderList.size() - 1) {
                     sellOrder.setActualAmount(usableAmount);
                     sellOrder.setBalanceAmount(usableBalance);
-                }else {
+                } else {
                     //获取分配的余额
-                    BigDecimal multiply = ratioAmount.multiply(balancePaymentAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
+                    BigDecimal multiply = ratioAmount.multiply(balancePaymentAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
                     //分配的实际支付
-                    BigDecimal multiply1 = ratioAmount.multiply(realityAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
+                    BigDecimal multiply1 = ratioAmount.multiply(realityAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
                     sellOrder.setActualAmount(multiply1);
                     sellOrder.setBalanceAmount(multiply);
                     usableAmount = usableAmount.subtract(multiply1);
@@ -811,22 +923,23 @@ 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.setSellCost2(JSONObject.toJSONString(costMap));
+            if (SellTypeEnum.ACCESSORIES.getCode().equals(goodsSellDto.getGoodsType()) || SellTypeEnum.INSTRUMENT.getCode().equals(goodsSellDto.getGoodsType())) {
+                sellOrder.setType(SellTypeEnum.valueOf(goodsSellDto.getGoodsType()));
+            } else {
+                sellOrder.setType(SellTypeEnum.OTHER);
+            }
+            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);
         }
     }
 

+ 235 - 13
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,14 @@ 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;
+    @Autowired
+    private GoodsService goodsService;
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
@@ -213,11 +223,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 +268,36 @@ 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);
+
+            subjectChange.setOrderId(studentPaymentOrder.getId().intValue());
+            subjectChange.setOrderNo(orderNo);
+            subjectChangeDao.update(subjectChange);
+
+            List<Integer> goodsIdList = Arrays.stream(goodsIds.split(",")).map(Integer::parseInt).collect(Collectors.toList());
+
+            //退原订单商品
+            sellOrderService.refundByOrderId(subjectChange.getOriginalOrderId().longValue(), false);
+            //添加新订单
+            this.addSellOrder(studentPaymentOrder.getId(), subjectChange.getMusicGroupId(), goodsIdList, BigDecimal.ZERO, BigDecimal.ZERO, subjectChange.getKitGroupPurchaseType());
+        }
         return subjectChange;
     }
 
@@ -280,25 +321,39 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
         SubjectChange subjectChange = new SubjectChange();
         SubjectChange studentLastChange = subjectChangeDao.getStudentLastChange(studentId, musicGroupId);
         if (studentLastChange != null) {
+            Set<Integer> refundSellOrderGoodsIds = getRefundGoodsId(studentLastChange.getOrderId().longValue());
             subjectChange.setStudentId(studentLastChange.getStudentId());
             subjectChange.setOrderId(studentLastChange.getOrderId());
             subjectChange.setCooperationOrganId(studentLastChange.getCooperationOrganId());
             subjectChange.setMusicGroupId(studentLastChange.getMusicGroupId());
             subjectChange.setOriginalCourseFee(studentLastChange.getChangeCourseFee());
             subjectChange.setKitGroupPurchaseType(studentLastChange.getKitGroupPurchaseType());
-            subjectChange.setOriginalCost(studentLastChange.getChangeCost());
 
-            if (studentLastChange.getChangeMusical() != null) {
+            BigDecimal originalCost = BigDecimal.ZERO;
+            if (studentLastChange.getChangeMusical() != null && !refundSellOrderGoodsIds.contains(studentLastChange.getChangeMusical())) {
                 subjectChange.setOriginalMusical(studentLastChange.getChangeMusical());
                 subjectChange.setOriginalMusicalGoods(goodsDao.get(studentLastChange.getChangeMusical()));
                 subjectChange.setOriginalMusicalPrice(studentLastChange.getChangeMusicalPrice());
             }
 
             if (studentLastChange.getChangeAccessories() != null) {
-                subjectChange.setOriginalAccessories(studentLastChange.getChangeAccessories());
-                subjectChange.setOriginalAccessoriesGoods(goodsDao.findGoodsByIds(studentLastChange.getChangeAccessories()));
-                subjectChange.setOriginalAccessoriesPrice(studentLastChange.getChangeAccessoriesPrice());
+                String[] goodsIdArr = studentLastChange.getChangeAccessories().split(",");
+                String accessoriesId = "";
+                for (String goodsId : goodsIdArr) {
+                    if (refundSellOrderGoodsIds.contains(Integer.parseInt(goodsId))) {
+                        continue;
+                    }
+                    accessoriesId += StringUtils.isBlank(accessoriesId) ? goodsId : "," + goodsId;
+                }
+                if (StringUtils.isNotBlank(accessoriesId)) {
+                    subjectChange.setOriginalAccessories(accessoriesId);
+                    List<Goods> accessoriesGoods = goodsDao.findGoodsByIds(accessoriesId);
+                    subjectChange.setOriginalAccessoriesGoods(accessoriesGoods);
+                    BigDecimal price = accessoriesGoods.stream().map(Goods::getGroupPurchasePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+                    subjectChange.setOriginalAccessoriesPrice(price);
+                }
             }
+            subjectChange.setOriginalCost(originalCost);
             return subjectChange;
         }
         //2.1不存在历史的更换
@@ -306,11 +361,15 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
         if (details.size() <= 0) {
             return null;
         }
+
+        Set<Integer> refundSellOrderGoodsIds = getRefundGoodsId(details.get(0).getPaymentOrderId());
+
         MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
         subjectChange.setStudentId(studentId);
         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) {
@@ -318,10 +377,12 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
                 subjectChange.setOriginalCourseFee(detail.getPrice());
             } else if (detail.getType().equals(OrderDetailTypeEnum.MUSICAL)) {
                 subjectChange.setKitGroupPurchaseType(detail.getKitGroupPurchaseType());
-                int goodsId = Integer.parseInt(detail.getGoodsIdList());
-                subjectChange.setOriginalMusical(goodsId);
-                subjectChange.setOriginalMusicalGoods(goodsDao.get(goodsId));
-                subjectChange.setOriginalMusicalPrice(detail.getPrice());
+                Integer goodsId = Integer.parseInt(detail.getGoodsIdList());
+                if (!refundSellOrderGoodsIds.contains(goodsId)) {
+                    subjectChange.setOriginalMusical(goodsId);
+                    subjectChange.setOriginalMusicalGoods(goodsDao.get(goodsId));
+                    subjectChange.setOriginalMusicalPrice(detail.getPrice());
+                }
             } else {
                 if (StringUtils.isNotBlank(detail.getGoodsIdList())) {
                     accessoriesPrice = accessoriesPrice.add(detail.getPrice());
@@ -330,9 +391,20 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
             }
         }
         if (StringUtils.isNotBlank(accessoriesIds)) {
-            subjectChange.setOriginalAccessories(accessoriesIds);
-            subjectChange.setOriginalAccessoriesGoods(goodsDao.findGoodsByIds(accessoriesIds));
-            subjectChange.setOriginalAccessoriesPrice(accessoriesPrice);
+            String[] goodsIdArr = accessoriesIds.split(",");
+            String accessoriesId = "";
+            for (String goodsId : goodsIdArr) {
+                if (refundSellOrderGoodsIds.contains(Integer.parseInt(goodsId))) {
+                    continue;
+                }
+                accessoriesId += StringUtils.isBlank(accessoriesId) ? goodsId : "," + goodsId;
+            }
+
+            subjectChange.setOriginalAccessories(accessoriesId);
+            List<Goods> accessoriesGoods = goodsDao.findGoodsByIds(accessoriesId);
+            subjectChange.setOriginalAccessoriesGoods(accessoriesGoods);
+            BigDecimal price = accessoriesGoods.stream().map(Goods::getGroupPurchasePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+            subjectChange.setOriginalAccessoriesPrice(price);
         }
         Long orderId = details.get(0).getPaymentOrderId();
         //2.2 计算销售成本
@@ -341,6 +413,14 @@ public class SubjectChangeServiceImpl extends BaseServiceImpl<Integer, SubjectCh
         return subjectChange;
     }
 
+    private Set<Integer> getRefundGoodsId(Long orderId) {
+        List<SellOrder> refundSellOrders = sellOrderService.getRefundSellOrder(orderId);
+        Set<Integer> refundSellOrderGoodsIds = refundSellOrders.stream().filter(e -> e.getParentGoodsId() == null).map(SellOrder::getGoodsId).collect(Collectors.toSet());
+        Set<Integer> refundSellOrderParentGoodsId = refundSellOrders.stream().filter(e -> e.getParentGoodsId() != null).map(SellOrder::getParentGoodsId).collect(Collectors.toSet());
+        refundSellOrderGoodsIds.addAll(refundSellOrderParentGoodsId);
+        return refundSellOrderGoodsIds;
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean orderCallback(StudentPaymentOrder studentPaymentOrder) {
@@ -393,6 +473,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(), false);
+                //添加新订单
+                this.addSellOrder(studentPaymentOrder.getId(), subjectChange.getMusicGroupId(), goodsIdList, studentPaymentOrder.getExpectAmount(), studentPaymentOrder.getBalancePaymentAmount(), subjectChange.getKitGroupPurchaseType());
+            }
 
             //插入交易明细
             BigDecimal amount = studentPaymentOrder.getActualAmount();
@@ -493,4 +587,132 @@ 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, KitGroupPurchaseTypeEnum kitGroupPurchaseType) {
+        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 hasRouteExpectAmount = BigDecimal.ZERO;
+
+        AccountType accountType = sysPaymentConfigService.checkAccountType(PaymentChannelEnum.valueOf(order.getPaymentChannel()), order.getMerNos());
+        List<SellOrder> sellOrderList = goodsService.subtractStock(goodsIds, accountType);
+
+        for (Integer goodsId : goodsIds) {
+            BigDecimal goodsPrice = BigDecimal.ZERO;
+            Goods nowGoods = new Goods();
+            for (Goods goods : goodies) {
+                if (goods.getId().equals(goodsId)) {
+                    nowGoods = goods;
+                    break;
+                }
+            }
+            goodsPrice = nowGoods.getGroupPurchasePrice();
+            BigDecimal expectAmount = BigDecimal.ZERO;
+            BigDecimal goodsBalance = BigDecimal.ZERO;
+
+            if (goodsTotalPrice.compareTo(BigDecimal.ZERO) > 0) {
+                goodsBalance = balance.multiply(goodsPrice).divide(goodsTotalPrice, 2, BigDecimal.ROUND_HALF_UP);
+                expectAmount = totalAmount.multiply(goodsPrice).divide(goodsTotalPrice, 2, BigDecimal.ROUND_HALF_UP);
+            }
+            if (i == goodsNum) {
+                goodsBalance = balance.subtract(hasRouteBalance);
+                expectAmount = totalAmount.subtract(hasRouteExpectAmount);
+            }
+            //租赁、免费的没有销售收入,有销售成本
+            if (nowGoods.getType().equals(GoodsType.INSTRUMENT) && (kitGroupPurchaseType.equals(KitGroupPurchaseTypeEnum.LEASE) || kitGroupPurchaseType.equals(KitGroupPurchaseTypeEnum.FREE))) {
+                goodsBalance = BigDecimal.ZERO;
+                expectAmount = BigDecimal.ZERO;
+            }
+
+            hasRouteBalance = hasRouteBalance.add(goodsBalance);
+            hasRouteExpectAmount = hasRouteExpectAmount.add(expectAmount);
+            i++;
+
+            int complementGoodsNum = nowGoods.getComplementGoodsIdList() == null ? 1 : nowGoods.getComplementGoodsIdList().split(",").length;
+            BigDecimal complementPrice = nowGoods.getGroupPurchasePrice();
+            Map<Integer, BigDecimal> complementGoodsPrice = new HashMap<>();
+            complementGoodsPrice.put(nowGoods.getId(), nowGoods.getGroupPurchasePrice());
+            if (nowGoods.getComplementGoodsIdList() != null) {
+                List<Goods> complementGoodies = goodsDao.findGoodsByIds(nowGoods.getComplementGoodsIdList());
+                complementGoodsPrice = complementGoodies.stream().collect(Collectors.toMap(Goods::getId, Goods::getGroupPurchasePrice));
+                complementPrice = complementGoodies.stream().map(Goods::getGroupPurchasePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+            }
+
+            BigDecimal hasRouteSellOrderExpectAmount = BigDecimal.ZERO;
+            BigDecimal hasRouteSellOrderBalance = BigDecimal.ZERO;
+            for (SellOrder sellOrder : sellOrderList) {
+                if (!goodsId.equals(sellOrder.getParentGoodsId()) && !goodsId.equals(sellOrder.getGoodsId())) {
+                    continue;
+                }
+                if (sellOrder.getHasRoute()) {
+                    continue;
+                }
+                BigDecimal sellOrderExpectAmount = BigDecimal.ZERO;
+                BigDecimal sellOrderBalance = BigDecimal.ZERO;
+                if (complementPrice.compareTo(BigDecimal.ZERO) > 0) {
+                    sellOrderExpectAmount = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(expectAmount).divide(complementPrice, 2, BigDecimal.ROUND_HALF_UP);
+                    sellOrderBalance = complementGoodsPrice.get(sellOrder.getGoodsId()).multiply(new BigDecimal(sellOrder.getNum())).multiply(goodsBalance).divide(complementPrice, 2, BigDecimal.ROUND_HALF_UP);
+                }
+                complementGoodsNum = complementGoodsNum - sellOrder.getNum();
+                if (complementGoodsNum <= 0) {
+                    sellOrderExpectAmount = expectAmount.subtract(hasRouteSellOrderExpectAmount);
+                    sellOrderBalance = goodsBalance.subtract(hasRouteSellOrderBalance);
+                }
+                hasRouteSellOrderExpectAmount = hasRouteSellOrderExpectAmount.add(sellOrderExpectAmount);
+                hasRouteSellOrderBalance = hasRouteSellOrderBalance.add(sellOrderBalance);
+
+                sellOrder.setExpectAmount(sellOrderExpectAmount);
+                sellOrder.setBalanceAmount(sellOrderBalance);
+                sellOrder.setActualAmount(sellOrderExpectAmount.subtract(sellOrderBalance));
+                sellOrder.setOrganId(order.getOrganId());
+                sellOrder.setCooperationOrganId(musicGroup.getCooperationOrganId());
+                sellOrder.setEduTeacherId(musicGroup.getEducationalTeacherId());
+                sellOrder.setTransNo(order.getTransNo());
+                sellOrder.setOrderId(order.getId());
+                sellOrder.setOrderNo(order.getOrderNo());
+                sellOrder.setUserId(order.getUserId());
+                sellOrder.setPaymentChannel(order.getPaymentChannel());
+                sellOrder.setMerNo(order.getMerNos());
+                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);
+                }
+                sellOrder.setHasRoute(true);
+                if (complementGoodsNum <= 0) {
+                    break;
+                }
+            }
+        }
+        sellOrderDao.batchInsert(sellOrderList);
+        return sellOrderList;
+    }
 }

+ 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){

+ 174 - 13
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,29 @@
     <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_,stock_type_)
+        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},
+        #{stockType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler})
     </insert>
-    <insert id="batchInsert">
+    <insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
         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_,stock_type_)
         VALUES
-        <foreach collection="goodsList" separator="," item="goods">
+        <foreach collection="list" 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},
+            #{goods.stockType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler})
         </foreach>
     </insert>
     <!-- 根据主键查询一条记录 -->
@@ -116,9 +127,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 +145,108 @@
             <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>
+            <if test="stockType != null">
+                stock_type_ = #{stockType,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>
+                <if test="goods.stockType != null">
+                    stock_type_ = #{goods.stockType,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 +257,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,6 +283,18 @@
             <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>
 
@@ -202,4 +320,47 @@
             #{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="lockBySn" resultMap="Goods">
+        SELECT * FROM goods WHERE sn_ = #{sn} FOR UPDATE
+    </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_ = 1 AND complement_goods_id_list_ IS NULL
+    </select>
+    <select id="getOuterRepertoryWarnName" resultType="java.lang.String">
+        SELECT GROUP_CONCAT( DISTINCT name_) FROM goods WHERE tax_stock_count_ &lt;= #{outerRepertoryWarnNum} AND stock_warning_ = 1 AND complement_goods_id_list_ IS NULL
+    </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="discount_price_"/>
+        <result property="totalGoodsPrice" column="discount_price_"/>
+    </resultMap>
+    <select id="queryGoodsSellDtos" resultMap="GoodsSellDtoMap">
+        SELECT id_,image_,name_,type_,discount_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_ DESC <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_ DESC <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>

+ 2 - 2
mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentCalenderMapper.xml

@@ -106,8 +106,8 @@
 	    <foreach collection="list" item="item" index="index" open="" close="" separator=";">
 	        UPDATE music_group_payment_calender
 	        <set>
-                <if test="paymentPattern != null">
-                    payment_pattern_ = #{paymentPattern},
+                <if test="item.paymentPattern != null">
+                    payment_pattern_ = #{item.paymentPattern},
                 </if>
 	            <if test="item.type != null">
 	                type_ = #{item.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},

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

@@ -370,8 +370,4 @@
         SET mgsf.payment_status_ = #{paymentStatus},mgsf.update_time_ = NOW()
         WHERE mgpcd.music_group_payment_calender_id_ = mgpc.id_ AND mgpc.id_ = #{calenderId}
     </update>
-    <update id="updateFeeStatus">
-        UPDATE music_group_student_fee_ mgsf SET mgsf.payment_status_ = 'NON_PAYMENT',mgsf.update_time_ = NOW()
-        WHERE mgsf.payment_valid_end_date_ IS NOT NULL AND mgsf.payment_status_ = 'PAID_COMPLETED' AND mgsf.payment_valid_end_date_ &lt; NOW()
-    </update>
 </mapper>

+ 246 - 36
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,24 @@
         <result column="user_id_" property="userId"/>
         <result column="payment_channel_" property="paymentChannel"/>
         <result column="mer_no_" property="merNo"/>
+        <result column="batch_no_" property="batchNo"/>
+        <result column="status_" property="status" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+        <result column="refund_time_" property="refundTime"/>
         <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_, refund_time_,sell_time_, create_ime_,
+        update_time_
     </sql>
     <select id="get" parameterType="java.lang.Integer" resultMap="SellOrder">
         <!--@mbg.generated-->
@@ -56,15 +65,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_, refund_time_,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},
+        #{refundTime},#{sellTime}, #{createIme}, #{updateTime})
     </insert>
     <update id="update" parameterType="com.ym.mec.biz.dal.entity.SellOrder">
         <!--@mbg.generated-->
@@ -98,7 +107,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 +136,21 @@
             <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="refundTime != null">
+                refund_time_ = #{refundTime},
+            </if>
             <if test="sellTime != null">
                 sell_time_ = #{sellTime},
             </if>
@@ -137,29 +164,121 @@
         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.refundTime != null">
+                    refund_time_ = #{sellOrder.refundTime},
+                </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 +287,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>
 
@@ -180,13 +300,19 @@
                 AND FIND_IN_SET(so.organ_id_,#{organIdList})
             </if>
             <if test="goodsName != null and goodsName != ''">
-                AND so.goods_name_ = #{goodsName}
+                AND so.goods_name_ LIKE CONCAT('%',#{goodsName},'%')
             </if>
             <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}
@@ -324,7 +450,7 @@
         FROM student_payment_order spo
                  LEFT JOIN sell_order so on so.order_id_ = spo.id_
         WHERE spo.status_ = 'SUCCESS'
-          AND spo.group_type_ IN ('REPAIR', 'GOODS_SELL')
+          AND spo.group_type_ = 'REPAIR'
           AND spo.create_time_ >= #{startTime}
           AND spo.create_time_ <= #{endTime}
         GROUP BY spo.organ_id_
@@ -336,13 +462,31 @@
         SELECT spo.organ_id_,
                SUM(spo.actual_amount_) income_total_
         FROM student_payment_order spo
+                 LEFT JOIN sell_order so on so.order_id_ = spo.id_
         WHERE spo.status_ = 'SUCCESS'
-          AND spo.group_type_ IN ('REPAIR', 'GOODS_SELL')
+          AND spo.group_type_ = 'REPAIR'
           AND spo.create_time_ >= #{startTime}
           AND spo.create_time_ <= #{endTime}
         GROUP BY spo.organ_id_
         ]]></select>
 
+    <!-- 获取分部学校的收入支出(商品销售订单) -->
+    <select id="getGoodsSellGroupMonthReport"
+            resultMap="com.ym.mec.biz.dal.dao.OperatingReportDao.OperatingReport"><![CDATA[
+        SELECT spo.organ_id_,
+               so.cooperation_organ_id_,
+               SUM(so.actual_amount_)       income_total_,
+               SUM(so.actual_amount_)       sell_amount_,
+               SUM(so.sell_cost_ * so.num_) sell_cost_
+        FROM student_payment_order spo
+                 LEFT JOIN sell_order so on so.order_id_ = spo.id_
+        WHERE spo.status_ = 'SUCCESS'
+          AND spo.group_type_ ='GOODS_SELL'
+          AND spo.create_time_ >= #{startTime}
+          AND spo.create_time_ <= #{endTime}
+        GROUP BY spo.organ_id_, so.cooperation_organ_id_
+        ]]></select>
+
 
     <!-- 获取订单的销售列表 -->
     <select id="getOrderSellOrder" resultMap="SellOrder">
@@ -363,17 +507,83 @@
         WHERE order_id_ = #{orderId}
     </select>
 
-    <select id="getSubjectChangeMonthReport" resultMap="com.ym.mec.biz.dal.dao.OperatingReportDao.OperatingReport"><![CDATA[
-        SELECT sc.organ_id_,
-               sc.cooperation_organ_id_,
-               SUM(spo.actual_amount_) income_total_,
-               SUM(sc.sell_amount_)    sell_amount_,
-               SUM(sc.cost_margin_)    sell_cost_
-        FROM subject_change sc
-                 LEFT JOIN student_payment_order spo ON spo.id_ = sc.order_id_
-        WHERE sc.status_ = 2
-          AND sc.sell_time_ >= #{startTime}
-          AND sc.sell_time_ <= #{endTime}
-        GROUP BY sc.organ_id_, sc.cooperation_organ_id_
+    <!-- 获取分部学校的收入支出(声部更改) -->
+    <select id="getSubjectChangeMonthReport"
+            resultMap="com.ym.mec.biz.dal.dao.OperatingReportDao.OperatingReport"><![CDATA[
+        SELECT spo.organ_id_,
+               spo.music_group_id_          cooperation_organ_id_,
+               SUM(so.actual_amount_)       sell_amount_,
+               SUM(so.sell_cost_ * so.num_) sell_cost_
+        FROM student_payment_order spo
+                 LEFT JOIN sell_order so on so.order_id_ = spo.id_
+        WHERE spo.status_ = 'SUCCESS'
+          AND spo.group_type_ = 'SUBJECT_CHANGE'
+          AND spo.create_time_ >= #{startTime}
+          AND spo.create_time_ <= #{endTime}
+        GROUP BY spo.organ_id_, spo.music_group_id_
+        ]]></select>
+
+    <!-- 获取分部学校的收入支出(声部更改) -->
+    <select id="getSubjectChangeGroupIncome"
+            resultMap="com.ym.mec.biz.dal.dao.OperatingReportDao.OperatingReport"><![CDATA[
+        SELECT spo.organ_id_,
+               spo.music_group_id_     cooperation_organ_id_,
+               SUM(spo.actual_amount_) income_total_
+        FROM student_payment_order spo
+        WHERE spo.status_ = 'SUCCESS'
+          AND spo.group_type_ = 'SUBJECT_CHANGE'
+          AND spo.create_time_ >= #{startTime}
+          AND spo.create_time_ <= #{endTime}
+        GROUP BY spo.organ_id_, spo.music_group_id_
+        ]]></select>
+
+    <!-- 获取退货订单的收入和成本 -->
+    <select id="getRefundIncome" resultMap="com.ym.mec.biz.dal.dao.OperatingReportDao.OperatingReport"><![CDATA[
+        SELECT organ_id_,
+               cooperation_organ_id_,
+               -SUM(sell_cost_ * num_) sell_cost_
+        FROM sell_order
+        WHERE status_ = 1
+          AND refund_time_ >= #{startTime}
+          AND refund_time_ <= #{endTime}
+        GROUP BY organ_id_, 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} AND status_=0
+        <if test="parentGoodsId != null">
+            AND parent_goods_id_ = #{parentGoodsId}
+        </if>
+    </select>
+
+    <select id="getNoneBatchNoSellOrderIds" resultType="int">
+        SELECT id_
+        FROM sell_order
+        WHERE status_ = 0
+          AND stock_type_ IS NOT NULL
+          AND batch_no_ IS NULL
+        ORDER BY sell_time_
+    </select>
+
+    <select id="getRefundSellOrder" resultMap="SellOrder">
+        SELECT *
+        FROM sell_order
+        WHERE order_id_ = #{orderId}
+          AND status_ = 1
+    </select>
+
+
+    <select id="lockSellOrders" resultMap="SellOrder">
+        SELECT * FROM sell_order WHERE id_ IN
+        <foreach collection="sellOrderIds" item="sellOrderId" open="(" close=")" separator=",">
+            #{sellOrderId}
+        </foreach>
+    </select>
+</mapper>

+ 47 - 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,44 @@
 		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>
+	<resultMap type="com.ym.mec.biz.dal.dto.StudentPaymentOrderDto" id="StudentPaymentOrderDto" extends="com.ym.mec.biz.dal.dao.StudentPaymentOrderDao.StudentPaymentOrder">
+		<result column="goods_image_" property="image" />
+		<result column="goods_name_" property="goodsName" />
+		<result column="goods_num_" property="goodsNum" />
+		<result column="goods_amount_" property="goodsAmount" />
+	</resultMap>
+	<sql id="queryStudentPaymentOrdersSql">
+		<where>
+				spo.type_ IN ('GOODS_SELL','APPLY','SUBJECT_CHANGE') AND so.id_ IS NOT NULL
+			<if test="status != null">
+				AND spo.status_ = #{status}
+			</if>
+			<if test="receiveStatus != null and receiveStatus != ''">
+				AND spo.receive_status_ = #{receiveStatus}
+			</if>
+			<if test="studentId != null">
+				AND spo.user_id_ = #{studentId}
+			</if>
+		</where>
+	</sql>
+    <select id="queryStudentPaymentOrders" resultMap="StudentPaymentOrderDto">
+		SELECT spo.*,g.image_ goods_image_,g.name_ goods_name_,so.num_ goods_num_,so.expect_amount_ goods_amount_
+		FROM student_payment_order spo
+		LEFT JOIN sell_order so ON so.order_no_ = spo.order_no_
+		LEFT JOIN goods g ON g.id_ = so.goods_id_
+		<include refid="queryStudentPaymentOrdersSql"/>
+		ORDER BY spo.pay_time_ DESC
+		<include refid="global.limit"/>
+	</select>
+	<select id="countStudentPaymentOrders" resultType="java.lang.Integer">
+		SELECT COUNT(DISTINCT spo.id_)
+		FROM student_payment_order spo
+		LEFT JOIN sell_order so ON so.order_no_ = spo.order_no_
+		<include refid="queryStudentPaymentOrdersSql"/>
+	</select>
 </mapper>

+ 3 - 1
mec-biz/src/main/resources/config/mybatis/StudentPaymentOrderDetailMapper.xml

@@ -23,6 +23,7 @@
             <result column="discount_price_" property="discountPrice"/>
             <result column="agree_cost_price_" property="agreeCostPrice"/>
             <result column="goods_type_" property="type" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
+            <result column="complement_goods_id_list_" property="complementGoodsIdList"/>
         </collection>
     </resultMap>
 
@@ -197,7 +198,8 @@
                g.group_purchase_price_,
                g.discount_price_,
                g.agree_cost_price_,
-               g.type_ goods_type_
+               g.type_ goods_type_,
+               g.complement_goods_id_list_
         FROM student_payment_order_detail spod
                  LEFT JOIN goods g ON FIND_IN_SET(g.id_, spod.goods_id_list_)
         WHERE spod.payment_order_id_ = #{orderId}

+ 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("确认收货执行失败");
+	}
 }

+ 61 - 0
mec-student/src/main/java/com/ym/mec/student/controller/GoodsController.java

@@ -0,0 +1,61 @@
+package com.ym.mec.student.controller;
+
+import com.ym.mec.biz.dal.entity.Goods;
+import com.ym.mec.biz.dal.entity.GoodsCategory;
+import com.ym.mec.biz.service.GoodsCategoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.biz.dal.page.GoodsQueryInfo;
+import com.ym.mec.biz.service.GoodsService;
+import com.ym.mec.common.controller.BaseController;
+
+import java.util.Objects;
+
+@RequestMapping("goods")
+@Api(tags = "商品(教材、辅件)服务")
+@RestController
+public class GoodsController extends BaseController {
+
+    @Autowired
+    private GoodsService goodsService;
+    @Autowired
+    private GoodsCategoryService goodsCategoryService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "根据商品(教材、辅件)编号查询商品(教材、辅件)")
+    @GetMapping("/get/{id}")
+    public Object get(@ApiParam(value = "商品(教材、辅件)编号", required = true) @PathVariable("id") Integer id){
+        Goods goods = goodsService.get(id);
+        GoodsCategory goodsCategory = goodsCategoryService.get(goods.getGoodsCategoryId());
+        if(Objects.nonNull(goodsCategory)){
+            goods.setGoodsCategoryName(goodsCategory.getName());
+        }
+        return succeed(goods);
+    }
+
+    @ApiOperation(value = "分页查询商品(教材、辅件)列表")
+    @GetMapping("/queryPage")
+    public Object queryPage(GoodsQueryInfo queryInfo){
+        return succeed(goodsService.queryPage(queryInfo));
+    }
+
+    @ApiOperation(value = "通过科目编号、商品分类 查询商品(教材、辅件)列表")
+    @GetMapping("/queryGoodsBySubId")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "subjectId", value = "科目编号", required = true, dataType = "Integer"),
+            @ApiImplicitParam(name = "type", value = "INSTRUMENT 乐器, ACCESSORIES 教辅", required = true, dataType = "String")})
+    public Object findGoodsBySubId(Integer subjectId,String type){
+        return succeed(goodsService.findGoodsBySubId(subjectId,type));
+    }
+}

+ 47 - 22
mec-student/src/main/java/com/ym/mec/student/controller/MusicGroupController.java

@@ -1,38 +1,59 @@
 package com.ym.mec.student.controller;
 
-import com.ym.mec.auth.api.client.SysUserFeignService;
-import com.ym.mec.auth.api.entity.SysUser;
-import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
-import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDetailDao;
-import com.ym.mec.biz.dal.dao.MusicGroupStudentFeeDao;
-import com.ym.mec.biz.dal.dto.RegisterPayDto;
-import com.ym.mec.biz.dal.entity.*;
-import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
-import com.ym.mec.biz.dal.enums.*;
-import com.ym.mec.biz.service.*;
-import com.ym.mec.common.controller.BaseController;
-import com.ym.mec.common.entity.HttpResponseResult;
-import com.ym.mec.common.exception.BizException;
-
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.ui.ModelMap;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
+import javax.annotation.Resource;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
+import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDetailDao;
+import com.ym.mec.biz.dal.dao.MusicGroupStudentFeeDao;
+import com.ym.mec.biz.dal.dto.RegisterPayDto;
+import com.ym.mec.biz.dal.entity.Goods;
+import com.ym.mec.biz.dal.entity.MusicGroup;
+import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
+import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderDetail;
+import com.ym.mec.biz.dal.entity.MusicGroupStudentFee;
+import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
+import com.ym.mec.biz.dal.entity.MusicGroupSubjectPlan;
+import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
+import com.ym.mec.biz.dal.entity.StudentRegistration;
+import com.ym.mec.biz.dal.enums.DealStatusEnum;
+import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
+import com.ym.mec.biz.dal.enums.OrderTypeEnum;
+import com.ym.mec.biz.dal.enums.PaymentStatusEnum;
+import com.ym.mec.biz.service.MusicGroupService;
+import com.ym.mec.biz.service.MusicGroupSubjectPlanService;
+import com.ym.mec.biz.service.StudentPaymentOrderDetailService;
+import com.ym.mec.biz.service.StudentPaymentOrderService;
+import com.ym.mec.biz.service.StudentRegistrationService;
+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.util.date.DateUtil;
+
 @RequestMapping("musicGroup")
 @Api(tags = "乐团服务")
 @RestController
@@ -136,6 +157,10 @@ public class MusicGroupController extends BaseController {
                 (musicGroup.getStatus() != MusicGroupStatusEnum.APPLY && musicGroup.getStatus() != MusicGroupStatusEnum.PAY)){
             return failed("乐团在"+musicGroup.getStatus().getMsg()+",不能缴费");
         }
+        Date now = new Date();
+        if (DateUtil.daysBetween(musicGroup.getPaymentExpireDate(), now) > 1) {
+            return failed("乐团缴费时间已截止");
+        }
         studentRegistration.setOwnershipType(musicGroup.getOwnershipType());
         studentRegistration.setChargeTypeId(musicGroup.getChargeTypeId());
 

+ 26 - 9
mec-student/src/main/java/com/ym/mec/student/controller/RepairController.java

@@ -1,6 +1,20 @@
 package com.ym.mec.student.controller;
 
 
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.entity.StudentGoodsSell;
@@ -13,18 +27,14 @@ import com.ym.mec.biz.dal.page.GoodsCategoryQueryInfo;
 import com.ym.mec.biz.dal.page.GoodsQueryInfo;
 import com.ym.mec.biz.dal.page.GoodsSellQueryInfo;
 import com.ym.mec.biz.dal.page.RepairStudentQueryInfo;
-import com.ym.mec.biz.service.*;
+import com.ym.mec.biz.service.GoodsCategoryService;
+import com.ym.mec.biz.service.GoodsService;
+import com.ym.mec.biz.service.StudentGoodsSellService;
+import com.ym.mec.biz.service.StudentPaymentOrderService;
+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 io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-import java.util.Map;
 
 @RequestMapping("repair")
 @Api(tags = "学生维修服务")
@@ -158,4 +168,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")) {

+ 43 - 3
mec-web/src/main/java/com/ym/mec/web/controller/GoodsController.java

@@ -1,5 +1,10 @@
 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.GoodsCategory;
+import com.ym.mec.biz.dal.entity.GoodsProcurement;
+import com.ym.mec.biz.service.GoodsCategoryService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -7,6 +12,7 @@ import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 
 import java.util.Date;
+import java.util.Objects;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -25,12 +31,34 @@ public class GoodsController extends BaseController {
 
     @Autowired
     private GoodsService goodsService;
+    @Autowired
+    private GoodsCategoryService goodsCategoryService;
+    @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.addGoods(goods,sysUser.getId());
+        return succeed();
+    }
+
+    @ApiOperation(value = "新增商品清单")
+    @PostMapping("/addGoodsProcurement")
+    @PreAuthorize("@pcs.hasPermissions('goods/addGoodsProcurement')")
+    public Object addGoodsProcurement(GoodsProcurement goodsProcurement){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        goodsProcurement.setOperatorId(sysUser.getId());
+        goodsService.addGoodsProcurement(goodsProcurement);
+        return succeed();
     }
 
     @ApiOperation(value = "删除商品(教材、辅件)")
@@ -47,6 +75,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')")
@@ -58,9 +94,13 @@ public class GoodsController extends BaseController {
 
     @ApiOperation(value = "根据商品(教材、辅件)编号查询商品(教材、辅件)")
     @GetMapping("/get/{id}")
-    @PreAuthorize("@pcs.hasPermissions('goods/get')")
     public Object get(@ApiParam(value = "商品(教材、辅件)编号", required = true) @PathVariable("id") Integer id){
-        return succeed(goodsService.get(id));
+        Goods goods = goodsService.get(id);
+        GoodsCategory goodsCategory = goodsCategoryService.get(goods.getGoodsCategoryId());
+        if(Objects.nonNull(goodsCategory)){
+            goods.setGoodsCategoryName(goodsCategory.getName());
+        }
+        return succeed(goods);
     }
 
     @ApiOperation(value = "分页查询商品(教材、辅件)列表")

+ 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 = "导入财务支出")

+ 12 - 2
mec-web/src/main/java/com/ym/mec/web/controller/MusicGroupController.java

@@ -249,13 +249,23 @@ public class MusicGroupController extends BaseController {
 		return succeed();
 	}
 
-	@ApiOperation(value = "延长缴费")
+	@ApiOperation(value = "延长缴费时间")
 	@PostMapping("/extensionPayment")
 	@PreAuthorize("@pcs.hasPermissions('musicGroup/extensionPayment')")
 	@ApiImplicitParams({ @ApiImplicitParam(name = "musicGroupId", value = "乐团编号", required = true, dataType = "String"),
 			@ApiImplicitParam(name = "expireDate", value = "延长缴费的截止日期", required = true, dataType = "Date") })
 	public Object extensionPayment(String musicGroupId, Date expireDate) {
-		musicGroupService.extensionPayment(musicGroupId, expireDate);
+		musicGroupService.extensionPaymentExpireDate(musicGroupId, expireDate);
+		return succeed();
+	}
+
+	@ApiOperation(value = "延长报名时间")
+	@PostMapping("/extensionApplyExpireDate")
+	@PreAuthorize("@pcs.hasPermissions('musicGroup/extensionApplyExpireDate')")
+	@ApiImplicitParams({ @ApiImplicitParam(name = "musicGroupId", value = "乐团编号", required = true, dataType = "String"),
+			@ApiImplicitParam(name = "expireDate", value = "延长报名的截止日期", required = true, dataType = "Date") })
+	public Object extensionApplyExpireDate(String musicGroupId, Date expireDate) {
+		musicGroupService.extensionApplyExpireDate(musicGroupId, expireDate);
 		return succeed();
 	}
 

+ 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,true));
+    }
+
 }

+ 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(){

+ 13 - 4
mec-web/src/main/resources/columnMapper.ini

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

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