Freeze for Dynamics 365 BC - en-US Manual for the administration and use of Freeze for Microsoft Dynamics 365 Business Central. With the Freeze Archive integration for Microsoft Dynamics 365 Business Central, you can access your audit-proof stored data and documents directly via the tried-and-tested Microsoft interface. Freeze Archive automatically links the documents to their business objects and also offers detailed search options via the index features and the full text of your documents. System Requirements System requirements for using FREEZE for Dynamics 365 BC Supported Microsoft Dynamics 365 Business Central versions Microsoft Dynamics 365 Business Central integration is possible from the following version due to minimum technical requirements: Supportet Microsoft Dynamics 365 Business Central Versions The prerequisite for operation is that the respective Microsoft Dynamics 365 Business Central version is still in regular support. The extended support is excluded.   Supported FREEZE versions A licensed FREEZE system is required to connect FREEZE to Microsoft Dynamics 365 Business Central and for operation. Installation Licenses Microsoft Information about the Microsoft Business Central licenses . FREEZE The DEXPRO FREEZE system that should be connected to Business Central requires a valid customer license. Obtaining the DEXPRO modules Detailed Information are here . OnPrem For OnPrem installations, an runtime package with the required apps is provided upon request of a registered reseller / partner. These modules are added to the customer license by the partner and then imported into Microsoft Dynamics Business Central. It should be noted that the DEXPRO Core module forms the basis for all DEXPRO modules and must therefore be imported first. Cloud For cloud installations, you only need the Microsoft AppSource . This is where the required DEXPRO modules are downloaded.   Configuration & Administration Permission sets In order to use the modules, the appropriate authorization set must be assigned to the respective users. The following are supplied with: DXP Core Admin -  DEXPRO Core Administrator DXP Core User -  DEXPRO Core User DXP FREEZE Admin -  DEXPRO FREEZE Administrator DXP FREEZE User -  DEXPRO FREEZE User Freeze Permission Sets DXP Freeze Admin : Full access (Read, Insert, Modify, Delete) to all Freeze tables and execution rights for all Freeze pages and codeunits. Suitable for administrators who manage the Freeze setup. DXP Freeze User : Access to all Freeze functions with restricted write permissions on setup tables (Setup, Store, User Setup, Additional Queries). Suitable for standard users who use Freeze on a daily basis. DEXPRO Core The DEXPRO Core manages the individual DEXPRO apps and their documents per client. All documents that have been entered and processed via the various DEXPRO modules in Microsoft Dynamics 365 Business Central are displayed. A global number series, which is used across all DEXPRO apps, is used to track individual documents. This offers the advantage that users only have to work with one number series per document. Further information can be found here . Freeze Setup In the FREEZE setup, both the connection to the Freeze Archive System and the processing within the app are set up. Menu Home Copy Setup This is used to copy the setup to another company. Upload Placeholder This function is used to upload a placeholder for file types that the PDF viewer cannot display. Navigation Document Class Setup This menu item takes you to the setup for the document classes . OAuth 2.0-Setup The users and their access tokens for OAuth 2.0 authentication are managed in this menu item . User Setup You can access the user assignment to the OAuth users via this menu item . Additional Search Queries Setting up additional search queries is particularly useful if you want to display archive folders that have not been archived via Freeze in BC. However, there are also other use cases. FastTabs General You can activate/deactivate the use of this app in this FastTab.   API The URL of the FREEZE system is specified in this fast tab. The default archive storage and the default authentication are also stored. You can also specify here how many archive data records should be displayed simultaneously during searches. Archiving Settings can be made here as to what should be archived automatically. Automatic archiving after posting a receipt. Printing and archiving in one step. Archiving of emails with attachments if they are sent via the BC Email module. Field Descriptions General Activated : Enables or disables the Freeze app for the current company. Attachments mandatory : When enabled, attachments are required when manually archiving a record. Validate Attachment Filesize : When enabled, the system validates that no attachment has a file size of 0 during manual archiving. This helps prevent archiving defective files. Max Results : Specifies the maximum number of search results to retrieve (topn parameter). Search Mode : Controls which versions are displayed in archive searches. Possible values: Default (store configuration), All Versions , Newest Version Only . Maximum Recent Records : Specifies how many recently archived records per document are shown in the "Recent Entries" FactBox (default: 5). API URL : The base URL of the connected FREEZE archive system. Default Authentication : The OAuth 2.0 authentication used by default for API access. Default Store : The archive store used by default for searching and archiving. Records per page : Number of records (folders) displayed per page in search results (default: 15). Alternative PDF Viewer URL : For on-premises environments with restricted internet access, an alternative URL for the PDF viewer can be specified. This field is hidden by default. Archiving – General Archive Attachments : Archives attachments linked to the corresponding record in Business Central. Archive Incoming : Archives incoming documents linked to the record in Business Central. Archive Email & Attachments : Archives email attachments sent via the BC email module, e.g. for posted documents, quotes, or orders. Archiving – Purchasing Archive after Posting : Enables automatic archiving of purchase documents after posting. Archive Outgoing : Additionally archives outgoing standard reports after posting. The print count is incremented in the process. Purchase Invoice : Archives outgoing purchase invoices after posting. Purchase Cr. Memo : Archives outgoing purchase credit memos after posting. Purchase Receipt : Archives outgoing purchase receipts after posting. Purchase Ret. Shpt : Archives outgoing purchase return shipments after posting. Archiving – Sales Archive after Posting : Enables automatic archiving of sales documents after posting. Archive Outgoing : Additionally archives outgoing standard reports after posting of sales documents. Archiving – General Journal Archive after Posting : Archives the resulting G/L Register after posting a General Journal. Freeze Storage The archive memories of the connected Freeze System are managed here.   Fields Name : The unique name of the archive store. Description : An optional description of the archive store. API Link : The API URL of the archive store. This is automatically retrieved from the FREEZE system. Archive stores are automatically synchronized from the connected FREEZE system when the page is opened. The store specified as Default Store in the Freeze Setup is used preferentially for searches and archiving operations. Document Class Setup In the document class setup, the mapping between the respective document class and your export interface is done. Furthermore, the field mapping of each document class is downloaded here, creating a set of standard fields and their usage in Microsoft Dynamics 365 Business Central. The document class setup is cross-app and is managed via the DEXPRO Core. Process Download field mapping This downloads the field structure of the SQUEEZE document class. These are needed for the metadata mapping . Navigation Metadata mapping Via this menu item you reach the metadata mapping . This defines which fields are to be transferred to Microsoft Dynamics 365 Business Central and how. List Document classes This overview lists all the document classes that have been set up. Card Document class Here, each document class is set up individually. General In this fastab the name of the document class, the next process step, as well as the automatic enrichment of the positions is set up. Freeze The standard search mask is defined here. User Setup Alternative authentication: If users are to access the archive with alternative authentication, this can be entered here. Show all results: The additional search queries (just like the full text search) only provide results for users who have been explicitly authorized to do so. This is necessary because archive folders that have not been archived via BC cannot be checked for effective authorizations due to the lack of a table number. OAuth 2.0 Setup The OAuth 2.0 / Open Id users and their access tokens are managed here.   Additional search queries Creation of additional search queries Below I have created a query that is appended to the system search query when you open Freeze via a record (here: vendor items - table 25). Search queries with the same table number are OR-linked.   Creation of additional search queries You can access the query lines via Related : Search by field name - Specifies the value of the field name to be used for the search query. These are the native fields of the archive software, but also data record fields saved in any form: Search value source (field no.) - Specifies the value to be searched for in combination with the field name. Fixed search value - The fixed search term is used instead of the search value. The query lines are AND-linked. Show the result If you then open the vendor item Freeze... ...you will get the desired search result: Do not forget: The additional search queries (just like the full text search) only provide results for users who have been explicitly authorized to do so in the setup . This is necessary because archive folders that have not been archived via BC cannot be checked for effective authorizations due to a lack of table numbers. Record Types Record Types define the categorization of archive folders in FREEZE. Each archived record is assigned a Record Type, which can later be used for filtering and searching. Available Record Types Miscellaneous – Default type for general documents Quotes Orders Blanket Orders Return Orders Invoices Credit Memos Payments Finance Charge Memos Reminders Refunds Contracts Claims Setup On the Freeze Record Types page, you can specify for each Record Type whether it should be used as the Default for certain document tables. This ensures that the appropriate Record Type is automatically assigned during automatic archiving. When manually archiving (Quick Freeze), users are shown a dialog where they can set the Record Type, Record Title, and Reference Date. FactBox: Count per Record Type On the search result page, the Record Type Count FactBox shows how many archive folders exist per Record Type for the current record. Application / Use Archive search of documents Freeze Searchmask The Freeze search mask enables a full-text search as well as a search based on table fields according to the Apache Lucene syntax . It is also possible to display results for specific time periods. 1. Full text search A free search according to Apache Lucene syntax . 2. Folder type filter Here you can filter the results by folder type (e.g. invoices). This filter is used in combination with the other search parameters. 3. Date filter The date filter allows you to narrow down the results by archiving or reference date. 4. Table search mask At this point, select any table whose structure you would like to use as a search mask. The table number is then part of the search. Apache Lucene-Syntax A query is divided into terms and operators. There are two types of terms: Single terms and phrases. A single term is a single word such as “test” or “hello”. A phrase is a group of words surrounded by double quotation marks, such as “hello dolly”. Multiple terms can be combined with Boolean operators to form a more complex query. The following Boolean operators are supported: AND, OR and NOT. For example, the query “hello AND world” returns documents that contain both the words “hello” and “world”. The following characters must be escaped in a query: + - && || ! ( ) { } [ ] ^ “ ~ * ? : \ To escape a character, simply place a backslash (\) in front of the character. Wildcards can be used to search for words that contain a specific character string. The asterisk (*) stands for zero or more characters, while the question mark (?) stands for exactly one character. The query “te?t”, for example, returns documents containing words such as “test”, “text” and “tent”. Data record-based search The data record-based search is always executed when you open Freeze via a data record saved in BC (menu item “DEXPRO Freeze” or key combination CTRL+ALT+F). Here is an example of a vendor:   Typical jumping off points: customers creditors items Purchasing documents Sales documents Posted documents Financial accounting journals Ledger Entries Archiving of documents The following can be archived... Archiving after Posting When the option Archive after Posting is enabled in the respective area (Purchasing, Sales, General Journal) in the Freeze Setup , the corresponding documents are automatically archived after posting. This includes: Purchase invoices, purchase credit memos, purchase receipts, purchase return shipments Sales documents General journal entries (the resulting G/L register is archived) Archiving of Outgoing Documents When Archive Outgoing is enabled, standard reports (e.g. printed invoices) are archived after posting. The print count is incremented in the process. Archiving of E-Mails When Archive Email & Attachments is enabled, email attachments sent via the BC email module are automatically archived. This applies to posted documents as well as quotes and orders. Archiving of Incoming Documents When Archive Incoming is enabled, incoming documents linked to a record in Business Central are archived. Archiving of Linked Attachments When Archive Attachments is enabled, all attachments within Business Central that are linked to the record are archived. Manual Archiving (Quick Freeze) On most document and master data pages, the Quick Freeze action is available as a FactBox. Users can manually archive files via drag-and-drop or the upload dialog. The files are directly assigned to the current record in the archive. Freeze Queue Entries All archiving processes are listed and processed here. Queue Entry Fields Entry No. : Sequential number of the queue entry. Record Title : Title of the record to be archived. Record Type : The type of archive folder (e.g. Invoice, Credit Memo, Miscellaneous). Status : The current status of the entry: Imported – The entry has just been created and is waiting to be picked up. Waiting – The entry is queued and will be archived on the next processing run. Processed – The record has been sent to the Freeze archive and is awaiting verification. Archived – Archiving was completed and verified successfully. Error – An error has occurred (see Error Notice / Last detailed error). Error Notice : Brief error description for failed archiving operations. Last detailed error : Full error message with details. Retry count : Number of retry attempts so far. Reference Date : The reference date under which the record is stored in the archive. Attachment count not matching : Indicates whether the number of local attachments matches the count in the archive. The processing Job Queue Entry Queue entries are processed automatically by codeunit 70954898 DXP Freeze Queue Processing . You do not have to create this Job Queue Entry manually: it is created automatically the first time the Freeze Setup page is opened. Object Type : Codeunit Object ID : 70954898 Recurrence Interval : 1 minute Initial status : On Hold – an administrator must set the entry to Ready to start automatic processing. On each run, the job works through the queue in the following order: it first clears entries that are already Archived , then retries entries in Error (up to a maximum of 3 retries), verifies entries in Processed against the archive, and finally archives entries in Waiting . Quick Freeze The Quick Freeze FactBox enables manual archiving of files directly from documents and master data pages. How it works Open a document or master data page (e.g. Purchase Invoice, Customer Card, Vendor Card). Use the Quick Freeze FactBox on the right side: Drag and drop files into the designated area, or Click Upload file to select files via the file picker dialog. A dialog opens where you can specify: Record Type : Type of the archive folder (e.g. Invoice, Credit Memo). Record Title : An optional custom title. Reference Date : Date under which the record is stored (default: work date). The files are added to the Freeze queue and archived in the background. Availability The Quick Freeze FactBox is available on all pages where Freeze Page Extensions are active. This includes: Purchase documents: Orders, Invoices, Credit Memos, Return Orders, Quotes Sales documents: Orders, Invoices, Credit Memos, Return Orders, Quotes Posted documents: Posted Purchase Invoices, Posted Purchase Receipts, Posted Sales Invoices, Posted Sales Shipments, etc. Master data: Customer Card, Vendor Card, Item Card Ledger entries: Customer Ledger Entries, Vendor Ledger Entries, G/L Entries, G/L Registers General Journals PDF Viewer The integrated PDF Viewer allows viewing PDF attachments directly within Business Central without leaving the application. Features FactBox : The PDF Viewer is displayed as a FactBox on the search result page. When selecting an attachment, the PDF is rendered directly in the FactBox. Full screen view : The full-screen page allows viewing a PDF in a larger format. Alternative PDF Viewer URL : For on-premises environments with restricted internet access, an alternative URL for the PDF Viewer can be configured in the Freeze Setup. Supported File Formats The PDF Viewer displays PDF files directly. For other file formats, a placeholder PDF can be uploaded in the Freeze Setup, which is displayed instead of the file that cannot be rendered. Recent Entries The Recent Entries FactBox shows the most recent archiving operations performed for the currently opened record. Displayed Information Title : The record title of the archived record. Type : The record type (e.g. Invoice, Credit Memo). Version : The version number of the archive record. Created DateTime : Date and time of the archiving operation. Configuration The maximum number of displayed entries can be controlled via the Maximum Recent Records field in the Freeze Setup (default: 5). Navigation Clicking an entry opens the archive folder directly in the Freeze search result, allowing you to view the associated attachments and fields. Page Extensions Freeze extends numerous standard pages in Business Central with archiving functions. The following features are available on each extended page: Available Actions Open Freeze : Opens the Freeze archive search in the context of the current record. The search automatically uses the appropriate fields (e.g. document number, vendor, customer) as search criteria. Freeze now : Immediately archives the current record together with its file attachments. The archiving job for the record is added to the Freeze queue and a notification confirms the queued session. Available FactBoxes Quick Freeze : Enables manual uploading and archiving of files via drag-and-drop. Recent Entries : Shows the most recent archiving operations for the current record. Count per Record Type : Shows the number of archive folders per Record Type. Extended Pages Purchasing Purchase Order / Purchase Orders Purchase Invoice / Purchase Invoices Purchase Credit Memo / Purchase Credit Memos Purchase Quote / Purchase Quotes Purchase Return Order / Purchase Return Orders Posted Purchase Invoice / Posted Purchase Invoices Posted Purchase Receipt / Posted Purchase Receipts Posted Purchase Credit Memo / Posted Purchase Credit Memos Posted Return Shipment / Posted Return Shipments Sales Sales Order / Sales Orders Sales Invoice / Sales Invoices Sales Credit Memo / Sales Credit Memos Sales Quote / Sales Quotes Sales Return Order / Sales Return Orders Posted Sales Invoice / Posted Sales Invoices Posted Sales Shipment / Posted Sales Shipments Posted Sales Credit Memo / Posted Sales Credit Memos Posted Return Receipt / Posted Return Receipts Master Data Customer Card / Customer List Vendor Card / Vendor List Item Card / Item List Ledger Entries & Registers Customer Ledger Entries Vendor Ledger Entries G/L Entries G/L Registers General Journals VAT Report / VAT Reports Extension Development This chapter lists important integration events and examples to help you develop an extension for Freeze for MSDynamics 365 Business Central Important: Adaptations may only be carried out by appropriately trained consultants/developers. Furthermore, these are always outside the standard support provided by DEXPRO. Attachment Download Overview The DXP Freeze Result Management codeunit provides two primary methods for downloading archived attachments as ZIP files: DownloadAttachmentsAsZipWithPagination  - Downloads attachments from search query results with pagination support DownloadAttachmentsAsZipFromRecord  - Downloads attachments from specific Business Central records Both methods organize attachments into structured ZIP archives with comprehensive metadata for audit and tracking purposes. Method 1: DownloadAttachmentsAsZipWithPagination Purpose Downloads all attachments from a search query result set, processing results page by page to handle large datasets efficiently. Each record’s attachments are organized into individual ZIP files within a main ZIP archive. Overloads Available 1. Basic Usage procedure DownloadAttachmentsAsZipWithPagination(SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer): Boolean 2. With Filters procedure DownloadAttachmentsAsZipWithPagination(SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer; FilenameFilter: Text; FileExtensionFilter: Text): Boolean 3. Full Control procedure DownloadAttachmentsAsZipWithPagination(SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer; FilenameFilter: Text; FileExtensionFilter: Text; StoreApiLink: Text; RecordsPerPage: Integer; SuppressDialog: Boolean): Boolean 4. Pre-populated Records (Advanced) procedure DownloadAttachmentsAsZipWithPagination(var TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary; var TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary; var TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary; var TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary; SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer; FilenameFilter: Text; FileExtensionFilter: Text; SuppressDialog: Boolean): Boolean Parameters Parameter Type Description SearchQuery Text Freeze search query string. If empty in pre-populated overload, uses existing query or re-executes search ZipArchive Codeunit “Data Compression” ZIP archive object that will contain the downloaded files AttachmentCount Integer (var) Returns the total number of attachments downloaded FilenameFilter Text Filter for attachment filenames (e.g., ‘ .pdf’, 'invoice ’) FileExtensionFilter Text Filter for file extensions (e.g., ‘pdf’, ‘docx’) StoreApiLink Text Optional specific store API link RecordsPerPage Integer Number of records per page (default: 100) SuppressDialog Boolean Whether to suppress progress dialog Return Value Boolean :  true  if attachments were found and downloaded;  false  otherwise Example Usage Basic Download procedure DownloadSearchResults() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; FileMgt: Codeunit "File Management"; TempBlob: Codeunit "Temp Blob"; AttachmentCount: Integer; InStr: InStream; OutStr: OutStream; SearchQuery: Text; begin SearchQuery := 'invoice AND 2024'; if ResultMgt.DownloadAttachmentsAsZipWithPagination(SearchQuery, ZipArchive, AttachmentCount) then begin // Save ZIP to file TempBlob.CreateOutStream(OutStr); ZipArchive.SaveZipArchive(OutStr); TempBlob.CreateInStream(InStr); FileMgt.DownloadFromStreamHandler(InStr, '', '', '', 'SearchResults.zip'); Message('Downloaded %1 attachments successfully.', AttachmentCount); end else Message('No attachments found for the search query.'); end; With Filters procedure DownloadPDFInvoices() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; AttachmentCount: Integer; SearchQuery: Text; begin SearchQuery := 'type:invoice'; if ResultMgt.DownloadAttachmentsAsZipWithPagination( SearchQuery, ZipArchive, AttachmentCount, '*.pdf', // Only PDF files 'pdf' // File extension filter ) then begin // Process the ZIP archive ProcessDownloadedFiles(ZipArchive, AttachmentCount); end; end; Using Pre-populated Records procedure DownloadFromExistingResults() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary; TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary; TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary; TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary; ZipArchive: Codeunit "Data Compression"; AttachmentCount: Integer; begin // Assume these records are already populated from a previous search PopulateSearchResults(TempFrzResultQueryHeader, TempFrzResultRecordHeader, TempFrzResultRecordField, TempFrzAttachmentResult); // Download using existing results without re-executing search if ResultMgt.DownloadAttachmentsAsZipWithPagination( TempFrzResultQueryHeader, TempFrzResultRecordHeader, TempFrzResultRecordField, TempFrzAttachmentResult, 'invoice search', // SearchQuery - if empty, will re-execute search ZipArchive, AttachmentCount, '', // No filename filter '', // No extension filter true // Suppress dialog ) then begin ProcessDownloadedFiles(ZipArchive, AttachmentCount); end; end; ZIP Structure (Pagination) SearchResults.zip ├── export-metadata.json ├── Invoice_001_V1_20241201_1430.zip │ ├── {GUID}_invoice.pdf │ └── {GUID}_supporting_doc.docx ├── PurchaseOrder_002_V2_20241202_0900.zip │ └── {GUID}_po_document.pdf └── Contract_003_V1_20241203_1200.zip ├── {GUID}_contract.pdf └── {GUID}_amendment.pdf Method 2: DownloadAttachmentsAsZipFromRecord Purpose Downloads attachments from specific Business Central records. Each selected record’s attachments are organized into individual ZIP files within a main ZIP archive. Overloads Available 1. Basic Usage procedure DownloadAttachmentsAsZipFromRecord(var SelectedRecord: RecordRef; var ZipArchive: Codeunit "Data Compression"): Boolean 2. With Filters procedure DownloadAttachmentsAsZipFromRecord(var SelectedRecord: RecordRef; var ZipArchive: Codeunit "Data Compression"; FilenameFilter: Text; FileExtensionFilter: Text): Boolean Parameters Parameter Type Description SelectedRecord RecordRef (var) RecordRef containing the selected Business Central records ZipArchive Codeunit “Data Compression” ZIP archive object that will contain the downloaded files FilenameFilter Text Filter for attachment filenames FileExtensionFilter Text Filter for file extensions Return Value Boolean :  true  if attachments were found and downloaded;  false  otherwise Example Usage Download from Sales Invoices procedure DownloadInvoiceAttachments() var SalesInvoiceHeader: Record "Sales Invoice Header"; ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; RecordRef: RecordRef; HasAttachments: Boolean; begin // Select specific invoices SalesInvoiceHeader.SetRange("Posting Date", DMY2Date(1, 1, 2024), DMY2Date(31, 12, 2024)); SalesInvoiceHeader.SetFilter("Sell-to Customer No.", '10000|20000'); if SalesInvoiceHeader.FindSet() then begin RecordRef.GetTable(SalesInvoiceHeader); HasAttachments := ResultMgt.DownloadAttachmentsAsZipFromRecord(RecordRef, ZipArchive); if HasAttachments then SaveZipFile(ZipArchive, 'InvoiceAttachments.zip') else Message('No attachments found for the selected invoices.'); end; end; Download with Filters from Page // In a page extension action(DownloadAttachmentsFiltered) { Caption = 'Download Filtered Attachments'; Image = ExportFile; trigger OnAction() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; RecordRef: RecordRef; FilenameFilter: Text; FileExtensionFilter: Text; begin // Show filter dialog if ShowFilterDialog(FilenameFilter, FileExtensionFilter) then begin CurrPage.SetSelectionFilter(Rec); RecordRef.GetTable(Rec); if ResultMgt.DownloadAttachmentsAsZipFromRecord( RecordRef, ZipArchive, FilenameFilter, FileExtensionFilter ) then DownloadZipFile(ZipArchive, 'FilteredAttachments.zip'); end; end; } ZIP Structure (Records) RecordAttachments.zip ├── export-metadata.json ├── Sales_Invoice_Header_Company_SI-001.zip │ ├── {GUID}_invoice.pdf │ └── {GUID}_terms.pdf ├── Sales_Invoice_Header_Company_SI-002.zip │ └── {GUID}_invoice.pdf └── Sales_Invoice_Header_Company_SI-003.zip ├── {GUID}_invoice.pdf ├── {GUID}_delivery_note.pdf └── {GUID}_receipt.jpg Metadata Structure Both methods generate comprehensive metadata in  export-metadata.json : Pagination Export Metadata { "exportInfo" : { "exportTimestamp" : "2024-12-19T10:13:52.248Z" , "exportedBy" : "USER001" , "searchQuery" : "type:invoice AND year:2024" , "totalRecordsFound" : 150 , "totalPages" : 15 , "exportType" : "paginated-search" , "description" : "Freeze Search Query Export" } , "appliedFilters" : { "filenameFilter" : "*.pdf" , "fileExtensionFilter" : "pdf" } , "statistics" : { "pagesProcessed" : 15 , "totalRecordsProcessed" : 150 , "recordsWithAttachments" : 120 , "recordsWithoutAttachments" : 30 , "totalAttachments" : 245 , "exportCompletedAt" : "2024-12-19T10:15:33.021Z" } , "records" : [ { "recordId" : "{GUID}" , "title" : "Invoice INV-2024-001" , "version" : 1 , "archivedAt" : "2024-12-01T09:30:00Z" , "archivedBy" : "SYSTEM" , "type" : "Sales Invoice" , "masterId" : "{GUID}" , "attachmentCount" : 3 , "hasAttachments" : true , "zipFile" : "Invoice_INV-2024-001_V1_20241201_0930.zip" } ] } Record Export Metadata { "exportTimestamp" : "2024-12-19T14:30:00Z" , "exportedBy" : "USER001" , "totalRecordsProcessed" : 25 , "description" : "DXP Freeze Attachments Export" , "sourceTable" : { "tableNumber" : 112 , "tableName" : "Sales Invoice Header" , "tableCaption" : "Posted Sales Invoice" } , "appliedFilters" : { "filenameFilter" : "*.pdf" , "fileExtensionFilter" : "pdf" } , "statistics" : { "totalAttachments" : 45 , "recordsWithAttachments" : 20 , "recordsWithoutAttachments" : 5 , "totalZipFiles" : 20 } , "records" : [ { "recordId" : "Sales Invoice Header: Company, SI-001" , "systemId" : "{GUID}" , "primaryKey" : { "fields" : [ { "fieldName" : "No." , "fieldValue" : "SI-001" , "fieldType" : "Code" } ] } , "hasAttachments" : true , "attachmentCount" : 2 , "zipFile" : "Sales_Invoice_Header_Company_SI-001.zip" } ] } Performance Considerations Pagination Method Large Result Sets : Automatically handles pagination to process large datasets efficiently Memory Management : Processes one page at a time, clearing memory between pages Progress Tracking : Shows real-time progress for long-running operations Recommended For : Search queries that may return hundreds or thousands of records Record Method Selected Records : Processes only the records you specifically select Direct Processing : No pagination overhead for smaller datasets Batch Processing : Efficient for processing specific record sets Recommended For : Targeted downloads from specific Business Central records Error Handling Both methods include comprehensive error handling: Common Scenarios No Results Found : Returns  false  when no records or attachments are found Permission Issues : Automatically excludes records the user cannot access API Failures : Gracefully handles API communication errors Empty Filters : Handles empty or invalid filter parameters Best Practices // Always check return value if not ResultMgt.DownloadAttachmentsAsZipWithPagination(SearchQuery, ZipArchive, AttachmentCount) then begin Message('No attachments found or download failed.'); exit; end; // Validate attachment count if AttachmentCount = 0 then begin Message('Search completed but no attachments matched the criteria.'); exit; end; // Handle large downloads if AttachmentCount > 1000 then if not Confirm('This will download %1 attachments. Continue?', false, AttachmentCount) then exit; Integration Events Both methods support integration events for customization: Available Events OnBeforeDownloadAttachmentsAsZip : Modify behavior before download starts OnBeforeProcessAttachmentForZip : Skip or modify individual attachments OnAfterGetAttachmentBase64 : Modify attachment content after retrieval OnAfterAddAttachmentToZip : Perform actions after adding to ZIP OnNoAttachmentsFound : Handle no attachments scenario Example Integration [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP FRZ Result Mgt.", 'OnBeforeProcessAttachmentForZip', '', false, false)] local procedure OnBeforeProcessAttachmentForZip(var TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary; var IsHandled: Boolean) begin // Skip attachments larger than 10MB if TempFrzAttachmentResult.Filesize > 10485760 then IsHandled := true; end; File Naming Conventions Automatic Sanitization All filenames are automatically sanitized using the  SanitizeFileName  method: Invalid characters ( < > : " / \ | ? * ) are replaced with underscores Spaces are replaced with underscores Maximum filename lengths are enforced Unique Naming Individual Files : Include attachment GUID prefix to ensure uniqueness ZIP Files : Include record information and timestamps No Conflicts : Guaranteed unique names within each ZIP archive Finding an archived document via search Finding an archived document via search The Attachment Download page describes how to download the attachments of an archive record you have already found. This page covers the step before that: how to find the matching archive record – including cross-company , e.g. in an intercompany scenario to locate the sales document of the partner company from a purchase invoice. Process Build a search term (Lucene query) Submit the search to Freeze Load the result and its attachments into temporary tables Download the attachments (see the "Attachment Download" page) Public procedures used DXP Freeze Search Mgt. (Codeunit 70954893) Procedure Purpose GetSearchCombinationForTable(SystemId: Guid; TableNo: Integer): Text Ready-made query for a local document (SysLink + customer/vendor + current company). ToSafeSearchTerm(OldSearchTerm: Text): Text Lucene escaping + URL encoding of a search value. Use for every dynamic value. SystemLinkSearchQuery(SystemId: Guid; TableNo: Integer): Text Building block SysLink:{GUID}-{TableNo} . Cross-company: GetSearchCombinationForTable cannot be used here – it requires the SystemId of the original document and automatically appends the current CompanyName() . To search in another company, build your own query and set the partner company explicitly via the Company field. DXP Freeze API Mgt. (Codeunit 70954891) Procedure Purpose SubmitSearch(SearchQuery: Text): JsonObject Submit a search (1 result/page). SubmitSearch(SearchQuery: Text; ItemsPerPage: Integer): JsonObject Search with page size. SubmitSearch(SearchQuery: Text; StoreName: Text[30]): JsonObject Search in a specific store. DXP FRZ Result Mgt. (Codeunit 70954894) Procedure Purpose CreateResultForAttachments(QueryResult: JsonObject; var TempFrzResultRecordHeader; var TempFrzAttachmentResult; SearchQueryTxt: Text) Loads results + attachment metadata from the JSON into temporary tables. HasRecord(SearchString: Text): Boolean Checks whether there is any result at all. GetEffectiveResultsCount(SearchString: Text): Integer Returns the number of results. Query structure A query consists of FieldName:"Value" pairs joined with AND / OR . Field names use _ instead of spaces/special characters (e.g. Sell_to_Customer_No ). Always escape values via ToSafeSearchTerm . Example – sales invoice by document number, document type and company: (No:"SO-2026-001" AND Document_Type:"2" AND Company:"SALES INC") Document_Type:"2" corresponds to the Invoice document type. Code example procedure FindSalesDocInArchive(SalesDocNo: Code[20]; PartnerCompany: Text): Boolean var TempResultHeader: Record "DXP FRZ Record Result Header" temporary; TempAttachment: Record "DXP FRZ Attachment Result" temporary; FrzApiMgt: Codeunit "DXP Freeze API Mgt."; FrzResultMgt: Codeunit "DXP FRZ Result Mgt."; FrzSearchMgt: Codeunit "DXP Freeze Search Mgt."; QueryResult: JsonObject; SearchQuery: Text; Base64: Text; begin // 1) Build the query (cross-company) SearchQuery := StrSubstNo( '(No:"%1" AND Document_Type:"2" AND Company:"%2")', FrzSearchMgt.ToSafeSearchTerm(SalesDocNo), FrzSearchMgt.ToSafeSearchTerm(PartnerCompany)); // 2) Submit the search QueryResult := FrzApiMgt.SubmitSearch(SearchQuery, 50); // 3) Load results + attachments FrzResultMgt.CreateResultForAttachments( QueryResult, TempResultHeader, TempAttachment, SearchQuery); if TempAttachment.IsEmpty() then exit(false); // 4) Fetch the attachment as Base64 (see "Attachment Download" page) TempAttachment.FindSet(); repeat Base64 := FrzApiMgt.GetSpecificRecordAttachment( TempAttachment."File Link", TempAttachment.ID, TempAttachment.Filename, false); // false = no direct browser download // ... process Base64 (e.g. store as document attachment) until TempAttachment.Next() = 0; exit(true); end; Note: Storing into the document attachment (table "Document Attachment", 1173) is standard Business Central functionality and not part of the Freeze module. Archiving files Depending on the setup, Freeze archives automatically in various situations (for example after posting sales or purchase documents). The following describes which procedures a developer can call to initiate the archiving of a folder including its file attachments. Let us assume you want to archive a new archive folder with one or more file(s). First, add the values that correspond to your files to the temporary record of type "DXP FRZ Attachment Buffer". To keep this simple, we recommend using the following procedure: codeunit 70954897 "DXP FRZ Attachment Mgt.": procedure AddFileFromStream(var TempFRZAttachmentBuffer: Record "DXP FRZ Attachment Buffer" temporary, var InStr: InStream, FileName: Text) Next, call the following procedure to create an entry in the Freeze processing queue that contains the folder details and attachments used to create the archive entry. codeunit 70954899 "DXP Freeze Queue Buffer Mgt.": procedure InsertQueueBufferEntry(RecSystemID: Guid, RecTableNo: Integer, var FRZAttachmentBufferTemp: Record "DXP FRZ Attachment Buffer" temporary, ArchiveRecordID: Guid, FrzRecordType: Text[35], ReferenceDate: Date, RecordTitle: Text[250]): Boolean The procedures are overloaded - choose the variant that matches your scenario. If you want to implement your own logic to initiate archiving after posting a sales or purchase document, disable automatic archiving in the Freeze Setup to avoid unwanted redundancies. Attachment download as ZIP This documentation provides comprehensive guidance for external AL developers on how to make effective use of the DXP Freeze attachment download functionality in their Business Central extensions. Overview The DXP Freeze Result Management codeunit provides two main methods for downloading archived attachments as ZIP files: DownloadAttachmentsAsZipWithPagination - Downloads attachments from search query results with pagination. DownloadAttachmentsAsZipFromRecord - Downloads attachments from specific Business Central records. Both methods organize attachments into structured ZIP archives with comprehensive metadata for auditing and traceability purposes. Method 1: DownloadAttachmentsAsZipWithPagination Purpose Downloads all attachments from a search query result set and processes the results page by page to handle large data sets efficiently. The attachments of each record are organized into individual ZIP files inside a main ZIP archive. Available overloads 1. Basic usage procedure DownloadAttachmentsAsZipWithPagination(SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer): Boolean 2. With filters procedure DownloadAttachmentsAsZipWithPagination(SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer; FilenameFilter: Text; FileExtensionFilter: Text): Boolean 3. Full control procedure DownloadAttachmentsAsZipWithPagination(SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer; FilenameFilter: Text; FileExtensionFilter: Text; StoreApiLink: Text; RecordsPerPage: Integer; SuppressDialog: Boolean): Boolean 4. Pre-populated records (advanced) procedure DownloadAttachmentsAsZipWithPagination(var TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary; var TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary; var TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary; var TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary; SearchQuery: Text; var ZipArchive: Codeunit "Data Compression"; var AttachmentCount: Integer; FilenameFilter: Text; FileExtensionFilter: Text; SuppressDialog: Boolean): Boolean Parameters Parameter Type Description SearchQuery Text Freeze search query string. If empty in the pre-populated overload, the existing query is used or the search is run again. ZipArchive Codeunit "Data Compression" ZIP archive object that will contain the downloaded files. AttachmentCount Integer (var) Returns the total number of downloaded attachments. FilenameFilter Text Filter for attachment file names (for example '*.pdf', 'invoice*'). FileExtensionFilter Text Filter for file extensions (for example 'pdf', 'docx'). StoreApiLink Text Optional, specific store API link. RecordsPerPage Integer Number of records per page (default: 100). SuppressDialog Boolean Whether the progress dialog should be suppressed. Return value Boolean : true if attachments were found and downloaded; false otherwise. Usage examples Basic download procedure DownloadSearchResults() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; FileMgt: Codeunit "File Management"; TempBlob: Codeunit "Temp Blob"; AttachmentCount: Integer; InStr: InStream; OutStr: OutStream; SearchQuery: Text; begin SearchQuery := 'invoice AND 2024'; if ResultMgt.DownloadAttachmentsAsZipWithPagination(SearchQuery, ZipArchive, AttachmentCount) then begin // Save ZIP to file TempBlob.CreateOutStream(OutStr); ZipArchive.SaveZipArchive(OutStr); TempBlob.CreateInStream(InStr); FileMgt.DownloadFromStreamHandler(InStr, '', '', '', 'SearchResults.zip'); Message('Successfully downloaded %1 attachments.', AttachmentCount); end else Message('No attachments found for the search query.'); end; With filters procedure DownloadPDFInvoices() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; AttachmentCount: Integer; SearchQuery: Text; begin SearchQuery := 'type:invoice'; if ResultMgt.DownloadAttachmentsAsZipWithPagination( SearchQuery, ZipArchive, AttachmentCount, '*.pdf', // PDF files only 'pdf' // File extension filter ) then begin // Process ZIP archive ProcessDownloadedFiles(ZipArchive, AttachmentCount); end; end; Using pre-populated records procedure DownloadFromExistingResults() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; TempFrzResultQueryHeader: Record "DXP FRZ Query Result Header" temporary; TempFrzResultRecordHeader: Record "DXP FRZ Record Result Header" temporary; TempFrzResultRecordField: Record "DXP FRZ Result Record-Field" temporary; TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary; ZipArchive: Codeunit "Data Compression"; AttachmentCount: Integer; begin // Assume these records are already populated from a previous search PopulateSearchResults(TempFrzResultQueryHeader, TempFrzResultRecordHeader, TempFrzResultRecordField, TempFrzAttachmentResult); // Download using existing results without running the search again if ResultMgt.DownloadAttachmentsAsZipWithPagination( TempFrzResultQueryHeader, TempFrzResultRecordHeader, TempFrzResultRecordField, TempFrzAttachmentResult, 'invoicesearch', // SearchQuery - if empty, the search is run again ZipArchive, AttachmentCount, '', // No file name filter '', // No extension filter true // Suppress dialog ) then begin ProcessDownloadedFiles(ZipArchive, AttachmentCount); end; end; ZIP structure (pagination) SearchResults.zip ├── export-metadata.json ├── Invoice_001_V1_20241201_1430.zip │ ├── {GUID}_invoice.pdf │ └── {GUID}_supporting-document.docx ├── Order_002_V2_20241202_0900.zip │ └── {GUID}_order-document.pdf └── Contract_003_V1_20241203_1200.zip ├── {GUID}_contract.pdf └── {GUID}_addendum.pdf Method 2: DownloadAttachmentsAsZipFromRecord Purpose Downloads attachments from specific Business Central records. The attachments of each selected record are organized into individual ZIP files inside a main ZIP archive. Available overloads 1. Basic usage procedure DownloadAttachmentsAsZipFromRecord(var SelectedRecord: RecordRef; var ZipArchive: Codeunit "Data Compression"): Boolean 2. With filters procedure DownloadAttachmentsAsZipFromRecord(var SelectedRecord: RecordRef; var ZipArchive: Codeunit "Data Compression"; FilenameFilter: Text; FileExtensionFilter: Text): Boolean Parameters Parameter Type Description SelectedRecord RecordRef (var) RecordRef holding the selected Business Central records. ZipArchive Codeunit "Data Compression" ZIP archive object that will contain the downloaded files. FilenameFilter Text Filter for attachment file names. FileExtensionFilter Text Filter for file extensions. Return value Boolean : true if attachments were found and downloaded; false otherwise. Usage examples Downloading sales invoices procedure DownloadInvoiceAttachments() var SalesInvoiceHeader: Record "Sales Invoice Header"; ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; RecordRef: RecordRef; HasAttachments: Boolean; begin // Select specific invoices SalesInvoiceHeader.SetRange("Posting Date", DMY2Date(1, 1, 2024), DMY2Date(31, 12, 2024)); SalesInvoiceHeader.SetFilter("Sell-to Customer No.", '10000|20000'); if SalesInvoiceHeader.FindSet() then begin RecordRef.GetTable(SalesInvoiceHeader); HasAttachments := ResultMgt.DownloadAttachmentsAsZipFromRecord(RecordRef, ZipArchive); if HasAttachments then SaveZipFile(ZipArchive, 'InvoiceAttachments.zip') else Message('No attachments found for the selected invoices.'); end; end; Downloading with filters from a page // In a page extension action(DownloadAttachmentsFiltered) { Caption = 'Download filtered attachments'; Image = ExportFile; trigger OnAction() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; ZipArchive: Codeunit "Data Compression"; RecordRef: RecordRef; FilenameFilter: Text; FileExtensionFilter: Text; begin // Show filter dialog if ShowFilterDialog(FilenameFilter, FileExtensionFilter) then begin CurrPage.SetSelectionFilter(Rec); RecordRef.GetTable(Rec); if ResultMgt.DownloadAttachmentsAsZipFromRecord( RecordRef, ZipArchive, FilenameFilter, FileExtensionFilter ) then DownloadZipFile(ZipArchive, 'FilteredAttachments.zip'); end; end; } ZIP structure (records) RecordAttachments.zip ├── export-metadata.json ├── Sales_Invoice_Header_Company_SI-001.zip │ ├── {GUID}_invoice.pdf │ └── {GUID}_terms.pdf ├── Sales_Invoice_Header_Company_SI-002.zip │ └── {GUID}_invoice.pdf └── Sales_Invoice_Header_Company_SI-003.zip ├── {GUID}_invoice.pdf ├── {GUID}_delivery-note.pdf └── {GUID}_receipt.jpg Metadata structure Both methods generate comprehensive metadata in export-metadata.json : Pagination export metadata { "exportInfo": { "exportTimestamp": "2024-12-19T10:13:52.248Z", "exportedBy": "USER001", "searchQuery": "type:invoice AND year:2024", "totalRecordsFound": 150, "totalPages": 15, "exportType": "paginated-search", "description": "Freeze search query export" }, "appliedFilters": { "filenameFilter": "*.pdf", "fileExtensionFilter": "pdf" }, "statistics": { "pagesProcessed": 15, "totalRecordsProcessed": 150, "recordsWithAttachments": 120, "recordsWithoutAttachments": 30, "totalAttachments": 245, "exportCompletedAt": "2024-12-19T10:15:33.021Z" }, "records": [ { "recordId": "{GUID}", "title": "Invoice REG-2024-001", "version": 1, "archivedAt": "2024-12-01T09:30:00Z", "archivedBy": "SYSTEM", "type": "Sales Invoice", "masterId": "{GUID}", "attachmentCount": 3, "hasAttachments": true, "zipFile": "Invoice_REG-2024-001_V1_20241201_0930.zip" } ] } Record export metadata { "exportTimestamp": "2024-12-19T14:30:00Z", "exportedBy": "USER001", "totalRecordsProcessed": 25, "description": "DXP Freeze attachment export", "sourceTable": { "tableNumber": 112, "tableName": "Sales Invoice Header", "tableCaption": "Posted Sales Invoice" }, "appliedFilters": { "filenameFilter": "*.pdf", "fileExtensionFilter": "pdf" }, "statistics": { "totalAttachments": 45, "recordsWithAttachments": 20, "recordsWithoutAttachments": 5, "totalZipFiles": 20 }, "records": [ { "recordId": "Sales Invoice Header: Company, SI-001", "systemId": "{GUID}", "primaryKey": { "fields": [ { "fieldName": "No.", "fieldValue": "SI-001", "fieldType": "Code" } ] }, "hasAttachments": true, "attachmentCount": 2, "zipFile": "Sales_Invoice_Header_Company_SI-001.zip" } ] } Performance considerations Pagination method Large result sets : Automatic pagination handling to process large data sets efficiently. Memory management : Processes one page at a time and clears memory between pages. Progress tracking : Shows real-time progress for longer-running operations. Recommended for : Search queries that can return hundreds or thousands of records. Record method Selected records : Processes only the specifically selected records. Direct processing : No pagination overhead for smaller data sets. Batch processing : Efficient for processing specific record sets. Recommended for : Targeted downloads of specific Business Central records. Error handling Both methods include comprehensive error handling: Common scenarios No results found : Returns false when no records or attachments are found. Permission issues : Automatically excludes records the user cannot access. API errors : Reliable handling of API communication errors. Empty filters : Handles empty or invalid filter parameters. Best practices // Always check the return value if not ResultMgt.DownloadAttachmentsAsZipWithPagination(SearchQuery, ZipArchive, AttachmentCount) then begin Message('No attachments found or download failed.'); exit; end; // Validate the attachment count if AttachmentCount = 0 then begin Message('Search completed, but no attachments match the criteria.'); exit; end; // Handle large downloads if AttachmentCount > 1000 then if not Confirm('This will download %1 attachments. Continue?', false, AttachmentCount) then exit; Integration events Both methods support integration events for customization: Available events OnBeforeDownloadAttachmentsAsZip : Modify behavior before the download starts. OnBeforeProcessAttachmentForZip : Skip or modify individual attachments. OnAfterGetAttachmentBase64 : Modify attachment content after retrieval. OnAfterAddAttachmentToZip : Perform actions after adding to the ZIP. OnNoAttachmentsFound : Handle the no-attachments scenario. Integration example [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP FRZ Result Mgt.", 'OnBeforeProcessAttachmentForZip', '', false, false)] local procedure OnBeforeProcessAttachmentForZip(var TempFrzAttachmentResult: Record "DXP FRZ Attachment Result" temporary; var IsHandled: Boolean) begin // Skip attachments larger than 10MB if TempFrzAttachmentResult.Filesize > 10485760 then IsHandled := true; end; File name conventions Automatic sanitization All file names are automatically sanitized with the SanitizeFileName method: Invalid characters ( < > : " / \ | ? * ) are replaced with underscores. Spaces are replaced with underscores. Maximum file name lengths are enforced. Unique naming Individual files : Include an attachment GUID prefix to ensure uniqueness. ZIP files : Include record information and a timestamp. No conflicts : Guarantees unique names within each ZIP archive. Freeze integration into custom pages Overview The DEXPRO Freeze extension provides document archiving functionality that lets users store and retrieve documents, attachments, and related data for any Business Central record. This guide explains how to integrate the Freeze functionality into custom pages. Core components 1. Quick Freeze infobox The central component is the "DXP FRZ Quick Freeze FB" page, which provides the following: Drag-and-drop file upload functionality Display of archived records related to the current record Quick access to Freeze operations 2. Management codeunits "DXP Extension Mgt." - Manages Freeze queue operations and background processing. "DXP Freeze Search Mgt." - Manages search functionality for archived records. "DXP FRZ Result Mgt." - Manages result display and archive viewing. 3. Key tables "DXP Frz Recent Record" - Stores recent Freeze entries. "DXP Freeze Setup" - Configuration settings. "DXP Freeze Record Type" - Available record types for archiving. Implementation steps Step 1: Add the infobox Add the Quick Freeze infobox to the layout area of your page: layout { addfirst(factboxes) { part("DXP Quick Archive"; "DXP FRZ Quick Freeze FB") { ApplicationArea = All; SubPageLink = "Record System ID" = field(SystemId), "Record Table No." = const(Database::"Your Table Name"); SubPageView = sorting("Entry No.") order(descending); } } } Important notes: Replace Database::"Your Table Name" with the appropriate table constant. Step 2: Add navigation actions Add Freeze-related actions to the actions area of the page: actions { addfirst(navigation) { action("DXP Freeze") { Caption = 'Open Freeze'; ApplicationArea = All; Image = Archive; ToolTip = 'Opens the Freeze archive and shows attachments linked to the selected record.'; ShortcutKey = 'Ctrl+Alt+F'; trigger OnAction() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; begin ResultMgt.SubmitSearchAndShowResults(Rec.RecordId(), FrzSearchMgt.GetSearchCombinationForTable(Rec.SystemId, Rec.RecordId.TableNo())); end; } } } Step 3: Add promoted actions actions { addfirst(Category_Category16) { actionref("DXP Freeze_Promoted"; "DXP Freeze") { } } modify(Category_Category16) { Caption = 'DEXPRO Freeze', Locked = true; } } Step 4: Add the page trigger trigger OnAfterGetCurrRecord() begin CurrPage."DXP Quick Archive".Page.SetSourceRecord(Rec.RecordId()); end; Step 5: Declare the variables var ExtMgt: Codeunit "DXP Extension Mgt."; FrzSearchMgt: Codeunit "DXP Freeze Search Mgt."; Complete example Here is a complete example for a custom document page: pageextension 50000 "My Custom Doc. Ext." extends "My Custom Document" { layout { addfirst(factboxes) { part("DXP Quick Archive"; "DXP FRZ Quick Freeze FB") { ApplicationArea = All; SubPageLink = "Record System ID" = field(SystemId), "Record Table No." = const(Database::"Your Table Name"); SubPageView = sorting("Entry No.") order(descending); } } } actions { addfirst(navigation) { action("DXP Freeze") { Caption = 'Open Freeze'; ApplicationArea = All; Image = Archive; ToolTip = 'Opens the Freeze archive and shows attachments linked to the selected record.'; ShortcutKey = 'Ctrl+Alt+F'; trigger OnAction() var ResultMgt: Codeunit "DXP FRZ Result Mgt."; begin ResultMgt.SubmitSearchAndShowResults(Rec.RecordId(), FrzSearchMgt.GetSearchCombinationForTable(Rec.SystemId, Rec.RecordId.TableNo())); end; } } addfirst(Category_Category16) { actionref("DXP Freeze_Promoted"; "DXP Freeze") { } } modify(Category_Category16) { Caption = 'DEXPRO Freeze', Locked = true; } } trigger OnAfterGetCurrRecord() begin CurrPage."DXP Quick Archive".Page.SetSourceRecord(Rec.RecordId()); end; var ExtMgt: Codeunit "DXP Extension Mgt."; FrzSearchMgt: Codeunit "DXP Freeze Search Mgt."; } Setting up additional search queries To also display archive entries based on records that are not directly linked via the system ID / table number (archived via BC), you can set up additional search queries. This is documented here: https://docs.squeeze.one/books/freeze-for-dynamics-365-bc-de-de/page/zusatzliche-suchabfragen Testing your implementation Navigate to your extended page. Verify that the Quick Freeze infobox appears. Test the "Open Freeze" action (Ctrl+Alt+F). Upload test files by drag-and-drop. Verify that archived records appear in the infobox. This integration pattern ensures consistent Freeze functionality across all Business Central pages while preserving the user experience established by the DEXPRO Freeze extension.