feat: add spare part management services
This commit is contained in:
parent
d042bf46c8
commit
799e358d0f
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.ether.pms.mdm.service;
|
||||||
|
|
||||||
|
import com.ether.pms.mdm.entity.SparePart;
|
||||||
|
import com.ether.pms.mdm.entity.SparePartCategory;
|
||||||
|
import com.ether.pms.mdm.entity.SparePartRecord;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface SparePartService {
|
||||||
|
// 分类管理
|
||||||
|
List<SparePartCategory> getCategories();
|
||||||
|
SparePartCategory createCategory(SparePartCategory category);
|
||||||
|
|
||||||
|
// 备件管理
|
||||||
|
SparePart createSparePart(SparePart sparePart);
|
||||||
|
SparePart updateSparePart(UUID id, SparePart sparePart);
|
||||||
|
void deleteSparePart(UUID id);
|
||||||
|
SparePart getSparePartById(UUID id);
|
||||||
|
List<SparePart> getSparePartsByProject(UUID projectId);
|
||||||
|
List<SparePart> getSparePartsByCategory(UUID categoryId);
|
||||||
|
List<SparePart> getLowStockParts(UUID projectId);
|
||||||
|
|
||||||
|
// 库存管理
|
||||||
|
SparePartRecord inStock(UUID sparePartId, Integer quantity, UUID recordedBy, String remarks);
|
||||||
|
SparePartRecord outStock(UUID sparePartId, Integer quantity, UUID relatedOrderId, UUID recordedBy, String remarks);
|
||||||
|
List<SparePartRecord> getSparePartRecords(UUID sparePartId);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,270 @@
|
||||||
|
package com.ether.pms.mdm.service.impl;
|
||||||
|
|
||||||
|
import com.ether.pms.common.BusinessException;
|
||||||
|
import com.ether.pms.mdm.entity.SparePart;
|
||||||
|
import com.ether.pms.mdm.entity.SparePartCategory;
|
||||||
|
import com.ether.pms.mdm.entity.SparePartRecord;
|
||||||
|
import com.ether.pms.mdm.repository.SparePartCategoryRepository;
|
||||||
|
import com.ether.pms.mdm.repository.SparePartRecordRepository;
|
||||||
|
import com.ether.pms.mdm.repository.SparePartRepository;
|
||||||
|
import com.ether.pms.mdm.service.SparePartService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SparePartServiceImpl implements SparePartService {
|
||||||
|
|
||||||
|
private final SparePartRepository sparePartRepository;
|
||||||
|
private final SparePartCategoryRepository sparePartCategoryRepository;
|
||||||
|
private final SparePartRecordRepository sparePartRecordRepository;
|
||||||
|
|
||||||
|
private static final DateTimeFormatter CODE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
||||||
|
|
||||||
|
// ==================== 分类管理 ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SparePartCategory> getCategories() {
|
||||||
|
return sparePartCategoryRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public SparePartCategory createCategory(SparePartCategory category) {
|
||||||
|
// 生成分类编码 CC + 时间戳
|
||||||
|
String categoryCode = generateCategoryCode();
|
||||||
|
category.setCategoryCode(categoryCode);
|
||||||
|
return sparePartCategoryRepository.save(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 备件管理 ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public SparePart createSparePart(SparePart sparePart) {
|
||||||
|
// 生成备件编码 SP + 时间戳
|
||||||
|
String sparePartCode = generateSparePartCode();
|
||||||
|
sparePart.setSparePartCode(sparePartCode);
|
||||||
|
|
||||||
|
// 设置默认状态为ACTIVE
|
||||||
|
if (sparePart.getStatus() == null) {
|
||||||
|
sparePart.setStatus(SparePart.Status.ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化库存为0
|
||||||
|
if (sparePart.getCurrentStock() == null) {
|
||||||
|
sparePart.setCurrentStock(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sparePartRepository.save(sparePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public SparePart updateSparePart(UUID id, SparePart sparePart) {
|
||||||
|
SparePart existing = getSparePartById(id);
|
||||||
|
|
||||||
|
if (sparePart.getSparePartName() != null) {
|
||||||
|
existing.setSparePartName(sparePart.getSparePartName());
|
||||||
|
}
|
||||||
|
if (sparePart.getCategoryId() != null) {
|
||||||
|
existing.setCategoryId(sparePart.getCategoryId());
|
||||||
|
}
|
||||||
|
if (sparePart.getSpecification() != null) {
|
||||||
|
existing.setSpecification(sparePart.getSpecification());
|
||||||
|
}
|
||||||
|
if (sparePart.getUnit() != null) {
|
||||||
|
existing.setUnit(sparePart.getUnit());
|
||||||
|
}
|
||||||
|
if (sparePart.getSafeStock() != null) {
|
||||||
|
existing.setSafeStock(sparePart.getSafeStock());
|
||||||
|
}
|
||||||
|
if (sparePart.getUnitPrice() != null) {
|
||||||
|
existing.setUnitPrice(sparePart.getUnitPrice());
|
||||||
|
}
|
||||||
|
if (sparePart.getSupplier() != null) {
|
||||||
|
existing.setSupplier(sparePart.getSupplier());
|
||||||
|
}
|
||||||
|
if (sparePart.getSupplierContact() != null) {
|
||||||
|
existing.setSupplierContact(sparePart.getSupplierContact());
|
||||||
|
}
|
||||||
|
if (sparePart.getLocation() != null) {
|
||||||
|
existing.setLocation(sparePart.getLocation());
|
||||||
|
}
|
||||||
|
if (sparePart.getRemarks() != null) {
|
||||||
|
existing.setRemarks(sparePart.getRemarks());
|
||||||
|
}
|
||||||
|
if (sparePart.getStatus() != null) {
|
||||||
|
existing.setStatus(sparePart.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
return sparePartRepository.save(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void deleteSparePart(UUID id) {
|
||||||
|
SparePart sparePart = getSparePartById(id);
|
||||||
|
sparePart.setStatus(SparePart.Status.INACTIVE);
|
||||||
|
sparePartRepository.save(sparePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SparePart getSparePartById(UUID id) {
|
||||||
|
return sparePartRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new BusinessException(6101, "备件不存在"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SparePart> getSparePartsByProject(UUID projectId) {
|
||||||
|
return sparePartRepository.findByProjectIdAndStatus(projectId, SparePart.Status.ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SparePart> getSparePartsByCategory(UUID categoryId) {
|
||||||
|
return sparePartRepository.findByCategoryId(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SparePart> getLowStockParts(UUID projectId) {
|
||||||
|
return sparePartRepository.findLowStockParts(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 库存管理 ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public SparePartRecord inStock(UUID sparePartId, Integer quantity, UUID recordedBy, String remarks) {
|
||||||
|
if (quantity == null || quantity <= 0) {
|
||||||
|
throw new BusinessException(6102, "入库数量必须大于0");
|
||||||
|
}
|
||||||
|
|
||||||
|
SparePart sparePart = getSparePartById(sparePartId);
|
||||||
|
|
||||||
|
// 更新库存
|
||||||
|
sparePart.setCurrentStock(sparePart.getCurrentStock() + quantity);
|
||||||
|
sparePartRepository.save(sparePart);
|
||||||
|
|
||||||
|
// 创建入库记录
|
||||||
|
return createSparePartRecord(sparePartId, SparePartRecord.RecordType.IN, quantity, recordedBy, remarks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public SparePartRecord outStock(UUID sparePartId, Integer quantity, UUID relatedOrderId, UUID recordedBy, String remarks) {
|
||||||
|
if (quantity == null || quantity <= 0) {
|
||||||
|
throw new BusinessException(6103, "出库数量必须大于0");
|
||||||
|
}
|
||||||
|
|
||||||
|
SparePart sparePart = getSparePartById(sparePartId);
|
||||||
|
|
||||||
|
// 校验库存是否充足
|
||||||
|
if (sparePart.getCurrentStock() < quantity) {
|
||||||
|
throw new BusinessException(6104, "库存不足,当前库存:" + sparePart.getCurrentStock() + ",需要出库:" + quantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存
|
||||||
|
sparePart.setCurrentStock(sparePart.getCurrentStock() - quantity);
|
||||||
|
sparePartRepository.save(sparePart);
|
||||||
|
|
||||||
|
// 创建出库记录
|
||||||
|
return createSparePartRecordWithOrder(sparePartId, SparePartRecord.RecordType.OUT, quantity, relatedOrderId, recordedBy, remarks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SparePartRecord> getSparePartRecords(UUID sparePartId) {
|
||||||
|
return sparePartRecordRepository.findBySparePartIdOrderByRecordDateDesc(sparePartId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 私有方法 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成备件编码:SP + yyyyMMddHHmmss
|
||||||
|
*/
|
||||||
|
private String generateSparePartCode() {
|
||||||
|
String timestamp = LocalDateTime.now().format(CODE_FORMATTER);
|
||||||
|
String sparePartCode = "SP" + timestamp;
|
||||||
|
|
||||||
|
// 确保编码唯一
|
||||||
|
int suffix = 1;
|
||||||
|
while (sparePartRepository.existsBySparePartCode(sparePartCode)) {
|
||||||
|
sparePartCode = "SP" + timestamp + "_" + suffix;
|
||||||
|
suffix++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sparePartCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成分类编码:CC + yyyyMMddHHmmss
|
||||||
|
*/
|
||||||
|
private String generateCategoryCode() {
|
||||||
|
String timestamp = LocalDateTime.now().format(CODE_FORMATTER);
|
||||||
|
String categoryCode = "CC" + timestamp;
|
||||||
|
|
||||||
|
// 检查编码是否存在
|
||||||
|
int suffix = 1;
|
||||||
|
while (sparePartCategoryRepository.findByCategoryCode(categoryCode).isPresent()) {
|
||||||
|
categoryCode = "CC" + timestamp + "_" + suffix;
|
||||||
|
suffix++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return categoryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建库存记录
|
||||||
|
*/
|
||||||
|
private SparePartRecord createSparePartRecord(UUID sparePartId, SparePartRecord.RecordType recordType,
|
||||||
|
Integer quantity, UUID recordedBy, String remarks) {
|
||||||
|
SparePart sparePart = getSparePartById(sparePartId);
|
||||||
|
|
||||||
|
SparePartRecord record = new SparePartRecord();
|
||||||
|
record.setRecordCode(generateRecordCode(recordType));
|
||||||
|
record.setRecordType(recordType);
|
||||||
|
record.setSparePartId(sparePartId);
|
||||||
|
record.setQuantity(quantity);
|
||||||
|
record.setBalance(sparePart.getCurrentStock());
|
||||||
|
record.setRecordedBy(recordedBy);
|
||||||
|
record.setRemarks(remarks);
|
||||||
|
record.setRecordDate(LocalDateTime.now());
|
||||||
|
|
||||||
|
return sparePartRecordRepository.save(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建带订单信息的库存记录
|
||||||
|
*/
|
||||||
|
private SparePartRecord createSparePartRecordWithOrder(UUID sparePartId, SparePartRecord.RecordType recordType,
|
||||||
|
Integer quantity, UUID relatedOrderId, UUID recordedBy, String remarks) {
|
||||||
|
SparePart sparePart = getSparePartById(sparePartId);
|
||||||
|
|
||||||
|
SparePartRecord record = new SparePartRecord();
|
||||||
|
record.setRecordCode(generateRecordCode(recordType));
|
||||||
|
record.setRecordType(recordType);
|
||||||
|
record.setSparePartId(sparePartId);
|
||||||
|
record.setQuantity(quantity);
|
||||||
|
record.setBalance(sparePart.getCurrentStock());
|
||||||
|
record.setRelatedOrderId(relatedOrderId);
|
||||||
|
record.setRecordedBy(recordedBy);
|
||||||
|
record.setRemarks(remarks);
|
||||||
|
record.setRecordDate(LocalDateTime.now());
|
||||||
|
|
||||||
|
return sparePartRecordRepository.save(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成记录编码:REC + 类型 + 时间戳
|
||||||
|
*/
|
||||||
|
private String generateRecordCode(SparePartRecord.RecordType recordType) {
|
||||||
|
String typeCode = recordType.name();
|
||||||
|
String timestamp = LocalDateTime.now().format(CODE_FORMATTER);
|
||||||
|
return "REC" + typeCode + timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue