Báo cáo chuyển đổi warehouse-service

Kho · warehouse/import-excel-save-data · api

POST/api/client/page/warehouse/import-excel/save-data

Vòng
3 (nội dung luồng từ vòng 2)
Cổng G1–G6
PENDING_SONAR
Bước
sonar-check
Nhánh đích
feat/thongpd/warehouse-create

Phân tích luồng sau chuyển — warehouse/import-excel-save-data — vòng 2

F-01 Lưu import — cập nhật (type=2)

  • Điểm vào: cũ easyposbackend1:src/main/java/vn/softdreams/easypos/web/rest/WarehouseResource.java:117-121 → mới WarehouseController.java:155-182
  • Quy tắc: R-01, R-02, R-03, R-04, R-05, R-08, R-09, R-10

Đối chiếu từng bước

# Luồng cũ Luồng mới Kết luận
1 Không validate — WarehouseResource.java:118-119 Không validate, map dòng sang command — WarehouseController.java:158-167 KHỚP; phần tử null → KHÁC (F-logic-2)
2 data.isEmpty() → FAIL — BaseWarehouseServiceImpl.java:1101-1103 rows == null || isEmpty → empty — WarehouseImportService.java:74-76; FAIL — WarehouseController.java:172-177 KHÁC có chủ đích (D-02, D-12)
3 Không kiểm công ty (LF-20) requireCompanyOfCurrentUser — WarehouseImportService.java:77 KHÁC có chủ đích (D-01)
4 Gom SKU, map dòng sau thắng — …:1106-1111 WarehouseImportService.java:96-101 KHỚP
5 findBySkuIn(listSku, comId) findAllBySkuIn → native SKU in :skus and com_id = :comId KHỚP
6 copyProperties(mapData.get(sku), …); null → IllegalArgumentException null → SystemException(EXCEPTION_ERROR) KHÁC có chủ đích (D-02, D-08)
7 Chép mọi field kể cả comId dòng, status=getStatus(), không đổi normalizedName Warehouse.applyImport, comId = request KHỚP; comId KHÁC có chủ đích (D-03)
8 Dirty-check → @PreUpdate làm sạch + audit so businessValues thô → cleanText + audit KHỚP
9 saveAll (merge entity managed, không SQL) — …:1135 WarehouseRepository.saveAll: một findAllById (trả instance managed), so comId, mapper.apply — WarehouseRelationalRepository.java:174-199 KHỚP về dữ liệu ghi; thêm 1 SELECT (thay N SELECT vòng 1) — F-logic-1 ĐÃ HẾT
10 200 SUCCESS, data = entity, count ok(toResponses, WAREHOUSE_IMPORT_SUCCESS) + count KHÁC có chủ đích (D-02)
11 Interceptor gói (LF-21) không có KHÁC có chủ đích (D-11)

Transaction, khoá, idempotency, tenant

  • Transaction: cũ cấp class (LF-33) → mới @Transactional trên saveImportData, qua proxy; SystemException rollback toàn bộ.
  • Khoá: không ở cả hai (KHỚP R-09). Không event; gửi lại cùng request thì chép đè lại (audit chỉ đổi khi dirty).
  • comId: truy vấn lọc com_id đã kiểm; comId ghi vào kho lấy từ dòng do controller gán (F-logic-3).

Dev cần chú ý khi review

Vị trí Vì sao
WarehouseImportService.java:102-110 Nhánh lỗi khi SKU khác hoa thường (D-08); ném trước mọi lệnh ghi
Warehouse.java:115-132 Dirty-check thô quyết định có ghi updater/update_time (K-02)
WarehouseRelationalRepository.java:177-180,190-192 findAllById không lọc com_id trong SQL, an toàn tenant dựa vào phép so comId; kho bị xoá đồng thời giữa hai SELECT → WAREHOUSE_NOT_FOUND (rất hiếm, rollback)
WarehouseRelationalRepository.java:197-198 Kết quả lấy từ danh sách entity gốc — đúng vì persist giữ instance khi id null
WarehouseJpaRepository.findAllBySkuInAndComId Native SQL, collation MSSQL chưa kiểm (K-13)

F-02 Lưu import — tạo mới (type=1)

  • Điểm vào: như F-01
  • Quy tắc: R-01, R-02, R-03, R-04, R-06, R-08, R-09, R-10

Đối chiếu từng bước

# Luồng cũ Luồng mới Kết luận
1 Rỗng / không validate / không kiểm công ty như F-01 như F-01
2 findBySku(sku) không lọc com_id, Optional — …:1121 countBySkuAllCompanies — WarehouseRelationalRepository.java:205-214 KHỚP (D-04 GIỮ)
3 ≥2 dòng → 417 count > 1 → SystemException(EXCEPTION_ERROR) KHÁC có chủ đích (D-02, D-04)
4 1 dòng → bỏ qua count == 1 → bỏ qua KHỚP
5 copyProperties(dòng, kho) gồm id, comId dòng Warehouse.create/copyFrom, id null, comId request KHÁC có chủ đích (D-03)
6 genCode(request.comId, "WH") WarehouseCodeGenerator.generate(comId) (tách nguyên vòng cũ) KHỚP
7 isNullOrEmpty(SKU) → SKU = code copyFrom: null hoặc "" → code KHỚP
8 normalizedName([name, SKU dòng]) WarehouseText.normalizedName([name, sku dòng]) KHỚP
9 status = getStatus(), sellable thô createFromImport: status = activeStatus() KHỚP (D-09)
10 @PrePersist làm sạch + creator/updater cleanText + audit trong create KHỚP
11 saveAll → INSERT từng dòng save từng kho → INSERT KHỚP

Dev cần chú ý khi review

Vị trí Vì sao
WarehouseRelationalRepository.java:205-214 Truy vấn cố ý không lọc com_id (D-04); sku == null trả 0 bằng code
WarehouseImportService.java:117-124 Kiểm SKU rồi mới sinh mã; lỗi ≥2 kho ném sau khi dòng trước đã tiêu mã Redis
WarehouseCodeGenerator.java + WarehouseManagementService Refactor dùng chung với warehouse/create
Warehouse.java:98-102 create ép status=TRUE rồi createFromImport ghi đè — phụ thuộc thứ tự

F-03 Lưu import — type khác 1/2

  • Điểm vào: như F-01. Quy tắc: R-01, R-02, R-03, R-07, R-08, R-10
# Luồng cũ Luồng mới Kết luận
1 Không duyệt data Controller map mọi dòng KHÁC (F-logic-2) với phần tử null
2 Rỗng → FAIL như F-01 KHÁC có chủ đích (D-02, D-12)
3 Không kiểm công ty requireCompanyOfCurrentUser KHÁC có chủ đích (D-01)
4 Không nhánh nào khớp → saveAll([]) warehouses = List.of() KHỚP (D-10)
5 200 SUCCESS, data=[], count=0 ok([]) + count=0 KHÁC có chủ đích (D-02)

Vòng 2 (thu hẹp): F-01 bước 9 và F-02 bước 11 viết lại theo logic-reviewer vòng 2 (lưu qua saveAll); F-03 không đổi so với vòng 1 (rỗng thì không gọi saveAll, kết quả như saveAll([]) cũ).

Nguồn của trang này

  • Ghi chú vòng 3 migrations/warehouse/import-excel-save-data/verify/round-3/flow-analysis.md vòng 3 · sha256 046cdb0bf340
  • Phân tích luồng migrations/warehouse/import-excel-save-data/verify/round-2/flow-analysis.md vòng 2 · sha256 d77b07fadd65

v1 dựng 2026-11-06 00:42 · base commit đích a06ccfa6d4