Purchase Requisitions Extension - Technical Architecture
Extension Name: Purchase Requisitions
Publisher: Theta Systems Limited
Object Range: 71025710-71025759
Platform Version: 26.0.0.0
Application Version: 26.5.0.0
Target: Cloud
1. Overview
The Purchase Requisitions extension enables organizations to manage purchase requests through an approval workflow system before creating purchase orders in Microsoft Dynamics 365 Business Central. This extension provides a full requisition lifecycle management system with approval workflows, integration with Dataverse/CRM, Entra ID synchronization, and advanced dimension handling.
Key Features:
- Purchase requisition creation and management
- Line-level approval workflows
- Requester management with Entra ID integration
- Vendor catalogue items for standardized purchasing (with categories and images)
- Ship-to address management
- SharePoint document integration (attach and preview files from SharePoint)
- Dataverse/CRM integration
- Allocation account management
- PO receipt processing (GRN tracking back to requisition lines)
- Portal invitation management (invite requesters to Power Pages portal)
- Full dimensional analysis support
2. Solution Structure
2.1 Repository Folders
erp-ext-root/
├── .scripts/ # PowerShell automation scripts
│ ├── app/ # App publishing & installation scripts
│ ├── common/ # Common utilities
│ ├── config/ # Configuration management
│ ├── docs/ # Documentation scripts
│ ├── ext/ # Extension publishing
│ ├── git/ # Git workflow automation
│ ├── sandbox/ # Local sandbox management
│ └── translation/ # Translation automation
├── .alpackages/ # AL dependency packages
├── ARTIFACTS/ # Build outputs and artifacts
├── DOCS/ # Documentation
├── MAIN/ # Main extension source code
│ ├── src/ # Source files
│ └── Dataverse/ # CRM/Dataverse integration
└── TEST/ # Test extension (separate app.json)
2.2 Source Code Organization (MAIN/src/)
src/
├── codeunit/ # Business logic
├── controladdin/ # Control add-ins
├── dotnet/ # .NET interop
├── enum/ # Enumerations
├── enumextension/ # Enum extensions
├── interface/ # Interface definitions
├── page/ # UI pages
├── pageextension/ # Page extensions
├── permissionset/ # Permission sets
├── profile/ # User profiles
├── query/ # Query objects
├── report/ # Reports
├── table/ # Data tables
├── tableextension/ # Table extensions
└── xmlport/ # XML import/export
3. Core Data Model
3.1 Primary Tables
| Object ID | Table Name | Purpose |
|---|---|---|
| 71025713 | Purch. Req. Hdr._REQ_TSL | Purchase requisition header - contains overall request information |
| 71025714 | Purch. Req. Line_REQ_TSL | Purchase requisition lines - individual line items for approval |
| 71025710 | Requester_REQ_TSL | User/requester master data synchronized with Entra ID |
| 71025715 | Req. Ship-to Address_REQ_TSL | Ship-to addresses for requisitions |
| 71025717 | PurchaseReqSetup_REQ_TSL | Configuration and setup for the requisition system (OAuth, SharePoint, Tenant IDs, currency) |
| 71025740 | PO Receipt Temp_REQ_TSL | Temporary table for PO receipt processing |
| 71025746 | Vend. Cat. Item_REQ_TSL | Vendor catalogue items for standardized purchasing (vendor, item, price, dimensions) |
| 71025747 | Vend. Cat. Item Img._REQ_TSL | Images for vendor catalogue items |
| 71025748 | Vend. Cat. Item Cat._REQ_TSL | Categories for vendor catalogue items |
| 71025741 | SharePoint Site Buffer_REQ_TSL | Buffer table for SharePoint site lookups |
| 71025742 | SP Drive Buffer_REQ_TSL | Buffer table for SharePoint drive listings |
| 71025743 | SP Drive Item Buffer_REQ_TSL | Buffer table for SharePoint drive items |
3.2 Enumerations
| Enum | Purpose |
|---|---|
| Purch. Req. Status_REQ_TSL | Header-level status (Open, Closed, etc.) |
| PurchReqLineStatus_REQ_TSL | Line-level status (Open, Pending Approval, Approved, Rejected, etc.) |
| PurchReqLineDesStatus_REQ_TSL | Line designation status |
| Purch. Req. Action_REQ_TSL | Available actions on requisitions |
3.3 Table Extensions
- Dimension Value - Extended for custom dimension handling
- Source Code Setup - Extended for requisition source codes
- Purchases & Payables Setup - Extended for requisition configuration
- Purchase Line - Extended to link back to requisition lines
- Purch. Rcpt. Line - Extended to link receipt lines back to requisition lines (for GRN tracking)
- General Ledger Setup - Extended for requisition GL configuration
- Document Attachment - Extended for requisition attachment management
- CRM Customer Address - Extended for Dataverse integration
- CRM Contact - Extended for Dataverse integration
4. Core Business Logic (Codeunits)
4.1 Workflow Management
| Codeunit ID | Name | Responsibility |
|---|---|---|
| 71025714 | PurReq WorkflowEvents_REQ_TSL | Defines workflow events (send for approval, cancel approval), handles approval entry updates, workflow event library |
| 71025716 | PurReqWorkflowRespMgmt_REQ_TSL | Workflow response management, workflow template creation, workflow step insertion |
| 71025715 | ApprovalPurchReqLine_REQ_TSL | Entry point for line-level approval execution |
| 71025717 | Purch. Req. Appr. Mgmt_REQ_TSL | Approval management functions (send, cancel, delegate approval requests) |
| 71025721 | SubsWFReqPgeHandl_REQ_TSL | Workflow page handler subscriber |
Workflow Design:
- Line-level approval - Each requisition line goes through approval independently
- Approval workflow code:
PRQAW(Purchase Request Approval Workflow) - Custom workflow template with prefix:
PR- - Standard BC workflow integration with Approval Entries
- Support for delegation, rejection, cancellation
- Workflow webhook support for external integrations
4.2 Document Management
| Codeunit ID | Name | Responsibility |
|---|---|---|
| 71025712 | Purch. Request Mgmt._REQ_TSL | Core requisition management - creation, modification, deletion, conversion to PO |
| 71025722 | PReq. Alloc. Acc. Mgt_REQ_TSL | Allocation account management for requisitions |
| 71025740 | Process PO Receipts_REQ_TSL | Processing of purchase order receipts back to requisitions |
| 71025741 | Post Purch. Receipt_REQ_TSL | Post purchase receipt logic |
| 71025746 | VendCatImportExport_REQ_TSL | Vendor catalogue item import/export |
4.3 Integration & Synchronization
| Codeunit ID | Name | Responsibility |
|---|---|---|
| 71025711 | Entra ID Sync_REQ_TSL | Synchronize requesters with Microsoft Entra ID (formerly Azure AD) |
| 71025734 | Requester Sync Sub._REQ_TSL | Subscriber for requester synchronization events |
| 71025732 | Portal Invitation Mgmt_REQ_TSL | Manage Power Pages portal invitations for requesters |
| 71025727 | SharePointIntMgt_REQ_TSL | SharePoint document integration management |
| 71025728 | SharePointOAuthMgt_REQ_TSL | SharePoint OAuth authentication |
| 71025718 | CDS Setup Def. Sub._REQ_TSL | Dataverse setup definition subscriber |
| 71025719 | CDS Setup Defaults_REQ_TSL | Dataverse setup and configuration |
| 71025756 | PurchReqHdr DVSetup_REQ_TSL | Purchase req header Dataverse mapping |
| 71025758 | PurchReqLineDVSetup_REQ_TSL | Purchase req line Dataverse mapping |
4.4 Dimension & Accounting
| Codeunit ID | Name | Responsibility |
|---|---|---|
| 71025724 | Dimension Object Mgt_REQ_TSL | Dimension management for requisition objects, updates DimensionObject JSON field. Includes UpdateJobDimensionObject(JobNo) and UpdateJobTaskDimensionObject(JobNo, JobTaskNo) writing to the BC Job / Job Task records. |
| 71025730 | SubsDefaultDimension_REQ_TSL | Default dimension handling subscriber, auto-updates DimensionObject on dimension changes (now includes Database::Job). |
| 71025854 | SubsJobTaskDimension_REQ_TSL | Job Task Dimension subscriber, auto-updates Job Task.DimensionObject_REQ_TSL on Job Task dimension changes (table 1002 has composite key, so handled separately from SubsDefaultDimension). |
| 71025731 | SubsDefaultDimPriority_REQ_TSL | Default dimension priority subscriber |
| 71025728 | SubsAllocationLine_REQ_TSL | Allocation line subscriber |
| 71025732 | SubsDocumentAtchMgmt_REQ_TSL | Document attachment management subscriber |
DimensionObject Field - Bidirectional Flow:
- Tables with DimensionObject field (Text[2048]): Requester, Request Cat. Item, Purch. Req. Hdr., Purch. Req. Line, Vendor (
DimensionObject_REQ_TSL), Salesperson/Purchaser (DimensionObject_REQ_TSL), Job (DimensionObject_REQ_TSL), Job Task (DimensionObject_REQ_TSL) - BC is the source of truth; the standard CDS integration table mapping (configured in
CDSSetupDefaults) pushes the field to the matching CDS proxy / Dataverse entity - Stores dimensions as JSON for external integrations (Dataverse, Power Platform)
From Default Dimensions → DimensionObject (JSON):
- Automatically updated when default dimensions change via SubsDefaultDimension subscribers
- No bulk update report exists — existing records must be updated individually or via data upgrade codeunit
From DimensionObject (JSON) → Dimension Fields:
- OnValidate trigger on DimensionObject field extracts JSON and populates Dimension Set ID
- Automatically applied when selecting Requester on Purchase Request Header
- Automatically applied when selecting Request Catalogue Item on Purchase Request Line
- Updates "Dimension Set ID", "Shortcut Dimension 1 Code", "Shortcut Dimension 2 Code"
5. User Interface
5.1 Primary Pages
| Page ID | Type | Name | Purpose |
|---|---|---|---|
| 71025714 | Document | Purchase Request Card_REQ_TSL | Main card for viewing/editing requisition header and lines |
| 71025719 | List | Purchase Request List_REQ_TSL | List view of all purchase requisitions |
| 71025718 | Document | Purch. Req. Worksheet_REQ_TSL | Worksheet view for line-level operations and approvals |
| 71025715 | ListPart | Purchase Request Line Subpage | Subpage for requisition lines on card |
| 71025712 | Card | Purch. Req. Appr._REQ_TSL | Approval workflow card page |
| 71025710 | List | Requester List_REQ_TSL | List view of requesters |
| 71025711 | Card | Requester Card_REQ_TSL | Card for requester details and Entra ID sync |
| 71025722 | RoleCenter | PurchaseReqRC_REQ_TSL | Role center for purchase requisition users |
5.2 Supporting Pages
| Page Type | Pages | Purpose |
|---|---|---|
| Requester | Requester Card (71025711), Requester List (71025710) | Manage requesters (synchronized with Entra ID) |
| Vendor Catalogue | Vend. Cat. Items (71025743), VendCatItemImgList (71025744), VendCatItemCatList (71025745), VendCatImportDlg (71025753) | Manage vendor catalogue items, categories, and images |
| Ship-to | Req. Ship-to Address (71025717), Req. Ship-to Addr List (71025716) | Manage shipping addresses |
| Setup | PurchaseReqSetup_REQ_TSL (71025723) | System configuration |
| SharePoint | SP Sites Lookup (71025724), SP Drives Lookup (71025725), SP Drive Items (71025741), SP Doc Preview FB (71025732) | SharePoint site/drive browsing and document preview factbox |
| Attachments | Standard BC Document Attachment factbox | Attachment list; no custom preview page — attachments use BC's built-in infrastructure |
5.3 Factbox Support
The solution includes comprehensive factbox support for approval workflows and document attachments:
Attachment Preview Factbox (Page 71025750)
- Image & PDF Preview: Automatically displays previews for supported file types (.jpg, .jpeg, .png, .gif, .bmp, .tiff, .tif, .pdf)
- Download Option: For non-previewable files, displays a download link
- Multi-attachment Support: Shows message when multiple attachments exist with option to view all
- Available On:
- Purchase Request Card (for header-level attachments)
- Purchase Request Line Subpage (for line-level attachments)
- Purchase Request Worksheet (for line-level attachments during approval)
- Actions: Download, View All Attachments, Open in New Window
Approval Factboxes
- Pending Approval FactBox: Shows pending approvals for current user
- Workflow Status FactBox: Displays current workflow status
5.4 Page Extensions
- Workflow Template - Extended to support custom requisition workflows
- Source Code Setup - Extended for requisition source codes
- Purchase Setup - Extended for requisition configuration
- Purchase Order SubForm - Extended to show linked requisition information
5.5 Approval Actions
Available on Worksheet and Card pages:
- Send Approval Request - Submit line(s) for approval
- Cancel Approval Request - Cancel pending approvals
- Approve - Approve pending lines (for approvers)
- Reject - Reject pending lines (for approvers)
- Delegate - Delegate approval to another user
- Comments - View/add approval comments
- Workflow Status - View current workflow status
Attachment Management:
- Attachments action available on both header and line level
- Automatic preview in factbox for images and PDFs during approval review
- Download option for all file types
- Multi-attachment indicator with quick access to view all
6. Attachment Preview System
6.1 Overview
The Purchase Requisitions extension includes a comprehensive attachment preview system that allows approvers to view attached images and PDF documents directly in the approval interface without downloading files.
6.2 Supported File Types
Preview Supported:
- Images: .jpg, .jpeg, .png, .gif, .bmp, .tiff, .tif
- Documents: .pdf
Download Only:
- All other file types (Excel, Word, text files, etc.)
6.3 Attachment Factbox
Note: A custom attachment preview page (previously documented as Page 71025750) does not exist. Attachment display uses BC's standard Document Attachment Factbox infrastructure.
SharePoint Document Preview Factbox (Page 71025732 — SP Doc Preview FB_REQ_TSL)
This separate factbox provides preview of documents stored in SharePoint (not BC document attachments). It uses a Control Add-in (SPDocPreview_REQ_TSL) to render documents from SharePoint URLs.
Standard BC Document Attachment Factbox
- Used for files attached directly to header or line records in BC
- Provides the standard attachment list and download capability
- Available on: Purchase Request Card, Purchase Request Line Subpage, Purchase Request Worksheet
6.4 Integration Points
Purchase Request Card (Page 71025714)
- Factbox displays header-level attachments
- Filters: Table ID = Database::"Purch. Req. Hdr._REQ_TSL", No. = Current Header No.
Purchase Request Line Subpage (Page 71025715)
- Factbox displays line-level attachments
- Filters: Table ID = Database::"Purch. Req. Line_REQ_TSL", No. = Document No., Line No. = Current Line
Purchase Request Worksheet (Page 71025718)
- Factbox displays line-level attachments during approval review
- Same filtering as Line Subpage
- Enables approvers to view supporting documentation without leaving the approval interface
6.5 User Workflow
- Requester attaches files to purchase request (header or line level)
- Requester sends request for approval
- Approver opens approval worksheet or card
- Approver views attachment preview in factbox automatically
- For images/PDFs: Preview appears instantly
- For other files: Download link displayed
- Approver can download files if needed
- Approver makes approval decision with full context
6.6 Benefits
- Faster Approvals: Approvers can quickly review supporting documents
- Better Context: Visual preview provides immediate understanding
- Reduced Clicks: No need to download files for common formats
- Mobile Friendly: Works in Business Central mobile and web clients
- Standard Integration: Uses BC's built-in Document Attachment infrastructure
7. Dataverse/CRM Integration
7.1 Dataverse Tables
All Dataverse integration tables are prefixed with CDStsl:
| Table ID | Table Name | Purpose |
|---|---|---|
| 71025730 | CDS tsl_PurchaseRequestHeader | Purchase req header sync with CRM |
| 71025731 | CDS tsl_PurchReqLine_REQ_TSL | Purchase req line sync with CRM |
| 71025732 | CDS tsl_PurchRcptLine_REQ_TSL | Purchase receipt line sync with CRM |
| 71025716 | CDS tsl_Shiptocode_REQ_TSL | Ship-to addresses sync with CRM |
| 71025723 | CDS tsl_Dimension_REQ_TSL | Dimension sync with CRM |
| 71025712 | CDS tsl_DimensionValue_REQ_TSL | Dimension values sync with CRM |
| 71025722 | CDS tsl_PurchReqSetup_REQ_TSL | Setup sync with CRM |
| 71025720 | CDS tsl_Job_REQ_TSL | Job sync with CRM |
| 71025721 | CDS tsl_JobTask_REQ_TSL | Job task sync with CRM |
| 71025719 | CDS tsl_DocumentAttachment | Document attachments sync with CRM |
| 71025749 | CDS tsl_VendCatItem_REQ_TSL | Vendor catalogue items sync with CRM |
| 71025750 | CDS tsl_VendCatItemImg_REQ_TSL | Vendor catalogue item images sync with CRM |
| 71025751 | CDS tsl_VendCatItemCat_REQ_TSL | Vendor catalogue item categories sync with CRM |
7.2 Dataverse Pages
Virtual tables and integration pages (prefixed with DV):
- DV Purch Req Hdr List_REQ_TSL (71025738) - Purchase req headers for Dataverse
- DV Purch Req Lines_REQ_TSL (71025739) - Purchase req lines for Dataverse
- DV Purch Rcpt Lines_REQ_TSL (71025730) - Purchase receipt lines for Dataverse
- DV Ship-to Addr List_REQ_TSL (71025729) - Ship-to addresses for Dataverse
- DV Dimension List_REQ_TSL (71025721) - Dimensions for Dataverse
- DV Dimension Val List_REQ_TSL (71025740) - Dimension values for Dataverse
- DV Purch Req Setup_REQ_TSL (71025726) - Setup for Dataverse
- DV Job List_REQ_TSL (71025727) - Jobs for Dataverse
- DV Job Task List_REQ_TSL (71025728) - Job tasks for Dataverse
- DV Doc. Attach. List_REQ_TSL (71025713) - Document attachments for Dataverse
- DV Vend Cat Item List_REQ_TSL (71025749) - Vendor catalogue items for Dataverse
- DVVendCatItemImgList_REQ_TSL (71025750) - Vendor catalogue images for Dataverse
- DVVendCatItemCatList_REQ_TSL (71025751) - Vendor catalogue categories for Dataverse
- DV Purchaser List_REQ_TSL (71025851) - Salespersons/Purchasers for Dataverse, coupled to
Salesperson/Purchaser
7.3 Integration Points
The Dataverse integration enables:
- Requisition creation from external systems (Power Apps, Power Automate)
- Real-time data synchronization
- Bi-directional updates
- CRM coupling management
- External approval workflows via Power Automate
8. Approval Workflow Architecture
8.1 Workflow Flow
1. User creates requisition lines (Status: Open)
2. User sends lines for approval
↓
3. System triggers: RunWorkflowOnSendPurchReqLineDocForApprovalCode()
↓
4. Workflow Response:
- Restrict record usage
- Set status to "Pending Approval"
- Create approval requests
- Send approval notifications
↓
5. Approver actions:
a) Approve → Status: Approved → Allow record usage
b) Reject → Status: Rejected → Open document
c) Delegate → Assign to another approver
d) Cancel → Status: Open → Allow record usage
8.2 Key Workflow Events
| Event Code | Trigger | Purpose |
|---|---|---|
RunWorkflowOnSendPurchReqLineDocForApprovalCode() | Line sent for approval | Initiate approval workflow |
RunWorkflowOnCancelPurchReqLineApprovalRequestCode() | Approval cancelled | Cancel approval workflow |
| Standard BC approval events | Approve/Reject/Delegate | Handle approval responses |
8.3 Workflow Responses
- SetStatusToPendingApprovalCode() - Update line status
- CreateApprovalRequestsCode() - Create approval entries
- SendApprovalRequestForApprovalCode() - Notify approvers
- RestrictRecordUsageCode() - Lock record during approval
- AllowRecordUsageCode() - Unlock record after approval/rejection
- RejectAllApprovalRequestsCode() - Handle rejection
- CancelAllApprovalRequestsCode() - Handle cancellation
8.4 Approval Argument Handling
Subscriber: OnPopulateApprovalEntryArgument in PurReq WorkflowEvents_REQ_TSL
- Populates approval entry with Document No.
- Sets Table ID to Purch. Req. Line table
- Links approval entry to record
9. Entra ID Integration
9.1 Purpose
Synchronize Business Central requesters with Microsoft Entra ID (Azure Active Directory) users for seamless authentication and user management.
9.2 Key Components
- Codeunit 71025711 - Entra ID Sync_REQ_TSL: Main synchronization logic
- Codeunit 71025734 - Requester Sync Sub._REQ_TSL: Event subscribers for sync
- Table 71025710 - Requester_REQ_TSL: Stores requester data with Entra ID references
9.3 Configuration Files
ENTRA_ID_INTEGRATION.md- Integration setup instructionsENTRA_ID_INTEGRATION_STATUS.md- Current status and configuration
10. Naming Conventions
10.1 Object Suffixes
All custom objects use the suffix: _REQ_TSL
- REQ = Purchase Requisitions
- TSL = Theta Systems Limited
10.2 Dataverse Objects
- Tables:
CDStslprefix (e.g.,CDStslPurchReqLine) - Pages:
DVprefix (e.g.,DVPurchReqLines)
10.3 Workflow Objects
- Workflow template prefix:
PR- - Workflow code:
PRQAW(Purchase Request Approval Workflow)
11. Extension Points & Customization
11.1 Events Published
The extension publishes events through subscribers to allow further customization:
- Document Management: Before/after requisition creation, modification, deletion
- Approval: Before/after sending for approval, approval status changes
- Synchronization: Requester sync events, Dataverse sync events
- Dimension Management: Default dimension events, allocation events
11.2 Event Subscribers in Extension
The extension subscribes to standard BC events:
| Subscriber Codeunit | Subscribes To |
|---|---|
| SubsWFReqPgeHandl | Workflow Request Page Handling |
| SubsDocumentAtchMgmt | Document Attachment Management |
| SubsDefaultDimPriority | Default Dimension Priority |
| SubsDefaultDimension | Default Dimension events |
| SubsJobTaskDimension | Job Task Dimension events |
| SubsAllocationLine | Allocation Line events |
| RequesterSyncSub | Requester synchronization events |
11.3 Extensibility Points
- Custom approval logic - Subscribe to approval workflow events
- Custom validation - Subscribe to before/after events on tables
- Additional integrations - Extend Dataverse mappings
- Custom dimensions - Use dimension management subscribers
- External systems - Use workflow webhooks
12. Key Business Processes
12.1 Purchase Requisition Lifecycle
- Creation: User creates requisition header and adds lines
- Catalogue Selection: Optionally use catalogue items for standardized requests
- Dimension Assignment: Assign dimensions and allocation accounts
- Ship-to Selection: Select delivery address
- Submission: Send lines for approval (line-by-line)
- Approval Process: Approvers review and approve/reject/delegate
- Conversion to PO: Approved lines can be converted to purchase orders
- Receipt Processing: PO receipts are tracked back to requisition lines
12.2 Catalogue Item Management
- Predefined items with standard descriptions, vendors, prices
- Dimension templates per catalogue item
- Simplified requisition creation using standard items
12.3 Allocation Account Flow
- Purchase requisitions support allocation accounts
- Automatically distribute costs across multiple dimensions/accounts
- Integration with standard BC allocation functionality
13. Development & Deployment
13.1 Build Process
Automated tasks available (see .scripts/):
- Build:
al_build- Compile current project - Build All:
al_buildall- Compile all projects and dependencies - Download Symbols:
al_downloadsymbols- Get dependency symbols - Publish:
al_publish- Deploy to environment
13.2 Environment Management
Scripts for local sandbox management:
- Start Sandbox: Start local BC container
- Remove Sandbox: Remove local BC container
- Create Users: Bulk user creation in sandbox
- Install App: Install extension in sandbox
- Download Runtime Package: Extract runtime from sandbox
13.3 Git Workflow
Automated Git tasks:
- New WIP Branch: Create work item branch
- New Extension: Initialize new extension branch
- Overwrite Local Branch: Reset local to remote
- Remove Orphan Branches: Clean up deleted remote branches
13.4 Dependencies
Configuration in app.json:
- Platform: 26.0.0.0
- Application: 26.5.0.0
- Target: Cloud
- No external dependencies (self-contained)
- Propagates dependencies to dependent extensions
13.5 Object ID Tracking
The file MAIN/object-ids.json tracks all used AL object IDs per object type. This avoids scanning all .al files to determine the next available ID and is automatically maintained by GitHub Copilot.
Structure:
{
"range": { "from": 71025710, "to": 71025759 },
"objectTypes": {
"<type>": {
"nextAvailable": <next free ID>,
"usedIds": [ ... ]
}
}
}
Rules:
- Before creating any new AL object, read
object-ids.jsonand useobjectTypes.<type>.nextAvailableas the ID. - After creating the object, add the ID to
usedIdsand incrementnextAvailable. - IDs are independent per object type —
table 71025710andpage 71025710can coexist. - If you manually create objects outside of a Copilot session, update
nextAvailablein this file accordingly.
14. Testing Strategy
14.1 Test Extension
Separate TEST folder with own app.json
- Test objects should be in TEST folder
- Can reference MAIN extension objects
- Allows isolated testing without affecting production code
14.2 Recommended Test Coverage
- Unit Tests: Table validation, codeunit logic
- Integration Tests: Workflow execution, approval flow
- UI Tests: Page interactions, field validations
- Dataverse Tests: Synchronization, coupling
- Entra ID Tests: User synchronization
15. Security & Permissions
15.1 Permission Sets
- ReqCatItem.PermissionSet.al - Catalogue item permissions
- GenPerm.PermissionSet.al - General permissions for requisition objects
15.2 Object Range Security
All objects within range: 71025710 - 71025759
15.3 User Roles
Typical user roles:
- Requester: Create and submit requisitions
- Approver: Approve/reject requisitions
- Administrator: Configure system, manage catalogue items
- Purchaser: Convert approved requisitions to POs
16. Monitoring & Diagnostics
16.1 Application Insights
Connection string configured in app.json:
- InstrumentationKey:
a9d782c8-6dac-4972-b698-8ade63233c34 - Region: Australia East
16.2 Telemetry Events
Standard BC telemetry for:
- Extension lifecycle events
- Workflow execution
- Error tracking
- Performance monitoring
17. Localization
17.1 Supported Locales
- en-NZ (New Zealand)
- en-AU (Australia)
- en-US (United States)
- en-GB (United Kingdom)
17.2 Translation Process
Automated translation task: APP: Translate
- Uses Microsoft Translator
- Script:
CarryOutTranslations.ps1 - Feature flag:
TranslationFileenabled inapp.json
18. Dependencies & Related Systems
18.1 Business Central Standard Objects
Dependencies on standard BC tables/codeunits:
- Approval Management (Codeunit "Approvals Mgmt.")
- Workflow Management (Codeunit "Workflow Management")
- Purchase Line / Purchase Header
- Dimension Management
- Allocation Accounts
- Source Code Setup
- CRM Integration Management
18.2 External Systems
- Microsoft Entra ID - User authentication and synchronization
- Microsoft Dataverse - CRM integration
- Power Platform - Power Apps, Power Automate workflows
- Application Insights - Telemetry and monitoring
19. Known Patterns & Best Practices
19.1 Coding Patterns
- Feature: NoImplicitWith - All
withstatements are explicit - Namespace:
Theta.PurchaseRequisitions- Used consistently - Error Handling: Labels for user-facing errors
- RecordRef Pattern: Used for generic record handling in workflows
- Event-Driven: Heavy use of subscribers for extensibility
19.2 Workflow Pattern
Standard BC workflow pattern:
- Define workflow events (OnSend, OnCancel)
- Define workflow responses (SetStatus, CreateApprovalRequests)
- Create workflow template
- Insert workflow steps with conditions
- Handle approval entry updates
19.3 Dataverse Pattern
Standard AL-CDS integration pattern:
- Create CDS* table for each entity
- Create integration page for each entity
- Define setup codeunits for mapping
- Use CDS Integration Table Mapping
20. Future Extensibility Considerations
20.1 Potential Extensions
- Budget Integration - Check budget before approval
- Vendor Management - Automatic vendor selection based on rules
- Multi-currency - Support for foreign currency requisitions
- Advanced Analytics - Power BI reports on requisition data
- Mobile App - Power Apps mobile interface
- AI/ML - Predictive approval routing
20.2 API Exposure
Consider exposing APIs for:
- Requisition creation from external systems
- Approval status queries
- Catalogue item queries
- Integration with procurement systems
21. Quick Reference
21.1 Key Tables
| Purpose | Table ID | Table Name |
|---|---|---|
| Header | 71025713 | Purch. Req. Hdr._REQ_TSL |
| Lines | 71025714 | Purch. Req. Line_REQ_TSL |
| Users | 71025710 | Requester_REQ_TSL |
| Vendor Catalogue | 71025746 | Vend. Cat. Item_REQ_TSL |
| Setup | 71025717 | PurchaseReqSetup_REQ_TSL |
| PO Receipt Temp | 71025740 | PO Receipt Temp_REQ_TSL |
21.2 Key Pages
| Purpose | Page ID | Page Name |
|---|---|---|
| Main Card | 71025714 | Purchase Request Card_REQ_TSL |
| List | 71025719 | Purchase Request List_REQ_TSL |
| Worksheet (Approvals) | 71025718 | Purch. Req. Worksheet_REQ_TSL |
| Line Subpage | 71025715 | Purchase Request Line Subpage |
| Requester List | 71025710 | Requester List_REQ_TSL |
| Requester Card | 71025711 | Requester Card_REQ_TSL |
| SharePoint Doc Preview | 71025732 | SP Doc Preview FB_REQ_TSL |
21.3 Key Codeunits
| Purpose | Codeunit ID | Codeunit Name |
|---|---|---|
| Document Mgmt | 71025712 | Purch. Request Mgmt._REQ_TSL |
| Workflow Events | 71025714 | PurReq WorkflowEvents_REQ_TSL |
| Workflow Responses | 71025716 | PurReqWorkflowRespMgmt_REQ_TSL |
| Approval Mgmt | 71025717 | Purch. Req. Appr. Mgmt_REQ_TSL |
| Entra ID Sync | 71025711 | Entra ID Sync_REQ_TSL |
| Dimension Mgmt | 71025724 | Dimension Object Mgt_REQ_TSL |
21.4 Key XMLPorts
| Purpose | XMLPort ID | XMLPort Name |
|---|---|---|
| PO Receipt Import | 71025710 | PO Receipt Transactions |
Note: A bulk dimension update report was previously referenced in this document but does not exist in the codebase.
22. SharePoint Integration
22.1 Overview
The extension integrates with SharePoint to allow requisition lines to have supporting documents stored in SharePoint drives, with a preview factbox directly in the BC approval interface.
22.2 Components
| Object | ID | Purpose |
|---|---|---|
| Codeunit SharePointIntMgt_REQ_TSL | 71025727 | Core SharePoint integration management |
| Codeunit SharePointOAuthMgt_REQ_TSL | 71025728 | OAuth authentication for SharePoint |
| Page SP Sites Lookup_REQ_TSL | 71025724 | Browse and select SharePoint sites |
| Page SP Drives Lookup_REQ_TSL | 71025725 | Browse and select SharePoint drives |
| Page SP Drive Items_REQ_TSL | 71025741 | Browse items within a SharePoint drive |
| Page SP Doc Preview FB_REQ_TSL | 71025732 | Factbox to preview SharePoint documents in BC |
| Control Add-in SPDocPreview_REQ_TSL | — | Renders document preview from SharePoint URL |
22.3 Configuration
SharePoint credentials and endpoints are stored in PurchaseReqSetup_REQ_TSL (Table 71025717), including OAuth client credentials and Tenant ID. Setup must be completed before SharePoint features are available.
23. Vendor Catalogue Management
23.1 Overview
The vendor catalogue provides a library of pre-defined items (with vendor, description, price, and dimensions) that requesters can select to simplify and standardise the requisition process. It replaces the earlier concept of "Request Catalogue Items".
23.2 Data Model
| Table | ID | Purpose |
|---|---|---|
| Vend. Cat. Item_REQ_TSL | 71025746 | Core catalogue item (vendor, item type, price, dimensions) |
| Vend. Cat. Item Img._REQ_TSL | 71025747 | One or more images per catalogue item |
| Vend. Cat. Item Cat._REQ_TSL | 71025748 | Categories for grouping catalogue items |
23.3 Key Pages
| Page | ID | Purpose |
|---|---|---|
| Vend. Cat. Items_REQ_TSL | 71025743 | Main list of catalogue items |
| VendCatItemImgList_REQ_TSL | 71025744 | Image management per item |
| VendCatItemCatList_REQ_TSL | 71025745 | Category management |
| VendCatImgPreviewFB_REQ_TSL | 71025752 | Image preview factbox |
| VendCatImportDlg_REQ_TSL | 71025753 | Import dialogue (uses Report/RequestPage pattern) |
23.4 Import/Export
Codeunit VendCatImportExport_REQ_TSL (71025746) handles bulk import and export of catalogue items. All three entity types (items, images, categories) are also synced to Dataverse — see Section 7.
24. PO Receipt Processing & GRN Tracking
24.1 Overview
When a purchase order created from a requisition is received, the extension tracks the received quantities back to the originating requisition lines, providing full visibility of what has been ordered and received.
24.2 Key Fields on Purch. Req. Line_REQ_TSL
| Field | Purpose |
|---|---|
| Qty. to Receive | Quantity expected to be received |
| Qty. Received | FlowField — sums from Purch. Rcpt. Line via Purchase Line System ID |
| Qty. to Receive Locked | Prevents further changes once receipt is confirmed |
| Purchase Line System ID | Links the requisition line to the generated purchase order line |
24.3 Components
| Object | ID | Purpose |
|---|---|---|
| Codeunit Process PO Receipts_REQ_TSL | 71025740 | Orchestrates receipt processing |
| Codeunit Post Purch. Receipt_REQ_TSL | 71025741 | Posts the receipt against the requisition |
| Codeunit Subs Purch. Rcpt._REQ_TSL | 71025742 | Subscriber — fires on purchase receipt posting |
| Table PO Receipt Temp_REQ_TSL | 71025740 | Temporary staging for receipt data |
| XMLPort PO Receipt Transactions | 71025710 | Import receipt transactions from external source |
| TableExt Purch. Rcpt. Line Ext._REQ_TSL | 71025715 | Extends standard receipt line to link back to requisition |
25. Portal Invitation Management
25.1 Overview
Requesters access the system via a Power Pages portal. The extension manages sending portal invitations to requesters so they can activate their portal access.
25.2 Key Fields on Requester_REQ_TSL
| Field | Purpose |
|---|---|
| Entra ID (Field 13) | Azure Entra ID object ID — used for Power Pages SSO |
| Login Enabled (Field 14) | Whether the requester's portal login is active |
| Office Location (Field 15) | Office location for the requester |
| Last Invitation Sent | Timestamp of the most recent portal invitation |
25.3 Components
| Object | ID | Purpose |
|---|---|---|
| Codeunit Portal Invitation Mgmt_REQ_TSL | 71025732 | Send and track portal invitations |
| Codeunit Entra ID Sync_REQ_TSL | 71025711 | Sync Entra IDs from Microsoft Graph so invitations can be sent |
26. Approval Tracking Fields
26.1 "Currently With" Fields
During the approval workflow, the following fields on Purch. Req. Line_REQ_TSL track who currently holds a line for approval:
| Field | Purpose |
|---|---|
| Currently With (Text) | Display name of the current approver |
| Currently With User ID (Code) | BC User ID of the current approver |
| Approval Comment | Free-text comment from the approver |
These are populated automatically by the workflow event subscribers and are visible in the worksheet and line subpage so requesters can see where their lines are in the process.
Document Version History
| Version | Date | Changes |
|---|---|---|
| 1.0 | 2026-01-21 | Initial architecture documentation |
| 1.1 | 2026-01-21 | Added automatic DimensionObject updates and bulk update report |
| 1.2 | 2026-01-21 | Added bidirectional DimensionObject flow: JSON extraction to dimension fields |
| 1.3 | 2026-02-09 | Added Attachment Preview System (Section 6) with image/PDF preview support for approval workflow |
| 1.4 | 2026-03-12 | Added Section 13.5 Object ID Tracking — documents MAIN/object-ids.json pattern for per-type ID management |
| 1.5 | 2026-04-10 | Corrected object IDs throughout (tables, pages, codeunits); removed non-existent report reference; added Sections 22–26 for SharePoint, Vendor Catalogue, PO Receipt processing, Portal Invitation, and Approval Tracking |
| 1.6 | 2026-05-20 | US #92263: added DimensionObject_REQ_TSL (Text[2048]) tableextensions on Job (71025829) and Job Task (71025830); added matching DimensionObject Blob field to CDS tsl_Job_REQ_TSL and CDS tsl_JobTask_REQ_TSL; wired CDS integration field mappings in CDSSetupDefaults (ToIntegrationTable); added UpdateJobDimensionObject / UpdateJobTaskDimensionObject to Dimension Object Mgt_REQ_TSL writing to BC tables; wired Database::Job into SubsDefaultDimension_REQ_TSL; added new SubsJobTaskDimension_REQ_TSL codeunit (71025854). BC is source of truth; sync engine pushes to Dataverse. |
| 1.7 | 2026-07-06 | US #96931: added missing Dataverse pages for two proxy tables that had none — DV General Setup_REQ_TSL (71025836, coupled to General Ledger Setup) and DV Purchaser List_REQ_TSL (71025851, coupled to Salesperson/Purchaser); registered both in ReqCatItem_REQ_TSL permission set; exposed both from the "Dataverse Records" action group on PurchaseReqSetup_REQ_TSL. |
| 1.8 | 2026-07-06 | US #96931: fixed ReqCatItem_REQ_TSL permission set — several existing Dataverse pages/tables were already wired into the "Dataverse Records" action group on PurchaseReqSetup_REQ_TSL but had no permission entries at all, causing a generic "Something went wrong" error on click. Added table/tabledata/page permissions for CDS tsl_Job_REQ_TSL, CDS tsl_JobTask_REQ_TSL, CDS tsl_DocumentAttachment, CDS tsl_PurchRcptLine_REQ_TSL, CDS tsl_VendCatItemCat_REQ_TSL, CDS tsl_VendCatItemImg_REQ_TSL, and the page permission for DV Purch Req Setup_REQ_TSL (its table was already permissioned). |
| 1.9 | 2026-07-06 | US #96931: added two more entries to the "Dataverse Records" action group on PurchaseReqSetup_REQ_TSL — DV DefDimPriority_REQ_TSL (existing page for CDS tsl_DefaultDimPriority_REQ_TSL, already permissioned) and Microsoft's standard CRM TransactionCurrency List (page 5345, table 5345 "CRM Transactioncurrency" — not one of our proxy tables, so no permission set change needed for it). |
| 1.10 | 2026-07-06 | US #96962: removed the PRGENERALSETUP integration mapping entirely — no longer used. Deleted CDS tsl_GeneralSetup_REQ_TSL (table 71025823) and DV General Setup_REQ_TSL (page 71025836); removed their permission set entries, the ResetGeneralSetupMapping procedure and its integration events from CDSSetupDefaults, the tsl_generalsetup/General Ledger Setup case entries from CDSSetupDefSub and CDSSynchronisationSubs, the DVGeneralSetup action from PurchaseReqSetup_REQ_TSL, and PRGENERALSETUP from the default Integration Job Group seed list. |
| 1.11 | 2026-07-06 | US #96930: made "Setup Default Synchronisation" reproduce the manually-verified reference configuration exactly. Renamed PurchaseReqSetup."Prevent Starting Int. Qs" to "Allow Starting Int. Qs" (inverted polarity, dropped InitValue) so the safe "hold base job queues" behaviour is the default even before the setup record exists, instead of the old bug where a missing record meant "don't hold." Fixed ResetVendCatItemMapping/ResetVendCatItemCatMapping passing UseSystemID=true when the reference config has it off. Added missing GetDefaultDirection case entries for Req. Ship-to Address_REQ_TSL and Vend. Cat. Item Cat._REQ_TSL (previously relying on the else fallback), removed dead entries for General Ledger Setup and unused standard Ship-to Address. Explicitly set Deletion-Conflict Resolution/Update-Conflict Resolution on all 14 mappings that need them (Delete Records_DI_TSL + Send Update to Integration, except PRDOCUMENTATTACHMENT which gets Get Update from Integration) so this no longer relies on an unverifiable dependency-app default; PRPURCHREQHDR/PRPURCHREQLINE intentionally left unset per the reference config. Removed the "Set Up Synchronization" actions from JobListDV/JobTaskLinesDV/DimensionValuesDV page extensions (the actual cause of PR* mapping job queues getting activated) and merged PurchReqListDV/PurchReqLineSubDV page extensions into their own base pages, deduplicating the overlapping Sync/Coupling actions. |
| 1.12 | 2026-07-06 | US #96930: added RemoveUnwantedBaseMappings to CDSSetupDefaults, called first thing in the OnAfterResetConfiguration subscriber. Microsoft's base CDS Setup Defaults.ResetConfiguration unconditionally creates SALESPEOPLE, CUSTOMER, CONTACT, PAYMENT TERMS, SHIPMENT METHOD, and SHIPPING AGENT mappings (plus TRANSACT-TRANSACT in some scenarios) before our subscriber ever runs, and we can't prevent Microsoft's own code from creating them — so instead we delete them (and their job queue entries) immediately after, keeping only CURRENCY and VENDOR per the reference configuration. |
| 1.13 | 2026-07-06 | US #96930: made the VENDOR field mapping match the manually-verified reference config exactly. Extended OnAfterResetVendorAccountMapping (already used to add our DimensionObject_REQ_TSL field) to also add a Mobile Phone No. → Other Phone (Telephone2) field mapping that didn't exist in any code, and to disable (Status = Disabled) five fields per the reference: Fax No., Shipment Method Code, Shipping Agent Code, Payment Terms Code, Mobile Phone No. — added helper DisableVendorFieldMapping. |
| 1.14 | 2026-07-06 | US #96930: CURRENCY and VENDOR (the two standard MS mappings we keep) were also missing Deletion-Conflict Resolution/Update-Conflict Resolution on a fresh reset, same issue as our own mappings. Fixed VENDOR in OnAfterResetVendorAccountMapping (Delete Records_DI_TSL + Send Update to Integration). Added SetCurrencyMappingConflictResolution, called from the main OnAfterResetConfiguration subscriber, for CURRENCY (Remove Coupling/"Delete coupling" + Send Update to Integration) since there's no dedicated OnAfterResetCurrencyTransactionCurrencyMapping event to hook into. |
| 1.15 | 2026-07-06 | US #96930: compared a live "Setup Default Synchronisation" run against the manually-verified reference via an exported Excel workbook, found two things. (1) Our OnAfterResetVendorAccountMapping's explicit Mobile Phone No. → Other Phone insert was a duplicate — Microsoft's own CRM Integration Management.AddExtraFieldMappings already adds that exact mapping automatically (disabled by default); removed our redundant copy and the matching DisableVendorFieldMapping call. (2) That same Microsoft mechanism also auto-adds VENDOR's No. → Account Number field mapping, always Disabled — but the reference has it Enabled, and nothing enabled it. Added a new OnAfterAddExtraFieldMappings subscriber (on CRM Integration Management, which fires after the auto-add, unlike our per-mapping subscriber) that enables it for VENDOR specifically. Also, ResetVendCatItemMapping's Dependency Filter was `'SALESPEOPLE |
| 1.16 | 2026-07-08 | US #97094: replaced the standard Microsoft VENDOR and CURRENCY mappings with our own PRVENDOR and PRCURRENCY in CDSSetupDefaults — both standard names are now deleted by RemoveUnwantedBaseMappings like the other base mappings. New ResetVendorMapping/ResetCurrencyMapping reproduce the reference configuration directly (conflict resolutions, No. → Account Number enabled + match-based coupling, DimensionObject, Contact/Country/Region Code/Primary Contact No./Mobile Phone No./Fax No./Shipment Method/Shipping Agent/Payment Terms created disabled per a live-export comparison against the reference VENDOR mapping, no SystemID coupling, BCIVENDOR CDS config template ensured), making the SetCurrencyMappingConflictResolution, DisableVendorSystemIdCoupling, OnAfterResetVendorAccountMapping, and OnAfterAddExtraFieldMappings patches redundant (all removed). Synch. Only Coupled Records is on only for PRCURRENCY; PRVENDOR uses match-based coupling on No.. PRVENDOR is Bidirectional like the reference (changed GetDefaultDirection's Database::Vendor entry from ToIntegrationTable), with No. → Account Number and DimensionObject as the two ToIntegrationTable field rows. PRVENDCATITEM dependency filter and the PRALL Integration Job Group seed list now reference `PRVENDOR |
| 1.17 | 2026-07-20 | US #95676: made the auto-release of the Purchase Order on PR→PO conversion (introduced in US #97108) configurable via setup. Added PurchaseReqSetup_REQ_TSL field 216 "Auto Release PO on Convert" (Boolean, InitValue = true), shown in the Auto Conversion group of PurchaseReqSetup_REQ_TSL (page 71025828). Gated the existing ReleasePurchaseOrder call in Purch. Request Mgmt._REQ_TSL behind a new AutoReleasePOOnConvertEnabled() helper (defaults to releasing when no setup record exists, preserving the US #97108 behaviour). Added a new Upgrade_REQ_TSL codeunit (71025866, Subtype = Upgrade) that turns the toggle on for existing setup records once — guarded by a per-company upgrade tag so it never overrides a later user choice — so current behaviour is preserved on upgrade while fresh installs get it from InitValue. Registered the codeunit in ReqCatItem_REQ_TSL permission set and object-ids.json. |
Note: This document should be updated when:
- New major features are added
- Significant architectural changes occur
- New integration points are created
- Object IDs or naming conventions change