ProtectedaccountingThe accounting provider this action is designed for (e.g., 'QuickBooks', 'NetSuite', etc.) Can be 'Generic' for provider-agnostic actions
ProtectedapiBusiness Central API version
ProtectedintegrationThe integration name to look up in the Integration entity
ProtectedparamsCurrent action parameters (set by the framework)
ProtectedrequestThe request's metadata provider (RunActionParams.Provider), captured in Run so the
connection and Credential lookups bind to it even in helpers that only receive the param
array. undefined when the caller supplied none, and the lookups fall back to the global
provider.
Static ReadonlyAuthorizesTrue when the action authorizes its caller itself, so a public entry point such as the
RunAction mutation may run it for an authenticated user without an MJ: Action Authorizations link. Set it only on an action that either checks an authorization the caller
must hold, or reads and writes only with the caller's own permissions. Leave it false for an
action that acts with more authority than its caller, or that reaches data or sends messages
the caller chooses but could not otherwise reach.
The engine reads the marker only from the class that runs, never from its parent classes. A subclass that overrides a marked action must declare the marker again.
Description of the action
ProtectedintegrationEvery Integration name this action's provider may be registered under (canonical first).
Define the parameters for this action
Whether this action can bound what it returns to an audience (RunActionParams.Audience): everyone
besides the caller who will see its output, such as the other participants of a shared conversation.
false by default, and the engine enforces it: when a run's audience adds a reader beyond the caller,
ActionEngineServer.RunAction refuses the action with result code AUDIENCE_UNSUPPORTED, without running
it. Override to return true only when the action honours the audience in full — every record, snippet
and count it returns is something every reader may see (pass the audience to the search engine, check each
reader's entitlement to anything it scopes by, and leave out aggregates computed before that filtering).
ProtectedbuildHelper to build consistent error messages for accounting operations
OptionalsystemError: anyProtectedbuildHelper to build OData filter expressions
ProtecteddispatchResolve the company's ERP connection and invoke the plugin registered as
${verb}:${canonical provider name}.
The connection is the one named by the CompanyIntegrationID param when given, otherwise
the company's single active accounting connection. Its ID is then written into the params
(added when absent) so the plugin runs against that same connection instead of looking one
up again. Plugin.Run → InternalRunAction with the caller's params.
ProtectedfindThe company's active connections whose Integration is one of integrationNames.
Filters on the view's Integration column (the Integration's name). Integration.Name is
not bindable on SQL Server.
ProtectedformatStandard date format for accounting systems (ISO 8601)
ProtectedformatFormats date for Business Central API (ISO 8601)
ProtectedformatFormats currency values consistently
ProtectedgetGets the base URL for API calls from the integration
Optionalprovider: IMetadataProviderProtectedgetGets the appropriate Business Central API URL
ProtectedgetCommon accounting parameters that many actions will need.
CompanyIntegrationID names the exact MJ: Company Integrations row to run against. It is
optional: without it the company's single active connection for the provider is used, and a
company with more than one is refused rather than guessed at.
ProtectedgetGets the company's connection for this action's accounting provider.
With companyIntegrationId, exactly that row is loaded; it must belong to companyId, be
active, and be one of this provider's Integrations. Without it, the company's active
connections for the provider (under any of its Integration names) are searched, and more
than one match is an error that names them — the first match is never taken.
The MJ Company the action runs for.
The user the lookup runs as.
OptionalcompanyIntegrationId: stringOptional ID of the exact connection to use.
The connection.
ProtectedgetGets credentials from environment variables Format: BIZAPPS_{PROVIDER}{COMPANY_ID}{CREDENTIAL_TYPE} Example: BIZAPPS_QUICKBOOKS_12345_ACCESS_TOKEN
ProtectedgetGets OAuth tokens - first tries environment variables, then falls back to database
ProtectedgetA param's value as a trimmed, non-empty string, or undefined when it is absent or blank.
ProtectedgetHelper to get a parameter value from the params array
ProtectedInternalProtectedloadLoads one connection by ID and checks that it can be used for companyId: it must exist,
belong to that company, be active, and be one of allowedIntegrationNames.
ProtectedloadLoads and parses the Values JSON of the MJ Credential a connection points at.
ProtectedmakeProtectedmapMaps Business Central account category to standard type
ProtectedmapMaps Business Central account types to standard categories
ProtectedparseParses Business Central date format
ProtectedqueryProtectedrequireReturns the only record in records; throws when there are none or more than one.
The message for the no-match error.
What the caller can pass to pick one when several match.
ProtectedresolveResolves the token, tenant, environment and Business Central company for a connection.
A connection made by MJ's Integrations connector (it has a CredentialID, or a
Configuration carrying a tenant or environment) is resolved the way the connector does it,
with a client-credentials token. Any other connection uses the legacy fields, unchanged.
ProtectedresolveLoad the company's accounting CompanyIntegration: its single active connection whose
Integration is any known ERP name or alias (or, with integrationName, any name of that
provider). Does not hard-filter to a single vendor.
More than one match is refused (AMBIGUOUS_ACCOUNTING_INTEGRATION), even when
integrationName narrows the search: a company with a production and a sandbox connection
to the same ERP must say which one with CompanyIntegrationID.
OptionalintegrationName: stringProtectedresolveConnector-style resolution: merges Configuration with the connection's Credential values,
then gets a client-credentials token from Entra ID (cached per CompanyIntegration).
ProtectedresolveLoad the connection the caller named with CompanyIntegrationID and check that it is an
active accounting connection of companyId (and of integrationName's provider, when given).
OptionalintegrationName: stringProtectedresolveThe original resolution, kept exactly for connections without the connector's settings:
token from BIZAPPS_BUSINESS_CENTRAL_<companyId>_ACCESS_TOKEN or AccessToken, environment
and tenant from CustomAttribute1, BC company from ExternalSystemID.
Captures the request's provider, then runs the action.
ProtectedusesTrue when the connection carries the connector's settings: a CredentialID, or a
Configuration with a tenant or environment key. A Configuration that is not valid JSON
is logged and ignored here, so a legacy connection keeps working.
ProtectedvalidateValidates common accounting data formats
ProtectedvalidateValidates journal entry balance (debits must equal credits)
Action to retrieve General Ledger Entries from Microsoft Dynamics 365 Business Central