Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/Apps/W1/Quality Management/app/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Quality Management

A comprehensive quality inspection framework for Business Central. Enables organizations to define quality tests, group them into reusable templates, configure rules that auto-generate inspections from business transactions (purchase receipts, production output, assembly, warehouse, transfers), record measurement results, and take disposition actions on non-conforming items. Currently an early-access feature available to partners.

## Quick reference

- **ID range**: 20400--20600
- **Namespace**: `Microsoft.Inventory.QualityManagement` (and sub-namespaces)
- **Dependencies**: None (extends base application directly)
- **Experience**: Essential for most features; Premium required for production output inspections

## How it works

The app follows a multi-level configuration hierarchy. At the base are **Quality Tests** -- individual measurements or checks with a value type (decimal, integer, boolean, text, option, table lookup, text expression). Tests are grouped into **Quality Inspection Templates**, which define sampling strategies (fixed quantity or percentage). **Inspection Generation Rules** connect templates to business events with item/vendor/location filters, so inspections are auto-created when specific transactions occur.

When an inspection is created (automatically, manually, or on schedule), the system clones the template's tests into inspection lines. Each line records a measured value that is evaluated against **Result Conditions** -- configurable rules that map value ranges or expressions to result codes (PASS, FAIL, INPROGRESS, or custom). Results have an **Evaluation Sequence** that determines priority: the system picks the highest-priority matching result. Conditions can be overridden at three levels: test defaults, template overrides, and inspection-specific overrides.

The inspection integrates deeply with BC's item tracking system. Results can block or allow specific transaction types per lot/serial/package -- a FAIL result can block sales, transfers, picks, and movements while still allowing put-away to quarantine. The system supports re-inspections (numbered chain) and workflow integration for approval, lot blocking, and automated disposition actions.

After finishing an inspection, **Dispositions** handle non-conforming items: change item tracking codes, create negative adjustments (scrap), move inventory (quarantine), create purchase returns, warehouse put-aways, or transfer orders. These can be triggered manually or via workflow responses.

## Structure

- `src/Configuration/` -- Tests, templates, results, conditions, generation rules, lookup values (46 files, the config hierarchy)
- `src/Integration/` -- Event subscribers and page extensions that hook QM into BC domains: purchasing, production, assembly, warehouse, sales, transfers, item tracking (67 files)
- `src/Dispositions/` -- Post-inspection actions: item tracking changes, negative adjustments, inventory moves, purchase returns, warehouse put-aways, transfer orders (22 files)
- `src/Document/` -- Inspection header/line tables and card/list pages
- `src/Utilities/` -- Expression evaluation, value parsing, boolean parsing, source field traversal helpers
- `src/Workflow/` -- BC workflow integration (approval events, lot blocking responses)
- `src/Setup/` -- Global setup table, guided experience, application area registration
- `src/Reports/` -- Certificate of Analysis, non-conformance report, bulk creation/scheduling reports
- `src/RoleCenters/` -- Quality Manager role center and cue table

## Documentation

- [docs/data-model.md](docs/data-model.md) -- Inspection hierarchy, configuration tables, result evaluation, item tracking blocking
- [docs/business-logic.md](docs/business-logic.md) -- Inspection creation, result evaluation, finishing, re-inspection, dispositions
- [docs/extensibility.md](docs/extensibility.md) -- 28+ integration events for customizing inspections, results, and workflows
- [src/Configuration/docs/CLAUDE.md](src/Configuration/docs/CLAUDE.md) -- Test, template, and generation rule configuration
- [src/Integration/docs/CLAUDE.md](src/Integration/docs/CLAUDE.md) -- Per-domain BC integration hooks
- [src/Dispositions/docs/CLAUDE.md](src/Dispositions/docs/CLAUDE.md) -- Post-inspection disposition actions
- [src/Utilities/docs/CLAUDE.md](src/Utilities/docs/CLAUDE.md) -- Expression and value evaluation
- [src/Workflow/docs/CLAUDE.md](src/Workflow/docs/CLAUDE.md) -- Workflow integration

## Things to know

- **Three creation modes** -- automatic (event-driven from posting), manual (from document lines or standalone), and scheduled (job queue with generation rules). The "intent" on a generation rule determines which BC event triggers creation.
- **Three-level condition override** -- result conditions can be set at the test level (defaults), overridden at the template level, and overridden again at the inspection level. The most specific wins.
- **Evaluation sequence determines result** -- when multiple conditions match, the result with the lowest evaluation sequence number wins. This is how FAIL overrides PASS when both conditions are met.
- **RecordId-based source tracking** -- inspections store up to 5 RecordIds plus 10 custom fields for source tracking. This allows attaching inspections to any BC table without schema changes.
- **Item tracking blocking is per-transaction-type** -- a result can block sales but allow put-away (quarantine scenario). Nine independent boolean fields control this per result code.
- **Re-inspection is a numbered chain** -- each re-inspection increments `Re-inspection No.` on the same `No.`. Only the most recent re-inspection is flagged as active for transaction blocking.
- **Expression tests reference other lines** -- a test with `Test Value Type = Text Expression` can reference other line values via formulas, creating computed fields within an inspection.
- **Table Lookup tests** -- tests can reference any BC table/field for dropdown values, with configurable filters. This avoids hardcoding option lists.
- **Feature is early access** -- as of 2025/2026, available only in partner sandbox environments. Auto-installs on new environments; manual install from AppSource for existing ones.
- **`_Obsolete` note** -- there is no _Obsolete folder in this app; it's a clean, modern codebase.
91 changes: 91 additions & 0 deletions src/Apps/W1/Quality Management/app/docs/business-logic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Business logic

## Overview

The app's business logic covers four phases of the inspection lifecycle: creation (how inspections come into existence), execution (recording values and evaluating results), completion (finishing with validation), and disposition (acting on non-conforming items). The creation phase has three modes; the evaluation phase uses a condition-driven engine; dispositions generate downstream BC documents.

## Inspection creation

```mermaid
flowchart TD
A{Creation mode?} -->|Automatic| B[BC event fires]
A -->|Manual| C[User creates from document/standalone]
A -->|Scheduled| D[Job queue runs generation rules]
B --> E[Match generation rules]
D --> E
E --> F{Rule matches item/vendor/location?}
F -->|No| G[Skip]
F -->|Yes| H{Existing inspection?}
C --> H
H -->|Use existing| I[Return existing]
H -->|Create new| J[Create header from template]
H -->|Re-inspect| K[Increment re-inspection no.]
J --> L[Clone template lines as inspection lines]
K --> L
L --> M[Evaluate with default values]
M --> N[Trigger workflow if configured]
```

**Automatic creation** is triggered by event subscribers in the Integration module. Each domain (purchase, production, assembly, warehouse, transfer, sales return) has subscribers on posting codeunits that call `QltyInspectionCreate`. The generation rule's `Intent` + trigger enum determines which events fire.

**Manual creation** can be initiated from item tracking lines, document lines, or the template list page. The `QltyInspectionCreate` codeunit handles all modes.

**Scheduled creation** uses job queue entries linked to generation rules with a `Schedule Group`. The `QltyScheduleInspection` report iterates matching rules and creates inspections for applicable items.

The `Inspection Creation Option` on setup controls behavior when an inspection already exists: always create new, always re-inspect, use existing open, use any existing, or create re-inspection if finished.

## Result evaluation

The `QltyResultEvaluation` codeunit is the evaluation engine. When a test value changes on an inspection line:

1. **Parse the value** -- `QltyValueParsing` converts text input to the appropriate type (numeric, boolean, etc.)
2. **Match conditions** -- iterate `QltyIResultConditConf` records for this test/template/inspection, checking if the value satisfies each condition expression
3. **Apply evaluation sequence** -- the matching result with the lowest `Evaluation Sequence` wins
4. **Cascade to header** -- after all lines are evaluated, the header result is determined by the line with the lowest evaluation sequence among all line results

For **Text Expression** tests, `QltyExpressionMgmt` evaluates formulas that can reference other inspection line values, creating computed/derived measurements within an inspection.

Condition expressions support ranges (`10..20`), comparisons (`>=80`), lists (`RED|GREEN|BLUE`), and combinations. The `QltyBooleanParsing` codeunit handles complex boolean logic in condition strings.

## Finishing an inspection

Finishing validates several conditions:

- **Item tracking** -- if setup requires, lot/serial/package must be filled and (optionally) posted to inventory
- **Result blocking** -- results with `Finish Allowed = Do Not Allow Finish` prevent completion (e.g., INPROGRESS)
- **All lines evaluated** -- lines without a result may block depending on configuration

On finish: sets `Finished Date` and `Finished By User ID`, locks the record from further edits, triggers the `OnInspectionFinished` workflow event. Item tracking blocking rules from the result now take effect for downstream transactions.

## Re-inspection

When a re-inspection is needed, the system increments `Re-inspection No.` on a new header sharing the same `No.`. Source fields, template, and item tracking are copied from the prior inspection. Lines are re-cloned from the template with fresh default values. The `Most Recent Re-inspection` flag is set on the new header and cleared on the old one.

## Dispositions

Post-inspection actions for non-conforming items, handled by codeunits in the Dispositions module:

- **Item tracking change** (`QltyDispChangeTracking`) -- reclassify lot/serial/package numbers
- **Negative adjustment** (`QltyDispNegAdjustInv`) -- create item journal lines for scrap/waste
- **Inventory move** (`QltyDispMoveItemReclass` / `QltyDispMoveWhseReclass`) -- transfer to quarantine bin or rework location via reclassification journal
- **Purchase return** (`QltyDispPurchaseReturn`) -- create purchase return order to send back to vendor
- **Warehouse put-away** (`QltyDispWarehousePutAway`) -- direct to rework/quarantine bin
- **Transfer order** (`QltyDispCreateTransferOrder`) -- move to another location (external lab, rework center)

These can be triggered manually from the inspection card or automatically via workflow responses when an inspection finishes with a specific result.

## Integration triggers

Each BC domain has dedicated subscriber codeunits in the Integration module:

| Domain | Trigger event | Codeunit |
|--------|--------------|----------|
| Purchasing | Post purchase receipt | `QltyReceivingIntegration` |
| Production | Post output journal | `QltyManufacturIntegration` |
| Assembly | Post assembly output | `QltyAssemblyIntegration` |
| Warehouse | Register warehouse receipt | `QltyReceivingIntegration` |
| Transfer | Post transfer receipt | `QltyTransferIntegration` |
| Sales return | Post sales return receipt | `QltySalesIntegration` |
| Warehouse movement | Register movement | `QltyWarehouseIntegration` |

The Integration module also extends 27+ BC pages with inspection-related fields, actions, and factboxes -- making inspections visible wherever users work with the source documents.
63 changes: 63 additions & 0 deletions src/Apps/W1/Quality Management/app/docs/data-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Data model

## Overview

The data model has three conceptual layers: configuration (tests, templates, results, generation rules), documents (inspection header/line), and setup (global settings). The configuration layer defines what to inspect and how to evaluate results. The document layer captures actual inspections. The key design insight is the flexible source tracking via RecordIds -- inspections can attach to any BC table without schema changes.

## Inspection documents

```mermaid
erDiagram
"Qlty Inspection Header" ||--|{ "Qlty Inspection Line" : "has lines"
"Qlty Inspection Header" }o--|| "Qlty Inspection Template Hdr" : "created from"
"Qlty Inspection Header" }o--o| "Qlty Inspection Result" : "header result"
"Qlty Inspection Line" }o--o| "Qlty Inspection Result" : "line result"
"Qlty Inspection Line" }o--|| "Qlty Test" : "tests"
```

The `QltyInspectionHeader` (20405) is the core document. Its primary key is `No.` + `Re-inspection No.`, which enables the re-inspection chain -- same inspection number, incrementing re-inspection counter. The header stores source tracking via `Source Table No.`, `Source Document No.`, `Source Item No.`, plus up to 5 `RecordId` fields and 10 custom text/decimal fields for flexible source linking.

The `QltyInspectionLine` (20406) stores individual test measurements. Each line has a `Test Value` (Text[250]) plus a `Test Value Blob` for large values, and a `Derived Numeric Value` for auto-calculated numeric interpretation. The `Failure State` enum tracks whether the line failed from an Acceptable Quality Level check. Lines reference their template origin via `Template Code` + `Template Line No.`.

### Quantity model

The header tracks `Source Quantity (Base)`, `Pass Quantity`, `Fail Quantity`, and `Sample Size`. Sample size is derived from the template's sampling strategy (fixed or percentage). Pass and fail quantities can be manually entered or derived from line results.

### Re-inspection

Re-inspections share the same `No.` but increment `Re-inspection No.`. The `Most Recent Re-inspection` boolean flags the latest in the chain. Only the most recent re-inspection's result applies for item tracking blocking decisions.

## Configuration hierarchy

```mermaid
erDiagram
"Qlty Test" ||--o{ "Qlty Inspection Template Line" : "used in templates"
"Qlty Inspection Template Hdr" ||--|{ "Qlty Inspection Template Line" : "has lines"
"Qlty Inspection Gen Rule" }o--|| "Qlty Inspection Template Hdr" : "uses template"
"Qlty Test" ||--o{ "Qlty Test Lookup Value" : "custom lookup values"
```

**QltyTest** (20401) defines what to measure. Key properties: `Test Value Type` (one of 10 types including Decimal, Boolean, Text Expression, Table Lookup), `Allowable Values` (constraint expression), and for Table Lookup types: `Lookup Table No.`, `Lookup Field No.`, `Lookup Table Filter`. The Table Lookup mechanism allows tests to reference any BC table/field as a dropdown, with filter expressions.

**QltyInspectionTemplateHdr/Line** (20402/20403) groups tests with a sampling strategy. `Sample Source` is either `Fixed Quantity` or `Percent of Quantity`. Template lines can override test-level properties (description, UOM, expression formula).

**QltyInspectionGenRule** (20409) connects templates to business events. The `Intent` enum determines the domain (Purchase, Production, Transfer, etc.), and intent-specific trigger enums control when to fire (e.g., `Purchase Order Trigger: On Receipt`). Item and attribute filters narrow which items trigger the rule.

## Result evaluation

```mermaid
erDiagram
"Qlty Inspection Result" ||--o{ "Qlty Result Condition Config" : "has conditions"
"Qlty Inspection Result" ||--o{ "Qlty Inspection Header" : "assigned to headers"
"Qlty Inspection Result" ||--o{ "Qlty Inspection Line" : "assigned to lines"
```

**QltyInspectionResult** (20411) defines outcomes (PASS, FAIL, INPROGRESS, custom). Each result has an `Evaluation Sequence` (priority -- lower wins), `Result Category` (Acceptable/Not acceptable/Uncategorized), and `Finish Allowed` (whether the inspection can be completed with this result).

The result also controls item tracking blocking via 9 independent fields: `Item Tracking Allow Sales`, `Allow Transfer`, `Allow Consumption`, `Allow Pick`, `Allow Put-Away`, `Allow Movement`, `Allow Output`, `Allow Assembly Consumption`, `Allow Assembly Output`. Each can be `Allowed`, `Blocked`, or `Blocked but can be overridden`. This enables granular quarantine scenarios.

**QltyIResultConditConf** (20418) maps test values to result codes. Conditions are text expressions (e.g., `>=80`, `RED|GREEN`, `true`) with a priority. They exist at three levels: test defaults, template overrides, and inspection-specific overrides.

## Setup

**QltyManagementSetup** (20400) is the global singleton. Key settings: `Inspection Creation Option` (always new, re-inspection, use existing, etc.), `Inspection Search Criteria` (how to find existing inspections), trigger defaults per domain, item tracking enforcement rules, and journal batch names for disposition operations.
Loading
Loading