✨ 付款申请同步接入金蝶付款申请保存接口并记录返回单据id
This commit is contained in:
+136
-4
@@ -23,6 +23,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
@@ -31,6 +32,11 @@ import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.system.cache.DictBizCache;
|
||||
import org.springblade.system.pojo.entity.DictBiz;
|
||||
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplySaveDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.dto.BfiPayApplySaveEntryDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultItemVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiBillSaveResultVO;
|
||||
import org.springblade.thirdparty.bfi.service.IBfiService;
|
||||
import org.springblade.transport.mapper.FormalSettlementMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementPaymentMapper;
|
||||
import org.springblade.transport.mapper.BillLedgerMapper;
|
||||
@@ -71,6 +77,7 @@ import org.springblade.transport.service.IPaymentApplicationService;
|
||||
import org.springblade.transport.service.IFormalSettlementService;
|
||||
import org.springblade.transport.wrapper.PaymentApplicationWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -84,6 +91,7 @@ import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** 付款申请服务实现。 @author Chill */
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplicationMapper, PaymentApplication>
|
||||
@@ -93,6 +101,11 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
||||
private static final String APPROVED = "approved";
|
||||
private static final String RETURNED = "returned";
|
||||
private static final String VOIDED = "voided";
|
||||
private static final String BFI_SUPPLIER_ASSTACT_TYPE = "bd_supplier";
|
||||
private static final String BFI_CONTRACT_SRC_BT = "awrp_contract_info";
|
||||
private static final String BFI_PROJECT_NUMBER_NONE = "999";
|
||||
private static final String BFI_PAYMENT_TYPE_FORMAL = "201";
|
||||
private static final String BFI_PAYMENT_TYPE_PREPAY = "202";
|
||||
private final PaymentApplicationInvoiceMapper invoiceMapper;
|
||||
private final PaymentApplicationRecordMapper recordMapper;
|
||||
private final PaymentApplicationSettlementMapper settlementRelationMapper;
|
||||
@@ -108,6 +121,19 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
||||
private final BillLedgerUsageMapper billLedgerUsageMapper;
|
||||
private final TemporaryCreditLimitMapper temporaryCreditLimitMapper;
|
||||
private final IFormalSettlementService formalSettlementService;
|
||||
private final IBfiService bfiService;
|
||||
@Value("${thirdParty.bfi.payApply.srcSys:TMS}")
|
||||
private String bfiPayApplySrcSys;
|
||||
@Value("${thirdParty.bfi.payApply.billtype:ap_payapply_BT_S}")
|
||||
private String bfiPayApplyBilltype;
|
||||
@Value("${thirdParty.bfi.payApply.orgNumber:}")
|
||||
private String bfiPayApplyOrgNumber;
|
||||
@Value("${thirdParty.bfi.payApply.currency:CNY}")
|
||||
private String bfiPayApplyCurrency;
|
||||
@Value("${thirdParty.bfi.payApply.exratetable:01}")
|
||||
private String bfiPayApplyExratetable;
|
||||
@Value("${thirdParty.bfi.payApply.srcType:TMS付款申请}")
|
||||
private String bfiPayApplySrcType;
|
||||
|
||||
@Override
|
||||
public IPage<PaymentApplicationVO> selectPage(IPage<PaymentApplication> page, PaymentApplicationVO query) {
|
||||
@@ -307,15 +333,25 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
||||
PaymentApplication entity = lockedPayment(id);
|
||||
if (!APPROVED.equals(entity.getApprovalStatus())) throw new ServiceException("仅审批通过的付款申请允许生成金蝶单据");
|
||||
if ("synced".equals(entity.getKingdeeStatus())) return entity.getKingdeeBillNo();
|
||||
String no = "FKD" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + String.format("%05d", count(Wrappers.<PaymentApplication>lambdaQuery().likeRight(PaymentApplication::getKingdeeBillNo, "FKD" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE))) + 1);
|
||||
entity.setKingdeeBillNo(no);
|
||||
String kingdeeBillId;
|
||||
try {
|
||||
kingdeeBillId = pushBfiPayApply(entity);
|
||||
} catch (ServiceException exception) {
|
||||
markSyncFailed(entity);
|
||||
throw exception;
|
||||
} catch (Exception exception) {
|
||||
log.error("付款申请[{}]推送金蝶付款申请单异常", entity.getPaymentNo(), exception);
|
||||
markSyncFailed(entity);
|
||||
throw new ServiceException("推送金蝶付款申请失败:" + exception.getMessage());
|
||||
}
|
||||
entity.setKingdeeBillNo(kingdeeBillId);
|
||||
entity.setKingdeeStatus("synced");
|
||||
entity.setPaidAmount(money(entity.getAppliedAmount()).setScale(2, RoundingMode.HALF_UP));
|
||||
mockPaymentRecords(entity);
|
||||
updateById(entity);
|
||||
syncPreSettlementAdvance(entity);
|
||||
syncFormalSettlementPayments(entity);
|
||||
return no;
|
||||
return kingdeeBillId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -325,10 +361,106 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
||||
List<Long> distinctIds = ids.stream().filter(Objects::nonNull).distinct().toList();
|
||||
if (distinctIds.isEmpty()) throw new ServiceException("请至少选择一条审批通过的付款申请");
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Long id : distinctIds) result.add(syncKingdee(id));
|
||||
for (Long id : distinctIds) {
|
||||
try {
|
||||
result.add(syncKingdee(id));
|
||||
} catch (Exception exception) {
|
||||
result.add("付款申请[" + id + "]同步失败:" + exception.getMessage());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送金蝶付款申请单(A103-3 付款申请保存),返回金蝶单据id
|
||||
*
|
||||
* @param entity 付款申请实体
|
||||
* @return 金蝶付款申请单id
|
||||
*/
|
||||
private String pushBfiPayApply(PaymentApplication entity) {
|
||||
if (Func.isBlank(bfiPayApplyOrgNumber)) throw new ServiceException("推送金蝶付款申请失败,请配置thirdParty.bfi.payApply.orgNumber");
|
||||
String applyDateText = (entity.getApplyDate() == null ? LocalDate.now() : entity.getApplyDate()).format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
BigDecimal applyAmount = money(entity.getAppliedAmount()).setScale(2, RoundingMode.HALF_UP);
|
||||
BfiPayApplySaveDTO param = new BfiPayApplySaveDTO();
|
||||
param.setAwrpSrcCode(entity.getPaymentNo());
|
||||
param.setAwrpSrcSys(bfiPayApplySrcSys);
|
||||
param.setSettleorgNumber(bfiPayApplyOrgNumber);
|
||||
param.setBilltypeNumber(bfiPayApplyBilltype);
|
||||
param.setApplydate(applyDateText);
|
||||
param.setApplyorgNumber(bfiPayApplyOrgNumber);
|
||||
param.setPayorgNumber(bfiPayApplyOrgNumber);
|
||||
param.setPurorgNumber(bfiPayApplyOrgNumber);
|
||||
param.setApplycause(bfiApplyCause(entity.getPaymentType()));
|
||||
param.setPaycurrencyNumber(bfiPayApplyCurrency);
|
||||
param.setSettlecurrencyNumber(bfiPayApplyCurrency);
|
||||
param.setAwrpSrcType(bfiPayApplySrcType);
|
||||
param.setExratetableNumber(bfiPayApplyExratetable);
|
||||
param.setExratedate(applyDateText);
|
||||
param.setAwrpTextfield1(bfiPaymentMethodLabel(entity.getPaymentMethod()));
|
||||
if (entity.getContractId() != null) {
|
||||
param.setAwrpSrcBt(BFI_CONTRACT_SRC_BT);
|
||||
param.setAwrpSrcConNo(entity.getContractNo());
|
||||
}
|
||||
BfiPayApplySaveEntryDTO entry = new BfiPayApplySaveEntryDTO();
|
||||
entry.setEPaymenttypeNumber("settlement_payment".equals(entity.getPaymentType()) ? BFI_PAYMENT_TYPE_FORMAL : BFI_PAYMENT_TYPE_PREPAY);
|
||||
entry.setEAsstacttype(BFI_SUPPLIER_ASSTACT_TYPE);
|
||||
entry.setEAsstactNumber(bfiSupplierCode(entity));
|
||||
entry.setEAssacct(entity.getBankAccount());
|
||||
entry.setEBebankNumber(entity.getBankName());
|
||||
entry.setEPayamount(applyAmount);
|
||||
entry.setEApplyamount(applyAmount);
|
||||
entry.setEExpaydate(applyDateText);
|
||||
entry.setProjectNumber(bfiProjectNumber(entity));
|
||||
entry.setAwrpEntryCode(entity.getPaymentNo() + "-1");
|
||||
entry.setERemark(entity.getRemark());
|
||||
param.setEntry(List.of(entry));
|
||||
BfiBillSaveResultVO saveResult = bfiService.savePrePayApply(param);
|
||||
if (saveResult == null || Func.isEmpty(saveResult.getResult())) {
|
||||
throw new ServiceException("推送金蝶付款申请失败,金蝶未返回单据结果");
|
||||
}
|
||||
BfiBillSaveResultItemVO item = saveResult.getResult().get(0);
|
||||
if (!Boolean.TRUE.equals(item.getBillStatus()) || item.getId() == null) {
|
||||
String errorText = Func.isEmpty(item.getErrors()) ? "未知错误" : String.join(";", item.getErrors());
|
||||
throw new ServiceException("推送金蝶付款申请失败:" + errorText);
|
||||
}
|
||||
return String.valueOf(item.getId());
|
||||
}
|
||||
|
||||
private void markSyncFailed(PaymentApplication entity) {
|
||||
entity.setKingdeeStatus("failed");
|
||||
updateById(entity);
|
||||
}
|
||||
|
||||
private String bfiApplyCause(String paymentType) {
|
||||
return switch (paymentType == null ? "" : paymentType) {
|
||||
case "project_advance" -> "项目预付款申请";
|
||||
case "progress_advance" -> "进度预付款申请";
|
||||
case "settlement_payment" -> "结算付款申请";
|
||||
default -> "付款申请";
|
||||
};
|
||||
}
|
||||
|
||||
private String bfiPaymentMethodLabel(String paymentMethod) {
|
||||
if (Func.isEmpty(paymentMethod)) return null;
|
||||
return DictBizCache.getList("pay_method").stream()
|
||||
.filter(item -> paymentMethod.equals(item.getDictKey()) || paymentMethod.equals(item.getDictValue()))
|
||||
.map(DictBiz::getDictValue).findFirst().orElse(paymentMethod);
|
||||
}
|
||||
|
||||
private String bfiSupplierCode(PaymentApplication entity) {
|
||||
if (Func.isEmpty(entity.getPayeeName())) throw new ServiceException("推送金蝶付款申请失败,收款方不能为空");
|
||||
CustomerArchive customer = customerArchiveMapper.selectOne(Wrappers.<CustomerArchive>lambdaQuery()
|
||||
.and(wrapper -> wrapper.eq(CustomerArchive::getFullName, entity.getPayeeName()).or().eq(CustomerArchive::getShortName, entity.getPayeeName()))
|
||||
.eq(CustomerArchive::getIsDeleted, 0).last("limit 1"));
|
||||
return customer == null || Func.isEmpty(customer.getCustomerCode()) ? entity.getPayeeName() : customer.getCustomerCode();
|
||||
}
|
||||
|
||||
private String bfiProjectNumber(PaymentApplication entity) {
|
||||
if (entity.getProjectId() == null) return BFI_PROJECT_NUMBER_NONE;
|
||||
ProjectApply project = projectApplyMapper.selectById(entity.getProjectId());
|
||||
return project == null || Func.isEmpty(project.getProjectCode()) ? BFI_PROJECT_NUMBER_NONE : project.getProjectCode();
|
||||
}
|
||||
|
||||
private void mockPaymentRecords(PaymentApplication entity) {
|
||||
recordMapper.delete(Wrappers.<PaymentApplicationRecord>lambdaQuery()
|
||||
.eq(PaymentApplicationRecord::getPaymentApplicationId, entity.getId()));
|
||||
|
||||
Reference in New Issue
Block a user