|
|
|
@ -7,10 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|
|
|
import com.fasterxml.jackson.core.type.TypeReference; |
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import com.gaotao.common.exception.XJException; |
|
|
|
import com.gaotao.common.utils.DateUtils; |
|
|
|
import com.gaotao.common.utils.HttpUtils; |
|
|
|
import com.gaotao.common.utils.PageUtils; |
|
|
|
import com.gaotao.common.utils.R; |
|
|
|
import com.gaotao.common.utils.*; |
|
|
|
import com.gaotao.modules.inspection.service.IfsInspectionHistoryService; |
|
|
|
import com.gaotao.modules.po.dao.PoReceiptDetailMapper; |
|
|
|
import com.gaotao.modules.po.dao.PoReceiptMapper; |
|
|
|
@ -69,7 +66,7 @@ public class PurchaseManageServiceImpl implements PurchaseManageService { |
|
|
|
|
|
|
|
@Value("${custom.ifs-domainUserID}") |
|
|
|
private String domainUserID; |
|
|
|
|
|
|
|
|
|
|
|
@Value("${ldap-control.control-flag:false}") |
|
|
|
private Boolean ldapFlag; |
|
|
|
|
|
|
|
@ -89,7 +86,7 @@ public class PurchaseManageServiceImpl implements PurchaseManageService { |
|
|
|
} |
|
|
|
return domainUserID; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public PageUtils getReceiptRecordList(PoReceiptQueryDto queryDto) { |
|
|
|
IPage<Map<String, Object>> page = poReceiptMapper.getReceiptRecordList( |
|
|
|
@ -133,7 +130,7 @@ public class PurchaseManageServiceImpl implements PurchaseManageService { |
|
|
|
@Override |
|
|
|
public PageUtils getCancelableReceiptList(PoReceiptQueryDto queryDto) { |
|
|
|
// 只查询状态为已接收且未取消的记录 |
|
|
|
queryDto.setStatus("RECEIVED"); |
|
|
|
queryDto.setStatus("ARRIVED"); |
|
|
|
IPage<Map<String, Object>> page = poReceiptMapper.getCancelableReceiptList( |
|
|
|
new Page<>(queryDto.getPage(), queryDto.getSize()), queryDto); |
|
|
|
return new PageUtils(page); |
|
|
|
@ -148,17 +145,11 @@ public class PurchaseManageServiceImpl implements PurchaseManageService { |
|
|
|
String cancelReason = (String) params.get("cancelReason"); |
|
|
|
Double itemNo = params.get("itemNo") != null ? Double.valueOf(params.get("itemNo").toString()) : null; |
|
|
|
|
|
|
|
// 1. 条件校验:验证库存 |
|
|
|
R validationResult = validateInventoryForCancel(receiptNo, site, itemNo); |
|
|
|
if ((int)validationResult.get("code") != 0) { |
|
|
|
return validationResult; |
|
|
|
} |
|
|
|
|
|
|
|
// 2. 调用IFS接口同步取消操作 |
|
|
|
syncCancelToIfs(receiptNo, site, itemNo, cancelReason); |
|
|
|
|
|
|
|
// 3. 更新本地记录状态 |
|
|
|
updateLocalRecordStatus(receiptNo, site, itemNo, "CANCELLED", cancelReason); |
|
|
|
updateLocalRecordStatus(receiptNo, site, itemNo, "CANCEL", cancelReason); |
|
|
|
|
|
|
|
return R.ok("取消接收成功"); |
|
|
|
|
|
|
|
@ -209,67 +200,46 @@ public class PurchaseManageServiceImpl implements PurchaseManageService { |
|
|
|
return poReceiptDetailMapper.getInspectionRecordsByReceiptNo(receiptNo, site); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 验证库存是否可以取消 |
|
|
|
*/ |
|
|
|
private R validateInventoryForCancel(String receiptNo, String site, Double itemNo) { |
|
|
|
// 获取接收记录明细 |
|
|
|
LambdaQueryWrapper<PoReceiptDetail> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(PoReceiptDetail::getReceiptNo, receiptNo) |
|
|
|
.eq(PoReceiptDetail::getSite, site); |
|
|
|
if (itemNo != null) { |
|
|
|
wrapper.eq(PoReceiptDetail::getItemNo, itemNo); |
|
|
|
} |
|
|
|
List<PoReceiptDetail> details = poReceiptDetailMapper.selectList(wrapper); |
|
|
|
|
|
|
|
for (PoReceiptDetail detail : details) { |
|
|
|
// 检查库存位置、批号和数量是否满足取消条件 |
|
|
|
LambdaQueryWrapper<InventoryStock> stockWrapper = new LambdaQueryWrapper<>(); |
|
|
|
stockWrapper.eq(InventoryStock::getSite, site) |
|
|
|
.eq(InventoryStock::getPartNo, detail.getPartNo()) |
|
|
|
.eq(InventoryStock::getBatchNo, detail.getBatchNo()) |
|
|
|
.eq(InventoryStock::getLocationId, detail.getLocationId()); |
|
|
|
|
|
|
|
InventoryStock stock = inventoryStockMapper.selectOne(stockWrapper); |
|
|
|
if (stock == null) { |
|
|
|
return R.error("物料 " + detail.getPartNo() + " 在库位 " + detail.getLocationId() + " 的库存不存在"); |
|
|
|
} |
|
|
|
|
|
|
|
if (stock.getQtyOnHand().compareTo(detail.getQtyReceived()) < 0) { |
|
|
|
return R.error("物料 " + detail.getPartNo() + " 库存数量不足,无法取消接收"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return R.ok(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 同步取消操作到IFS |
|
|
|
*/ |
|
|
|
private void syncCancelToIfs(String receiptNo, String site, Double itemNo, String cancelReason) { |
|
|
|
try { |
|
|
|
Map<String, Object> params = Map.of( |
|
|
|
"ifsDBName", ifsDBName, |
|
|
|
"domainUserID", getCurrentDomainUserID(), |
|
|
|
"ifsSiteID", site, |
|
|
|
"receiptNo", receiptNo, |
|
|
|
"itemNo", itemNo != null ? itemNo : 0, |
|
|
|
"cancelReason", cancelReason |
|
|
|
); |
|
|
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper(); |
|
|
|
String jsonBody = objectMapper.writeValueAsString(params); |
|
|
|
String response = HttpUtils.doPost(ifsUrl + "CancelReceipt", jsonBody, null); |
|
|
|
|
|
|
|
// 解析响应 |
|
|
|
Map<String, Object> responseData = objectMapper.readValue(response, new TypeReference<>() {}); |
|
|
|
Boolean success = (Boolean) responseData.get("success"); |
|
|
|
|
|
|
|
if (success != null && success) { |
|
|
|
log.info("IFS同步成功"); |
|
|
|
} else { |
|
|
|
String errorMsg = (String) responseData.get("message"); |
|
|
|
throw new XJException("IFS同步失败: " + errorMsg); |
|
|
|
// 根据receiptNo、site、itemNo查询PoReceiptDetail记录,获取订单相关信息 |
|
|
|
LambdaQueryWrapper<PoReceiptDetail> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(PoReceiptDetail::getReceiptNo, receiptNo) |
|
|
|
.eq(PoReceiptDetail::getSite, site); |
|
|
|
if (itemNo != null) { |
|
|
|
wrapper.eq(PoReceiptDetail::getItemNo, itemNo); |
|
|
|
} |
|
|
|
|
|
|
|
List<PoReceiptDetail> details = poReceiptDetailMapper.selectList(wrapper); |
|
|
|
if (details.isEmpty()) { |
|
|
|
throw new XJException("未找到对应的接收记录"); |
|
|
|
} |
|
|
|
|
|
|
|
// 对每个接收记录调用IFS取消方法 |
|
|
|
for (PoReceiptDetail detail : details) { |
|
|
|
Map<String, Object> params = Map.of( |
|
|
|
"ifsDBName", ifsDBName, |
|
|
|
"domainUserID", getCurrentDomainUserID(), |
|
|
|
"ifsSiteID", site, |
|
|
|
"ifsReceiptSequence", "2690471" |
|
|
|
); |
|
|
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper(); |
|
|
|
String jsonBody = objectMapper.writeValueAsString(params); |
|
|
|
String ifsResponse = HttpUtils.doPost(ifsUrl + "CancelPurchaseOrderArrival", jsonBody, null); |
|
|
|
|
|
|
|
if ("IFSUpdated".equals(ifsResponse) || "\"IFSUpdated\"".equals(ifsResponse)) { |
|
|
|
log.info("IFS取消接收成功,PO号: {}", detail.getOrderNo()); |
|
|
|
} else { |
|
|
|
log.error("IFS取消接收失败,PO号: {}, 响应: {}", detail.getOrderNo(), ifsResponse); |
|
|
|
// 同步失败需要回滚前面所有的数据库操作 |
|
|
|
String errorMessage = IfsErrorMessageUtils.extractOracleErrorMessage(ifsResponse); |
|
|
|
throw new XJException(errorMessage); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
@ -295,57 +265,4 @@ public class PurchaseManageServiceImpl implements PurchaseManageService { |
|
|
|
poReceiptDetailMapper.update(detail, detailWrapper); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 从IFS获取检验数据 |
|
|
|
*/ |
|
|
|
private List<Map<String, Object>> getIfsInspectionData(String site) { |
|
|
|
try { |
|
|
|
Map<String, Object> params = Map.of( |
|
|
|
"ifsDBName", ifsDBName, |
|
|
|
"domainUserID", getCurrentDomainUserID(), |
|
|
|
"ifsSiteID", site |
|
|
|
); |
|
|
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper(); |
|
|
|
String jsonBody = objectMapper.writeValueAsString(params); |
|
|
|
String response = HttpUtils.doGetWithBody(ifsUrl + "InspectionResults", jsonBody, null); |
|
|
|
|
|
|
|
return objectMapper.readValue(response, new TypeReference<>() {}); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
log.error("获取IFS检验数据异常: {}", e.getMessage(), e); |
|
|
|
return new ArrayList<>(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 更新本地检验记录 |
|
|
|
*/ |
|
|
|
private int updateLocalInspectionRecords(List<Map<String, Object>> inspectionData) { |
|
|
|
int updatedCount = 0; |
|
|
|
|
|
|
|
for (Map<String, Object> data : inspectionData) { |
|
|
|
String receiptNo = (String) data.get("receiptNo"); |
|
|
|
String site = (String) data.get("site"); |
|
|
|
Double itemNo = (Double) data.get("itemNo"); |
|
|
|
BigDecimal qtyApproved = new BigDecimal(data.get("qtyApproved").toString()); |
|
|
|
String inspectionRemark = (String) data.get("inspectionRemark"); |
|
|
|
|
|
|
|
// 更新对应的接收明细记录 |
|
|
|
LambdaQueryWrapper<PoReceiptDetail> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(PoReceiptDetail::getReceiptNo, receiptNo) |
|
|
|
.eq(PoReceiptDetail::getSite, site) |
|
|
|
.eq(PoReceiptDetail::getItemNo, itemNo); |
|
|
|
|
|
|
|
PoReceiptDetail detail = new PoReceiptDetail(); |
|
|
|
detail.setQtyApproved(qtyApproved); |
|
|
|
detail.setRemark2(inspectionRemark); |
|
|
|
detail.setInspectionTime(new Date()); |
|
|
|
|
|
|
|
int updated = poReceiptDetailMapper.update(detail, wrapper); |
|
|
|
updatedCount += updated; |
|
|
|
} |
|
|
|
|
|
|
|
return updatedCount; |
|
|
|
} |
|
|
|
} |