Browse Source

新增
1、新增获取当前机构 otherFiles 为空的统计信息
2、外出配置增加是否自动跨月,0:否,1:是
BUGFIX
1、解决长者档案分页接口长者存在多个附件时会有多条记录的问题
2、解决入住办理时填入床位号后重新打开详情页面丢失字段信息问题

liangwenxuan 1 tuần trước cách đây
mục cha
commit
234f4e5ced
11 tập tin đã thay đổi với 138 bổ sung18 xóa
  1. 4 0
      sql/mysql/alter_elderly_outbound_refund_config_add_is_auto_cross.sql
  2. 2 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/business/BpmElderlApplyServiceImpl.java
  3. 6 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/ElderlyInfoController.java
  4. 28 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/vo/ElderlyOtherFilesStatisticsRespVO.java
  5. 4 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/OutboundRefundConfigDO.java
  6. 5 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/ElderlyInfoMapper.java
  7. 51 14
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyAskLeaveServiceImpl.java
  8. 5 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyInfoService.java
  9. 22 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyInfoServiceImpl.java
  10. 2 4
      yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyContractMapper.xml
  11. 9 0
      yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyInfoMapper.xml

+ 4 - 0
sql/mysql/alter_elderly_outbound_refund_config_add_is_auto_cross.sql

@@ -0,0 +1,4 @@
+-- 外出退费配置表新增是否自动跨月字段
+-- 0:否(所有费用生成在归属月中),1:是(默认,跨月时按月份拆分)
+ALTER TABLE `elderly_outbound_refund_config`
+    ADD COLUMN `is_auto_cross` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否自动跨月,0:否,1:是' AFTER `config_type`;

+ 2 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/business/BpmElderlApplyServiceImpl.java

@@ -519,6 +519,8 @@ public class BpmElderlApplyServiceImpl implements BpmElderlApplyService {
         if (null != elderlyInfo) {
             LogRecordContext.putVariable("id", elderlyInfo.getId());
             LogRecordContext.putVariable("elderName", elderlyInfo.getElderName());
+            elderlyInfo.setBedId(createReqVO.getExpenseBO().getBedId());
+            bpmElderlyApi.update(elderlyInfo);
         }
         LogRecordContext.putVariable("nickname", SecurityFrameworkUtils.getLoginUserNickname());
         createReqVO.setBusinessId2(createReqVO.getElderlyId());

+ 6 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/ElderlyInfoController.java

@@ -440,4 +440,10 @@ public class ElderlyInfoController {
                                                  @RequestParam("tenantId") Long tenantId){
         return success(elderlyInfoService.miniGetElderInfo(elderName,tenantId));
     }
+
+    @GetMapping("/getOtherFilesStatistics")
+    @Operation(summary = "获取当前机构 otherFiles 为空的统计信息")
+    public CommonResult<ElderlyOtherFilesStatisticsRespVO> getOtherFilesStatistics() {
+        return success(elderlyInfoService.getOtherFilesStatistics());
+    }
 }

+ 28 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/vo/ElderlyOtherFilesStatisticsRespVO.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.system.controller.admin.biz.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 长者其他文件统计响应 VO
+ */
+@Data
+public class ElderlyOtherFilesStatisticsRespVO {
+
+    /**
+     * 当前机构所有长者数
+     */
+    private Long totalCount;
+
+    /**
+     * otherFiles 字段为空的长者数量
+     */
+    private Long emptyOtherFilesCount;
+
+    /**
+     * otherFiles 为空的长者数占当前机构所有长者数的百分比
+     */
+    private BigDecimal emptyOtherFilesPercentage;
+
+}

+ 4 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/OutboundRefundConfigDO.java

@@ -73,6 +73,10 @@ public class OutboundRefundConfigDO{
      * 配置类型:0-全局统一配置,1-项目独立配置
      */
     private Integer configType;
+    /**
+     * 是否自动跨月,0:否,1:是
+     */
+    private Integer isAutoCross;
 
     @TableField(exist = false)
     private String tenantName;

+ 5 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/ElderlyInfoMapper.java

@@ -58,4 +58,9 @@ public interface ElderlyInfoMapper extends BaseMapperX<ElderlyInfoDO> {
     List<ElderlyInfoDO> selectExportListWithBedInfo(@Param("tenantId") Long tenantId);
 
     ElderlyInfoDO selectByIdIgnoreDeleted(@Param("id") Long id);
+
+    /**
+     * 统计当前机构 other_files 为空的长者数量及总数
+     */
+    ElderlyOtherFilesStatisticsRespVO selectOtherFilesStatistics(@Param("tenantId") Long tenantId);
 }

+ 51 - 14
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyAskLeaveServiceImpl.java

@@ -186,7 +186,6 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
     private void processRefundItem(ElderlyAskLeaveDO elderlyAskLeaveDO, OutboundRefundItemDO item,
                                    LocalDate outLocalDate, LocalDate endLocalDate, int totalDays,
                                    OutboundRefundConfigDO config) {
-        String configName = config.getName();
         // 获取退费规则
         RefundRule rule = getRefundRule(config, item);
 
@@ -306,7 +305,7 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
 
             // 根据退费类型处理(传入实际退费开始的日期,用于计算归属月份)
             processRefundByType(elderlyAskLeaveDO, item, expenseItemDO,
-                    adjustedStart, adjustedEnd, overlapDays, adjustedIncludeEndDay, configName, adjustedStart);
+                    adjustedStart, adjustedEnd, overlapDays, adjustedIncludeEndDay, config, adjustedStart);
         }
     }
 
@@ -399,31 +398,34 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
      */
     private void processRefundByType(ElderlyAskLeaveDO elderlyAskLeaveDO, OutboundRefundItemDO outboundRefundItem,
                                      ExpenseItemDO expenseItemDO, LocalDate startDate, LocalDate endDate,
-                                     int refundDays, boolean includeEndDay, String configName, LocalDate actualRefundStartDate) {
+                                     int refundDays, boolean includeEndDay, OutboundRefundConfigDO config, LocalDate actualRefundStartDate) {
+
+        boolean isAutoCross = config.getIsAutoCross() == null || Objects.equals(config.getIsAutoCross(), 1);
+        String configName = config.getName();
 
         if (Objects.equals(outboundRefundItem.getType(), 1)) {
             // 固定金额退费
-            processFixedAmountRefund(elderlyAskLeaveDO, outboundRefundItem, startDate, endDate, refundDays, includeEndDay, configName, actualRefundStartDate);
+            processFixedAmountRefund(elderlyAskLeaveDO, outboundRefundItem, startDate, endDate, refundDays, includeEndDay, configName, actualRefundStartDate, isAutoCross);
         } else if (outboundRefundItem.getType() == 2) {
             // 比例退费
-            processProportionalRefund(elderlyAskLeaveDO, outboundRefundItem, startDate, endDate, refundDays, includeEndDay, configName, actualRefundStartDate);
+            processProportionalRefund(elderlyAskLeaveDO, outboundRefundItem, startDate, endDate, refundDays, includeEndDay, configName, actualRefundStartDate, isAutoCross);
         } else {
             // 按月份天数计算
             processMonthlyRefunds(elderlyAskLeaveDO, outboundRefundItem, expenseItemDO,
-                    startDate, endDate, refundDays, includeEndDay, configName, actualRefundStartDate);
+                    startDate, endDate, refundDays, includeEndDay, configName, actualRefundStartDate, isAutoCross);
         }
     }
 
     private void processFixedAmountRefund(ElderlyAskLeaveDO elderlyAskLeaveDO, OutboundRefundItemDO outboundRefundItem,
-                                          LocalDate startDate, LocalDate endDate, int refundDays, boolean includeEndDay, String configName, LocalDate actualRefundStartDate) {
+                                          LocalDate startDate, LocalDate endDate, int refundDays, boolean includeEndDay, String configName, LocalDate actualRefundStartDate, boolean isAutoCross) {
         BigDecimal dailyAmount = resolveCustomAmount(outboundRefundItem, outboundRefundItem.getAmount());
 
         // 判断是否跨月
         YearMonth startMonth = YearMonth.from(startDate);
         YearMonth endMonth = YearMonth.from(endDate);
         
-        if (startMonth.equals(endMonth)) {
-            // 不跨月,按原逻辑处理
+        if (startMonth.equals(endMonth) || !isAutoCross) {
+            // 不跨月(或不允许自动跨月),按原逻辑处理(所有费用合并到一条记录)
             DailyExpensesDO dailyExpenses = createBaseExpenseRecord(elderlyAskLeaveDO, outboundRefundItem, startDate, endDate);
             BigDecimal totalAmount = dailyAmount.multiply(BigDecimal.valueOf(refundDays)).setScale(8, RoundingMode.DOWN);
             
@@ -480,7 +482,7 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
     }
 
     private void processProportionalRefund(ElderlyAskLeaveDO elderlyAskLeaveDO, OutboundRefundItemDO outboundRefundItem,
-                                           LocalDate startDate, LocalDate endDate, int refundDays, boolean includeEndDay, String configName, LocalDate actualRefundStartDate) {
+                                           LocalDate startDate, LocalDate endDate, int refundDays, boolean includeEndDay, String configName, LocalDate actualRefundStartDate, boolean isAutoCross) {
         BigDecimal proportion = outboundRefundItem.getProportion();
 
         // 获取费用项原价
@@ -500,8 +502,8 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
         YearMonth startMonth = YearMonth.from(startDate);
         YearMonth endMonth = YearMonth.from(endDate);
         
-        if (startMonth.equals(endMonth)) {
-            // 不跨月,按原逻辑处理
+        if (startMonth.equals(endMonth) || !isAutoCross) {
+            // 不跨月(或不允许自动跨月),按原逻辑处理(所有费用合并到一条记录)
             DailyExpensesDO dailyExpenses = createBaseExpenseRecord(elderlyAskLeaveDO, outboundRefundItem, startDate, endDate);
             BigDecimal totalAmount = dailyPrice.multiply(BigDecimal.valueOf(refundDays)).setScale(8, RoundingMode.DOWN);
             
@@ -561,8 +563,43 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
 
     private void processMonthlyRefunds(ElderlyAskLeaveDO elderlyAskLeaveDO, OutboundRefundItemDO outboundRefundItem,
                                        ExpenseItemDO expenseItemDO, LocalDate startDate, LocalDate endDate,
-                                       int totalDays, boolean includeEndDay, String configName, LocalDate actualRefundStartDate) {
-        // 按月份循环处理
+                                       int totalDays, boolean includeEndDay, String configName, LocalDate actualRefundStartDate, boolean isAutoCross) {
+        if (!isAutoCross) {
+            // 不自动跨月,所有费用生成在归属月中(一条记录)
+            YearMonth startYearMonth = YearMonth.from(startDate);
+            DailyExpensesDO dailyExpenses = createBaseExpenseRecord(elderlyAskLeaveDO, outboundRefundItem, startDate, endDate);
+
+            BigDecimal actualAmount = resolveCustomAmount(outboundRefundItem, expenseItemDO.getActualAmount());
+            BigDecimal calculateAmount = resolveCalculateAmount(outboundRefundItem, expenseItemDO.getActualAmount(), actualAmount);
+            BigDecimal dayPrice;
+            if (Objects.equals(expenseItemDO.getIsDayCalculate(), 1)) {
+                dayPrice = actualAmount;
+            } else {
+                dayPrice = calculateAmount.divide(BigDecimal.valueOf(startYearMonth.lengthOfMonth()), 5, RoundingMode.HALF_UP);
+            }
+            BigDecimal monthAmount = dayPrice.multiply(BigDecimal.valueOf(totalDays)).setScale(2, RoundingMode.HALF_UP);
+
+            dailyExpenses.setPrice(dayPrice);
+            dailyExpenses.setAmount(monthAmount.negate());
+            dailyExpenses.setCount(totalDays);
+
+            String attributionBillTime = calculateAttributionBillTime(elderlyAskLeaveDO, startYearMonth, actualRefundStartDate);
+            dailyExpenses.setAttributionBillTime(attributionBillTime);
+
+            String subtractMark = "";
+            if (Objects.equals(outboundRefundItem.getIsSubtract(), BooleanEnum.TRUE.getValue())) {
+                BigDecimal baseAmount = expenseItemDO.getActualAmount() == null ? BigDecimal.ZERO : expenseItemDO.getActualAmount();
+                subtractMark = "减底价,原始金额:" + baseAmount.setScale(2, RoundingMode.HALF_UP) + ",减底价后金额:" + calculateAmount.setScale(2, RoundingMode.HALF_UP) + ",";
+            }
+            String customMark = BooleanEnum.TRUE.getValue().equals(outboundRefundItem.getIsCustom()) ? "使用自定义金额,退费计算金额:" + actualAmount.setScale(2,RoundingMode.HALF_UP) + ",": "";
+            String endDayInfo = includeEndDay ? "包含最后一天" : "不包含最后一天";
+            dailyExpenses.setRemarks(subtractMark + customMark + configName + "退费:长者外出,退" + startDate + "到" + endDate + "的费用(共" + totalDays + "天," + endDayInfo + ")");
+
+            saveDailyExpenseAndAttachBill(elderlyAskLeaveDO, dailyExpenses);
+            return;
+        }
+
+        // 按月份循环处理(自动跨月)
         LocalDate currentDate = startDate;
         while (!currentDate.isAfter(endDate)) {
             YearMonth currentYearMonth = YearMonth.from(currentDate);

+ 5 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyInfoService.java

@@ -99,5 +99,10 @@ public interface ElderlyInfoService {
     String importCheckIn(List<ElderlyCheckInImportVO> list);
     String importDeposit(List<ElderlyDepositImportVO> list);
     String miniGetElderInfo(String elderName,Long tenantId);
+
+    /**
+     * 获取当前机构 otherFiles 为空的统计信息
+     */
+    ElderlyOtherFilesStatisticsRespVO getOtherFilesStatistics();
 }
 

+ 22 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyInfoServiceImpl.java

@@ -3194,5 +3194,27 @@ public class ElderlyInfoServiceImpl implements ElderlyInfoService {
         }
     }
 
+    @Override
+    public ElderlyOtherFilesStatisticsRespVO getOtherFilesStatistics() {
+        Long tenantId = TenantContextHolder.getTenantId();
+        ElderlyOtherFilesStatisticsRespVO respVO = elderlyInfoMapper.selectOtherFilesStatistics(tenantId);
+        if (respVO == null) {
+            respVO = new ElderlyOtherFilesStatisticsRespVO();
+            respVO.setTotalCount(0L);
+            respVO.setEmptyOtherFilesCount(0L);
+            respVO.setEmptyOtherFilesPercentage(BigDecimal.ZERO);
+        } else {
+            // 计算百分比,避免除零
+            if (respVO.getTotalCount() != null && respVO.getTotalCount() > 0) {
+                BigDecimal percentage = new BigDecimal(respVO.getEmptyOtherFilesCount())
+                        .multiply(new BigDecimal("100"))
+                        .divide(new BigDecimal(respVO.getTotalCount()), 2, RoundingMode.HALF_UP);
+                respVO.setEmptyOtherFilesPercentage(percentage);
+            } else {
+                respVO.setEmptyOtherFilesPercentage(BigDecimal.ZERO);
+            }
+        }
+        return respVO;
+    }
 
 }

+ 2 - 4
yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyContractMapper.xml

@@ -12,8 +12,6 @@
         select ec.*,ei.in_status_type
         from elderly_contract ec
         left join elderly_info ei on ei.id = ec.elder_id
-        left join elderly_contract_detail ecd on  ec.id = ecd.contract_id
-        left join system_tenant st on st.id = ec.tenant_id
         <where>
             <if test="params.elderName != null and params.elderName != ''">
                 and ei.elder_name like concat('%',#{params.elderName} ,'%')
@@ -25,10 +23,10 @@
                 and ei.in_status_type = #{params.inStatusType}
             </if>
             <if test="params.hasExtra != null and params.hasExtra == 1">
-                and ecd.file_name is not null
+                and exists (select 1 from elderly_contract_detail ecd where ecd.contract_id = ec.id and ecd.file_name is not null)
             </if>
             <if test="params.hasExtra != null and params.hasExtra == 0">
-                and ecd.file_name is null
+                and not exists (select 1 from elderly_contract_detail ecd where ecd.contract_id = ec.id and ecd.file_name is not null)
             </if>
             <if test="params.orgType != null">
                 and ei.org_type = #{params.orgType}

+ 9 - 0
yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyInfoMapper.xml

@@ -439,4 +439,13 @@
         WHERE id = #{id}
     </select>
 
+    <select id="selectOtherFilesStatistics" resultType="cn.iocoder.yudao.module.system.controller.admin.biz.vo.ElderlyOtherFilesStatisticsRespVO">
+        SELECT
+            COUNT(1) AS totalCount,
+            SUM(CASE WHEN ei.other_files IS NULL OR ei.other_files = '' THEN 1 ELSE 0 END) AS emptyOtherFilesCount
+        FROM elderly_info ei
+        WHERE ei.deleted = 0
+          AND ei.tenant_id = #{tenantId}
+    </select>
+
 </mapper>