Kaynağa Gözat

中间计量申请,自动批量计量

qianxb 1 yıl önce
ebeveyn
işleme
1ac4bf0321

+ 3 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/InventoryFormMeterVO.java

@@ -37,6 +37,9 @@ public class InventoryFormMeterVO extends InventoryFormMeter {
 	@ApiModelProperty(value = "当前部位当前清单当前计量总和")
 	private BigDecimal allMeterMoney;
 
+	@ApiModelProperty(value = "当前部位当前清单当前计量数量总和")
+	private BigDecimal allMeterTotal;
+
 	@ApiModelProperty(value = "清单编号")
 	private String formNumber;
 

+ 23 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterLinkWbsInfoVO.java

@@ -0,0 +1,23 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Param   计量单元关联的节点信息->附带节点状态,附带节点最大附件type
+ * @Author wangwl
+ * @Date 2024/3/13 14:02
+ **/
+@Data
+public class MeterLinkWbsInfoVO {
+
+    @ApiModelProperty(value = "wbs_contract 的pKeyId")
+    private Long id;
+
+    @ApiModelProperty(value = "节点审批状态")
+    private Integer appStatus;
+
+    @ApiModelProperty(value = "节点最大附件type值")
+    private Integer maxType;
+
+}

+ 46 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterTreeContractVO2.java

@@ -0,0 +1,46 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.meter.entity.MeterTreeContract;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 自动计量专用VO
+ */
+@Data
+public class MeterTreeContractVO2 {
+
+    @ApiModelProperty(value = "合同计量单元id")
+    private Long id;
+
+    @ApiModelProperty(value = "合同计量单元名称")
+    private String nodeName;
+
+    @ApiModelProperty(value = "是否混泥土节点1是0否")
+    private Integer isConcreteNode;
+
+    @ApiModelProperty(value = "7天强度")
+    private BigDecimal sevenRatio;
+
+    @ApiModelProperty(value = "28天强度")
+    private BigDecimal twentyEightRatio;
+
+    @ApiModelProperty(value = "关联的WBS,逗号拼接")
+    private String linkWbs;
+
+    @ApiModelProperty(value = "关联的清单,逗号拼接")
+    private String linkForm;
+
+    @ApiModelProperty(value = "当前期的中间计量的id,逗号拼接")
+    private String linkMiddle;
+
+    @ApiModelProperty(value = "中期计量总体支付比例")
+    private BigDecimal payRatio;
+
+    @ApiModelProperty(value = "计算式")
+    private String calculateFormula;
+
+}

+ 26 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/WbsLinkQueryInfoVO.java

@@ -0,0 +1,26 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Param   WBS节点的审批信息-> 包含电签PDF和queryInfoId和name
+ * @Author wangwl
+ * @Date 2024/3/13 14:02
+ **/
+@Data
+public class WbsLinkQueryInfoVO {
+
+    @ApiModelProperty(value = "u_information_query的id")
+    private Long id;
+
+    @ApiModelProperty(value = "电签PDF")
+    private String eVisaPdf;
+
+    @ApiModelProperty(value = "wbs节点的pKeyId")
+    private Long wbsId;
+
+    @ApiModelProperty(value = "u_information_query的name")
+    private String name;
+
+}

+ 1 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/MeterTreeController.java

@@ -905,7 +905,7 @@ public class MeterTreeController extends BladeController {
     @ApiOperation(value = "删除合同计量单元关联WBS节点", notes = "传入wbs节点ids,逗号拼接")
     public R<String> deleteLinkWbsTree(@RequestBody Map<String, String> params) {
         meterTreeContractService.deleteLinkWbsTree(params);
-        return R.success("删除成功");
+        return R.success("取消关联成功");
     }
 
 }

+ 16 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/MiddleMeterApplyController.java

@@ -302,4 +302,20 @@ public class MiddleMeterApplyController extends BladeController {
         DeductStatisticsVO vo = middleMeterApplyService.deductStatistics(contractId);
         return R.data(vo);
     }
+
+    /**
+     * 自动批量计量
+     */
+    @GetMapping("/autoBatchMeter")
+    @ApiOperationSupport(order = 17)
+    @ApiOperation(value = "自动批量计量", notes = "传入项目id,合同id,计量期id")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "contractId", value = "合同id", required = true),
+            @ApiImplicitParam(name = "PeriodId", value = "计量期id", required = true),
+    })
+    public R<String> autoBatchMeter(Long projectId,Long contractId,Long PeriodId) {
+        String info = middleMeterApplyService.autoBatchMeter(projectId,contractId,PeriodId);
+        return R.success("计量完成:"+info);
+    }
 }

+ 11 - 4
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MiddleMeterApplyMapper.java

@@ -22,10 +22,7 @@ import org.springblade.business.entity.InformationQuery;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.meter.dto.WbsNodeDTO;
-import org.springblade.meter.entity.ChangeTokenForm;
-import org.springblade.meter.entity.ChangeTokenMeter;
-import org.springblade.meter.entity.MeterTreeContract;
-import org.springblade.meter.entity.MiddleMeterApply;
+import org.springblade.meter.entity.*;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springblade.meter.vo.*;
 
@@ -102,4 +99,14 @@ public interface MiddleMeterApplyMapper extends BaseMapper<MiddleMeterApply> {
     List<InformationQuery>  getQueryDataByIds(@Param("ids") List<Long> ids);
 
     List<MiddleMeterApply> getALLUnLinkDataApply(@Param("contractId") Long contractId);
+
+    List<MeterTreeContractVO2> getAllAutoMeterNode(@Param("contractId") Long contractId,@Param("periodId") Long periodId);
+
+    List<MeterLinkWbsInfoVO> getAllLinkWbsInfo(@Param("contractId") Long contractId,@Param("ids") HashSet<Long> hashSet);
+
+    List<WbsLinkQueryInfoVO> getQueryInfo(@Param("contractId") Long contractId,@Param("ids") HashSet<Long> hashSet);
+
+    List<InventoryFormMeterVO> getAllFormMeter(@Param("contractId")Long contractId,@Param("ids") List<Long> meterIds);
+
+
 }

+ 44 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MiddleMeterApplyMapper.xml

@@ -328,6 +328,50 @@
         WHERE contract_id = #{contractId} and is_deleted = 0 and approve_status = 2
                 and is_link_data = 0
     </select>
+    <select id="getAllAutoMeterNode" resultType="org.springblade.meter.vo.MeterTreeContractVO2">
+        select id ,is_concrete_node,seven_ratio,twenty_eight_ratio,node_name,calculate_formula,
+               (select GROUP_CONCAT(lwt.wbs_tree_id) from s_meter_tree_link_wbs_tree lwt
+                    where lwt.contract_id = #{contractId} and smtc.id = lwt.meter_tree_id and lwt.is_deleted = 0) as linkWbs,
+               (select GROUP_CONCAT(ifm.contract_form_id) from s_inventory_form_meter ifm
+                    where ifm.contract_id = #{contractId} and smtc.id = ifm.contract_meter_id and ifm.is_deleted = 0) as linkForm,
+               (select GROUP_CONCAT(mma.id) from s_middle_meter_apply mma
+                    where mma.contract_id = #{contractId} and smtc.id = mma.contract_unit_id and mma.is_deleted = 0) as linkMiddle
+        from s_meter_tree_contract smtc where contract_id = #{contractId} and is_auto_meter = 1 and is_deleted = 0
+    </select>
+    <select id="getAllLinkWbsInfo" resultType="org.springblade.meter.vo.MeterLinkWbsInfoVO">
+        select p_key_id as id,
+               (select ifnull(MAX(uiq.status),0) from u_information_query uiq
+                    where uiq.contract_id = #{contractId} and uiq.classify = 1 and uiq.wbs_id = wtc.p_key_id
+                      and uiq.type = 1 and uiq.status != 3 and uiq.is_deleted = 0 ) as appStatus,
+               (select ifnull(MAX(mtf.type),0) from m_table_file mtf
+                    where mtf.contract_id = #{contractId} and mtf.tab_id = wtc.p_key_id and mtf.is_deleted = 0) as maxType,
+        from m_wbs_tree_contract wtc
+        where p_key_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+    <select id="getQueryInfo" resultType="org.springblade.meter.vo.WbsLinkQueryInfoVO">
+        select id ,e_visa_pdf_url as eVisaPdf,wbs_id as wbsId,name
+        from u_information_query uiq
+        where uiq.contract_id = #{contractId} and uiq.classify = 1
+            and uiq.type = 1 and uiq.status = 2 and uiq.is_deleted = 0
+            and  uiq.wbs_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+    <select id="getAllFormMeter" resultType="org.springblade.meter.vo.InventoryFormMeterVO">
+        select *,
+            IFNULL((select sum(current_meter_total) from s_inventory_form_apply ifa where ifa.contract_id = #{contractId} and is_deleted = 0
+                and ifa.contract_meter_id = ifm.contract_meter_id and ifa.contract_form_id = ifm.contract_form_id),0) as allMeterTotal
+        from s_inventory_form_meter ifm where contract_id = #{contractId} and is_deleted = 0
+        and contract_meter_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
 
 
 </mapper>

+ 5 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/service/IMiddleMeterApplyService.java

@@ -85,4 +85,9 @@ public interface IMiddleMeterApplyService extends BaseService<MiddleMeterApply>
      * 扣回统计
      */
     DeductStatisticsVO deductStatistics(Long contractId);
+
+    /**
+     * 自动批量计量
+     */
+    String autoBatchMeter(Long projectId,Long contractId, Long periodId);
 }

+ 269 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MiddleMeterApplyServiceImpl.java

@@ -78,6 +78,8 @@ public class MiddleMeterApplyServiceImpl extends BaseServiceImpl<MiddleMeterAppl
 
     private final IContractInventoryFormService inventoryFormService;
 
+    private final MeterContractInfoService meterContractInfoService;
+
 
 
     /**
@@ -485,6 +487,9 @@ public class MiddleMeterApplyServiceImpl extends BaseServiceImpl<MiddleMeterAppl
             //删除中间表当前中间计量申请数据
             inventoryFormApplyService.remove(new LambdaQueryWrapper<InventoryFormApply>()
                     .eq(InventoryFormApply::getMiddleMeterId,id));
+            //删除附件数据
+            attachmentFormService.remove(new LambdaQueryWrapper<AttachmentForm>()
+                    .eq(AttachmentForm::getMasterId,id));
         }
     }
 
@@ -985,6 +990,270 @@ public class MiddleMeterApplyServiceImpl extends BaseServiceImpl<MiddleMeterAppl
         return vo;
     }
 
+    @Override
+    @Transactional
+    public String autoBatchMeter(Long projectId,Long contractId, Long periodId) {
+        try {
+            /*校验,过滤允许自动计量的节点,并设置需要的相关属性值*/
+            //判断当前计量期是否是未上报
+            ContractMeterPeriod period = contractMeterPeriodService.getById(periodId);
+            if (period == null || period.getApproveStatus() != 0){
+                throw new ServiceException("当前计量期不是未上报状态");
+            }
+            //查询后台设置的支付比例,没有则提示
+            MeterContractInfo contractInfo = meterContractInfoService.getOne(new LambdaQueryWrapper<MeterContractInfo>()
+                        .eq(MeterContractInfo::getContractId,contractId));
+            if (contractInfo == null || contractInfo.getMiddlePayRatio() == null){
+                throw new ServiceException("后台未设置支付比例");
+            }
+            //查询出当前合同段所有允许自动计量的合同计量单元信息,并携带关联WBS节点逗号拼接,并携带关联清单的id逗号拼接,并携带当前计量期下当前合同计量单元的id,逗号拼接
+            List<MeterTreeContractVO2> voList = baseMapper.getAllAutoMeterNode(contractId,periodId);
+            //过滤,如果不存在关联WBS节点则排除,如果不存在挂载清单也排除,如果已经计量也排除
+            voList = voList.stream()
+                    .filter(l-> StringUtils.isNotBlank(l.getLinkWbs()) && StringUtils.isNotBlank(l.getLinkForm()) && StringUtils.isBlank(l.getLinkMiddle()))
+                    .collect(Collectors.toList());
+            if (voList.size() == 0){
+                throw new ServiceException("当前没有符合要求的合同计量单元-1");
+            }
+            //取出计量单元混凝土节点所有关联节点,查询->附带节点状态,附带每个节点最大附件type
+            List<MeterTreeContractVO2> vo2s = voList.stream().filter(l -> l.getIsConcreteNode() == 1).collect(Collectors.toList());
+            Map<Long, MeterLinkWbsInfoVO> wbsInfoVOMap = new HashMap<>();
+            if (vo2s.size() > 0) {
+                List<String> collect = voList.stream().map(l -> l.getLinkWbs()).collect(Collectors.toList());
+                String join = String.join(",", collect);
+                List<Long> wbsIds = Func.toLongList(join);
+                HashSet<Long> hashSet = new HashSet<>(wbsIds);
+                List<MeterLinkWbsInfoVO> vos = baseMapper.getAllLinkWbsInfo(contractId, hashSet);
+                //关联wbsId分组
+                wbsInfoVOMap = vos.stream().collect(Collectors.toMap(l -> l.getId(), l -> l));
+            }
+            //循环合同计量单元,过滤掉不符合要求的计量单元,
+            Iterator<MeterTreeContractVO2> iterator = voList.iterator();
+            //wbs拼接
+            StringBuilder str = new StringBuilder();
+            //计量单元id拼接
+            StringBuilder str2 = new StringBuilder();
+            //清单id拼接
+            StringBuilder str3 = new StringBuilder();
+            while (iterator.hasNext()){
+                MeterTreeContractVO2 vo2 = iterator.next();
+                //为混凝土节点,则去找寻附件
+                if (vo2.getIsConcreteNode() == 1) {
+                    List<Long> linkWbsIds = Func.toLongList(vo2.getLinkWbs());
+                    Boolean isApp = false;
+                    Integer strength = null;
+                    for (Long id : linkWbsIds) {
+                        MeterLinkWbsInfoVO vo = wbsInfoVOMap.get(id);
+                        if (vo.getAppStatus() != 2) {
+                            isApp = true;
+                            break;
+                        }
+                        if (vo.getMaxType() == 12) {
+                            strength = 28;
+                            break;
+                        }
+                        if (vo.getMaxType() == 11) {
+                            strength = 7;
+                        }
+                    }
+                    //审批不过通过,附件不存在7天或28天,直接过滤
+                    if (isApp || strength == null) {
+                        iterator.remove();
+                        continue;
+                    }
+                    //根据附件设置强度设置强度值
+                    if (strength == 7){
+                        vo2.setPayRatio(vo2.getSevenRatio());
+                    }else {
+                        vo2.setPayRatio(vo2.getTwentyEightRatio());
+                    }
+                }else {
+                    //不为混凝土节点,直接设置强度值为后管合同段默认
+                    vo2.setPayRatio(contractInfo.getMiddlePayRatio());
+                }
+                //末尾拼接所有WBS节点,所有计量节点
+                str.append(vo2.getLinkWbs()+",");
+                str2.append(vo2.getId());
+                str3.append(vo2.getLinkForm());
+
+            }
+            if (voList.size() == 0 || StringUtils.isBlank(str.toString()) || StringUtils.isBlank(str2.toString()) || StringUtils.isBlank(str3.toString())){
+                throw new ServiceException("当前没有符合要求的合同计量单元-2");
+            }
+            //根据拼接的所有WBS节点,去查询query表中的数据,然后转换为map,key为WBSId, 用于生成中间计量申请的附件。
+            List<Long> wbsIds = Func.toLongList((str.toString()));
+            HashSet<Long> hashSet = new HashSet<>(wbsIds);
+            List<WbsLinkQueryInfoVO> vos = baseMapper.getQueryInfo(contractId,hashSet);
+            Map<Long, WbsLinkQueryInfoVO> wbsMap = vos.stream().collect(Collectors.toMap(l -> l.getWbsId(), l -> l));
+            //根据拼接的所有计量节点,去查询清单与计量单元中间表数据(附带已经计量数),按计量节点id分组,用于生成中间计量申请的清单。
+            List<Long> meterIds = Func.toLongList((str2.toString()));
+            List<InventoryFormMeterVO> vos1 = baseMapper.getAllFormMeter(contractId,meterIds);
+            if (vos1.size() == 0){
+                throw new ServiceException("未找到关联的计量中间表信息");
+            }
+            Map<Long, List<InventoryFormMeterVO>> meterMap = vos1.stream().collect(Collectors.groupingBy(InventoryFormMeterVO::getContractMeterId));
+            //根据拼接的所有计量节点关联的表单id,查询表单数据,然后转换为map,key为表单id,用于生成中间计量申请的清单。
+            List<Long> formIds = Func.toLongList((str3.toString()));
+            HashSet<Long> hashSet2 = new HashSet<>(formIds);
+            List<ContractInventoryForm> vos2 = inventoryFormService.listByIds(hashSet2);
+            if (vos2.size() == 0){
+                throw new ServiceException("未找到关联的合同工程清单信息");
+            }
+            Map<Long, ContractInventoryForm> formMap = vos2.stream().collect(Collectors.toMap(l -> l.getId(), l -> l));
+
+            /*最终批量生成中间计量单,计量单与清单中间表,附件表*/
+            List<MiddleMeterApply> middleMeterApplyAdd = new ArrayList<>();
+            List<InventoryFormApply> inventoryFormApplyAdd = new ArrayList<>();
+            List<AttachmentForm> attachmentFormAdd = new ArrayList<>();
+            //获取当前计量期前缀
+            String prefix = this.getMeterNumberPrefix(contractId, periodId);
+            int count;
+            //查询出当前计量期所有未删除的计量单,如果不为空,则过滤出最大后缀
+            List<MiddleMeterApply> applyList = this.list(new LambdaQueryWrapper<MiddleMeterApply>()
+                    .eq(MiddleMeterApply::getContractId, contractId)
+                    .eq(MiddleMeterApply::getContractPeriodId, period));
+            //获取当前计量期所有已经计量的数量(),用于生成计量单编号
+            if (applyList.size() == 0){
+                count = 1;
+            }else {
+                Integer max = applyList.stream().map(l -> l.getMeterNumber()).map(l -> {
+                    String[] split = l.split("-");
+                    return Integer.parseInt(split[2]);
+                }).max(Integer::compareTo).orElse(0);
+                count = ++max;
+            }
+            //循环合同计量单元,获取中间表集合
+            for (MeterTreeContractVO2 vo2 : voList) {
+                //new中间计量单,并创建计量金额初始值,在下面循环中统计
+                MiddleMeterApply apply = new MiddleMeterApply();
+                Long middleId = SnowFlakeUtil.getId();
+                apply.setId(middleId);
+                BigDecimal total = BigDecimal.ZERO;
+                //循环中间表,取出计量单元中的比例,new中间表对象
+                List<InventoryFormMeterVO> formMeters = meterMap.get(vo2.getId());
+                if (formMeters == null || formMeters.size() == 0){
+                    throw new ServiceException("节点:("+vo2.getNodeName()+")未找到清单中间表信息");
+                }
+                //判断是否有需要计量的清单,如果没有则连中间计量单都不保存
+                int formTotal = 0;
+                for (InventoryFormMeterVO vo : formMeters) {
+                     /*
+                        变更后施工图数量 * 比例 = 最大可以计量的数量
+                        if 当前已经计量的数量 >= 最大可以计量的数量,则跳过
+                        else 最大施工图数量 - 已经计量数 = 当前期计量数
+                     */
+                    BigDecimal changeBuildPictureTotal = vo.getChangeBuildPictureTotal();
+                    if (changeBuildPictureTotal == null || changeBuildPictureTotal.compareTo(BigDecimal.ZERO) == 0){
+                        continue;
+                    }
+                    BigDecimal payRatio = vo2.getPayRatio();
+                    BigDecimal maxMeterTotal = changeBuildPictureTotal.multiply(payRatio).divide(new BigDecimal(100));
+                    if (vo.getAllMeterTotal().compareTo(maxMeterTotal) >= 0){
+                        continue;
+                    }
+                    //根据清单id获取清单信息
+                    ContractInventoryForm form = formMap.get(vo.getContractFormId());
+                    //生成中间计量与清单中间表数据
+                    InventoryFormApply inventoryFormApply = new InventoryFormApply();
+                    inventoryFormApply.setProjectId(projectId);
+                    inventoryFormApply.setContractId(contractId);
+                    inventoryFormApply.setMiddleMeterId(middleId);
+                    inventoryFormApply.setContractFormId(vo.getContractFormId());
+                    inventoryFormApply.setContractMeterId(vo.getContractMeterId());
+                    inventoryFormApply.setContractPeriodId(periodId);
+                    //表单基础信息
+                    inventoryFormApply.setFormNumber(form.getFormNumber());
+                    inventoryFormApply.setFormName(form.getFormName());
+                    inventoryFormApply.setCurrentPrice(form.getCurrentPrice());
+                    inventoryFormApply.setBuildPictureTotal(vo.getBuildPictureTotal());
+                    inventoryFormApply.setChangeBuildPictureTotal(vo.getChangeBuildPictureTotal());
+                    //计量信息
+                    inventoryFormApply.setCurrentMeterTotal(maxMeterTotal.subtract(vo.getAllMeterTotal()));
+                    inventoryFormApply.setCurrentMeterMoney(inventoryFormApply.getCurrentMeterTotal().multiply(inventoryFormApply.getCurrentPrice()));
+                    inventoryFormApply.setBusinessDate(period.getEndDate());
+                    total = total.add(inventoryFormApply.getCurrentMeterMoney());
+                    //加入计量单与清单中间表集合
+                    inventoryFormApplyAdd.add(inventoryFormApply);
+                    formTotal++;
+                }
+                if (formTotal == 0){
+                    continue;
+                }
+                //循环关联的wbsId,获取query数据
+                List<Long> longs = Func.toLongList(vo2.getLinkWbs());
+                for (Long aLong : longs) {
+                    //new 中间计量申请的附件,通过query数据填写信息
+                    WbsLinkQueryInfoVO vo = wbsMap.get(aLong);
+                    if (vo == null || StringUtils.isBlank(vo.getEVisaPdf())){
+                        throw new ServiceException("合同计量单元("+vo2.getNodeName()+")所关联的WBS节点id:"+aLong+"未找到电签PDF");
+                    }
+                    AttachmentForm form = new AttachmentForm();
+                    form.setProjectId(projectId);
+                    form.setContractId(contractId);
+                    form.setMasterId(middleId);
+                    form.setFileName(vo.getName());
+                    form.setFileUrl(vo.getEVisaPdf());
+                    form.setFilePdfUrl(vo.getEVisaPdf());
+                    form.setFileType(1);
+                    form.setSelectId(vo.getId());
+                    //添加到附件表
+                    attachmentFormAdd.add(form);
+                }
+                //设置中间计量申请属性
+                apply.setProjectId(projectId);
+                apply.setContractId(contractId);
+                apply.setContractUnitId(vo2.getId());
+                apply.setContractPeriodId(periodId);
+                apply.setPeriodNumber(period.getPeriodNumber());
+                //生成计量单编号
+                apply.setMeterNumber(prefix+count);
+                apply.setBusinessDate(period.getEndDate());
+                apply.setEngineerDivide(this.getNodeDivide(vo2.getId()));
+                apply.setMeterMoney(total);
+                apply.setCalculateFormula(vo2.getCalculateFormula());
+                apply.setIsLinkData(1);
+                //添加到计量单集合
+                middleMeterApplyAdd.add(apply);
+                count++;
+            }
+            /*执行保存*/
+            if (middleMeterApplyAdd.size() > 0){
+                this.saveBatch(middleMeterApplyAdd);
+            }
+            if (inventoryFormApplyAdd.size() > 0){
+                inventoryFormApplyService.saveBatch(inventoryFormApplyAdd);
+            }
+            if (attachmentFormAdd.size() > 0){
+                attachmentFormService.saveBatch(attachmentFormAdd);
+            }
+            return "共生成"+middleMeterApplyAdd.size()+"条计量单";
+        }catch (Exception e){
+            throw new ServiceException("自动生成失败:"+e.getMessage());
+        }
+        
+    }
+
+    /**
+     *  获取当前计量期计量单前缀
+     */
+    private String getMeterNumberPrefix(Long contractId,Long periodId){
+        StringBuilder str = new StringBuilder();
+        //获取合同信息
+        ContractInfo info = baseMapper.getContractInfo(contractId);
+        String contractNumber = info.getContractNumber();
+        if (StringUtils.isBlank(contractNumber)){
+            throw new ServiceException("未获取到当前合同段编号信息");
+        }
+        str.append(contractNumber+"-");
+        //获取计量期信息
+        ContractMeterPeriod contractMeterPeriod = contractMeterPeriodService.getById(periodId);
+        if (contractMeterPeriod == null || StringUtils.isBlank(contractMeterPeriod.getPeriodNumber())){
+            throw new ServiceException("未获取到计量期期号信息");
+        }
+        str.append(contractMeterPeriod.getPeriodNumber()+"-");
+        return str.toString();
+    }
+
     //递归方法
     private void gatherSortNode(List<NodeSortVO> list,List<Long> ids){
         for (NodeSortVO vo : list) {