Browse Source

采购接收记录取消

master
han\hanst 8 months ago
parent
commit
da6ce98e51
  1. 21
      src/main/java/com/gaotao/modules/inspection/service/impl/QualifiedStorageServiceImpl.java
  2. 8
      src/main/java/com/gaotao/modules/po/service/impl/PoServiceImpl.java
  3. 161
      src/main/java/com/gaotao/modules/po/service/impl/PurchaseManageServiceImpl.java
  4. 13
      src/main/java/com/gaotao/modules/scrap/service/impl/ScrapServiceImpl.java
  5. 1
      src/main/java/com/gaotao/modules/trans/entity/TransDetailDto.java
  6. 212
      src/main/resources/mapper/procurement/PoReceiptMapper.xml

21
src/main/java/com/gaotao/modules/inspection/service/impl/QualifiedStorageServiceImpl.java

@ -1,6 +1,8 @@
package com.gaotao.modules.inspection.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gaotao.common.exception.XJException;
import com.gaotao.common.utils.IfsErrorMessageUtils;
import com.gaotao.common.utils.R;
@ -353,6 +355,18 @@ public class QualifiedStorageServiceImpl implements QualifiedStorageService {
String result = ifsApiIssueAndReturnService.purchaseOrderMoveToStockOneLocation(moveDto);
if ("IFSUpdated".equals(result) || "\"IFSUpdated\"".equals(result)) {
// 8. IFS接口调用成功后更新接收记录状态
LambdaUpdateWrapper<PoReceiptDetail> receiptDetailQueryWrapper = Wrappers.lambdaUpdate();
receiptDetailQueryWrapper.eq(PoReceiptDetail::getSite, site)
.eq(PoReceiptDetail::getOrderNo, sourceRef1)
.eq(PoReceiptDetail::getOrderItemNo, sourceRef2)
.eq(PoReceiptDetail::getOrderReleaseNo, sourceRef3)
.eq(PoReceiptDetail::getItemNo, receiptNo);
PoReceiptDetail poReceiptDetail = new PoReceiptDetail();
poReceiptDetail.setStatus("RECEIVED"); // 设置为已入库
poReceiptDetailService.update(poReceiptDetail, receiptDetailQueryWrapper);
log.info("检验合格入库成功,事务号: {}, HandlingUnit数量: {}", inboundTransNo, handlingUnits.size());
return R.ok("检验合格入库成功");
} else {
@ -360,7 +374,6 @@ public class QualifiedStorageServiceImpl implements QualifiedStorageService {
String errorMessage = IfsErrorMessageUtils.extractOracleErrorMessage(result);
throw new XJException("IFS移库失败: " + errorMessage);
}
} catch (Exception e) {
log.error("检验合格入库失败: {}", e.getMessage());
throw new RuntimeException(e.getMessage(), e);
@ -375,19 +388,19 @@ public class QualifiedStorageServiceImpl implements QualifiedStorageService {
// 直接在此方法中实现库存创建逻辑使用带行锁的库存操作防止并发
String site = transDetail.getSite();
String locationId = transDetail.getLocationId();
// 根据库位获取仓库ID
String warehouseId = null;
Location location = locationService.getByLocationIdAndSite(site, locationId);
if (location != null) {
warehouseId = location.getWarehouseId();
}
// 如果根据库位获取不到仓库则使用transHeader中的仓库ID作为备用
if (StringUtils.isBlank(warehouseId)) {
warehouseId = transHeader.getWarehouseId();
}
String partNo = transDetail.getPartNo();
String batchNo = transDetail.getBatchNo();
String wdr = firstHu.getWdr() != null ? firstHu.getWdr() : "*";

8
src/main/java/com/gaotao/modules/po/service/impl/PoServiceImpl.java

@ -326,19 +326,19 @@ public class PoServiceImpl extends ServiceImpl<PoMapper, PurchaseOrder> implemen
// 直接在此方法中实现库存创建逻辑使用带行锁的库存操作防止并发
String site = inData.getSite();
String locationId = inData.getLocationNo();
// 根据库位获取仓库ID
String warehouseId = null;
Location location = locationService.getByLocationIdAndSite(site, locationId);
if (location != null) {
warehouseId = location.getWarehouseId();
}
// 如果根据库位获取不到仓库则使用transHeader中的仓库ID作为备用
if (StringUtils.isBlank(warehouseId)) {
warehouseId = transHeader.getWarehouseId();
}
String partNo = inData.getPartNo();
String batchNo = inData.getBatchNo();
String wdr = inData.getWdr();
@ -560,7 +560,7 @@ public class PoServiceImpl extends ServiceImpl<PoMapper, PurchaseOrder> implemen
poReceiptDetail.setPartNo(inData.getPartNo());
poReceiptDetail.setPartDesc(inData.getPartDesc());
// 基本字段设置
poReceiptDetail.setArriveQty(inData.getTransQty());
poReceiptDetail.setArriveQty(inData.getQtyToReceive());
poReceiptDetail.setQtyInspectedNew(BigDecimal.valueOf(0.0));
poReceiptDetail.setPoumId(inData.getPurchaseUOM() != null ? inData.getPurchaseUOM() : "");
poReceiptDetail.setConvertFactor(inData.getConvertFactor() != null ? inData.getConvertFactor() : 1);

161
src/main/java/com/gaotao/modules/po/service/impl/PurchaseManageServiceImpl.java

@ -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);
// 根据receiptNositeitemNo查询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;
}
}

13
src/main/java/com/gaotao/modules/scrap/service/impl/ScrapServiceImpl.java

@ -20,6 +20,8 @@ import com.gaotao.modules.sys.controller.AbstractController;
import com.gaotao.modules.handlingunit.entity.HandlingUnit;
import com.gaotao.modules.handlingunit.service.HandlingUnitService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gaotao.modules.warehouse.entity.InventoryStock;
import com.gaotao.modules.warehouse.service.InventoryStockService;
import org.apache.shiro.SecurityUtils;
@ -231,7 +233,16 @@ public class ScrapServiceImpl extends AbstractController implements ScrapService
stock.setOutQty((stock.getOutQty() != null ? stock.getOutQty() : BigDecimal.ZERO).add(label.getQuantity()));
stock.setLatestOutDate(new Date());
inventoryStockService.updateById(stock);
// 使用复合主键条件更新库存记录
LambdaUpdateWrapper<InventoryStock> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(InventoryStock::getSite, site)
.eq(InventoryStock::getWarehouseId, label.getWarehouseId())
.eq(InventoryStock::getPartNo, label.getPartNo())
.eq(InventoryStock::getBatchNo, label.getBatchNo())
.eq(InventoryStock::getLocationId, label.getLocationId())
.eq(InventoryStock::getWdr, handlingUnit.getWdr() != null ? handlingUnit.getWdr() : "*");
inventoryStockService.update(stock, updateWrapper);
log.info("库存更新成功 - 物料: {}, 批次: {}, 库位: {}, WDR: {}, 原库存: {}, 报废数量: {}, 新库存: {}",
label.getPartNo(), label.getBatchNo(), label.getLocationId(),
handlingUnit.getWdr() != null ? handlingUnit.getWdr() : "", currentQty, label.getQuantity(), newQty);

1
src/main/java/com/gaotao/modules/trans/entity/TransDetailDto.java

@ -28,6 +28,7 @@ public class TransDetailDto extends TransDetail{
private String inventoryPartDB; // 库存物料DB
private String partDesc; // 物料描述
private String wdr; // WDR
private BigDecimal qtyToReceive; // 待接收数量
private String samplePercent; // 抽样百分比
private String sampleQty; // 抽样数量

212
src/main/resources/mapper/procurement/PoReceiptMapper.xml

@ -5,62 +5,62 @@
<!-- 获取采购订单接收记录列表 -->
<select id="getReceiptRecordList" resultType="java.util.Map">
SELECT
SELECT
prd.site,
prd.receipt_no,
prd.item_no,
prd.part_no,
prd.arrive_qty,
prd.qty_inspected_new,
prd.poum_id,
prd.convert_factor,
prd.receipt_no AS receiptNo,
prd.item_no AS itemNo,
prd.part_no AS partNo,
prd.arrive_qty AS arriveQty,
prd.qty_inspected_new AS qtyInspectedNew,
prd.poum_id AS poumId,
prd.convert_factor AS convertFactor,
prd.status,
prd.need_inspect_flag,
prd.inspect_code,
prd.qty_sample,
prd.percent_sample,
prd.qty_to_inspect,
prd.qty_inspected,
prd.qty_approved,
prd.qty_returned,
prd.qty_replace,
prd.qty_scrapt,
prd.qty_to_received,
prd.qty_received,
prd.invoice_qty,
prd.invoice_price,
prd.invoice_no,
prd.location_id,
prd.order_no,
prd.order_item_no,
prd.cance_iremark,
prd.batch_no,
prd.manu_facture_date,
prd.expired_date,
prd.sample_inspection_method_id,
prd.sample_inspection_level_no,
prd.need_inspect_flag AS needInspectFlag,
prd.inspect_code AS inspectCode,
prd.qty_sample AS qtySample,
prd.percent_sample AS percentSample,
prd.qty_to_inspect AS qtyToInspect,
prd.qty_inspected AS qtyInspected,
prd.qty_approved AS qtyApproved,
prd.qty_returned AS qtyReturned,
prd.qty_replace AS qtyReplace,
prd.qty_scrapt AS qtyScrapt,
prd.qty_to_received AS qtyToReceived,
prd.qty_received AS qtyReceived,
prd.invoice_qty AS invoiceQty,
prd.invoice_price AS invoicePrice,
prd.invoice_no AS invoiceNo,
prd.location_id AS locationId,
prd.order_no AS orderNo,
prd.order_item_no AS orderItemNo,
prd.cance_iremark AS canceIremark,
prd.batch_no AS batchNo,
prd.manu_facture_date AS manuFactureDate,
prd.expired_date AS expiredDate,
prd.sample_inspection_method_id AS sampleInspectionMethodId,
prd.sample_inspection_level_no AS sampleInspectionLevelNo,
prd.remark,
prd.to_inv_nofity_qty,
prd.inv_notify_qty,
prd.inspect_type_db,
prd.inspect_type,
prd.need_receive_flag,
prd.to_invoice_qty,
prd.qty_rbjs,
prd.to_inv_nofity_qty AS toInvNofityQty,
prd.inv_notify_qty AS invNotifyQty,
prd.inspect_type_db AS inspectTypeDb,
prd.inspect_type AS inspectType,
prd.need_receive_flag AS needReceiveFlag,
prd.to_invoice_qty AS toInvoiceQty,
prd.qty_rbjs AS qtyRbjs,
prd.orderfef1,
prd.orderfef2,
prd.orderfef_type,
prd.price_no_tax,
prd.orderfef_type AS orderfefType,
prd.price_no_tax AS priceNoTax,
prd.status2,
prd.check_by,
prd.check_by AS checkBy,
prd.remark2,
prd.inspector,
prd.inspection_time,
pr.receive_date,
pr.supplier_id,
prd.inspection_time AS inspectionTime,
pr.receive_date AS receiveDate,
pr.supplier_id AS supplierId,
pr.receiver,
pr.delivery_note_no,
pr.warehouse_id
pr.delivery_note_no AS deliveryNoteNo,
pr.warehouse_id AS warehouseId
FROM po_receipt_detail prd
LEFT JOIN po_receipt pr ON prd.receipt_no = pr.receipt_no AND prd.site = pr.site
<where>
@ -97,66 +97,66 @@
<!-- 获取可取消的接收记录列表 -->
<select id="getCancelableReceiptList" resultType="java.util.Map">
SELECT
SELECT
prd.site,
prd.receipt_no,
prd.item_no,
prd.part_no,
prd.arrive_qty,
prd.qty_inspected_new,
prd.poum_id,
prd.convert_factor,
prd.receipt_no AS receiptNo,
prd.item_no AS itemNo,
prd.part_no AS partNo,
prd.arrive_qty AS arriveQty,
prd.qty_inspected_new AS qtyInspectedNew,
prd.poum_id AS poumId,
prd.convert_factor AS convertFactor,
prd.status,
prd.need_inspect_flag,
prd.inspect_code,
prd.qty_sample,
prd.percent_sample,
prd.qty_to_inspect,
prd.qty_inspected,
prd.qty_approved,
prd.qty_returned,
prd.qty_replace,
prd.qty_scrapt,
prd.qty_to_received,
prd.qty_received,
prd.invoice_qty,
prd.invoice_price,
prd.invoice_no,
prd.location_id,
prd.order_no,
prd.order_item_no,
prd.cance_iremark,
prd.batch_no,
prd.manu_facture_date,
prd.expired_date,
prd.sample_inspection_method_id,
prd.sample_inspection_level_no,
prd.need_inspect_flag AS needInspectFlag,
prd.inspect_code AS inspectCode,
prd.qty_sample AS qtySample,
prd.percent_sample AS percentSample,
prd.qty_to_inspect AS qtyToInspect,
prd.qty_inspected AS qtyInspected,
prd.qty_approved AS qtyApproved,
prd.qty_returned AS qtyReturned,
prd.qty_replace AS qtyReplace,
prd.qty_scrapt AS qtyScrapt,
prd.qty_to_received AS qtyToReceived,
prd.qty_received AS qtyReceived,
prd.invoice_qty AS invoiceQty,
prd.invoice_price AS invoicePrice,
prd.invoice_no AS invoiceNo,
prd.location_id AS locationId,
prd.order_no AS orderNo,
prd.order_item_no AS orderItemNo,
prd.cance_iremark AS canceIremark,
prd.batch_no AS batchNo,
prd.manu_facture_date AS manuFactureDate,
prd.expired_date AS expiredDate,
prd.sample_inspection_method_id AS sampleInspectionMethodId,
prd.sample_inspection_level_no AS sampleInspectionLevelNo,
prd.remark,
prd.to_inv_nofity_qty,
prd.inv_notify_qty,
prd.inspect_type_db,
prd.inspect_type,
prd.need_receive_flag,
prd.to_invoice_qty,
prd.qty_rbjs,
prd.to_inv_nofity_qty AS toInvNofityQty,
prd.inv_notify_qty AS invNotifyQty,
prd.inspect_type_db AS inspectTypeDb,
prd.inspect_type AS inspectType,
prd.need_receive_flag AS needReceiveFlag,
prd.to_invoice_qty AS toInvoiceQty,
prd.qty_rbjs AS qtyRbjs,
prd.orderfef1,
prd.orderfef2,
prd.orderfef_type,
prd.price_no_tax,
prd.orderfef_type AS orderfefType,
prd.price_no_tax AS priceNoTax,
prd.status2,
prd.check_by,
prd.check_by AS checkBy,
prd.remark2,
prd.inspector,
prd.inspection_time,
pr.receive_date,
pr.supplier_id,
prd.inspection_time AS inspectionTime,
pr.receive_date AS receiveDate,
pr.supplier_id AS supplierId,
pr.receiver,
pr.delivery_note_no,
pr.warehouse_id
pr.delivery_note_no AS deliveryNoteNo,
pr.warehouse_id AS warehouseId
FROM po_receipt_detail prd
INNER JOIN po_receipt pr ON prd.receipt_no = pr.receipt_no AND prd.site = pr.site
<where>
AND prd.status = 'RECEIVED'
AND prd.status = 'ARRIVED'
AND prd.qty_received > 0
<if test="params.site != null and params.site != ''">
AND prd.site = #{params.site}
@ -185,21 +185,21 @@
<!-- 获取已检验合格的接收记录列表 -->
<select id="getInspectedReceiptList" resultType="java.util.Map">
SELECT
SELECT
pr.site,
pr.receipt_no,
pr.receive_date,
pr.supplier_id,
pr.receipt_no AS receiptNo,
pr.receive_date AS receiveDate,
pr.supplier_id AS supplierId,
pr.receiver,
pr.delivery_note_no,
pr.delivery_note_no AS deliveryNoteNo,
pr.remark,
pr.warehouse_id,
prd.part_no,
prd.batch_no,
prd.qty_approved,
prd.inspection_time,
pr.warehouse_id AS warehouseId,
prd.part_no AS partNo,
prd.batch_no AS batchNo,
prd.qty_approved AS qtyApproved,
prd.inspection_time AS inspectionTime,
prd.inspector,
prd.remark2 as inspection_remark
prd.remark2 AS inspectionRemark
FROM po_receipt pr
INNER JOIN po_receipt_detail prd ON pr.receipt_no = prd.receipt_no AND pr.site = prd.site
<where>

Loading…
Cancel
Save