完成采购调拨单,入库单,部分库存盘点。
This commit is contained in:
@@ -23,6 +23,7 @@ public class CustomerTenantHandler implements TenantLineHandler {
|
||||
customerTables.add("storage_list");
|
||||
customerTables.add("bom_list");
|
||||
customerTables.add("vendor");
|
||||
customerTables.add("productionform");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "InventoryCount")
|
||||
@@ -46,10 +48,10 @@ public class InventoryCountController {
|
||||
wrapper.like(Document::getFormCode, searchParams.searchCode());
|
||||
}
|
||||
}
|
||||
wrapper.orderByDesc(Document::getCreateDate);
|
||||
return BaseResult.successWithData(inventoryCountService.getInventoryCountPage(pageParams, wrapper));
|
||||
}
|
||||
|
||||
|
||||
@ApiLog(type = OperationType.ADD, remark = "新增一条InventoryCount记录")
|
||||
@Operation(summary = "新增InventoryCount", operationId = "addInventoryCount")
|
||||
@PostMapping("/addInventoryCount")
|
||||
@@ -59,66 +61,20 @@ public class InventoryCountController {
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@ApiLog(type = OperationType.UPDATE, remark = "更新一条InventoryCount记录")
|
||||
@Operation(summary = "更新InventoryCount", operationId = "updateInventoryCount")
|
||||
@PostMapping("/updateInventoryCount")
|
||||
@PreAuthorize("hasAuthority('inventory_count:update')")
|
||||
public BaseResult<?> updateInventoryCount(@Validated(Update.class) @RequestBody InventoryCountDto dto) {
|
||||
inventoryCountService.updateInventoryCount(dto);
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@ApiLog(type = OperationType.DELETE, remark = "删除一条InventoryCount记录")
|
||||
@Operation(summary = "删除InventoryCount", operationId = "deleteInventoryCount")
|
||||
@PostMapping("/deleteInventoryCount")
|
||||
@PreAuthorize("hasAuthority('inventory_count:delete')")
|
||||
@PreAuthorize("hasAuthority('inventory_count:remove')")
|
||||
public BaseResult<?> deleteInventoryCount(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
|
||||
inventoryCountService.deleteInventoryCount(req.id());
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@ApiLog(type = OperationType.DELETE, remark = "批量删除InventoryCount记录")
|
||||
@Operation(summary = "批量删除InventoryCount", operationId = "deleteInventoryCountBatch")
|
||||
@PostMapping("/deleteInventoryCountBatch")
|
||||
@PreAuthorize("hasAuthority('inventory_count:deleteBatch')")
|
||||
public BaseResult<?> deleteInventoryCountBatch(@Validated(DeleteBatch.class) @RequestBody BaseDeleteBody req) {
|
||||
inventoryCountService.deleteBatch(req.ids());
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@ApiLog(type = OperationType.UPDATE, remark = "审核InventoryCount")
|
||||
@Operation(summary = "审核InventoryCount", operationId = "approveInventoryCount")
|
||||
@PostMapping("/approveInventoryCount")
|
||||
@PreAuthorize("hasAuthority('inventory_count:approve')")
|
||||
public BaseResult<?> approveInventoryCount(
|
||||
@Parameter(description = "盘点单ID") @RequestParam Long id) {
|
||||
inventoryCountService.approve(id);
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@ApiLog(type = OperationType.UPDATE, remark = "反审核InventoryCount")
|
||||
@Operation(summary = "反审核InventoryCount", operationId = "unapproveInventoryCount")
|
||||
@PostMapping("/unapproveInventoryCount")
|
||||
@PreAuthorize("hasAuthority('inventory_count:unapprove')")
|
||||
public BaseResult<?> unapproveInventoryCount(
|
||||
@Parameter(description = "盘点单ID") @RequestParam Long id) {
|
||||
inventoryCountService.unapprove(id);
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "获取InventoryCount明细", operationId = "getInventoryCountDetail")
|
||||
@GetMapping("/getInventoryCountDetail")
|
||||
@PreAuthorize("hasAuthority('inventorycount:index')")
|
||||
@PreAuthorize("hasAuthority('inventory_count:index')")
|
||||
public BaseResult<List<InventoryCountItemDto>> getInventoryCountDetail(
|
||||
@Parameter(description = "盘点单ID") @RequestParam Long id) {
|
||||
return BaseResult.successWithData(inventoryCountService.getDetail(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "导入InventoryCount明细", operationId = "importInventoryCountItems")
|
||||
@PostMapping("/importInventoryCountItems")
|
||||
@PreAuthorize("hasAuthority('inventory_count:import')")
|
||||
public BaseResult<List<InventoryCountItemDto>> importInventoryCountItems(
|
||||
@Parameter(description = "Excel文件") @RequestParam("file") MultipartFile file) {
|
||||
return BaseResult.successWithData(inventoryCountService.importItems(file));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.niuan.erp.common.annotation.ApiLog;
|
||||
import com.niuan.erp.common.annotation.ModuleLog;
|
||||
import com.niuan.erp.common.base.BaseApproveAndRejectDto;
|
||||
import com.niuan.erp.common.base.BaseDeleteBody;
|
||||
import com.niuan.erp.common.base.BasePageReqParams;
|
||||
import com.niuan.erp.common.base.BaseResult;
|
||||
@@ -41,10 +42,13 @@ public class WarehouseReceiptController {
|
||||
public BaseResult<IPage<WarehouseReceiptDto>> getWarehouseReceiptPage(@Validated BasePageReqParams pageParams,
|
||||
@Validated(Get.class) WarehouseReceiptDto searchParams) {
|
||||
var wrapper = new LambdaQueryWrapper<Document>();
|
||||
if (searchParams != null) {
|
||||
if (StringUtils.hasText(searchParams.searchCode())) {
|
||||
wrapper.like(Document::getFormCode, searchParams.searchCode());
|
||||
}
|
||||
if (searchParams != null && StringUtils.hasText(searchParams.searchCode())) {
|
||||
String searchCode = searchParams.searchCode();
|
||||
wrapper.and(w -> w.like(Document::getFormCode, searchCode)
|
||||
.or()
|
||||
.like(Document::getFormName, searchCode)
|
||||
.or()
|
||||
.like(Document::getFormMark, searchCode));
|
||||
}
|
||||
return BaseResult.successWithData(warehouseReceiptService.getWarehouseReceiptPage(pageParams, wrapper));
|
||||
}
|
||||
@@ -71,7 +75,7 @@ public class WarehouseReceiptController {
|
||||
@ApiLog(type = OperationType.DELETE, remark = "删除一条WarehouseReceipt记录")
|
||||
@Operation(summary = "删除WarehouseReceipt", operationId = "deleteWarehouseReceipt")
|
||||
@PostMapping("/deleteWarehouseReceipt")
|
||||
@PreAuthorize("hasAuthority('warehouse_receipt:delete')")
|
||||
@PreAuthorize("hasAuthority('warehouse_receipt:remove')")
|
||||
public BaseResult<?> deleteWarehouseReceipt(@Validated(DeleteOne.class) @RequestBody BaseDeleteBody req) {
|
||||
warehouseReceiptService.deleteWarehouseReceipt(req.id());
|
||||
return BaseResult.success();
|
||||
@@ -91,34 +95,26 @@ public class WarehouseReceiptController {
|
||||
@PostMapping("/approveWarehouseReceipt")
|
||||
@PreAuthorize("hasAuthority('warehouse_receipt:approve')")
|
||||
public BaseResult<?> approveWarehouseReceipt(
|
||||
@Parameter(description = "入库单ID") @RequestParam Long id) {
|
||||
warehouseReceiptService.approve(id);
|
||||
@Validated @RequestBody BaseApproveAndRejectDto dto) {
|
||||
warehouseReceiptService.approve(dto.id());
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@ApiLog(type = OperationType.UPDATE, remark = "反审核WarehouseReceipt")
|
||||
@Operation(summary = "反审核WarehouseReceipt", operationId = "unapproveWarehouseReceipt")
|
||||
@PostMapping("/unapproveWarehouseReceipt")
|
||||
@PreAuthorize("hasAuthority('warehouse_receipt:unapprove')")
|
||||
public BaseResult<?> unapproveWarehouseReceipt(
|
||||
@Parameter(description = "入库单ID") @RequestParam Long id) {
|
||||
warehouseReceiptService.unapprove(id);
|
||||
@Operation(summary = "反审核WarehouseReceipt", operationId = "rejectWarehouseReceipt")
|
||||
@PostMapping("/rejectWarehouseReceipt")
|
||||
@PreAuthorize("hasAuthority('warehouse_receipt:reject')")
|
||||
public BaseResult<?> rejectWarehouseReceipt(
|
||||
@Validated @RequestBody BaseApproveAndRejectDto dto) {
|
||||
warehouseReceiptService.reject(dto.id());
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "获取WarehouseReceipt明细", operationId = "getWarehouseReceiptDetail")
|
||||
@GetMapping("/getWarehouseReceiptDetail")
|
||||
@PreAuthorize("hasAuthority('warehousereceipt:index')")
|
||||
@PreAuthorize("hasAuthority('warehouse_receipt:index')")
|
||||
public BaseResult<List<WarehouseReceiptItemDto>> getWarehouseReceiptDetail(
|
||||
@Parameter(description = "入库单ID") @RequestParam Long id) {
|
||||
return BaseResult.successWithData(warehouseReceiptService.getDetail(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "导入WarehouseReceipt明细", operationId = "importWarehouseReceiptItems")
|
||||
@PostMapping("/importWarehouseReceiptItems")
|
||||
@PreAuthorize("hasAuthority('warehouse_receipt:add')")
|
||||
public BaseResult<List<WarehouseReceiptItemDto>> importWarehouseReceiptItems(
|
||||
@Parameter(description = "Excel文件") @RequestParam("file") MultipartFile file) {
|
||||
return BaseResult.successWithData(warehouseReceiptService.importItems(file));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.niuan.erp.module.warehouse.controller.dto;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public record WarehouseReceiptDto(
|
||||
Long id,
|
||||
@@ -20,11 +21,6 @@ public record WarehouseReceiptDto(
|
||||
String formMark,
|
||||
Integer reserve1,
|
||||
String reserve2,
|
||||
Integer vendorNo,
|
||||
String vendorName,
|
||||
Double totalValue,
|
||||
Integer outStoreNo,
|
||||
String outStoreName,
|
||||
Integer groupId,
|
||||
Integer customerId,
|
||||
String searchCode) {}
|
||||
String searchCode,
|
||||
List<WarehouseReceiptItemAddDto> receiptItems) {}
|
||||
@@ -22,7 +22,6 @@ public interface InventoryCountConverter {
|
||||
InventoryCountItem toEntity(InventoryCountItemAddDto dto);
|
||||
List<InventoryCountItem> toEntityList(List<InventoryCountItemAddDto> dtoList);
|
||||
|
||||
@Mapping(target = "productSpec", ignore = true)
|
||||
InventoryCountItemDto toItemDto(InventoryCountItem entity);
|
||||
List<InventoryCountItemDto> toItemDtoList(List<InventoryCountItem> entities);
|
||||
}
|
||||
@@ -25,9 +25,7 @@ public interface WarehouseReceiptService {
|
||||
|
||||
void approve(long id);
|
||||
|
||||
void unapprove(long id);
|
||||
void reject(long id);
|
||||
|
||||
List<WarehouseReceiptItemDto> getDetail(long id);
|
||||
|
||||
List<WarehouseReceiptItemDto> importItems(MultipartFile file);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ import com.niuan.erp.module.warehouse.controller.dto.InventoryCountItemAddDto;
|
||||
import com.niuan.erp.module.warehouse.controller.dto.InventoryCountItemDto;
|
||||
import com.niuan.erp.module.warehouse.converter.InventoryCountConverter;
|
||||
import com.niuan.erp.module.warehouse.entity.InventoryCountItem;
|
||||
import com.niuan.erp.module.warehouse.entity.Stock;
|
||||
import com.niuan.erp.module.warehouse.entity.WarehouseItem;
|
||||
import com.niuan.erp.module.warehouse.mapper.InventoryCountItemMapper;
|
||||
import com.niuan.erp.module.warehouse.mapper.StockMapper;
|
||||
import com.niuan.erp.module.warehouse.mapper.WarehouseItemMapper;
|
||||
import com.niuan.erp.module.warehouse.service.InventoryCountService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
@@ -45,7 +45,7 @@ public class InventoryCountServiceImpl extends ServiceImpl<DocumentMapper, Docum
|
||||
|
||||
private final InventoryCountItemMapper inventoryCountItemMapper;
|
||||
|
||||
private final StockMapper stockMapper;
|
||||
private final WarehouseItemMapper warehouseItemMapper;
|
||||
|
||||
@Override
|
||||
public IPage<InventoryCountDto> getInventoryCountPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) {
|
||||
@@ -87,20 +87,16 @@ public class InventoryCountServiceImpl extends ServiceImpl<DocumentMapper, Docum
|
||||
.map(InventoryCountItem::getPartNumber)
|
||||
.toList();
|
||||
|
||||
LambdaQueryWrapper<Stock> stockWrapper = new LambdaQueryWrapper<>();
|
||||
stockWrapper.eq(Stock::getStoreNo, dto.storeNo())
|
||||
.in(Stock::getPartNumber, partNumbers);
|
||||
List<Stock> stockList = stockMapper.selectList(stockWrapper);
|
||||
Map<String, Stock> stockMap = stockList.stream()
|
||||
.collect(Collectors.toMap(Stock::getPartNumber, s -> s));
|
||||
Map<String, Map<String, Object>> stockMaps = warehouseItemMapper.getWarehouseItemStockListByPartNumbers(partNumbers);
|
||||
Map<String, Integer> stockMap = new HashMap<>();
|
||||
for (Map.Entry<String, Map<String, Object>> entry : stockMaps.entrySet()) {
|
||||
stockMap.put(entry.getKey(), ((Number) entry.getValue().get("productCount")).intValue());
|
||||
}
|
||||
|
||||
for (InventoryCountItem item : items) {
|
||||
Stock stock = stockMap.get(item.getPartNumber());
|
||||
if (stock == null) {
|
||||
throw new BusinessException("warehouse.inventory_count.exception.stock_not_found");
|
||||
}
|
||||
item.setOriginalProductCount(stock.getProductCount());
|
||||
item.setDiffCount(item.getProductCount() - stock.getProductCount());
|
||||
Integer originalCount = stockMap.get(item.getPartNumber());
|
||||
item.setOriginalProductCount(originalCount != null ? originalCount : 0);
|
||||
item.setDiffCount(item.getProductCount() - item.getOriginalProductCount());
|
||||
}
|
||||
} else {
|
||||
for (InventoryCountItem item : items) {
|
||||
@@ -121,25 +117,6 @@ public class InventoryCountServiceImpl extends ServiceImpl<DocumentMapper, Docum
|
||||
}
|
||||
|
||||
inventoryCountItemMapper.insert(items);
|
||||
|
||||
if (isInit == 1) {
|
||||
List<Stock> newStocks = new ArrayList<>();
|
||||
for (InventoryCountItem item : items) {
|
||||
Stock stock = new Stock();
|
||||
stock.setPartNumber(item.getPartNumber());
|
||||
stock.setProductCount(item.getProductCount());
|
||||
stock.setStoreNo(dto.storeNo());
|
||||
stock.setStoreName(dto.storeName());
|
||||
stock.setCreateDate(LocalDateTime.now());
|
||||
stock.setCreateUserId(SecurityUtils.getUserId());
|
||||
stock.setCreateUserName(SecurityUtils.getUserName());
|
||||
stock.setStatus(0);
|
||||
newStocks.add(stock);
|
||||
}
|
||||
for (Stock stock : newStocks) {
|
||||
stockMapper.insert(stock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -214,47 +191,6 @@ public class InventoryCountServiceImpl extends ServiceImpl<DocumentMapper, Docum
|
||||
throw new BusinessException("warehouse.inventory_count.exception.no_items");
|
||||
}
|
||||
|
||||
Integer storeNo = entity.getStoreNo();
|
||||
List<String> partNumbers = items.stream()
|
||||
.map(InventoryCountItem::getPartNumber)
|
||||
.toList();
|
||||
|
||||
LambdaQueryWrapper<Stock> stockWrapper = new LambdaQueryWrapper<>();
|
||||
stockWrapper.eq(Stock::getStoreNo, storeNo)
|
||||
.in(Stock::getPartNumber, partNumbers);
|
||||
List<Stock> existingStockList = stockMapper.selectList(stockWrapper);
|
||||
Map<String, Stock> existingStockMap = existingStockList.stream()
|
||||
.collect(Collectors.toMap(Stock::getPartNumber, s -> s));
|
||||
|
||||
List<Stock> newStocks = new ArrayList<>();
|
||||
for (InventoryCountItem item : items) {
|
||||
Stock existingStock = existingStockMap.get(item.getPartNumber());
|
||||
if (existingStock == null) {
|
||||
Stock newStock = new Stock();
|
||||
newStock.setPartNumber(item.getPartNumber());
|
||||
newStock.setProductCount(item.getProductCount());
|
||||
newStock.setStoreNo(storeNo);
|
||||
newStock.setStoreName(entity.getStoreName());
|
||||
newStock.setCreateDate(LocalDateTime.now());
|
||||
newStock.setCreateUserId(SecurityUtils.getUserId());
|
||||
newStock.setCreateUserName(SecurityUtils.getUserName());
|
||||
newStock.setStatus(0);
|
||||
newStocks.add(newStock);
|
||||
} else {
|
||||
existingStock.setProductCount(item.getProductCount());
|
||||
existingStock.setUpdateDate(LocalDateTime.now());
|
||||
existingStock.setUpdateUserId(SecurityUtils.getUserId());
|
||||
existingStock.setUpdateUserName(SecurityUtils.getUserName());
|
||||
stockMapper.updateById(existingStock);
|
||||
}
|
||||
}
|
||||
|
||||
if (!newStocks.isEmpty()) {
|
||||
for (Stock newStock : newStocks) {
|
||||
stockMapper.insert(newStock);
|
||||
}
|
||||
}
|
||||
|
||||
entity.setFormStatus(FormStatus.APPROVE);
|
||||
entity.setUpdateDate(LocalDateTime.now());
|
||||
entity.setUpdateUserId(SecurityUtils.getUserId());
|
||||
@@ -281,31 +217,7 @@ public class InventoryCountServiceImpl extends ServiceImpl<DocumentMapper, Docum
|
||||
|
||||
LambdaQueryWrapper<InventoryCountItem> itemWrapper = new LambdaQueryWrapper<>();
|
||||
itemWrapper.eq(InventoryCountItem::getDocumentNo, id);
|
||||
List<InventoryCountItem> items = inventoryCountItemMapper.selectList(itemWrapper);
|
||||
|
||||
Integer storeNo = entity.getStoreNo();
|
||||
List<String> partNumbers = items.stream()
|
||||
.map(InventoryCountItem::getPartNumber)
|
||||
.toList();
|
||||
|
||||
LambdaQueryWrapper<Stock> stockWrapper = new LambdaQueryWrapper<>();
|
||||
stockWrapper.eq(Stock::getStoreNo, storeNo)
|
||||
.in(Stock::getPartNumber, partNumbers);
|
||||
List<Stock> existingStockList = stockMapper.selectList(stockWrapper);
|
||||
Map<String, Stock> existingStockMap = existingStockList.stream()
|
||||
.collect(Collectors.toMap(Stock::getPartNumber, s -> s));
|
||||
|
||||
for (InventoryCountItem item : items) {
|
||||
Stock existingStock = existingStockMap.get(item.getPartNumber());
|
||||
if (existingStock == null) {
|
||||
throw new BusinessException("warehouse.inventory_count.exception.stock_not_found_for_unapprove");
|
||||
}
|
||||
existingStock.setProductCount(item.getOriginalProductCount());
|
||||
existingStock.setUpdateDate(LocalDateTime.now());
|
||||
existingStock.setUpdateUserId(SecurityUtils.getUserId());
|
||||
existingStock.setUpdateUserName(SecurityUtils.getUserName());
|
||||
stockMapper.updateById(existingStock);
|
||||
}
|
||||
inventoryCountItemMapper.selectList(itemWrapper);
|
||||
|
||||
entity.setFormStatus(FormStatus.NO_APPROVE);
|
||||
entity.setUpdateDate(LocalDateTime.now());
|
||||
@@ -326,7 +238,47 @@ public class InventoryCountServiceImpl extends ServiceImpl<DocumentMapper, Docum
|
||||
LambdaQueryWrapper<InventoryCountItem> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(InventoryCountItem::getDocumentNo, id);
|
||||
List<InventoryCountItem> items = inventoryCountItemMapper.selectList(wrapper);
|
||||
return inventoryCountConverter.toItemDtoList(items);
|
||||
|
||||
List<String> partNumbers = items.stream()
|
||||
.map(InventoryCountItem::getPartNumber)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
Map<String, String> partNumberToSpecs = new HashMap<>();
|
||||
if (!partNumbers.isEmpty()) {
|
||||
LambdaQueryWrapper<WarehouseItem> itemWrapper = new LambdaQueryWrapper<>();
|
||||
itemWrapper.in(WarehouseItem::getPartNumber, partNumbers);
|
||||
List<WarehouseItem> warehouseItems = warehouseItemMapper.selectList(itemWrapper);
|
||||
partNumberToSpecs = warehouseItems.stream()
|
||||
.collect(Collectors.toMap(WarehouseItem::getPartNumber, WarehouseItem::getProductSpecs, (v1, v2) -> v1));
|
||||
}
|
||||
|
||||
List<InventoryCountItemDto> dtoList = inventoryCountConverter.toItemDtoList(items);
|
||||
Map<String, String> finalPartNumberToSpecs = partNumberToSpecs;
|
||||
return dtoList.stream()
|
||||
.map(dto -> new InventoryCountItemDto(
|
||||
dto.id(),
|
||||
dto.status(),
|
||||
dto.createDate(),
|
||||
dto.createUserId(),
|
||||
dto.createUserName(),
|
||||
dto.updateDate(),
|
||||
dto.updateUserId(),
|
||||
dto.updateUserName(),
|
||||
dto.storeNo(),
|
||||
dto.storeName(),
|
||||
dto.partNumber(),
|
||||
dto.productCount(),
|
||||
dto.diffCount(),
|
||||
dto.stockTakingMark(),
|
||||
dto.reserve1(),
|
||||
dto.reserve2(),
|
||||
dto.documentNo(),
|
||||
dto.originalProductCount(),
|
||||
finalPartNumberToSpecs.get(dto.partNumber())
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,9 @@ import com.niuan.erp.module.warehouse.controller.dto.WarehouseReceiptItemAddDto;
|
||||
import com.niuan.erp.module.warehouse.controller.dto.WarehouseReceiptItemDto;
|
||||
import com.niuan.erp.module.warehouse.converter.WarehouseReceiptConverter;
|
||||
import com.niuan.erp.module.warehouse.entity.Stock;
|
||||
import com.niuan.erp.module.warehouse.entity.WarehouseItem;
|
||||
import com.niuan.erp.module.warehouse.mapper.StockMapper;
|
||||
import com.niuan.erp.module.warehouse.mapper.WarehouseItemMapper;
|
||||
import com.niuan.erp.module.warehouse.service.WarehouseReceiptService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
@@ -47,9 +49,12 @@ public class WarehouseReceiptServiceImpl extends ServiceImpl<DocumentMapper, Doc
|
||||
|
||||
private final StockMapper stockMapper;
|
||||
|
||||
private final WarehouseItemMapper warehouseItemMapper;
|
||||
|
||||
@Override
|
||||
public IPage<WarehouseReceiptDto> getWarehouseReceiptPage(BasePageReqParams pageParams, LambdaQueryWrapper<Document> wrapper) {
|
||||
wrapper.eq(Document::getFormType, DocumentType.WAREHOUSE_RECEIPT);
|
||||
wrapper.eq(Document::getFormType, DocumentType.WAREHOUSE_RECEIPT)
|
||||
.orderByDesc(Document::getCreateDate);
|
||||
IPage<Document> result = this.baseMapper.selectPage(new Page<>(pageParams.page(), pageParams.pageSize()), wrapper);
|
||||
return result.convert(warehouseReceiptConverter::toDto);
|
||||
}
|
||||
@@ -93,6 +98,24 @@ public class WarehouseReceiptServiceImpl extends ServiceImpl<DocumentMapper, Doc
|
||||
entity.setUpdateUserName(SecurityUtils.getUserName());
|
||||
entity.setUpdateDate(LocalDateTime.now());
|
||||
this.baseMapper.updateById(entity);
|
||||
|
||||
// 删除旧明细
|
||||
LambdaQueryWrapper<DocumentMaterial> materialWrapper = new LambdaQueryWrapper<>();
|
||||
materialWrapper.eq(DocumentMaterial::getDocumentNo, dto.id());
|
||||
documentMaterialMapper.delete(materialWrapper);
|
||||
|
||||
// 插入新明细
|
||||
if (dto.receiptItems() != null && !dto.receiptItems().isEmpty()) {
|
||||
List<DocumentMaterial> materials = warehouseReceiptConverter.toEntityList(dto.receiptItems());
|
||||
materials.forEach(m -> {
|
||||
m.setDocumentNo(dto.id().intValue());
|
||||
m.setCreateUserId(SecurityUtils.getUserId());
|
||||
m.setCreateUserName(SecurityUtils.getUserName());
|
||||
m.setCreateDate(LocalDateTime.now());
|
||||
m.setStatus(0);
|
||||
});
|
||||
documentMaterialMapper.insert(materials);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,6 +185,7 @@ public class WarehouseReceiptServiceImpl extends ServiceImpl<DocumentMapper, Doc
|
||||
Map<String, Stock> existingStockMap = existingStockList.stream()
|
||||
.collect(Collectors.toMap(Stock::getPartNumber, s -> s));
|
||||
|
||||
String storeName = entity.getStoreName();
|
||||
List<Stock> newStocks = new ArrayList<>();
|
||||
for (DocumentMaterial material : materialList) {
|
||||
Stock existingStock = existingStockMap.get(material.getPartNumber());
|
||||
@@ -170,6 +194,7 @@ public class WarehouseReceiptServiceImpl extends ServiceImpl<DocumentMapper, Doc
|
||||
newStock.setPartNumber(material.getPartNumber());
|
||||
newStock.setProductCount(material.getProductCount());
|
||||
newStock.setStoreNo(storeNo);
|
||||
newStock.setStoreName(storeName);
|
||||
newStock.setCreateDate(LocalDateTime.now());
|
||||
newStock.setCreateUserId(SecurityUtils.getUserId());
|
||||
newStock.setCreateUserName(SecurityUtils.getUserName());
|
||||
@@ -205,7 +230,7 @@ public class WarehouseReceiptServiceImpl extends ServiceImpl<DocumentMapper, Doc
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unapprove(long id) {
|
||||
public void reject(long id) {
|
||||
Document entity = this.baseMapper.selectById(id);
|
||||
if (entity == null) {
|
||||
throw new BusinessException("warehouse.warehouse_receipt.exception.not_found");
|
||||
@@ -264,60 +289,52 @@ public class WarehouseReceiptServiceImpl extends ServiceImpl<DocumentMapper, Doc
|
||||
LambdaQueryWrapper<DocumentMaterial> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(DocumentMaterial::getDocumentNo, id);
|
||||
List<DocumentMaterial> materials = documentMaterialMapper.selectList(wrapper);
|
||||
return warehouseReceiptConverter.toItemDtoList(materials);
|
||||
|
||||
// 获取所有物料编号
|
||||
List<String> partNumbers = materials.stream()
|
||||
.map(DocumentMaterial::getPartNumber)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
// 查询物料规格信息
|
||||
Map<String, String> partNumberToSpecs = new HashMap<>();
|
||||
if (!partNumbers.isEmpty()) {
|
||||
LambdaQueryWrapper<WarehouseItem> itemWrapper = new LambdaQueryWrapper<>();
|
||||
itemWrapper.in(WarehouseItem::getPartNumber, partNumbers);
|
||||
List<WarehouseItem> items = warehouseItemMapper.selectList(itemWrapper);
|
||||
partNumberToSpecs = items.stream()
|
||||
.collect(Collectors.toMap(WarehouseItem::getPartNumber, WarehouseItem::getProductSpecs, (v1, v2) -> v1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WarehouseReceiptItemDto> importItems(MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new BusinessException("warehouse.warehouse_receipt.exception.file_empty");
|
||||
}
|
||||
|
||||
try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
List<WarehouseReceiptItemDto> items = new ArrayList<>();
|
||||
|
||||
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
|
||||
Row row = sheet.getRow(i);
|
||||
if (row == null) continue;
|
||||
|
||||
String partNumber = getCellValueAsString(row.getCell(0));
|
||||
String productSpec = getCellValueAsString(row.getCell(1));
|
||||
String countStr = getCellValueAsString(row.getCell(2));
|
||||
|
||||
if (!StringUtils.hasText(partNumber)) continue;
|
||||
|
||||
int productCount = 0;
|
||||
if (StringUtils.hasText(countStr)) {
|
||||
try {
|
||||
productCount = Integer.parseInt(countStr);
|
||||
} catch (NumberFormatException e) {
|
||||
productCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
WarehouseReceiptItemDto item = new WarehouseReceiptItemDto(
|
||||
null, null, null, null, null, null, null, null,
|
||||
null, partNumber, null, productCount, null, null, null, null, null, null, productSpec
|
||||
// 转换并填充 productSpec
|
||||
List<WarehouseReceiptItemDto> dtoList = warehouseReceiptConverter.toItemDtoList(materials);
|
||||
Map<String, String> finalPartNumberToSpecs = partNumberToSpecs;
|
||||
return dtoList.stream()
|
||||
.map(dto -> {
|
||||
String specs = finalPartNumberToSpecs.get(dto.partNumber());
|
||||
return new WarehouseReceiptItemDto(
|
||||
dto.id(),
|
||||
dto.status(),
|
||||
dto.createDate(),
|
||||
dto.createUserId(),
|
||||
dto.createUserName(),
|
||||
dto.updateDate(),
|
||||
dto.updateUserId(),
|
||||
dto.updateUserName(),
|
||||
dto.documentNo(),
|
||||
dto.partNumber(),
|
||||
dto.originalCount(),
|
||||
dto.productCount(),
|
||||
dto.productMark(),
|
||||
dto.reserve1(),
|
||||
dto.reserve2(),
|
||||
dto.storeNo(),
|
||||
dto.demandCount(),
|
||||
dto.partId(),
|
||||
specs
|
||||
);
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
return items;
|
||||
} catch (IOException e) {
|
||||
throw new BusinessException("warehouse.warehouse_receipt.exception.import_failed");
|
||||
}
|
||||
}
|
||||
|
||||
private String getCellValueAsString(Cell cell) {
|
||||
if (cell == null) {
|
||||
return "";
|
||||
}
|
||||
return switch (cell.getCellType()) {
|
||||
case STRING -> cell.getStringCellValue().trim();
|
||||
case NUMERIC -> String.valueOf((long) cell.getNumericCellValue());
|
||||
case BOOLEAN -> String.valueOf(cell.getBooleanCellValue());
|
||||
default -> "";
|
||||
};
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,28 @@ warehouse.stock_transfer_order.validate.product_count.min=调拨数量不能小
|
||||
warehouse.stock_transfer_order.validate.part_id.not_null=物料 ID 不能为空
|
||||
warehouse.stock_transfer_order.validate.order_id.not_null=调拨单 ID 不能为空
|
||||
|
||||
warehouse.inventory_count.validate.form_code.not_null=盘点单编号不能为空
|
||||
warehouse.inventory_count.validate.form_name.not_null=盘点单名称不能为空
|
||||
warehouse.inventory_count.validate.store_no.not_null=仓库 ID 不能为空
|
||||
warehouse.inventory_count.validate.store_name.not_null=仓库名称不能为空
|
||||
warehouse.inventory_count.validate.count_items.not_null=盘点明细不能为空
|
||||
warehouse.inventory_count.validate.part_number.not_null=物料编号不能为空
|
||||
warehouse.inventory_count.validate.product_count.not_null=盘点数量不能为空
|
||||
warehouse.inventory_count.validate.product_count.min=盘点数量不能小于 0
|
||||
warehouse.inventory_count.exception.init_already_exists=当前仓库已有初始库存单
|
||||
warehouse.inventory_count.exception.stock_not_found=物料库存不存在
|
||||
warehouse.inventory_count.exception.not_found=盘点单不存在
|
||||
warehouse.inventory_count.exception.cannot_update_approved=已审核的盘点单不能修改
|
||||
warehouse.inventory_count.exception.cannot_delete_approved=已审核的盘点单不能删除
|
||||
warehouse.inventory_count.exception.cannot_delete_approved_batch=选中的盘点单中包含已审核的单据,不能删除
|
||||
warehouse.inventory_count.exception.ids_empty=请选择要删除的记录
|
||||
warehouse.inventory_count.exception.already_approved=盘点单已经审核
|
||||
warehouse.inventory_count.exception.not_approved=盘点单不是已审核状态,不能反审
|
||||
warehouse.inventory_count.exception.no_items=盘点单没有明细
|
||||
warehouse.inventory_count.exception.file_empty=文件不能为空
|
||||
warehouse.inventory_count.exception.import_failed=导入失败
|
||||
warehouse.inventory_count.exception.stock_not_found_for_unapprove=反审核时找不到对应库存记录
|
||||
|
||||
|
||||
# ==========>> 生产管理
|
||||
|
||||
@@ -86,7 +108,7 @@ password.notNull=密码不能为空
|
||||
httpMessage.notNull=参数不能为空
|
||||
validated.error=参数错误
|
||||
|
||||
#jakarta.validation.constraints.NotNull.message=“{0}”不能为空
|
||||
#jakarta.validation.constraints.NotBlank.message=“{0}”不能为空
|
||||
#jakarta.validation.constraints.Size.message=“{0}”长度必须在{min}到{max}之间
|
||||
#jakarta.validation.constraints.Pattern.message=“{0}”格式不正确
|
||||
#jakarta.validation.constraints.NotNull.message="{0}"不能为空
|
||||
#jakarta.validation.constraints.NotBlank.message="{0}"不能为空
|
||||
#jakarta.validation.constraints.Size.message="{0}"长度必须在{min}到{max}之间
|
||||
#jakarta.validation.constraints.Pattern.message="{0}"格式不正确
|
||||
|
||||
Reference in New Issue
Block a user