diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/ding/task/EmployeeBatchGetTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/ding/task/EmployeeBatchGetTask.java index 947d3b3..be229f3 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/ding/task/EmployeeBatchGetTask.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/ding/task/EmployeeBatchGetTask.java @@ -44,6 +44,8 @@ public class EmployeeBatchGetTask { private final static Integer GROUP_SIZE = 100; + private final static Integer MAX_SIZE = 10000; + @Autowired private ZwddClient zwddClient; @@ -67,7 +69,7 @@ public class EmployeeBatchGetTask { if (CollUtil.isNotEmpty(dingOrganizationList)) { for (DingOrganization dingOrganization : dingOrganizationList) { if(!"GOV_UNIT".equals(dingOrganization.getTypeCode())){ - log.info("不是单位的 跳过 :{}",dingOrganization.getTypeCode()); + log.info("不是单位的 跳过 :{},{}",dingOrganization.getTypeCode(),dingOrganization.getOrganizationName()); continue; } List allOrganizationEmployeePositionList = new ArrayList<>(); @@ -84,6 +86,10 @@ public class EmployeeBatchGetTask { // 查询组织下 用户信息 GenericResult> firstPageGenericResult = zwddClient.pageOrganizationEmployeePositions(query); Page data = firstPageGenericResult.getData(); + if (Objects.isNull(data)){ + log.info("响应为空:{}",organizationCode); + continue; + } if (CollUtil.isNotEmpty(data.getData())) { allOrganizationEmployeePositionList.addAll(data.getData()); } @@ -91,18 +97,23 @@ public class EmployeeBatchGetTask { log.info("dingOrganization :{}", JSON.toJSONString(dingOrganization)); - log.info("totalSize :{}", totalSize); + log.info("totalSize :{},{}", totalSize,dingOrganization.getOrganizationName()); if (totalSize > PAGE_SIZE) { + if (totalSize > MAX_SIZE) { + //超过1万 按1万的处理 + totalSize = MAX_SIZE.longValue(); + } + int restPageNo = totalSize % PAGE_SIZE > 0 ? 1 : 0; int maxPageNo = (int) Math.ceil(totalSize / PAGE_SIZE) + restPageNo; for (pageNo = 2; pageNo <= maxPageNo; pageNo++) { query.setPageNo(pageNo); - log.info("PAGE_SIZE :{}", PAGE_SIZE); - log.info("PAGE_NO :{}", pageNo); GenericResult> pageGenericResult = zwddClient.pageOrganizationEmployeePositions(query); // log.info("pageGenericResult :{}", JSON.toJSONString(pageGenericResult)); - if (CollUtil.isNotEmpty(pageGenericResult.getData().getData())) { + if(pageGenericResult.isSuccess()){ allOrganizationEmployeePositionList.addAll(pageGenericResult.getData().getData()); + }else{ + log.error(pageGenericResult.getMsg()); } } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/FinalAcceptanceController.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/FinalAcceptanceController.java new file mode 100644 index 0000000..6eb4916 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/controller/FinalAcceptanceController.java @@ -0,0 +1,35 @@ +package com.ningdatech.pmapi.projectdeclared.controller; + +import com.ningdatech.basic.model.PageVo; +import com.ningdatech.pmapi.projectdeclared.manage.FinalAcceptanceManage; +import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; +import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + + +/** + * @Classname FinalAcceptanceController + * @Description 申报项目-终验 + * @Date 2023/6/2 09:29 + * @Author PoffyZhang + */ +@Slf4j +@Validated +@RestController +@RequestMapping("/api/v1/declared/final-acc") +@Api(value = "FinalAcceptanceController", tags = "申报管理-终验") +@RequiredArgsConstructor +public class FinalAcceptanceController { + private final FinalAcceptanceManage finalAcceptanceManage; + + @ApiOperation(value = "待终验申报的项目列表", notes = "待终验申报的项目列表") + @GetMapping("/project-list") + public PageVo projectlist(@ModelAttribute ProjectListReq req) { + return finalAcceptanceManage.projectLibList(req); + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/FinalAcceptanceManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/FinalAcceptanceManage.java new file mode 100644 index 0000000..bf271ee --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/manage/FinalAcceptanceManage.java @@ -0,0 +1,305 @@ +package com.ningdatech.pmapi.projectdeclared.manage; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.alibaba.excel.EasyExcel; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import com.ningdatech.basic.function.VUtils; +import com.ningdatech.basic.model.PageVo; +import com.ningdatech.basic.util.CollUtils; +import com.ningdatech.basic.util.NdDateUtils; +import com.ningdatech.pmapi.common.constant.BizConst; +import com.ningdatech.pmapi.common.helper.UserInfoHelper; +import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils; +import com.ningdatech.pmapi.common.util.ExcelDownUtil; +import com.ningdatech.pmapi.common.util.ExcelExportStyle; +import com.ningdatech.pmapi.projectdeclared.model.dto.ContractSaveDTO; +import com.ningdatech.pmapi.projectdeclared.model.dto.DeclaredProjectExportDTO; +import com.ningdatech.pmapi.projectdeclared.model.entity.Contract; +import com.ningdatech.pmapi.projectdeclared.model.entity.PaymentPlan; +import com.ningdatech.pmapi.projectdeclared.model.entity.Purchase; +import com.ningdatech.pmapi.projectdeclared.model.vo.ContractVO; +import com.ningdatech.pmapi.projectdeclared.model.vo.PaymentPlanVO; +import com.ningdatech.pmapi.projectdeclared.service.IContractService; +import com.ningdatech.pmapi.projectdeclared.service.IPaymentPlanService; +import com.ningdatech.pmapi.projectdeclared.service.IPreInsAcceptancePersonService; +import com.ningdatech.pmapi.projectdeclared.service.IPurchaseService; +import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; +import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum; +import com.ningdatech.pmapi.projectlib.helper.ProjectHelper; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq; +import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO; +import com.ningdatech.pmapi.projectlib.service.IProjectService; +import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; +import com.ningdatech.pmapi.user.util.LoginUserUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + * @Classname FinalAcceptanceManage + * @Description 终验 + * @Date 2023/6/2 14:48 + * @Author PoffyZhang + */ +@Component +@Slf4j +@RequiredArgsConstructor +public class FinalAcceptanceManage { + + private final IProjectService projectService; + private final UserInfoHelper userInfoHelper; + + private final IPurchaseService purchaseService; + + private final IContractService contractService; + + private final IPaymentPlanService paymentPlanService; + + private final IPreInsAcceptancePersonService acceptancePersonService; + + private final StateMachineUtils stateMachineUtils; + + /** + * 待采购的-项目列表 + * @param req + * @return + */ + public PageVo projectLibList(ProjectListReq req) { + UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); + VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); + LambdaQueryWrapper query = ProjectHelper.projectQuery(req); + //待终验 + query.eq(Project::getStatus,ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode()); + query.eq(Project::getStage,ProjectStatusEnum.PROJECT_APPROVED.getCode()); + query.eq(Project::getNewest,Boolean.TRUE); + query.isNotNull(Project::getApprovalDate); + query.isNotNull(Project::getBuildCycle); + query.orderByAsc(Project::getApprovalDate); + Page page = projectService.page(req.page(), query); + long total; + if ((total = page.getTotal()) == 0) { + return PageVo.empty(); + } + + List projectIds = page.getRecords().stream().map(Project::getId).collect(Collectors.toList()); + + List purchases = purchaseService.list(Wrappers.lambdaQuery(Purchase.class) + .in(Purchase::getProjectId, projectIds)); + Map purchaseMap = purchases.stream().collect(Collectors.toMap(Purchase::getProjectId, v -> v)); + + List records = CollUtils.convert(page.getRecords(), w -> { + ProjectLibListItemVO item = new ProjectLibListItemVO(); + item.setId(w.getId()); + item.setProjectName(w.getProjectName()); + item.setCreateOn(w.getCreateOn()); + item.setDeclaredAmount(w.getDeclareAmount()); + item.setStage(w.getStage()); + item.setStatus(w.getStatus()); + item.setProjectType(w.getProjectType()); + item.setProjectYear(w.getProjectYear()); + item.setBuildOrg(w.getBuildOrgName()); + item.setBizDomain(w.getBizDomain()); + item.setProcessStatus(w.getProcessStatus()); + item.setInstCode(w.getInstCode()); + item.setIsHigherSuperOrg(w.getIsHigherSuperOrg()); + item.setApprovedAmount(w.getApprovalAmount()); + item.setApprovalDate(w.getApprovalDate()); + if(purchaseMap.containsKey(w.getId())){ + Purchase purchase = purchaseMap.get(w.getId()); + item.setTransactionAmount(purchase.getTransactionAmount()); + item.setTransactionTime(purchase.getTransactionTime()); + } + item.setBuildCycle(StringUtils.isNotBlank(w.getBuildCycle()) ? + Integer.valueOf(w.getBuildCycle()) : null); + return item; + }); + return PageVo.of(records, total); + } + + public void exportList(HttpServletResponse response, ProjectListReq param) { + UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); + VUtils.isTrue(Objects.isNull(user)).throwMessage("获取登录用户失败!"); + LambdaQueryWrapper query = ProjectHelper.projectQuery(param); + //待终验 + query.eq(Project::getStatus,ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode()); + query.eq(Project::getStage,ProjectStatusEnum.PROJECT_APPROVED.getCode()); + query.eq(Project::getNewest,Boolean.TRUE); + query.isNotNull(Project::getApprovalDate); + query.isNotNull(Project::getBuildCycle); + query.orderByAsc(Project::getApprovalDate); + List records = projectService.list(query); + + AtomicInteger serialNumber = new AtomicInteger(0); + List collect = Lists.newArrayList(); + if(CollUtil.isNotEmpty(records)){ + List projectIds = records.stream().map(Project::getId).collect(Collectors.toList()); + + List purchases = purchaseService.list(Wrappers.lambdaQuery(Purchase.class) + .in(Purchase::getProjectId, projectIds)); + Map purchaseMap = purchases.stream().collect(Collectors.toMap(Purchase::getProjectId, v -> v)); + + collect = records.stream().map(r -> { + DeclaredProjectExportDTO exportDTO = new DeclaredProjectExportDTO(); + BeanUtils.copyProperties(r, exportDTO); + exportDTO.setProjectTypeName(ProjectTypeEnum.getDesc(r.getProjectType())); + exportDTO.setStatusName(ProjectStatusEnum.getDesc(r.getStatus())); + String createOnStr = NdDateUtils.format(r.getCreateOn(), "yyyy-MM-dd HH:mm"); + exportDTO.setCreateOn(createOnStr); + exportDTO.setSerialNumber(serialNumber.incrementAndGet()); + exportDTO.setPlanAcceptanceTime(convertPlanAcceptanceTime(r)); + return exportDTO; + }).collect(Collectors.toList()); + } + + String fileName = "待终验申请项目列表"; + ExcelDownUtil.setFileName(fileName,response); + //数据导出处理函数 + try { + EasyExcel.write(response.getOutputStream(), DeclaredProjectExportDTO.class) + .autoCloseStream(false) + .registerWriteHandler(ExcelExportStyle.formalStyle()) + .sheet(fileName) + .doWrite(collect); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private String convertPlanAcceptanceTime(Project project) { + if (Objects.nonNull(project.getApprovalDate()) && StringUtils.isNotBlank(project.getBuildCycle())) { + Integer buidCycle = Integer.valueOf(project.getBuildCycle()); + return NdDateUtils.format(project.getApprovalDate().plusMonths(buidCycle), "yyyy-MM-dd HH:mm"); + } + return StringUtils.EMPTY; + } + + /** + * 获取合同备案详情 + * @param projectId + * @return + */ + public ContractVO detailContractByProjectId(Long projectId) { + Contract contract = contractService.getOne(Wrappers.lambdaQuery(Contract.class) + .eq(Contract::getProjectId, projectId) + .last(BizConst.LIMIT_1)); + + ContractVO vo = BeanUtil.copyProperties(contract, ContractVO.class); + + List payments = paymentPlanService.list(Wrappers.lambdaQuery(PaymentPlan.class) + .eq(PaymentPlan::getProjectId, projectId) + .orderByAsc(PaymentPlan::getPaymentTime)); + + if(CollUtil.isNotEmpty(payments)){ + vo.setPayments(convertPayments(payments,contract.getTotalAmount())); + } + + return vo; + } + + private List convertPayments(List payments,BigDecimal totalAmount) { + if(CollUtil.isEmpty(payments)){ + return Collections.emptyList(); + } + return payments.stream().map(p -> { + PaymentPlanVO vo = BeanUtil.copyProperties(p, PaymentPlanVO.class); + vo.setRatio((Objects.isNull(totalAmount)||totalAmount.compareTo(BigDecimal.ZERO) == 0) ? "0%" + : p.getPaymentAmount().multiply(BigDecimal.valueOf(100)) + .divide(totalAmount,BigDecimal.ROUND_CEILING,BigDecimal.ROUND_CEILING) + "%"); + return vo; + }) + .collect(Collectors.toList()); + } + + /** + * 填写合同信息 + * @param dto + * @return + */ + public String submitContract(ContractSaveDTO dto) { + UserFullInfoDTO user = userInfoHelper.getUserFullInfo(LoginUserUtil.getUserId()); + String employeeCode = user.getEmployeeCode(); + VUtils.isTrue(StringUtils.isBlank(employeeCode)).throwMessage("获取登录用户 员工号 失败!"); + + Long projectId = dto.getProjectId(); + VUtils.isTrue(Objects.isNull(projectId)).throwMessage("提交失败 缺少项目ID!"); + Project project = projectService.getNewProject(dto.getProjectId()); + VUtils.isTrue(Objects.isNull(project)).throwMessage("提交失败 此项目不存在!"); + + //首先要判断 项目当前状态 是不是 采购结果备案 + VUtils.isTrue(!ProjectStatusEnum.UNDER_CONSTRUCTION.getCode().equals(project.getStatus()) || + !ProjectStatusEnum.PROJECT_APPROVED.getCode().equals(project.getStage())) + .throwMessage("提交失败 该项目不是 建设中或者已立项阶段"); + + Contract contractEntity = new Contract(); + Contract contract = contractService.getOne(Wrappers.lambdaQuery(Contract.class) + .eq(Contract::getProjectId, projectId) + .last(BizConst.LIMIT_1)); + + BeanUtil.copyProperties(dto,contractEntity); + if(Objects.isNull(contract)){ + contractEntity.setCreateOn(LocalDateTime.now()); + contractEntity.setCreateBy(employeeCode); + }else{ + contractEntity.setId(contract.getId()); + } + contractEntity.setProjectId(projectId); + if(contractService.saveOrUpdate(contractEntity)){ + //存 付款计划信心 + if(Objects.nonNull(dto.getPayments())){ + //先删除 + paymentPlanService.remove(Wrappers.lambdaQuery(PaymentPlan.class) + .eq(PaymentPlan::getProjectId,projectId)); + if(CollUtil.isNotEmpty(dto.getPayments())){ + List payments = dto.getPayments().stream().map(d -> { + PaymentPlan plan = BeanUtil.copyProperties(d, PaymentPlan.class); + plan.setProjectId(projectId); + plan.setCreateOn(LocalDateTime.now()); + plan.setUpdateOn(LocalDateTime.now()); + plan.setCreateBy(employeeCode); + plan.setUpdateBy(employeeCode); + return plan; + }).collect(Collectors.toList()); + + paymentPlanService.saveBatch(payments); + } + } + } + + //判断下 如果和初验都完成了 才进入下一阶段 + if(StringUtils.isNotBlank(project.getPreliminaryInspectionMaterials())){ + //进入到下一状态 + stateMachineUtils.pass(project); + } + project.setUpdateOn(LocalDateTime.now()); + if(Objects.nonNull(dto.getDeliveryTime())){ + project.setDeliveryTime(dto.getDeliveryTime()); + } + if(Objects.nonNull(dto.getTotalAmount())){ + project.setContractAmount(dto.getTotalAmount()); + } + projectService.updateById(project); + + return "填写成功"; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/model/dto/DeclaredProjectExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/model/dto/DeclaredProjectExportDTO.java index b1ca87c..5c021c4 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/model/dto/DeclaredProjectExportDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectdeclared/model/dto/DeclaredProjectExportDTO.java @@ -1,6 +1,7 @@ package com.ningdatech.pmapi.projectdeclared.model.dto; import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -62,4 +63,7 @@ public class DeclaredProjectExportDTO { @ExcelProperty("年度预算") private BigDecimal annualPlanAmount; + + @ExcelProperty("计划验收时间") + private String planAcceptanceTime; } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/vo/ProjectLibListItemVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/vo/ProjectLibListItemVO.java index 9a3fb15..f734ddb 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/vo/ProjectLibListItemVO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/vo/ProjectLibListItemVO.java @@ -100,6 +100,19 @@ public class ProjectLibListItemVO { @ApiModelProperty("年度支付计划-年度支付计划(元)") private BigDecimal annualPlanAmount; + @ApiModelProperty("建设周期 月") + private Integer buildCycle; + + @ApiModelProperty("计划验收时间") + private LocalDate planAcceptanceTime; + + public LocalDate getPlanAcceptanceTime(){ + if (Objects.nonNull(this.approvalDate) && Objects.nonNull(this.buildCycle)) { + planAcceptanceTime = this.approvalDate.plusMonths(buildCycle); + } + return null; + } + public String getProjectTypeName() { if (Objects.nonNull(this.projectType)) { Optional.ofNullable(ProjectTypeEnum.getDesc(this.projectType))