Codeunit 431 IC Outbox Export

App
Base Application
Namespace
Microsoft.Intercompany.Outbox
Versions
17-28

Procedures, 8Events, 14

Versions171819202122232425262728

Source29

Source in 29

src/Layers/W1/BaseApp/Finance/Intercompany/Outbox/ICOutboxExport.Codeunit.al585 lines, Copyright (c) Microsoft Corporation. MIT

// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Intercompany.Outbox;

using Microsoft.Finance.GeneralLedger.Preview;
using Microsoft.Foundation.BatchProcessing;
using Microsoft.Foundation.Company;
using Microsoft.Intercompany;
using Microsoft.Intercompany.GLAccount;
using Microsoft.Intercompany.Inbox;
using Microsoft.Intercompany.Partner;
using Microsoft.Intercompany.Setup;
using Microsoft.Purchases.Document;
using Microsoft.Sales.Document;
using System.Email;
using System.Environment;
using System.IO;
using System.Telemetry;
using System.Utilities;

/// <summary>
/// Manages intercompany outbox transaction export and transmission operations.
/// Handles file export, partner communication, and transaction status updates for outbound intercompany processes.
/// </summary>
/// <remarks>
/// Core codeunit for outbox transaction processing. Integrates with partner setup, file systems, email communication, and internal company transfers.
/// Key workflows: Export transactions, send to partners, update status, handle responses.
/// Extensible via integration events for custom export formats and partner communication methods.
/// </remarks>
codeunit 431 "IC Outbox Export"
{
    TableNo = "IC Outbox Transaction";

    trigger OnRun()
    var
        ConfirmManagement: Codeunit "Confirm Management";
        FeatureTelemetry: Codeunit "Feature Telemetry";
        ICMapping: Codeunit "IC Mapping";
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnRunOnBeforeConfirmGetResponseOrDefault(IsHandled, Rec);
        if not IsHandled then
            if not ConfirmManagement.GetResponseOrDefault(Text003, true) then
                exit;

        FeatureTelemetry.LogUptake('0000ILC', ICMapping.GetFeatureTelemetryName(), Enum::"Feature Uptake Status"::Used);
        FeatureTelemetry.LogUsage('0000ILE', ICMapping.GetFeatureTelemetryName(), 'IC Outbox Export');
        RunOutboxTransactions(Rec);
    end;

    var
        CompanyInfo: Record "Company Information";
        ICInboxOutboxMgt: Codeunit ICInboxOutboxMgt;
        FileMgt: Codeunit "File Management";
        ClientTypeManagement: Codeunit "Client Type Management";

#pragma warning disable AA0074
        Text003: Label 'Do you want to complete line actions?';
#pragma warning restore AA0074
        FolderPathMissingErr: Label 'Folder Path must have a value in IC Partner: Code=%1. It cannot be zero or empty.', Comment = '%1=Intercompany Code';
        EmailAddressMissingErr: Label 'Email Address must have a value in IC Partner: Code=%1. It cannot be zero or empty.', Comment = '%1=Intercompany Code';

    [Scope('OnPrem')]
    procedure RunOutboxTransactions(var ICOutboxTransaction: Record "IC Outbox Transaction")
    var
        CopyICOutboxTransaction: Record "IC Outbox Transaction";
        FeatureTelemetry: Codeunit "Feature Telemetry";
        ICMapping: Codeunit "IC Mapping";
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeRunOutboxTransactions(ICOutboxTransaction, IsHandled);
        if IsHandled then
            exit;

        FeatureTelemetry.LogUptake('0000ILD', ICMapping.GetFeatureTelemetryName(), Enum::"Feature Uptake Status"::Used);
        FeatureTelemetry.LogUsage('0000ILF', ICMapping.GetFeatureTelemetryName(), 'Run Outbox Transaction');

        CompanyInfo.Get();
        CopyICOutboxTransaction.Copy(ICOutboxTransaction);
        CopyICOutboxTransaction.SetRange("Line Action",
          CopyICOutboxTransaction."Line Action"::"Send to IC Partner");
        UpdateICStatus(CopyICOutboxTransaction);
        OnRunOutboxTransactionsOnBeforeSend(CopyICOutboxTransaction);
        SendToExternalPartner(CopyICOutboxTransaction);
        SendToInternalPartner(CopyICOutboxTransaction);
        CopyICOutboxTransaction.SetRange("Line Action",
          CopyICOutboxTransaction."Line Action"::"Return to Inbox");
        ReturnToInbox(CopyICOutboxTransaction);
        CancelTransaction(CopyICOutboxTransaction);
    end;

    local procedure ModifyAndRunOutboxTransactionNo(ICOutboxTransactionNo: Integer)
    var
        ICOutboxTransaction: Record "IC Outbox Transaction";
    begin
        ICOutboxTransaction.SetRange("Transaction No.", ICOutboxTransactionNo);
        if ICOutboxTransaction.FindFirst() then begin
            ICOutboxTransaction."Line Action" := ICOutboxTransaction."Line Action"::"Send to IC Partner";
            ICOutboxTransaction.Modify();
            RunOutboxTransactions(ICOutboxTransaction);
        end;
    end;

    /// <summary>
    /// Processes automatic sending of a specific outbox transaction by transaction number.
    /// Handles auto-send configuration validation and initiates transaction processing.
    /// </summary>
    /// <param name="ICOutboxTransactionNo">Transaction number to process for auto-send</param>
    procedure ProcessAutoSendOutboxTransactionNo(ICOutboxTransactionNo: Integer)
    var
        ICSetup: Record "IC Setup";
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeProcessAutoSendOutboxTransactionNo(ICOutboxTransactionNo, IsHandled);
        if IsHandled then
            exit;

        ICSetup.Get();
        if ICSetup."Auto. Send Transactions" then
            ModifyAndRunOutboxTransactionNo(ICOutboxTransactionNo);
    end;

    /// <summary>
    /// Sends outbox transactions to external intercompany partners via file export or email.
    /// Handles partner-specific communication methods and file generation for transaction transmission.
    /// </summary>
    /// <param name="ICOutboxTrans">IC Outbox Transaction records to send to external partners</param>
    procedure SendToExternalPartner(var ICOutboxTrans: Record "IC Outbox Transaction")
    var
        ICPartner: Record "IC Partner";
        EmailItem: Record "Email Item";
        DocumentMailing: Codeunit "Document-Mailing";
        GenJnlPostPreview: Codeunit "Gen. Jnl.-Post Preview";
        InStream: InStream;
        OFile: File;
        FileName: Text;
        ICPartnerFilter: Text[1024];
        i: Integer;
        ToName: Text[100];
        CcName: Text[100];
        OutFileName: Text;
        IsHandled: Boolean;
        SourceTableIDs, SourceRelationTypes : List of [Integer];
        SourceIDs: List of [Guid];
    begin
        IsHandled := false;
        OnBeforeSendToExternalPartner(ICOutboxTrans, IsHandled);
        if IsHandled then
            exit;

        if GenJnlPostPreview.IsActive() then
            exit;

        ICPartner.SetFilter("Inbox Type", '<>%1', ICPartner."Inbox Type"::Database);
        ICPartnerFilter := ICOutboxTrans.GetFilter("IC Partner Code");
        if ICPartnerFilter <> '' then
            ICPartner.SetFilter(Code, ICPartnerFilter);
        OnSendToExternalPartnerOnBeforeICPartnerFindset(ICPartner);
        if ICPartner.Find('-') then
            repeat
                ICOutboxTrans.SetRange("IC Partner Code", ICPartner.Code);
                if ICOutboxTrans.Find('-') then begin
                    if (ICPartner."Inbox Type" = ICPartner."Inbox Type"::"File Location") and not IsWebClient() then begin
                        ICPartner.TestField(Blocked, false);
                        if ICPartner."Inbox Details" = '' then
                            Error(FolderPathMissingErr, ICPartner.Code);
                        i := 1;
                        while i <> 0 do begin
                            FileName :=
                              StrSubstNo('%1\%2_%3_%4.xml', ICPartner."Inbox Details", ICPartner.Code, ICOutboxTrans."Transaction No.", i);
                            if Exists(FileName) then
                                i := i + 1
                            else
                                i := 0;
                        end;
                    end else begin
                        OFile.CreateTempFile();
                        FileName := StrSubstNo('%1.%2.xml', OFile.Name, ICPartner.Code);
                        OFile.Close();
                    end;

                    ExportOutboxTransaction(ICOutboxTrans, FileName);

                    if IsWebClient() then begin
                        OutFileName := StrSubstNo('%1_%2.xml', ICPartner.Code, ICOutboxTrans."Transaction No.");
                        if not AddBatchProcessingArtifact(FileName, CopyStr(OutFileName, 1, 1024)) then
                            Download(FileName, '', '', '', OutFileName)
                    end else
                        FileName := FileMgt.DownloadTempFile(FileName);

                    if ICPartner."Inbox Type" = ICPartner."Inbox Type"::Email then begin
                        ICPartner.TestField(Blocked, false);
                        if ICPartner."Inbox Details" = '' then
                            Error(EmailAddressMissingErr, ICPartner.Code);
                        ToName := ICPartner."Inbox Details";
                        if StrPos(ToName, ';') > 0 then begin
                            CcName := CopyStr(ToName, StrPos(ToName, ';') + 1);
                            ToName := CopyStr(ToName, 1, StrPos(ToName, ';') - 1);
                            if StrPos(CcName, ';') > 0 then
                                CcName := CopyStr(CcName, 1, StrPos(CcName, ';') - 1);
                        end;

                        if IsWebClient() then begin
                            EmailItem."Send to" := ICPartner."Inbox Details";
                            EmailItem.Subject := StrSubstNo('%1 %2', ICOutboxTrans."Document Type", ICOutboxTrans."Document No.");
                            Commit();

                            OFile.Open(FileName);
                            OFile.CreateInStream(InStream);

                            SourceTableIDs.Add(Database::"IC Outbox Transaction");
                            SourceIDs.Add(ICOutboxTrans.SystemId);
                            SourceRelationTypes.Add(Enum::"Email Relation Type"::"Primary Source".AsInteger());

                            SourceTableIDs.Add(Database::"IC Partner");
                            SourceIDs.Add(ICPartner.SystemId);
                            SourceRelationTypes.Add(Enum::"Email Relation Type"::"Related Entity".AsInteger());

                            DocumentMailing.EnqueueEmailFile(
                              InStream,
                              StrSubstNo('%1.xml', ICPartner.Code),
                              ICOutboxTrans."Document No.",
                              EmailItem."Send to",
                              EmailItem.Subject,
                              true,
                              5, // S.Test
                              SourceTableIDs,
                              SourceIDs,
                              SourceRelationTypes);
                        end;
                    end;
                    OnSendToExternalPartnerOnAfterDocWasSent(ICPartner, FileName);
                    ICOutboxTrans.Find('-');
                    repeat
                        ICInboxOutboxMgt.MoveOutboxTransToHandledOutbox(ICOutboxTrans);
                    until ICOutboxTrans.Next() = 0;
                end;
            until ICPartner.Next() = 0;
        ICOutboxTrans.SetRange("IC Partner Code");
        if ICPartnerFilter <> '' then
            ICOutboxTrans.SetFilter("IC Partner Code", ICPartnerFilter);
    end;

    local procedure AddBatchProcessingArtifact(FilePath: Text; ArtifactName: Text[1024]): Boolean
    var
        BatchProcessingMgt: Codeunit "Batch Processing Mgt.";
        FileManagement: Codeunit "File Management";
        TempBlob: Codeunit "Temp Blob";
        BatchProcessingArtifactType: Enum "Batch Processing Artifact Type";
    begin
        if not BatchProcessingMgt.IsActive() then
            exit(false);

        FileManagement.BLOBImportFromServerFile(TempBlob, FilePath);

        BatchProcessingMgt.AddArtifact(BatchProcessingArtifactType::"IC Output File", ArtifactName, TempBlob);

        exit(true);
    end;

    /// <summary>
    /// Downloads batch processed files as a compressed archive with the specified filename.
    /// </summary>
    /// <param name="DownloadFileName">Name for the downloaded compressed file</param>
    procedure DownloadBatchFiles(DownloadFileName: Text)
    var
        TempBatchProcessingArtifact: Record "Batch Processing Artifact" temporary;
        BatchProcessingMgt: Codeunit "Batch Processing Mgt.";
        DataCompression: Codeunit "Data Compression";
        FileManagement: Codeunit "File Management";
        TempBlob: Codeunit "Temp Blob";
        InStreamVar: InStream;
        OutStreamVar: OutStream;
        BatchProcessingArtifactType: Enum "Batch Processing Artifact Type";
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeDownloadBatchFiles(IsHandled);
        if IsHandled then
            exit;

        if not BatchProcessingMgt.IsActive() then
            exit;

        if not BatchProcessingMgt.GetArtifacts(BatchProcessingArtifactType::"IC Output File", TempBatchProcessingArtifact) then
            exit;

        DataCompression.CreateZipArchive();

        TempBatchProcessingArtifact.FindSet();
        repeat
            Clear(InStreamVar);
            Clear(TempBlob);
            TempBlob.FromRecord(TempBatchProcessingArtifact, TempBatchProcessingArtifact.FieldNo("Artifact Value"));
            TempBlob.CreateInStream(InStreamVar);
            DataCompression.AddEntry(InStreamVar, TempBatchProcessingArtifact."Artifact Name");
        until TempBatchProcessingArtifact.Next() = 0;


        Clear(InStreamVar);
        Clear(TempBlob);

        TempBlob.CreateOutStream(OutStreamVar);

        DataCompression.SaveZipArchive(OutStreamVar);
        DataCompression.CloseZipArchive();

        TempBlob.CreateInStream(InStreamVar);

        FileManagement.DownloadFromStreamHandler(InStreamVar, '', '', '', DownloadFileName);
    end;

    /// <summary>
    /// Sends outbox transactions to internal intercompany partners within the same database.
    /// Manages direct company-to-company transaction transfer for internal partner relationships.
    /// </summary>
    /// <param name="ICOutboxTrans">IC Outbox Transaction records to send to internal partners</param>
    procedure SendToInternalPartner(var ICOutboxTrans: Record "IC Outbox Transaction")
    var
        ICPartner: Record "IC Partner";
        TempAllPartnerICInboxTransaction: Record "IC Inbox Transaction" temporary;
        TempAllPartnerHandledICInboxTrans: Record "Handled IC Inbox Trans." temporary;
        MoveICTransToPartnerCompany: Report "Move IC Trans. to Partner Comp";
        ICPartnerCodeList: List of [Text];
        IsHandled: Boolean;
    begin
        if ICOutboxTrans.Find('-') then
            repeat
                ICPartner.Get(ICOutboxTrans."IC Partner Code");
                ICPartner.TestField(Blocked, false);
                if ICPartner."Inbox Type" = ICPartner."Inbox Type"::Database then begin
                    ICPartner.TestField("Inbox Details");
                    ICOutboxTrans.SetRange("Transaction No.", ICOutboxTrans."Transaction No.");
                    IsHandled := false;
                    OnSendToInternalPartnerOnBeforeMoveICTransToPartnerCompany(ICOutboxTrans, IsHandled);
                    if not IsHandled then begin
                        MoveICTransToPartnerCompany.Initialize(ICPartnerCodeList, TempAllPartnerICInboxTransaction, TempAllPartnerHandledICInboxTrans);
                        MoveICTransToPartnerCompany.SetTableView(ICOutboxTrans);
                        MoveICTransToPartnerCompany.UseRequestPage := false;
                        MoveICTransToPartnerCompany.Run();
                    end;
                    ICOutboxTrans.SetRange("Transaction No.");
                    if ICOutboxTrans."Line Action" = ICOutboxTrans."Line Action"::"Send to IC Partner" then
                        ICInboxOutboxMgt.MoveOutboxTransToHandledOutbox(ICOutboxTrans);
                end;
            until ICOutboxTrans.Next() = 0;
    end;

    /// <summary>
    /// Returns outbox transactions to the IC partner's inbox for reprocessing.
    /// </summary>
    /// <param name="ICOutboxTrans">IC outbox transaction records to return to inbox</param>
    procedure ReturnToInbox(var ICOutboxTrans: Record "IC Outbox Transaction")
    var
        ICPartner: Record "IC Partner";
        MoveICTransToPartnerCompany: Report "Move IC Trans. to Partner Comp";
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeReturnToInbox(ICOutboxTrans, IsHandled);
        if IsHandled then
            exit;

        if ICOutboxTrans.Find('-') then
            repeat
                if ICPartner.Get(ICOutboxTrans."IC Partner Code") then
                    ICPartner.TestField(Blocked, false);
                MoveICTransToPartnerCompany.RecreateInboxTrans(ICOutboxTrans);
                ICOutboxTrans.Delete(true);
            until ICOutboxTrans.Next() = 0;
    end;

    /// <summary>
    /// Cancels outbox transactions by moving them to the handled outbox.
    /// </summary>
    /// <param name="ICOutboxTrans">IC outbox transaction records to cancel</param>
    procedure CancelTransaction(var ICOutboxTrans: Record "IC Outbox Transaction")
    begin
        ICOutboxTrans.SetRange("Line Action", ICOutboxTrans."Line Action"::Cancel);
        if ICOutboxTrans.Find('-') then
            repeat
                ICInboxOutboxMgt.MoveOutboxTransToHandledOutbox(ICOutboxTrans);
            until ICOutboxTrans.Next() = 0;
    end;

    /// <summary>
    /// Updates the intercompany status on source documents based on outbox transaction processing.
    /// </summary>
    /// <param name="ICOutboxTransaction">IC outbox transaction records to update status for</param>
    procedure UpdateICStatus(var ICOutboxTransaction: Record "IC Outbox Transaction")
    var
        PurchHeader: Record "Purchase Header";
        SalesHeader: Record "Sales Header";
    begin
        if ICOutboxTransaction.FindSet() then
            repeat
                if ICOutboxTransaction."IC Source Type" = ICOutboxTransaction."IC Source Type"::"Purchase Document" then
                    case ICOutboxTransaction."Document Type" of
                        ICOutboxTransaction."Document Type"::Order:
                            if PurchHeader.Get(PurchHeader."Document Type"::Order, ICOutboxTransaction."Document No.") then begin
                                PurchHeader.Validate("IC Status", PurchHeader."IC Status"::Sent);
                                PurchHeader.Modify();
                            end;
                        ICOutboxTransaction."Document Type"::"Return Order":
                            if PurchHeader.Get(PurchHeader."Document Type"::"Return Order", ICOutboxTransaction."Document No.") then begin
                                PurchHeader.Validate("IC Status", PurchHeader."IC Status"::Sent);
                                PurchHeader.Modify();
                            end;
                    end
                else
                    if ICOutboxTransaction."IC Source Type" = ICOutboxTransaction."IC Source Type"::"Sales Document" then
                        case ICOutboxTransaction."Document Type" of
                            ICOutboxTransaction."Document Type"::Order:
                                if SalesHeader.Get(SalesHeader."Document Type"::Order, ICOutboxTransaction."Document No.") then begin
                                    SalesHeader.Validate("IC Status", SalesHeader."IC Status"::Sent);
                                    SalesHeader.Modify();
                                end;
                            ICOutboxTransaction."Document Type"::"Return Order":
                                if SalesHeader.Get(SalesHeader."Document Type"::"Return Order", ICOutboxTransaction."Document No.") then begin
                                    SalesHeader.Validate("IC Status", SalesHeader."IC Status"::Sent);
                                    SalesHeader.Modify();
                                end;
                        end;
                OnUpdateICStatusOnAfterLoopIteration(ICOutboxTransaction);
            until ICOutboxTransaction.Next() = 0
    end;

    local procedure ExportOutboxTransaction(var ICOutboxTransaction: Record "IC Outbox Transaction"; var FileName: Text)
    var
        ICOutboxImpExpXML: XMLport "IC Outbox Imp/Exp";
        OFile: File;
        OStr: OutStream;
        IsHandled: Boolean;
    begin
        OFile.Create(FileName);
        OFile.CreateOutStream(OStr);

        IsHandled := false;
        OnBeforeExportOutboxTransaction(ICOutboxTransaction, OStr, IsHandled);
        if IsHandled then
            exit;

        ICOutboxImpExpXML.SetICOutboxTrans(ICOutboxTransaction);
        ICOutboxImpExpXML.SetDestination(OStr);
        ICOutboxImpExpXML.Export();

        OFile.Close();
        Clear(OStr);
        Clear(ICOutboxImpExpXML);
    end;

    local procedure IsWebClient(): Boolean
    begin
        exit(ClientTypeManagement.GetCurrentClientType() in [CLIENTTYPE::Web, CLIENTTYPE::Phone, CLIENTTYPE::Tablet, CLIENTTYPE::Desktop]);
    end;

    /// <summary>
    /// Integration event raised before exporting an outbox transaction to enable custom export logic.
    /// </summary>
    /// <param name="ICOutboxTransaction">IC outbox transaction being exported</param>
    /// <param name="OutStr">Output stream for the export data</param>
    /// <param name="IsHandled">Set to true to skip standard export processing</param>
    [IntegrationEvent(false, false)]
    local procedure OnBeforeExportOutboxTransaction(var ICOutboxTransaction: Record "IC Outbox Transaction"; OutStr: OutStream; var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event raised before returning transactions to inbox to enable custom return logic.
    /// </summary>
    /// <param name="ICOutboxTransaction">IC outbox transaction being returned to inbox</param>
    /// <param name="IsHandled">Set to true to skip standard return processing</param>
    [IntegrationEvent(false, false)]
    local procedure OnBeforeReturnToInbox(var ICOutboxTransaction: Record "IC Outbox Transaction"; var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event raised before running outbox transactions to enable custom processing logic.
    /// </summary>
    /// <param name="ICOutboxTransaction">IC outbox transaction being processed</param>
    /// <param name="IsHandled">Set to true to skip standard processing</param>
    [IntegrationEvent(false, false)]
    local procedure OnBeforeRunOutboxTransactions(var ICOutboxTransaction: Record "IC Outbox Transaction"; var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event raised before sending transactions to external partners to enable custom logic.
    /// </summary>
    /// <param name="ICOutboxTransaction">IC outbox transaction being sent to external partner</param>
    /// <param name="IsHandled">Set to true to skip standard external partner processing</param>
    [IntegrationEvent(false, false)]
    local procedure OnBeforeSendToExternalPartner(var ICOutboxTransaction: Record "IC Outbox Transaction"; var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event raised after each loop iteration when updating IC status.
    /// </summary>
    /// <param name="ICOutboxTransaction">IC outbox transaction being processed in status update</param>
    [IntegrationEvent(false, false)]
    local procedure OnUpdateICStatusOnAfterLoopIteration(var ICOutboxTransaction: Record "IC Outbox Transaction")
    begin
    end;

    /// <summary>
    /// Integration event raised before sending outbox transactions in the run process.
    /// </summary>
    /// <param name="ICOutboxTransaction">IC outbox transaction about to be sent</param>
    [IntegrationEvent(false, false)]
    local procedure OnRunOutboxTransactionsOnBeforeSend(var ICOutboxTransaction: Record "IC Outbox Transaction")
    begin
    end;

    /// <summary>
    /// Integration event raised before downloading batch files to enable custom download logic.
    /// </summary>
    /// <param name="IsHandled">Set to true to skip standard batch file download</param>
    [IntegrationEvent(false, false)]
    local procedure OnBeforeDownloadBatchFiles(var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event raised before confirming automatic response handling for outbox transactions.
    /// Enables custom logic for transaction confirmation and response processing.
    /// </summary>
    /// <param name="IsHandled">Set to true to skip standard confirmation processing</param>
    /// <param name="ICOutboxTransaction">Outbox transaction being processed</param>
    [IntegrationEvent(false, false)]
    local procedure OnRunOnBeforeConfirmGetResponseOrDefault(var IsHandled: Boolean; var ICOutboxTransaction: Record "IC Outbox Transaction")
    begin
    end;

    /// <summary>
    /// Integration event raised after successfully sending document to external partner.
    /// Enables custom post-send processing and partner communication tracking.
    /// </summary>
    /// <param name="ICPartner">Partner that received the document</param>
    /// <param name="FileName">Name of the file that was sent</param>
    [IntegrationEvent(false, false)]
    local procedure OnSendToExternalPartnerOnAfterDocWasSent(ICPartner: Record "IC Partner"; FileName: Text)
    begin
    end;

    /// <summary>
    /// Integration event raised before moving transactions to internal partner company.
    /// Enables custom validation and processing logic for internal company transfers.
    /// </summary>
    /// <param name="ICOutboxTransaction">Outbox transaction being transferred</param>
    /// <param name="IsHandled">Set to true to skip standard transfer processing</param>
    [IntegrationEvent(false, false)]
    local procedure OnSendToInternalPartnerOnBeforeMoveICTransToPartnerCompany(var ICOutboxTransaction: Record "IC Outbox Transaction"; var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event raised before processing automatic send for specific outbox transaction.
    /// Enables custom logic for transaction number validation and send criteria.
    /// </summary>
    /// <param name="ICOutboxTransactionNo">Transaction number being processed</param>
    /// <param name="IsHandled">Set to true to skip standard processing</param>
    [IntegrationEvent(false, false)]
    local procedure OnBeforeProcessAutoSendOutboxTransactionNo(var ICOutboxTransactionNo: Integer; var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event raised before filtering and processing IC partner records for external sending.
    /// Enables custom partner filtering and selection logic.
    /// </summary>
    /// <param name="ICPartner">IC Partner record set being processed</param>
    [IntegrationEvent(false, false)]
    local procedure OnSendToExternalPartnerOnBeforeICPartnerFindset(var ICPartner: Record "IC Partner")
    begin
    end;
}