1.1.57 订单的发货、开票、采购、回款状态完成时更新。

dev
yinq 4 weeks ago
parent 081119f5ef
commit 74080946e3

@ -14,6 +14,7 @@
<module>ruoyi-api-resource</module>
<module>ruoyi-api-workflow</module>
<module>ruoyi-api-wms</module>
<module>ruoyi-api-oa</module>
</modules>
<artifactId>ruoyi-api</artifactId>

@ -48,6 +48,13 @@
<version>${revision}</version>
</dependency>
<!-- oa接口 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-oa</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-api-oa</artifactId>
<description>
ruoyi-api-oa OA接口模块
</description>
<dependencies>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-core</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,19 @@
package org.dromara.oa.api;
/**
*
*
* @author Codex
*/
public interface RemoteErpContractOrderService {
/**
*
*
* @param contractId ID///
* @param projectId ID contractId 使
* @param statusType purchase / delivery / invoice / payment {@link org.dromara.oa.api.enums.ContractOrderStatusTypeEnum}
*/
void refreshContractOrderStatus(Long contractId, Long projectId, String statusType);
}

@ -17,4 +17,12 @@ public interface RemoteWmsShippingBillService {
*/
Long createDraftByProject(RemoteWmsShippingDraft draft);
/**
* is_all_receiving
*
* @param contractId ID
* @return 1 2 3
*/
String resolveOrderDeliveryStatusByContractId(Long contractId);
}

@ -110,6 +110,11 @@
<artifactId>ruoyi-api-wms</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-oa</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-bus</artifactId>

@ -0,0 +1,26 @@
package org.dromara.oa.dubbo;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.oa.api.RemoteErpContractOrderService;
import org.dromara.oa.erp.service.IErpContractOrderService;
import org.springframework.stereotype.Service;
/**
*
*
* @author Codex
*/
@RequiredArgsConstructor
@Service
@DubboService
public class RemoteErpContractOrderServiceImpl implements RemoteErpContractOrderService {
private final IErpContractOrderService erpContractOrderService;
@Override
public void refreshContractOrderStatus(Long contractId, Long projectId, String statusType) {
erpContractOrderService.refreshContractOrderStatus(contractId, projectId, statusType);
}
}

@ -80,5 +80,22 @@ public interface IErpContractOrderService {
* @return
*/
ErpProjectInfoVo submitContractOrderAndFlowStart(ErpProjectInfoBo bo);
/**
* ///
*
* @param contractId ID
* @param projectId ID
* @param statusType purchase / delivery / invoice / payment
*/
void refreshContractOrderStatus(Long contractId, Long projectId, String statusType);
/**
* IDID
*
* @param projectId ID
* @return ID
*/
Long resolveContractIdByProjectId(Long projectId);
}

@ -112,4 +112,18 @@ public interface IErpProjectPlanService {
*/
void syncCollectionStageFromInstallmentDetail(Long contractId, Long projectId, Long paymentStageId,
Date receivableDate);
/**
* order_payment_rate
*
* @param contractId ID
*/
void refreshContractOrderPaymentRateByContractId(Long contractId);
/**
*
*
* @param projectId ID
*/
void refreshContractOrderPaymentRateByProjectId(Long projectId);
}

@ -2,6 +2,7 @@ package org.dromara.oa.erp.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.seata.spring.annotation.GlobalTransactional;
@ -12,8 +13,13 @@ import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.oa.api.constant.OrderInvoiceStatusConstant;
import org.dromara.oa.api.constant.OrderPurchaseStatusConstant;
import org.dromara.oa.api.enums.ContractOrderStatusTypeEnum;
import org.dromara.oa.erp.domain.ErpContractInfo;
import org.dromara.oa.erp.domain.ErpFinInvoiceInfo;
import org.dromara.oa.erp.domain.ErpProjectInfo;
import org.dromara.oa.erp.domain.ErpProjectPurchase;
import org.dromara.oa.erp.domain.ErpProjectContracts;
import org.dromara.oa.erp.domain.ErpProjectPlan;
import org.dromara.oa.erp.domain.ErpProjectPlanStage;
@ -25,8 +31,10 @@ import org.dromara.oa.erp.domain.vo.ErpContractOrderPurchaseMaterialVo;
import org.dromara.oa.erp.domain.vo.ErpProjectInfoVo;
import org.dromara.oa.erp.mapper.ErpContractInfoMapper;
import org.dromara.oa.erp.mapper.ErpContractMaterialMapper;
import org.dromara.oa.erp.mapper.ErpFinInvoiceInfoMapper;
import org.dromara.oa.erp.mapper.ErpProjectInfoMapper;
import org.dromara.oa.erp.mapper.ErpProjectContractsMapper;
import org.dromara.oa.erp.mapper.ErpProjectPurchaseMapper;
import org.dromara.oa.erp.mapper.ErpProjectPlanMapper;
import org.dromara.oa.erp.mapper.ErpProjectPlanStageMapper;
import org.dromara.oa.crm.domain.vo.CrmCustomerInfoVo;
@ -35,6 +43,7 @@ import org.dromara.oa.erp.service.IErpContractChangeService;
import org.dromara.oa.erp.service.IErpContractOrderService;
import org.dromara.oa.erp.service.IErpProjectContractsService;
import org.dromara.oa.erp.service.IErpProjectInfoService;
import org.dromara.oa.erp.service.IErpProjectPlanService;
import org.dromara.oa.erp.service.IErpProjectTypeService;
import org.dromara.oa.erp.domain.vo.ErpProjectTypeVo;
import org.dromara.oa.erp.constant.ProjectCategoryConstant;
@ -44,6 +53,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.dromara.system.api.RemoteCodeRuleService;
import org.dromara.wms.api.RemoteWmsShippingBillService;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
@ -52,6 +62,7 @@ import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.apache.dubbo.config.annotation.DubboReference;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -79,9 +90,12 @@ public class ErpContractOrderServiceImpl implements IErpContractOrderService {
private final ErpContractInfoMapper contractInfoMapper;
private final ErpContractMaterialMapper contractMaterialMapper;
private final ErpProjectContractsMapper projectContractsMapper;
private final ErpProjectPurchaseMapper projectPurchaseMapper;
private final ErpFinInvoiceInfoMapper finInvoiceInfoMapper;
private final IErpProjectContractsService projectContractsService;
private final IErpContractChangeService erpContractChangeService;
private final IErpProjectPlanService erpProjectPlanService;
private final IErpProjectInfoService projectInfoService;
private final IErpProjectTypeService projectTypeService;
private final ICrmCustomerInfoService crmCustomerInfoService;
@ -97,6 +111,9 @@ public class ErpContractOrderServiceImpl implements IErpContractOrderService {
@DubboReference(timeout = 30000)
private RemoteCodeRuleService remoteCodeRuleService;
@DubboReference(timeout = 30000)
private RemoteWmsShippingBillService remoteWmsShippingBillService;
/**
*
*
@ -659,6 +676,263 @@ public class ErpContractOrderServiceImpl implements IErpContractOrderService {
}
}
/**
* ///
*/
@Override
public void refreshContractOrderStatus(Long contractId, Long projectId, String statusType) {
ContractOrderStatusTypeEnum type = ContractOrderStatusTypeEnum.getByCode(statusType);
if (type == null) {
log.warn("不支持的合同订单状态类型: {}", statusType);
return;
}
switch (type) {
case PAYMENT -> erpProjectPlanService.refreshContractOrderPaymentRateByContractId(contractId);
case DELIVERY -> refreshDeliveryStatus(contractId);
case PURCHASE -> refreshPurchaseStatus(contractId);
case INVOICE -> refreshInvoiceStatus(contractId);
default -> log.warn("未处理的状态类型: {}", statusType);
}
}
private void refreshDeliveryStatus(Long contractId) {
if (contractId == null) {
return;
}
String deliveryStatus = remoteWmsShippingBillService.resolveOrderDeliveryStatusByContractId(contractId);
updateContractOrdersField(contractId, deliveryStatus, ContractOrderStatusTypeEnum.DELIVERY);
}
private void refreshInvoiceStatus(Long contractId) {
if (contractId == null) {
return;
}
String invoiceStatus = resolveInvoiceStatus(contractId);
updateContractOrdersField(contractId, invoiceStatus, ContractOrderStatusTypeEnum.INVOICE);
}
private void refreshPurchaseStatus(Long contractId) {
if (contractId == null) {
return;
}
List<ErpProjectInfo> contractOrders = listContractOrdersByContractId(contractId);
if (CollUtil.isEmpty(contractOrders)) {
log.warn("未找到合同订单contractId={}", contractId);
return;
}
for (ErpProjectInfo contractOrder : contractOrders) {
String purchaseStatus = resolvePurchaseStatus(contractOrder);
if (Objects.equals(purchaseStatus, contractOrder.getOrderPurchaseStatus())) {
continue;
}
ErpProjectInfo update = new ErpProjectInfo();
update.setProjectId(contractOrder.getProjectId());
update.setOrderPurchaseStatus(purchaseStatus);
projectInfoMapper.updateById(update);
}
}
private void updateContractOrdersField(Long contractId, String statusValue, ContractOrderStatusTypeEnum type) {
List<ErpProjectInfo> contractOrders = listContractOrdersByContractId(contractId);
if (CollUtil.isEmpty(contractOrders)) {
log.warn("未找到合同订单contractId={}", contractId);
return;
}
for (ErpProjectInfo contractOrder : contractOrders) {
String current = switch (type) {
case DELIVERY -> contractOrder.getOrderDeliveryStatus();
case INVOICE -> contractOrder.getOrderInvoiceStatus();
default -> null;
};
if (Objects.equals(statusValue, current)) {
continue;
}
ErpProjectInfo update = new ErpProjectInfo();
update.setProjectId(contractOrder.getProjectId());
switch (type) {
case DELIVERY -> update.setOrderDeliveryStatus(statusValue);
case INVOICE -> update.setOrderInvoiceStatus(statusValue);
default -> {
}
}
projectInfoMapper.updateById(update);
}
}
private List<ErpProjectInfo> listContractOrdersByContractId(Long contractId) {
return projectInfoMapper.selectList(Wrappers.<ErpProjectInfo>lambdaQuery()
.eq(ErpProjectInfo::getContractId, contractId)
.eq(ErpProjectInfo::getProjectCategory, ProjectCategoryConstant.CONTRACT_ORDER)
.eq(ErpProjectInfo::getDelFlag, "0"));
}
/**
*
*/
private String resolveInvoiceStatus(Long contractId) {
List<ErpFinInvoiceInfo> invoices = finInvoiceInfoMapper.selectList(Wrappers.<ErpFinInvoiceInfo>lambdaQuery()
.eq(ErpFinInvoiceInfo::getContractId, contractId)
.eq(ErpFinInvoiceInfo::getDelFlag, "0"));
if (CollUtil.isEmpty(invoices)) {
return OrderInvoiceStatusConstant.NOT_INVOICED;
}
boolean hasCompleted = false;
boolean hasInProgress = false;
BigDecimal completedAmount = BigDecimal.ZERO;
for (ErpFinInvoiceInfo invoice : invoices) {
if (OAStatusEnum.APPROVING.getStatus().equals(invoice.getInvoiceStatus())
|| BusinessStatusEnum.WAITING.getStatus().equals(invoice.getFlowStatus())) {
hasInProgress = true;
}
if (OAStatusEnum.COMPLETED.getStatus().equals(invoice.getInvoiceStatus())) {
hasCompleted = true;
if (invoice.getIssueAmount() != null) {
completedAmount = completedAmount.add(invoice.getIssueAmount());
}
}
}
if (!hasCompleted) {
return hasInProgress ? OrderInvoiceStatusConstant.PARTIAL_INVOICED : OrderInvoiceStatusConstant.NOT_INVOICED;
}
BigDecimal contractAmount = resolveContractAmount(contractId);
if (contractAmount.compareTo(BigDecimal.ZERO) <= 0 || completedAmount.compareTo(contractAmount) >= 0) {
return OrderInvoiceStatusConstant.INVOICED;
}
return OrderInvoiceStatusConstant.PARTIAL_INVOICED;
}
/**
*
*/
private String resolvePurchaseStatus(ErpProjectInfo contractOrder) {
Long bizProjectId = resolvePurchaseBizProjectId(contractOrder);
if (bizProjectId == null) {
return OrderPurchaseStatusConstant.NOT_PURCHASED;
}
Long contractId = contractOrder.getContractId();
if (hasPurchasingInProgress(bizProjectId, contractId)) {
return OrderPurchaseStatusConstant.PURCHASING;
}
List<ErpContractOrderPurchaseMaterialVo> materials = queryPurchaseMaterialList(bizProjectId);
if (CollUtil.isEmpty(materials)) {
return OrderPurchaseStatusConstant.NOT_PURCHASED;
}
boolean hasPurchased = false;
boolean allPurchased = true;
boolean hasRequiredMaterial = false;
for (ErpContractOrderPurchaseMaterialVo material : materials) {
if (contractId != null && material.getContractId() != null
&& !Objects.equals(contractId, material.getContractId())) {
continue;
}
BigDecimal contractAmount = material.getContractAmount() == null ? BigDecimal.ZERO : material.getContractAmount();
if (contractAmount.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
hasRequiredMaterial = true;
BigDecimal purchasedAmount = material.getPurchasedAmount() == null ? BigDecimal.ZERO : material.getPurchasedAmount();
if (purchasedAmount.compareTo(BigDecimal.ZERO) > 0) {
hasPurchased = true;
}
BigDecimal unpurchased = material.getUnpurchasedAmount() == null ? BigDecimal.ZERO : material.getUnpurchasedAmount();
if (unpurchased.compareTo(BigDecimal.ZERO) > 0) {
allPurchased = false;
}
}
if (!hasRequiredMaterial || !hasPurchased) {
return OrderPurchaseStatusConstant.NOT_PURCHASED;
}
if (allPurchased) {
return OrderPurchaseStatusConstant.PURCHASED;
}
return OrderPurchaseStatusConstant.PARTIAL_PURCHASED;
}
private boolean hasPurchasingInProgress(Long bizProjectId, Long contractId) {
LambdaQueryWrapper<ErpProjectPurchase> lqw = Wrappers.<ErpProjectPurchase>lambdaQuery()
.eq(ErpProjectPurchase::getProjectId, bizProjectId)
.eq(ErpProjectPurchase::getDelFlag, "0")
.and(w -> w.eq(ErpProjectPurchase::getProjectPurchaseStatus, OAStatusEnum.APPROVING.getStatus())
.or()
.eq(ErpProjectPurchase::getFlowStatus, BusinessStatusEnum.WAITING.getStatus()));
if (contractId != null) {
lqw.eq(ErpProjectPurchase::getRelationId, contractId);
}
return projectPurchaseMapper.selectCount(lqw) > 0;
}
/**
* ID
*/
private Long resolvePurchaseBizProjectId(ErpProjectInfo contractOrder) {
if (contractOrder == null) {
return null;
}
if (!ProjectCategoryConstant.CONTRACT_ORDER.equals(contractOrder.getProjectCategory())) {
return contractOrder.getProjectId();
}
if (contractOrder.getParentProjectId() != null) {
return contractOrder.getParentProjectId();
}
Long contractId = contractOrder.getContractId();
if (contractId == null) {
return null;
}
List<ErpProjectContracts> relations = projectContractsMapper.selectList(Wrappers.<ErpProjectContracts>lambdaQuery()
.eq(ErpProjectContracts::getContractId, contractId)
.eq(ErpProjectContracts::getDelFlag, "0")
.orderByAsc(ErpProjectContracts::getSortOrder)
.orderByAsc(ErpProjectContracts::getProjectContractsId));
if (CollUtil.isEmpty(relations)) {
return null;
}
Set<Long> projectIds = relations.stream()
.map(ErpProjectContracts::getProjectId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (CollUtil.isEmpty(projectIds)) {
return null;
}
List<ErpProjectInfo> projects = projectInfoMapper.selectList(Wrappers.<ErpProjectInfo>lambdaQuery()
.in(ErpProjectInfo::getProjectId, projectIds)
.ne(ErpProjectInfo::getProjectCategory, ProjectCategoryConstant.CONTRACT_ORDER)
.eq(ErpProjectInfo::getDelFlag, "0")
.last("limit 1"));
return CollUtil.isEmpty(projects) ? null : projects.get(0).getProjectId();
}
private BigDecimal resolveContractAmount(Long contractId) {
ErpContractInfo contractInfo = contractInfoMapper.selectById(contractId);
if (contractInfo != null && contractInfo.getTotalPrice() != null
&& contractInfo.getTotalPrice().compareTo(BigDecimal.ZERO) > 0) {
return contractInfo.getTotalPrice();
}
List<ErpProjectInfo> orders = listContractOrdersByContractId(contractId);
return orders.stream()
.map(ErpProjectInfo::getAmount)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
@Override
public Long resolveContractIdByProjectId(Long projectId) {
if (projectId == null) {
return null;
}
ErpProjectInfo project = projectInfoMapper.selectById(projectId);
if (project == null || !"0".equals(project.getDelFlag())) {
return null;
}
if (project.getContractId() != null) {
return project.getContractId();
}
ErpProjectContracts relation = projectContractsMapper.selectOne(Wrappers.<ErpProjectContracts>lambdaQuery()
.eq(ErpProjectContracts::getProjectId, projectId)
.eq(ErpProjectContracts::getDelFlag, "0")
.last("limit 1"), false);
return relation == null ? null : relation.getContractId();
}
/**
* (: 稿退)
*

@ -25,6 +25,7 @@ import org.dromara.oa.erp.domain.vo.ErpFinAccountInstallmentVo;
import org.dromara.oa.erp.mapper.ErpFinAccountInstallmentDetailMapper;
import org.dromara.oa.erp.mapper.ErpFinAccountInstallmentMapper;
import org.dromara.oa.erp.service.IErpFinAccountInstallmentService;
import org.dromara.oa.erp.service.IErpProjectPlanService;
import org.dromara.system.api.RemoteCodeRuleService;
import org.dromara.system.api.RemoteUserService;
import org.dromara.workflow.api.RemoteWorkflowService;
@ -44,6 +45,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@ -68,6 +70,8 @@ public class ErpFinAccountInstallmentServiceImpl implements IErpFinAccountInstal
private final ErpFinAccountInstallmentMapper baseMapper;
private final ErpFinAccountInstallmentDetailMapper detailMapper;
private final IErpProjectPlanService erpProjectPlanService;
@DubboReference(timeout = 30000)
private RemoteCodeRuleService remoteCodeRuleService;
@ -432,9 +436,32 @@ public class ErpFinAccountInstallmentServiceImpl implements IErpFinAccountInstal
update.setAccountInstallmentId(installmentId);
applyInstallmentStatusByFlowStatus(update, processEvent.getStatus());
baseMapper.updateById(update);
if (BusinessStatusEnum.FINISH.getStatus().equals(processEvent.getStatus())) {
refreshContractOrderPaymentStatus(installmentId);
}
});
}
private void refreshContractOrderPaymentStatus(Long installmentId) {
List<ErpFinAccountInstallmentDetail> details = detailMapper.selectList(Wrappers.<ErpFinAccountInstallmentDetail>lambdaQuery()
.eq(ErpFinAccountInstallmentDetail::getAccountInstallmentId, installmentId)
.eq(ErpFinAccountInstallmentDetail::getDelFlag, "0"));
if (CollUtil.isEmpty(details)) {
return;
}
details.stream()
.map(ErpFinAccountInstallmentDetail::getContractId)
.filter(Objects::nonNull)
.distinct()
.forEach(contractId -> {
try {
erpProjectPlanService.refreshContractOrderPaymentRateByContractId(contractId);
} catch (Exception e) {
log.error("刷新合同订单回款比例失败contractId={}", contractId, e);
}
});
}
/**
* flow_statusinstallment_status
*

@ -1,5 +1,6 @@
package org.dromara.oa.erp.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -421,6 +422,39 @@ public class ErpProjectPlanServiceImpl implements IErpProjectPlanService {
return updated;
}
@Override
public void refreshContractOrderPaymentRateByContractId(Long contractId) {
if (contractId == null) {
return;
}
List<ErpProjectInfo> contractOrders = projectInfoMapper.selectList(Wrappers.<ErpProjectInfo>lambdaQuery()
.eq(ErpProjectInfo::getContractId, contractId)
.eq(ErpProjectInfo::getProjectCategory, ProjectCategoryConstant.CONTRACT_ORDER)
.eq(ErpProjectInfo::getDelFlag, "0"));
if (CollUtil.isEmpty(contractOrders)) {
return;
}
for (ErpProjectInfo contractOrder : contractOrders) {
refreshContractOrderPaymentRateByProjectId(contractOrder.getProjectId());
}
}
@Override
public void refreshContractOrderPaymentRateByProjectId(Long projectId) {
if (projectId == null) {
return;
}
ErpProjectPlan plan = baseMapper.selectOne(Wrappers.<ErpProjectPlan>lambdaQuery()
.eq(ErpProjectPlan::getProjectId, projectId)
.eq(ErpProjectPlan::getDelFlag, "0")
.orderByDesc(ErpProjectPlan::getCreateTime)
.last("limit 1"), false);
if (plan == null) {
return;
}
refreshContractOrderPaymentRate(plan.getProjectPlanId(), projectId);
}
/**
* actual_repayment_rate(%) erp_project_info.order_payment_rate
*/

@ -26,6 +26,8 @@ import org.dromara.oa.erp.domain.vo.ErpProjectPurchaseVo;
import org.dromara.oa.erp.domain.vo.ErpProjectPurchaseMaterialVo;
import org.dromara.oa.erp.mapper.ErpProjectPurchaseMapper;
import org.dromara.oa.erp.mapper.ErpProjectPurchaseMaterialMapper;
import org.dromara.oa.api.enums.ContractOrderStatusTypeEnum;
import org.dromara.oa.erp.service.IErpContractOrderService;
import org.dromara.oa.erp.service.IErpProjectPurchaseService;
import org.dromara.system.api.RemoteCodeRuleService;
import org.dromara.workflow.api.RemoteWorkflowService;
@ -67,6 +69,8 @@ public class ErpProjectPurchaseServiceImpl implements IErpProjectPurchaseService
private final ErpProjectPurchaseMaterialMapper purchaseMaterialMapper;
private final IErpContractOrderService erpContractOrderService;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
@ -557,6 +561,17 @@ public class ErpProjectPurchaseServiceImpl implements IErpProjectPurchaseService
purchase.setProjectPurchaseStatus(OAStatusEnum.DRAFT.getStatus());
}
baseMapper.updateById(purchase);
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
Long contractId = erpContractOrderService.resolveContractIdByProjectId(purchase.getProjectId());
if (contractId != null) {
try {
erpContractOrderService.refreshContractOrderStatus(
contractId, null, ContractOrderStatusTypeEnum.PURCHASE.getCode());
} catch (Exception e) {
log.error("刷新合同订单采购状态失败contractId={}", contractId, e);
}
}
}
});
}
}

@ -3,16 +3,23 @@ package org.dromara.oa.workflow.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.oa.api.enums.ContractOrderStatusTypeEnum;
import org.dromara.oa.erp.domain.ErpFinInvoiceInfo;
import org.dromara.oa.erp.mapper.ErpFinInvoiceInfoMapper;
import org.dromara.oa.erp.mapper.OaUniversalMapper;
import org.dromara.oa.erp.service.IErpContractOrderService;
import org.dromara.workflow.api.event.ProcessEvent;
import org.dromara.workflow.enums.FlowConfigEnum;
import org.dromara.workflow.event.AbstractProcessEventHandler;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.convert.Convert;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* @Author xins
@ -24,6 +31,8 @@ import java.util.Map;
@RequiredArgsConstructor
public class OaProcessEventHandler extends AbstractProcessEventHandler {
private final OaUniversalMapper oaUniversalMapper;
private final ErpFinInvoiceInfoMapper finInvoiceInfoMapper;
private final IErpContractOrderService erpContractOrderService;
@EventListener(condition = "#processEvent.flowCode.startsWith('HWOA')")
@Transactional(rollbackFor = Exception.class)
@ -42,7 +51,24 @@ public class OaProcessEventHandler extends AbstractProcessEventHandler {
int updateCount = handleProcessEvent(processEvent);
if (updateCount > 0
&& Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())
&& FlowConfigEnum.INVOICE.getFlowCode().equals(flowCode)) {
refreshContractOrderInvoiceStatus(processEvent);
}
}
private void refreshContractOrderInvoiceStatus(ProcessEvent processEvent) {
ErpFinInvoiceInfo invoice = finInvoiceInfoMapper.selectById(Convert.toLong(processEvent.getBusinessId()));
if (invoice == null || invoice.getContractId() == null) {
return;
}
try {
erpContractOrderService.refreshContractOrderStatus(
invoice.getContractId(), null, ContractOrderStatusTypeEnum.INVOICE.getCode());
} catch (Exception e) {
log.error("刷新合同订单开票状态失败contractId={}", invoice.getContractId(), e);
}
}
@Override

@ -109,6 +109,11 @@
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-wms</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-oa</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-bus</artifactId>

@ -7,6 +7,7 @@ import org.dromara.wms.api.domain.RemoteWmsShippingDraft;
import org.dromara.wms.service.IWmsShippingBillService;
import org.springframework.stereotype.Service;
/**
*
*
@ -28,4 +29,9 @@ public class RemoteWmsShippingBillServiceImpl implements RemoteWmsShippingBillSe
return 1L;
}
@Override
public String resolveOrderDeliveryStatusByContractId(Long contractId) {
return wmsShippingBillService.resolveOrderDeliveryStatusByContractId(contractId);
}
}

@ -84,6 +84,14 @@ public interface IWmsShippingBillService {
*/
Map<String, Object> buildWordExportData(Long shippingBillId);
/**
* is_all_receiving
*
* @param contractId ID
* @return 1 2 3
*/
String resolveOrderDeliveryStatusByContractId(Long contractId);
// /**
// * 根据项目快照创建发货草稿

@ -13,6 +13,9 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.oa.api.RemoteErpContractOrderService;
import org.dromara.oa.api.constant.OrderDeliveryStatusConstant;
import org.dromara.oa.api.enums.ContractOrderStatusTypeEnum;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.enums.OAStatusEnum;
import org.dromara.common.core.exception.ServiceException;
@ -65,6 +68,8 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService {
private RemoteWorkflowService remoteWorkflowService;
@DubboReference(timeout = 30000)
private RemoteCodeRuleService remoteCodeRuleService;
@DubboReference(timeout = 30000)
private RemoteErpContractOrderService remoteErpContractOrderService;
/**
*
@ -410,9 +415,7 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService {
public WmsShippingBillVo shippingBillSubmitAndFlowStart(WmsShippingBillBo bo) {
// 根据发货类型决定是否需要到货确认1=普通发货需确认2=备件/3=物流不需确认
String shippingType = bo.getShippingType();
boolean needConfirm = !"2".equals(shippingType) && !"3".equals(shippingType);
bo.setNeedArrivalConfirm(needConfirm ? "1" : "0");
bo.setNeedArrivalConfirm("1");
WmsShippingBill add = MapstructUtils.convert(bo, WmsShippingBill.class);
validEntityBeforeSave(add);
if (StringUtils.isNull(bo.getShippingBillId())) {
@ -426,14 +429,8 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService {
variables.put("shippingType", StringUtils.defaultIfBlank(shippingType, "1"));
variables.put("shippingCode", bo.getShippingCode());
variables.put("applicantId", String.valueOf(LoginHelper.getUserId()));
// 到货确认节点配置了 ${tManagerId} 抄送表达式,发起流程时必须保证变量有效
if (needConfirm) {
String tManagerId = StringUtils.trim(Convert.toStr(variables.get("tManagerId")));
// if (StringUtils.isBlank(tManagerId) || "null".equalsIgnoreCase(tManagerId)) {
// throw new ServiceException("到货确认节点抄送人员不能为空");
// }
variables.put("tManagerId", tManagerId);
}
String tManagerId = StringUtils.trim(Convert.toStr(variables.get("tManagerId")));
variables.put("tManagerId", tManagerId);
// 后端发起需要忽略权限
variables.put("ignore", true);
if (StringUtils.isBlank(bo.getBizExt().getBusinessCode())) {
@ -493,7 +490,7 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService {
// 审批中
shippingBill.setOutStockBillStatus(OAStatusEnum.APPROVING.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
// 审批完成 → 业务状态变为可用/待发货
// 审批完成 → 业务状态变为可用
shippingBill.setOutStockBillStatus(OAStatusEnum.COMPLETED.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) {
@ -505,9 +502,58 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService {
shippingBill.setOutStockBillStatus(OAStatusEnum.DRAFT.getStatus());
}
baseMapper.updateById(shippingBill);
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
// 发货单状态落库后再汇总,确保本次完成的发货单计入合同订单发货状态
refreshContractOrderDeliveryStatus(shippingBill.getContractId());
}
});
}
/**
*
*/
private void refreshContractOrderDeliveryStatus(Long contractId) {
if (contractId == null) {
return;
}
try {
remoteErpContractOrderService.refreshContractOrderStatus(
contractId, null, ContractOrderStatusTypeEnum.DELIVERY.getCode());
} catch (Exception e) {
log.error("刷新合同订单发货状态失败contractId={}", contractId, e);
}
}
/**
* is_all_receiving0 1
*/
@Override
public String resolveOrderDeliveryStatusByContractId(Long contractId) {
if (contractId == null) {
return OrderDeliveryStatusConstant.NOT_DELIVERED;
}
List<WmsShippingBill> completedBills = baseMapper.selectList(Wrappers.<WmsShippingBill>lambdaQuery()
.select(WmsShippingBill::getIsAllReceiving, WmsShippingBill::getNeedArrivalConfirm)
.eq(WmsShippingBill::getContractId, contractId)
.eq(WmsShippingBill::getOutStockBillStatus, OAStatusEnum.COMPLETED.getStatus())
.eq(WmsShippingBill::getDelFlag, "0"));
if (CollUtil.isEmpty(completedBills)) {
return OrderDeliveryStatusConstant.NOT_DELIVERED;
}
for (WmsShippingBill bill : completedBills) {
String isAllReceiving = StringUtils.trim(bill.getIsAllReceiving());
// 1=部分到货 → 合同订单为部分发货
if ("1".equals(isAllReceiving)) {
return OrderDeliveryStatusConstant.PARTIAL_DELIVERED;
}
// 需到货确认但未标记全部到货,按部分发货处理
if (!"0".equals(isAllReceiving)) {
return OrderDeliveryStatusConstant.PARTIAL_DELIVERED;
}
}
return OrderDeliveryStatusConstant.DELIVERED;
}
/**
* Word
*/

Loading…
Cancel
Save