Đến nội dung chính
ERP Thực Chiến
Thư viện
Menu

Kiểm tra bản fix extension Business Central trước khi nghiệm thu

Cách tôi dùng AI kiểm tra bản fix extension Business Central trước khi đưa khách nghiệm thu: đúng bản build, đọc code đổi, test hồi quy, kiểm số sau post.

Tôi kiểm tra bản fix extension Business Central trước khi đưa khách nghiệm thu theo thứ tự: chắc đang cầm đúng bản build, nhờ AI đọc phần code đã đổi, chạy lại test hồi quy của ticket cũ, rồi mở bảng dữ liệu sau khi post xem số có đổi đúng không. "Post không còn báo lỗi" chưa phải là đã sửa.

Lần tôi kể dưới đây, tháng 07/2026 ở một dự án kho dùng Tasklet, đi qua ba bản build mới có một bản sửa đúng lỗi gốc. Nếu chỉ test bằng cách xem còn báo lỗi hay không, bản đầu tiên đã được nghiệm thu.

Tôi là functional consultant, không đọc AL thành thạo, nên phần đọc code tôi giao cho AI (Claude Code chạy trên máy). Bài này để có một quy trình tự kiểm, không để chấm điểm ai: hai bản đầu nằm ở hai nhánh code chạy song song, còn hai trong ba lần đọc nhầm bản là lỗi phía tôi.

Lỗi gốc: hai lot trên một dòng thì báo thiếu tồn pallet#

Extension của dự án giữ tồn theo pallet trong MOB License Plate Content, bảng tồn pallet của Tasklet, và trừ tồn này khi post Warehouse Shipment. Lỗi xảy ra ở kho không bật Require Pick, chứng từ nguồn là Transfer Order, Item Tracking của dòng có 2 lot: 380 và 120, tổng 500.

Vòng kiểm tra chạy theo từng lot, nhưng đem tồn của lot so với Qty. to Ship (Base) của cả dòng:

Con sốĐúng raHệ thống đang làm
Số đem kiểm tra cho lot 1380500
Số đem kiểm tra cho lot 2120500
Tổng trừ nếu cả hai lot đều còn từ 500 trở lên5001.000

Lot 2 còn đúng 120 vẫn bị báo thiếu tồn. Dòng cuối mới đáng lo: cả hai lot đều còn từ 500 trở lên thì lọt qua kiểm tra, phiếu xuất 500 trừ mất 1.000 trong bảng tồn pallet mà không ai thấy.

Vì sao sửa lỗi này lại sinh lỗi kia#

Bản sửa trước đó ở chính chỗ này đã đổi từ "trừ theo số của từng lot" sang "trừ theo số của cả dòng", để chữa một lỗi khác: phiếu có nhiều dòng cùng lot khác pallet, hoặc xuất một phần nhiều lần, thì pallet bị trừ trùng. Hai lỗi kéo ngược nhau. Chọn một trong hai con số thì sửa lỗi này sẽ mở lại lỗi kia.

Quy tắc nghiệm thu tôi viết cho dev dùng cả hai con số cùng lúc:

Kiểm tra và trừ tồn theo từng lot trên Item Tracking, nhưng tổng trừ của mỗi dòng phải đúng bằng Qty. to Ship (Base) của dòng đó, không hơn, không kém.

Spec gắn nhãn từng bước [KHÔNG ĐỔI], [SỬA], [MỚI] để dev biết chỗ nào phải đụng. Kèm 7 test hồi quy, trong đó test 3 và 4 chép nguyên văn kịch bản đã nghiệm thu của ticket cũ:

#Kịch bảnKỳ vọng
11 dòng, 1 lot, 1 palletTrừ đúng
21 dòng, 2 lot (380 và 120)Post được, trừ 380 và 120 theo từng lot
3Nhiều dòng cùng lot, khác pallet (50, 60, 70)Mỗi pallet trừ đúng phần của nó, không pallet nào bị trừ hai lần
4Xuất một phần nhiều lần (100 rồi 200)Mỗi lần trừ đúng số đã xuất
5Bắt buộc trừ đúng pallet chỉ địnhTrừ đúng pallet đó
6Kho có Require Pick, nguồn Sales Order, Purchase Return OrderKhông đổi so với trước
7Mặt hàng có đơn vị tính khác đơn vị cơ sởTrừ đúng theo Base

Spec và comment do AI soạn, tôi sửa hai chỗ. Comment bản đầu trích số dòng code và tên hàm. Tôi không phải dev, đem số dòng ra thì dev hỏi lại một câu là tôi không trả lời được. Comment chỉ nói hệ thống làm gì sai, nghiệp vụ cần gì, kiểm chứng bằng dữ liệu nào. Spec bản đầu có câu "giữ nguyên máy móc trừ hiện tại", kiểu câu tôi gặp nhiều trong tài liệu FDD do AI viết: đọc xong không ai biết hiện tại là gì. Phải tả ra: hệ thống lấy pallet ghi trên Item Tracking trước, không đủ thì vét sang pallet khác cùng lot trong bin, pallet nhập sau vét trước. Cách viết mỗi bước logic thành một câu đủ ý có ví dụ ở bài lấy diễn giải khuyến mãi lên hóa đơn điện tử LS Central.

Ba bản build và test nào bắt được#

BảnThay đổiHậu quảTest bắt được
ABỏ phép tính số lượng cần trừ, số này thành 0. Thêm một query tính tổng tồnHết báo lỗi nhưng tồn pallet không giảm. Kho có Require Pick vốn đúng cũng ngừng trừ tồnMọi test, nếu mở bảng tồn pallet sau khi post. Chỉ nhìn thông báo lỗi thì không test nào bắt được
BSố version cao hơn bản A nhưng là nhánh cũ. Tắt mấy subscriber của Sales-Post và Purch.-PostVẫn báo lỗi gốc. Giao hàng bán không còn trừ tồn palletTest 2 và test 6
CViết lại, lấy số theo từng lot từ Reservation EntryLỗi gốc hết. Còn bốn chỗ phải test hoặc hỏi lạiTest 3 và 4 phải chạy thật mới biết

Bản A là loại khó bắt nhất. Lỗi biến mất vì phép kiểm tra không còn gì để kiểm, không phải vì hệ thống tính đúng lên. Trước đó lỗi còn chặn post nên dữ liệu sạch, bản này post lọt và tồn pallet sai âm thầm. Phần code bị đổi nhìn gọn, phần chạy sai lại là phần không ai đụng tới, nên đọc lướt cũng dễ lọt. AI còn thấy query tính tổng tồn mới viết đúng, nhưng dòng kiểm tra ngay dưới vẫn dùng biến cũ chưa được tính. Đặt lại phép tính số lượng là lỗi này lộ ra, mọi phiếu báo thiếu tồn ngay lot đầu tiên.

Bản B số version cao hơn nên tôi tưởng mới hơn. Thật ra đó là nhánh khác, phép tính vẫn như bản gốc.

Bản C sửa đúng hướng. Bốn chỗ còn hở tôi ghi vào ticket:

  • Với mỗi dòng chứng từ nguồn, hệ thống vẫn chỉ xử lý dòng Warehouse Shipment đầu tiên, nên phiếu tách nhiều dòng theo pallet phải chạy test 3.
  • Bản này quay lại lấy số theo Item Tracking, đúng thứ bản sửa trước từng đổi đi, nên phải chạy test 4 xem lỗi trừ trùng có quay lại không.
  • Bước lọc theo kết quả QC chỉ áp cho Sales Order. Phải hỏi dev đây là chủ ý hay bỏ sót.
  • Chưa chặn khi Item Tracking khai thiếu so với số xuất.

Người dùng test bản C và gặp Quantity must be positive#

Người dùng test bản C: post được. Nhưng chọn một lot trên Item Tracking Lines, đổi sang lot khác rồi đóng trang thì báo:

text
Quantity must be positive

AI tìm câu này trong toàn bộ source của extension, không có. Đây là chặn chuẩn của BC khi còn một dòng tracking số lượng 0. Phần custom trên trang Item Tracking Lines có đổi 76 dòng giữa bản gốc và bản C, nhưng không đụng logic lot. Cách làm tạm cho người dùng: xóa hẳn dòng lot cũ rồi thêm dòng mới, không gõ đè. Tôi tách thành ticket riêng để ticket post đóng được.

Kết luận này từ đọc code tĩnh, chưa tái hiện trên hệ thống. Muốn chốt thì đổi lot y như vậy trên bản cũ: bản cũ cũng báo thì không phải do bản fix.

AI làm phần nào, tôi làm phần nào#

ViệcAi làm
Tìm file .app mới trên máy, kể cả khi nó nằm ở thư mục project khác với chỗ tôi đang mởAI
Giải nén, so nội dung giữa hai bảnAI
Đọc phần code đổi, lần theo biến số lượng cần trừAI
Đối chiếu từng bước trong spec, chấm đạt hay chưaAI
Chọn giọng comment gửi dev, quyết định trả bản build hay nhậnTôi
Test trên sandboxNgười dùng

Kiểm đúng bản build: đừng tin ngày sửa file#

Ba lần tôi suýt review nhầm bản. Lần đầu, dev báo đã fix, file bản A trên máy mang ngày sửa mới nhưng cùng số version và cùng dung lượng với lần trước. AI giải nén và so từng byte: nội dung y hệt, chỉ là OneDrive đồng bộ lại. Hai lần sau là lỗi của tôi: một lần tải về mà chưa giải nén, một lần tải nhầm bản.

Quy tắc: nhìn số version, không nhìn ngày sửa file. Trùng số version thì so nội dung. Số version cao hơn cũng chưa chắc mới hơn, bản B là ví dụ.

File .app có source code không#

AI đọc được code vì file .app của chính extension dự án có kèm source. File .app là container NAVX: 40 byte header rồi tới một file zip chuẩn, cắt header là giải nén được.

Gói chỉ có symbol thì không đọc được thân hàm, ví dụ một gói 39 KB tôi gặp chỉ có NavxManifest, SymbolReference, DocComments. Nếu app.json của extension bật allowDownloadingSource thì tải source ở trang Extension Management, chọn Download Source. Các cờ này nằm trong resourceExposurePolicy, xem Resource exposure policy setting trên Microsoft Learn.

Chỉ giải nén .app của extension do công ty mình sở hữu, hoặc khách cho phép xem source. Symbol của Microsoft (Base Application, System Application và các gói đi kèm bản 28.4 giải nén ra 9.875 file .al) thì để ở thư mục ngoài project. Để trong project, AL compiler quét luôn số file đó và báo trùng object ID hàng loạt.

Checklist kiểm bản fix trước khi đưa khách nghiệm thu#

  1. Đúng bản: số version khớp bản dev báo. Trùng số thì so nội dung, không tin ngày sửa file.
  2. Đọc phần code đổi so với bản trước, và cả phần không đổi nhưng nhận số liệu khác.
  3. Chạy lại nguyên văn test đã nghiệm thu của các ticket cũ ở cùng chỗ.
  4. Sau khi post, mở bảng dữ liệu bị tác động, ở đây là MOB License Plate Content, xem số có đổi đúng từng lot không.
  5. Chạy một phiếu ở luồng ngoài phạm vi sửa, ở đây là kho có Require Pick và giao hàng bán.
  6. Lỗi mới không thuộc ticket thì tách ticket riêng, ghi rõ đã tái hiện hay mới đọc code.

Đọc tiếp