fix:备件出库添加出库用途

main
HuangHuiKang 1 day ago
parent d88b519326
commit 418c0ca99b

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.erp.enums;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
@RequiredArgsConstructor
@Getter
public enum ErpStockOutUsageTypeEnum implements IntArrayValuable {
REPAIR_RECEIVE(1, "维修领用"),
MAINTENANCE_RECEIVE(2, "保养领用"),
OTHER_OUT(3, "其他出库");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockOutUsageTypeEnum::getType).toArray();
private final Integer type;
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
public static String getNameByType(Integer type) {
if (type == null) {
return null;
}
for (ErpStockOutUsageTypeEnum value : values()) {
if (value.getType().equals(type)) {
return value.getName();
}
}
return null;
}
}

@ -32,6 +32,11 @@
<artifactId>yudao-module-infra-api</artifactId> <artifactId>yudao-module-infra-api</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-mes-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 --> <!-- 业务组件 -->

@ -63,8 +63,8 @@ public class ErpStockController {
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得产品库存") @Operation(summary = "获得产品库存")
@Parameters({ @Parameters({
@Parameter(name = "id", description = "编号", example = "1"), // 方案一:传递 id @Parameter(name = "id", description = "编号", example = "1"),
@Parameter(name = "productId", description = "产品编号", example = "10"), // 方案二:传递 productId + warehouseId @Parameter(name = "productId", description = "产品编号", example = "10"),
@Parameter(name = "warehouseId", description = "仓库编号", example = "2") @Parameter(name = "warehouseId", description = "仓库编号", example = "2")
}) })
@PreAuthorize("@ss.hasPermission('erp:stock:query')") @PreAuthorize("@ss.hasPermission('erp:stock:query')")
@ -96,10 +96,9 @@ public class ErpStockController {
@PreAuthorize("@ss.hasPermission('erp:stock:export')") @PreAuthorize("@ss.hasPermission('erp:stock:export')")
@ApiAccessLog(operateType = EXPORT) @ApiAccessLog(operateType = EXPORT)
public void exportStockExcel(@Valid ErpStockPageReqVO pageReqVO, public void exportStockExcel(@Valid ErpStockPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ErpStockRespVO> list = buildStockVOPageResult(stockService.getStockPage(pageReqVO)).getList(); List<ErpStockRespVO> list = buildStockVOPageResult(stockService.getStockPage(pageReqVO)).getList();
// 导出 Excel
ExcelUtils.write(response, "产品库存.xls", "数据", ErpStockRespVO.class, list); ExcelUtils.write(response, "产品库存.xls", "数据", ErpStockRespVO.class, list);
} }
@ -119,7 +118,10 @@ public class ErpStockController {
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName()) .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())
.setCategoryType(product.getCategoryType()); .setCategoryType(product.getCategoryType());
fillProductExtraInfo(stock, product); fillProductExtraInfo(stock, product);
fillPackagingSnapshot(stock, product);
}); });
stock.setPackagingRule(buildPackagingRule(stock));
stock.setStockDisplay(buildStockDisplay(stock));
MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName())); MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName()));
if (stock.getAreaName() == null) { if (stock.getAreaName() == null) {
MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> stock.setAreaName(area.getAreaName())); MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> stock.setAreaName(area.getAreaName()));
@ -138,10 +140,18 @@ public class ErpStockController {
respVO.setProductName(product.getName()); respVO.setProductName(product.getName());
respVO.setBarCode(product.getBarCode()); respVO.setBarCode(product.getBarCode());
respVO.setCategoryName(product.getCategoryName()); respVO.setCategoryName(product.getCategoryName());
respVO.setUnitName(product.getUnitName()); if (respVO.getUnitName() == null) {
respVO.setCategoryType(product.getCategoryType()); respVO.setUnitName(product.getUnitName());
}
if (respVO.getCategoryType() == null) {
respVO.setCategoryType(product.getCategoryType());
}
fillProductExtraInfo(respVO, product); fillProductExtraInfo(respVO, product);
fillPackagingSnapshot(respVO, product);
} }
fillDerivedFields(respVO);
respVO.setPackagingRule(buildPackagingRule(respVO));
respVO.setStockDisplay(buildStockDisplay(respVO));
ErpWarehouseDO warehouse = warehouseService.getWarehouse(stock.getWarehouseId()); ErpWarehouseDO warehouse = warehouseService.getWarehouse(stock.getWarehouseId());
if (warehouse != null) { if (warehouse != null) {
respVO.setWarehouseName(warehouse.getName()); respVO.setWarehouseName(warehouse.getName());
@ -162,16 +172,64 @@ public class ErpStockController {
stock.setRecentOutTime(stockRecordService.getLatestRecordTime( stock.setRecentOutTime(stockRecordService.getLatestRecordTime(
stock.getProductId(), stock.getWarehouseId(), stock.getAreaId(), false)); stock.getProductId(), stock.getWarehouseId(), stock.getAreaId(), false));
} }
private void fillProductExtraInfo(ErpStockRespVO stock, ErpProductRespVO product) { private void fillProductExtraInfo(ErpStockRespVO stock, ErpProductRespVO product) {
stock.setUnitId(product.getUnitId()); if (stock.getUnitId() == null) {
stock.setPurchaseUnitId(product.getPurchaseUnitId()); stock.setUnitId(product.getUnitId());
stock.setPurchaseUnitName(product.getPurchaseUnitName()); }
stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity()); if (stock.getPurchaseUnitId() == null) {
stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId()); stock.setPurchaseUnitId(product.getPurchaseUnitId());
stock.setDefaultPackagingScheme(findDefaultPackagingScheme(product)); }
if (stock.getPurchaseUnitName() == null) {
stock.setPurchaseUnitName(product.getPurchaseUnitName());
}
if (stock.getPurchaseUnitConvertQuantity() == null) {
stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity());
}
if (stock.getDefaultPackagingSchemeId() == null) {
stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId());
}
if (stock.getDefaultPackagingScheme() == null) {
stock.setDefaultPackagingScheme(findDefaultPackagingScheme(product));
}
}
private void fillPackagingSnapshot(ErpStockRespVO stock, ErpProductRespVO product) {
if (stock.getDefaultPackagingSchemeName() != null
&& stock.getPackageQuantity() != null
&& stock.getPalletPackageQuantity() != null
&& stock.getPalletTotalQuantity() != null) {
return;
}
ProductPackagingSchemeRespVO defaultScheme = findDefaultPackagingScheme(product);
if (defaultScheme == null) {
return;
}
if (stock.getDefaultPackagingSchemeName() == null) {
stock.setDefaultPackagingSchemeName(defaultScheme.getPackagingSchemeName());
}
if (stock.getPackageQuantity() == null) {
stock.setPackageQuantity(defaultScheme.getPackageQuantity());
}
if (stock.getPalletPackageQuantity() == null) {
stock.setPalletPackageQuantity(defaultScheme.getPalletPackageQuantity());
}
if (stock.getPalletTotalQuantity() == null) {
stock.setPalletTotalQuantity(defaultScheme.getPalletTotalQuantity());
}
}
private void fillDerivedFields(ErpStockRespVO stock) {
if (stock.getUnitName() == null && stock.getUnitId() != null) {
// no-op: 目前库存单位名称只能从产品侧回填
}
if (stock.getDefaultPackagingSchemeId() == null && stock.getDefaultPackagingScheme() != null) {
stock.setDefaultPackagingSchemeId(stock.getDefaultPackagingScheme().getPackagingSchemeId());
}
} }
private ProductPackagingSchemeRespVO findDefaultPackagingScheme(ErpProductRespVO product) { private ProductPackagingSchemeRespVO findDefaultPackagingScheme(ErpProductRespVO product) {
if (product.getDefaultPackagingSchemeId() == null || CollUtil.isEmpty(product.getPackagingSchemes())) { if (product == null || product.getDefaultPackagingSchemeId() == null || CollUtil.isEmpty(product.getPackagingSchemes())) {
return null; return null;
} }
return product.getPackagingSchemes().stream() return product.getPackagingSchemes().stream()
@ -179,4 +237,68 @@ public class ErpStockController {
.findFirst() .findFirst()
.orElse(null); .orElse(null);
} }
private String buildPackagingRule(ErpStockRespVO stock) {
if (stock == null) {
return null;
}
if (isProductType(stock.getCategoryType())) {
if (stock.getPackageQuantity() == null || stock.getPalletPackageQuantity() == null) {
return null;
}
return "1托=" + formatNumber(stock.getPalletPackageQuantity()) + "包 1包=" + formatNumber(stock.getPackageQuantity()) + "个";
}
if (stock.getPurchaseUnitName() == null || stock.getPurchaseUnitConvertQuantity() == null) {
return null;
}
return "1" + stock.getPurchaseUnitName() + "=" + formatNumber(stock.getPurchaseUnitConvertQuantity()) + "个";
}
private String buildStockDisplay(ErpStockRespVO stock) {
if (stock == null || stock.getCount() == null) {
return null;
}
if (isProductType(stock.getCategoryType())) {
if (stock.getPalletTotalQuantity() == null || stock.getPalletTotalQuantity().compareTo(BigDecimal.ZERO) <= 0) {
return formatNumber(stock.getCount()) + stock.getUnitName();
}
BigDecimal palletCount = stock.getCount().divideToIntegralValue(stock.getPalletTotalQuantity());
return formatNumber(palletCount) + "托,0包,0个";
}
if (stock.getPurchaseUnitConvertQuantity() == null || stock.getPurchaseUnitConvertQuantity().compareTo(BigDecimal.ZERO) <= 0
|| stock.getPurchaseUnitName() == null || stock.getUnitName() == null) {
return formatNumber(stock.getCount()) + stock.getUnitName();
}
BigDecimal purchaseCount = stock.getCount().divideToIntegralValue(stock.getPurchaseUnitConvertQuantity());
BigDecimal unitCount = stock.getCount().remainder(stock.getPurchaseUnitConvertQuantity());
StringBuilder display = new StringBuilder();
appendQuantity(display, purchaseCount, stock.getPurchaseUnitName(), true);
appendQuantity(display, unitCount, stock.getUnitName(), false);
return display.length() > 0 ? display.toString() : formatNumber(stock.getCount()) + stock.getUnitName();
}
private void appendQuantity(StringBuilder display, BigDecimal quantity, String unitName, boolean keepZero) {
if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0 || unitName == null) {
if (!keepZero) {
return;
}
if (display.length() > 0) {
display.append(",");
}
display.append("0").append(unitName);
return;
}
if (display.length() > 0) {
display.append(",");
}
display.append(formatNumber(quantity)).append(unitName);
}
private boolean isProductType(Integer categoryType) {
return Integer.valueOf(1).equals(categoryType);
}
private String formatNumber(BigDecimal value) {
return value == null ? "0" : value.stripTrailingZeros().toPlainString();
}
} }

@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutApproveRecord
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
import cn.iocoder.yudao.module.erp.enums.ErpStockOutStatusEnum; import cn.iocoder.yudao.module.erp.enums.ErpStockOutStatusEnum;
import cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum;
import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService; import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService;
import cn.iocoder.yudao.module.erp.service.mold.MoldService; import cn.iocoder.yudao.module.erp.service.mold.MoldService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
@ -216,6 +217,7 @@ public class ErpStockOutController {
List<ErpStockOutApproveRecordDO> approveRecords) { List<ErpStockOutApproveRecordDO> approveRecords) {
ErpStockOutRespVO stockOutVO = BeanUtils.toBean(stockOut, ErpStockOutRespVO.class); ErpStockOutRespVO stockOutVO = BeanUtils.toBean(stockOut, ErpStockOutRespVO.class);
stockOutVO.setStatusName(getStockOutStatusName(stockOut.getStatus())); stockOutVO.setStatusName(getStockOutStatusName(stockOut.getStatus()));
stockOutVO.setOutUsageTypeName(ErpStockOutUsageTypeEnum.getNameByType(stockOut.getOutUsageType()));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap( Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(
Collections.singletonList(stockOut), item -> Stream.of(NumberUtils.parseLong(item.getCreator()), Collections.singletonList(stockOut), item -> Stream.of(NumberUtils.parseLong(item.getCreator()),
item.getResponserId(), item.getAuditUserId()))); item.getResponserId(), item.getAuditUserId())));
@ -305,4 +307,4 @@ public class ErpStockOutController {
private String getStockOutStatusName(Integer status) { private String getStockOutStatusName(Integer status) {
return ErpStockOutStatusEnum.OUT_STOCK.getStatus().equals(status) ? "已出库" : "待出库"; return ErpStockOutStatusEnum.OUT_STOCK.getStatus().equals(status) ? "已出库" : "待出库";
} }
} }

@ -44,6 +44,30 @@ public class ErpStockOutRespVO {
@Schema(description = "出库类型", example = "其他出库") @Schema(description = "出库类型", example = "其他出库")
private String outType; private String outType;
@Schema(description = "出库用途", example = "1")
private Integer outUsageType;
@Schema(description = "出库用途名称", example = "维修领用")
private String outUsageTypeName;
@Schema(description = "维修单编号", example = "1001")
private Long repairId;
@Schema(description = "维修单名称快照", example = "设备维修单A")
private String repairName;
@Schema(description = "维修单设备编号", example = "2001")
private Long repairDeviceId;
@Schema(description = "维修单设备名称快照", example = "设备A")
private String repairDeviceName;
@Schema(description = "保养单编号", example = "3001")
private Long maintenanceId;
@Schema(description = "保养单名称快照", example = "设备保养单A")
private String maintenanceName;
@Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("出库时间") @ExcelProperty("出库时间")
private LocalDateTime outTime; private LocalDateTime outTime;

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out; package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import lombok.Data; import lombok.Data;
import javax.validation.Valid; import javax.validation.Valid;
@ -10,6 +11,8 @@ import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum;
@Schema(description = "管理后台 - ERP 其它出库单新增/修改 Request VO") @Schema(description = "管理后台 - ERP 其它出库单新增/修改 Request VO")
@Data @Data
public class ErpStockOutSaveReqVO { public class ErpStockOutSaveReqVO {
@ -26,6 +29,20 @@ public class ErpStockOutSaveReqVO {
@Schema(description = "出库类型", example = "其他出库") @Schema(description = "出库类型", example = "其他出库")
private String outType; private String outType;
@Schema(description = "出库用途", example = "1")
@InEnum(ErpStockOutUsageTypeEnum.class)
@NotNull(message = "出库用途不能为空")
private Integer outUsageType;
@Schema(description = "维修单编号", example = "1001")
private Long repairId;
@Schema(description = "维修单设备编号", example = "2001")
private Long repairDeviceId;
@Schema(description = "保养单编号", example = "3001")
private Long maintenanceId;
@Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "出库时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "出库时间不能为空") @NotNull(message = "出库时间不能为空")
private LocalDateTime outTime; private LocalDateTime outTime;

@ -75,6 +75,26 @@ public class ErpStockRespVO {
@Schema(description = "Default Packaging Scheme") @Schema(description = "Default Packaging Scheme")
private ProductPackagingSchemeRespVO defaultPackagingScheme; private ProductPackagingSchemeRespVO defaultPackagingScheme;
@Schema(description = "默认包装方案名称", example = "标准包装")
private String defaultPackagingSchemeName;
@Schema(description = "每包数量(库存单位)", example = "50")
private BigDecimal packageQuantity;
@Schema(description = "每托包数(包)", example = "20")
private BigDecimal palletPackageQuantity;
@Schema(description = "每托总数量(库存单位)", example = "1000")
private BigDecimal palletTotalQuantity;
@Schema(description = "包装/换算规则", example = "1托=20包 1包=50个")
@ExcelProperty("包装/换算规则")
private String packagingRule;
@Schema(description = "库存展示", example = "2托8包30个")
@ExcelProperty("库存展示")
private String stockDisplay;
// ========== 仓库信息 ========== // ========== 仓库信息 ==========
@Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")

@ -54,6 +54,46 @@ public class ErpStockDO extends BaseDO {
* *
*/ */
private BigDecimal count; private BigDecimal count;
/**
*
*/
private Long unitId;
/**
*
*/
private String unitName;
/**
*
*/
private Long purchaseUnitId;
/**
*
*/
private String purchaseUnitName;
/**
*
*/
private BigDecimal purchaseUnitConvertQuantity;
/**
*
*/
private Long defaultPackagingSchemeId;
/**
*
*/
private String defaultPackagingSchemeName;
/**
*
*/
private BigDecimal packageQuantity;
/**
*
*/
private BigDecimal palletPackageQuantity;
/**
*
*/
private BigDecimal palletTotalQuantity;
/** /**
* *
*/ */

@ -48,6 +48,36 @@ public class ErpStockOutDO extends BaseDO {
private Long responserId; private Long responserId;
//@Schema(description = "出库类型", example = "随便") //@Schema(description = "出库类型", example = "随便")
private String outType; private String outType;
/**
*
*
* {@link cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum}
*/
private Integer outUsageType;
/**
*
*/
private String repairName;
/**
*
*/
private Long repairId;
/**
*
*/
private Long repairDeviceId;
/**
*
*/
private String repairDeviceName;
/**
*
*/
private Long maintenanceId;
/**
*
*/
private String maintenanceName;
/** /**
* *
*/ */

@ -26,8 +26,13 @@ import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutMapper;
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
import cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum;
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockOutApproveActionEnum; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockOutApproveActionEnum;
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
import cn.iocoder.yudao.module.mes.api.dvrepair.DvRepairApi;
import cn.iocoder.yudao.module.mes.api.dvrepair.dto.DvRepairRespDTO;
import cn.iocoder.yudao.module.mes.api.ticketmanagement.TicketManagementApi;
import cn.iocoder.yudao.module.mes.api.ticketmanagement.dto.TicketManagementRespDTO;
import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService; import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService;
import cn.iocoder.yudao.module.erp.service.mold.MoldService; import cn.iocoder.yudao.module.erp.service.mold.MoldService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
@ -96,6 +101,10 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
private ConfigApi configApi; private ConfigApi configApi;
@Resource @Resource
private PermissionApi permissionApi; private PermissionApi permissionApi;
@Resource
private DvRepairApi dvRepairApi;
@Resource
private TicketManagementApi ticketManagementApi;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -123,6 +132,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
.setStatus(status) .setStatus(status)
.setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add)) .setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
.setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); .setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
fillUsageSnapshot(stockOut, createReqVO.getOutUsageType(), createReqVO.getRepairId(),
createReqVO.getRepairDeviceId(), createReqVO.getMaintenanceId());
stockOutMapper.insert(stockOut); stockOutMapper.insert(stockOut);
stockOutItems.forEach(item -> item.setOutId(stockOut.getId())); stockOutItems.forEach(item -> item.setOutId(stockOut.getId()));
stockOutItemMapper.insertBatch(stockOutItems); stockOutItemMapper.insertBatch(stockOutItems);
@ -165,6 +176,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
.setNeedAudit(needAudit) .setNeedAudit(needAudit)
.setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add)) .setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
.setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); .setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
fillUsageSnapshot(updateObj, updateReqVO.getOutUsageType(), updateReqVO.getRepairId(),
updateReqVO.getRepairDeviceId(), updateReqVO.getMaintenanceId());
stockOutMapper.updateById(updateObj); stockOutMapper.updateById(updateObj);
updateStockOutItemList(updateReqVO.getId(), stockOutItems); updateStockOutItemList(updateReqVO.getId(), stockOutItems);
} }
@ -394,6 +407,33 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
return !AUDIT_CONFIG_DISABLE_VALUE.equals(configApi.getConfigValueByCategoryAndKey(AUDIT_CONFIG_CATEGORY, AUDIT_CONFIG_KEY)); return !AUDIT_CONFIG_DISABLE_VALUE.equals(configApi.getConfigValueByCategoryAndKey(AUDIT_CONFIG_CATEGORY, AUDIT_CONFIG_KEY));
} }
private void fillUsageSnapshot(ErpStockOutDO stockOut, Integer outUsageType, Long repairId,
Long repairDeviceId, Long maintenanceId) {
stockOut.setOutUsageType(outUsageType);
stockOut.setRepairId(null);
stockOut.setRepairName(null);
stockOut.setRepairDeviceId(null);
stockOut.setRepairDeviceName(null);
stockOut.setMaintenanceId(null);
stockOut.setMaintenanceName(null);
if (ErpStockOutUsageTypeEnum.REPAIR_RECEIVE.getType().equals(outUsageType) && repairId != null) {
DvRepairRespDTO repair = dvRepairApi.getDvRepair(repairId);
if (repair != null) {
stockOut.setRepairId(repair.getId());
stockOut.setRepairName(repair.getRepairName());
stockOut.setRepairDeviceId(repairDeviceId != null ? repairDeviceId : repair.getMachineryId());
stockOut.setRepairDeviceName(repair.getMachineryName());
}
} else if (ErpStockOutUsageTypeEnum.MAINTENANCE_RECEIVE.getType().equals(outUsageType) && maintenanceId != null) {
TicketManagementRespDTO maintenance = ticketManagementApi.getTicketManagement(maintenanceId);
if (maintenance != null) {
stockOut.setMaintenanceId(maintenance.getId());
stockOut.setMaintenanceName(maintenance.getPlanNo());
}
}
}
private void createApproveRecord(Long stockOutId, ErpStockOutApproveActionEnum action, Integer fromStatus, private void createApproveRecord(Long stockOutId, ErpStockOutApproveActionEnum action, Integer fromStatus,
Integer toStatus, Long targetUserId, String remark) { Integer toStatus, Long targetUserId, String remark) {
stockOutApproveRecordMapper.insert(ErpStockOutApproveRecordDO.builder() stockOutApproveRecordMapper.insert(ErpStockOutApproveRecordDO.builder()

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.erp.service.stock;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
@ -90,12 +91,14 @@ public class ErpStockServiceImpl implements ErpStockService {
String areaName, BigDecimal count) { String areaName, BigDecimal count) {
ErpProductRespVO product = productService.getProduct(productId); ErpProductRespVO product = productService.getProduct(productId);
Integer categoryType = product != null ? product.getCategoryType() : null; Integer categoryType = product != null ? product.getCategoryType() : null;
ProductPackagingSchemeRespVO defaultPackagingScheme = product != null ? findDefaultPackagingScheme(product) : null;
// 1.1 查询当前库存 // 1.1 查询当前库存
ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseIdAndAreaId(productId, warehouseId, areaId); ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseIdAndAreaId(productId, warehouseId, areaId);
if (stock == null) { if (stock == null) {
stock = new ErpStockDO().setProductId(productId).setWarehouseId(warehouseId).setAreaId(areaId) stock = new ErpStockDO().setProductId(productId).setWarehouseId(warehouseId).setAreaId(areaId)
.setAreaName(areaName).setCount(BigDecimal.ZERO).setCategoryType(categoryType); .setAreaName(areaName).setCount(BigDecimal.ZERO).setCategoryType(categoryType);
stock.setCategoryId(categoryId); stock.setCategoryId(categoryId);
fillStockSnapshot(stock, product, defaultPackagingScheme);
stockMapper.insert(stock); stockMapper.insert(stock);
} else if (stock.getCategoryType() == null) { } else if (stock.getCategoryType() == null) {
stock.setCategoryType(categoryType); stock.setCategoryType(categoryType);
@ -105,6 +108,10 @@ public class ErpStockServiceImpl implements ErpStockService {
stock.setAreaName(areaName); stock.setAreaName(areaName);
stockMapper.updateById(new ErpStockDO().setId(stock.getId()).setAreaName(areaName)); stockMapper.updateById(new ErpStockDO().setId(stock.getId()).setAreaName(areaName));
} }
if (product != null && isStockSnapshotMissing(stock)) {
fillStockSnapshot(stock, product, defaultPackagingScheme);
stockMapper.updateById(buildStockSnapshotUpdate(stock));
}
// 1.2 校验库存是否充足 // 1.2 校验库存是否充足
if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) { if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) {
throw exception(STOCK_COUNT_NEGATIVE, productService.getProduct(productId).getName(), throw exception(STOCK_COUNT_NEGATIVE, productService.getProduct(productId).getName(),
@ -123,4 +130,60 @@ public class ErpStockServiceImpl implements ErpStockService {
return stock.getCount().add(count); return stock.getCount().add(count);
} }
private void fillStockSnapshot(ErpStockDO stock, ErpProductRespVO product,
ProductPackagingSchemeRespVO defaultPackagingScheme) {
if (product == null) {
return;
}
stock.setUnitId(product.getUnitId());
stock.setUnitName(product.getUnitName());
stock.setPurchaseUnitId(product.getPurchaseUnitId());
stock.setPurchaseUnitName(product.getPurchaseUnitName());
stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity());
if (defaultPackagingScheme != null) {
stock.setDefaultPackagingSchemeId(defaultPackagingScheme.getPackagingSchemeId());
stock.setDefaultPackagingSchemeName(defaultPackagingScheme.getPackagingSchemeName());
stock.setPackageQuantity(defaultPackagingScheme.getPackageQuantity());
stock.setPalletPackageQuantity(defaultPackagingScheme.getPalletPackageQuantity());
stock.setPalletTotalQuantity(defaultPackagingScheme.getPalletTotalQuantity());
}
}
private ProductPackagingSchemeRespVO findDefaultPackagingScheme(ErpProductRespVO product) {
if (product.getDefaultPackagingSchemeId() == null || product.getPackagingSchemes() == null) {
return null;
}
return product.getPackagingSchemes().stream()
.filter(item -> product.getDefaultPackagingSchemeId().equals(item.getPackagingSchemeId()))
.findFirst()
.orElse(null);
}
private boolean isStockSnapshotMissing(ErpStockDO stock) {
return stock.getUnitId() == null
|| stock.getUnitName() == null
|| stock.getPurchaseUnitId() == null
|| stock.getPurchaseUnitName() == null
|| stock.getPurchaseUnitConvertQuantity() == null
|| stock.getDefaultPackagingSchemeId() == null
|| stock.getDefaultPackagingSchemeName() == null
|| stock.getPackageQuantity() == null
|| stock.getPalletPackageQuantity() == null
|| stock.getPalletTotalQuantity() == null;
}
private ErpStockDO buildStockSnapshotUpdate(ErpStockDO stock) {
return new ErpStockDO().setId(stock.getId())
.setUnitId(stock.getUnitId())
.setUnitName(stock.getUnitName())
.setPurchaseUnitId(stock.getPurchaseUnitId())
.setPurchaseUnitName(stock.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(stock.getPurchaseUnitConvertQuantity())
.setDefaultPackagingSchemeId(stock.getDefaultPackagingSchemeId())
.setDefaultPackagingSchemeName(stock.getDefaultPackagingSchemeName())
.setPackageQuantity(stock.getPackageQuantity())
.setPalletPackageQuantity(stock.getPalletPackageQuantity())
.setPalletTotalQuantity(stock.getPalletTotalQuantity());
}
} }

@ -0,0 +1,11 @@
package cn.iocoder.yudao.module.mes.api.dvrepair;
import cn.iocoder.yudao.module.mes.api.dvrepair.dto.DvRepairRespDTO;
/**
* API
*/
public interface DvRepairApi {
DvRepairRespDTO getDvRepair(Long id);
}

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.mes.api.dvrepair.dto;
import lombok.Data;
/**
* DTO
*/
@Data
public class DvRepairRespDTO {
private Long id;
private String repairCode;
private String repairName;
private Long machineryId;
private String machineryCode;
private String machineryName;
}

@ -0,0 +1,11 @@
package cn.iocoder.yudao.module.mes.api.ticketmanagement;
import cn.iocoder.yudao.module.mes.api.ticketmanagement.dto.TicketManagementRespDTO;
/**
* API
*/
public interface TicketManagementApi {
TicketManagementRespDTO getTicketManagement(Long id);
}

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.mes.api.ticketmanagement.dto;
import lombok.Data;
/**
* DTO
*/
@Data
public class TicketManagementRespDTO {
private Long id;
private String planNo;
private String deviceName;
private String configName;
}

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.mes.api.dvrepair;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.api.dvrepair.dto.DvRepairRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvrepair.DvRepairDO;
import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class DvRepairApiImpl implements DvRepairApi {
@Resource
private DvRepairMapper dvRepairMapper;
@Override
public DvRepairRespDTO getDvRepair(Long id) {
DvRepairDO repair = dvRepairMapper.selectById(id);
return BeanUtils.toBean(repair, DvRepairRespDTO.class);
}
}

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.mes.api.ticketmanagement;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.api.ticketmanagement.dto.TicketManagementRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.ticketmanagement.TicketManagementDO;
import cn.iocoder.yudao.module.mes.dal.mysql.ticketmanagement.TicketManagementMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class TicketManagementApiImpl implements TicketManagementApi {
@Resource
private TicketManagementMapper ticketManagementMapper;
@Override
public TicketManagementRespDTO getTicketManagement(Long id) {
TicketManagementDO ticketManagement = ticketManagementMapper.selectById(id);
return BeanUtils.toBean(ticketManagement, TicketManagementRespDTO.class);
}
}

@ -105,8 +105,17 @@ public class UserController {
@GetMapping({"/list-all-simple", "/simple-list"}) @GetMapping({"/list-all-simple", "/simple-list"})
@Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项") @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项")
public CommonResult<List<UserSimpleRespVO>> getSimpleUserList() { public CommonResult<List<UserSimpleRespVO>> getSimpleUserList(@RequestParam(value = "username", required = false) String username,
@RequestParam(value = "nickname", required = false) String nickname) {
List<AdminUserDO> list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus()); List<AdminUserDO> list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus());
if (username != null && !username.isEmpty()) {
list = list.stream().filter(user -> user.getUsername() != null && user.getUsername().contains(username))
.collect(java.util.stream.Collectors.toList());
}
if (nickname != null && !nickname.isEmpty()) {
list = list.stream().filter(user -> user.getNickname() != null && user.getNickname().contains(nickname))
.collect(java.util.stream.Collectors.toList());
}
// 拼接数据 // 拼接数据
Map<Long, DeptDO> deptMap = deptService.getDeptMap( Map<Long, DeptDO> deptMap = deptService.getDeptMap(
convertList(list, AdminUserDO::getDeptId)); convertList(list, AdminUserDO::getDeptId));

Loading…
Cancel
Save