mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 06:36:55 +01:00
Normalize SCM knowledge and review ownership
Align article and AL sample conventions, keep BC facts separate from review mechanics, and clarify reciprocal Finance ownership without bespoke shared test assertions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
9ac62e3967
commit
525e84e183
30 changed files with 148 additions and 362 deletions
22
.github/scripts/Test-SkillIndex.ps1
vendored
22
.github/scripts/Test-SkillIndex.ps1
vendored
|
|
@ -110,28 +110,6 @@ try {
|
|||
}
|
||||
}
|
||||
|
||||
$scm = @($skills | Where-Object id -eq 'al-scm-review')
|
||||
if ($scm.Count -ne 1 -or
|
||||
(@($scm[0].inputs) -join ',') -cne 'pr-diff,file-path,folder-path' -or
|
||||
(@($scm[0].filters.technologies) -join ',') -cne 'al') {
|
||||
throw 'SCM must be discoverable as an AL leaf accepting diffs, files, and complete folders.'
|
||||
}
|
||||
$scmText = Get-Content -LiteralPath (Join-Path $Root $scm[0].path) -Raw
|
||||
$scmExamples = [regex]::Matches($scmText, '(?s)```json\s*(\{.*?\})\s*```')
|
||||
if ($scmExamples.Count -ne 2) {
|
||||
throw "Expected two SCM findings-report examples, found $($scmExamples.Count)."
|
||||
}
|
||||
foreach ($example in $scmExamples) {
|
||||
if (-not ($example.Groups[1].Value | Test-Json -SchemaFile $reportSchema -ErrorAction Stop)) {
|
||||
throw 'An SCM output example does not satisfy schemas/findings-report.schema.json.'
|
||||
}
|
||||
$report = $example.Groups[1].Value | ConvertFrom-Json
|
||||
if ($report.skill.id -cne 'al-scm-review' -or
|
||||
@($report.findings | Where-Object domain -cne 'Supply Chain Management').Count) {
|
||||
throw 'SCM output examples must retain the leaf id and complete display domain.'
|
||||
}
|
||||
}
|
||||
|
||||
$minimalReport = @{
|
||||
skill = @{ id = 'al-style-review'; version = 1 }
|
||||
outcome = 'completed'
|
||||
|
|
|
|||
|
|
@ -194,8 +194,8 @@ Available knowledge is **not** a promise that every rule will run. Selection
|
|||
depends on the task, target context, enabled layers, and source evidence.
|
||||
A whole-folder review is a current-state snapshot: detecting a published API
|
||||
removal or another comparison-only regression requires an actual baseline.
|
||||
The corpus combines technical AL guidance with a focused SCM functional
|
||||
domain, not exhaustive functional validation or AppSource certification.
|
||||
The corpus combines technical AL guidance with targeted functional-domain
|
||||
invariants, not exhaustive functional validation or AppSource certification.
|
||||
|
||||
The SCM leaf owns selected inventory/value, application, reservation, tracking,
|
||||
and warehouse/posting invariants. It prunes unrelated AL using the actual
|
||||
|
|
@ -205,6 +205,12 @@ must not be replaced with an assumed posting defect. Manufacturing, assembly,
|
|||
planning, and other supply-chain areas are covered only where an article
|
||||
explicitly names the shared interface or invariant.
|
||||
|
||||
SCM owns Item/Value/Capacity/Warehouse and inventory-application posting
|
||||
records. Pure G/L, customer/vendor/detailed/VAT and financial-only posting
|
||||
mutations belong to Finance, even when that domain is not enabled. Equivalent
|
||||
findings for one inventory-originated posting bypass have one SCM primary
|
||||
owner; distinct independent financial defects remain separate.
|
||||
|
||||
BCQuality intentionally does not duplicate mechanical diagnostics already
|
||||
enforced by the AL compiler or standard analyzers. Run the consuming app's
|
||||
normal compiler and analyzer pipeline alongside review and authoring. Knowledge
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Tracking;
|
||||
using Microsoft.Sales.Document;
|
||||
|
||||
codeunit 50106 "SCM Cancel Reservation Bad"
|
||||
{
|
||||
procedure CancelSalesReservation(ReservationEntryNo: Integer)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Tracking;
|
||||
using Microsoft.Sales.Document;
|
||||
|
||||
codeunit 50107 "SCM Cancel Reservation Good"
|
||||
{
|
||||
procedure CancelSalesReservation(ReservationEntryNo: Integer)
|
||||
|
|
|
|||
|
|
@ -15,22 +15,21 @@ Persistent `"Reservation Entry"` rows are not disposable allocation markers. Res
|
|||
|
||||
## Best Practice
|
||||
|
||||
For explicit cancellation of an existing binding reservation, use `"Reservation Engine Mgt.".CancelReservation`. It checks the reservation status and `"Disallow Cancellation"`, handles the counterpart, and preserves or retracks the remaining source quantities as appropriate. For source-line quantity changes, use the source-specific reservation management path rather than deleting its reservation rows yourself.
|
||||
Explicit cancellation of an existing binding reservation uses `"Reservation Engine Mgt.".CancelReservation`. It checks the reservation status and `"Disallow Cancellation"`, handles the counterpart, and preserves or retracks the remaining source quantities as appropriate. Source-line quantity changes have their own source-specific reservation management path.
|
||||
|
||||
Do not require every Reservation Entry to have a partner or identical lot/serial values on both sides: Surplus/Prospect entries and supported late-binding scenarios need different treatment. Temporary buffers, engine-owned updates, and supported publisher metadata are not independent cancellation. Cancelling a reservation is also different from intentionally removing an item-tracking assignment.
|
||||
Not every Reservation Entry has a partner or identical lot/serial values on both sides: Surplus/Prospect entries and supported late-binding scenarios have different relationships. Temporary buffers, engine-owned updates, and supported publisher metadata are not independent cancellation. Cancelling a reservation is also different from intentionally removing an item-tracking assignment.
|
||||
|
||||
The samples retrieve the negative side of a persistent sales-line reservation and cancel only the binding. They do not delete the sales line or remove its tracking specifications.
|
||||
|
||||
See sample: [`cancel-reservations-through-reservation-management.good.al`](cancel-reservations-through-reservation-management.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report `Delete(true)`, `DeleteAll`, or a status/source rewrite on persistent `"Reservation Entry"` records used as a replacement for cancelling a reservation. Deleting both sides is not a sufficient repair: it can still discard tracking that should survive and omit retracking.
|
||||
`Delete(true)`, `DeleteAll`, or a status/source rewrite on persistent `"Reservation Entry"` records does not perform binding-reservation cancellation. Even deleting both sides can discard tracking that should survive and omit retracking.
|
||||
|
||||
Require cancellation intent and a binding reservation in the visible context. Do not flag normal processing of temporary Prospect/Surplus buffers or diagnose every single row as an orphan.
|
||||
Normal processing of temporary Prospect/Surplus buffers is outside that cancellation workflow, and an unpaired row is not intrinsically an orphan.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`cancel-reservations-through-reservation-management.bad.al`](cancel-reservations-through-reservation-management.bad.al)
|
||||
- [`cancel-reservations-through-reservation-management.good.al`](cancel-reservations-through-reservation-management.good.al)
|
||||
See sample: [`cancel-reservations-through-reservation-management.bad.al`](cancel-reservations-through-reservation-management.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Requisition;
|
||||
using Microsoft.Purchases.Document;
|
||||
using Microsoft.Sales.Document;
|
||||
|
||||
codeunit 50116 "SCM Requisition Action Bad"
|
||||
{
|
||||
procedure CarryOutAcceptedNewPurchase(TemplateName: Code[10]; BatchName: Code[10]; LineNo: Integer; OrderDate: Date; PostingDate: Date; ReceiptDate: Date; CutoffDate: Date)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Requisition;
|
||||
using Microsoft.Purchases.Document;
|
||||
using Microsoft.Sales.Document;
|
||||
|
||||
codeunit 50117 "SCM Requisition Action Good"
|
||||
{
|
||||
procedure CarryOutAcceptedNewPurchase(TemplateName: Code[10]; BatchName: Code[10]; LineNo: Integer; OrderDate: Date; PostingDate: Date; ReceiptDate: Date; CutoffDate: Date)
|
||||
|
|
|
|||
|
|
@ -15,24 +15,23 @@ A requisition/planning line is a pending change to a supply/demand network, not
|
|||
|
||||
## Best Practice
|
||||
|
||||
For requisition batch carry-out, initialize `"Req. Wksh.-Make Order"` with `Set` and invoke `CarryOutBatchAction` on the intended accepted lines. Supply the order/posting/receipt defaults separately from the ending-order-date cutoff, and preserve the selected worksheet/batch/line filters. A plain `Run` or a single order-line insertion helper is not a replacement for this batch initialization and finalization.
|
||||
Requisition batch carry-out initializes `"Req. Wksh.-Make Order"` with `Set` and invokes `CarryOutBatchAction` on the intended accepted lines. Order/posting/receipt defaults are separate from the ending-order-date cutoff, and worksheet/batch/line filters define the selection. A plain `Run` or a single order-line insertion helper is not a replacement for this batch initialization and finalization.
|
||||
|
||||
Use the standard `"Carry Out Action"` dispatch for broader planning output and its configured purchase, transfer, assembly, or manufacturing choices. Do not turn every action into a new purchase order, bypass source-specific reservation transfer, or delete proposals before the owning workflow has completed their supply change.
|
||||
The standard `"Carry Out Action"` dispatch handles broader planning output and its configured purchase, transfer, assembly, or manufacturing choices. Each action's supply change and source-specific reservation transfer precede proposal finalization; not every action creates a new purchase order.
|
||||
|
||||
Ordinary manual purchase creation that does not consume planning output is outside this rule. Users may reject or delete unwanted proposals without creating supply; temporary planning simulations, pre-carry-out enrichment, and engine-owned cleanup are also legitimate. `Delete(true)` on a requisition line is not intrinsically a defect.
|
||||
|
||||
The samples select an existing accepted New/Purchase item proposal with sales-demand context. Dates are explicit, the source selection remains bounded, and the clean sample leaves order creation and reservation handoff to the standard workflow; it is not a complete planning-run generator.
|
||||
|
||||
See sample: [`carry-out-requisition-actions-through-the-standard-workflow.good.al`](carry-out-requisition-actions-through-the-standard-workflow.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report code that consumes accepted persistent `"Requisition Line"` action messages, manually creates or changes supply from a subset of fields, and then deletes or marks the proposal handled without the standard carry-out/source-reservation handoff. Running purchase-field validation and the requisition delete trigger does not first move the proposal's demand links to the new purchase line.
|
||||
Manually creating or changing supply from a subset of an accepted persistent `"Requisition Line"`, then deleting or marking that proposal handled, skips the standard carry-out/source-reservation handoff. Purchase-field validation and the requisition delete trigger do not first move the proposal's demand links to the new purchase line.
|
||||
|
||||
Require both proposal-consumption intent and a visible supply conversion. Do not flag an isolated deletion of an unwanted suggestion, an ordinary purchase-order API, or the standard carry-out engine's own insert/delete sequence.
|
||||
Deleting an unwanted suggestion or creating an ordinary purchase order without consuming planning output is a separate operation. The standard carry-out engine's own insert/delete sequence participates in the source handoff rather than replacing it.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`carry-out-requisition-actions-through-the-standard-workflow.bad.al`](carry-out-requisition-actions-through-the-standard-workflow.bad.al)
|
||||
- [`carry-out-requisition-actions-through-the-standard-workflow.good.al`](carry-out-requisition-actions-through-the-standard-workflow.good.al)
|
||||
See sample: [`carry-out-requisition-actions-through-the-standard-workflow.bad.al`](carry-out-requisition-actions-through-the-standard-workflow.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Ledger;
|
||||
|
||||
codeunit 50104 "SCM Item Application Bad"
|
||||
{
|
||||
procedure ChangeSalesQuantityApplication(ApplicationEntryNo: Integer; NewInboundEntryNo: Integer)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Ledger;
|
||||
using Microsoft.Inventory.Posting;
|
||||
|
||||
codeunit 50105 "SCM Item Application Good"
|
||||
{
|
||||
procedure ChangeSalesQuantityApplication(ApplicationEntryNo: Integer; NewInboundEntryNo: Integer)
|
||||
|
|
|
|||
|
|
@ -15,22 +15,21 @@ An `"Item Application Entry"` connects quantity application to cost flow; changi
|
|||
|
||||
## Best Practice
|
||||
|
||||
Prefer the Application Worksheet for interactive corrections. For a narrowly controlled programmatic correction of an ordinary quantity application, use the same `"Item Jnl.-Post Line"` instance for `UnApply`, reload the affected outbound item entry, then `ReApply` it to the compatible inbound entry. Complete the application's `RedoApplications`, `CostAdjust`, and `ClearApplicationLog` lifecycle; do not commit a half-completed replacement.
|
||||
The Application Worksheet provides the interactive correction workflow. A narrowly controlled programmatic correction of an ordinary quantity application uses the same `"Item Jnl.-Post Line"` instance for `UnApply`, a reload of the affected outbound item entry, and `ReApply` to the compatible inbound entry. Its finalization lifecycle includes `RedoApplications`, `CostAdjust`, and `ClearApplicationLog`.
|
||||
|
||||
Respect the posting routines' inventory-period, correction, transfer, and drop-shipment restrictions rather than bypassing them. `"Transferred-from Entry No."`, outbound transfers, and special application types are not permission to reuse the ordinary-sales sample unchecked. Do not enable application-check bypasses or borrow the worksheet's multi-step recovery flags for a standalone transaction.
|
||||
The posting routines enforce inventory-period, correction, transfer, and drop-shipment restrictions. Entries with `"Transferred-from Entry No."`, outbound transfers, and special application types are outside the ordinary-sales sample's scope. Application-check bypasses remove those protections, and the worksheet's multi-step recovery flags belong to its UI lifecycle rather than a standalone transaction.
|
||||
|
||||
`CostAdjust` honors automatic-cost-adjustment setup; calling it does not promise that all costs are settled when adjustment is disabled or deferred. Retain the required scheduled/manual adjustment process. Temporary application projections, extension metadata, and source-document reservation/order-tracking changes are not edits to the persistent item-application graph.
|
||||
`CostAdjust` honors automatic-cost-adjustment setup; calling it does not mean all costs are settled when adjustment is disabled or deferred. Scheduled/manual adjustment remains necessary in those configurations. Temporary application projections, extension metadata, and source-document reservation/order-tracking changes are not edits to the persistent item-application graph.
|
||||
|
||||
See sample: [`change-item-applications-through-posting-routines.good.al`](change-item-applications-through-posting-routines.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report independent `Modify`, `Delete`, or replacement `Insert` operations on persistent `"Item Application Entry"` rows used to repoint a receipt/shipment application, including a change to `"Inbound Item Entry No."` that leaves remaining quantities and cost propagation untouched. Valid item numbers, matching quantities, or running table triggers do not complete reapplication.
|
||||
Independent `Modify`, `Delete`, or replacement `Insert` operations on persistent `"Item Application Entry"` rows can repoint a receipt/shipment application without updating remaining quantities or cost propagation. Valid item numbers, matching quantities, and running table triggers do not complete reapplication.
|
||||
|
||||
Also report a visibly incomplete custom unapply/reapply transaction that omits finalization or commits between the two operations. Do not flag code merely because the standard posting/application workflow internally writes these tables.
|
||||
Omitting finalization or committing between unapply and reapply exposes an incomplete replacement. The standard posting/application workflow's internal table writes differ because they participate in that lifecycle.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`change-item-applications-through-posting-routines.bad.al`](change-item-applications-through-posting-routines.bad.al)
|
||||
- [`change-item-applications-through-posting-routines.good.al`](change-item-applications-through-posting-routines.good.al)
|
||||
See sample: [`change-item-applications-through-posting-routines.bad.al`](change-item-applications-through-posting-routines.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Journal;
|
||||
using Microsoft.Inventory.Ledger;
|
||||
|
||||
codeunit 50100 "SCM Stock Adjustment Bad"
|
||||
{
|
||||
procedure PostPreparedPositiveAdjustment(ItemJournalLine: Record "Item Journal Line"; NewEntryNo: Integer)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Journal;
|
||||
using Microsoft.Inventory.Posting;
|
||||
|
||||
codeunit 50101 "SCM Stock Adjustment Good"
|
||||
{
|
||||
procedure PostPreparedPositiveAdjustment(var ItemJournalLine: Record "Item Journal Line")
|
||||
|
|
|
|||
|
|
@ -15,24 +15,23 @@ An item ledger entry is not an independently insertable stock balance. Posting c
|
|||
|
||||
## Best Practice
|
||||
|
||||
For a prepared standalone item-journal movement, enter through codeunit `"Item Jnl.-Post Line".RunWithCheck`. For a persisted journal batch, use `"Item Jnl.-Post Batch"`; for a sales, purchase, transfer, assembly, or production transaction, retain that workflow's owning document/posting orchestration rather than replacing it with a naked journal call. Let the posting engine create the ledger, value, and application records and perform its checks.
|
||||
The posting entry point for a prepared standalone item-journal movement is `"Item Jnl.-Post Line".RunWithCheck`. Persisted journal batches use `"Item Jnl.-Post Batch"`; sales, purchase, transfer, assembly, and production transactions retain their owning document/posting orchestration. Those workflows create the ledger, value, and application records together with their required checks.
|
||||
|
||||
Extend supported posting events and pass validated journal/source data into the owning workflow. Read-only ledger queries, temporary previews, extension-owned metadata fields, and supported publisher parameters consumed by the poster are not independent ledger posting and must not be flagged merely because they assign record fields. A publisher's `var` parameter or `IsHandled` flag is not blanket authorization to recreate quantity/cost state. A change inside the posting engine itself requires tracing that engine's surrounding invariants, not a ban on its own inserts.
|
||||
Supported posting events enrich validated journal/source data within the owning workflow. Read-only ledger queries, temporary ledger previews, extension-owned metadata fields, and publisher parameters consumed by the poster are not independent ledger posting. A temporary item-journal buffer can still produce persistent entries when passed to a posting codeunit. A publisher's `var` parameter or `IsHandled` flag alone does not supply the missing quantity/cost coordination; the normal engine's own inserts operate within that coordination.
|
||||
|
||||
Do not require every value entry to point to an item ledger entry: capacity and production WIP have their own supported posting relationships. Assembly and manufacturing posting retain order/component/routing and capacity context; one bare output/consumption call is not full order completion.
|
||||
Not every value entry points to an item ledger entry: capacity and production WIP have their own supported posting relationships. Assembly and manufacturing posting retain order/component/routing and capacity context; one bare output/consumption call is not full order completion.
|
||||
|
||||
The clean sample takes an already prepared positive-adjustment journal line. It is not a substitute for journal preparation, batch revaluation, warehouse reconciliation, or source-document posting.
|
||||
|
||||
See sample: [`post-item-ledger-changes-through-item-journals.good.al`](post-item-ledger-changes-through-item-journals.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report extension code that independently inserts/deletes persistent `"Item Ledger Entry"` or `"Value Entry"` transaction rows, or overwrites posted quantity, remaining quantity, application identity, or cost amounts to implement a receipt, shipment, adjustment, or cost correction. `Insert(true)`, `Modify(true)`, and balanced-looking quantities do not supply the missing posting orchestration.
|
||||
Independent inserts/deletes of persistent `"Item Ledger Entry"` or `"Value Entry"` transaction rows, or overwrites of posted quantity, remaining quantity, application identity, or cost amounts, bypass the coordinated receipt, shipment, adjustment, or cost-correction workflow. `Insert(true)`, `Modify(true)`, and balanced-looking quantities do not supply that orchestration: stock can change without the corresponding application/value graph, or downstream cost flow can remain stale.
|
||||
|
||||
Require evidence of a persistent transaction mutation and its business purpose; a table declaration or a write to a custom annotation field is insufficient. For a more specific revaluation or application defect, prefer the corresponding SCM article rather than reporting the same correction twice.
|
||||
A table declaration or custom annotation-field update does not change inventory quantities or costs and is outside this transaction-state concern.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`post-item-ledger-changes-through-item-journals.bad.al`](post-item-ledger-changes-through-item-journals.bad.al)
|
||||
- [`post-item-ledger-changes-through-item-journals.good.al`](post-item-ledger-changes-through-item-journals.good.al)
|
||||
See sample: [`post-item-ledger-changes-through-item-journals.bad.al`](post-item-ledger-changes-through-item-journals.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Journal;
|
||||
using Microsoft.Inventory.Posting;
|
||||
|
||||
codeunit 50102 "SCM Revaluation Batch Bad"
|
||||
{
|
||||
procedure PostCalculatedRevaluationBatch(TemplateName: Code[10]; BatchName: Code[10])
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Journal;
|
||||
using Microsoft.Inventory.Posting;
|
||||
|
||||
codeunit 50103 "SCM Revaluation Batch Good"
|
||||
{
|
||||
procedure PostCalculatedRevaluationBatch(TemplateName: Code[10]; BatchName: Code[10])
|
||||
|
|
|
|||
|
|
@ -15,22 +15,21 @@ A calculated revaluation line with nonblank `"Inventory Value Per"` represents a
|
|||
|
||||
## Best Practice
|
||||
|
||||
Post a prepared revaluation batch through `"Item Jnl.-Post Batch"`. Keep the calculated line's valuation date, aggregation scope, location/variant filters, and revaluation fields intact. The batch expands summarized values into per-entry postings and checks that the eligible inventory has not changed; for partial revaluation it also rechecks remaining quantity before posting.
|
||||
Posting a prepared revaluation batch through `"Item Jnl.-Post Batch"` preserves the calculated line's valuation date, aggregation scope, location/variant filters, and revaluation fields. The batch expands summarized values into per-entry postings and checks that the eligible inventory has not changed; for partial revaluation it also rechecks remaining quantity before posting.
|
||||
|
||||
Do not treat the public `"Item Jnl.-Post Line".RunWithCheck` API as a replacement for that orchestration. It remains legitimate for finalized individual-entry revaluation lines within a workflow that already supplies the necessary checks; the batch itself uses the line poster. A call to that API without evidence of summarized or partial revaluation is not this defect.
|
||||
The public `"Item Jnl.-Post Line".RunWithCheck` API does not replace that orchestration. It remains legitimate for finalized individual-entry revaluation lines within a workflow that already supplies the necessary checks; the batch itself uses the line poster. Ordinary quantity journals and finalized per-entry revaluations are distinct from this summarized/partial-revaluation case.
|
||||
|
||||
The samples explicitly require `"Value Entry Type" = Revaluation` and a nonblank `"Inventory Value Per"` in an existing calculated journal batch. They demonstrate posting, not how to calculate a new valuation or choose a standard cost.
|
||||
|
||||
See sample: [`post-revaluation-through-the-item-journal-batch.good.al`](post-revaluation-through-the-item-journal-batch.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report a loop that sends calculated aggregate revaluation lines straight to `"Item Jnl.-Post Line"`, or a custom partial-revaluation workflow that bypasses the remaining-quantity recheck visible in the standard batch. A loop over the journal is not equivalent to distributing the aggregate over its underlying item entries.
|
||||
A loop that sends calculated aggregate revaluation lines straight to `"Item Jnl.-Post Line"` skips distribution over the underlying item entries. A partial-revaluation workflow without the remaining-quantity recheck can post a valuation against inventory that no longer matches the calculation.
|
||||
|
||||
Do not recommend directly editing existing `"Value Entry"` cost amounts or the Item's unit cost to repair the result. Use the revaluation/cost-adjustment workflow appropriate to the correction.
|
||||
Directly editing existing `"Value Entry"` cost amounts or the Item's unit cost does not repair those allocation and adjustment relationships. Their correction belongs to the revaluation/cost-adjustment workflow.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`post-revaluation-through-the-item-journal-batch.bad.al`](post-revaluation-through-the-item-journal-batch.bad.al)
|
||||
- [`post-revaluation-through-the-item-journal-batch.good.al`](post-revaluation-through-the-item-journal-batch.good.al)
|
||||
See sample: [`post-revaluation-through-the-item-journal-batch.bad.al`](post-revaluation-through-the-item-journal-batch.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Journal;
|
||||
using Microsoft.Inventory.Location;
|
||||
using Microsoft.Inventory.Posting;
|
||||
using Microsoft.Inventory.Transfer;
|
||||
|
||||
codeunit 50112 "SCM Transfer Posting Bad"
|
||||
{
|
||||
procedure ShipTransferOrder(TransferOrderNo: Code[20]; var ItemJournalLine: Record "Item Journal Line")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Location;
|
||||
using Microsoft.Inventory.Transfer;
|
||||
|
||||
codeunit 50113 "SCM Transfer Posting Good"
|
||||
{
|
||||
procedure ShipTransferOrder(TransferOrderNo: Code[20])
|
||||
|
|
|
|||
|
|
@ -15,22 +15,21 @@ A two-step transfer order preserves a continuous quantity, reservation, and cost
|
|||
|
||||
## Best Practice
|
||||
|
||||
For a prepared non-direct transfer order without required warehouse documents, use `"TransferOrder-Post Shipment".Run` at shipment and `"TransferOrder-Post Receipt".Run` at receipt, passing the actual `"Transfer Header"`. Validate the intended quantities to ship/receive through the source document; do not assign posted quantity counters as preparation.
|
||||
A prepared non-direct transfer order without required warehouse documents uses `"TransferOrder-Post Shipment".Run` at shipment and `"TransferOrder-Post Receipt".Run` at receipt, with the actual `"Transfer Header"`. Validated source quantities to ship/receive prepare the operation; posted quantity counters are results of posting.
|
||||
|
||||
When warehouse shipment or receipt is required, use the warehouse document posting workflow that invokes the transfer poster with its real source context. Retain the configured standard direct-transfer workflow for direct transfers; the two-step sample's in-transit guard is not a universal requirement.
|
||||
Required warehouse shipment or receipt enters the warehouse document posting workflow, which invokes the transfer poster with its real source context. Direct transfers have their configured standard workflow; the two-step sample's in-transit guard is not a universal requirement.
|
||||
|
||||
Standalone item reclassification journals and bin movements are legitimate separate operations. Do not demand a fixed number of item ledger entries, or a nonzero `"Transferred-from Entry No."` on every transfer application: tracking/application splits and average-cost transfer handling differ. Require evidence that code is replacing completion of an existing transfer order, not merely moving stock through another supported process.
|
||||
Standalone item reclassification journals and bin movements are legitimate separate operations, not completion of an existing transfer order. Tracking/application splits and average-cost handling mean transfers do not have one fixed item-entry count or a nonzero `"Transferred-from Entry No."` on every application.
|
||||
|
||||
See sample: [`post-transfers-through-shipment-and-receipt-codeunits.good.al`](post-transfers-through-shipment-and-receipt-codeunits.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report ad-hoc item postings, independent positive/negative adjustments, manually created posted-transfer rows, or changes to source shipment/receipt counters used to stand in for transfer-order posting. Updating `"Last Shipment No."` after a bare item-journal call does not create the posted shipment, source-line progress, or transfer application lineage.
|
||||
Ad-hoc item postings, independent positive/negative adjustments, manually created posted-transfer rows, and direct shipment/receipt-counter changes cannot substitute for transfer-order posting. Updating `"Last Shipment No."` after a bare item-journal call does not create the posted shipment, source-line progress, or transfer application lineage.
|
||||
|
||||
Do not repair this by changing an existing item ledger entry's location or inventing application links. Route the source transaction through its owning shipment/receipt or configured direct-transfer workflow. Metadata enrichment inside that workflow is not itself a posting bypass.
|
||||
Changing an existing item ledger entry's location or inventing application links does not repair that missing workflow. Metadata enrichment within the normal shipment/receipt or direct-transfer workflow is distinct from replacing the posting operation.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`post-transfers-through-shipment-and-receipt-codeunits.bad.al`](post-transfers-through-shipment-and-receipt-codeunits.bad.al)
|
||||
- [`post-transfers-through-shipment-and-receipt-codeunits.good.al`](post-transfers-through-shipment-and-receipt-codeunits.good.al)
|
||||
See sample: [`post-transfers-through-shipment-and-receipt-codeunits.bad.al`](post-transfers-through-shipment-and-receipt-codeunits.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Item;
|
||||
using Microsoft.Inventory.Journal;
|
||||
using Microsoft.Inventory.Location;
|
||||
using Microsoft.Warehouse.Journal;
|
||||
|
||||
codeunit 50110 "SCM Warehouse Adjustment Bad"
|
||||
{
|
||||
procedure ReconcileRegisteredWarehouseAdjustment(ItemNo: Code[20]; LocationCode: Code[10]; TemplateName: Code[10]; BatchName: Code[10]; PostingDate: Date; DocumentNo: Code[20]): Boolean
|
||||
|
|
|
|||
|
|
@ -1,11 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Item;
|
||||
using Microsoft.Inventory.Journal;
|
||||
using Microsoft.Inventory.Location;
|
||||
using Microsoft.Inventory.Posting;
|
||||
using Microsoft.Warehouse.Journal;
|
||||
|
||||
codeunit 50111 "SCM Warehouse Adjustment Good"
|
||||
{
|
||||
procedure ReconcileRegisteredWarehouseAdjustment(ItemNo: Code[20]; LocationCode: Code[10]; TemplateName: Code[10]; BatchName: Code[10]; PostingDate: Date; DocumentNo: Code[20]): Boolean
|
||||
|
|
|
|||
|
|
@ -15,24 +15,23 @@ At a Directed Put-away and Pick location, registering an ordinary warehouse quan
|
|||
|
||||
## Best Practice
|
||||
|
||||
After the warehouse adjustment has been registered, run `"Calculate Whse. Adjustment"` for the intended item/location and prepared item-journal batch, then post the generated lines through `"Item Jnl.-Post Batch"`. The calculation derives the reconciliation by location, variant, units of measure, and tracking, marks the lines `"Warehouse Adjustment"`, and accounts for already prepared unposted adjustments.
|
||||
After warehouse registration, `"Calculate Whse. Adjustment"` prepares item-journal lines for the intended item/location and batch; `"Item Jnl.-Post Batch"` posts those lines. The calculation derives the reconciliation by location, variant, units of measure, and tracking, marks the lines `"Warehouse Adjustment"`, and accounts for already prepared unposted adjustments.
|
||||
|
||||
Keep reconciliation separate from source-document posting: warehouse receipts/shipments use their document workflows. Intentional warehouse-only staging is valid when a separately owned reconciliation step completes the process; do not flag the registration call just because that later job is outside the diff.
|
||||
Reconciliation is separate from source-document posting: warehouse receipts/shipments use their document workflows. Intentional warehouse-only staging is valid when a separately owned reconciliation step completes the process; registration need not perform both phases in one call.
|
||||
|
||||
Do not generalize this rule to every warehouse operation. Bin movements need not change total inventory, and warehouse tracking/expiration reclassification has a standard batch path that can also post item-journal entries. Standard reclassification and basic-location item adjustments are not this ordinary advanced-warehouse quantity-adjustment case.
|
||||
Bin movements need not change total inventory, and warehouse tracking/expiration reclassification has a standard batch path that can also post item-journal entries. Standard reclassification and basic-location item adjustments are not this ordinary advanced-warehouse quantity-adjustment case.
|
||||
|
||||
The samples start after warehouse quantity registration and report whether inventory reconciliation completed. The clean sample calculates and posts into an empty dedicated batch; it is not a complete warehouse physical-count workflow.
|
||||
|
||||
See sample: [`reconcile-warehouse-adjustments-with-the-item-ledger.good.al`](reconcile-warehouse-adjustments-with-the-item-ledger.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report a workflow that claims to reconcile a registered advanced-warehouse quantity adjustment by posting a manually mirrored ordinary item-journal line, or that marks reconciliation complete after only warehouse registration or adjustment calculation. Calculation prepares journal lines; it does not post those lines. Require explicit synchronization intent and location/workflow evidence.
|
||||
A manually mirrored ordinary item-journal line does not reconcile a registered advanced-warehouse quantity adjustment. Likewise, a reconciliation function that returns completion after only registration or adjustment calculation leaves any generated adjustment lines unposted. Calculation prepares journal lines; it does not post them.
|
||||
|
||||
Do not repair the defect by inventing positive/negative quantities or flipping `"Warehouse Adjustment"` on an arbitrary line. Use the calculation step so the adjustment-bin balance and the actual tracked quantities drive inventory reconciliation.
|
||||
Invented positive/negative quantities or flipping `"Warehouse Adjustment"` on an arbitrary line does not establish the required relationship to the adjustment-bin balance and tracked quantities. That relationship comes from the calculation step.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`reconcile-warehouse-adjustments-with-the-item-ledger.bad.al`](reconcile-warehouse-adjustments-with-the-item-ledger.bad.al)
|
||||
- [`reconcile-warehouse-adjustments-with-the-item-ledger.good.al`](reconcile-warehouse-adjustments-with-the-item-ledger.good.al)
|
||||
See sample: [`reconcile-warehouse-adjustments-with-the-item-ledger.bad.al`](reconcile-warehouse-adjustments-with-the-item-ledger.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Tracking;
|
||||
using Microsoft.Sales.Document;
|
||||
|
||||
codeunit 50108 "SCM Tracking Transfer Bad"
|
||||
{
|
||||
procedure TransferBlanketOrderTracking(var SourceBlanketOrderLine: Record "Sales Line"; var DestinationSalesOrderLine: Record "Sales Line"; QuantityBaseToTransfer: Decimal)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Sales.Document;
|
||||
|
||||
codeunit 50109 "SCM Tracking Transfer Good"
|
||||
{
|
||||
procedure TransferBlanketOrderTracking(var SourceBlanketOrderLine: Record "Sales Line"; var DestinationSalesOrderLine: Record "Sales Line"; QuantityBaseToTransfer: Decimal)
|
||||
|
|
|
|||
|
|
@ -15,22 +15,21 @@ Moving lot/serial tracking between document lines is a source-ownership operatio
|
|||
|
||||
## Best Practice
|
||||
|
||||
Use the reservation codeunit for the source workflow. For the tracking portion of blanket-sales-order or quote conversion to a sales order, `"Sales Line-Reserve".TransferSaleLineToSalesLine` takes the existing source line, prepared destination line, and quantity to transfer in **base units**. It delegates the source/status and quantity movement to `"Create Reserv. Entry".TransferReservEntry`.
|
||||
Reservation codeunits provide source-specific tracking workflows. For the tracking portion of blanket-sales-order or quote conversion to a sales order, `"Sales Line-Reserve".TransferSaleLineToSalesLine` takes the existing source line, prepared destination line, and quantity to transfer in **base units**. It delegates the source/status and quantity movement to `"Create Reserv. Entry".TransferReservEntry`.
|
||||
|
||||
The caller still owns document conversion and destination-line preparation; this method does not create a sales order. Keep item, variant, location, and source identity consistent, and use other source-specific wrappers for purchases, transfers, assembly, or production instead of reusing a sales wrapper indiscriminately.
|
||||
The caller still owns document conversion and destination-line preparation; this method does not create a sales order. The source and destination must have compatible item, variant, location, and source identity. Purchases, transfers, assembly, and production have their own source-specific wrappers rather than sharing the sales conversion contract.
|
||||
|
||||
`"Item Tracking Management".CopyItemTracking` serves a different purpose: it creates Prospect copies, not a transfer of reservation ownership. That is valid for its intended copy workflow. Temporary Tracking Specification processing is also normal, and persisted historical tracking specifications are not forbidden; distinguish the working/historic representation from the current source booking.
|
||||
`"Item Tracking Management".CopyItemTracking` serves a different purpose: it creates Prospect copies, not a transfer of reservation ownership. That is valid for its intended copy workflow. Temporary Tracking Specification processing and persisted historical tracking specifications are also normal; the working/historic representation differs from the current source booking.
|
||||
|
||||
See sample: [`transfer-item-tracking-through-source-reservation-codeunits.good.al`](transfer-item-tracking-through-source-reservation-codeunits.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report direct rewrites of persistent `"Reservation Entry"` source type/subtype, ID, reference number, or quantities to implement source-line conversion or a partial tracking transfer. Changing only `"Quantity (Base)"` and source keys can drop the remainder or leave the other tracking/reservation quantities attached to the wrong source.
|
||||
Direct rewrites of persistent `"Reservation Entry"` source type/subtype, ID, reference number, or quantities do not perform the source-line conversion or partial tracking-transfer workflow. Changing only `"Quantity (Base)"` and source keys can drop the remainder or leave the other tracking/reservation quantities attached to the wrong source.
|
||||
|
||||
Also report use of a tracking copy as a replacement for moving an existing binding reservation when that intent is explicit. Do not flag a legitimate Prospect copy, temporary tracking buffer, historical tracking read, or source-specific engine call merely because it uses these tables.
|
||||
A tracking copy cannot replace movement of an existing binding reservation. Legitimate Prospect copying, temporary tracking buffers, historical tracking reads, and source-specific engine calls serve distinct purposes and are not independent reservation transfers.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`transfer-item-tracking-through-source-reservation-codeunits.bad.al`](transfer-item-tracking-through-source-reservation-codeunits.bad.al)
|
||||
- [`transfer-item-tracking-through-source-reservation-codeunits.good.al`](transfer-item-tracking-through-source-reservation-codeunits.good.al)
|
||||
See sample: [`transfer-item-tracking-through-source-reservation-codeunits.bad.al`](transfer-item-tracking-through-source-reservation-codeunits.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Inventory.Item;
|
||||
|
||||
codeunit 50114 "SCM Additional Promise Bad"
|
||||
{
|
||||
procedure CanPromiseAdditionalDemand(ItemNo: Code[20]; LocationCode: Code[10]; VariantCode: Code[10]; ShipmentDate: Date; RequestedAdditionalQuantityBase: Decimal; LookaheadDateFormula: DateFormula): Boolean
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
namespace BCQuality.SCM.Samples;
|
||||
|
||||
using Microsoft.Foundation.Enums;
|
||||
using Microsoft.Inventory.Availability;
|
||||
using Microsoft.Inventory.Item;
|
||||
|
||||
codeunit 50115 "SCM Additional Promise Good"
|
||||
{
|
||||
procedure CanPromiseAdditionalDemand(ItemNo: Code[20]; LocationCode: Code[10]; VariantCode: Code[10]; ShipmentDate: Date; RequestedAdditionalQuantityBase: Decimal; LookaheadDateFormula: DateFormula): Boolean
|
||||
|
|
|
|||
|
|
@ -15,22 +15,21 @@ application-area: [all]
|
|||
|
||||
## Best Practice
|
||||
|
||||
For an additional demand not already recorded on a source line, use `"Available to Promise".CalcQtyAvailableToPromise` with the Item's location/variant filters, date range ending on the shipment date, and the configured period/lookahead horizon. Compare in base units. Use a fresh calculation context or the codeunit's recalculation support rather than carrying cached quantities between unrelated items or requests.
|
||||
For additional demand not already recorded on a source line, `"Available to Promise".CalcQtyAvailableToPromise` uses the Item's location/variant filters, date range ending on the shipment date, and configured period/lookahead horizon. Its result and the additional quantity are compared in base units. A fresh calculation context or the codeunit's recalculation support avoids carrying cached quantities between unrelated items or requests.
|
||||
|
||||
For an existing sales-line change, retain the source-aware order-promising/availability workflow, which accounts for the line's own quantity or delta; blindly applying an additional-demand calculation can double-count that line. Assembly and production requirements/supply likewise need the standard availability context, not just a sales-only stock subtraction.
|
||||
The source-aware order-promising/availability workflow accounts for an existing sales line's own quantity or delta; applying an additional-demand calculation to that line can double-count it. Assembly and production requirements/supply likewise participate in the standard availability context, not just a sales-only stock subtraction.
|
||||
|
||||
An ATP result is not a reservation or a guarantee of warehouse pickability. Lot/serial constraints, bins, warehouse activity, and later concurrent changes still need their own checks. Conversely, an on-hand display, valuation report, or deliberately immediate-stock-only check is allowed to use `Item.Inventory`; do not replace its distinct business question with ATP.
|
||||
An ATP result is not a reservation or a guarantee of warehouse pickability. Lot/serial constraints, bins, warehouse activity, and later concurrent changes still need their own checks. Conversely, an on-hand display, valuation report, or deliberately immediate-stock-only check can use `Item.Inventory`: it answers a different business question from ATP.
|
||||
|
||||
See sample: [`use-date-aware-availability-for-promising.good.al`](use-date-aware-availability-for-promising.good.al).
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
Report `CalcFields(Inventory)` or an equivalent sum of item ledger quantities used as the complete decision for a dated additional-demand promise, including code that applies location/variant filters but ignores other demand and supply. Require explicit promising intent; an Inventory FlowField read alone is not a finding.
|
||||
`CalcFields(Inventory)` or an equivalent item-ledger quantity sum used as the complete decision for a dated additional-demand promise ignores existing demand and incoming supply, even with location/variant filters. An Inventory FlowField read for an on-hand display has no such promising contract.
|
||||
|
||||
Also report a visible loss of location, variant, date, or source-line context in that calculation. Do not invent missing demand in an unseen caller or require this exact API when a visible supported workflow already supplies the correct availability semantics.
|
||||
Losing location, variant, date, or source-line context changes the calculation's business meaning. Another supported workflow that preserves the same availability semantics does not have to call this exact API.
|
||||
|
||||
## Samples
|
||||
|
||||
- [`use-date-aware-availability-for-promising.bad.al`](use-date-aware-availability-for-promising.bad.al)
|
||||
- [`use-date-aware-availability-for-promising.good.al`](use-date-aware-availability-for-promising.good.al)
|
||||
See sample: [`use-date-aware-availability-for-promising.bad.al`](use-date-aware-availability-for-promising.bad.al).
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -15,77 +15,57 @@ application-area: [all]
|
|||
# AL Supply Chain Management review
|
||||
|
||||
Reviews AL source against the `scm` knowledge domain. This leaf invokes no
|
||||
sub-skills and is composed by `al-code-review`. It accepts diffs, individual
|
||||
files, and complete app folders; for a folder, inspect every relevant AL file,
|
||||
not a representative sample. A folder supplies no historical baseline.
|
||||
sub-skills and is composed by `al-code-review`. For a folder, inspect every
|
||||
relevant AL file; a folder supplies no historical baseline.
|
||||
|
||||
## Source
|
||||
|
||||
Apply the source-surface gate in Relevance before retrieving knowledge. If the
|
||||
gate passes, use READ's **Bounded retrieval for review skills** workflow with
|
||||
`-Domain scm` and `-Technologies @('al')`. Consume every catalog page across
|
||||
enabled layers, preserving exact paths, complete keywords, applicability, and
|
||||
unknown dimensions. Select articles using catalog metadata only; never use an
|
||||
index row as the basis for a finding.
|
||||
|
||||
Entry owns index preparation. Do not rebuild the index in this leaf. When a
|
||||
helper or prepared index is unavailable or invalid, follow READ's explicit
|
||||
path-discovery and bounded native-read fallback through EOF. A retrieval
|
||||
failure is not an empty or clean review.
|
||||
Apply Relevance's source gate before retrieval. For a relevant scope, use READ's
|
||||
**Bounded retrieval for review skills** with `-Domain scm` and
|
||||
`-Technologies @('al')`. Consume every catalog page across enabled layers,
|
||||
preserving exact paths and applicability. Select from metadata, then read only
|
||||
worklisted complete articles. Entry owns index preparation; the leaf does not
|
||||
rebuild. Unavailable/invalid helpers or indexes use READ's bounded native-read
|
||||
fallback, never a success-shaped empty result.
|
||||
|
||||
## Relevance
|
||||
|
||||
First inspect the supplied scope for an SCM source surface: a changed
|
||||
procedure, trigger, subscriber, or bound action that writes or posts inventory,
|
||||
cost, application, reservation, tracking, warehouse, transfer, or planning
|
||||
state, or calculates availability for a supply/demand decision. Resolve record
|
||||
and codeunit declarations, source tables, event publishers, and nearby calls
|
||||
within the supplied scope. Do not infer object identity from a variable name.
|
||||
Resolve changed record/codeunit types, source tables, publishers and calls.
|
||||
Gate on code that mutates or posts inventory, application, reservation,
|
||||
tracking, warehouse, transfer or planning state, or makes a supply/demand
|
||||
availability decision. Stock displays and other read-only queries without
|
||||
that decision do not pass the gate. Names, comments, captions, an `Item`
|
||||
reference or a broad `ApplicationArea` alone are not signals.
|
||||
If no SCM surface remains, return `not-applicable` with zero coverage
|
||||
and no article-body retrieval; in mixed diffs, retain only relevant procedures
|
||||
and their visible supporting context.
|
||||
|
||||
An `Item` reference, a field caption, an unrelated ledger read, an object name
|
||||
containing "warehouse", or a broad `ApplicationArea` alone does not pass this
|
||||
gate. Comments and display strings are not execution evidence. When no source
|
||||
surface passes, return `not-applicable` with zero coverage and no article-body
|
||||
reads. In a mixed diff, worklist only the relevant procedures and their visible
|
||||
supporting context, not every AL file in the app. Unknown application areas do
|
||||
not by themselves exclude codeunits or subscribers.
|
||||
SCM owns `"Item Ledger Entry"`, `"Value Entry"`, `"Capacity Ledger Entry"`,
|
||||
`"Warehouse Entry"` and inventory posting/application records. Pure `"G/L Entry"`,
|
||||
`"Cust. Ledger Entry"`, `"Vendor Ledger Entry"`, `"Detailed Cust. Ledg. Entry"`,
|
||||
`"Detailed Vendor Ledg. Entry"`, `"VAT Entry"` and financial-only posting
|
||||
mutations belong to Finance. They remain outside SCM even if Finance is absent
|
||||
or disabled; do not reclaim them as SCM agent findings. Ownership is not a
|
||||
claim that every owned surface already has a dedicated article.
|
||||
|
||||
For candidates, apply READ's frontmatter matching semantics:
|
||||
|
||||
- `bc-version`: the target BC major version from application dependency or
|
||||
host context, not the extension's own version; otherwise unknown.
|
||||
- `technologies`: AL.
|
||||
- `countries`: the known target localization or host context; otherwise
|
||||
unknown, not a guess based on the developer's language.
|
||||
- `application-area`: the actual known task/object areas, not a substituted
|
||||
`[all]`. Use explicit inventory, warehousing, assembly, manufacturing, or
|
||||
supply-chain context to narrow the relevant source, not as proof of a defect.
|
||||
|
||||
Discard nonmatching articles. Retain conditionally applicable articles only
|
||||
when configuration permits; cap their findings at `medium` confidence and
|
||||
name every unknown dimension in the message.
|
||||
Apply READ's frontmatter filters using the target BC major version from
|
||||
application dependency/host context (not the extension version), AL, known
|
||||
localization and actual task/object application areas. Omitted context stays
|
||||
unknown, not `[all]`; unknown areas alone do not exclude codeunits/subscribers.
|
||||
Retain conditional articles only when configured, cap their findings at
|
||||
`medium`, and name every unknown dimension.
|
||||
|
||||
## Worklist
|
||||
|
||||
Extract deterministic tokens from the gated source: resolved object/type
|
||||
names, quoted field names, methods, enum members, and called publishers.
|
||||
Lowercase invariantly, replace punctuation and whitespace runs with one hyphen,
|
||||
and trim leading/trailing hyphens. Thus `"Item Ledger Entry"` becomes
|
||||
`item-ledger-entry`, `"Qty. (Base)"` becomes `qty-base`, and `RunWithCheck`
|
||||
becomes `runwithcheck`. Apply the same normalization to catalog keywords.
|
||||
Match whole normalized tokens/phrases, not substrings such as `item` in an
|
||||
unrelated identifier. Do not manufacture synonyms that are not supported by
|
||||
the changed source or the targeted cues.
|
||||
Extract resolved object/type names, quoted fields, methods, enum members and
|
||||
publishers. Normalize these and catalog keywords by lowercasing invariantly,
|
||||
replacing punctuation/whitespace runs with one hyphen and trimming hyphens:
|
||||
`"Item Ledger Entry"` becomes `item-ledger-entry`; `RunWithCheck` becomes
|
||||
`runwithcheck`. Match whole tokens/phrases, not identifier substrings.
|
||||
|
||||
Select a catalog row only when a keyword intersects these tokens, or its
|
||||
path/title/description identifies the same gated source surface **and
|
||||
operation**. Object declarations establish context; field assignments, calls,
|
||||
and decision logic establish the operation to evaluate. A shared table name
|
||||
does not select every rule using that table.
|
||||
|
||||
Use these targeted candidate-selection cues, resolving each slug to its
|
||||
actual enabled catalog paths. They select articles to read, not findings to
|
||||
emit; all platform reasoning and exceptions remain in those articles.
|
||||
Select matching keywords or catalog topics only for the same source surface
|
||||
**and operation**. The following cues resolve slugs to actual enabled catalog
|
||||
paths; they select articles, not findings. Facts and exceptions stay in articles.
|
||||
|
||||
| Changed source surface and operation | Article slug |
|
||||
| --- | --- |
|
||||
|
|
@ -99,115 +79,43 @@ emit; all platform reasoning and exceptions remain in those articles.
|
|||
| `Inventory`, `CalcQtyAvailableToPromise`, or stock sums used in a dated supply/demand promise, including changed location/variant/date filters and source-demand context | `use-date-aware-availability-for-promising` |
|
||||
| `"Requisition Line"` action-message execution, accepted planning suggestions, `"Req. Wksh.-Make Order"`, `CarryOutBatchAction`, or linked supply creation/change plus requisition-line deletion | `carry-out-requisition-actions-through-the-standard-workflow` |
|
||||
|
||||
Do not select a cue solely from a caption, comment, or unrelated declaration.
|
||||
Use the same gates for clean supported calls so their article exclusions are
|
||||
evaluated, not just suspicious writes. Applicability is never an anti-pattern.
|
||||
|
||||
Resolve normative conflicts per READ after reading the selected complete
|
||||
articles. Keep enabled-layer candidates additive unless guidance actually
|
||||
contradicts; do not deduplicate merely by filename. Record losing candidates
|
||||
in `suppressed` with `layer-precedence`, and configuration-hidden candidates
|
||||
with `configuration`. Noncandidates are not suppressions.
|
||||
|
||||
Order exact worklisted paths ordinally and retrieve complete bodies in stable
|
||||
chunks of at most eight, following every continuation within each chunk.
|
||||
Never turn the chunk size into a top-eight cutoff. Read samples only when
|
||||
needed, via their exact READ links and bounded sample retrieval.
|
||||
Route clean supported calls through the same cues, not just suspicious writes.
|
||||
Resolve actual normative conflicts per READ, preserving additive layers and
|
||||
recording `layer-precedence`/`configuration` suppressions, not noncandidates.
|
||||
Retrieve exact paths in ordinal chunks of at most eight, consume every
|
||||
continuation, and never impose a top-eight cutoff. Samples use exact READ links.
|
||||
|
||||
## Action
|
||||
|
||||
Evaluate the visible source against each opened article's normative Best
|
||||
Practice and Anti Pattern, including its scope and exclusions. Establish the
|
||||
record's persistence, caller contract, document type/state, and affected
|
||||
operation from evidence before reporting. Consult the article for treatment
|
||||
of temporary buffers, supported publisher parameters, managed posting paths,
|
||||
and legitimate read-only calculations; the skill itself defines no BC rule.
|
||||
Do not infer missing work in an unseen caller or report every use of a routed
|
||||
API. A supported alternative is not a defect.
|
||||
Evaluate every opened article's normative facts, scope and exclusions against
|
||||
visible persistence, caller contract, document state and operation. Emit only
|
||||
concrete violations with business consequences and supported remediation; a
|
||||
declaration, valid alternative or unseen caller is not evidence of a defect.
|
||||
|
||||
Emit only a concrete violation with its business consequence and supported
|
||||
remediation. Use `major` for a demonstrated material SCM defect, `minor` for
|
||||
a narrower best-practice conflict, and `blocker` only if the opened article
|
||||
establishes a violated platform-level guarantee. Relevance alone produces no
|
||||
finding. Deduplicate overlapping findings that prescribe the same correction;
|
||||
prefer the article that owns the specific operation and retain any other
|
||||
applicable article as a supporting reference.
|
||||
- Use `major` for material SCM defects, `minor` for narrower best-practice
|
||||
conflicts, and `blocker` only for an article-established platform guarantee.
|
||||
Applicability alone produces no finding. High confidence requires unambiguous
|
||||
evidence and known applicability; inference/conditional applicability caps it
|
||||
at `medium`.
|
||||
- Apply DO's single-owner deduplication. Equivalent findings for the same
|
||||
inventory-originated posting bypass and correction have one SCM primary
|
||||
owner, even when financial records are downstream. Prefer the most specific
|
||||
SCM article and retain other applicable references as supporting evidence.
|
||||
Distinct independent financial defects remain Finance; do not duplicate them.
|
||||
- Agent findings stay strictly SCM-scoped under DO's precision bar, with
|
||||
`references: []`, an `agent:` id and `minor`/`medium` ceilings. Generic AL and
|
||||
other domains' concerns remain outside this leaf.
|
||||
- Supply literal `suggested-code` only for a complete, local, unambiguous fix,
|
||||
not a sample call that omits workflow setup/source identity. Explain omitted
|
||||
mechanical-looking fixes with `suggested-code-omission-reason`.
|
||||
|
||||
Copy `findings[].id` verbatim from the primary article's exact catalog path;
|
||||
it must equal `references[0].path`. Cite only complete articles actually read.
|
||||
Use `high` confidence only for unambiguous source evidence with known
|
||||
applicability, `medium` for justified inference or conditional applicability.
|
||||
Never label a guessed API signature or missing workflow context high confidence.
|
||||
|
||||
Agent findings are optional and strictly SCM-scoped. Follow DO's precision
|
||||
bar: concrete, material defects only, with `references: []`, an `agent:` id,
|
||||
severity at most `minor`, and confidence at most `medium`. Omit generic AL,
|
||||
style, performance, privacy, and unrelated technical findings owned by other
|
||||
leaves. Do not invent a finding to compensate for an empty worklist.
|
||||
|
||||
For an unambiguous local fix, supply literal replacement AL in
|
||||
`suggested-code`, with a location range covering exactly those lines. Do not
|
||||
replace an entire business workflow with a sample call that omits the
|
||||
caller's setup, filters, source identity, or validations. When a mechanical-
|
||||
looking fix cannot be expressed safely, give `suggested-code-omission-reason`.
|
||||
|
||||
Outcomes follow DO: `completed` after evaluating the complete worklist,
|
||||
including a clean result; `not-applicable` when the source gate fails;
|
||||
`no-knowledge` when no applicable corpus survives filtering/configuration;
|
||||
`partial` when only part of the worklist was evaluated; `failed` when no
|
||||
reliable result can be produced. A source match with no matching article is
|
||||
`completed` with an empty worklist, not a claimed evaluation of every SCM
|
||||
concern. Explain partial/failed results and report accurate coverage.
|
||||
Outcome selection follows DO, including accurate coverage and reasons for
|
||||
`partial`/`failed`. No surviving applicable corpus is `no-knowledge`; an existing
|
||||
corpus with no matching operation is `completed` with an empty worklist.
|
||||
|
||||
## Output
|
||||
|
||||
Return one strict JSON findings-report per DO and
|
||||
`schemas/findings-report.schema.json`, with no surrounding prose. Every
|
||||
finding, including an agent finding, must have
|
||||
`domain: "Supply Chain Management"`. Do not set `from-sub-skill` in a leaf
|
||||
report; the coordinator adds it. All locations must identify existing lines
|
||||
in the supplied source, and any range must start at `location.line`.
|
||||
|
||||
A knowledge-backed finding with an exact article id:
|
||||
|
||||
```json
|
||||
{
|
||||
"skill": { "id": "al-scm-review", "version": 1 },
|
||||
"outcome": "completed",
|
||||
"summary": {
|
||||
"counts": { "blocker": 0, "major": 1, "minor": 0, "info": 0 },
|
||||
"coverage": { "worklist-size": 1, "items-evaluated": 1 }
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"id": "microsoft/knowledge/scm/cancel-reservations-through-reservation-management.md",
|
||||
"severity": "major",
|
||||
"message": "This cancellation deletes only the negative reservation row. Use Reservation Engine Mgt. cancellation so counterpart and surviving tracking are handled by the owning workflow.",
|
||||
"location": { "file": "src/CancelReservation.Codeunit.al", "line": 16 },
|
||||
"references": [
|
||||
{ "path": "microsoft/knowledge/scm/cancel-reservations-through-reservation-management.md" }
|
||||
],
|
||||
"confidence": "high",
|
||||
"domain": "Supply Chain Management",
|
||||
"suggested-code-omission-reason": "The replacement also requires a codeunit declaration outside the reported line."
|
||||
}
|
||||
],
|
||||
"suppressed": []
|
||||
}
|
||||
```
|
||||
|
||||
An unrelated AL change, excluded before article retrieval:
|
||||
|
||||
```json
|
||||
{
|
||||
"skill": { "id": "al-scm-review", "version": 1 },
|
||||
"outcome": "not-applicable",
|
||||
"outcome-reason": "The supplied AL changes contain no SCM posting, state mutation, or supply/demand availability surface.",
|
||||
"summary": {
|
||||
"counts": { "blocker": 0, "major": 0, "minor": 0, "info": 0 },
|
||||
"coverage": { "worklist-size": 0, "items-evaluated": 0 }
|
||||
},
|
||||
"findings": [],
|
||||
"suppressed": []
|
||||
}
|
||||
```
|
||||
Output conforms to the DO findings-report contract and shared schema. Every
|
||||
finding MUST set `domain` to `"Supply Chain Management"`. Knowledge-backed ids
|
||||
equal the primary opened article's exact catalog path. The coordinator, not
|
||||
this leaf, sets `from-sub-skill`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue