YunaiV/yudao-cloud · error · IllegalArgumentException

业务类型不正确:{}

Error message

业务类型不正确:{}

What it means

Mirror of the payment case: ErpFinanceReceiptServiceImpl throws IllegalArgumentException when a receipt (收款单) item's bizType is neither SALE_OUT (销售出库) nor SALE_RETURN (销售退货). Valid items are enriched from the validated sale document's totalPrice (negated for returns) and the customerId must equal the header customer via Assert.

Source

Thrown at yudao-module-erp/yudao-module-erp-server/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinanceReceiptServiceImpl.java:172

        if (updateCount == 0) {
            throw exception(approve ? FINANCE_RECEIPT_APPROVE_FAIL : FINANCE_RECEIPT_PROCESS_FAIL);
        }
    }

    private List<ErpFinanceReceiptItemDO> validateFinanceReceiptItems(
            Long customerId,
            List<ErpFinanceReceiptSaveReqVO.Item> list) {
        return convertList(list, o -> BeanUtils.toBean(o, ErpFinanceReceiptItemDO.class, item -> {
            if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.SALE_OUT.getType())) {
                ErpSaleOutDO saleOut = saleOutService.validateSaleOut(item.getBizId());
                Assert.equals(saleOut.getCustomerId(), customerId, "客户必须相同");
                item.setTotalPrice(saleOut.getTotalPrice()).setBizNo(saleOut.getNo());
            } else if (ObjectUtil.equal(item.getBizType(), ErpBizTypeEnum.SALE_RETURN.getType())) {
                ErpSaleReturnDO saleReturn = saleReturnService.validateSaleReturn(item.getBizId());
                Assert.equals(saleReturn.getCustomerId(), customerId, "客户必须相同");
                item.setTotalPrice(saleReturn.getTotalPrice().negate()).setBizNo(saleReturn.getNo());
            } else {
                throw new IllegalArgumentException("业务类型不正确:" + item.getBizType());
            }
        }));
    }

    private void updateFinanceReceiptItemList(Long id, List<ErpFinanceReceiptItemDO> newList) {
        // 第一步,对比新老数据,获得添加、修改、删除的列表
        List<ErpFinanceReceiptItemDO> oldList = financeReceiptItemMapper.selectListByReceiptId(id);
        List<List<ErpFinanceReceiptItemDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
                (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));

        // 第二步,批量添加、修改、删除
        if (CollUtil.isNotEmpty(diffList.get(0))) {
            diffList.get(0).forEach(o -> o.setReceiptId(id));
            financeReceiptItemMapper.insertBatch(diffList.get(0));
        }
        if (CollUtil.isNotEmpty(diffList.get(1))) {
            financeReceiptItemMapper.updateBatch(diffList.get(1));
        }

View on GitHub (pinned to 477be9dd49)

Solutions

  1. Use only ErpBizTypeEnum.SALE_OUT or SALE_RETURN as bizType in receipt items
  2. Use the finance payment (付款单) API for purchase-side documents (PURCHASE_IN / PURCHASE_RETURN)
  3. Validate bizType per item in the frontend before submit

Example fix

// before: purchase doc in a receipt
{"customerId":1,"items":[{"bizType":1,"bizId":201}]} // PURCHASE_IN -> throws

// after
{"customerId":1,"items":[{"bizType":3,"bizId":201}]} // SALE_OUT; purchase docs go to /erp/finance-payment
Defensive patterns

Strategy: validation

Validate before calling

for (var item : reqVO.getItems()) {
    Integer t = item.getBizType();
    if (!Objects.equals(t, ErpBizTypeEnum.SALE_OUT.getType())
     && !Objects.equals(t, ErpBizTypeEnum.SALE_RETURN.getType())) {
        throw new IllegalArgumentException("收款单明细 bizType 必须为 销售出库/销售退货");
    }
}

Type guard

boolean isReceiptBizType(Integer bizType) {
    return Objects.equals(bizType, ErpBizTypeEnum.SALE_OUT.getType())
        || Objects.equals(bizType, ErpBizTypeEnum.SALE_RETURN.getType());
}

Prevention

When it happens

Trigger: POST/PUT of a finance receipt whose items[] include bizType PURCHASE_IN/PURCHASE_RETURN — purchase documents belong to payments; bizType null/0 from an incomplete form; caller swapping payment and receipt payloads.

Common situations: Shared item-picker component emitting purchase types on the receipt screen; import scripts mapping doc kinds to the wrong finance type; guessing bizType numbering instead of ErpBizTypeEnum.

Related errors


AI-assisted analysis of YunaiV/yudao-cloud@477be9dd49 (2026-08-14). Data as JSON: /api/errors/913f12653d363520. Report an issue: GitHub.