ソースを参照

08 20 02 计算数值修改

hr 4 年 前
コミット
a214b984e8
27 ファイル変更1054 行追加80 行削除
  1. 17 14
      src/main/java/com/imed/costaccount/common/util/JacksonUtil.java
  2. 16 0
      src/main/java/com/imed/costaccount/mapper/AllocationMapper.java
  3. 2 0
      src/main/java/com/imed/costaccount/mapper/ShareParamValueMapper.java
  4. 90 0
      src/main/java/com/imed/costaccount/model/Allocation.java
  5. 34 16
      src/main/java/com/imed/costaccount/model/CostCostingCollection.java
  6. 19 0
      src/main/java/com/imed/costaccount/model/vo/AccountShareVO.java
  7. 8 0
      src/main/java/com/imed/costaccount/service/AccountingService.java
  8. 25 0
      src/main/java/com/imed/costaccount/service/AllocationService.java
  9. 8 0
      src/main/java/com/imed/costaccount/service/CostAccountShareService.java
  10. 9 0
      src/main/java/com/imed/costaccount/service/CostCostingGroupService.java
  11. 9 0
      src/main/java/com/imed/costaccount/service/CostShareLevelService.java
  12. 15 0
      src/main/java/com/imed/costaccount/service/CostShareParamService.java
  13. 24 0
      src/main/java/com/imed/costaccount/service/ResponsibilityService.java
  14. 9 0
      src/main/java/com/imed/costaccount/service/ShareParamValueService.java
  15. 23 0
      src/main/java/com/imed/costaccount/service/impl/AccountingServiceImpl.java
  16. 282 0
      src/main/java/com/imed/costaccount/service/impl/AllocationServiceImpl.java
  17. 18 0
      src/main/java/com/imed/costaccount/service/impl/CostAccountShareServiceImpl.java
  18. 232 14
      src/main/java/com/imed/costaccount/service/impl/CostCostingGroupServiceImpl.java
  19. 19 1
      src/main/java/com/imed/costaccount/service/impl/CostShareLevelServiceImpl.java
  20. 59 25
      src/main/java/com/imed/costaccount/service/impl/CostShareParamServiceImpl.java
  21. 59 1
      src/main/java/com/imed/costaccount/service/impl/ResponsibilityServiceImpl.java
  22. 13 0
      src/main/java/com/imed/costaccount/service/impl/ShareParamValueServiceImpl.java
  23. 6 2
      src/main/java/com/imed/costaccount/web/CostCostingCollectionController.java
  24. 7 2
      src/main/java/com/imed/costaccount/web/CostCostingGroupController.java
  25. 28 0
      src/main/resources/mapper/AllocationMapper.xml
  26. 8 5
      src/main/resources/mapper/CostCostingCollectionMapper.xml
  27. 15 0
      src/main/resources/mapper/ShareParamValueMapper.xml

+ 17 - 14
src/main/java/com/imed/costaccount/common/util/JacksonUtil.java

@@ -98,13 +98,13 @@ public class JacksonUtil {
 
     /**
      * 字符串转List等集合类型使用
-     *   样例:
-     *      *  JacksonUtil.string2ObjList(str,new TypeReference<List<User>>{})
-     * @param str 字符串
+     * 样例:
+     * *  JacksonUtil.string2ObjList(str,new TypeReference<List<User>>{})
+     *
+     * @param str           字符串
      * @param typeReference 泛型包装
-     * @param <T> 泛型
+     * @param <T>           泛型
      * @return T
-     *
      */
     public static <T> T str2ObjList(String str, TypeReference<T> typeReference) {
         if (StrUtil.isBlank(str) || Objects.isNull(typeReference)) {
@@ -120,13 +120,14 @@ public class JacksonUtil {
     }
 
     /**
-     *  字符串转List等集合类型使用
-     *         样例:
-     *              JacksonUtil.string2ObjList(str,List.class,User.class)
-     * @param str json字符串
+     * 字符串转List等集合类型使用
+     * 样例:
+     * JacksonUtil.string2ObjList(str,List.class,User.class)
+     *
+     * @param str             json字符串
      * @param collectionClazz 集合class对象
-     * @param elementClazzs 元素class对象
-     * @param <T> 返回的类型
+     * @param elementClazzs   元素class对象
+     * @param <T>             返回的类型
      * @return T
      */
     public static <T> T str2ObjList(String str, Class<?> collectionClazz, Class<?>... elementClazzs) {
@@ -141,7 +142,8 @@ public class JacksonUtil {
 
     /**
      * json字符串转为泛型 Map<String,Object>
-     *     可根据类型自己创建不同的泛型Map
+     * 可根据类型自己创建不同的泛型Map
+     *
      * @param str json字符串
      * @return
      */
@@ -157,6 +159,7 @@ public class JacksonUtil {
 
     /**
      * 构建json字符串
+     *
      * @return json Str
      */
     public static JacksonUtil.JsonBuilder builder() {
@@ -164,11 +167,11 @@ public class JacksonUtil {
     }
 
 
-
     public static class JsonBuilder {
         private Map<String, Object> map = new HashMap<>();
 
-        JsonBuilder(){}
+        JsonBuilder() {
+        }
 
         public JacksonUtil.JsonBuilder put(String key, Object value) {
             map.put(key, value);

+ 16 - 0
src/main/java/com/imed/costaccount/mapper/AllocationMapper.java

@@ -0,0 +1,16 @@
+package com.imed.costaccount.mapper;
+
+import com.imed.costaccount.model.Allocation;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 成本分摊后表
+ * 
+ * @author huangrui
+ * @date 2021-08-24 16:05:16
+ */
+@Mapper
+public interface AllocationMapper extends BaseMapper<Allocation> {
+	
+}

+ 2 - 0
src/main/java/com/imed/costaccount/mapper/ShareParamValueMapper.java

@@ -43,4 +43,6 @@ public interface ShareParamValueMapper extends BaseMapper<ShareParamValue> {
      * @return List
      */
     int getValuesCount(@Param("current") Integer current, @Param("pageSize") Integer pageSize, @Param("date") String date, @Param("shareParamCode") String shareParamCode, @Param("responsibilityCode") String responsibilityCode, @Param("hospId") Long hospId);
+
+    List<ShareParamValue> getListByYearAndMonth(@Param("year") Integer year, @Param("month") Integer month, @Param("hospId") Long hospId);
 }

+ 90 - 0
src/main/java/com/imed/costaccount/model/Allocation.java

@@ -0,0 +1,90 @@
+package com.imed.costaccount.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 成本分摊后表
+ * 
+ * @author huangrui
+ * @email 
+ * @date 2021-08-24 16:05:16
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("cost_allocation")
+public class Allocation implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 
+	 */
+	@TableId
+	private Long id;
+	/**
+	 * 年
+	 */
+	private Integer dateYear;
+	/**
+	 * 月
+	 */
+	private Integer dateMonth;
+	/**
+	 * 分摊层级序号
+	 */
+	private Integer levelSort;
+	/**
+	 * 分摊层级数名称
+	 */
+	private String levelName;
+	/**
+	 * 医院id
+	 */
+	private Long hospId;
+	/**
+	 * 责任中心代码
+	 */
+	private String responsibilityCode;
+	/**
+	 * 责任中心名称
+	 */
+	private String responsibilityName;
+
+	private Long accountShareId;
+
+	/**
+	 * 分摊得到的钱
+	 */
+	private BigDecimal amount;
+	/**
+	 * 是否固定成本 0.不是,1.是
+	 */
+	private Integer isBaseCost;
+	/**
+	 * 
+	 */
+	private Long createTime;
+
+	private String targetResponsibilityCode;
+	private String targetResponsibilityName;
+	private String shareParamCode;
+	private String shareParamName;
+	/**
+	 * 
+	 */
+	@TableLogic(value = "0",delval = "UNIX_TIMESTAMP(NOW()) * 1000")
+	private Long deleteTime;
+
+}

+ 34 - 16
src/main/java/com/imed/costaccount/model/CostCostingCollection.java

@@ -39,14 +39,6 @@ public class CostCostingCollection implements Serializable {
 	 * 月份
 	 */
 	private Integer month;
-	/**
-	 * 科室代码
-	 */
-	private String departmentCode;
-	/**
-	 * 科室名称
-	 */
-	private String departmentName;
 	/**
 	 * 责任中心代码
 	 */
@@ -64,13 +56,13 @@ public class CostCostingCollection implements Serializable {
 	 */
 	private String shareLevelName;
 	/**
-	 * 成本项目代码
+	 * 会计科目代码
 	 */
-	private String productCode;
+	private String accountCode;
 	/**
-	 * 成本项目名称
+	 * 会计科目名称
 	 */
-	private String productName;
+	private String accountName;
 	/**
 	 * 是否固定成本 0.不是,1.是
 	 */
@@ -79,10 +71,6 @@ public class CostCostingCollection implements Serializable {
 	 * 金额
 	 */
 	private BigDecimal amount;
-	/**
-	 * 导入的文件id
-	 */
-	private Long fileId;
 	/**
 	 * 创建时间
 	 */
@@ -97,4 +85,34 @@ public class CostCostingCollection implements Serializable {
 	 */
 	private Long hospId;
 
+	/**
+	 * 分摊比例
+	 */
+	private String shareParamProportion;
+
+	/**
+	 * 分摊参数名称
+	 */
+	private String shareParam;
+
+	/**
+	 * 分摊参数数值
+	 */
+	private BigDecimal shareValue;
+
+//	/**
+//	 * 目标层级责任中心代码
+//	 */
+//	private String targetResponsibilityCode;
+//
+//	/**
+//	 * 目标层级责任中心名称
+//	 */
+//	private String targetResponsibilityName;
+
+	/**
+	 * 分摊的金额
+	 */
+	private BigDecimal shareAmount;
+
 }

+ 19 - 0
src/main/java/com/imed/costaccount/model/vo/AccountShareVO.java

@@ -0,0 +1,19 @@
+package com.imed.costaccount.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class AccountShareVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private String shareParamCode;
+
+    private String shareParamName;
+
+    private String shareParamPopout;
+
+}

+ 8 - 0
src/main/java/com/imed/costaccount/service/AccountingService.java

@@ -55,5 +55,13 @@ public interface AccountingService extends IService<Accounting> {
      * @param user
      */
     void deleteAccount(Long id, User user);
+
+    /**
+     * 通过code得到对应的会计科目对象 需要调用者自己判断空
+     *
+     * @param accountCode 会计科目代码
+     * @return {@link Accounting} 可能为空 需要调用者自行判断
+     */
+    Accounting getByCode(String accountCode,Long hospId);
 }
 

+ 25 - 0
src/main/java/com/imed/costaccount/service/AllocationService.java

@@ -0,0 +1,25 @@
+package com.imed.costaccount.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.imed.costaccount.model.dto.StartDTO;
+import com.imed.costaccount.model.Allocation;
+
+import java.util.Map;
+
+/**
+ * 成本分摊后表
+ *
+ * @author huangrui
+ * @email 
+ * @date 2021-08-24 16:05:16
+ */
+public interface AllocationService extends IService<Allocation> {
+
+    /**
+     * 分摊成本数据
+     * @param startDTO {@link StartDTO}
+     * @param hospId 医院id
+     */
+    void startAllocation(StartDTO startDTO, Long hospId);
+}
+

+ 8 - 0
src/main/java/com/imed/costaccount/service/CostAccountShareService.java

@@ -79,5 +79,13 @@ public interface CostAccountShareService extends IService<CostAccountShare> {
      * @return
      */
     List<Responsibility> getResponsibilityCalType(Long accountShareId, Long hospId);
+
+    /**
+     * 通过责任中心得到对应的成本分摊参数对应
+     * @param responsibilityCode 责任中心code
+     * @param hospId 医院id
+     * @return 成本分摊参数对应列表
+     */
+    List<CostAccountShare> getByResponsibility(String responsibilityCode, Long hospId);
 }
 

+ 9 - 0
src/main/java/com/imed/costaccount/service/CostCostingGroupService.java

@@ -58,5 +58,14 @@ public interface CostCostingGroupService extends IService<CostCostingGroup> {
      * @param hospId 医院id
      */
     void startAllocation(StartDTO startDTO, Long hospId);
+
+    /**
+     * 得到这个月的所有导入的成本数据
+     * @param year 年
+     * @param month 月
+     * @param hospId 医院id
+     * @return List
+     */
+    List<CostCostingGroup> getByYearAndDate(Integer year, Integer month, Long hospId);
 }
 

+ 9 - 0
src/main/java/com/imed/costaccount/service/CostShareLevelService.java

@@ -7,6 +7,7 @@ import com.imed.costaccount.model.dto.CostShareLevelEditDto;
 import com.imed.costaccount.model.dto.CostShareLevelSaveDto;
 import com.imed.costaccount.model.vo.CostShareLevelVO;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -45,5 +46,13 @@ public interface CostShareLevelService extends IService<CostShareLevel> {
      * @return
      */
     List<CostShareLevelVO> getAll(Long hospId);
+
+    /**
+     * 通过分摊层级序号得到分摊层级列表
+     * @param targetLevelList
+     * @param hospId
+     * @return
+     */
+    List<CostShareLevel> getListByLevelSort(ArrayList<String> targetLevelList, Long hospId);
 }
 

+ 15 - 0
src/main/java/com/imed/costaccount/service/CostShareParamService.java

@@ -62,5 +62,20 @@ public interface CostShareParamService extends IService<CostShareParam> {
     CostShareParamVO getByHospIdAndAPramId(Integer id, Long hospId);
 
     List<Long> selectIsSelect(Integer shareParamId);
+
+    /**
+     * 通过计算方式和id获取是否存在会计科目的成本分摊参数
+     * @param shareParamId 主键id
+     * @return CostShareParam
+     */
+    CostShareParam getByIdAndCalcType(Long shareParamId);
+
+    /**
+     * 通过code得到name
+     * @param shareParamCode
+     * @param hospId
+     * @return
+     */
+    String getByCode(String shareParamCode, Long hospId);
 }
 

+ 24 - 0
src/main/java/com/imed/costaccount/service/ResponsibilityService.java

@@ -76,5 +76,29 @@ public interface ResponsibilityService extends IService<Responsibility> {
      * @return
      */
     List<CostResponsibilityVO> responsibilityList(User user);
+
+    /**
+     * 通过分摊级别id列表得到所有的责任中心
+     * @param levelId 分摊级别id
+     * @param hospId 医院id
+     * @return 责任中心
+     */
+    List<Responsibility> getByLevelIds(List<Long> levelId, Long hospId);
+
+    /**
+     * 通过分摊层级列表得到对应的责任中心
+     * @param levelId 分摊层级id
+     * @param hospId 医院id
+     * @return 责任中心 可能存在null
+     */
+    List<Responsibility> getByLevelId(Long levelId, Long hospId);
+
+    /**
+     * 通过code得到名字
+     * @param valueResponsibilityCode
+     * @param hospId
+     * @return
+     */
+    String getByCode(String valueResponsibilityCode, Long hospId);
 }
 

+ 9 - 0
src/main/java/com/imed/costaccount/service/ShareParamValueService.java

@@ -74,5 +74,14 @@ public interface ShareParamValueService extends IService<ShareParamValue> {
      * @param hospId 医院id
      */
     void calcData(String date, Long hospId);
+
+    /**
+     * 得到这个月导入的成本分摊参数值列表 ,聚合过
+     * @param year 年
+     * @param month 月
+     * @param hospId 医院id
+     * @return 某月成本分摊参数值
+     */
+    List<ShareParamValue> getListByYearAndMonth(Integer year, Integer month, Long hospId);
 }
 

+ 23 - 0
src/main/java/com/imed/costaccount/service/impl/AccountingServiceImpl.java

@@ -1,6 +1,7 @@
 package com.imed.costaccount.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -23,6 +24,8 @@ import org.springframework.transaction.annotation.Transactional;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.imed.costaccount.common.constants.Constant.LIMIT;
+
 @Slf4j
 @Service("accountingService")
 public class AccountingServiceImpl extends ServiceImpl<AccountingMapper, Accounting> implements AccountingService {
@@ -337,4 +340,24 @@ public class AccountingServiceImpl extends ServiceImpl<AccountingMapper, Account
         collect.add(id);
         this.removeByIds(collect);
     }
+
+    /**
+     * 通过code得到对应的会计科目对象 需要调用者自己判断空
+     *
+     * @param accountCode 会计科目代码
+     * @return {@link Accounting} 可能为空 需要调用者自行判断
+     */
+    @Override
+    public Accounting getByCode(String accountCode,Long hospId) {
+        if (StrUtil.isEmpty(accountCode)) {
+            throw new CostException("参数异常,accountCode 不能为空");
+        }
+        Accounting one = this.getOne(
+                new LambdaQueryWrapper<Accounting>()
+                        .eq(Accounting::getAccountingCode, accountCode)
+                        .eq(Accounting::getHospId, hospId)
+                        .last(LIMIT)
+        );
+        return one;
+    }
 }

+ 282 - 0
src/main/java/com/imed/costaccount/service/impl/AllocationServiceImpl.java

@@ -0,0 +1,282 @@
+package com.imed.costaccount.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.imed.costaccount.common.exception.CostException;
+import com.imed.costaccount.common.util.JacksonUtil;
+import com.imed.costaccount.mapper.AllocationMapper;
+import com.imed.costaccount.model.*;
+import com.imed.costaccount.model.dto.StartDTO;
+import com.imed.costaccount.model.vo.AccountShareVO;
+import com.imed.costaccount.model.vo.CostShareLevelVO;
+import com.imed.costaccount.service.*;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+
+@Service("allocationService")
+public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocation> implements AllocationService {
+
+    private final CostCostingGroupService costCostingGroupService;
+    private final CostShareLevelService shareLevelService;
+    private final ResponsibilityService responsibilityService;
+    private final CostAccountShareService accountShareService;
+    private final ShareParamValueService shareParamValueService;
+    private final CostShareParamService shareParamService;
+
+    public AllocationServiceImpl(CostCostingGroupService costCostingGroupService,
+                                 CostShareLevelService shareLevelService, ResponsibilityService responsibilityService, CostAccountShareService accountShareService, ShareParamValueService shareParamValueService, CostShareParamService shareParamService) {
+        this.costCostingGroupService = costCostingGroupService;
+        this.shareLevelService = shareLevelService;
+        this.responsibilityService = responsibilityService;
+        this.accountShareService = accountShareService;
+        this.shareParamValueService = shareParamValueService;
+        this.shareParamService = shareParamService;
+    }
+
+    /**
+     * 分摊成本数据
+     *
+     * @param startDTO {@link StartDTO}
+     * @param hospId   医院id
+     */
+    @Override
+    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
+    public void startAllocation(StartDTO startDTO, Long hospId) {
+        // 得到这个月的所有导入的成本数据
+        List<CostCostingGroup> costingGroups = costCostingGroupService.getByYearAndDate(startDTO.getYear(), startDTO.getMonth(), hospId);
+        // 没有重新导入
+        if (costingGroups.isEmpty()) {
+            throw new CostException("本月分摊参数值数据未导入");
+        }
+        Map<String, List<CostCostingGroup>> responsibilityCodeMap = costingGroups.stream().collect(Collectors.groupingBy(CostCostingGroup::getResponsibilityCode));
+        // 得到这个月导入的成本分摊参数值列表
+        List<ShareParamValue> shareParamValues = shareParamValueService.getListByYearAndMonth(startDTO.getYear(), startDTO.getMonth(), hospId);
+        if (shareParamValues.isEmpty()) {
+            throw new CostException("本月成本分摊参数值未导入");
+        }
+        Map<String, List<ShareParamValue>> paramValueRespCodeMap = shareParamValues.stream().collect(Collectors.groupingBy(ShareParamValue::getResponsibilityCode));
+        // 删除该年月已经分摊过的数据
+        this.remove(
+                new LambdaQueryWrapper<Allocation>()
+                        .eq(Allocation::getDateYear, startDTO.getYear())
+                        .eq(Allocation::getDateMonth, startDTO.getMonth())
+                        .eq(Allocation::getHospId, hospId)
+        );
+        // 得到这个医院所有的分摊层级列表排序
+        List<CostShareLevelVO> shareLevelVOs = shareLevelService.getAll(hospId);
+        if (CollUtil.isEmpty(shareLevelVOs)) {
+            throw new CostException("请先设置医院分摊层级");
+        }
+        List<Allocation> allocations = new LinkedList<>();
+        // key  责任中心代码, value 分摊过来的钱
+//        Map<String, BigDecimal> costMap = new ConcurrentReaderHashMap();
+        List<Allocation> costList = new ArrayList();
+        for (CostShareLevelVO shareLevelVO : shareLevelVOs) {
+            // 分摊层级id
+            Long levelId = shareLevelVO.getId();
+            // 目标分摊层级,可能不存在
+            String targetLevel = shareLevelVO.getTargetLevel();
+            if (StrUtil.isBlank(targetLevel)) {
+                throw new CostException("未设置目标层级");
+            }
+            // 计算方式 0是合并计算  1是分开计算
+            Integer calcType = shareLevelVO.getCalcType();
+            // 得到该分摊层级下责任中心列表,如果不存在,下一个
+            List<Responsibility> responsibilities = responsibilityService.getByLevelId(levelId, hospId);
+            if (responsibilities.isEmpty()) {
+                continue;
+            }
+            // 遍历责任中心得到对应的分摊参数对应
+            for (Responsibility responsibility : responsibilities) {
+                String responsibilityCode = responsibility.getResponsibilityCode();
+                // 得到分摊参数对应记录,不存在,下一个
+                if (responsibilityCode.equals("123")) {
+                    System.out.println(1);
+                }
+                List<CostAccountShare> accountShares = accountShareService.getByResponsibility(responsibilityCode, hospId);
+                if (accountShares.isEmpty()) {
+                    continue;
+                }
+                // 遍历分摊参数对应记录
+                for (CostAccountShare accountShare : accountShares) {
+                    Long accountShareId = accountShare.getId();
+                    String paramList = accountShare.getParamList();
+                    List<AccountShareVO> accountShareVOs = JacksonUtil.str2ObjList(paramList, List.class, AccountShareVO.class);
+                    // 如果分摊比例未设置直接报错
+                    if (StrUtil.isBlank(paramList)) {
+                        throw new CostException("责任中心:" + accountShare.getResponsibilityName() + ";会计中心为:" + accountShare.getAccountingNames() + ";未设置分摊参数比例");
+                    }
+
+                    List<CostCostingGroup> groups = responsibilityCodeMap.get(responsibilityCode);
+                    if (CollUtil.isEmpty(groups)) {
+                        continue;
+                    }
+                    // 计算本次分摊的钱
+
+                    BigDecimal totalAmount = this.getCostAmount(accountShare, calcType, responsibilityCodeMap, costList);
+                    if (totalAmount.equals(BigDecimal.ZERO)) {
+                        continue;
+                    }
+                    // 相关的分摊参数比例
+                    for (AccountShareVO accountShareVO : accountShareVOs) {
+                        String paramCode = accountShareVO.getShareParamCode();
+                        String shareParamPopout = accountShareVO.getShareParamPopout();
+                        BigDecimal rate = new BigDecimal("1");
+                        if (!"100".equals(shareParamPopout)) {
+                            rate = new BigDecimal("0." + shareParamPopout);
+                        }
+                        // 本次的分摊比例计算
+                        BigDecimal thisAmount = rate.multiply(totalAmount);
+
+//                        Allocation allocation = new Allocation();
+//                        allocation.setDateMonth(startDTO.getMonth()).setDateYear(startDTO.getYear()).setLevelSort(shareLevelVO.getLeverSort())
+//                                .setLevelName(shareLevelVO.getShareName()).setHospId(hospId).setResponsibilityCode(responsibilityCode).setResponsibilityName(responsibility.getResponsibilityName())
+//                                .setAccountShareId(accountShareId).setAmount(thisAmount).setCreateTime(System.currentTimeMillis());
+//                        allocations.add(allocation);
+
+                        // 得到目标层级责任中心列表
+                        List<Responsibility> targetResponsibilities = this.getTargetResponsibility(targetLevel, hospId, shareLevelVO.getLeverSort());
+                        if (targetResponsibilities.isEmpty()) {
+                            throw new CostException("找不到目标责任中心");
+                        }
+
+                        // 目标责任中心得到对应
+                        List<ShareParamValue> targetShareParmValue = getTarget(targetResponsibilities, accountShareVO, paramValueRespCodeMap);
+                        if (CollUtil.isEmpty(targetResponsibilities)) {
+                            throw new CostException("找不到目标责任中心对应的分摊参数值");
+                        }
+                        // 分母
+                        BigDecimal reduce = targetShareParmValue.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
+                        for (ShareParamValue paramValue : targetShareParmValue) {
+                            // 分子
+                            BigDecimal numerator = paramValue.getValueNum();
+                            BigDecimal targetAmount = thisAmount.multiply(numerator).divide(reduce, 4);
+                            Allocation targetAllocation = new Allocation();
+                            String valueResponsibilityCode = paramValue.getResponsibilityCode();
+                            String targetRespName = responsibilityService.getByCode(valueResponsibilityCode, hospId);
+                            String shareParamName = shareParamService.getByCode(paramValue.getShareParamCode(), hospId);
+                            targetAllocation.setDateMonth(startDTO.getMonth()).setDateYear(startDTO.getYear()).setLevelSort(shareLevelVO.getLeverSort())
+                                    .setLevelName(shareLevelVO.getShareName()).setHospId(hospId).setResponsibilityCode(responsibility.getResponsibilityCode())
+                                    .setResponsibilityName(responsibility.getResponsibilityName()).setAccountShareId(accountShareId).setAmount(targetAmount)
+                                    .setCreateTime(System.currentTimeMillis()).setTargetResponsibilityCode(valueResponsibilityCode).setTargetResponsibilityName(targetRespName)
+                                    .setShareParamCode(paramValue.getShareParamCode()).setShareParamName(shareParamName)
+                            ;
+                            // todo 目标分摊层级责任中心 就是当前列个表中的责任中心
+                            allocations.add(targetAllocation);
+                            costList.add(targetAllocation);
+                        }
+
+
+                    }
+                }
+            }
+        }
+        this.saveBatch(allocations);
+    }
+
+    /**
+     * 得到目标月成本分摊参数值数据
+     *
+     * @param targetResponsibilities
+     * @param map
+     * @return
+     */
+    private List<ShareParamValue> getTarget(List<Responsibility> targetResponsibilities, AccountShareVO accountShareVO, Map<String, List<ShareParamValue>> map) {
+        // 目标的责任中心
+        List<ShareParamValue> shareParamValues = map.entrySet().stream().map(Map.Entry::getValue).flatMap(Collection::stream).collect(Collectors.toList());
+        List<String> originRespCodes = targetResponsibilities.stream().map(Responsibility::getResponsibilityCode).collect(Collectors.toList());
+        return shareParamValues.stream().filter(j -> originRespCodes.contains(j.getResponsibilityCode()))
+                .filter(i -> i.getShareParamCode().equals(accountShareVO.getShareParamCode())).collect(Collectors.toList());
+    }
+
+    /**
+     * 计算本次的成本金额
+     *
+     * @return
+     */
+    private BigDecimal getCostAmount(CostAccountShare accountShare, Integer calcType, Map<String, List<CostCostingGroup>> map,List<Allocation> costList) {
+        // 是否包含分摊成本 0不包含 1 包含
+        Integer isShareCost = accountShare.getIsShareCost();
+        String accountingCodes = accountShare.getAccountingCodes();
+        String responsibilityCode = accountShare.getResponsibilityCode();
+        List<CostCostingGroup> costingGroups = map.get(responsibilityCode);
+        if (CollUtil.isEmpty(costingGroups)) {
+            return BigDecimal.ZERO;
+        }
+        // 计算方式 0是合并计算  1是分开计算
+        BigDecimal costAmount = BigDecimal.ZERO;
+        List<Allocation> all=new ArrayList<>();
+        if (!costList.isEmpty()) {
+            all = costList.stream().filter(i -> i.getTargetResponsibilityCode().equals(responsibilityCode)).collect(Collectors.toList());
+//            Stream<Allocation> allocationStream = costList.stream().filter(i -> i.getTargetResponsibilityCode().equals(responsibilityCode));
+//            if (Objects.nonNull(allocationStream)) {
+//                all = allocationStream.collect(Collectors.toList());
+//            }
+        }
+        if (calcType == 0) {
+            costAmount = costingGroups.stream().map(CostCostingGroup::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+            if (!all.isEmpty()) {
+
+                BigDecimal bigDecimal = all.stream()
+                        .map(Allocation::getAmount)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                if (Objects.nonNull(bigDecimal)) {
+                    costAmount = costAmount.add(bigDecimal);
+                }
+            }
+
+        } else {
+            if (StrUtil.isBlank(accountingCodes)) {
+                return BigDecimal.ZERO;
+            }
+
+            ArrayList<String> accountCodes = CollUtil.newArrayList(accountingCodes.split(StrUtil.COMMA));
+            List<CostCostingGroup> costGroups = costingGroups.stream().filter(i -> accountCodes.contains(i.getAccountCode())).collect(Collectors.toList());
+            costAmount = costGroups.stream().map(CostCostingGroup::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+            if (isShareCost == 1) {
+                if (!all.isEmpty()) {
+                    BigDecimal bigDecimal = all.stream()
+                            .map(Allocation::getAmount)
+                            .reduce(BigDecimal.ZERO, BigDecimal::add);
+                    if (Objects.nonNull(bigDecimal)) {
+                        costAmount = costAmount.add(bigDecimal);
+                    }
+                }
+            }
+        }
+        return costAmount;
+    }
+
+
+    /**
+     * 通过目标层级获取目标责任中心
+     *
+     * @param targetLevel 目标层级 2,3,4
+     * @param leverSort
+     * @return List
+     */
+    private List<Responsibility> getTargetResponsibility(String targetLevel, Long hospId, Integer leverSort) {
+        ArrayList<String> targetLevelList = CollUtil.newArrayList(StrUtil.split(targetLevel, StrUtil.COMMA));
+        if (targetLevelList.size() == 1) {
+            if (leverSort.equals(Integer.parseInt(targetLevelList.get(0)))) {
+                return new ArrayList<>();
+            }
+        }
+        List<CostShareLevel> shareLevels = shareLevelService.getListByLevelSort(targetLevelList, hospId);
+        if (shareLevels.isEmpty()) {
+            throw new CostException("请重新设置分摊层级");
+        }
+        List<Long> shareLevelIds = shareLevels.stream().map(CostShareLevel::getId).collect(Collectors.toList());
+        return responsibilityService.getByLevelIds(shareLevelIds, hospId);
+    }
+}

+ 18 - 0
src/main/java/com/imed/costaccount/service/impl/CostAccountShareServiceImpl.java

@@ -1,6 +1,7 @@
 package com.imed.costaccount.service.impl;
 
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -45,6 +46,7 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
 
     private final CostShareParamService costShareParamService;
 
+
     public CostAccountShareServiceImpl(ResponsibilityService responsibilityService, AccountingService accountingService, CostShareLevelService costShareLevelService, CostShareParamService costShareParamService) {
         this.responsibilityService = responsibilityService;
         this.accountingService = accountingService;
@@ -416,4 +418,20 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
         return responsibilityList;
     }
 
+    /**
+     * 通过责任中心得到对应的成本分摊参数对应
+     *
+     * @param responsibilityCode 责任中心code
+     * @param hospId             医院id
+     * @return 成本分摊参数对应列表
+     */
+    @Override
+    public List<CostAccountShare> getByResponsibility(String responsibilityCode, Long hospId) {
+        List<CostAccountShare> list = this.list(
+                new LambdaQueryWrapper<CostAccountShare>()
+                        .eq(CostAccountShare::getResponsibilityCode, responsibilityCode)
+                        .eq(CostAccountShare::getHospId, hospId)
+        );
+        return list;
+    }
 }

+ 232 - 14
src/main/java/com/imed/costaccount/service/impl/CostCostingGroupServiceImpl.java

@@ -1,5 +1,6 @@
 package com.imed.costaccount.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
@@ -14,9 +15,7 @@ import com.imed.costaccount.enums.DateStyleEnum;
 import com.imed.costaccount.mapper.CostCostingGroupMapper;
 import com.imed.costaccount.model.*;
 import com.imed.costaccount.model.dto.StartDTO;
-import com.imed.costaccount.model.vo.AllocationVO;
-import com.imed.costaccount.model.vo.CostingGroupStartVO;
-import com.imed.costaccount.model.vo.IncomeErrorMessage;
+import com.imed.costaccount.model.vo.*;
 import com.imed.costaccount.service.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -27,6 +26,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.stream.Collectors;
 
 
 @Service("costCostingGroupService")
@@ -35,6 +35,8 @@ public class CostCostingGroupServiceImpl extends ServiceImpl<CostCostingGroupMap
 
     private final CostIncomeGroupServiceImpl costIncomeGroupService;
 
+    private final AccountingService accountingService;
+
     private final AccountingProductService accountingProductService;
 
     private final CostIncomeFileService costIncomeFileService;
@@ -43,16 +45,34 @@ public class CostCostingGroupServiceImpl extends ServiceImpl<CostCostingGroupMap
 
     private final CostCostingCollectionService costingCollectionService;
 
+    private final CostShareLevelService shareLevelService;
+
+    private final CostAccountShareService accountShareService;
+
+    private final ShareParamValueService shareParamValueService;
+
+    private final CostShareParamService shareParamService;
+
     public CostCostingGroupServiceImpl(CostIncomeGroupServiceImpl costIncomeGroupService,
+                                       AccountingService accountingService,
                                        AccountingProductService accountingProductService,
                                        CostIncomeFileService costIncomeFileService,
                                        ResponsibilityService responsibilityService,
-                                       CostCostingCollectionService costingCollectionService) {
+                                       CostCostingCollectionService costingCollectionService,
+                                       CostShareLevelService shareLevelService,
+                                       CostAccountShareService accountShareService,
+                                       ShareParamValueService shareParamValueService,
+                                       CostShareParamService shareParamService) {
         this.costIncomeGroupService = costIncomeGroupService;
+        this.accountingService = accountingService;
         this.accountingProductService = accountingProductService;
         this.costIncomeFileService = costIncomeFileService;
         this.responsibilityService = responsibilityService;
         this.costingCollectionService = costingCollectionService;
+        this.shareLevelService = shareLevelService;
+        this.accountShareService = accountShareService;
+        this.shareParamValueService = shareParamValueService;
+        this.shareParamService = shareParamService;
     }
 
     /**
@@ -131,24 +151,203 @@ public class CostCostingGroupServiceImpl extends ServiceImpl<CostCostingGroupMap
     @Override
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
     public void startAllocation(StartDTO startDTO, Long hospId) {
-        // 先拿到这个月数据 如果数据量很大 优化处理
+        // 这个月成本数据数据
         List<CostCostingGroup> list = this.list(
                 new LambdaQueryWrapper<CostCostingGroup>()
                         .eq(CostCostingGroup::getDateYear, startDTO.getYear())
                         .eq(CostCostingGroup::getDateMonth, startDTO.getMonth())
                         .eq(CostCostingGroup::getHospId, hospId)
         );
+        // 没有重新导入
+        if (list.isEmpty()) {
+            throw new CostException("本月成本数据暂未导入");
+        }
 
-        // 删除该年月已经过的数据
-        costingCollectionService.remove(
-                new LambdaQueryWrapper<CostCostingCollection>()
-                        .eq(CostCostingCollection::getYear, startDTO.getYear())
-                        .eq(CostCostingCollection::getMonth, startDTO.getMonth())
-                        .eq(CostCostingCollection::getHospId, hospId)
-        );
-        // 得到分摊层级为1 的
-//        list.stream().map(get)
+        Map<String, List<CostCostingGroup>> responsibilityCodeMap = list.stream().collect(Collectors.groupingBy(CostCostingGroup::getResponsibilityCode));
+        Set<String> responsibilityCodes = responsibilityCodeMap.keySet();
+        for (String responsibilityCode : responsibilityCodes) {
+
+        }
+
+
+//        // 得到这个月导入的成本分摊参数值数据
+//        List<ShareParamValue> shareParamValues = shareParamValueService.list(
+//                new LambdaQueryWrapper<ShareParamValue>()
+//                        .eq(ShareParamValue::getHospId, hospId)
+//                        .eq(ShareParamValue::getDateYear, startDTO.getYear())
+//                        .eq(ShareParamValue::getDateMonth, startDTO.getMonth())
+//        );
+//        // 没有重新导入
+//        if (shareParamValues.isEmpty()) {
+//            throw new CostException("本月分摊参数值数据未导入");
+//        }
+//        // 通过会计科目聚合月成本数据
+//        Map<String, List<CostCostingGroup>> accountMap = list.stream().collect(Collectors.groupingBy(CostCostingGroup::getAccountCode));
+//
+//        // 删除该年月已经过的数据
+//        costingCollectionService.remove(
+//                new LambdaQueryWrapper<CostCostingCollection>()
+//                        .eq(CostCostingCollection::getYear, startDTO.getYear())
+//                        .eq(CostCostingCollection::getMonth, startDTO.getMonth())
+//                        .eq(CostCostingCollection::getHospId, hospId)
+//        );
+//        // 得到这个医院所有的分摊层级(通过sort_level正序排序的数据)
+//        List<CostShareLevelVO> shareLevelVOs = shareLevelService.getAll(hospId);
+//        if (CollUtil.isEmpty(shareLevelVOs)) {
+//            throw new CostException("请先设置医院分摊层级");
+//        }
+//        List<CostCostingCollection> costingCollections = new ArrayList<>();
+//        // 遍历这个医院的分摊层级
+//        for (int i = 0; i < shareLevelVOs.size(); i++) {
+//            // 最后一层不分摊
+//            if (i == shareLevelVOs.size() - 1) {
+//                break;
+//            }
+//            // 通过分摊层级id 得到对应的责任中心
+//            CostShareLevelVO shareLevelVO = shareLevelVOs.get(i);
+//            Responsibility responsibility = responsibilityService.getByLevelId(shareLevelVO.getId(), hospId);
+//            // 如果这个分摊层级没有责任中心那么不分摊
+//            if (Objects.isNull(responsibility)) {
+//                continue;
+//            }
+//            // 通过责任中心code去得到分摊参数对应信息 并得到对应的会计科目和对应的分摊参数比例等信息
+//            List<CostAccountShare> accountShares = accountShareService.getByResponsibility(responsibility.getResponsibilityCode(), hospId);
+//            if (accountShares.isEmpty()) {
+//                continue;
+//            }
+//            // 遍历分摊参数对应信息
+//            for (CostAccountShare accountShare : accountShares) {
+//                // 得到对应的会计中心code
+//                String accountingCodes = accountShare.getAccountingCodes();
+//                // 没有会计中心,合并计算未设置好分摊参数比例
+//                if (StrUtil.isBlank(accountingCodes) && shareLevelVO.getCalcType().equals(1)) {
+//                    throw new CostException("责任中心:" + accountShare.getResponsibilityName() + ";会计中心为:" + accountShare.getAccountingNames() + ";未设置分摊参数比例");
+//                }
+//                // 会计科目不存在且是合并计算,这种情况直接分摊下去
+//                String paramList = accountShare.getParamList();
+//                if (StrUtil.isBlank(paramList)) {
+//                    throw new CostException("责任中心:" + accountShare.getResponsibilityName() + ";会计中心为:" + accountShare.getAccountingNames() + (";未设置分摊参数比例值"));
+//                }
+//                // 分摊参数以及比例集合
+//                List<AccountShareVO> accountShareVOs = JacksonUtil.str2ObjList(paramList, List.class, AccountShareVO.class);
+//                // 没有会计中心直接分摊的情况
+//                if (StrUtil.isBlank(accountingCodes) && shareLevelVO.getCalcType().equals(0)) {
+//                    // 直接分摊到责任中心去 这情况只有一个分摊计划
+//                    AccountShareVO accountShareVO = accountShareVOs.get(0);
+//                    Long shareParamId = accountShareVO.getId();
+//                    CostShareParam shareParam = shareParamService.getByIdAndCalcType(shareParamId);
+//                    if (Objects.isNull(shareParam)) {
+//                        continue;
+//                    }
+//                    String accountCodeStr = shareParam.getAccountingCodes();
+//                    if (StrUtil.isBlank(accountCodeStr)) {
+//                        throw new CostException("成本分摊参数:" + shareParam.getShareParamName() + ";设置会计科目不存在");
+//                    }
+//                    ArrayList<String> accountCodes = CollUtil.newArrayList(accountCodeStr.split(StrUtil.COMMA));
+//                    String shareParamPout = accountShareVO.getShareParamPopout();
+//                    BigDecimal rate = new BigDecimal("1");
+//                    if (!"100".equals(shareParamPout)) {
+//                        rate = new BigDecimal("0." + shareParamPout);
+//                    }
+//                    // 计算分摊数值
+//                    BigDecimal valueNum = shareParamValues.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
+//                    for (String accountCode : accountCodes) {
+//                        Accounting account = this.getAccountByCode(accountCode, hospId);
+//                        List<CostCostingGroup> costCostingGroups = accountMap.get(accountCode);
+//                        if (CollUtil.isEmpty(costCostingGroups)) {
+//                            continue;
+//                        }
+//                        BigDecimal accountCodeAmount = costCostingGroups.stream().map(CostCostingGroup::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+//                        CostCostingCollection collection = new CostCostingCollection();
+//                        collection.setYear(startDTO.getYear()).setMonth(startDTO.getMonth()).setResponsibilityCode(accountShare.getResponsibilityCode())
+//                                .setResponsibilityName(accountShare.getResponsibilityName()).setLeverSort(shareLevelVO.getLeverSort())
+//                                .setShareLevelName(shareLevelVO.getShareName()).setAccountCode(accountCode).setAccountName(account.getAccountingName())
+//                                .setIsBaseCost(account.getIsBaseCost()).setAmount(accountCodeAmount).setCreateTime(System.currentTimeMillis())
+//                                .setHospId(hospId).setShareParam(accountShareVO.getShareParamName()).setShareParamProportion(rate.toString())
+//                                .setShareValue(valueNum)
+//                                // 目标分摊层级暂不处理
+//                                //.setTargetResponsibilityCode().setTargetResponsibilityName()
+//                                .setShareAmount(rate.multiply(accountCodeAmount));
+//                        costingCollections.add(collection);
+//                    }
+//                    continue;
+//                }
+//                // 责任中心对应的会计科目代码列表
+//                ArrayList<String> accountCodeList = CollUtil.newArrayList(accountingCodes.split(StrUtil.COMMA));
+//                for (String accountCode : accountCodeList) {
+//                    // 分摊前数据 通过会计科目得到
+//                    List<CostCostingGroup> costCostingGroups = accountMap.get(accountCode);
+//
+//                    if (CollUtil.isEmpty(costCostingGroups)) {
+//                        continue;
+//                    }
+//                    BigDecimal accountCodeAmount = costCostingGroups.stream().map(CostCostingGroup::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+//                    Accounting accounting = this.getAccountByCode(accountCode, hospId);
+//                    if (StrUtil.isBlank(paramList)) {
+//                        throw new CostException("未设置分摊参数比例值");
+//                    }
+//                    // 分摊比例相关数据
+//                    if (CollUtil.isEmpty(accountShareVOs)) {
+//                        throw new CostException("分摊参数对应比例错误");
+//                    }
+//                    for (AccountShareVO accountShareVO : accountShareVOs) {
+//                        CostCostingCollection collection = new CostCostingCollection();
+//                        String shareParamPout = accountShareVO.getShareParamPopout();
+//                        BigDecimal rate = new BigDecimal("1");
+//                        if (!"100".equals(shareParamPout)) {
+//                            rate = new BigDecimal("0." + shareParamPout);
+//                        }
+//                        // 计算分摊数值
+//                        BigDecimal valueNum = shareParamValues.stream().map(ShareParamValue::getValueNum).reduce(BigDecimal.ZERO, BigDecimal::add);
+//                        collection.setYear(startDTO.getYear()).setMonth(startDTO.getMonth()).setResponsibilityCode(accountShare.getResponsibilityCode())
+//                                .setResponsibilityName(accountShare.getResponsibilityName()).setLeverSort(shareLevelVO.getLeverSort())
+//                                .setShareLevelName(shareLevelVO.getShareName()).setAccountCode(accountCode).setAccountName(accounting.getAccountingName())
+//                                .setIsBaseCost(accounting.getIsBaseCost()).setAmount(accountCodeAmount).setCreateTime(System.currentTimeMillis())
+//                                .setHospId(hospId).setShareParam(accountShareVO.getShareParamName()).setShareParamProportion(rate.toString())
+//                                .setShareValue(valueNum)
+//                                // 目标分摊层级暂不处理
+//                                //.setTargetResponsibilityCode().setTargetResponsibilityName()
+//                                .setShareAmount(rate.multiply(accountCodeAmount));
+//                        costingCollections.add(collection);
+////                        costingCollectionService.save(collection);
+//                    }
+//
+//                }
+//            }
+//        }
+//        log.info("list:{}", costingCollections);
+//        costingCollectionService.saveBatch(costingCollections);
+    }
+
+    /**
+     * 通过code获取名称
+     *
+     * @param accountCode
+     * @return
+     */
+    private Accounting getAccountByCode(String accountCode, Long hospId) {
+        Accounting byCode = accountingService.getByCode(accountCode, hospId);
+        if (Objects.isNull(byCode)) {
+            throw new CostException("会计科目不存在");
+        }
+        return byCode;
+    }
 
+    /**
+     * 是否固定成本
+     *
+     * @param hospId 医院id
+     * @param i      {@link CostCostingGroup}
+     * @return 是否固定成本 0.不是,1.是(支出的时候才会存在)
+     */
+    private Integer getIsBaseCost(Long hospId, CostCostingGroup i) {
+        String accountCode = i.getAccountCode();
+        Accounting accounting = accountingService.getByCode(accountCode, hospId);
+        if (Objects.isNull(accountCode)) {
+            return null;
+        }
+        // 是否固定成本 0.不是,1.是(支出的时候才会存在) (成本数据)
+        return accounting.getIsBaseCost();
     }
 
     /**
@@ -426,4 +625,23 @@ public class CostCostingGroupServiceImpl extends ServiceImpl<CostCostingGroupMap
             }
         }
     }
+
+
+    /**
+     * 得到这个月的所有导入的成本数据
+     *
+     * @param year   年
+     * @param month  月
+     * @param hospId 医院id
+     * @return List
+     */
+    @Override
+    public List<CostCostingGroup> getByYearAndDate(Integer year, Integer month, Long hospId) {
+        return this.list(
+                new LambdaQueryWrapper<CostCostingGroup>()
+                        .eq(CostCostingGroup::getDateYear, year)
+                        .eq(CostCostingGroup::getDateMonth, month)
+                        .eq(CostCostingGroup::getHospId, hospId)
+        );
+    }
 }

+ 19 - 1
src/main/java/com/imed/costaccount/service/impl/CostShareLevelServiceImpl.java

@@ -1,6 +1,7 @@
 package com.imed.costaccount.service.impl;
 
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -20,6 +21,7 @@ import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -128,9 +130,25 @@ public class CostShareLevelServiceImpl extends ServiceImpl<CostShareLevelMapper,
     @Override
     public List<CostShareLevelVO> getAll(Long hospId) {
         QueryWrapper<CostShareLevel> wrapper = new QueryWrapper<>();
-        wrapper.eq(!StringUtils.isEmpty(hospId),"hosp_id",hospId);
+        wrapper.eq(!StringUtils.isEmpty(hospId), "hosp_id", hospId).orderByAsc("lever_sort");
         List<CostShareLevel> costShareLevels = baseMapper.selectList(wrapper);
         List<CostShareLevelVO> costShareLevelVOList = BeanUtil.convertList(costShareLevels, CostShareLevelVO.class);
         return costShareLevelVOList;
     }
+
+    /**
+     * 通过分摊层级序号得到分摊层级列表
+     *
+     * @param targetLevelList 分摊层级序号列表
+     * @param hospId 医院id
+     * @return CostShareLevel List
+     */
+    @Override
+    public List<CostShareLevel> getListByLevelSort(ArrayList<String> targetLevelList, Long hospId) {
+        return this.list(
+                new LambdaQueryWrapper<CostShareLevel>()
+                        .in(CostShareLevel::getLeverSort, targetLevelList)
+                        .eq(CostShareLevel::getHospId, hospId)
+        );
+    }
 }

+ 59 - 25
src/main/java/com/imed/costaccount/service/impl/CostShareParamServiceImpl.java

@@ -2,6 +2,7 @@ package com.imed.costaccount.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -29,6 +30,8 @@ import org.springframework.util.StringUtils;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.imed.costaccount.common.constants.Constant.LIMIT;
+
 
 @Service("costShareParamService")
 public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper, CostShareParam> implements CostShareParamService {
@@ -48,20 +51,19 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
      * @return
      */
     @Override
-    public PageUtils queryList(Integer current, Integer pageSize, String name,Long hospId) {
+    public PageUtils queryList(Integer current, Integer pageSize, String name, Long hospId) {
         Page<CostShareParam> costShareParamPage = new Page<>(current, pageSize);
         Page<CostShareParam> pages = this.page(costShareParamPage, new QueryWrapper<CostShareParam>().lambda()
                 .eq(!StringUtils.isEmpty(hospId), CostShareParam::getHospId, hospId)
-                .like(!StringUtils.isEmpty(name), CostShareParam::getShareParamName, name).orderByDesc(CostShareParam::getCreateTime))
-                ;
+                .like(!StringUtils.isEmpty(name), CostShareParam::getShareParamName, name).orderByDesc(CostShareParam::getCreateTime));
         List<CostShareParam> records = pages.getRecords();
         List<CostShareParamVO> costShareParamVOList = BeanUtil.convertList(records, CostShareParamVO.class);
         // 封装会计科目Id的集合
-        costShareParamVOList.forEach(i->{
+        costShareParamVOList.forEach(i -> {
             String accountingId = i.getAccountingId();
-            if (StrUtil.isNotBlank(accountingId)){
+            if (StrUtil.isNotBlank(accountingId)) {
                 i.setAccountingIds(Arrays.asList(accountingId.split(StrUtil.COMMA)));
-            }else {
+            } else {
                 i.setAccountingIds(null);
             }
         });
@@ -73,10 +75,11 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
     /**
      * 保存分摊参数
      * 保存的时候需要校验分摊参数
+     *
      * @param costShareParamSaveDto
      */
     @Override
-    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public void addCostShareParam(CostShareParamSaveDto costShareParamSaveDto) {
         //检验分摊参数是存在
         getCostShareParamByCode(costShareParamSaveDto);
@@ -84,6 +87,7 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
         costShareParam.setCreateTime(System.currentTimeMillis());
         baseMapper.insert(costShareParam);
     }
+
     /**
      * 检验分摊参数是存在
      */
@@ -91,10 +95,10 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
         List<CostShareParam> costShareParamList = baseMapper.selectList(new QueryWrapper<CostShareParam>().lambda()
                 .eq(CostShareParam::getHospId, costShareParamSaveDto.getHospId()));
         // 检验添加的分摊参数是否存在
-        if (!CollectionUtils.isEmpty(costShareParamList)){
+        if (!CollectionUtils.isEmpty(costShareParamList)) {
             Map<String, List<CostShareParam>> costShareMap = costShareParamList.stream().collect(Collectors.groupingBy(CostShareParam::getShareParamCode));
-            if (!CollectionUtils.isEmpty(costShareMap.get(costShareParamSaveDto.getShareParamCode()))){
-                throw new CostException(500,"分摊参数已存在");
+            if (!CollectionUtils.isEmpty(costShareMap.get(costShareParamSaveDto.getShareParamCode()))) {
+                throw new CostException(500, "分摊参数已存在");
             }
         }
     }
@@ -105,24 +109,24 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
      * @param costShareParamEditDto
      */
     @Override
-    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public void updateCostShareParam(CostShareParamEditDto costShareParamEditDto) {
         Long id = costShareParamEditDto.getId();
         CostShareParam costShareParam = baseMapper.selectById(id);
-        if (Objects.isNull(costShareParam)){
-            throw new CostException(500,"对不起分摊参数不存在");
+        if (Objects.isNull(costShareParam)) {
+            throw new CostException(500, "对不起分摊参数不存在");
         }
         baseMapper.deleteById(id);
         // 判断当前输入的Code以最初的Code是否一样
         List<CostShareParam> costShareParamList = baseMapper.selectList(new QueryWrapper<CostShareParam>().lambda().select(CostShareParam::getShareParamCode).eq(CostShareParam::getHospId, costShareParamEditDto.getHospId()));
         Map<String, List<CostShareParam>> map = costShareParamList.stream().collect(Collectors.groupingBy(CostShareParam::getShareParamCode));
-        if (!CollectionUtils.isEmpty(map.get(costShareParamEditDto.getShareParamCode()))){
-            throw new CostException(500,"对不起分摊参数代码已存在");
+        if (!CollectionUtils.isEmpty(map.get(costShareParamEditDto.getShareParamCode()))) {
+            throw new CostException(500, "对不起分摊参数代码已存在");
         }
         CostShareParam costShareParamRequest = BeanUtil.convertObj(costShareParamEditDto, CostShareParam.class);
         costShareParamRequest.setId(null);
         costShareParamRequest.setCreateTime(System.currentTimeMillis());
-        if (NumberConstant.ONE.equals( costShareParamEditDto.getShareParamCode()) && NumberConstant.ONE.equals(costShareParamEditDto.getShareParamCode())){
+        if (NumberConstant.ONE.equals(costShareParamEditDto.getShareParamCode()) && NumberConstant.ONE.equals(costShareParamEditDto.getShareParamCode())) {
             costShareParamRequest.setAccountingId(costShareParam.getAccountingId());
         }
         baseMapper.insert(costShareParamRequest);
@@ -135,7 +139,7 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
      * @return
      */
     @Override
-    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public CostShareParam updateCostShareParamByAccountId(CostShareParamAccountDto costShareParamAccountDto) {
         Long hospId = UserContext.getHospId();
         Long costShareParamId = costShareParamAccountDto.getCostShareParamId();
@@ -143,23 +147,23 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
         List<String> accoutingCodes = new LinkedList<>();
         Map<Long, String> accountingMap = accountingMapper.selectList(new QueryWrapper<Accounting>().lambda().eq(Accounting::getHospId, hospId)).stream().collect(Collectors.toMap(Accounting::getId, Accounting::getAccountingCode));
         //  判断当前操作的分层参数的计算方式是不是按科目计算
-        if (NumberConstant.TWO.equals(costShareParam.getCalcType())){
+        if (NumberConstant.TWO.equals(costShareParam.getCalcType())) {
             String[] accountIds = costShareParamAccountDto.getAccountIds();
             List<String> accountList = Arrays.asList(accountIds);
-            if (!CollectionUtil.isEmpty(accountList)){
+            if (!CollectionUtil.isEmpty(accountList)) {
                 String accountingIds = accountList.stream().map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA));
                 costShareParam.setAccountingId(accountingIds);
-                accountList.forEach(i->{
+                accountList.forEach(i -> {
                     String accountCode = accountingMap.get(Long.parseLong(i));
                     accoutingCodes.add(accountCode);
                 });
                 costShareParam.setAccountingCodes(accoutingCodes.stream().map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA)));
-            }else {
+            } else {
                 costShareParam.setAccountingId(null);
             }
             baseMapper.updateById(costShareParam);
-        }else {
-            throw new CostException(500,"计算方式不是按会计科目计算");
+        } else {
+            throw new CostException(500, "计算方式不是按会计科目计算");
         }
         return null;
     }
@@ -202,16 +206,46 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
             return Collections.emptyList();
         }
         String accountingId = byId.getAccountingId();
-        if (!StringUtils.isEmpty(accountingId)){
+        if (!StringUtils.isEmpty(accountingId)) {
             String[] split = accountingId.split(StrUtil.COMMA);
             List<Long> accountingIdList = Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList());
             return accountingIdList;
-        }else {
+        } else {
             return Collections.emptyList();
         }
 
 
     }
 
+    /**
+     * 通过计算方式和id获取是否存在会计科目的成本分摊参数
+     *
+     * @param shareParamId 主键id
+     * @return CostShareParam
+     */
+    @Override
+    public CostShareParam getByIdAndCalcType(Long shareParamId) {
+        return this.getOne(
+                new LambdaQueryWrapper<CostShareParam>().eq(CostShareParam::getId, shareParamId).eq(CostShareParam::getCalcType, 2)
+        );
+    }
 
+    /**
+     * 通过code得到name
+     *
+     * @param shareParamCode
+     * @param hospId
+     * @return
+     */
+    @Override
+    public String getByCode(String shareParamCode, Long hospId) {
+        CostShareParam one = this.getOne(
+                new LambdaQueryWrapper<CostShareParam>().eq(CostShareParam::getShareParamCode, shareParamCode)
+                        .eq(CostShareParam::getHospId, hospId).last(LIMIT)
+        );
+        if (Objects.isNull(one)) {
+            throw new CostException("数据异常");
+        }
+        return one.getShareParamName();
+    }
 }

+ 59 - 1
src/main/java/com/imed/costaccount/service/impl/ResponsibilityServiceImpl.java

@@ -420,7 +420,7 @@ public class ResponsibilityServiceImpl extends ServiceImpl<ResponsibilityMapper,
         List<Responsibility> responsibilities = baseMapper.selectList(new QueryWrapper<Responsibility>().lambda()
                 .eq(Responsibility::getHospId, hospId)
                 .eq(Responsibility::getIsGatherCenter, NumberConstant.TWO)
-                .ne(Responsibility::getShareId,NumberConstant.ZERO));
+                .ne(Responsibility::getShareId, NumberConstant.ZERO));
         List<CostResponsibilityLevelVO> costResponsibilityLevelVOS = BeanUtil.convertList(responsibilities, CostResponsibilityLevelVO.class);
         List<CostShareLevelVO> costShareLevelServiceAll = costShareLevelService.getAll(hospId);
         Map<Long, List<CostShareLevelVO>> listMap = costShareLevelServiceAll.stream().collect(Collectors.groupingBy(CostShareLevelVO::getId));
@@ -465,4 +465,62 @@ public class ResponsibilityServiceImpl extends ServiceImpl<ResponsibilityMapper,
         }));
         return parentCostResponsibility;
     }
+
+
+    /**
+     * 通过分摊级别id得到所有的责任中心
+     *
+     * @param levelId 分摊级别id
+     * @param hospId  医院id
+     * @return 责任中心
+     */
+    @Override
+    public List<Responsibility> getByLevelIds(List<Long> levelId, Long hospId) {
+        List<Responsibility> list = this.list(
+                new LambdaQueryWrapper<Responsibility>()
+                        .in(Responsibility::getShareId, levelId)
+                        .eq(Responsibility::getHospId, hospId)
+        );
+        if (list.isEmpty()) {
+            throw new CostException("责任中心未分配正确的分摊层级");
+        }
+        return list;
+    }
+
+    /**
+     * 通过分摊层级列表得到对应的责任中心
+     *
+     * @param levelId 分摊层级id
+     * @param hospId  医院id
+     * @return 责任中心 可能存在null
+     */
+    @Override
+    public List<Responsibility> getByLevelId(Long levelId, Long hospId) {
+        return this.list(
+                new LambdaQueryWrapper<Responsibility>()
+                        .in(Responsibility::getShareId, levelId)
+                        .eq(Responsibility::getHospId, hospId)
+        );
+    }
+
+    /**
+     * 通过code得到名字
+     *
+     * @param valueResponsibilityCode
+     * @param hospId
+     * @return
+     */
+    @Override
+    public String getByCode(String valueResponsibilityCode, Long hospId) {
+        Responsibility one = this.getOne(
+                new LambdaQueryWrapper<Responsibility>()
+                        .eq(Responsibility::getResponsibilityCode, valueResponsibilityCode)
+                        .eq(Responsibility::getHospId, hospId)
+                        .last(LIMIT)
+        );
+        if (Objects.isNull(one)) {
+            throw new CostException("数据异常");
+        }
+        return one.getResponsibilityName();
+    }
 }

+ 13 - 0
src/main/java/com/imed/costaccount/service/impl/ShareParamValueServiceImpl.java

@@ -502,4 +502,17 @@ public class ShareParamValueServiceImpl extends ServiceImpl<ShareParamValueMappe
         });
         this.updateBatchById(list);
     }
+
+    /**
+     * 得到这个月导入的成本分摊参数值列表 聚合过
+     *
+     * @param year   年
+     * @param month  月
+     * @param hospId 医院id
+     * @return 某月成本分摊参数值
+     */
+    @Override
+    public List<ShareParamValue> getListByYearAndMonth(Integer year, Integer month, Long hospId) {
+        return baseMapper.getListByYearAndMonth(year, month, hospId);
+    }
 }

+ 6 - 2
src/main/java/com/imed/costaccount/web/CostCostingCollectionController.java

@@ -20,8 +20,12 @@ import java.util.Arrays;
 @RestController
 @RequestMapping("/costAccount/costcostingcollection")
 public class CostCostingCollectionController {
-    @Autowired
-    private CostCostingCollectionService costCostingCollectionService;
+
+    private final CostCostingCollectionService costCostingCollectionService;
+
+    public CostCostingCollectionController(CostCostingCollectionService costCostingCollectionService) {
+        this.costCostingCollectionService = costCostingCollectionService;
+    }
 
     /**
      * 分页查询列表

+ 7 - 2
src/main/java/com/imed/costaccount/web/CostCostingGroupController.java

@@ -4,6 +4,7 @@ import com.imed.costaccount.common.exception.CostException;
 import com.imed.costaccount.common.util.PageUtils;
 import com.imed.costaccount.common.util.Result;
 import com.imed.costaccount.model.dto.StartDTO;
+import com.imed.costaccount.service.AllocationService;
 import com.imed.costaccount.service.CostCostingGroupService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
@@ -26,8 +27,11 @@ import javax.validation.Valid;
 public class CostCostingGroupController extends AbstractController {
     private final CostCostingGroupService costCostingGroupService;
 
-    public CostCostingGroupController(CostCostingGroupService costCostingGroupService) {
+    private final AllocationService allocationService;
+
+    public CostCostingGroupController(CostCostingGroupService costCostingGroupService, AllocationService allocationService) {
         this.costCostingGroupService = costCostingGroupService;
+        this.allocationService = allocationService;
     }
 
     @ApiOperation("成本分摊前数据列表")
@@ -69,7 +73,8 @@ public class CostCostingGroupController extends AbstractController {
     @ApiOperation("开始归集")
     @PostMapping("/startAllocation")
     public Result startAllocation(@RequestBody @Valid StartDTO startDTO) {
-        costCostingGroupService.startAllocation(startDTO, getHospId());
+//        costCostingGroupService.startAllocation(startDTO, getHospId());
+        allocationService.startAllocation(startDTO,getHospId());
         return Result.ok();
     }
 }

+ 28 - 0
src/main/resources/mapper/AllocationMapper.xml

@@ -0,0 +1,28 @@
+<?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.imed.costaccount.mapper.AllocationMapper">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.imed.costaccount.model.Allocation" id="allocationMap">
+        <result property="id" column="id"/>
+        <result property="dateYear" column="date_year"/>
+        <result property="dateMonth" column="date_month"/>
+        <result property="levelSort" column="level_sort"/>
+        <result property="levelName" column="level_name"/>
+        <result property="hospId" column="hosp_id"/>
+        <result property="responsibilityCode" column="responsibility_code"/>
+        <result property="responsibilityName" column="responsibility_name"/>
+        <result property="accountShareId" column="account_share_id"/>
+        <result property="amount" column="amount"/>
+        <result property="targetResponsibilityCode" column="target_responsibility_code"/>
+        <result property="targetResponsibilityName" column="target_responsibility_name"/>
+        <result property="shareParamCode" column="share_param_code"/>
+        <result property="shareParamName" column="share_param_name"/>
+        <result property="isBaseCost" column="is_base_cost"/>
+        <result property="createTime" column="create_time"/>
+        <result property="deleteTime" column="delete_time"/>
+    </resultMap>
+
+
+</mapper>

+ 8 - 5
src/main/resources/mapper/CostCostingCollectionMapper.xml

@@ -8,20 +8,23 @@
         <result property="id" column="id"/>
         <result property="year" column="year"/>
         <result property="month" column="month"/>
-        <result property="departmentCode" column="department_code"/>
-        <result property="departmentName" column="department_name"/>
         <result property="responsibilityCode" column="responsibility_code"/>
         <result property="responsibilityName" column="responsibility_name"/>
         <result property="leverSort" column="lever_sort"/>
         <result property="shareLevelName" column="share_level_name"/>
-        <result property="productCode" column="product_code"/>
-        <result property="productName" column="product_name"/>
+        <result property="accountCode" column="account_code"/>
+        <result property="accountName" column="account_name"/>
         <result property="isBaseCost" column="is_base_cost"/>
         <result property="amount" column="amount"/>
-        <result property="fileId" column="file_id"/>
         <result property="createTime" column="create_time"/>
         <result property="deleteTime" column="delete_time"/>
         <result property="hospId" column="hosp_id"/>
+        <result property="shareParamProportion" column="share_param_proportion" />
+        <result property="shareParam" column="share_param" />
+        <result property="shareValue" column="share_value" />
+<!--        <result property="targetResponsibilityCode" column="target_responsibility_code" />-->
+<!--        <result property="targetResponsibilityName" column="target_responsibility_name" />-->
+        <result property="shareAmount" column="share_amount" />
     </resultMap>
 
 

+ 15 - 0
src/main/resources/mapper/ShareParamValueMapper.xml

@@ -60,5 +60,20 @@
         </if>
     </select>
 
+    <select id="getListByYearAndMonth" resultType="com.imed.costaccount.model.ShareParamValue">
+        select cspv.*
+        from cost_share_param_value cspv
+                 left join cost_share_param csp
+                           on csp.share_param_code = cspv.share_param_code and csp.hosp_id = cspv.hosp_id
+                 left join cost_responsibility cr
+                           on cspv.responsibility_code = cr.responsibility_code and cspv.hosp_id = cr.hosp_id
+        where cspv.hosp_id = #{hospId}
+          and cspv.delete_time = 0
+          and csp.delete_time = 0
+          and cr.delete_time = 0
+          and cspv.date_month = #{month}
+          and cspv.date_year = #{year}
+    </select>
+
 
 </mapper>