From 7b10eff9c89d7ee86debc1783170ab93ee8f2f5c Mon Sep 17 00:00:00 2001 From: liuyuxin Date: Fri, 3 Apr 2026 15:32:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A5=E5=BA=93=E6=A8=A1=E5=9D=97=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/WornUniqueCodeController.java | 6 + .../unique/mapper/WornUniqueCodeMapper.java | 17 ++ .../service/IWornUniqueCodeService.java | 8 + .../impl/WornUniqueCodeServiceImpl.java | 37 ++- .../controller/WornInboundBillController.java | 30 +- .../controller/WornInboundItemController.java | 41 +-- .../project/worn/domain/WornInboundBill.java | 4 +- .../project/worn/domain/WornInboundItem.java | 153 +++++++++- .../project/worn/domain/WornMaterial.java | 13 +- .../worn/domain/dto/WornInboundItemDTO.java | 44 +++ .../dto/WornInboundPartialFinishDTO.java | 29 ++ .../dto/WornInboundPartialFinishItemDTO.java | 13 + .../worn/domain/dto/WornInboundUpdateDTO.java | 130 ++++++++ .../worn/mapper/WornInboundBillMapper.java | 10 + .../worn/mapper/WornInboundItemMapper.java | 24 ++ .../worn/service/IWornInboundBillService.java | 16 + .../worn/service/IWornInboundItemService.java | 7 +- .../impl/WornInboundBillServiceImpl.java | 289 +++++++++++++++++- .../impl/WornInboundItemServiceImpl.java | 270 +++++++++++++++- .../mybatis/system/SysDeptMapper.xml | 2 +- .../mybatis/unique/WornUniqueCodeMapper.xml | 95 +++++- .../mybatis/worn/WornInboundBillMapper.xml | 70 ++++- .../mybatis/worn/WornInboundItemMapper.xml | 148 ++++++++- 23 files changed, 1376 insertions(+), 80 deletions(-) create mode 100644 src/main/java/com/shzg/project/worn/domain/dto/WornInboundItemDTO.java create mode 100644 src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishDTO.java create mode 100644 src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishItemDTO.java create mode 100644 src/main/java/com/shzg/project/worn/domain/dto/WornInboundUpdateDTO.java diff --git a/src/main/java/com/shzg/project/unique/controller/WornUniqueCodeController.java b/src/main/java/com/shzg/project/unique/controller/WornUniqueCodeController.java index 90e4730..4ba18f7 100644 --- a/src/main/java/com/shzg/project/unique/controller/WornUniqueCodeController.java +++ b/src/main/java/com/shzg/project/unique/controller/WornUniqueCodeController.java @@ -103,4 +103,10 @@ public class WornUniqueCodeController extends BaseController { return toAjax(wornUniqueCodeService.deleteWornUniqueCodeByIds(ids)); } + @PreAuthorize("@ss.hasPermi('worn:uniqueCode:list')") + @GetMapping("/materialInfo/{code}") + public AjaxResult getMaterialInfo(@PathVariable("code") Integer code) + { + return AjaxResult.success(wornUniqueCodeService.selectMaterialInfoByCode(code)); + } } diff --git a/src/main/java/com/shzg/project/unique/mapper/WornUniqueCodeMapper.java b/src/main/java/com/shzg/project/unique/mapper/WornUniqueCodeMapper.java index b27f5ba..ebb3b28 100644 --- a/src/main/java/com/shzg/project/unique/mapper/WornUniqueCodeMapper.java +++ b/src/main/java/com/shzg/project/unique/mapper/WornUniqueCodeMapper.java @@ -2,6 +2,7 @@ package com.shzg.project.unique.mapper; import java.util.List; import com.shzg.project.unique.domain.WornUniqueCode; +import com.shzg.project.worn.domain.dto.WornInboundItemDTO; import io.lettuce.core.dynamic.annotation.Param; /** @@ -64,4 +65,20 @@ public interface WornUniqueCodeMapper * 根据code查询id */ Long selectIdByCode(@Param("code") Integer code); + /** + * 根据code查询 + */ + public WornUniqueCode selectByCode(Integer code); + /** + * 根据唯一码编号查询对应物料信息 + * + * @param code 唯一码编号 + * @return 物料信息列表 + */ + List selectMaterialInfoByCode(@Param("code") Integer code); + + int updateInboundStatusByCode(WornUniqueCode wornUniqueCode); + + int updateVoidStatusByCode(WornUniqueCode code); + } diff --git a/src/main/java/com/shzg/project/unique/service/IWornUniqueCodeService.java b/src/main/java/com/shzg/project/unique/service/IWornUniqueCodeService.java index e9c7904..2efd71e 100644 --- a/src/main/java/com/shzg/project/unique/service/IWornUniqueCodeService.java +++ b/src/main/java/com/shzg/project/unique/service/IWornUniqueCodeService.java @@ -2,6 +2,7 @@ package com.shzg.project.unique.service; import java.util.List; import com.shzg.project.unique.domain.WornUniqueCode; +import com.shzg.project.worn.domain.dto.WornInboundItemDTO; /** * 唯一码管理Service接口 @@ -50,5 +51,12 @@ public interface IWornUniqueCodeService * @return 结果 */ public int deleteWornUniqueCodeByIds(Long[] ids); + /** + * 根据唯一码编号查询物料信息 + * + * @param code 唯一码编号 + * @return 物料信息列表 + */ + List selectMaterialInfoByCode(Integer code); } diff --git a/src/main/java/com/shzg/project/unique/service/impl/WornUniqueCodeServiceImpl.java b/src/main/java/com/shzg/project/unique/service/impl/WornUniqueCodeServiceImpl.java index bf679cb..450cba6 100644 --- a/src/main/java/com/shzg/project/unique/service/impl/WornUniqueCodeServiceImpl.java +++ b/src/main/java/com/shzg/project/unique/service/impl/WornUniqueCodeServiceImpl.java @@ -5,12 +5,15 @@ import java.util.List; import com.shzg.common.exception.ServiceException; import com.shzg.common.utils.DateUtils; import com.shzg.common.utils.SecurityUtils; +import com.shzg.common.utils.StringUtils; import com.shzg.framework.aspectj.lang.annotation.DataScope; import com.shzg.project.unique.domain.WornUniqueCodeEvent; import com.shzg.project.unique.domain.WornUniqueCodeMaterial; import com.shzg.project.unique.mapper.WornUniqueCodeEventMapper; import com.shzg.project.unique.mapper.WornUniqueCodeMaterialMapper; import com.shzg.project.unique.unit.QrCodeUtils; +import com.shzg.project.worn.domain.dto.WornInboundItemDTO; +import com.shzg.project.worn.mapper.WornInboundItemMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.shzg.project.unique.mapper.WornUniqueCodeMapper; @@ -35,7 +38,8 @@ public class WornUniqueCodeServiceImpl implements IWornUniqueCodeService @Autowired private WornUniqueCodeEventMapper eventMapper; - + @Autowired + private WornInboundItemMapper wornInboundItemMapper; /** * 查询唯一码管理 * @@ -182,6 +186,18 @@ public class WornUniqueCodeServiceImpl implements IWornUniqueCodeService event.setEventType("1"); // 生成入库单号 event.setEventStatus("1"); event.setEventDesc("生成入库单号"); + //更新明细表中 + if (material.getMaterialId() == null) + { + throw new RuntimeException("物料ID不能为空,无法同步更新明细表唯一码"); + } + + int itemRows = wornInboundItemMapper.updateUniqueCodeByBillNoAndMaterialId( + wornUniqueCode.getBillNo(), + material.getMaterialId(), + code + ); + } else { @@ -237,4 +253,23 @@ public class WornUniqueCodeServiceImpl implements IWornUniqueCodeService return wornUniqueCodeMapper.deleteWornUniqueCodeByIds(ids); } + @Override + public List selectMaterialInfoByCode(Integer code) + { + if (code == null) + { + throw new RuntimeException("唯一码编号不能为空"); + } + List dto = wornUniqueCodeMapper.selectMaterialInfoByCode(code); + + if (dto != null && dto.size() >= 0){ + for (WornInboundItemDTO item : dto){ + if (StringUtils.isNotEmpty(item.getStatus()) && !"0".equals(item.getStatus())){ + throw new RuntimeException("唯一码编号已经被使用"); + } + } + + } + return dto; + } } diff --git a/src/main/java/com/shzg/project/worn/controller/WornInboundBillController.java b/src/main/java/com/shzg/project/worn/controller/WornInboundBillController.java index 85d565b..b640d50 100644 --- a/src/main/java/com/shzg/project/worn/controller/WornInboundBillController.java +++ b/src/main/java/com/shzg/project/worn/controller/WornInboundBillController.java @@ -2,16 +2,12 @@ package com.shzg.project.worn.controller; import java.util.List; import javax.servlet.http.HttpServletResponse; + +import com.shzg.project.worn.domain.dto.WornInboundPartialFinishDTO; +import com.shzg.project.worn.domain.dto.WornInboundUpdateDTO; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.shzg.framework.aspectj.lang.annotation.Log; import com.shzg.framework.aspectj.lang.enums.BusinessType; import com.shzg.project.worn.domain.WornInboundBill; @@ -74,7 +70,7 @@ public class WornInboundBillController extends BaseController */ @PreAuthorize("@ss.hasPermi('worn:inbound:add')") @Log(title = "入库库存", businessType = BusinessType.INSERT) - @PostMapping + @PostMapping("/add") public AjaxResult add(@RequestBody WornInboundBill wornInboundBill) { return toAjax(wornInboundBillService.insertWornInboundBill(wornInboundBill)); @@ -101,4 +97,20 @@ public class WornInboundBillController extends BaseController { return toAjax(wornInboundBillService.deleteWornInboundBillByIds(ids)); } + + @PreAuthorize("@ss.hasPermi('worn:inbound:edit')") + @Log(title = "入库单入库", businessType = BusinessType.UPDATE) + @PostMapping("/inboundFinish") + public AjaxResult inboundFinish(@RequestBody WornInboundPartialFinishDTO dto) + { + return toAjax(wornInboundBillService.inboundFinish(dto)); + } + /** + * 入库单作废(整单) + */ + @PostMapping("/void") + public AjaxResult voidBill(@RequestBody WornInboundBill wornInboundBill) + { + return toAjax(wornInboundBillService.voidBill(wornInboundBill.getBillNo())); + } } diff --git a/src/main/java/com/shzg/project/worn/controller/WornInboundItemController.java b/src/main/java/com/shzg/project/worn/controller/WornInboundItemController.java index de57213..33b0be3 100644 --- a/src/main/java/com/shzg/project/worn/controller/WornInboundItemController.java +++ b/src/main/java/com/shzg/project/worn/controller/WornInboundItemController.java @@ -2,6 +2,9 @@ package com.shzg.project.worn.controller; import java.util.List; import javax.servlet.http.HttpServletResponse; + +import com.github.pagehelper.PageHelper; +import com.shzg.project.worn.domain.dto.WornInboundUpdateDTO; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -39,25 +42,25 @@ public class WornInboundItemController extends BaseController */ @PreAuthorize("@ss.hasPermi('worn:item:list')") @GetMapping("/list") - public TableDataInfo list(WornInboundItem wornInboundItem) + public AjaxResult list(WornInboundItem wornInboundItem) { - startPage(); - List list = wornInboundItemService.selectWornInboundItemList(wornInboundItem); - return getDataTable(list); + //startPage(); + WornInboundUpdateDTO list = wornInboundItemService.selectWornInboundItemByBillNo(wornInboundItem); + return AjaxResult.success(list); } - /** - * 导出入库单明细列表 - */ - @PreAuthorize("@ss.hasPermi('worn:item:export')") - @Log(title = "入库单明细", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(HttpServletResponse response, WornInboundItem wornInboundItem) - { - List list = wornInboundItemService.selectWornInboundItemList(wornInboundItem); - ExcelUtil util = new ExcelUtil(WornInboundItem.class); - util.exportExcel(response, list, "入库单明细数据"); - } +// /** +// * 导出入库单明细列表 +// */ +// @PreAuthorize("@ss.hasPermi('worn:item:export')") +// @Log(title = "入库单明细", businessType = BusinessType.EXPORT) +// @PostMapping("/export") +// public void export(HttpServletResponse response, WornInboundItem wornInboundItem) +// { +// List list = wornInboundItemService.selectWornInboundItemByBillNo(wornInboundItem); +// ExcelUtil util = new ExcelUtil(WornInboundItem.class); +// util.exportExcel(response, list, "入库单明细数据"); +// } /** * 获取入库单明细详细信息 @@ -85,10 +88,10 @@ public class WornInboundItemController extends BaseController */ @PreAuthorize("@ss.hasPermi('worn:item:edit')") @Log(title = "入库单明细", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@RequestBody WornInboundItem wornInboundItem) + @PostMapping("/update") + public AjaxResult edit(@RequestBody WornInboundUpdateDTO dto) { - return toAjax(wornInboundItemService.updateWornInboundItem(wornInboundItem)); + return toAjax(wornInboundItemService.updateWornInboundItem(dto)); } /** diff --git a/src/main/java/com/shzg/project/worn/domain/WornInboundBill.java b/src/main/java/com/shzg/project/worn/domain/WornInboundBill.java index 507a111..28b1d7a 100644 --- a/src/main/java/com/shzg/project/worn/domain/WornInboundBill.java +++ b/src/main/java/com/shzg/project/worn/domain/WornInboundBill.java @@ -24,7 +24,7 @@ public class WornInboundBill extends BaseEntity private String billNo; /** 入库单类型(0入库单入库 1调拨入库 2退货入库) */ - @Excel(name = "入库单类型", readConverterExp = "0=入库申请,1=入库成功") + @Excel(name = "入库单类型", readConverterExp = "0=入库申请,1=入库成功,2=出库申请,3=出库成功,4=已作废") private String billType; /** 仓库编码 */ @@ -49,7 +49,7 @@ public class WornInboundBill extends BaseEntity private Date inboundTime; /** 状态(0草稿 1已完成) */ - @Excel(name = "状态", readConverterExp = "0=草稿,1=已完成") + @Excel(name = "状态", readConverterExp = "0=草稿,1=已完成,2=部分入库") private String status; /** 逻辑删除(0正常 1删除) */ diff --git a/src/main/java/com/shzg/project/worn/domain/WornInboundItem.java b/src/main/java/com/shzg/project/worn/domain/WornInboundItem.java index 2a03fa5..1eb2414 100644 --- a/src/main/java/com/shzg/project/worn/domain/WornInboundItem.java +++ b/src/main/java/com/shzg/project/worn/domain/WornInboundItem.java @@ -1,7 +1,10 @@ package com.shzg.project.worn.domain; import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonFormat; import com.shzg.framework.web.domain.BaseEntity; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -43,9 +46,12 @@ public class WornInboundItem extends BaseEntity /** 物料备注 */ @Excel(name = "物料备注") private String remark; + /** 明细状态 */ + private String status; // ================== 物料扩展信息(查询用,不入库) ================== - + /** ================== 新增:明细列表 ================== */ + private List itemList; /** 物料名称 */ @Excel(name = "物料名称") private String materialName; @@ -65,7 +71,46 @@ public class WornInboundItem extends BaseEntity /** 型号 */ @Excel(name = "型号") private String model; + /** 仓库编码 */ + private String warehouseCode; + /** 仓库名称 */ + @Excel(name = "仓库名称") + private String warehouseName; + /** 存储区编码 */ + private String areaCode; + /** 存储区名称 */ + @Excel(name = "存储区名称") + private String areaName; + /** 创建时间 */ + @Excel(name = "创建时间") + private java.util.Date createTime; + /** 入库时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入库时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date inboundTime; + /** 单件重量 */ + @Excel(name = "单件重量") + private BigDecimal weight; + + /** 单据备注 */ + @Excel(name = "单据备注") + private String billRemark; + /** 入库单类型(0=入库申请,1=入库成功,2=出库申请,3=出库成功,4=已作废") */ + private String billType; + /** 逻辑删除(0正常 1删除) */ + private String isDelete; + /** 物资类型 */ + private String typeName; + /** 父级类型名称 */ + private String typeParentNames; + /** 物料单位ID */ + private Long unitId; + /** 单位名称 */ + private String unitName; + + /** 主单据状态 */ + private String billStatus; // ================== getter / setter ================== public Long getId() { return id; } @@ -100,10 +145,116 @@ public class WornInboundItem extends BaseEntity public String getSpecification() { return specification; } public void setSpecification(String specification) { this.specification = specification; } + public Date getInboundTime() { return inboundTime; } + public void setInboundTime(Date inboundTime) { this.inboundTime = inboundTime; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } + public String getWarehouseName() { + return warehouseName; + } + public void setWarehouseName(String warehouseName) { + this.warehouseName = warehouseName; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + @Override + public java.util.Date getCreateTime() { + return super.getCreateTime(); + } + + @Override + public void setCreateTime(java.util.Date createTime) { + super.setCreateTime(createTime); + } + + public BigDecimal getWeight() { + return weight; + } + + public void setWeight(BigDecimal weight) { + this.weight = weight; + } + + public String getBillRemark() { + return billRemark; + } + + public void setBillRemark(String billRemark) { + this.billRemark = billRemark; + } + public List getItemList() { return itemList; } + public void setItemList(List itemList) { this.itemList = itemList; } + public String getBillType() { return billType; } + public void setBillType(String billType) { this.billType = billType; } + public String getWarehouseCode() { return warehouseCode; } + public void setWarehouseCode(String warehouseCode) { this.warehouseCode = warehouseCode; } + + public String getAreaCode() { return areaCode; } + public void setAreaCode(String areaCode) { this.areaCode = areaCode; } + public String getIsDelete() { + return isDelete; + } + + public void setIsDelete(String isDelete) { + this.isDelete = isDelete; + } + public String getTypeName() { + return typeName; + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } + public String getTypeParentNames() { + return typeParentNames; + } + + public void setTypeParentNames(String typeParentNames) { + this.typeParentNames = typeParentNames; + } + public Long getUnitId() { + return unitId; + } + + public void setUnitId(Long unitId) { + this.unitId = unitId; + } + public void setUnitName(String unitName) + { + this.unitName = unitName; + } + + public String getUnitName() + { + return unitName; + } + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + public void setBillStatus(String billStatus) + { + this.billStatus = billStatus; + } + + public String getBillStatus() + { + return billStatus; + } // ================== toString ================== @Override diff --git a/src/main/java/com/shzg/project/worn/domain/WornMaterial.java b/src/main/java/com/shzg/project/worn/domain/WornMaterial.java index 656e33a..b7f52c3 100644 --- a/src/main/java/com/shzg/project/worn/domain/WornMaterial.java +++ b/src/main/java/com/shzg/project/worn/domain/WornMaterial.java @@ -19,7 +19,7 @@ public class WornMaterial extends BaseEntity /** 主键ID */ private Long id; - + private Long materialId; /** 物料名称 */ @Excel(name = "物料名称") private String materialName; @@ -98,6 +98,8 @@ public class WornMaterial extends BaseEntity /** 父级类型名称 */ private String typeParentNames; + /** 单位名称 */ + private BigDecimal quantity; public Long getId() { @@ -107,6 +109,13 @@ public class WornMaterial extends BaseEntity public void setId(Long id) { this.id = id; } + public Long getMaterialId() { + return materialId; + } + + public void setMaterialId(Long materialId) { + this.materialId = materialId; + } public String getMaterialName() { return materialName; @@ -268,6 +277,8 @@ public class WornMaterial extends BaseEntity this.typeParentNames = typeParentNames; } + public BigDecimal getQuantity() { return quantity; } + public void setQuantity(BigDecimal quantity) { this.quantity = quantity; } @Override public String toString() { return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) diff --git a/src/main/java/com/shzg/project/worn/domain/dto/WornInboundItemDTO.java b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundItemDTO.java new file mode 100644 index 0000000..315e320 --- /dev/null +++ b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundItemDTO.java @@ -0,0 +1,44 @@ +package com.shzg.project.worn.domain.dto; + +import lombok.Data; + +import java.math.BigDecimal; +@Data + +public class WornInboundItemDTO +{ + /** 明细ID,更新时有值,新增时可不传 */ + private Long id; + + /** 物料ID */ + private Long materialId; + /** 物料名称(展示用) */ + private String materialName; + + /** 数量 */ + private BigDecimal quantity; + + /** 明细备注 */ + private String remark; + + /** 明细备注 */ + private String status; + /** 唯一码 */ + private Integer uniqueCode; + + /** 是否删除(0正常 1删除) */ + private String isDelete; + // ===== 物料扩展字段(前端需要的)===== + private String materialCode; + private String materialShortName; + private String specification; + private String model; + private String typeName; + /** 父级类型名称 */ + private String typeParentNames; + /** 物料单位ID */ + private Long unitId; + /** 单位名称 */ + private String unitName; + +} \ No newline at end of file diff --git a/src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishDTO.java b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishDTO.java new file mode 100644 index 0000000..7190481 --- /dev/null +++ b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishDTO.java @@ -0,0 +1,29 @@ +package com.shzg.project.worn.domain.dto; + +import lombok.Data; +import java.util.List; + +@Data +public class WornInboundPartialFinishDTO +{ + /** 单据号 */ + private String billNo; + + /** 仓库编码 */ + private String warehouseCode; + + /** 仓库名称 */ + private String warehouseName; + + /** 存储区编码 */ + private String areaCode; + + /** 存储区名称 */ + private String areaName; + + /** 主表备注 */ + private String billRemark; + + /** 本次入库的明细 */ + private List itemList; +} \ No newline at end of file diff --git a/src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishItemDTO.java b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishItemDTO.java new file mode 100644 index 0000000..d09f487 --- /dev/null +++ b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundPartialFinishItemDTO.java @@ -0,0 +1,13 @@ +package com.shzg.project.worn.domain.dto; + +import lombok.Data; + +@Data +public class WornInboundPartialFinishItemDTO +{ + /** 明细ID */ + private Long id; + + /** 明细备注 */ + private String remark; +} \ No newline at end of file diff --git a/src/main/java/com/shzg/project/worn/domain/dto/WornInboundUpdateDTO.java b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundUpdateDTO.java new file mode 100644 index 0000000..8a3814c --- /dev/null +++ b/src/main/java/com/shzg/project/worn/domain/dto/WornInboundUpdateDTO.java @@ -0,0 +1,130 @@ +package com.shzg.project.worn.domain.dto; + +import java.util.Date; +import java.util.List; + +public class WornInboundUpdateDTO +{ + /** 入库单ID */ + private Long billId; + + /** 入库单号 */ + private String billNo; + /** 入库单号 */ + private String billType; + /** 仓库编码 */ + private String warehouseCode; + + /** 仓库名称 */ + private String warehouseName; + + /** 存储区编码 */ + private String areaCode; + + /** 存储区名称 */ + private String areaName; + + /** 单据备注 */ + private String billRemark; + + /** 入库时间 */ + private Date inboundTime; + /** 创建时间 */ + private Date createTime; + + /** 状态 */ + private String status; + + /** 物料明细列表 */ + private List itemList; + + public Long getBillId() { + return billId; + } + + public void setBillId(Long billId) { + this.billId = billId; + } + + public String getBillNo() { + return billNo; + } + + public void setBillNo(String billNo) { + this.billNo = billNo; + } + + public String getWarehouseCode() { + return warehouseCode; + } + + public void setWarehouseCode(String warehouseCode) { + this.warehouseCode = warehouseCode; + } + + public String getWarehouseName() { + return warehouseName; + } + + public void setWarehouseName(String warehouseName) { + this.warehouseName = warehouseName; + } + + public String getAreaCode() { + return areaCode; + } + + public void setAreaCode(String areaCode) { + this.areaCode = areaCode; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + public String getBillRemark() { + return billRemark; + } + + public void setBillRemark(String billRemark) { + this.billRemark = billRemark; + } + + public Date getInboundTime() { + return inboundTime; + } + + public void setInboundTime(Date inboundTime) { + this.inboundTime = inboundTime; + } + public Date getCreateTime() { + return createTime; +} + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public List getItemList() { + return itemList; + } + + public void setItemList(List itemList) { + this.itemList = itemList; + } + public String getBillType() { return billType; } + public void setBillType(String billType) { this.billType = billType; } + +} \ No newline at end of file diff --git a/src/main/java/com/shzg/project/worn/mapper/WornInboundBillMapper.java b/src/main/java/com/shzg/project/worn/mapper/WornInboundBillMapper.java index 3ceab4a..ea0228c 100644 --- a/src/main/java/com/shzg/project/worn/mapper/WornInboundBillMapper.java +++ b/src/main/java/com/shzg/project/worn/mapper/WornInboundBillMapper.java @@ -58,4 +58,14 @@ public interface WornInboundBillMapper * @return 结果 */ public int deleteWornInboundBillByIds(Long[] ids); + + /** + * 根据单号查询入库单 + */ + public WornInboundBill selectWornInboundBillByBillNo(String billNo); + + /** + * 根据ID更新入库单 + */ + public int updateWornInboundBillById(WornInboundBill bill); } diff --git a/src/main/java/com/shzg/project/worn/mapper/WornInboundItemMapper.java b/src/main/java/com/shzg/project/worn/mapper/WornInboundItemMapper.java index 3028971..3de7c41 100644 --- a/src/main/java/com/shzg/project/worn/mapper/WornInboundItemMapper.java +++ b/src/main/java/com/shzg/project/worn/mapper/WornInboundItemMapper.java @@ -2,6 +2,7 @@ package com.shzg.project.worn.mapper; import java.util.List; import com.shzg.project.worn.domain.WornInboundItem; +import io.lettuce.core.dynamic.annotation.Param; /** * 入库单明细Mapper接口 @@ -58,4 +59,27 @@ public interface WornInboundItemMapper * @return 结果 */ public int deleteWornInboundItemByIds(Long[] ids); +// /** +// * 根据billId查询明细 +// */ +// public List selectWornInboundItemByBillId(Long billId); + /** + * 根据单号和物料ID更新明细唯一码 + * + * @param billNo 单号 + * @param materialId 物料ID + * @param uniqueCode 唯一码 + * @return 结果 + */ + int updateUniqueCodeByBillNoAndMaterialId(@Param("billNo") String billNo, + @Param("materialId") Long materialId, + @Param("uniqueCode") Integer uniqueCode); + + int updateInboundItemStatus(WornInboundItem wornInboundItem); + + int countNotInboundByBillId(@Param("billId") Long billId); + + int updateItemToVoid(WornInboundItem item); + + List selectWornInboundItemByBillId(Long billId); } diff --git a/src/main/java/com/shzg/project/worn/service/IWornInboundBillService.java b/src/main/java/com/shzg/project/worn/service/IWornInboundBillService.java index c7387ab..1fe1e12 100644 --- a/src/main/java/com/shzg/project/worn/service/IWornInboundBillService.java +++ b/src/main/java/com/shzg/project/worn/service/IWornInboundBillService.java @@ -2,6 +2,7 @@ package com.shzg.project.worn.service; import java.util.List; import com.shzg.project.worn.domain.WornInboundBill; +import com.shzg.project.worn.domain.dto.WornInboundPartialFinishDTO; /** * 入库库存Service接口 @@ -58,4 +59,19 @@ public interface IWornInboundBillService * @return 结果 */ public int deleteWornInboundBillById(Long id); + /** + * 提交入库库存信息 + * + * @param dto 入库单号 + * @return 结果 + */ + public int inboundFinish(WornInboundPartialFinishDTO dto); + + /** + * 作废入库库存信息 + * + * @param billNo 入库单号 + * @return 结果 + */ + int voidBill(String billNo); } diff --git a/src/main/java/com/shzg/project/worn/service/IWornInboundItemService.java b/src/main/java/com/shzg/project/worn/service/IWornInboundItemService.java index 7e2e3c0..ed53d50 100644 --- a/src/main/java/com/shzg/project/worn/service/IWornInboundItemService.java +++ b/src/main/java/com/shzg/project/worn/service/IWornInboundItemService.java @@ -2,6 +2,7 @@ package com.shzg.project.worn.service; import java.util.List; import com.shzg.project.worn.domain.WornInboundItem; +import com.shzg.project.worn.domain.dto.WornInboundUpdateDTO; /** * 入库单明细Service接口 @@ -25,7 +26,7 @@ public interface IWornInboundItemService * @param wornInboundItem 入库单明细 * @return 入库单明细集合 */ - public List selectWornInboundItemList(WornInboundItem wornInboundItem); + public WornInboundUpdateDTO selectWornInboundItemByBillNo(WornInboundItem wornInboundItem); /** * 新增入库单明细 @@ -38,10 +39,10 @@ public interface IWornInboundItemService /** * 修改入库单明细 * - * @param wornInboundItem 入库单明细 + * @param dto 入库单明细 * @return 结果 */ - public int updateWornInboundItem(WornInboundItem wornInboundItem); + public int updateWornInboundItem(WornInboundUpdateDTO dto); /** * 批量删除入库单明细 diff --git a/src/main/java/com/shzg/project/worn/service/impl/WornInboundBillServiceImpl.java b/src/main/java/com/shzg/project/worn/service/impl/WornInboundBillServiceImpl.java index 13c5b23..a2f37e6 100644 --- a/src/main/java/com/shzg/project/worn/service/impl/WornInboundBillServiceImpl.java +++ b/src/main/java/com/shzg/project/worn/service/impl/WornInboundBillServiceImpl.java @@ -1,13 +1,17 @@ package com.shzg.project.worn.service.impl; +import java.util.Date; import java.util.List; import com.shzg.common.utils.DateUtils; import com.shzg.common.utils.SecurityUtils; +import com.shzg.common.utils.StringUtils; import com.shzg.project.unique.domain.WornUniqueCode; import com.shzg.project.unique.domain.WornUniqueCodeEvent; import com.shzg.project.unique.mapper.WornUniqueCodeEventMapper; import com.shzg.project.unique.mapper.WornUniqueCodeMapper; import com.shzg.project.worn.domain.WornInboundItem; +import com.shzg.project.worn.domain.dto.WornInboundPartialFinishDTO; +import com.shzg.project.worn.domain.dto.WornInboundPartialFinishItemDTO; import com.shzg.project.worn.mapper.WornInboundItemMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -115,10 +119,8 @@ public class WornInboundBillServiceImpl implements IWornInboundBillService /* ================== 5. 插入明细 ================== */ List itemList = wornInboundBill.getItemList(); - for (WornInboundItem item : itemList) - { - if (item == null) - { + for (WornInboundItem item : itemList){ + if (item == null){ continue; } @@ -126,22 +128,21 @@ public class WornInboundBillServiceImpl implements IWornInboundBillService item.setBillNo(billNo); item.setCreateTime(DateUtils.getNowDate()); item.setCreateBy(String.valueOf(userId)); + item.setIsDelete(item.getIsDelete()); int itemRows = wornInboundItemMapper.insertWornInboundItem(item); - if (itemRows <= 0) - { + if (itemRows <= 0){ throw new RuntimeException("入库明细新增失败"); } /* ================== 6. 唯一码联动 ================== */ - if (item.getUniqueCode() != null) - { + if (item.getUniqueCode() != null){ Integer code = item.getUniqueCode(); Long uniqueId = wornUniqueCodeMapper.selectIdByCode(code); if (uniqueId == null) { - throw new RuntimeException("唯一码不存在:" + code); + throw new RuntimeException("唯一码不存在:" + code+",请添加唯一码"); } WornUniqueCode update = new WornUniqueCode(); @@ -155,12 +156,12 @@ public class WornInboundBillServiceImpl implements IWornInboundBillService { throw new RuntimeException("唯一码状态更新失败:" + code); } - + /* ================== 插入物料详情 ================== */ WornUniqueCodeEvent event = new WornUniqueCodeEvent(); event.setUniqueCodeId(uniqueId); event.setEventType("1"); event.setEventStatus("1"); - event.setEventDesc("入库单入库"); + event.setEventDesc("生成入库单号"); event.setOperatorId(userId); event.setCreateBy(String.valueOf(userId)); event.setCreateTime(DateUtils.getNowDate()); @@ -187,6 +188,8 @@ public class WornInboundBillServiceImpl implements IWornInboundBillService public int updateWornInboundBill(WornInboundBill wornInboundBill) { wornInboundBill.setUpdateTime(DateUtils.getNowDate()); + Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); + wornInboundBill.setUpdateBy(String.valueOf(userId)); return wornInboundBillMapper.updateWornInboundBill(wornInboundBill); } @@ -213,4 +216,268 @@ public class WornInboundBillServiceImpl implements IWornInboundBillService { return wornInboundBillMapper.deleteWornInboundBillById(id); } + /** + * 提交入库单申请 + * + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public int inboundFinish(WornInboundPartialFinishDTO dto){ + if (dto == null) + { + throw new RuntimeException("参数不能为空"); + } + if (dto.getBillNo() == null || "".equals(dto.getBillNo().trim())) + { + throw new RuntimeException("单据号不能为空"); + } + if (dto.getItemList() == null || dto.getItemList().isEmpty()) + { + throw new RuntimeException("本次入库明细不能为空"); + } + + Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); + String userName = SecurityUtils.getLoginUser().getUser().getNickName(); + Date now = DateUtils.getNowDate(); + + // 1. 查询主表 + WornInboundBill bill = wornInboundBillMapper.selectWornInboundBillByBillNo(dto.getBillNo()); + if (bill == null) + { + throw new RuntimeException("入库单不存在:" + dto.getBillNo()); + } + if ("1".equals(bill.getIsDelete())) + { + throw new RuntimeException("入库单已删除,不能入库"); + } + + // 2. 先更新本次入库的明细(防重复) + for (WornInboundPartialFinishItemDTO itemDTO : dto.getItemList()) + { + if (itemDTO == null || itemDTO.getId() == null) + { + throw new RuntimeException("明细ID不能为空"); + } + + // 查询明细 + WornInboundItem item = wornInboundItemMapper.selectWornInboundItemById(itemDTO.getId()); + if (item == null) + { + throw new RuntimeException("明细不存在,ID=" + itemDTO.getId()); + } + if (!bill.getId().equals(item.getBillId())) + { + throw new RuntimeException("明细不属于当前单据,ID=" + itemDTO.getId()); + } + + // 更新明细状态=已入库,且只能从未入库改为已入库 + WornInboundItem updateItem = new WornInboundItem(); + updateItem.setId(itemDTO.getId()); + updateItem.setRemark(itemDTO.getRemark()); + updateItem.setStatus("1"); + updateItem.setUpdateBy(String.valueOf(userId)); + updateItem.setUpdateTime(now); + + int itemRows = wornInboundItemMapper.updateInboundItemStatus(updateItem); + if (itemRows <= 0) + { + throw new RuntimeException("该明细已入库,请勿重复操作,ID=" + itemDTO.getId()); + } + + // 处理唯一码 + if (item.getUniqueCode() != null){ + WornUniqueCode uniqueCode = wornUniqueCodeMapper.selectByCode(item.getUniqueCode()); + if (uniqueCode == null) + { + throw new RuntimeException("唯一码不存在:" + item.getUniqueCode()); + } + + // 只能从 1=生成入库单号 改成 2=快速入库 + WornUniqueCode updateUnique = new WornUniqueCode(); + updateUnique.setCode(item.getUniqueCode()); + updateUnique.setStatus("2"); + updateUnique.setUpdateBy(String.valueOf(userId)); + updateUnique.setUpdateTime(now); + + int uniqueRows = wornUniqueCodeMapper.updateInboundStatusByCode(updateUnique); + if (uniqueRows <= 0) + { + throw new RuntimeException("唯一码已入库或状态异常:" + item.getUniqueCode()); + } + + // 写事件 + WornUniqueCodeEvent event = new WornUniqueCodeEvent(); + event.setUniqueCodeId(uniqueCode.getId()); + event.setEventType("2"); // 快速入库 + event.setEventStatus("1"); + event.setEventDesc("入库成功"); + event.setOperatorId(userId); + event.setOperatorName(userName); + event.setCreateBy(String.valueOf(userId)); + event.setCreateTime(now); + event.setIsDelete("0"); + event.setRemark("单号:" + dto.getBillNo() + ",唯一码:" + item.getUniqueCode()); + + int eventRows = eventMapper.insertWornUniqueCodeEvent(event); + if (eventRows <= 0) + { + throw new RuntimeException("唯一码事件记录新增失败:" + item.getUniqueCode()); + } + } + } + + // 3. 更新主表仓库信息、备注 + WornInboundBill updateBill = new WornInboundBill(); + updateBill.setId(bill.getId()); + updateBill.setWarehouseCode(dto.getWarehouseCode()); + updateBill.setWarehouseName(dto.getWarehouseName()); + updateBill.setAreaCode(dto.getAreaCode()); + updateBill.setAreaName(dto.getAreaName()); + updateBill.setRemark(dto.getBillRemark()); + updateBill.setUpdateBy(String.valueOf(userId)); + updateBill.setUpdateTime(now); + + // 4. 判断该单据下是否全部明细已入库 + int notInboundCount = wornInboundItemMapper.countNotInboundByBillId(bill.getId()); + if (notInboundCount == 0) + { + // 全部入库 + updateBill.setStatus("1"); // 已完成 + updateBill.setBillType("1"); // 入库成功 + } + else + { + // 部分入库 + updateBill.setStatus("2"); // 部分入库 + // billType 暂不改,保持原单据类型 + } + + int billRows = wornInboundBillMapper.updateWornInboundBillById(updateBill); + if (billRows <= 0) + { + throw new RuntimeException("主表更新失败"); + } + + return 1; + } + /** + * 单据作废接口 + * */ + @Override + @Transactional(rollbackFor = Exception.class) + public int voidBill(String billNo) + { + if (StringUtils.isEmpty(billNo)) + { + throw new RuntimeException("单据号不能为空"); + } + + Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); + String userName = SecurityUtils.getLoginUser().getUser().getNickName(); + Date now = DateUtils.getNowDate(); + + // 1️⃣ 查询主表 + WornInboundBill bill = wornInboundBillMapper.selectWornInboundBillByBillNo(billNo); + if (bill == null) + { + throw new RuntimeException("单据不存在"); + } + + if ("4".equals(bill.getBillType())) + { + throw new RuntimeException("单据已作废,请勿重复操作"); + } + + // ❗(建议加)有已入库的不允许作废 + List itemList = wornInboundItemMapper.selectWornInboundItemByBillId(bill.getId()); + if (itemList == null || itemList.isEmpty()) + { + throw new RuntimeException("没有明细,无法作废"); + } + + for (WornInboundItem item : itemList) + { + if ("1".equals(item.getStatus())) + { + throw new RuntimeException("存在已入库明细,不允许整单作废"); + } + } + + // 2️⃣ 处理明细 + 唯一码 + for (WornInboundItem item : itemList){ + // 2.1 明细作废 + WornInboundItem updateItem = new WornInboundItem(); + updateItem.setId(item.getId()); + updateItem.setStatus("9"); // 明细作废 + updateItem.setUpdateBy(String.valueOf(userId)); + updateItem.setUpdateTime(now); + + int itemRows = wornInboundItemMapper.updateItemToVoid(updateItem); + if (itemRows <= 0) + { + throw new RuntimeException("明细作废失败,ID=" + item.getId()); + } + + // 2.2 唯一码作废 + if (item.getUniqueCode() != null) + { + WornUniqueCode unique = wornUniqueCodeMapper.selectByCode(item.getUniqueCode()); + if (unique != null) + { + // 🔥 状态改为 9(作废) + WornUniqueCode updateUnique = new WornUniqueCode(); + updateUnique.setCode(item.getUniqueCode()); + updateUnique.setStatus("9"); + updateUnique.setUpdateBy(String.valueOf(userId)); + updateUnique.setUpdateTime(now); + + int uniqueRows = wornUniqueCodeMapper.updateVoidStatusByCode(updateUnique); + if (uniqueRows <= 0) + { + throw new RuntimeException("唯一码作废失败:" + item.getUniqueCode()); + } + + // 🔥 写事件(9=作废) + WornUniqueCodeEvent event = new WornUniqueCodeEvent(); + event.setUniqueCodeId(unique.getId()); + event.setEventType("9"); // 作废事件 + event.setEventStatus("9"); // 作废状态 + event.setEventDesc("入库单作废"); + event.setOperatorId(userId); + event.setOperatorName(userName); + event.setCreateBy(String.valueOf(userId)); + event.setCreateTime(now); + event.setIsDelete("0"); + event.setRemark("作废单号:" + billNo + ",唯一码:" + item.getUniqueCode()); + + int eventRows = eventMapper.insertWornUniqueCodeEvent(event); + if (eventRows <= 0) + { + throw new RuntimeException("唯一码事件记录失败:" + item.getUniqueCode()); + } + } + } + } + + // 3️⃣ 主表作废 + WornInboundBill updateBill = new WornInboundBill(); + updateBill.setId(bill.getId()); + updateBill.setBillType("4"); // 已作废 + updateBill.setStatus("9"); // 作废状态 + updateBill.setUpdateBy(String.valueOf(userId)); + updateBill.setUpdateTime(now); + + int billRows = wornInboundBillMapper.updateWornInboundBillById(updateBill); + if (billRows <= 0) + { + throw new RuntimeException("主表作废失败"); + } + + return 1; + } + } + + + + diff --git a/src/main/java/com/shzg/project/worn/service/impl/WornInboundItemServiceImpl.java b/src/main/java/com/shzg/project/worn/service/impl/WornInboundItemServiceImpl.java index 0797e5d..3c28790 100644 --- a/src/main/java/com/shzg/project/worn/service/impl/WornInboundItemServiceImpl.java +++ b/src/main/java/com/shzg/project/worn/service/impl/WornInboundItemServiceImpl.java @@ -1,12 +1,27 @@ package com.shzg.project.worn.service.impl; +import java.util.ArrayList; +import java.util.Date; import java.util.List; import com.shzg.common.utils.DateUtils; +import com.shzg.common.utils.SecurityUtils; +import com.shzg.common.utils.StringUtils; +import com.shzg.project.unique.domain.WornUniqueCode; +import com.shzg.project.unique.domain.WornUniqueCodeEvent; +import com.shzg.project.unique.mapper.WornUniqueCodeEventMapper; +import com.shzg.project.unique.mapper.WornUniqueCodeMapper; +import com.shzg.project.worn.domain.WornInboundBill; +import com.shzg.project.worn.domain.WornMaterial; +import com.shzg.project.worn.domain.dto.WornInboundItemDTO; +import com.shzg.project.worn.domain.dto.WornInboundUpdateDTO; +import com.shzg.project.worn.mapper.WornInboundBillMapper; +import com.shzg.project.worn.service.IWornMaterialService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.shzg.project.worn.mapper.WornInboundItemMapper; import com.shzg.project.worn.domain.WornInboundItem; import com.shzg.project.worn.service.IWornInboundItemService; +import org.springframework.transaction.annotation.Transactional; /** * 入库单明细Service业务层处理 @@ -19,7 +34,14 @@ public class WornInboundItemServiceImpl implements IWornInboundItemService { @Autowired private WornInboundItemMapper wornInboundItemMapper; - + @Autowired + private IWornMaterialService wornMaterialService; + @Autowired + private WornUniqueCodeMapper wornUniqueCodeMapper; + @Autowired + private WornUniqueCodeEventMapper eventMapper; + @Autowired + private WornInboundBillMapper wornInboundBillMapper; /** * 查询入库单明细 * @@ -39,9 +61,71 @@ public class WornInboundItemServiceImpl implements IWornInboundItemService * @return 入库单明细 */ @Override - public List selectWornInboundItemList(WornInboundItem wornInboundItem) + public WornInboundUpdateDTO selectWornInboundItemByBillNo(WornInboundItem wornInboundItem) { - return wornInboundItemMapper.selectWornInboundItemList(wornInboundItem); + String billNo = wornInboundItem.getBillNo(); + if (billNo == null || "".equals(billNo.trim())) + { + return null; + } + + // 1. 查询明细列表 + WornInboundItem param = new WornInboundItem(); + param.setBillNo(billNo); + + List itemList = wornInboundItemMapper.selectWornInboundItemList(param); + + if (itemList == null || itemList.isEmpty()) + { + return null; + } + + // 2. 取第一条作为主数据(bill信息) + WornInboundItem first = itemList.get(0); + + // 3. 构建 DTO + WornInboundUpdateDTO dto = new WornInboundUpdateDTO(); + dto.setBillId(first.getBillId()); + dto.setBillNo(first.getBillNo()); + dto.setBillType(first.getBillType()); + dto.setWarehouseCode(first.getWarehouseCode()); + dto.setWarehouseName(first.getWarehouseName()); + dto.setAreaCode(first.getAreaCode()); + dto.setAreaName(first.getAreaName()); + dto.setBillRemark(first.getBillRemark()); + dto.setInboundTime(first.getInboundTime()); + dto.setStatus(first.getBillStatus()); + dto.setCreateTime(first.getCreateTime()); + + List dtoList = new ArrayList<>(); + + // 4. 组装明细 + for (WornInboundItem item : itemList) + { + WornInboundItemDTO itemDTO = new WornInboundItemDTO(); + + itemDTO.setId(item.getId()); + itemDTO.setMaterialId(item.getMaterialId()); + itemDTO.setMaterialName(item.getMaterialName()); + itemDTO.setMaterialCode(item.getMaterialCode()); + itemDTO.setMaterialShortName(item.getMaterialShortName()); + itemDTO.setModel(item.getModel()); + itemDTO.setSpecification(item.getSpecification()); + itemDTO.setTypeName(item.getTypeName()); + itemDTO.setQuantity(item.getQuantity()); + itemDTO.setRemark(item.getRemark()); + itemDTO.setUniqueCode(item.getUniqueCode()); + itemDTO.setIsDelete(StringUtils.isEmpty(item.getIsDelete()) ? "0" : item.getIsDelete()); + itemDTO.setTypeParentNames(item.getTypeParentNames()); + itemDTO.setUnitId(item.getUnitId()); + itemDTO.setUnitName(item.getUnitName()); + itemDTO.setStatus(item.getStatus()); + dtoList.add(itemDTO); + } + + dto.setItemList(dtoList); + + return dto; } /** @@ -60,15 +144,187 @@ public class WornInboundItemServiceImpl implements IWornInboundItemService /** * 修改入库单明细 * - * @param wornInboundItem 入库单明细 + * @param dto 入库单明细 * @return 结果 */ @Override - public int updateWornInboundItem(WornInboundItem wornInboundItem) - { - return wornInboundItemMapper.updateWornInboundItem(wornInboundItem); + @Transactional(rollbackFor = Exception.class) + public int updateWornInboundItem(WornInboundUpdateDTO dto ) { + if (dto == null) { + throw new RuntimeException("入库单参数不能为空"); + } + + Long userId = SecurityUtils.getLoginUser().getUser().getUserId(); + Date now = DateUtils.getNowDate(); + + // 1. 更新主表 + WornInboundBill bill = new WornInboundBill(); + bill.setBillNo(dto.getBillNo()); + bill.setWarehouseCode(dto.getWarehouseCode()); + bill.setWarehouseName(dto.getWarehouseName()); + bill.setAreaCode(dto.getAreaCode()); + bill.setAreaName(dto.getAreaName()); + bill.setRemark(dto.getBillRemark()); +// bill.setBillType(dto.getBillType()); + bill.setInboundTime(dto.getInboundTime()); + bill.setStatus("0"); + bill.setUpdateBy(String.valueOf(userId)); + bill.setUpdateTime(now); + + int billRows = wornInboundBillMapper.updateWornInboundBill(bill); + if (billRows <= 0){ + throw new RuntimeException("入库单更新失败"); + } + + // 2. 更新 / 新增 / 删除明细 + if (dto.getItemList() != null && !dto.getItemList().isEmpty()){ + for (WornInboundItemDTO itemDTO : dto.getItemList()){ + if (itemDTO == null){ + continue; + } + + // 删除 + if ("1".equals(itemDTO.getIsDelete())){ + if (itemDTO.getId() != null){ + WornInboundItem oldItem = wornInboundItemMapper.selectWornInboundItemById(itemDTO.getId()); + if (oldItem != null){ + oldItem.setIsDelete("1"); + oldItem.setUpdateBy(String.valueOf(userId)); + oldItem.setUpdateTime(now); + + int deleteRows = wornInboundItemMapper.updateWornInboundItem(oldItem); + if (deleteRows <= 0){ + throw new RuntimeException("入库明细删除失败"); + } + + if (oldItem.getUniqueCode() != null){ + rollbackUniqueCode(userId, oldItem.getUniqueCode(), now); + } + } + } + continue; + } + + // 新增 + if (itemDTO.getId() == null){ + WornInboundItem newItem = new WornInboundItem(); + newItem.setBillId(dto.getBillId()); + newItem.setBillNo(dto.getBillNo()); + newItem.setMaterialId(itemDTO.getMaterialId()); + newItem.setQuantity(itemDTO.getQuantity()); + newItem.setRemark(itemDTO.getRemark()); + newItem.setUniqueCode(itemDTO.getUniqueCode()); + newItem.setIsDelete("0"); + newItem.setCreateBy(String.valueOf(userId)); + newItem.setCreateTime(now); + + int itemRows = wornInboundItemMapper.insertWornInboundItem(newItem); + if (itemRows <= 0) + { + throw new RuntimeException("入库明细新增失败"); + } + + if (newItem.getUniqueCode() != null) + { + handleUniqueCodeIn(userId, newItem.getUniqueCode(), now); + } + }else{ + // 更新 + WornInboundItem oldItem = wornInboundItemMapper.selectWornInboundItemById(itemDTO.getId()); + if (oldItem == null) + { + throw new RuntimeException("入库明细不存在,ID:" + itemDTO.getId()); + } + + Integer oldCode = oldItem.getUniqueCode(); + Integer newCode = itemDTO.getUniqueCode(); + + oldItem.setMaterialId(itemDTO.getMaterialId()); + oldItem.setQuantity(itemDTO.getQuantity()); + oldItem.setRemark(itemDTO.getRemark()); + oldItem.setUniqueCode(newCode); +// oldItem.setUpdateBy(String.valueOf(userId)); +// oldItem.setUpdateTime(now); + + int itemRows = wornInboundItemMapper.updateWornInboundItem(oldItem); + if (itemRows <= 0) + { + throw new RuntimeException("入库明细更新失败"); + } + + // 唯一码变更处理 + if (oldCode != null && !oldCode.equals(newCode)){ + rollbackUniqueCode(userId, oldCode, now); + } + if (newCode != null && !newCode.equals(oldCode)){ + handleUniqueCodeIn(userId, newCode, now); + } + } + } + } + + return 1; } + + +/** + * 唯一码入库联动 + */ +private void handleUniqueCodeIn(Long userId, Integer code, Date now) +{ + Long uniqueId = wornUniqueCodeMapper.selectIdByCode(code); + if (uniqueId == null) + { + throw new RuntimeException("唯一码不存在:" + code + ",请添加唯一码"); + } + + WornUniqueCode update = new WornUniqueCode(); + update.setCode(code); + update.setStatus("1"); + update.setUpdateBy(String.valueOf(userId)); + update.setUpdateTime(now); + + int updateRows = wornUniqueCodeMapper.updateByCode(update); + if (updateRows <= 0) + { + throw new RuntimeException("唯一码状态更新失败:" + code); + } + + WornUniqueCodeEvent event = new WornUniqueCodeEvent(); + event.setUniqueCodeId(uniqueId); + event.setEventType("1"); + event.setEventStatus("1"); + event.setEventDesc("入库单入库"); + event.setOperatorId(userId); + event.setCreateBy(String.valueOf(userId)); + event.setCreateTime(now); + event.setIsDelete("0"); + + int eventRows = eventMapper.insertWornUniqueCodeEvent(event); + if (eventRows <= 0) + { + throw new RuntimeException("唯一码事件记录失败:" + code); + } +} + +/** + * 唯一码回退 + */ +private void rollbackUniqueCode(Long userId, Integer code, Date now) +{ + WornUniqueCode update = new WornUniqueCode(); + update.setCode(code); + update.setStatus("0"); + update.setUpdateBy(String.valueOf(userId)); + update.setUpdateTime(now); + + int updateRows = wornUniqueCodeMapper.updateByCode(update); + if (updateRows <= 0) + { + throw new RuntimeException("唯一码状态回退失败:" + code); + } +} /** * 批量删除入库单明细 * diff --git a/src/main/resources/mybatis/system/SysDeptMapper.xml b/src/main/resources/mybatis/system/SysDeptMapper.xml index 48965ac..488e736 100644 --- a/src/main/resources/mybatis/system/SysDeptMapper.xml +++ b/src/main/resources/mybatis/system/SysDeptMapper.xml @@ -156,7 +156,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update sys_dept set del_flag = '2' where dept_id = #{deptId} - SELECT * FROM sys_dept WHERE diff --git a/src/main/resources/mybatis/unique/WornUniqueCodeMapper.xml b/src/main/resources/mybatis/unique/WornUniqueCodeMapper.xml index 5164068..2a85c7a 100644 --- a/src/main/resources/mybatis/unique/WornUniqueCodeMapper.xml +++ b/src/main/resources/mybatis/unique/WornUniqueCodeMapper.xml @@ -19,7 +19,22 @@ - + + + + + + + + + + + + + + + + select id, code, bill_no, project_id, status, rfid_code, print_count, create_by, create_time, update_by, update_time, remark, is_delete from worn_unique_code @@ -49,6 +64,7 @@ AND t.rfid_code = #{rfidCode} + order by t.create_time desc, t.id desc @@ -127,4 +144,80 @@ #{id} + + + + + UPDATE worn_unique_code + SET status = #{status}, + update_by = #{updateBy}, + update_time = #{updateTime} + WHERE code = #{code} + AND status = '1' + AND (is_delete = '0' OR is_delete IS NULL) + + + update worn_unique_code + set status = '9', + update_by = #{updateBy}, + update_time = #{updateTime} + where code = #{code} + and (is_delete = '0' or is_delete is null) + \ No newline at end of file diff --git a/src/main/resources/mybatis/worn/WornInboundBillMapper.xml b/src/main/resources/mybatis/worn/WornInboundBillMapper.xml index 1676680..43a9706 100644 --- a/src/main/resources/mybatis/worn/WornInboundBillMapper.xml +++ b/src/main/resources/mybatis/worn/WornInboundBillMapper.xml @@ -38,7 +38,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and inbound_time = #{inboundTime} and status = #{status} and is_delete = #{isDelete} + and is_delete = '0' + + and bill_no like 'WR%' + + order by create_time desc, id desc + + + + + bill_no = #{billNo} + AND (is_delete = '0' OR is_delete IS NULL) + + + LIMIT 1 + + + + UPDATE worn_inbound_bill + + + bill_no = #{billNo}, + bill_type = #{billType}, + + warehouse_code = #{warehouseCode}, + warehouse_name = #{warehouseName}, + + area_code = #{areaCode}, + area_name = #{areaName}, + + inbound_time = #{inboundTime}, + + status = #{status}, + + remark = #{remark}, + + update_by = #{updateBy}, + update_time = #{updateTime}, + + is_delete = #{isDelete}, + + + + WHERE id = #{id} + + \ No newline at end of file diff --git a/src/main/resources/mybatis/worn/WornInboundItemMapper.xml b/src/main/resources/mybatis/worn/WornInboundItemMapper.xml index 5546579..3b852ac 100644 --- a/src/main/resources/mybatis/worn/WornInboundItemMapper.xml +++ b/src/main/resources/mybatis/worn/WornInboundItemMapper.xml @@ -14,21 +14,87 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + + + + + + + + select id, bill_id, bill_no, material_id, quantity, unique_code, remark, create_by, create_time from worn_inbound_item - + SELECT + -- ===== 主表(bill)===== + b.id AS bill_id, + b.bill_no AS bill_no, + b.bill_type , + b.warehouse_code , + b.warehouse_name , + b.area_code , + b.area_name , + b.remark AS bill_remark, + b.inbound_time , + b.status AS bill_status, + b.update_by , + b.update_time , + + -- ===== 明细(item)===== + i.id AS id, + i.material_id, + i.quantity , + i.unique_code , + i.remark , + i.is_delete , + i.create_by , + i.create_time , + i.status, + -- ===== 物料(material)===== + m.material_name , + m.material_code , + m.material_short_name , + m.specification , + m.model , + m.weight, + m.unit_id, + mu.unit_name, + -- ===== 类型(material_type)===== + mt.type_name AS type_name, + ( + SELECT GROUP_CONCAT(t2.type_name ORDER BY t2.id SEPARATOR '/') + FROM worn_material_type t2 + WHERE FIND_IN_SET(t2.id, mt.ancestors) OR t2.id = mt.id + ) AS type_parent_names + FROM worn_inbound_bill b + LEFT JOIN worn_inbound_item i + ON b.id = i.bill_id + LEFT JOIN worn_material m + ON i.material_id = m.id + LEFT JOIN worn_material_type mt ON m.type_id = mt.id + LEFT JOIN worn_material_unit mu ON m.unit_id = mu.id + WHERE b.bill_no = #{billNo} + AND b.is_delete = '0' + AND (i.is_delete = '0' OR i.is_delete IS NULL) + + ORDER BY i.id ASC + SELECT COUNT(1) + FROM worn_inbound_item + WHERE bill_id = #{billId} + AND (is_delete = '0' OR is_delete IS NULL) + AND (status IS NULL OR status != '1') + + + update worn_inbound_item + set status = '2', + update_by = #{updateBy}, + update_time = #{updateTime} + where id = #{id} + and (is_delete = '0' or is_delete is null) + + \ No newline at end of file