diff --git a/hw-modules/hw-wms/src/main/java/com/hw/wms/controller/WmsRawOutstockController.java b/hw-modules/hw-wms/src/main/java/com/hw/wms/controller/WmsRawOutstockController.java index 83987342..5d436ab4 100644 --- a/hw-modules/hw-wms/src/main/java/com/hw/wms/controller/WmsRawOutstockController.java +++ b/hw-modules/hw-wms/src/main/java/com/hw/wms/controller/WmsRawOutstockController.java @@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletResponse; import com.hw.common.core.constant.WmsConstants; import com.hw.wms.domain.WmsBaseWarehouse; import com.hw.wms.domain.WmsStockTotal; +import com.hw.wms.domain.dto.OutstockRequestDTO; import com.hw.wms.domain.vo.WmsRawOutstockAuditVo; import com.hw.wms.service.IWmsBaseWarehouseService; import com.hw.wms.service.IWmsStockTotalService; @@ -190,4 +191,16 @@ public class WmsRawOutstockController extends BaseController public AjaxResult applyRawOutstock(@Validated @RequestBody WmsRawOutstock wmsRawOutstock) { return toAjax(wmsRawOutstockService.applyRawOutstock(wmsRawOutstock)); } + + /** + * 关联销售订单 + * @param outstockRequestDTO + * @return + */ + @RequiresPermissions("wms:rawOutstockDetail:relation") + @Log(title = "原材料出库记录", businessType = BusinessType.UPDATE) + @PostMapping("/relateSaleOrder") + public AjaxResult associatedSalesOrders(@RequestBody OutstockRequestDTO outstockRequestDTO) { + return toAjax(wmsRawOutstockService.associatedSalesOrders(outstockRequestDTO)); + } } diff --git a/hw-modules/hw-wms/src/main/java/com/hw/wms/domain/dto/OutstockRequestDTO.java b/hw-modules/hw-wms/src/main/java/com/hw/wms/domain/dto/OutstockRequestDTO.java new file mode 100644 index 00000000..d336b65e --- /dev/null +++ b/hw-modules/hw-wms/src/main/java/com/hw/wms/domain/dto/OutstockRequestDTO.java @@ -0,0 +1,50 @@ +package com.hw.wms.domain.dto; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * 关联销售订单DTO + * + * @author Yinq + * @date 2025-06-19 + */ +public class OutstockRequestDTO implements Serializable { + private static final long serialVersionUID = 1L; + private Long rawOutstockDetailId; + private BigDecimal outstockAmount; + private List saleOrders; + + public BigDecimal getOutstockAmount() { + return outstockAmount; + } + + public void setOutstockAmount(BigDecimal outstockAmount) { + this.outstockAmount = outstockAmount; + } + + public Long getRawOutstockDetailId() { + return rawOutstockDetailId; + } + + public void setRawOutstockDetailId(Long rawOutstockDetailId) { + this.rawOutstockDetailId = rawOutstockDetailId; + } + + public List getSaleOrders() { + return saleOrders; + } + + public void setSaleOrders(List saleOrders) { + this.saleOrders = saleOrders; + } + + @Override + public String toString() { + return "OutstockRequestDTO{" + + "rawOutstockDetailId=" + rawOutstockDetailId + + ", saleOrders=" + saleOrders + + '}'; + } +} diff --git a/hw-modules/hw-wms/src/main/java/com/hw/wms/domain/dto/SaleOrderDTO.java b/hw-modules/hw-wms/src/main/java/com/hw/wms/domain/dto/SaleOrderDTO.java new file mode 100644 index 00000000..224bd59f --- /dev/null +++ b/hw-modules/hw-wms/src/main/java/com/hw/wms/domain/dto/SaleOrderDTO.java @@ -0,0 +1,72 @@ +package com.hw.wms.domain.dto; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 关联销售订单对象 + * + * @author Yinq + * @date 2025-06-19 + */ +public class SaleOrderDTO implements Serializable { + private static final long serialVersionUID = 1L; + + private String saleorderCode; + private BigDecimal outstockAmount; + private Long saleOrderId; + private String materialCode; + private String materialName; + + public String getSaleorderCode() { + return saleorderCode; + } + + public void setSaleorderCode(String saleorderCode) { + this.saleorderCode = saleorderCode; + } + + public BigDecimal getOutstockAmount() { + return outstockAmount; + } + + public void setOutstockAmount(BigDecimal outstockAmount) { + this.outstockAmount = outstockAmount; + } + + public Long getSaleOrderId() { + return saleOrderId; + } + + public void setSaleOrderId(Long saleOrderId) { + this.saleOrderId = saleOrderId; + } + + public String getMaterialCode() { + return materialCode; + } + + public void setMaterialCode(String materialCode) { + this.materialCode = materialCode; + } + + public String getMaterialName() { + return materialName; + } + + public void setMaterialName(String materialName) { + this.materialName = materialName; + } + + + @Override + public String toString() { + return "SaleOrderDTO{" + + "saleorderCode='" + saleorderCode + '\'' + + ", outstockAmount=" + outstockAmount + + ", saleOrderId=" + saleOrderId + + ", materialCode='" + materialCode + '\'' + + ", materialName='" + materialName + '\'' + + '}'; + } +} diff --git a/hw-modules/hw-wms/src/main/java/com/hw/wms/service/IWmsRawOutstockService.java b/hw-modules/hw-wms/src/main/java/com/hw/wms/service/IWmsRawOutstockService.java index 3d6e4808..51d7b60c 100644 --- a/hw-modules/hw-wms/src/main/java/com/hw/wms/service/IWmsRawOutstockService.java +++ b/hw-modules/hw-wms/src/main/java/com/hw/wms/service/IWmsRawOutstockService.java @@ -6,6 +6,7 @@ import java.util.List; import com.alibaba.fastjson2.JSONObject; import com.hw.wms.domain.WmsRawOutstock; import com.hw.wms.domain.WmsRawOutstockDetail; +import com.hw.wms.domain.dto.OutstockRequestDTO; import com.hw.wms.domain.vo.*; import org.springframework.transaction.annotation.Transactional; @@ -169,5 +170,13 @@ public interface IWmsRawOutstockService * @return */ public List selectWmsRawOutstockJoinMaterialList(WmsRawOutstock wmsRawOutstock); + + /** + * 关联销售订单 + * @param outstockRequestDTO + * @return + */ + public int associatedSalesOrders(OutstockRequestDTO outstockRequestDTO); + } diff --git a/hw-modules/hw-wms/src/main/java/com/hw/wms/service/impl/WmsRawOutstockServiceImpl.java b/hw-modules/hw-wms/src/main/java/com/hw/wms/service/impl/WmsRawOutstockServiceImpl.java index 78c95f4f..2f7db80b 100644 --- a/hw-modules/hw-wms/src/main/java/com/hw/wms/service/impl/WmsRawOutstockServiceImpl.java +++ b/hw-modules/hw-wms/src/main/java/com/hw/wms/service/impl/WmsRawOutstockServiceImpl.java @@ -18,6 +18,8 @@ import com.hw.mes.api.domain.vo.MesBaseMaterialInfoVo; import com.hw.mes.api.domain.vo.MesPdaProductPlanVo; import com.hw.wms.config.WmsConfig; import com.hw.wms.domain.*; +import com.hw.wms.domain.dto.OutstockRequestDTO; +import com.hw.wms.domain.dto.SaleOrderDTO; import com.hw.wms.domain.vo.*; import com.hw.wms.mapper.*; import com.hw.wms.service.IWmsRawOutstockService; @@ -1446,4 +1448,68 @@ public class WmsRawOutstockServiceImpl implements IWmsRawOutstockService { public List selectWmsRawOutstockJoinMaterialList(WmsRawOutstock wmsRawOutstock){ return wmsRawOutstockMapper.selectWmsRawOutstockJoinMaterialList(wmsRawOutstock); } + + /** + * 关联销售订单 + * @param outstockRequestDTO + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int associatedSalesOrders(OutstockRequestDTO outstockRequestDTO) { + Long rawOutstockDetailId = outstockRequestDTO.getRawOutstockDetailId(); + List saleOrders = outstockRequestDTO.getSaleOrders(); + Date currentDate = new Date(); + String userName = SecurityUtils.getLoginUser() == null ? SecurityUtils.getUsername() : SecurityUtils.getLoginUser().getNickname(); + if (saleOrders.isEmpty()) { + throw new ServiceException("请关联销售订单!"); + } + + WmsRawOutstockDetail wmsRawOutstockDetail = wmsRawOutstockDetailMapper.selectWmsRawOutstockDetailByRawOutstockDetailId(rawOutstockDetailId); + WmsRawOutstock wmsRawOutstock = wmsRawOutstockMapper.selectWmsRawOutstockByRawOutstockId(wmsRawOutstockDetail.getRawOutstockId()); + String taskCode = wmsRawOutstock.getTaskCode(); + + BigDecimal sumAmount = saleOrders.stream().map(SaleOrderDTO::getOutstockAmount).reduce(BigDecimal.ZERO, BigDecimal::add); + if (outstockRequestDTO.getOutstockAmount().compareTo(sumAmount) > 0) { + BigDecimal amount = outstockRequestDTO.getOutstockAmount().subtract(sumAmount); + SaleOrderDTO orderDTO = new SaleOrderDTO(); + orderDTO.setSaleOrderId(wmsRawOutstock.getSaleOrderId()); + orderDTO.setOutstockAmount(amount); + saleOrders.add(0, orderDTO); + } + + for (int i = 0; i < saleOrders.size(); i++) { + SaleOrderDTO saleOrderDTO = saleOrders.get(i); + Long saleOrderId = saleOrderDTO.getSaleOrderId(); + BigDecimal outstockAmount = saleOrderDTO.getOutstockAmount(); + + wmsRawOutstock.setSaleOrderId(saleOrderId); + wmsRawOutstock.setOutstockAmount(outstockAmount); + wmsRawOutstock.setRealOutstockAmount(outstockAmount); + wmsRawOutstock.setUpdateBy(userName); + wmsRawOutstock.setUpdateDate(currentDate); + Long rawOutstockId = wmsRawOutstockDetail.getRawOutstockId(); + if (i == 0){ + wmsRawOutstockMapper.updateWmsRawOutstock(wmsRawOutstock); + } else { + wmsRawOutstock.setTaskCode(taskCode + "-" + i); + wmsRawOutstockMapper.insertWmsRawOutstock(wmsRawOutstock); + rawOutstockId = wmsRawOutstock.getRawOutstockId(); + } + + wmsRawOutstockDetail.setRawOutstockId(rawOutstockId); + wmsRawOutstockDetail.setPlanAmount(outstockAmount); + wmsRawOutstockDetail.setOutstockAmount(outstockAmount); + wmsRawOutstockDetail.setUpdateBy(userName); + wmsRawOutstockDetail.setUpdateDate(currentDate); + if (i == 0){ + wmsRawOutstockDetailMapper.updateWmsRawOutstockDetail(wmsRawOutstockDetail); + } else { + wmsRawOutstockDetailMapper.insertWmsRawOutstockDetail(wmsRawOutstockDetail); + } + + } + + return 1; + } } diff --git a/hw-modules/hw-wms/src/main/resources/mapper/wms/WmsRawOutstockDetailMapper.xml b/hw-modules/hw-wms/src/main/resources/mapper/wms/WmsRawOutstockDetailMapper.xml index 2b936cfa..b4f7b7c3 100644 --- a/hw-modules/hw-wms/src/main/resources/mapper/wms/WmsRawOutstockDetailMapper.xml +++ b/hw-modules/hw-wms/src/main/resources/mapper/wms/WmsRawOutstockDetailMapper.xml @@ -141,6 +141,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_by, update_date, stack_amount, + tips, #{rawOutstockId}, @@ -163,6 +164,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{updateBy}, #{updateDate}, #{stackAmount}, + #{tips}, diff --git a/hw-ui/src/api/wms/rawOutstockDetail.js b/hw-ui/src/api/wms/rawOutstockDetail.js index e33e8102..1f23d042 100644 --- a/hw-ui/src/api/wms/rawOutstockDetail.js +++ b/hw-ui/src/api/wms/rawOutstockDetail.js @@ -42,3 +42,12 @@ export function delRawOutstockDetail(rawOutstockDetailId) { method: 'delete' }) } + +// 关联销售订单 +export function relateSaleOrder(data) { + return request({ + url: '/wms/rawoutstock/relateSaleOrder', + method: 'post', + data: data + }) +} diff --git a/hw-ui/src/views/wms/info/rawOutstockDetail/index.vue b/hw-ui/src/views/wms/info/rawOutstockDetail/index.vue index 3c7e3069..e4199cd2 100644 --- a/hw-ui/src/views/wms/info/rawOutstockDetail/index.vue +++ b/hw-ui/src/views/wms/info/rawOutstockDetail/index.vue @@ -129,11 +129,13 @@ - + - + @@ -158,7 +160,7 @@ + v-if="columns[12].visible" width="100"> @@ -198,23 +200,32 @@ - + @@ -349,6 +360,103 @@ + + + + + + 任务编号:{{ relateSaleOrderForm.taskCode || getCurrentDetail('taskCode') }} + 计划编号:{{ relateSaleOrderForm.planCode || getCurrentDetail('planCode') }} + 物料编号:{{ relateSaleOrderForm.materialCode || getCurrentDetail('materialCode') }} + + + 物料名称:{{ relateSaleOrderForm.materialName || getCurrentDetail('materialName') }} + 计划数量:{{ relateSaleOrderForm.planAmount || getCurrentDetail('planAmount') }} + 出库数量:{{ relateSaleOrderForm.outstockAmount || getCurrentDetail('outstockAmount') }} + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + 添加销售订单 + +
+ +
+ + + + + + @@ -359,12 +467,17 @@ import { getRawOutstockDetail, delRawOutstockDetail, addRawOutstockDetail, - updateRawOutstockDetail + updateRawOutstockDetail, + relateSaleOrder } from "@/api/wms/rawOutstockDetail"; +import addSaleOrder from '@/views/mes/productOrder/addSaleOrder.vue'; export default { name: "RawOutstockDetail", dicts: ['wms_product_outstock_manualflag', 'qms_check_status', 'wms_erp_status', 'wms_execute_status', 'wms_audit_status', 'wms_raw_outstock_task_type'], + components: { + 'add-SaleOrder': addSaleOrder, + }, data() { return { // 遮罩层 @@ -455,6 +568,15 @@ export default { {key: 29, label: `物料编号`, visible: true}, {key: 30, label: `物料名称`, visible: true}, ], + relateSaleOrderDialogVisible: false, + relateSaleOrderForm: { + rawOutstockDetailId: null, + saleOrders: [ + // { saleorderCode: '', outstockAmount: 0 } + ] + }, + saleOrderSelectDialogVisible: false, + saleOrderSelectIndex: 0, // 当前操作的saleOrders下标 }; }, created() { @@ -544,7 +666,77 @@ export default { this.download('wms/rawOutstockDetail/export', { ...this.queryParams }, `rawOutstockDetail_${new Date().getTime()}.xlsx`) - } + }, + + handleRelateSaleOrder(row) { + this.relateSaleOrderForm = { + rawOutstockDetailId: row.rawOutstockDetailId, + outstockAmount: row.outstockAmount, + saleOrders: [ + {saleorderCode: '', outstockAmount: row.outstockAmount} + ] + }; + this.relateSaleOrderDialogVisible = true; + }, + addSaleOrder() { + // 新增一项并弹出选择销售订单弹窗 + const newIndex = this.relateSaleOrderForm.saleOrders.length; + this.relateSaleOrderForm.saleOrders.push({saleorderCode: '', outstockAmount: 1}); + this.saleOrderSelectIndex = newIndex; + this.saleOrderSelectDialogVisible = true; + }, + removeSaleOrder(index) { + this.relateSaleOrderForm.saleOrders.splice(index, 1); + }, + submitRelateSaleOrder() { + // 校验出库数量总和不能大于原出库数量 + const total = this.relateSaleOrderForm.saleOrders.reduce((sum, item) => sum + Number(item.outstockAmount), 0); + // 新增校验:出库数量不能小于等于0 + const hasInvalidAmount = this.relateSaleOrderForm.saleOrders.some(item => item.outstockAmount == null); + if (hasInvalidAmount) { + this.$message.error('出库数量不能为空!'); + return; + } + // 这里假设原出库数量在第一个saleOrders的outstockAmount里 + const originAmount = this.rawOutstockDetailList.find( + item => item.rawOutstockDetailId === this.relateSaleOrderForm.rawOutstockDetailId + )?.outstockAmount || 0; + if (total > originAmount) { + this.$message.error('出库数量总和不能大于原出库数量'); + return; + } + // 发送请求到后端 + relateSaleOrder(this.relateSaleOrderForm).then(res => { + this.$message.success('关联成功'); + this.relateSaleOrderDialogVisible = false; + this.getList(); + }); + }, + openSaleOrderSelect(index) { + this.saleOrderSelectIndex = index; + this.saleOrderSelectDialogVisible = true; + }, + submitSaleOrderSelect() { + let selectedRow = this.$refs.saleOrderRef.selectedRow; + if (!selectedRow) { + this.$message.error('请选择销售订单'); + return; + } + // 回填到对应的saleOrders项,增加物料编码和物料名称 + this.$set(this.relateSaleOrderForm.saleOrders, this.saleOrderSelectIndex, { + ...this.relateSaleOrderForm.saleOrders[this.saleOrderSelectIndex], + saleOrderId: selectedRow.saleOrderId, + saleorderCode: selectedRow.saleorderCode, + materialCode: selectedRow.materialCode, + materialName: selectedRow.materialName, + }); + this.saleOrderSelectDialogVisible = false; + }, + getCurrentDetail(field) { + // 根据 rawOutstockDetailId 查找当前明细行 + const detail = this.rawOutstockDetailList.find(item => item.rawOutstockDetailId === this.relateSaleOrderForm.rawOutstockDetailId) || {}; + return detail[field] || ''; + }, } } ;