-
Notifications
You must be signed in to change notification settings - Fork 323
Open
Labels
ApprovedThe issue is approvedThe issue is approvedSCMGitHub request for SCM areaGitHub request for SCM area
Description
Describe the issue
ISSUE 6.1: Commit() Before Posting Without Rollback on Failure
Severity: CRITICAL
Category: Transaction Management & Data Integrity
Files: src/Integration/Inventory/QltyItemJournalManagement.Codeunit.al
Problem:
The PostWarehouseJournal procedure uses Commit() before each posting attempt but has no rollback mechanism when posting fails, leading to partial success scenarios with no recovery path.
Code Location (Lines 181-202):
procedure PostWarehouseJournal(...)
var
ErrorMessage: Text;
ErrorStack: Text;
ErroredLinesErrorMessages: List of [Text];
ConsideredLines: List of [Text];
begin
// ... setup code ...
if WarehouseJournalLine.FindSet() then begin
repeat
ToPostWarehouseJournalLine := WarehouseJournalLine;
ToPostWarehouseJournalLine.SetRecFilter();
if not ConsideredLines.Contains(Format(ToPostWarehouseJournalLine.RecordId())) then begin
Commit(); // DEFECT: Commits before posting - no rollback if posting fails
if not WhseJnlRegisterBatch.Run(ToPostWarehouseJournalLine) then begin
ErrorMessage := GetLastErrorText(); // DEFECT: Gets error but doesn't clear it
ErrorStack := GetLastErrorCallStack();
ErroredLinesErrorMessages.Add(ErrorMessage);
QltyNotificationMgmt.NotifyDocumentCreationFailed(..., ErrorMessage, ...);
end;
end;
ConsideredLines.Add(Format(WarehouseJournalLine.RecordId()))
until WarehouseJournalLine.Next() = 0;
AllLinesPosted := ErroredLinesErrorMessages.Count() = 0;
end;
end;Critical Issues:
- No Rollback:
Commit()executed before posting - if posting fails, committed changes cannot be rolled back - Partial Success: Some lines may post while others fail, leaving system in inconsistent state
- No Error Recovery: Failed lines are logged but not retried or handled
- Data Integrity Risk: Test records may be modified before journal lines created/posted
Failure Scenario:
1. User executes disposition with 10 journal lines
2. Commit() executes before line 1 posts
3. Lines 1-5 post successfully
4. Line 6 fails (inventory shortage, locked record, etc.)
5. Lines 7-10 are not processed
6. Result: Partial posting - 5 lines posted, 5 lines not posted
7. Test status may be changed (committed) but disposition incomplete
8. No way to rollback or complete the operation
Recommended Fix:
procedure PostWarehouseJournal(var QltyInspectionTestHeader: Record "Qlty. Inspection Test Header"; var TempInstructionQltyDispositionBuffer: Record "Qlty. Disposition Buffer" temporary; var WarehouseJournalLine: Record "Warehouse Journal Line") AllLinesPosted: Boolean
var
ToPostWarehouseJournalLine: Record "Warehouse Journal Line";
WhseJnlRegisterBatch: Codeunit "Whse. Jnl.-Register Batch";
QltyNotificationMgmt: Codeunit "Qlty. Notification Mgmt.";
ErrorMessage: Text;
ErrorStack: Text;
ErroredLines: List of [RecordId];
ErroredLinesErrorMessages: Dictionary of [RecordId, Text];
PostingSucceeded: Boolean;
begin
ClearLastError();
AllLinesPosted := false;
if WarehouseJournalLine."Line No." <> 0 then
WarehouseJournalLine.SetRecFilter();
if WarehouseJournalLine.GetFilters() = '' then
Error(NoFiltersWereSuppliedWhenTryingToPostAWarehouseJournalLineErr);
// Attempt to post all lines in single transaction
if WarehouseJournalLine.FindSet() then begin
repeat
ToPostWarehouseJournalLine := WarehouseJournalLine;
ToPostWarehouseJournalLine.SetRecFilter();
ClearLastError();
PostingSucceeded := WhseJnlRegisterBatch.Run(ToPostWarehouseJournalLine);
if not PostingSucceeded then begin
ErrorMessage := GetLastErrorText();
ErrorStack := GetLastErrorCallStack();
ErroredLines.Add(ToPostWarehouseJournalLine.RecordId());
ErroredLinesErrorMessages.Add(ToPostWarehouseJournalLine.RecordId(), ErrorMessage);
end;
until WarehouseJournalLine.Next() = 0;
// If any errors, rollback by not committing
if ErroredLines.Count() > 0 then begin
// Notify user of all failed lines
foreach ErrorLine in ErroredLines do begin
if ToPostWarehouseJournalLine.GetBySystemId(ErrorLine) then
QltyNotificationMgmt.NotifyDocumentCreationFailed(
QltyInspectionTestHeader,
TempInstructionQltyDispositionBuffer,
PostedWarehouseJournalEntryDocumentTypeLbl,
ErroredLinesErrorMessages.Get(ErrorLine),
ToPostWarehouseJournalLine);
end;
// Error to rollback transaction
Error(PartialPostingNotAllowedErr, ErroredLines.Count(), WarehouseJournalLine.Count());
end;
AllLinesPosted := true;
Commit(); // Only commit if ALL lines posted successfully
end;
OnAfterPostWarehouseJournal(QltyInspectionTestHeader, TempInstructionQltyDispositionBuffer, WarehouseJournalLine, AllLinesPosted);
end;
var
PartialPostingNotAllowedErr: Label '%1 of %2 warehouse journal lines failed to post. The entire operation has been rolled back. Please correct the errors and try again.', Comment = '%1=failed count, %2=total count';Same Issue in:
- Line 359: Similar pattern with
Commit()before item journal posting src/Setup/SetupWizard/QltyManagementSetupWizard.Page.allines 482, 508, 560, 566, 568, 672src/Integration/Warehouse/QltyWhseGenRuleWizard.Page.alline 390src/Integration/Receiving/QltyRecGenRuleWizard.Page.alline 693
Expected behavior
Steps to reproduce
Additional context
I will provide a fix for a bug
- I will provide a fix for a bug
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
ApprovedThe issue is approvedThe issue is approvedSCMGitHub request for SCM areaGitHub request for SCM area