From 10b88a7ff17caf92f3d4e8a550c1085a70c2517a Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 28 五月 2026 17:43:26 +0800
Subject: [PATCH] Merge dev_New_pro into dev_山西_晋和园_pro
---
src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 254 insertions(+), 0 deletions(-)
diff --git a/src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java b/src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java
new file mode 100644
index 0000000..352818d
--- /dev/null
+++ b/src/test/java/com/ruoyi/stock/service/impl/StockOutRecordBatchUpdateTest.java
@@ -0,0 +1,254 @@
+package com.ruoyi.stock.service.impl;
+
+import com.ruoyi.production.mapper.ProductionOrderMapper;
+import com.ruoyi.production.mapper.ProductionOrderPickMapper;
+import com.ruoyi.production.pojo.ProductionOrder;
+import com.ruoyi.production.pojo.ProductionOrderPick;
+import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper;
+import com.ruoyi.purchase.pojo.PurchaseReturnOrders;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.mapper.ShippingInfoMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
+import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
+import com.ruoyi.stock.pojo.StockOutRecord;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@SpringBootTest
+public class StockOutRecordBatchUpdateTest {
+
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ @Autowired
+ private StockOutRecordMapper stockOutRecordMapper;
+
+ @Autowired
+ private PurchaseReturnOrdersMapper purchaseReturnOrdersMapper;
+
+ @Autowired
+ private ShippingInfoMapper shippingInfoMapper;
+
+ @Autowired
+ private SalesLedgerMapper salesLedgerMapper;
+
+ @Autowired
+ private ProductionOrderPickMapper productionOrderPickMapper;
+
+ @Autowired
+ private ProductionOrderMapper productionOrderMapper;
+
+ /**
+ * 鏇存柊鍑哄簱鍗曟椂闂�
+ */
+ @Test
+ void testUpdateStockOutRecords() {
+ List<StockOutRecord> allRecords = stockOutRecordMapper.selectList(null);
+ System.out.println("鎬昏褰曟暟: " + allRecords.size());
+
+ List<RecordWithDate> recordWithDates = new ArrayList<>();
+
+ for (StockOutRecord record : allRecords) {
+ String type = record.getRecordType();
+ if (type == null) continue;
+
+ switch (type) {
+ case "1":
+ case "10":
+ recordWithDates.add(resolveType1or10(record, type));
+ break;
+ case "3":
+ System.out.println("绫诲瀷3锛堢敓浜ф姤宸�-鍑哄簱锛夐鐣欏垎鏀紝褰撳墠鏃犳暟鎹紝璺宠繃");
+ break;
+ case "8":
+ System.out.println("绫诲瀷8锛堥攢鍞�-鍑哄簱锛夐鐣欏垎鏀紝褰撳墠鏃犳暟鎹紝璺宠繃");
+ break;
+ case "9":
+ recordWithDates.add(resolveType9(record));
+ break;
+ case "13":
+ recordWithDates.add(resolveType13(record));
+ break;
+ case "14":
+ recordWithDates.add(resolveType14or15(record));
+ break;
+ case "15":
+ recordWithDates.add(resolveType14or15(record));
+ break;
+ default:
+ System.out.println("鏈煡绫诲瀷 " + type + "锛岃烦杩� ID=" + record.getId());
+ }
+ }
+
+ Map<LocalDate, List<RecordWithDate>> byDate = recordWithDates.stream()
+ .collect(Collectors.groupingBy(
+ rwd -> rwd.dateTime.toLocalDate(),
+ LinkedHashMap::new,
+ Collectors.toList()
+ ));
+
+ int totalUpdated = 0;
+ for (Map.Entry<LocalDate, List<RecordWithDate>> dateEntry : byDate.entrySet()) {
+ LocalDate date = dateEntry.getKey();
+ List<RecordWithDate> records = dateEntry.getValue();
+ records.sort(Comparator.comparing(rwd -> rwd.dateTime));
+
+ assignRandomTimes(records, date);
+
+ records.sort(Comparator.comparing(rwd -> rwd.dateTime));
+
+ int seq = 1;
+ for (RecordWithDate rwd : records) {
+ StockOutRecord record = rwd.record;
+ String type = record.getRecordType();
+ String batchNo = "CK" + date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + String.format("%03d", seq++);
+ LocalDateTime createTime = rwd.dateTime;
+
+ jdbcTemplate.update(
+ "UPDATE stock_out_record SET outbound_batches = ?, create_time = ?, update_time = ? WHERE id = ?",
+ batchNo, createTime, createTime, record.getId());
+
+ System.out.println("ID=" + record.getId()
+ + " type=" + type
+ + " batch=" + batchNo
+ + " time=" + createTime);
+ totalUpdated++;
+ }
+ }
+
+ System.out.println("鍏ㄩ儴瀹屾垚锛佸叡鏇存柊 " + totalUpdated + " 鏉¤褰�");
+ }
+
+ private void assignRandomTimes(List<RecordWithDate> records, LocalDate date) {
+ List<RecordWithDate> individual = new ArrayList<>();
+ Map<Long, List<RecordWithDate>> grouped = new LinkedHashMap<>();
+
+ for (RecordWithDate rwd : records) {
+ String type = rwd.record.getRecordType();
+ if (!"1".equals(type) && !"9".equals(type) && !"10".equals(type)
+ && !"13".equals(type) && !"14".equals(type) && !"15".equals(type)) {
+ continue;
+ }
+ if (("14".equals(type) || "15".equals(type)) && rwd.record.getRecordId() != null) {
+ grouped.computeIfAbsent(rwd.record.getRecordId(), k -> new ArrayList<>()).add(rwd);
+ } else {
+ individual.add(rwd);
+ }
+ }
+
+ List<TimeSlot> slots = new ArrayList<>();
+ for (RecordWithDate rwd : individual) {
+ slots.add(new TimeSlot(rwd.record.getId(), List.of(rwd)));
+ }
+ for (Map.Entry<Long, List<RecordWithDate>> entry : grouped.entrySet()) {
+ long minId = entry.getValue().stream()
+ .mapToLong(rwd -> rwd.record.getId())
+ .min().orElse(0);
+ slots.add(new TimeSlot(minId, entry.getValue()));
+ }
+
+ if (slots.isEmpty()) return;
+
+ slots.sort(Comparator.comparingLong(s -> s.sortKey));
+
+ int totalMinutes = 480;
+ for (int i = 0; i < slots.size(); i++) {
+ int offsetMinutes = (int) ((long) i * totalMinutes / slots.size());
+ int jitter = (int) (Math.random() * 6 - 3);
+ offsetMinutes = Math.max(0, Math.min(479, offsetMinutes + jitter));
+
+ LocalTime time;
+ if (offsetMinutes < 240) {
+ time = LocalTime.of(8, 0).plusMinutes(offsetMinutes);
+ } else {
+ time = LocalTime.of(14, 0).plusMinutes(offsetMinutes - 240);
+ }
+ LocalDateTime dt = LocalDateTime.of(date, time);
+ for (RecordWithDate rwd : slots.get(i).members) {
+ rwd.dateTime = dt;
+ }
+ }
+ }
+
+ private static class TimeSlot {
+ final long sortKey;
+ final List<RecordWithDate> members;
+
+ TimeSlot(long sortKey, List<RecordWithDate> members) {
+ this.sortKey = sortKey;
+ this.members = members;
+ }
+ }
+
+ private RecordWithDate resolveType1or10(StockOutRecord record, String type) {
+ LocalDate date = record.getCreateTime() != null
+ ? record.getCreateTime().toLocalDate()
+ : LocalDate.now();
+ return new RecordWithDate(record, LocalDateTime.of(date, LocalTime.of(8, 0)));
+ }
+
+ private RecordWithDate resolveType9(StockOutRecord record) {
+ Long recordId = record.getRecordId();
+ if (recordId != null) {
+ PurchaseReturnOrders pro = purchaseReturnOrdersMapper.selectById(recordId);
+ if (pro != null && pro.getPreparedAt() != null) {
+ return new RecordWithDate(record, LocalDateTime.of(pro.getPreparedAt(), LocalTime.of(8, 0)));
+ }
+ }
+ return fallbackDateTime(record);
+ }
+
+ private RecordWithDate resolveType13(StockOutRecord record) {
+ Long recordId = record.getRecordId();
+ if (recordId != null) {
+ ShippingInfo shippingInfo = shippingInfoMapper.selectById(recordId);
+ if (shippingInfo != null && shippingInfo.getSalesLedgerId() != null) {
+ SalesLedger salesLedger = salesLedgerMapper.selectById(shippingInfo.getSalesLedgerId());
+ if (salesLedger != null && salesLedger.getDeliveryDate() != null) {
+ return new RecordWithDate(record, LocalDateTime.of(salesLedger.getDeliveryDate(), LocalTime.of(8, 0)));
+ }
+ }
+ }
+ return fallbackDateTime(record);
+ }
+
+ private RecordWithDate resolveType14or15(StockOutRecord record) {
+ Long recordId = record.getRecordId();
+ if (recordId != null) {
+ ProductionOrderPick pick = productionOrderPickMapper.selectById(recordId);
+ if (pick != null && pick.getProductionOrderId() != null) {
+ ProductionOrder order = productionOrderMapper.selectById(pick.getProductionOrderId());
+ if (order != null && order.getStartTime() != null) {
+ return new RecordWithDate(record, LocalDateTime.of(order.getStartTime().toLocalDate(), LocalTime.of(8, 0)));
+ }
+ }
+ }
+ return fallbackDateTime(record);
+ }
+
+ private RecordWithDate fallbackDateTime(StockOutRecord record) {
+ return record.getCreateTime() != null
+ ? new RecordWithDate(record, record.getCreateTime())
+ : new RecordWithDate(record, LocalDateTime.now());
+ }
+
+ private static class RecordWithDate {
+ final StockOutRecord record;
+ LocalDateTime dateTime;
+
+ RecordWithDate(StockOutRecord record, LocalDateTime dateTime) {
+ this.record = record;
+ this.dateTime = dateTime;
+ }
+ }
+}
--
Gitblit v1.9.3