|
|
@@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
|
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
|
|
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.ImportResultVO;
|
|
|
-import cn.iocoder.yudao.module.system.controller.admin.biz.vo.materialio.MaterialIoImportExcelVO;
|
|
|
import cn.iocoder.yudao.module.system.util.ImportUtil;
|
|
|
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.materialio.MaterialInBalanceListReqVO;
|
|
|
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.materialio.MaterialInBalanceRespVO;
|
|
|
@@ -2322,76 +2321,155 @@ public class MaterialIoServiceImpl implements MaterialIoService {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void exportImportTemplate(HttpServletResponse response) throws IOException {
|
|
|
- ExcelUtils.write(response, "物资出入库导入模板.xlsx", "模板", MaterialIoImportExcelVO.class, Collections.emptyList());
|
|
|
+ public void exportInboundImportTemplate(HttpServletResponse response) throws IOException {
|
|
|
+ ExcelUtils.write(response, "物资入库导入模板.xlsx", "模板", MaterialInboundImportExcelVO.class, Collections.emptyList());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void exportOutboundImportTemplate(HttpServletResponse response) throws IOException {
|
|
|
+ ExcelUtils.write(response, "物资出库导入模板.xlsx", "模板", MaterialOutboundImportExcelVO.class, Collections.emptyList());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public ImportResultVO importMaterialIo(MultipartFile file) {
|
|
|
- List<MaterialIoImportExcelVO> rows = ExcelUtils.read(file, MaterialIoImportExcelVO.class);
|
|
|
+ public ImportResultVO importInbound(MultipartFile file) throws IOException {
|
|
|
+ List<MaterialInboundImportExcelVO> rows = ExcelUtils.read(file, MaterialInboundImportExcelVO.class);
|
|
|
int success = 0;
|
|
|
- int rowNum = 1;
|
|
|
List<ImportResultVO.RowError> failures = new ArrayList<>();
|
|
|
+ Map<String, List<MaterialInboundImportExcelVO>> grouped = new LinkedHashMap<>();
|
|
|
|
|
|
- for (MaterialIoImportExcelVO row : rows) {
|
|
|
+ int rowNum = 1;
|
|
|
+ for (MaterialInboundImportExcelVO row : rows) {
|
|
|
rowNum++;
|
|
|
+ if (StringUtils.isBlank(row.getOrderNo())) {
|
|
|
+ ImportUtil.addFailure(failures, rowNum, null, row.getMaterialId() == null ? null : String.valueOf(row.getMaterialId()), "单据号不能为空");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ grouped.computeIfAbsent(row.getOrderNo().trim(), k -> new ArrayList<>()).add(row);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (Map.Entry<String, List<MaterialInboundImportExcelVO>> entry : grouped.entrySet()) {
|
|
|
try {
|
|
|
- MaterialIoOrderSaveReqVO reqVO = buildImportReq(row);
|
|
|
- if ("IN".equalsIgnoreCase(reqVO.getBizType())) {
|
|
|
- inbound(reqVO);
|
|
|
- } else if ("OUT".equalsIgnoreCase(reqVO.getBizType())) {
|
|
|
- outbound(reqVO);
|
|
|
- } else {
|
|
|
- throw new IllegalArgumentException("业务类型仅支持 IN 或 OUT");
|
|
|
- }
|
|
|
+ inbound(buildInboundReq(entry.getValue()));
|
|
|
success++;
|
|
|
} catch (Exception e) {
|
|
|
- ImportUtil.addFailure(failures, rowNum, null,
|
|
|
- row.getMaterialId() == null ? null : String.valueOf(row.getMaterialId()),
|
|
|
- e.getMessage(), e);
|
|
|
+ ImportUtil.addFailure(failures, null, null, entry.getKey(), e.getMessage(), e);
|
|
|
}
|
|
|
}
|
|
|
return ImportUtil.buildResult(success, failures);
|
|
|
}
|
|
|
|
|
|
- private MaterialIoOrderSaveReqVO buildImportReq(MaterialIoImportExcelVO row) {
|
|
|
- if (row.getBizType() == null) {
|
|
|
- throw new IllegalArgumentException("业务类型不能为空");
|
|
|
- }
|
|
|
- if (row.getOrderDate() == null) {
|
|
|
- throw new IllegalArgumentException("单据日期不能为空");
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public ImportResultVO importOutbound(MultipartFile file) throws IOException {
|
|
|
+ List<MaterialOutboundImportExcelVO> rows = ExcelUtils.read(file, MaterialOutboundImportExcelVO.class);
|
|
|
+ int success = 0;
|
|
|
+ List<ImportResultVO.RowError> failures = new ArrayList<>();
|
|
|
+ Map<String, List<MaterialOutboundImportExcelVO>> grouped = new LinkedHashMap<>();
|
|
|
+
|
|
|
+ int rowNum = 1;
|
|
|
+ for (MaterialOutboundImportExcelVO row : rows) {
|
|
|
+ rowNum++;
|
|
|
+ if (StringUtils.isBlank(row.getOrderNo())) {
|
|
|
+ ImportUtil.addFailure(failures, rowNum, null, row.getMaterialId() == null ? null : String.valueOf(row.getMaterialId()), "单据号不能为空");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ grouped.computeIfAbsent(row.getOrderNo().trim(), k -> new ArrayList<>()).add(row);
|
|
|
}
|
|
|
- if (row.getMaterialId() == null) {
|
|
|
- throw new IllegalArgumentException("物资ID不能为空");
|
|
|
+
|
|
|
+ for (Map.Entry<String, List<MaterialOutboundImportExcelVO>> entry : grouped.entrySet()) {
|
|
|
+ try {
|
|
|
+ outbound(buildOutboundReq(entry.getValue()));
|
|
|
+ success++;
|
|
|
+ } catch (Exception e) {
|
|
|
+ ImportUtil.addFailure(failures, null, null, entry.getKey(), e.getMessage(), e);
|
|
|
+ }
|
|
|
}
|
|
|
- if (row.getQuantity() == null || row.getQuantity() <= 0) {
|
|
|
- throw new IllegalArgumentException("数量必须大于0");
|
|
|
+ return ImportUtil.buildResult(success, failures);
|
|
|
+ }
|
|
|
+
|
|
|
+ private MaterialIoOrderSaveReqVO buildInboundReq(List<MaterialInboundImportExcelVO> groupRows) {
|
|
|
+ MaterialInboundImportExcelVO head = groupRows.get(0);
|
|
|
+ if (head.getOrderDate() == null) {
|
|
|
+ throw new IllegalArgumentException("单据日期不能为空");
|
|
|
}
|
|
|
+ MaterialIoOrderSaveReqVO reqVO = new MaterialIoOrderSaveReqVO();
|
|
|
+ reqVO.setBizType("IN");
|
|
|
+ reqVO.setOrderDate(head.getOrderDate());
|
|
|
+ reqVO.setRemark(head.getRemark());
|
|
|
+ reqVO.setTenantId(TenantContextHolder.getTenantId());
|
|
|
|
|
|
- MaterialIoOrderItemSaveReqVO item = new MaterialIoOrderItemSaveReqVO();
|
|
|
- item.setMaterialId(row.getMaterialId());
|
|
|
- item.setInboundItemId(row.getInboundItemId());
|
|
|
- item.setRefInStoreId(row.getRefInStoreId());
|
|
|
- item.setQuantity(row.getQuantity());
|
|
|
- item.setInUnitPrice(row.getInUnitPrice());
|
|
|
- item.setSaleUnitPrice(row.getSaleUnitPrice());
|
|
|
- item.setAmount(row.getAmount());
|
|
|
- item.setProduceDate(row.getProduceDate());
|
|
|
+ List<MaterialIoOrderItemSaveReqVO> items = new ArrayList<>();
|
|
|
+ for (MaterialInboundImportExcelVO row : groupRows) {
|
|
|
+ if (!Objects.equals(head.getOrderDate(), row.getOrderDate())) {
|
|
|
+ throw new IllegalArgumentException("同单号的单据日期必须一致");
|
|
|
+ }
|
|
|
+ if (!Objects.equals(StringUtils.trimToEmpty(head.getRemark()), StringUtils.trimToEmpty(row.getRemark()))) {
|
|
|
+ throw new IllegalArgumentException("同单号的备注必须一致");
|
|
|
+ }
|
|
|
+ if (row.getMaterialId() == null || row.getQuantity() == null || row.getQuantity() <= 0) {
|
|
|
+ throw new IllegalArgumentException("入库明细物资ID与数量必须填写且数量大于0");
|
|
|
+ }
|
|
|
+ MaterialIoOrderItemSaveReqVO item = new MaterialIoOrderItemSaveReqVO();
|
|
|
+ item.setMaterialId(row.getMaterialId());
|
|
|
+ item.setRefInStoreId(row.getRefInStoreId());
|
|
|
+ item.setQuantity(row.getQuantity());
|
|
|
+ item.setInUnitPrice(row.getInUnitPrice());
|
|
|
+ item.setAmount(row.getAmount());
|
|
|
+ item.setProduceDate(row.getProduceDate());
|
|
|
+ items.add(item);
|
|
|
+ }
|
|
|
+ reqVO.setItems(items);
|
|
|
+ return reqVO;
|
|
|
+ }
|
|
|
|
|
|
+ private MaterialIoOrderSaveReqVO buildOutboundReq(List<MaterialOutboundImportExcelVO> groupRows) {
|
|
|
+ MaterialOutboundImportExcelVO head = groupRows.get(0);
|
|
|
+ if (head.getOrderDate() == null) {
|
|
|
+ throw new IllegalArgumentException("单据日期不能为空");
|
|
|
+ }
|
|
|
+ if (head.getOutDeptId() == null) {
|
|
|
+ throw new IllegalArgumentException("领用部门ID不能为空");
|
|
|
+ }
|
|
|
MaterialIoOrderSaveReqVO reqVO = new MaterialIoOrderSaveReqVO();
|
|
|
- reqVO.setBizType(row.getBizType().trim().toUpperCase());
|
|
|
- reqVO.setOrderDate(row.getOrderDate());
|
|
|
- reqVO.setRemark(row.getRemark());
|
|
|
- reqVO.setOutDeptId(row.getOutDeptId());
|
|
|
- reqVO.setOutUser(row.getOutUser());
|
|
|
- reqVO.setOutReason(row.getOutReason());
|
|
|
+ reqVO.setBizType("OUT");
|
|
|
+ reqVO.setOrderDate(head.getOrderDate());
|
|
|
+ reqVO.setOutDeptId(head.getOutDeptId());
|
|
|
+ reqVO.setOutUser(head.getOutUser());
|
|
|
+ reqVO.setOutReason(head.getOutReason());
|
|
|
+ reqVO.setRemark(head.getRemark());
|
|
|
reqVO.setTenantId(TenantContextHolder.getTenantId());
|
|
|
- reqVO.setItems(Collections.singletonList(item));
|
|
|
|
|
|
- if ("OUT".equals(reqVO.getBizType()) && row.getInboundItemId() == null) {
|
|
|
- throw new IllegalArgumentException("出库导入时,入库批次明细ID不能为空");
|
|
|
+ List<MaterialIoOrderItemSaveReqVO> items = new ArrayList<>();
|
|
|
+ for (MaterialOutboundImportExcelVO row : groupRows) {
|
|
|
+ if (!Objects.equals(head.getOrderDate(), row.getOrderDate())) {
|
|
|
+ throw new IllegalArgumentException("同单号的单据日期必须一致");
|
|
|
+ }
|
|
|
+ if (!Objects.equals(head.getOutDeptId(), row.getOutDeptId())) {
|
|
|
+ throw new IllegalArgumentException("同单号的领用部门ID必须一致");
|
|
|
+ }
|
|
|
+ if (!Objects.equals(StringUtils.trimToEmpty(head.getOutUser()), StringUtils.trimToEmpty(row.getOutUser()))) {
|
|
|
+ throw new IllegalArgumentException("同单号的领用人必须一致");
|
|
|
+ }
|
|
|
+ if (!Objects.equals(StringUtils.trimToEmpty(head.getOutReason()), StringUtils.trimToEmpty(row.getOutReason()))) {
|
|
|
+ throw new IllegalArgumentException("同单号的出库原因必须一致");
|
|
|
+ }
|
|
|
+ if (!Objects.equals(StringUtils.trimToEmpty(head.getRemark()), StringUtils.trimToEmpty(row.getRemark()))) {
|
|
|
+ throw new IllegalArgumentException("同单号的备注必须一致");
|
|
|
+ }
|
|
|
+ if (row.getMaterialId() == null || row.getInboundItemId() == null || row.getQuantity() == null || row.getQuantity() <= 0) {
|
|
|
+ throw new IllegalArgumentException("出库明细物资ID、入库批次明细ID、数量必须填写且数量大于0");
|
|
|
+ }
|
|
|
+ MaterialIoOrderItemSaveReqVO item = new MaterialIoOrderItemSaveReqVO();
|
|
|
+ item.setMaterialId(row.getMaterialId());
|
|
|
+ item.setInboundItemId(row.getInboundItemId());
|
|
|
+ item.setQuantity(row.getQuantity());
|
|
|
+ item.setSaleUnitPrice(row.getSaleUnitPrice());
|
|
|
+ item.setAmount(row.getAmount());
|
|
|
+ item.setProduceDate(row.getProduceDate());
|
|
|
+ items.add(item);
|
|
|
}
|
|
|
+ reqVO.setItems(items);
|
|
|
return reqVO;
|
|
|
}
|
|
|
|
|
|
@@ -2427,3 +2505,4 @@ public class MaterialIoServiceImpl implements MaterialIoService {
|
|
|
|
|
|
}
|
|
|
|
|
|
+
|