mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 06:36:55 +01:00
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate skill index and report schemas / validate-contract (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
* Add 5 AL/BC patterns: document distribution (Report Selections, Document Sending Profile, Find Entries, TransferFields) Five rules about Business Central's document distribution architecture, verified against BCApps source and Microsoft Learn. - custom-document-dispatch-must-not-bypass-report-selections - document-print-and-email-actions-call-report-selections-directly - extend-find-entries-navigate-for-new-document-types - extend-report-selection-usage-for-new-document-types - transferfields-mirrored-fields-must-match-type-and-length Wired into al-data-modeling-review.md's worklist cues. Added a disambiguation note on the TransferFields article distinguishing it from the existing transferfields-skip-type-mismatch-can-drop-data.md (type-mismatch skipping vs. length mismatch, which SkipFieldsNotMatchingType does not affect). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix four merge-critical blockers from Jesper's review; add 4 more patterns Addresses microsoft/BCQuality#175 review feedback: - Extend al-data-modeling-review's entry gate/relevance scope and token list to recognize document actions, Navigate subscribers, Report Selection registration, price-calculation/price-source extensibility, TransferFields posting-cascade mirroring, and barcode font-provider usage - previously excluded before any worklist cue could run. - Fix document-print-and-email-actions-call-report-selections-directly: permit the legitimate stateless DocumentSendingProfile.TrySendToPrinter/ TrySendToEMail path; rework the bad fixture to load a configured profile instead of demonstrating a trivial blank-record no-op. - Fix extend-report-selection-usage-for-new-document-types: scope to the applicable single counterparty (ReportSelectionHandlerCZZ partitions strictly; only genuinely two-sided usages like Compensation need both), and add the page-facing usage-enum map/validate events alongside the filter-event subscription for full Document Layouts support. - Fix a stale field-citation in custom-document-dispatch-must-not-bypass- report-selections (Custom Report Layout Code is field 7, not part of the 19-26 email-configuration range). - Add deterministic positive/clean evaluation coverage (review-fixtures.json additionalArticles + Test-ReviewFixtures.ps1 support) so all 9 new good/bad pairs are actually exercised, not just present. - Add 4 new patterns: activate-new-price-calculation-handler-via- onfindsupportedsetup, extend-price-source-type-must-sync-document- subset-enum, new-price-source-must-add-candidate-and-trigger- recalculation, report-barcodes-must-use-barcode-module-and-production- font-name. All claims verified against live microsoft/BCApps source and Microsoft Learn. Validators: frontmatter 0/0, review-fixtures 52 cases/17 domains PASSED, knowledge-index 309 articles PASSED. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix 5 merge-critical issues from Jesper's 2026-09-24 review round - activate-new-price-calculation-handler-via-onfindsupportedsetup: Default := true is required only for the fallback branch of PriceCalculationMgt's two-stage FindSetup - a handler reachable via a specific Dtld. Price Calculation Setup row needs no Default. Softened the article and its worklist cue accordingly. Also fixed an undefined "Sample Price Calc - Special" codeunit referenced but never declared in the eval fixtures - added a real implementation of interface "Price Calculation" with stub methods. - new-price-source-must-add-candidate-and-trigger-recalculation: the good fixture called UpdateUnitPriceByField directly, which is a silent no-op without a prior PlanPriceCalcByField call (FieldCausedPriceCalculation gating, verified against SalesLine.Table.al). Switched to the public UpdateUnitPrice wrapper, matching real BCApps usage in ItemReferenceManagement.Codeunit.al. - report-barcodes-must-use-barcode-module-and-production-font-name: split the 1D (ValidateInput + EncodeFont) and 2D (EncodeFont only) Barcode Font Provider interfaces, which the article previously conflated. Reframed the Code 39 anti-pattern around demonstrable encoding/checksum mismatch (verified against IDA1DCode39Encoder.Codeunit.al's real '(value)' output) rather than rejecting all manual delimiter use, since '*' is a legitimate Code 39 start/stop character. Also fixed extend-find-entries-navigate- for-new-document-types' eval fixtures, which referenced an undefined "Sample Posted Document Header" table/page - declared both. All claims re-verified against live microsoft/BCApps source. Validators: frontmatter 0/0, review-fixtures 126/20 domains PASSED, knowledge-index 342/575 PASSED, skill-index 19 leaves PASSED. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Align price-source and barcode routing cues with corrected articles - Price-source cue now accepts UpdateUnitPrice, or the explicit PlanPriceCalcByField + UpdateUnitPriceByField sequence; bare UpdateUnitPriceByField does not count. Both APIs added to tokens. - Barcode cue no longer flags manual delimiters as a category; routes only demonstrably invalid/provider-font-mismatched hand encoding, and requires ValidateInput + EncodeFont for 1D, EncodeFont only for 2D. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Make barcode bad fixture self-contained: 1D EncodeFont without ValidateInput The previous bad fixture (literal '*' delimiters, no layout/font/provider evidence) no longer matched the narrowed routing cue. It now shows an IDAutomation 1D provider path that calls EncodeFont without ValidateInput, which is visible in AL alone. Article Anti Pattern and Source updated to describe this variant (verified: IDAutomation 1D Provider's EncodeFont does not call IsValidInput). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fix three merge-critical items from Jesper's 2026-09-29 review - Barcode: drop the false claim that '*value*' is mismatched with the IDAutomation Code 39 font; '*' is a documented start/stop form and '(' / ')' an accepted alternative. Cue and article now route only independently provable validation/checksum/font-binding defects. - Dispatch good samples (and matching bad samples) now pass a Sales Invoice Header with the S.Invoice usage, matching the record the selected report (1306 "Standard Sales - Invoice") expects. - custom-document-dispatch rule made disjunctive: a hardcoded report or a hand-built email is each a bypass on its own; scoped to customer/vendor-facing documents. Bad fixture shows the hardcoded report alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Clarify TrySendToEMail comment in print/email good sample Make explicit that TrySendToEMail is also correct *because* it never reads the customer's assigned profile (local record, E-Mail option set by the helper itself), and name Get/GetDefaultForCustomer + Send as the anti-pattern. Matches the article's Best Practice and BaseApp's own Sales Invoice Header.EmailRecords. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
99 lines
5.2 KiB
Markdown
99 lines
5.2 KiB
Markdown
---
|
|
bc-version: [all]
|
|
domain: data-modeling
|
|
keywords: [barcode, qr-code, barcode-font-provider, barcode-font-provider-2d, report-layout, saas, idautomation, code-39, checksum]
|
|
technologies: [al]
|
|
countries: [w1]
|
|
application-area: [all]
|
|
---
|
|
|
|
# Generate report barcodes through the Barcode module, with the production font name
|
|
|
|
## Description
|
|
|
|
Business Central's barcode support lives in the System Application's
|
|
`Barcode` module (`src/System Application/App/Barcode`): `interface
|
|
"Barcode Font Provider"` / `"Barcode Font Provider 2D"`, `enum "Barcode
|
|
Symbology"` / `"Barcode Symbology 2D"`, and built-in implementations
|
|
(`codeunit 9215`/`9221`). A report encodes a data string via this API;
|
|
the layout then displays it using a barcode *font*.
|
|
|
|
The two interfaces are not symmetric: `"Barcode Font Provider"` (1D)
|
|
declares both `ValidateInput` and `EncodeFont`; `"Barcode Font Provider
|
|
2D"` declares only `EncodeFont` (see Source). BCApps' `Item GTIN Label`
|
|
report reflects that split exactly — it validates then encodes through
|
|
the 1D provider, but only encodes through the 2D provider, for the same
|
|
"No." value.
|
|
|
|
On Business Central online this needs no setup ("the IDAutomation fonts
|
|
are automatically available as part of the service" — Microsoft Learn),
|
|
unlike on-premises, where fonts must be purchased and installed. That
|
|
ease hides a SaaS-specific trap the API doesn't cover: naming the actual
|
|
font. IDAutomation ships both a purchased font and a same-looking
|
|
evaluation font per version (Code 39: `IDAutomationHC39M` purchased vs.
|
|
`IDAutomationSHC39M Demo`) — per Microsoft Learn, "be sure to use the
|
|
purchased font name... If you use the evaluation font name, the barcode
|
|
won't render." The wrong name produces nothing, in the layout not AL, so
|
|
no reviewer catches it reading the object.
|
|
|
|
## Best Practice
|
|
|
|
Encode through the real API, matching the calls to what the chosen
|
|
interface actually declares. One-dimensional: declare `Interface
|
|
"Barcode Font Provider"` and call both `ValidateInput` and `EncodeFont`
|
|
— skipping validation lets a value outside the character set, or one
|
|
needing a checksum setting never applied, reach the font unchecked.
|
|
Two-dimensional: declare `Interface "Barcode Font Provider 2D"` and call
|
|
`EncodeFont` alone — there is no `ValidateInput` on this interface.
|
|
|
|
Treat naming the production font in the layout as equally required, not
|
|
an afterthought. Two-dimensional symbologies other than Maxicode use
|
|
`IDAutomation2D` (Maxicode: `IDAutomation2D MaxiCode`); one-dimensional
|
|
symbologies use the purchased version name (e.g. `IDAutomationHC39M` for
|
|
Code 39), never a name containing `Demo`.
|
|
|
|
See sample: [`report-barcodes-must-use-barcode-module-and-production-font-name.good.al`](report-barcodes-must-use-barcode-module-and-production-font-name.good.al).
|
|
|
|
## Anti Pattern
|
|
|
|
Constructing a barcode string by hand where that construction has a
|
|
concrete, independently provable defect: a source value that can contain
|
|
characters outside the symbology's character set is never validated, a
|
|
checksum the symbology or setup requires is never applied, or there is
|
|
concrete evidence of an incompatible font binding.
|
|
|
|
The delimiter itself is not the defect. `*value*` is a documented, valid
|
|
Code 39 form for IDAutomation fonts (Microsoft Learn's font table and
|
|
IDAutomation's own manual both give `*` as start/stop); the `(`/`)` that
|
|
IDAutomation 1D Provider's encoder emits (BCApps test:
|
|
`EncodeFont('1234', Code39) = '(1234)'`) is an alternative start/stop
|
|
form the same fonts accept, used to keep `*` out of the human-readable
|
|
text. Never flag delimiter choice alone.
|
|
|
|
The same validation gap exists when the module *is* used: a 1D path that
|
|
calls `EncodeFont` on `"Barcode Font Provider"` without `ValidateInput`
|
|
(IDAutomation 1D Provider's `EncodeFont` does not validate on its own).
|
|
The sample shows this variant, visible in AL alone. A last version:
|
|
encoding correctly but naming the evaluation font, which BC online
|
|
refuses to render.
|
|
|
|
See sample: [`report-barcodes-must-use-barcode-module-and-production-font-name.bad.al`](report-barcodes-must-use-barcode-module-and-production-font-name.bad.al).
|
|
|
|
## Source
|
|
|
|
BCApps (`src/System Application/App/Barcode/src/`):
|
|
`Barcode Provider/Font/BarcodeFontProvider.Interface.al` (1D:
|
|
`ValidateInput` + `EncodeFont`); `IDAutomation 1D Provider/
|
|
IDAutomation1DProvider.Codeunit.al` (`EncodeFont` goes straight to the
|
|
symbology encoder; only `ValidateInput` calls `IsValidInput`); `Barcode Provider 2D/Font/BarcodeFontProvider2D.Interface.al`
|
|
(2D: only `EncodeFont`). `IDAutomation 1D Provider/Encoders/IDA1DCode39Encoder.Codeunit.al`
|
|
(`codeunit 9204`, regex accepts literal `*`; `EncodeFont` → `DotNet FontEncoder.Code39`).
|
|
1D/2D split: `.../Inventory/Item/ItemGTINLabel.Report.al` (`report 6625`,
|
|
validates+encodes 1D, only encodes 2D). Encoder output form: `IDA1DCode39Test.Codeunit.al`
|
|
(`codeunit 135044`): `EncodeFontSuccessTest('1234', Code39, '(1234)')`.
|
|
|
|
Microsoft Learn "Adding Barcodes to Reports" and "Barcode Fonts with
|
|
Business Central Online" — quoted above, incl. the Code39 row ("`*` is
|
|
used for both start and stop delimiters"). IDAutomation, "Code 39 Font
|
|
User Manual" (https://idautomation.com/barcode-fonts/code-39/fontnames/):
|
|
`*` start/stop, or parentheses to keep `*` out of the human-readable text.
|