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