feat(InventoryCheck): add detailed statistics fields and methods for inventory check calculations

This commit is contained in:
2025-09-14 13:26:48 +08:00
parent bb8ef42582
commit 7bd76bcf54
3 changed files with 290 additions and 50 deletions

View File

@@ -5,13 +5,14 @@ import cn.lihongjie.coal.base.entity.OrgCommonEntity;
import jakarta.persistence.Entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.Formula;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@jakarta.persistence.Table(indexes = @jakarta.persistence.Index(name ="idx_inventory_check_org_id", columnList = "organization_id"))
@@ -31,68 +32,146 @@ public class InventoryCheckEntity extends OrgCommonEntity {
/** 精煤 合计 */
@Formula(
"""
(
select sum(d.amount) from t_inventory_check_detail d
left join t_coal_info c on d.coal_info_id = c.id
left join t_product p on d.product_id = p.id
where (c.coal_type = '0' or p.coal_type = '0') and d.inventory_check_id = id
)""")
@Comment("精煤合计")
private Double sum0;
/** 中煤 合计 */
@Formula(
"""
(
select sum(d.amount) from t_inventory_check_detail d
left join t_coal_info c on d.coal_info_id = c.id
left join t_product p on d.product_id = p.id
where (c.coal_type = '1' or p.coal_type = '1') and d.inventory_check_id = id
)""")
@Comment("中煤合计")
private Double sum1;
/** 原煤 合计 */
@Formula(
"""
(
select sum(d.amount) from t_inventory_check_detail d
left join t_coal_info c on d.coal_info_id = c.id
left join t_product p on d.product_id = p.id
where (c.coal_type = '2' or p.coal_type = '2') and d.inventory_check_id = id
)""")
@Comment("原煤合计")
private Double sum2;
/** 煤泥 合计 */
@Formula(
"""
(
select sum(d.amount) from t_inventory_check_detail d
left join t_coal_info c on d.coal_info_id = c.id
left join t_product p on d.product_id = p.id
where (c.coal_type = '3' or p.coal_type = '3') and d.inventory_check_id = id
)""")
@Comment("煤泥合计")
private Double sum3;
/** 矸石 合计 */
@Formula(
"""
(
select sum(d.amount) from t_inventory_check_detail d
left join t_coal_info c on d.coal_info_id = c.id
left join t_product p on d.product_id = p.id
where (c.coal_type = '4' or p.coal_type = '4') and d.inventory_check_id = id
)""")
@Comment("矸石合计")
private Double sum4;
/** 其他 合计 */
@Formula(
"""
(
select sum(d.amount) from t_inventory_check_detail d
left join t_coal_info c on d.coal_info_id = c.id
left join t_product p on d.product_id = p.id
where (c.coal_type = '5' or p.coal_type = '5') and d.inventory_check_id = id
)""")
@Comment("其他合计")
private Double sum5;
/** 精煤 上期结余 */
@Comment("精煤上期结余")
private Double sqjy0;
/** 中煤 上期结余 */
@Comment("中煤上期结余")
private Double sqjy1;
/** 原煤 上期结余 */
@Comment("原煤上期结余")
private Double sqjy2;
/** 煤泥 上期结余 */
@Comment("煤泥上期结余")
private Double sqjy3;
/** 矸石 上期结余 */
@Comment("矸石上期结余")
private Double sqjy4;
/** 其他 上期结余 */
@Comment("其他上期结余")
private Double sqjy5;
/** 精煤 本期调入 */
@Comment("精煤本期调入")
private Double bqdy0;
/** 中煤 本期调入 */
@Comment("中煤本期调入")
private Double bqdy1;
/** 原煤 本期调入 */
@Comment("原煤本期调入")
private Double bqdy2;
/** 煤泥 本期调入 */
@Comment("煤泥本期调入")
private Double bqdy3;
/** 矸石 本期调入 */
@Comment("矸石本期调入")
private Double bqdy4;
/** 其他 本期调入 */
@Comment("其他本期调入")
private Double bqdy5;
/** 精煤 本期调出 */
@Comment("精煤本期调出")
private Double bqdc0;
/** 中煤 本期调出 */
@Comment("中煤本期调出")
private Double bqdc1;
/** 原煤 本期调出 */
@Comment("原煤本期调出")
private Double bqdc2;
/** 煤泥 本期调出 */
@Comment("煤泥本期调出")
private Double bqdc3;
/** 矸石 本期调出 */
@Comment("矸石本期调出")
private Double bqdc4;
/** 其他 本期调出 */
@Comment("其他本期调出")
private Double bqdc5;
/** 精煤 理论库存 */
@Comment("精煤理论库存")
private Double llkc0;
/** 中煤 理论库存 */
@Comment("中煤理论库存")
private Double llkc1;
/** 原煤 理论库存 */
@Comment("原煤理论库存")
private Double llkc2;
/** 煤泥 理论库存 */
@Comment("煤泥理论库存")
private Double llkc3;
/** 矸石 理论库存 */
@Comment("矸石理论库存")
private Double llkc4;
/** 其他 理论库存 */
@Comment("其他理论库存")
private Double llkc5;
/** 精煤 偏差 */
@Comment("精煤偏差")
private Double pc0;
/** 中煤 偏差 */
@Comment("中煤偏差")
private Double pc1;
/** 原煤 偏差 */
@Comment("原煤偏差")
private Double pc2;
/** 煤泥 偏差 */
@Comment("煤泥偏差")
private Double pc3;
/** 矸石 偏差 */
@Comment("矸石偏差")
private Double pc4;
/** 其他 偏差 */
@Comment("其他偏差")
private Double pc5;
}

View File

@@ -82,6 +82,130 @@ public class InventoryCheckService
});
inventoryCheckDetailRepository.saveAll(list);
// 计算并更新统计信息
calculateAndUpdateStatistics(entity);
}
private void calculateAndUpdateStatistics(InventoryCheckEntity entity) {
// 获取所有明细
List<InventoryCheckDetailEntity> details =
inventoryCheckDetailRepository.findAll(
(Specification<InventoryCheckDetailEntity>)
(root, query, criteriaBuilder) ->
criteriaBuilder.equal(
root.get("inventoryCheck").get("id"), entity.getId()));
// 初始化统计数据
Double[] sum = new Double[6]; // amount合计
Double[] sqjy = new Double[6]; // 上期结余
Double[] bqdy = new Double[6]; // 本期调入
Double[] bqdc = new Double[6]; // 本期调出
Double[] llkc = new Double[6]; // 理论库存
Double[] pc = new Double[6]; // 偏差
for (int i = 0; i < 6; i++) {
sum[i] = 0.0;
sqjy[i] = 0.0;
bqdy[i] = 0.0;
bqdc[i] = 0.0;
llkc[i] = 0.0;
pc[i] = 0.0;
}
// 遍历明细计算统计
for (InventoryCheckDetailEntity detail : details) {
String coalType = getCoalType(detail);
if (coalType != null) {
try {
int typeIndex = Integer.parseInt(coalType);
if (typeIndex >= 0 && typeIndex <= 5) {
sum[typeIndex] += safeDouble(detail.getAmount());
sqjy[typeIndex] += safeDouble(detail.getSqjy());
bqdy[typeIndex] += safeDouble(detail.getBqdy());
bqdc[typeIndex] += safeDouble(detail.getBqdc());
llkc[typeIndex] += safeDouble(detail.getLlkc());
pc[typeIndex] += safeDouble(detail.getPc());
}
} catch (NumberFormatException e) {
log.warn("Invalid coal type: " + coalType, e);
}
}
}
// 更新实体的统计字段
entity.setSum0(sum[0]);
entity.setSum1(sum[1]);
entity.setSum2(sum[2]);
entity.setSum3(sum[3]);
entity.setSum4(sum[4]);
entity.setSum5(sum[5]);
entity.setSqjy0(sqjy[0]);
entity.setSqjy1(sqjy[1]);
entity.setSqjy2(sqjy[2]);
entity.setSqjy3(sqjy[3]);
entity.setSqjy4(sqjy[4]);
entity.setSqjy5(sqjy[5]);
entity.setBqdy0(bqdy[0]);
entity.setBqdy1(bqdy[1]);
entity.setBqdy2(bqdy[2]);
entity.setBqdy3(bqdy[3]);
entity.setBqdy4(bqdy[4]);
entity.setBqdy5(bqdy[5]);
entity.setBqdc0(bqdc[0]);
entity.setBqdc1(bqdc[1]);
entity.setBqdc2(bqdc[2]);
entity.setBqdc3(bqdc[3]);
entity.setBqdc4(bqdc[4]);
entity.setBqdc5(bqdc[5]);
entity.setLlkc0(llkc[0]);
entity.setLlkc1(llkc[1]);
entity.setLlkc2(llkc[2]);
entity.setLlkc3(llkc[3]);
entity.setLlkc4(llkc[4]);
entity.setLlkc5(llkc[5]);
entity.setPc0(pc[0]);
entity.setPc1(pc[1]);
entity.setPc2(pc[2]);
entity.setPc3(pc[3]);
entity.setPc4(pc[4]);
entity.setPc5(pc[5]);
// 保存更新后的实体
repository.save(entity);
}
/**
* 获取明细的煤源类型
*/
private String getCoalType(InventoryCheckDetailEntity detail) {
if (detail.getCoalInfo() != null && detail.getCoalInfo().getCoalType() != null) {
return detail.getCoalInfo().getCoalType();
}
if (detail.getProduct() != null && detail.getProduct().getCoalType() != null) {
return detail.getProduct().getCoalType();
}
return null;
}
/**
* 安全获取Double值避免null
*/
private Double safeDouble(Double value) {
return value != null ? value : 0.0;
}
/**
* 外部调用接口:重新计算指定盘点单的统计信息
*/
public void recalculateStatistics(String inventoryCheckId) {
InventoryCheckEntity entity = repository.get(inventoryCheckId);
calculateAndUpdateStatistics(entity);
}
public cn.lihongjie.coal.inventoryCheck.dto.InventoryCheckDetailDto update(UpdateInventoryCheckDto request) {

View File

@@ -16,6 +16,7 @@ import jakarta.persistence.PersistenceContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@@ -36,11 +37,16 @@ public class InventoryCheckDetailService
@Autowired private ConversionService conversionService;
@Autowired private ApplicationContext applicationContext;
public InventoryCheckDetailDto create(CreateInventoryCheckDetailDto request) {
InventoryCheckDetailEntity entity = mapper.toEntity(request);
this.repository.save(entity);
// 如果有关联的盘点单,重新计算统计信息
triggerStatisticsRecalculation(entity);
return getById(entity.getId());
}
@@ -50,11 +56,42 @@ public class InventoryCheckDetailService
this.repository.save(entity);
// 如果有关联的盘点单,重新计算统计信息
triggerStatisticsRecalculation(entity);
return getById(entity.getId());
}
public void delete(IdRequest request) {
// 获取被删除的明细实体,用于重新计算统计
List<InventoryCheckDetailEntity> entitiesToDelete = repository.findAllById(request.getIds());
this.repository.deleteAllById(request.getIds());
// 对每个被删除的明细所属的盘点单重新计算统计
entitiesToDelete.stream()
.map(entity -> entity.getInventoryCheck())
.filter(inventoryCheck -> inventoryCheck != null)
.map(inventoryCheck -> inventoryCheck.getId())
.distinct()
.forEach(this::triggerStatisticsRecalculationById);
}
private void triggerStatisticsRecalculation(InventoryCheckDetailEntity entity) {
if (entity.getInventoryCheck() != null) {
triggerStatisticsRecalculationById(entity.getInventoryCheck().getId());
}
}
private void triggerStatisticsRecalculationById(String inventoryCheckId) {
// 使用Spring的ApplicationContext来获取InventoryCheckService避免循环依赖
try {
cn.lihongjie.coal.inventoryCheck.service.InventoryCheckService inventoryCheckService =
applicationContext.getBean(cn.lihongjie.coal.inventoryCheck.service.InventoryCheckService.class);
inventoryCheckService.recalculateStatistics(inventoryCheckId);
} catch (Exception e) {
log.warn("Failed to recalculate statistics for inventory check: " + inventoryCheckId, e);
}
}
public InventoryCheckDetailDto getById(String id) {