Describe the issue
The Subscription Billing module contains multiple procedures declared as internal and enums with Extensible = false that produce AL0161 compiler errors when called from partner extensions, or prevent partners from adding custom enum values.
Part 1 — Remove internal from procedures
1. Page 8002 "Extend Contract" — SetParameters()
internal procedure SetParameters(
NewCustomerNo: Code[20];
NewCustomerContractNo: Code[20];
NewProvisionStartDate: Date;
NewExtendCustomerContract: Boolean)
Must be called before RunModal to pre-populate customer no., customer contract no., provision start date, and extend-customer-contract flag from an upstream usage data import record, eliminating manual entry per import line.
2. Page 8002 "Extend Contract" — SetUsageBasedParameters()
internal procedure SetUsageBasedParameters(
SupplierNo: Code[20];
NewSubscriptionEntryNo: Integer)
Must be called alongside SetParameters() to pass the usage data supplier no. and subscription entry no. for the usage-based billing path.
3. Table 8057 "Subscription Header" — SetUnitPriceAndUnitCostFromExtendContract()
internal procedure SetUnitPriceAndUnitCostFromExtendContract(
NewUnitPrice: Decimal;
NewUnitCost: Decimal)
Called after subscription creation to set unit price and cost on the new Subscription Header. Required to replicate the standard "Extend Contract" page flow from an extension.
4. Table 8057 "Subscription Header" — ResetCalledFromExtendContract()
internal procedure ResetCalledFromExtendContract()
Must be called at the end of the extension flow to reset the CalledFromExtendContract flag. Without this, the record is left in an inconsistent state.
5. Table 8055 "Subscription Package" — FilterCodeOnPackageFilter()
internal procedure FilterCodeOnPackageFilter(PackageFilter: Text)
Used to filter subscription packages for a selected item using the standard package filter logic. Required to replicate item-validation behaviour of the standard "Extend Contract" page.
6. Table 8055 "Subscription Package" — ServCommPackageLineExists()
internal procedure ServCommPackageLineExists(): Boolean
Required to check whether a subscription package has any lines before proceeding with contract extension. Currently inaccessible, forcing re-implementation of equivalent logic.
7. Table 8058 "Item Subscription Package" — GetAllStandardPackageFilterForItem()
internal procedure GetAllStandardPackageFilterForItem(
ItemNo: Code[20];
CustomerPriceGroup: Code[10]) PackageFilter: Text
Used to retrieve the complete standard package filter for a given item, required when filtering subscription packages in a cloned or extended "Extend Contract" flow.
8. Table 8058 "Item Subscription Package" — GetPackageFilterForItem() (overloads)
The following three overloads are declared as internal (one overload is already public):
internal procedure GetPackageFilterForItem(
ItemNo: Code[20]; ServiceObjectNo: Code[20]) PackageFilter: Text
internal procedure GetPackageFilterForItem(
ItemNo: Code[20]; ServiceObjectNo: Code[20];
OnlyNonStandardPackage: Boolean) PackageFilter: Text
internal procedure GetPackageFilterForItem(
SalesLine: Record "Sales Line";
RemoveExistingPackageFromFilter: Boolean) PackageFilter: Text
These overloads provide variant-aware and sales-line-aware package filtering, required for partner extensions managing subscription packages per item variant.
9. Table 8015 "Usage Data Supplier Reference" — FindSupplierReference()
internal procedure FindSupplierReference(
SupplierNo: Code[20];
SupplierReference: Text[80];
ReferenceType: Enum "Usage Data Reference Type"): Boolean
Required to look up existing supplier references during usage data import processing. Currently inaccessible, blocking partner extensions that need to resolve or validate supplier references programmatically.
10. Table 8013 "Usage Data Import" — CollectVendorContractsAndCreateInvoices()
internal procedure CollectVendorContractsAndCreateInvoices(
var UsageDataImport: Record "Usage Data Import")
Needs to be called before the standard invocation to set SingleInstance variables controlling processing behaviour. Declared as internal, this pre-call is not possible.
11. Page 8058 "Service Comm. Package Lines" — SetItemNo(), SetShowAllPackageLines(), SetPackageCode()
internal procedure SetItemNo(NewItemNo: Code[20])
internal procedure SetShowAllPackageLines(NewShowAllPackageLines: Boolean)
internal procedure SetPackageCode(NewPackageCode: Code[20])
All three are required to clone or embed this page in a partner extension managing subscription packages per item variant. Without them, the page cannot be opened with the correct context.
12. Tableextension 8054 "Sales Line" — IsContractRenewal()
internal procedure IsContractRenewal(): Boolean
Required to determine whether a sales line is part of a contract renewal, needed when implementing item-variant-based subscription package assignment in the sales flow.
13. Codeunit 8069 "Sales Subscription Line Mgmt." — AddSalesServiceCommitmentsForSalesLine()
internal procedure AddSalesServiceCommitmentsForSalesLine(
var SalesLine: Record "Sales Line";
SkipAddAdditionalSalesServComm: Boolean)
Required to trigger subscription line assignment for a sales line from a partner extension. Currently internal, blocking extensions that need to add subscription commitments programmatically during sales order processing.
Part 2 — Remove Access = Internal from codeunits
14. Codeunit 8028 "Usage Based Contr. Subscribers"
codeunit 8028 "Usage Based Contr. Subscribers"
{
Access = Internal;
The entire codeunit is inaccessible to partner extensions. Removing Access = Internal (or selectively making individual procedures public) is required for usage-based contract processing scenarios.
15. Codeunit 8020 "Personalization Data Mgmt."
codeunit 8020 "Personalization Data Mgmt."
{
Access = Internal;
Required to clone Page 8058 "Service Comm. Package Lines" for item-variant-level subscription package management. The personalization data this codeunit manages cannot be accessed from the cloned page when sealed with Access = Internal.
Part 3 — Set Extensible = true on enums
16. Enum 8057 "Customer Rec. Billing Grouping"
Current values: Contract, Sell-to Customer No., Bill-to Customer No.
Partners need to add custom grouping options for customer recurring billing runs.
17. Enum 8058 "Vendor Rec. Billing Grouping"
Current values: Contract, Buy-from Vendor No., Pay-to Vendor No.
Same as above for vendor recurring billing runs.
18. Enum 8001 "Contract Invoice Text Type"
Current values: , Service Object, Service Commitment, Customer Reference, Serial No., Billing Period, Primary attribute
Partners need to add custom invoice text types (e.g. project number or external reference) without duplicating the entire text-generation logic.
19. Enum 8054 "Rec. Billing Document Type"
Current values: None, Invoice, Credit Memo
Partners need to add Order as a document type to support billing workflows requiring a sales order step before invoicing.
20. Enum 8008 "Usage Based Billing Doc. Type"
Current values: None, Invoice, Credit Memo, Posted Invoice, Posted Credit Memo
Order is needed to support order-based processing in the usage-based billing path.
Expected behavior
The listed procedures are accessible from partner extensions (internal modifier removed). The listed enums are extensible (Extensible = true).
Steps to reproduce
Call any of the listed internal procedures from a partner extension targeting Subscription Billing. Result: AL0161 compiler error "inaccessible due to its protection level".
Additional context
No response
I will provide a fix for a bug
Describe the issue
The Subscription Billing module contains multiple procedures declared as
internaland enums withExtensible = falsethat produce AL0161 compiler errors when called from partner extensions, or prevent partners from adding custom enum values.Part 1 — Remove
internalfrom procedures1. Page 8002 "Extend Contract" —
SetParameters()Must be called before
RunModalto pre-populate customer no., customer contract no., provision start date, and extend-customer-contract flag from an upstream usage data import record, eliminating manual entry per import line.2. Page 8002 "Extend Contract" —
SetUsageBasedParameters()Must be called alongside
SetParameters()to pass the usage data supplier no. and subscription entry no. for the usage-based billing path.3. Table 8057 "Subscription Header" —
SetUnitPriceAndUnitCostFromExtendContract()Called after subscription creation to set unit price and cost on the new Subscription Header. Required to replicate the standard "Extend Contract" page flow from an extension.
4. Table 8057 "Subscription Header" —
ResetCalledFromExtendContract()Must be called at the end of the extension flow to reset the
CalledFromExtendContractflag. Without this, the record is left in an inconsistent state.5. Table 8055 "Subscription Package" —
FilterCodeOnPackageFilter()Used to filter subscription packages for a selected item using the standard package filter logic. Required to replicate item-validation behaviour of the standard "Extend Contract" page.
6. Table 8055 "Subscription Package" —
ServCommPackageLineExists()Required to check whether a subscription package has any lines before proceeding with contract extension. Currently inaccessible, forcing re-implementation of equivalent logic.
7. Table 8058 "Item Subscription Package" —
GetAllStandardPackageFilterForItem()Used to retrieve the complete standard package filter for a given item, required when filtering subscription packages in a cloned or extended "Extend Contract" flow.
8. Table 8058 "Item Subscription Package" —
GetPackageFilterForItem()(overloads)The following three overloads are declared as
internal(one overload is already public):These overloads provide variant-aware and sales-line-aware package filtering, required for partner extensions managing subscription packages per item variant.
9. Table 8015 "Usage Data Supplier Reference" —
FindSupplierReference()Required to look up existing supplier references during usage data import processing. Currently inaccessible, blocking partner extensions that need to resolve or validate supplier references programmatically.
10. Table 8013 "Usage Data Import" —
CollectVendorContractsAndCreateInvoices()Needs to be called before the standard invocation to set SingleInstance variables controlling processing behaviour. Declared as
internal, this pre-call is not possible.11. Page 8058 "Service Comm. Package Lines" —
SetItemNo(),SetShowAllPackageLines(),SetPackageCode()All three are required to clone or embed this page in a partner extension managing subscription packages per item variant. Without them, the page cannot be opened with the correct context.
12. Tableextension 8054 "Sales Line" —
IsContractRenewal()Required to determine whether a sales line is part of a contract renewal, needed when implementing item-variant-based subscription package assignment in the sales flow.
13. Codeunit 8069 "Sales Subscription Line Mgmt." —
AddSalesServiceCommitmentsForSalesLine()Required to trigger subscription line assignment for a sales line from a partner extension. Currently
internal, blocking extensions that need to add subscription commitments programmatically during sales order processing.Part 2 — Remove
Access = Internalfrom codeunits14. Codeunit 8028 "Usage Based Contr. Subscribers"
The entire codeunit is inaccessible to partner extensions. Removing
Access = Internal(or selectively making individual procedures public) is required for usage-based contract processing scenarios.15. Codeunit 8020 "Personalization Data Mgmt."
Required to clone Page 8058 "Service Comm. Package Lines" for item-variant-level subscription package management. The personalization data this codeunit manages cannot be accessed from the cloned page when sealed with
Access = Internal.Part 3 — Set
Extensible = trueon enums16. Enum 8057 "Customer Rec. Billing Grouping"
Current values:
Contract,Sell-to Customer No.,Bill-to Customer No.Partners need to add custom grouping options for customer recurring billing runs.
17. Enum 8058 "Vendor Rec. Billing Grouping"
Current values:
Contract,Buy-from Vendor No.,Pay-to Vendor No.Same as above for vendor recurring billing runs.
18. Enum 8001 "Contract Invoice Text Type"
Current values:
,Service Object,Service Commitment,Customer Reference,Serial No.,Billing Period,Primary attributePartners need to add custom invoice text types (e.g. project number or external reference) without duplicating the entire text-generation logic.
19. Enum 8054 "Rec. Billing Document Type"
Current values:
None,Invoice,Credit MemoPartners need to add
Orderas a document type to support billing workflows requiring a sales order step before invoicing.20. Enum 8008 "Usage Based Billing Doc. Type"
Current values:
None,Invoice,Credit Memo,Posted Invoice,Posted Credit MemoOrderis needed to support order-based processing in the usage-based billing path.Expected behavior
The listed procedures are accessible from partner extensions (internal modifier removed). The listed enums are extensible (Extensible = true).
Steps to reproduce
Call any of the listed internal procedures from a partner extension targeting Subscription Billing. Result: AL0161 compiler error "inaccessible due to its protection level".
Additional context
No response
I will provide a fix for a bug