One Poison Record Shouldn't Kill the Batch
The overnight import job dies at 03:12 on record 37 of 200, and in the morning you learn the real damage: the error didn't just skip one bad record; it rolled back the 36 good ones imported before it. Real BC batch routines — the job queue, batch posting — are built so that one poison record can never undo the work already done. In this task you build a batch importer with exactly that guarantee.
The starter ships three finished data objects. Do not rename them or their fields — the grading tests bind to every name below character for character.
The objects you get
- Table
"Order Import Line"— primary key"Batch Code"(Code[20]) +"Line No."(Integer); fields"Customer No."(Code[20]),Quantity(Decimal),Status(enum"Order Import Status", defaults toPending). - Table
"Imported Order"— primary key"Batch Code"+"Line No."; fields"Customer No.",Quantity. - Enum
"Order Import Status"— valuesPending,Imported.
Requirements
Implement ImportBatch in the codeunit "Order Import Batch":
procedure ImportBatch(BatchCode: Code[20])Rules:
- Scope — the run concerns exactly the lines of
BatchCodewhoseStatusisPending, processed in ascending"Line No."order. Other batches and already-imported lines must be invisible to it; a batch with no pending lines is a quiet no-op — no error, no writes. - Importing a line — a valid line produces exactly one
"Imported Order"with the same"Batch Code"and"Line No."and copies of"Customer No."andQuantity, and the line'sStatusflips toImported. The line stays in the import table; importing never deletes lines. - Guards, checked per line before it is imported — a line with a blank
"Customer No."fails with the standard field-guard error: the message names the field and containsmust have a value(exactly whatTestFieldproduces). A line whoseQuantityis zero or negative fails with an error message that containsmust be positive. - The poison rule — when a line fails, the run stops there and the error reaches the caller. But every line this run already imported must survive the failure: its
"Imported Order"record and itsImportedstatus must still be in the database afterwards. The failing line leaves no"Imported Order"behind and staysPending, and so do all lines after it. - Guard errors are not the only way a line can die — one test makes a line crash while writing its
"Imported Order"(the record already exists). Whatever the error, the lines imported before it must survive it, unconditionally. - Fix and rerun — calling
ImportBatchagain after the bad line is repaired imports the remaining pending lines and creates no duplicates for the lines imported earlier.
What the tests check
The happy-path count and a field-by-field copy check with generated values (hardcoding won't survive); each guard with its error text (matching is case-insensitive, but the quoted phrases must appear exactly as written); a four-line batch whose third line is poison — the two lines before it must still be imported after the run fails, while the poison line and the line after it must not; the same batch repaired and rerun without duplicates; a mid-run crash at insert time whose predecessors must survive; scoping to the given batch next to a poisoned neighbour batch; a pre-imported line that must not be imported again; and the empty batch.
Learn More
Commit(), which ends the current transaction and starts a new one. Work committed before an error survives it; everything after the last Commit() is lost with it."Imported Order" and flip its Status, then call Commit() before moving to the next line. Let a failing line's error propagate uncaught — the tests expect the run itself to fail while every fully imported line stays in the database.