Browse Source

#一键智能匹配 AI改动 V2#

master
default 2 months ago
parent
commit
0c77aa0e47
  1. 878
      src/main/java/com/cmsen/ticket/application/manager/service/impl/SupplierServiceImpl.java

878
src/main/java/com/cmsen/ticket/application/manager/service/impl/SupplierServiceImpl.java

@ -28,12 +28,10 @@ import com.cmsen.ticket.application.manager.vo.GetMaterialParamVo;
import com.cmsen.ticket.application.manager.vo.MatterV3ResponseVo; import com.cmsen.ticket.application.manager.vo.MatterV3ResponseVo;
import com.cmsen.ticket.application.manager.vo.SupplierInvoiceMatchOrderVo; import com.cmsen.ticket.application.manager.vo.SupplierInvoiceMatchOrderVo;
import com.cmsen.ticket.application.manager.vo.SupplierMaterialDefineVo; import com.cmsen.ticket.application.manager.vo.SupplierMaterialDefineVo;
import com.cmsen.ticket.application.service.ConcurService;
import com.cmsen.ticket.application.service.SupplierOutService; import com.cmsen.ticket.application.service.SupplierOutService;
import com.cmsen.ticket.bestsign.util.InterfaceUtil; import com.cmsen.ticket.bestsign.util.InterfaceUtil;
import com.cmsen.ticket.domain.dto.*; import com.cmsen.ticket.domain.dto.*;
import com.cmsen.ticket.domain.entity.*; import com.cmsen.ticket.domain.entity.*;
import com.cmsen.ticket.domain.entity.concur.ConcurConfigEntity;
import com.cmsen.ticket.domain.entity.manager.*; import com.cmsen.ticket.domain.entity.manager.*;
import com.cmsen.ticket.domain.mapper.*; import com.cmsen.ticket.domain.mapper.*;
import com.cmsen.ticket.domain.mapper.manager.*; import com.cmsen.ticket.domain.mapper.manager.*;
@ -162,11 +160,7 @@ public class SupplierServiceImpl implements SupplierService {
@Resource @Resource
private AccountPeriodMapper accountPeriodMapper; private AccountPeriodMapper accountPeriodMapper;
@Resource
private ConcurService concurService;
@Resource
private ConcurConfigEntity concurConfig;
@Resource @Resource
private TaxMappingMapper taxMappingMapper; private TaxMappingMapper taxMappingMapper;
@ -771,14 +765,7 @@ public class SupplierServiceImpl implements SupplierService {
} }
} }
@Override
public RestResponse matchInvoices(String numberS, String numberE, Integer invoiceType) {
List<InvoiceItemListDto> list = corporateInvoiceMapper.supplierInvoiceMatchInvoiceList(numberS, numberE, invoiceType);
for (InvoiceItemListDto invoiceItemListDto : list) {
invoiceItemListDto.setUsedMoney(supplierOrderItemMatchingMapper.getUsedAmountByItemId(invoiceItemListDto.getId()));
}
return RestResponse.success(list);
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@ -2933,497 +2920,335 @@ public class SupplierServiceImpl implements SupplierService {
// 2025-05-27 // 2025-05-27
List<SupplierState> stateList = supplierStateMapper.listByNumber(invoiceNumber); List<SupplierState> stateList = supplierStateMapper.listByNumber(invoiceNumber);
List<CorporateInvoiceItems> stateItems = new ArrayList<>();//supplierInvoiceMatchOrderVo
if (!stateList.isEmpty()) { if (!stateList.isEmpty()) {
// 对账单逻辑 supplier_state 优先匹配原则 // 对账单逻辑 supplier_state 优先匹配原则
List<CorporateInvoiceItems> itemList = corporateInvoiceItemsMapper.selectItemsByPid(invoiceId); List<CorporateInvoiceItems> itemList = corporateInvoiceItemsMapper.selectItemsByPid(invoiceId);
List<SupplierOrderItemMatching> stateInsertList = new ArrayList<>();
// 需要重算差异的发票明细行(按 id 去重,避免同一行被反复计算)
Map<String, CorporateInvoiceItems> stateDirtyItems = new LinkedHashMap<>();
for (SupplierState supplierState : stateList) { for (SupplierState supplierState : stateList) {
String receiveNo = supplierState.getExt01(); String receiveNo = supplierState.getExt01();
String orderNo = supplierState.getPo(); if (org.apache.commons.lang3.StringUtils.isEmpty(receiveNo)) {
String stateItemNo = supplierState.getItemNo();
String desc = supplierState.getDesc();
BigDecimal amount = new BigDecimal(supplierState.getAmount());
BigDecimal quantity = new BigDecimal(supplierState.getQuantity());
BigDecimal price = amount.divide(quantity).setScale(2, BigDecimal.ROUND_HALF_UP);
if (org.apache.commons.lang3.StringUtils.isNotEmpty(receiveNo)) {
//4. 取这个发票的state第一行,如果有receive number(放在ext01上),
// 则取这个receive number的值去查收货表,获取相关信息,只有数量从state上取,金额计算。
SupplierOrder stateOrder = supplierOrderMapper.selectByState(receiveNo, orderNo, stateItemNo);
if (null != stateOrder) {
// 可以匹配 查找items的name TODO 目前简单点是否包含 state的des描述
boolean matchedFlag = false;
for (CorporateInvoiceItems item : itemList) {
BigDecimal itemTotal = new BigDecimal(item.getTotal());
String name = item.getName();
if (name.indexOf(desc) > -1) {
stateItems.add(item);
matchedFlag = true;
// 简单的表示匹配成功
//插入supplier_order_item_matching
SupplierOrderItemMatching matching = new SupplierOrderItemMatching();
matching.setInvoiceId(invoiceId);
matching.setItemId(item.getId());
matching.setOrderId(stateOrder.getId());
matching.setName(desc);
matching.setSpecification(item.getSpecification());
matching.setUnit(supplierState.getUom());
// 20220510price取值修改
matching.setPrice(price);
// 20220508price取值修改
//matching.setPrice(price.setScale(6, BigDecimal.ROUND_HALF_UP));
matching.setQuantity(supplierState.getQuantity());
log.info(matching.getQuantity());
matching.setTotal(amount);
matching.setDeductionAmount(BigDecimal.ZERO);
matching.setDeductionTax(BigDecimal.ZERO);
matching.setDeductionTaxRate(item.getDeductionTaxRate());
// tax 不是空并且 tax和deduction_tax
if (StringUtil.isNotBlank(item.getTax())) {
if (itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())).compareTo(BigDecimal.ZERO) == 1) {
BigDecimal percent = matching.getTotal().divide(itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())), 10, BigDecimal.ROUND_HALF_UP);
matching.setTax(new BigDecimal(item.getTax()).add(new BigDecimal(item.getDeductionTax() == null ? "0" : item.getDeductionTax())).multiply(percent));
} else {
matching.setTax(BigDecimal.ZERO);
}
}
matching.setReceivedTotal(amount);
matching.setTaxRate(item.getTaxRate());
matching.setMatchingStatus(0);
matching.setReceiveNo(supplierState.getExt01());
matching.setOrderNo(supplierState.getPo());
matching.setItemNo(supplierState.getItemNo());
if (new BigDecimal(matching.getQuantity()).compareTo(BigDecimal.ZERO) == 0) {
break;
}
// 插入匹配数据
supplierOrderItemMatchingMapper.insert(matching);
}
}
if (!matchedFlag) {
CorporateInvoiceItems item = itemList.get(0);
stateItems.add(item);
BigDecimal itemTotal = new BigDecimal(item.getTotal());
String name = item.getName();
matchedFlag = true;
// 简单的表示匹配成功
//插入supplier_order_item_matching
SupplierOrderItemMatching matching = new SupplierOrderItemMatching();
matching.setInvoiceId(invoiceId);
matching.setItemId(item.getId());
matching.setOrderId(stateOrder.getId());
matching.setName(desc);
matching.setSpecification(item.getSpecification());
matching.setUnit(supplierState.getUom());
// 20220510price取值修改
matching.setPrice(price);
// 20220508price取值修改
//matching.setPrice(price.setScale(6, BigDecimal.ROUND_HALF_UP));
matching.setQuantity(supplierState.getQuantity());
log.info(matching.getQuantity());
matching.setTotal(amount);
matching.setDeductionAmount(BigDecimal.ZERO);
matching.setDeductionTax(BigDecimal.ZERO);
matching.setDeductionTaxRate(item.getDeductionTaxRate());
// tax 不是空并且 tax和deduction_tax
if (StringUtil.isNotBlank(item.getTax())) {
if (itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())).compareTo(BigDecimal.ZERO) == 1) {
BigDecimal percent = matching.getTotal().divide(itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())), 10, BigDecimal.ROUND_HALF_UP);
matching.setTax(new BigDecimal(item.getTax()).add(new BigDecimal(item.getDeductionTax() == null ? "0" : item.getDeductionTax())).multiply(percent));
} else {
matching.setTax(BigDecimal.ZERO);
}
}
matching.setReceivedTotal(amount);
matching.setTaxRate(item.getTaxRate());
matching.setMatchingStatus(0);
matching.setReceiveNo(supplierState.getExt01());
matching.setOrderNo(supplierState.getPo());
matching.setItemNo(supplierState.getItemNo());
if (new BigDecimal(matching.getQuantity()).compareTo(BigDecimal.ZERO) == 0) {
break;
}
// 插入匹配数据
supplierOrderItemMatchingMapper.insert(matching);
}
}
// 20220430更新diff
for (CorporateInvoiceItems tmpItem : stateItems) {
updateDifference(corporateInvoice, tmpItem);
}
} else {
//如果没有receive,先根据PO订单号 + 料号获取收货表的可匹配数量,先找下是否有同样的数量, //如果没有receive,先根据PO订单号 + 料号获取收货表的可匹配数量,先找下是否有同样的数量,
// 如果有就匹配这一行,没有就按照先进先出来匹配,插入supplier order item matching // 如果有就匹配这一行,没有就按照先进先出来匹配,插入supplier order item matching
continue;
}
// 数量为 0 时不能作为单价分母,直接跳过
BigDecimal quantity = dec(supplierState.getQuantity());
if (quantity.signum() == 0) {
log.warn("对账单数量为0,跳过:invoiceId={}, po={}, itemNo={}", invoiceId,
supplierState.getPo(), supplierState.getItemNo());
continue;
}
// 金额为空时不写 0 值数据,直接跳过
if (StringUtil.isBlank(supplierState.getAmount())) {
log.warn("对账单金额为空,跳过:invoiceId={}, po={}, itemNo={}", invoiceId,
supplierState.getPo(), supplierState.getItemNo());
continue;
} }
BigDecimal amount = dec(supplierState.getAmount());
BigDecimal price = amount.divide(quantity, 2, RoundingMode.HALF_UP);
//4. 取这个发票的state第一行,如果有receive number(放在ext01上),
// 则取这个receive number的值去查收货表,获取相关信息,只有数量从state上取,金额计算。
SupplierOrder stateOrder = supplierOrderMapper.selectByState(receiveNo, supplierState.getPo(), supplierState.getItemNo());
if (null == stateOrder) {
continue;
}
// 可以匹配 查找items的name :优先名称包含 state 描述的行,未命中则兜底第一行;命中即停
CorporateInvoiceItems item = findStateItem(itemList, supplierState.getDesc());
if (null == item) {
log.warn("对账单未匹配到发票明细行:invoiceId={}, po={}, itemNo={}", invoiceId,
supplierState.getPo(), supplierState.getItemNo());
continue;
}
// 简单的表示匹配成功,插入 supplier_order_item_matching
stateInsertList.add(buildStateMatching(invoiceId, item, supplierState, stateOrder, price, amount));
stateDirtyItems.put(item.getId(), item);
}
// 批量插入匹配数据
if (!stateInsertList.isEmpty()) {
supplierOrderItemMatchingMapper.insertBatch(stateInsertList);
}
// 20220430更新diff
for (CorporateInvoiceItems tmpItem : stateDirtyItems.values()) {
updateDifference(corporateInvoice, tmpItem);
} }
} }
// 2025-05-29 如果是服务类行 按金额匹配 根据po查询永远匹配到第一个item上面。 // 2025-05-29 如果是服务类行 按金额匹配 根据po查询永远匹配到第一个item上面。
// 根据PO 查询 supplierOrder // 根据PO 查询 supplierOrder
if (0 == matchType && corporateInvoice.getInvoiceType() == 1) { if (0 == matchType && corporateInvoice.getInvoiceType() == 1) {
List<SupplierOrderItemMatching> insertList2 = new ArrayList<>(); // 没有PO时 split 和 IN 查询都没有意义,直接跳过
Map<String, Object> mapParams = new HashMap<>(); if (StringUtil.isBlank(supplierMatching.getOrderNo())) {
if (!supplier.getSupplierSpecial()) { log.warn("服务类匹配跳过:未匹配到PO,invoiceId={}", invoiceId);
mapParams.put("supplierCode", supplierCode); } else {
} Map<String, Object> mapParams = new HashMap<>();
mapParams.put("all", 0); if (!supplier.getSupplierSpecial()) {
mapParams.put("isOutIn", 1); mapParams.put("supplierCode", supplierCode);
String[] orderNos = supplierMatching.getOrderNo().split(","); }
mapParams.put("pos", orderNos); mapParams.put("all", 0);
List<SupplierOrder> orderList = supplierOrderMapper.listByPOs(mapParams); mapParams.put("isOutIn", 1);
List<CorporateInvoiceItems> items = corporateInvoiceItemsMapper.selectItemsByPid(invoiceId); String[] orderNos = supplierMatching.getOrderNo().split(",");
if (!items.isEmpty()) { mapParams.put("pos", orderNos);
CorporateInvoiceItems item = items.get(0); List<SupplierOrder> orderList = supplierOrderMapper.listByPOs(mapParams);
BigDecimal itemTotal = new BigDecimal(item.getTotal()); List<CorporateInvoiceItems> items = corporateInvoiceItemsMapper.selectItemsByPid(invoiceId);
for (SupplierOrder order : orderList) { if (!items.isEmpty()) {
log.info("order.getUnusedDquantity:{}", order.getUnUsedQuantity()); CorporateInvoiceItems item = items.get(0);
order.setUsedAmount(supplierOrderItemMatchingMapper.getUsedAmountByOrderId(order.getId())); BigDecimal itemTotal = dec(item.getTotal());
order.setUsedQuantity(supplierOrderItemMatchingMapper.getUsedQuantityByOrderId(order.getId())); // 已分摊金额,防止超出明细金额继续匹配
//插入supplier_order_item_matching BigDecimal allocated = BigDecimal.ZERO;
SupplierOrderItemMatching matching = new SupplierOrderItemMatching(); for (SupplierOrder order : orderList) {
matching.setInvoiceId(invoiceId); if (allocated.compareTo(itemTotal) >= 0) {
matching.setItemId(item.getId()); log.warn("服务类匹配已分摊满,剩余订单跳过:invoiceId={}, itemId={}", invoiceId, item.getId());
matching.setOrderId(order.getId()); break;
matching.setName(order.getGoods()); }
matching.setSpecification(item.getSpecification()); order.setUsedAmount(supplierOrderItemMatchingMapper.getUsedAmountByOrderId(order.getId()));
matching.setUnit(order.getUom()); order.setUsedQuantity(supplierOrderItemMatchingMapper.getUsedQuantityByOrderId(order.getId()));
BigDecimal price = order.getUnitPrice(); //插入supplier_order_item_matching
// 20220510price取值修改 SupplierOrderItemMatching matching = new SupplierOrderItemMatching();
matching.setPrice(order.getUnitPrice()); matching.setInvoiceId(invoiceId);
if (0 == corporateInvoice.getMatchType()) { matching.setItemId(item.getId());
BigDecimal percent = order.getUnUsedAmount().divide(itemTotal, 5, BigDecimal.ROUND_HALF_UP); matching.setOrderId(order.getId());
matching.setTotal(order.getUnUsedAmount() == null ? BigDecimal.ZERO : order.getUnUsedAmount()); matching.setName(order.getGoods());
if (StringUtil.isNotBlank(item.getDeductionAmount())) { matching.setSpecification(item.getSpecification());
matching.setDeductionAmount(new BigDecimal(item.getDeductionAmount()).multiply(percent)); matching.setUnit(order.getUom());
if (StringUtil.isNotBlank(item.getDeductionTax())) { // 20220510price取值修改
matching.setDeductionTax(new BigDecimal(item.getDeductionTax()).multiply(percent)); matching.setPrice(order.getUnitPrice());
if (0 == corporateInvoice.getMatchType()) {
BigDecimal unUsedAmount = nvl(order.getUnUsedAmount());
BigDecimal percent = div(unUsedAmount, itemTotal, 5);
matching.setTotal(unUsedAmount);
if (StringUtil.isNotBlank(item.getDeductionAmount())) {
matching.setDeductionAmount(dec(item.getDeductionAmount()).multiply(percent));
if (StringUtil.isNotBlank(item.getDeductionTax())) {
matching.setDeductionTax(dec(item.getDeductionTax()).multiply(percent));
}
matching.setDeductionTaxRate(item.getDeductionTaxRate());
} }
matching.setDeductionTaxRate(item.getDeductionTaxRate()); // 20220510单价修改
matching.setQuantity(div(unUsedAmount, order.getUnitPrice(), 2).toString());
} }
// 20220510单价修改 // 数量没算出来(matchType 非 0)或数量为 0 的行不能入库
//matching.setQuantity(matching.getTotal().divide(price, 2, BigDecimal.ROUND_HALF_UP).intValue()); if (StringUtil.isBlank(matching.getQuantity()) || dec(matching.getQuantity()).signum() == 0) {
matching.setQuantity(matching.getTotal().divide(order.getUnitPrice(), 2, BigDecimal.ROUND_HALF_UP).toString()); continue;
} }
// tax 不是空并且 tax和deduction_tax // tax 不是空并且 tax和deduction_tax
if (1 == priceType) { if (1 == priceType) {
matching.setTax(BigDecimal.ZERO); matching.setTax(BigDecimal.ZERO);
} else { } else if (StringUtil.isNotBlank(item.getTax())) {
if (StringUtil.isNotBlank(item.getTax())) { BigDecimal baseAmount = itemTotal.add(dec(item.getDeductionAmount()));
if (itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())).compareTo(BigDecimal.ZERO) == 1) { if (baseAmount.signum() > 0) {
BigDecimal percent = matching.getTotal().divide(itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())), 10, BigDecimal.ROUND_HALF_UP); matching.setTax(dec(item.getTax()).add(dec(item.getDeductionTax()))
matching.setTax(new BigDecimal(item.getTax()).add(new BigDecimal(item.getDeductionTax() == null ? "0" : item.getDeductionTax())).multiply(percent)); .multiply(div(matching.getTotal(), baseAmount, 10)));
} else { } else {
matching.setTax(BigDecimal.ZERO); matching.setTax(BigDecimal.ZERO);
} }
} else {
matching.setTax(BigDecimal.ZERO);
} }
matching.setReceivedTotal(nvl(matching.getPrice()).multiply(dec(matching.getQuantity())));
matching.setTaxRate(item.getTaxRate());
matching.setMatchingStatus(0);
matching.setReceiveNo(order.getReceiveNo());
matching.setOrderNo(order.getOrderNo());
matching.setItemNo(order.getItemNo());
allocated = allocated.add(nvl(matching.getTotal()));
// 插入匹配数据
supplierOrderItemMatchingMapper.insert(matching);
} }
updateDifference(corporateInvoice, item);
matching.setReceivedTotal(order.getUnitPrice().multiply(new BigDecimal(matching.getQuantity())));
matching.setTaxRate(item.getTaxRate());
matching.setMatchingStatus(0);
matching.setReceiveNo(order.getReceiveNo());
matching.setOrderNo(order.getOrderNo());
matching.setItemNo(order.getItemNo());
if (new BigDecimal(matching.getQuantity()).compareTo(BigDecimal.ZERO) == 0) {
break;
}
insertList2.add(matching);
// 插入匹配数据
supplierOrderItemMatchingMapper.insert(matching);
} }
updateDifference(corporateInvoice, item);
} }
} else { } else {
// 待插入数据 // 待插入数据
List<SupplierOrderItemMatching> insertList = new ArrayList<>(); List<SupplierOrderItemMatching> insertList = new ArrayList<>();
Map<String, SupplierInvoiceMatchOrderVo> matchMap = new HashMap<>(); // 按 itemNo 分组,同一 itemNo 下按 id 去重并保持出现顺序
// 已使用数据 Map<String, LinkedHashMap<Integer, SupplierInvoiceMatchOrderVo>> grouped = new LinkedHashMap<>();
Map<String, BigDecimal> matchMapNum = new HashMap<>(); for (SupplierInvoiceMatchOrderVo vo : result) {
// 数据分组 grouped.computeIfAbsent(vo.getItemNo(), key -> new LinkedHashMap<>()).putIfAbsent(vo.getId(), vo);
Map<String, List<SupplierInvoiceMatchOrderVo>> matchList = new HashMap<>();
StringBuffer poStr = new StringBuffer();
for (SupplierInvoiceMatchOrderVo supplierInvoiceMatchOrderVo : result) {
// 判断itemNo是否已出现过
String tmpKey = supplierInvoiceMatchOrderVo.getItemNo();
int temId = supplierInvoiceMatchOrderVo.getId();
if (matchList.get(tmpKey) != null) {
List<SupplierInvoiceMatchOrderVo> tmp = matchList.get(tmpKey);
boolean existFlag1 = true;
for (SupplierInvoiceMatchOrderVo invoiceMatchOrderVo : tmp) {
if (invoiceMatchOrderVo.getId() == temId) {
existFlag1 = false;
}
}
if (existFlag1) {
tmp.add(supplierInvoiceMatchOrderVo);
matchList.put(tmpKey, tmp);
}
} else {
List<SupplierInvoiceMatchOrderVo> tmp = new ArrayList<>();
tmp.add(supplierInvoiceMatchOrderVo);
matchList.put(tmpKey, tmp);
}
} }
// 新增物料和收货单价是否需要匹配 // 新增物料和收货单价是否需要匹配
SysConfig AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG = sysConfigMapper.selectByCode("AUTO_MATCHING_NEED_PRICE_EQUAL"); SysConfig AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG = sysConfigMapper.selectByCode("AUTO_MATCHING_NEED_PRICE_EQUAL");
log.info("matchList=>{}", JSONObject.toJSONString(matchList)); boolean needPriceEqual = null != AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG
List<CorporateInvoiceItems> items = new ArrayList<>();//supplierInvoiceMatchOrderVo && "1".equals(AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG.getValue());
for (String itemNo : matchList.keySet()) { // 需要重算差异的发票明细行,按 id 去重,避免同一行反复计算
List<CorporateInvoiceItems> items2 = null; Map<String, CorporateInvoiceItems> dirtyItems = new LinkedHashMap<>();
String unitPrice = null; // 已匹配订单号,去重且保持顺序
List<SupplierInvoiceMatchOrderVo> simovs = matchList.get(itemNo); LinkedHashSet<String> matchedOrderNos = new LinkedHashSet<>();
if (simovs.isEmpty()) { // 收货行剩余可匹配数量:内存记账,不再依赖同一次事务里刚插入的数据
Map<Integer, BigDecimal> orderRemainQty = new HashMap<>();
} else { // 收货行缓存,避免同一行反复查询
unitPrice = simovs.get(0).getPrice().toString(); Map<Integer, SupplierOrder> orderCache = new HashMap<>();
} // 发票明细行已匹配数量,避免每一行都回查一次
// String needPriceRight = supplierMaterialMapper.selectItemTypeFromMaterialDefine(itemNo); Map<String, BigDecimal> itemMatchedQty = new HashMap<>();
SupplierMaterialDefineVo supplierMaterialDefineVo = supplierMaterialMapper.getSimilarMaterialNo(itemNo, supplierCode, unitPrice);
log.info("supplierMaterialDefineVo=>{}", JSONObject.toJSONString(supplierMaterialDefineVo)); for (Map.Entry<String, LinkedHashMap<Integer, SupplierInvoiceMatchOrderVo>> groupEntry : grouped.entrySet()) {
String needPriceRight = null; String itemNo = groupEntry.getKey();
// 候选收货行:在副本上消耗,不再改动共享集合;按 id 去重
if (null != supplierMaterialDefineVo) { LinkedHashMap<Integer, SupplierInvoiceMatchOrderVo> available = new LinkedHashMap<>(groupEntry.getValue());
// needPriceRight = supplierMaterialDefineVo.getItemType(); SupplierInvoiceMatchOrderVo firstVo = available.isEmpty() ? null : available.values().iterator().next();
items2 = corporateInvoiceItemsMapper.selectForAutoSmartMatchingMulti3(invoiceId, supplierMaterialDefineVo.getSimilarItemNo()); String unitPrice = null == firstVo || null == firstVo.getPrice() ? null : firstVo.getPrice().toString();
} else { SupplierMaterialDefineVo supplierMaterialDefineVo =
items2 = corporateInvoiceItemsMapper.selectForAutoSmartMatchingMulti2(invoiceId, itemNo); supplierMaterialMapper.getSimilarMaterialNo(itemNo, supplierCode, unitPrice);
} List<CorporateInvoiceItems> items2 = null == supplierMaterialDefineVo
int startIndex = 0; ? corporateInvoiceItemsMapper.selectForAutoSmartMatchingMulti2(invoiceId, itemNo)
BigDecimal useQty = BigDecimal.ZERO; : corporateInvoiceItemsMapper.selectForAutoSmartMatchingMulti3(invoiceId, supplierMaterialDefineVo.getSimilarItemNo());
List<SupplierInvoiceMatchOrderVo> lsMa = matchList.get(itemNo); // 相似料号对应的收货行一并作为候选
if (null != supplierMaterialDefineVo) { if (null != supplierMaterialDefineVo && StringUtil.isNotBlank(supplierMaterialDefineVo.getSimilarItemNo())) {
if (!org.apache.commons.lang3.StringUtils.isEmpty(supplierMaterialDefineVo.getSimilarItemNo())) { for (String no : supplierMaterialDefineVo.getSimilarItemNo().split(",")) {
String[] similarItemNos = supplierMaterialDefineVo.getSimilarItemNo().split(","); if (no.equals(itemNo)) {
for (String no : similarItemNos) { continue;
if (no.equals(itemNo)) continue; }
if (null != matchList.get(no)) { LinkedHashMap<Integer, SupplierInvoiceMatchOrderVo> similarGroup = grouped.get(no);
lsMa.addAll(matchList.get(no)); if (null != similarGroup) {
} available.putAll(similarGroup);
} }
} }
} }
int temp = 0; if (null == items2 || items2.isEmpty()) {
continue;
}
for (CorporateInvoiceItems item : items2) { for (CorporateInvoiceItems item : items2) {
if (item.getName().equals("*金属制品*直角接头")) {
log.info("123");
}
temp++;
// 发票信息 // 发票信息
BigDecimal itemTotal = new BigDecimal(item.getTotal()); BigDecimal itemTotal = dec(item.getTotal());
BigDecimal itemQty = item.getUnUsedQuantity(); BigDecimal itemQty = nvl(item.getUnUsedQuantity());
BigDecimal itemQty2 = item.getUnUsedQuantity(); if (itemQty.signum() <= 0) {
BigDecimal lineQty = new BigDecimal("0"); continue;
boolean isEnough = false; }
// 2025 04 28 这里会存在多个物料匹配同一个行数据的情况。 这就使得这2个物料都匹配了同一个名称的明细行 // 该明细行已匹配的数量(含本次匹配过程中已插入的行)
// 判断 是否有无剩余 / 或者超配 也同样需要从 items这里确保。 BigDecimal matchedQty = itemMatchedQty.computeIfAbsent(item.getId(),
String qtt = item.getQuantity(); id -> nvl(supplierOrderItemMatchingMapper.getUsedQuantityByItemId(id)));
BigDecimal qt = new BigDecimal(qtt); if (matchedQty.compareTo(dec(item.getQuantity())) >= 0) {
// 通过itemId去 supplier_order_item_matching查询匹配的数量。 continue;
String itemId = item.getId(); }
// 是否存在剩余数量完全相等的收货行:有则只匹配这一行,取收货时间最早的一行
BigDecimal matchedQt = supplierOrderItemMatchingMapper.getUsedQuantityByItemId(itemId);
if (matchedQt.compareTo(qt) >= 0) continue;
// 是否有完全匹配数据
boolean isOk = false; boolean isOk = false;
Integer isId = 0; int isId = 0;
SupplierInvoiceMatchOrderVo isOkInvoice = null; SupplierInvoiceMatchOrderVo isOkInvoice = null;
startIndex = 0; for (SupplierInvoiceMatchOrderVo so : available.values()) {
for (int i = startIndex; i < lsMa.size(); i++) { if (needPriceEqual && !isSamePrice(item.getPrice(), so.getPrice())) {
SupplierInvoiceMatchOrderVo so = lsMa.get(i); continue;
if (null != AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG && "1".equals(AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG.getValue())) {
// 判断单价是否相等
String price1 = item.getPrice();
BigDecimal priceOne = new BigDecimal(price1).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal priceTwo = so.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP);
if (priceOne.compareTo(priceTwo) != 0) {
continue;
}
} }
if (useQty.compareTo(BigDecimal.ZERO) > 0) continue; if (itemQty.compareTo(nvl(so.getUsedQuantity())) == 0) {
if (itemQty.compareTo(so.getUsedQuantity()) == 0) {
isOk = true; isOk = true;
if (isOkInvoice != null && isId > 0) { if (null == isOkInvoice || isEarlier(so.getReceiveDate(), isOkInvoice.getReceiveDate())) {
if (isOkInvoice.getReceiveDate().after(so.getReceiveDate())) {
isOkInvoice = so;
isId = isOkInvoice.getId();
}
} else {
isOkInvoice = so; isOkInvoice = so;
isId = so.getId(); isId = so.getId();
} }
} }
} }
int tryed = 0; // 按顺序消耗收货行的剩余数量
int maxTry = 50; BigDecimal remaining = itemQty;
while (!lsMa.isEmpty() && tryed <= maxTry) { Iterator<SupplierInvoiceMatchOrderVo> iterator = available.values().iterator();
tryed++; while (iterator.hasNext() && remaining.signum() > 0) {
int j = startIndex; SupplierInvoiceMatchOrderVo so = iterator.next();
if (startIndex >= lsMa.size()) { if (needPriceEqual && !isSamePrice(item.getPrice(), so.getPrice())) {
break; continue;
}
// for (int j=startIndex;j<lsMa.size(); j++) {
SupplierInvoiceMatchOrderVo supplierInvoiceMatchOrderVo = lsMa.get(j);
if (null != AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG && "1".equals(AUTO_MATCHING_NEED_PRICE_EQUAL_CONIG.getValue())) {
// 判断单价是否相等
String price1 = item.getPrice();
BigDecimal priceOne = new BigDecimal(price1).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal priceTwo = supplierInvoiceMatchOrderVo.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP);
if (priceOne.compareTo(priceTwo) != 0) {
startIndex++;
continue;
}
} }
if (isOk && isId != supplierInvoiceMatchOrderVo.getId()) { if (isOk && isId != so.getId()) {
// lsMa.remove(supplierInvoiceMatchOrderVo); // 已定位到完全匹配的收货行,其它行不再参与匹配
startIndex++;
continue; continue;
} }
SupplierOrder order = supplierOrderMapper.selectForAutoSmartMatching(supplierInvoiceMatchOrderVo.getId()); SupplierOrder order = orderCache.computeIfAbsent(so.getId(), supplierOrderMapper::selectForAutoSmartMatching);
log.info("order.getUnusedDquantity:{}", order.getUnUsedQuantity()); if (null == order) {
if (order.getId() == 910187) { continue;
log.info("=====");
} }
if (null != item && null != order) { BigDecimal orderAvail = orderRemainQty.get(order.getId());
items.add(item); if (null == orderAvail) {
// 大于可用数量
boolean qtyFlag = false;
if (supplierInvoiceMatchOrderVo.getUsedQuantity().subtract(useQty).compareTo(itemQty2) > 0) {
qtyFlag = true;
}
order.setUsedAmount(supplierOrderItemMatchingMapper.getUsedAmountByOrderId(order.getId())); order.setUsedAmount(supplierOrderItemMatchingMapper.getUsedAmountByOrderId(order.getId()));
order.setUsedQuantity(supplierOrderItemMatchingMapper.getUsedQuantityByOrderId(order.getId())); order.setUsedQuantity(supplierOrderItemMatchingMapper.getUsedQuantityByOrderId(order.getId()));
orderAvail = dec(order.getUnUsedQuantity());
//插入supplier_order_item_matching orderRemainQty.put(order.getId(), orderAvail);
SupplierOrderItemMatching matching = new SupplierOrderItemMatching(); }
matching.setInvoiceId(invoiceId); if (orderAvail.signum() <= 0) {
matching.setItemId(item.getId()); continue;
matching.setOrderId(order.getId()); }
matching.setName(order.getGoods()); // 收货行剩余 大于 发票行剩余:本次只匹配发票需要的部分,剩余留给后面的明细行
matching.setSpecification(item.getSpecification()); boolean qtyFlag = orderAvail.compareTo(remaining) > 0;
matching.setUnit(order.getUom()); BigDecimal matchQty = qtyFlag ? remaining : orderAvail;
BigDecimal price = order.getUnitPrice();
// 20220510price取值修改 SupplierOrderItemMatching matching = new SupplierOrderItemMatching();
matching.setPrice(order.getUnitPrice()); matching.setInvoiceId(invoiceId);
if (0 == corporateInvoice.getMatchType()) { matching.setItemId(item.getId());
BigDecimal percent = order.getUnUsedAmount().divide(itemTotal, 5, BigDecimal.ROUND_HALF_UP); matching.setOrderId(order.getId());
matching.setTotal(order.getUnUsedAmount() == null ? BigDecimal.ZERO : order.getUnUsedAmount()); matching.setName(order.getGoods());
if (qtyFlag) { matching.setSpecification(item.getSpecification());
percent = itemQty2.divide(itemQty, 5, BigDecimal.ROUND_HALF_UP); matching.setUnit(order.getUom());
matching.setTotal(order.getUnUsedAmount() == null ? BigDecimal.ZERO : order.getUnUsedAmount().multiply(percent)); // 20220510price取值修改
} matching.setPrice(order.getUnitPrice());
if (StringUtil.isNotBlank(item.getDeductionAmount())) { if (0 == corporateInvoice.getMatchType()) {
matching.setDeductionAmount(new BigDecimal(item.getDeductionAmount()).multiply(percent)); BigDecimal unUsedAmount = nvl(order.getUnUsedAmount());
if (StringUtil.isNotBlank(item.getDeductionTax())) { BigDecimal percent = div(unUsedAmount, itemTotal, 5);
matching.setDeductionTax(new BigDecimal(item.getDeductionTax()).multiply(percent)); BigDecimal matchAmount = unUsedAmount;
} if (qtyFlag) {
matching.setDeductionTaxRate(item.getDeductionTaxRate()); percent = div(remaining, itemQty, 5);
} matchAmount = unUsedAmount.multiply(percent);
// 20220510单价修改
//matching.setQuantity(matching.getTotal().divide(price, 2, BigDecimal.ROUND_HALF_UP).intValue());
matching.setQuantity(matching.getTotal().divide(order.getUnitPrice(), 2, BigDecimal.ROUND_HALF_UP).toString());
} else {
// 20220508pricsee取值修改
//matching.setPrice(price.setScale(6, BigDecimal.ROUND_HALF_UP));
if (new BigDecimal(order.getUnUsedQuantity()).compareTo(itemQty2) > 0) {
matching.setQuantity(itemQty2.toString());
} else {
matching.setQuantity(order.getUnUsedQuantity());
}
if (matching.getQuantity().indexOf("-") > -1) {
log.info(matching.getQuantity());
}
if (qtyFlag) {
matching.setQuantity(itemQty2.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
}
matching.setTotal(price.multiply(new BigDecimal(matching.getQuantity())));
matching.setDeductionAmount(BigDecimal.ZERO);
matching.setDeductionTax(BigDecimal.ZERO);
matching.setDeductionTaxRate(item.getDeductionTaxRate());
}
// tax 不是空并且 tax和deduction_tax
if (StringUtil.isNotBlank(item.getTax())) {
if (itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())).compareTo(BigDecimal.ZERO) == 1) {
BigDecimal percent = matching.getTotal().divide(itemTotal.add(new BigDecimal(item.getDeductionAmount() == null ? "0" : item.getDeductionAmount())), 10, BigDecimal.ROUND_HALF_UP);
matching.setTax(new BigDecimal(item.getTax()).add(new BigDecimal(item.getDeductionTax() == null ? "0" : item.getDeductionTax())).multiply(percent));
} else {
matching.setTax(BigDecimal.ZERO);
}
}
matching.setReceivedTotal(order.getUnitPrice().multiply(new BigDecimal(matching.getQuantity())));
matching.setTaxRate(item.getTaxRate());
matching.setMatchingStatus(0);
matching.setReceiveNo(order.getReceiveNo());
matching.setOrderNo(order.getOrderNo());
matching.setItemNo(order.getItemNo());
if (new BigDecimal(matching.getQuantity()).compareTo(BigDecimal.ZERO) == 0) {
break;
}
insertList.add(matching);
// 插入匹配数据
if (matching.getQuantity().indexOf("-") > -1) {
log.error("=================");
} }
supplierOrderItemMatchingMapper.insert(matching); matching.setTotal(matchAmount);
// 拼接orderNo if (StringUtil.isNotBlank(item.getDeductionAmount())) {
if (poStr.toString().indexOf(matching.getOrderNo()) == -1) { matching.setDeductionAmount(dec(item.getDeductionAmount()).multiply(percent));
if (poStr.length() > 0) { if (StringUtil.isNotBlank(item.getDeductionTax())) {
poStr.append(","); matching.setDeductionTax(dec(item.getDeductionTax()).multiply(percent));
} }
poStr.append(matching.getOrderNo()); matching.setDeductionTaxRate(item.getDeductionTaxRate());
}
// 判断数据是否足够
lineQty = lineQty.add(supplierInvoiceMatchOrderVo.getUsedQuantity().subtract(useQty));
itemQty2 = itemQty2.subtract(supplierInvoiceMatchOrderVo.getUsedQuantity().subtract(useQty));
// 足够则跳出
startIndex = 0;
if (lineQty.compareTo(itemQty) > 0) {
useQty = useQty.add(new BigDecimal(matching.getQuantity()));
// isEnough = true;
break;
} else if (lineQty.compareTo(itemQty) == 0) {
// startIndex++;
useQty = BigDecimal.ZERO;
lsMa.remove(supplierInvoiceMatchOrderVo);
// isEnough = true;
break;
} }
// startIndex--; // 20220510单价修改
useQty = BigDecimal.ZERO; matching.setQuantity(div(matchAmount, order.getUnitPrice(), 2).toString());
lsMa.remove(supplierInvoiceMatchOrderVo); } else {
// 20220508pricsee取值修改
matching.setQuantity(matchQty.setScale(2, RoundingMode.HALF_UP).toString());
matching.setTotal(nvl(order.getUnitPrice()).multiply(matchQty));
matching.setDeductionAmount(BigDecimal.ZERO);
matching.setDeductionTax(BigDecimal.ZERO);
matching.setDeductionTaxRate(item.getDeductionTaxRate());
}
if (dec(matching.getQuantity()).signum() == 0) {
// 数量为 0 的行不能入库,继续尝试下一行
continue; continue;
// log.info("==:"+j);
// log.info("==:"+startIndex);
// log.info("==:{}",j<lsMa.size());
// log.info("==:"+j<lsMa.size());
} }
// startIndex++; // tax 不是空并且 tax和deduction_tax
if (StringUtil.isNotBlank(item.getTax())) {
BigDecimal baseAmount = itemTotal.add(dec(item.getDeductionAmount()));
if (baseAmount.signum() > 0) {
matching.setTax(dec(item.getTax()).add(dec(item.getDeductionTax()))
.multiply(div(matching.getTotal(), baseAmount, 10)));
} else {
matching.setTax(BigDecimal.ZERO);
}
} else {
matching.setTax(BigDecimal.ZERO);
}
matching.setReceivedTotal(nvl(order.getUnitPrice()).multiply(dec(matching.getQuantity())));
matching.setTaxRate(item.getTaxRate());
matching.setMatchingStatus(0);
matching.setReceiveNo(order.getReceiveNo());
matching.setOrderNo(order.getOrderNo());
matching.setItemNo(order.getItemNo());
insertList.add(matching);
// 插入匹配数据
supplierOrderItemMatchingMapper.insert(matching);
if (StringUtil.isNotBlank(matching.getOrderNo())) {
matchedOrderNos.add(matching.getOrderNo());
}
// 内存记账:扣减收货行和发票行的剩余数量
orderRemainQty.put(order.getId(), orderAvail.subtract(matchQty));
itemMatchedQty.put(item.getId(), matchedQty.add(matchQty));
dirtyItems.putIfAbsent(item.getId(), item);
remaining = remaining.subtract(matchQty);
if (!qtyFlag) {
// 该收货行已耗尽,不再参与后续明细行的匹配
iterator.remove();
}
} }
// if(isEnough){
// break;
// }
} }
} }
if (!insertList.isEmpty()) { if (!insertList.isEmpty() && StringUtil.isBlank(supplierMatching.getOrderNo())) {
if (supplierMatching.getOrderNo() == null || supplierMatching.getOrderNo().length() == 0) { supplierMatching.setOrderNo(String.join(",", matchedOrderNos));
supplierMatching.setOrderNo(poStr.toString()); supplierMatchingMapper.updateByPrimaryKey(supplierMatching);
supplierMatchingMapper.updateByPrimaryKey(supplierMatching);
}
} }
for (CorporateInvoiceItems tmpItem : items) { for (CorporateInvoiceItems tmpItem : dirtyItems.values()) {
updateDifference(corporateInvoice, tmpItem); updateDifference(corporateInvoice, tmpItem);
} }
} }
@ -4104,6 +3929,121 @@ public class SupplierServiceImpl implements SupplierService {
} }
} }
/**
* 数字/金额字符串安全解析:null、空串、千分位、非数字 一律按 0 处理,避免 new BigDecimal 抛异常
*/
private static BigDecimal dec(String value) {
if (value == null) {
return BigDecimal.ZERO;
}
String text = value.trim().replace(",", "");
if (text.isEmpty()) {
return BigDecimal.ZERO;
}
try {
return new BigDecimal(text);
} catch (NumberFormatException e) {
log.warn("无法解析为数字,按 0 处理:{}", value);
return BigDecimal.ZERO;
}
}
/**
* 数字/金额字符串安全解析并按指定精度取值
*/
private static BigDecimal dec(String value, int scale) {
return dec(value).setScale(scale, RoundingMode.HALF_UP);
}
/**
* 安全除法:被除数或除数为 null、除数为 0 时返回 0,避免 ArithmeticException
*/
private static BigDecimal div(BigDecimal dividend, BigDecimal divisor, int scale) {
if (dividend == null || divisor == null || divisor.signum() == 0) {
return BigDecimal.ZERO;
}
return dividend.divide(divisor, scale, RoundingMode.HALF_UP);
}
/**
* 金额取 0 值兜底
*/
private static BigDecimal nvl(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
/**
* 收货单价与发票单价是否相等(都按 2 位小数比较)
*/
private static boolean isSamePrice(String invoicePrice, BigDecimal orderPrice) {
return null != orderPrice && dec(invoicePrice, 2).compareTo(orderPrice.setScale(2, RoundingMode.HALF_UP)) == 0;
}
/**
* candidate 是否比 current 更早,null 视为最晚
*/
private static boolean isEarlier(Date candidate, Date current) {
if (null == candidate) {
return false;
}
return null == current || candidate.before(current);
}
/**
* 对账单明细匹配发票明细行:优先取名称包含对账单描述的行,未命中则兜底第一行
*/
private CorporateInvoiceItems findStateItem(List<CorporateInvoiceItems> itemList, String desc) {
if (itemList == null || itemList.isEmpty()) {
return null;
}
if (StringUtil.isNotBlank(desc)) {
for (CorporateInvoiceItems item : itemList) {
if (null != item.getName() && item.getName().contains(desc)) {
return item;
}
}
}
return itemList.get(0);
}
/**
* 构建对账单(supplier_state)与发票明细行的匹配数据
*/
private SupplierOrderItemMatching buildStateMatching(String invoiceId, CorporateInvoiceItems item, SupplierState supplierState,
SupplierOrder stateOrder, BigDecimal price, BigDecimal amount) {
// 折前金额,作为税额分摊的分母
BigDecimal baseAmount = dec(item.getTotal()).add(dec(item.getDeductionAmount()));
SupplierOrderItemMatching matching = new SupplierOrderItemMatching();
matching.setInvoiceId(invoiceId);
matching.setItemId(item.getId());
matching.setOrderId(stateOrder.getId());
matching.setName(supplierState.getDesc());
matching.setSpecification(item.getSpecification());
matching.setUnit(supplierState.getUom());
// 20220510price取值修改
matching.setPrice(price);
matching.setQuantity(supplierState.getQuantity());
matching.setTotal(amount);
matching.setDeductionAmount(BigDecimal.ZERO);
matching.setDeductionTax(BigDecimal.ZERO);
matching.setDeductionTaxRate(item.getDeductionTaxRate());
// tax 不是空并且 tax和deduction_tax
if (StringUtil.isNotBlank(item.getTax()) && baseAmount.signum() > 0) {
BigDecimal percent = div(matching.getTotal(), baseAmount, 10);
matching.setTax(dec(item.getTax()).add(dec(item.getDeductionTax())).multiply(percent));
} else {
// 置 0 而非 null,避免后续 updateDifference 累加税额时空指针
matching.setTax(BigDecimal.ZERO);
}
matching.setReceivedTotal(amount);
matching.setTaxRate(item.getTaxRate());
matching.setMatchingStatus(0);
matching.setReceiveNo(supplierState.getExt01());
matching.setOrderNo(supplierState.getPo());
matching.setItemNo(supplierState.getItemNo());
return matching;
}
public void updateDifference(CorporateInvoice corporateInvoice, CorporateInvoiceItems item) { public void updateDifference(CorporateInvoice corporateInvoice, CorporateInvoiceItems item) {
log.info("supplierOrderItemMatching item.getId()=>{}", item.getId()); log.info("supplierOrderItemMatching item.getId()=>{}", item.getId());
List<SupplierOrderItemMatching> supplierOrderItemMatchings = supplierOrderItemMatchingMapper.selectListByItemId(item.getId()); List<SupplierOrderItemMatching> supplierOrderItemMatchings = supplierOrderItemMatchingMapper.selectListByItemId(item.getId());
@ -4111,7 +4051,7 @@ public class SupplierServiceImpl implements SupplierService {
BigDecimal orderTotal = BigDecimal.ZERO; BigDecimal orderTotal = BigDecimal.ZERO;
// ReceivedTotal合计 // ReceivedTotal合计
for (SupplierOrderItemMatching supplierOrderItemMatching : supplierOrderItemMatchings) { for (SupplierOrderItemMatching supplierOrderItemMatching : supplierOrderItemMatchings) {
orderTotal = orderTotal.add(supplierOrderItemMatching.getTotal()).add(supplierOrderItemMatching.getTax()); orderTotal = orderTotal.add(nvl(supplierOrderItemMatching.getTotal())).add(nvl(supplierOrderItemMatching.getTax()));
/* // 折前+数量 /* // 折前+数量
if (corporateInvoice.getPriceType().equals(1) && corporateInvoice.getMatchType().equals(1)&& null != supplierOrderItemMatching.getDeductionAmount()) { if (corporateInvoice.getPriceType().equals(1) && corporateInvoice.getMatchType().equals(1)&& null != supplierOrderItemMatching.getDeductionAmount()) {
orderTotal = orderTotal.add(supplierOrderItemMatching.getDeductionAmount()); orderTotal = orderTotal.add(supplierOrderItemMatching.getDeductionAmount());
@ -4128,16 +4068,10 @@ public class SupplierServiceImpl implements SupplierService {
}*/ }*/
} }
// 发票金额 // 发票金额
BigDecimal invoiceMoney = new BigDecimal(item.getTotal()); BigDecimal invoiceMoney = dec(item.getTotal())
if (StringUtil.isNotEmpty(item.getDeductionAmount())) { .add(dec(item.getDeductionAmount()))
invoiceMoney = invoiceMoney.add(new BigDecimal(item.getDeductionAmount())); .add(dec(item.getTax()))
} .add(dec(item.getDeductionTax()));
if (StringUtil.isNotEmpty(item.getTax())) {
invoiceMoney = invoiceMoney.add(new BigDecimal(item.getTax()));
}
if (StringUtil.isNotEmpty(item.getDeductionTax())) {
invoiceMoney = invoiceMoney.add(new BigDecimal(item.getDeductionTax()));
}
BigDecimal difference = invoiceMoney.subtract(orderTotal).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal difference = invoiceMoney.subtract(orderTotal).setScale(2, BigDecimal.ROUND_HALF_UP);
log.info("invoiceMoney=>{} ,difference=>{}", invoiceMoney.toString(), difference.toString()); log.info("invoiceMoney=>{} ,difference=>{}", invoiceMoney.toString(), difference.toString());
@ -4896,28 +4830,6 @@ public class SupplierServiceImpl implements SupplierService {
}}); }});
// RPA调用判断 // RPA调用判断
SysConfig config = sysConfigMapper.selectByCode("RPA_FLAG"); SysConfig config = sysConfigMapper.selectByCode("RPA_FLAG");
if (config == null || config.getValue().equals("1")) {
//调用ics20220413
String token = concurService.getToken();
log.info("调用APInvoice接口 发票id{}", invoiceId);
String post = HttpRequest.post(concurConfig.getBaseUrl() + concurConfig.getSendApInvoice())
.header("token", token)
.form("ocrId", invoiceId)
.form("opType", "sendApInvoice")
.execute().body();
log.info("调用APInvoice接口{}", post);
if (post.indexOf("操作成功") > -1) {
// 20220413invoice_type:1-OA 2-ebs
List<Long> ids = supplierOrderItemMatchingMapper.selectIdsByStatusAndInvoiceId(invoiceId, 1);
supplierOutService.sendMatchingData(ids, invoiceId);
} else {
return Response.failure("ics sendApInvoice ERROR");
}
} else {
log.info("等待RPA修改状态:" + invoiceId);
}
CorporateInvoice corporateInvoice = corporateInvoiceMapper.selectByPrimaryKey(invoiceId); CorporateInvoice corporateInvoice = corporateInvoiceMapper.selectByPrimaryKey(invoiceId);
//插入日志记录 2022/6/17 //插入日志记录 2022/6/17
@ -6073,4 +5985,12 @@ public class SupplierServiceImpl implements SupplierService {
} }
return token; return token;
} }
@Override
public RestResponse matchInvoices(String numberS, String numberE, Integer invoiceType) {
List<InvoiceItemListDto> list = corporateInvoiceMapper.supplierInvoiceMatchInvoiceList(numberS, numberE, invoiceType);
for (InvoiceItemListDto invoiceItemListDto : list) {
invoiceItemListDto.setUsedMoney(supplierOrderItemMatchingMapper.getUsedAmountByItemId(invoiceItemListDto.getId()));
}
return RestResponse.success(list);
}
} }

Loading…
Cancel
Save