Hello,
To prevent customer table locks from recurring each time an integration reads OData from Business Central, I created an API Query Extension in AL.
Everything resolves in VSCode without a problem; however, I get the following exception when I attempt to upload my extension to the sandbox:
The supplied field number “55217” cannot be found in the Customer Table.
I opened a customer record and verified that field 55217 exists within the table and page extension:
Field 55217 on the Customer Table is a Text[50] flow field that correlates to a Text[50] field on the Salespeople/Purchasers extended table/page.
I attempted to enlist the aid of Microsoft Support to identify why, despite resolving without a problem in VSCode, the Extension installation keeps failing. The moment they saw that this related to an extension, I was told they would not render support and to post this on the support (Case 119103124004346).
Any assistance would be greatly appreciated. In addition to understanding why this query fails to recognize field 55217, I am also curious about why API Queries are used over Normal Queries for the sake of integrations.
Customer Table Extension:
tableextension 55200 "SWC-SV00 Customer" extends Customer
{ // These are fields added to support the sync from BC to Shopify, Salesforce, and Zendesk
fields
{
field(55200; "SWC-SV Shopify ID"; Code[20])
{
Caption = 'Shopify ID';
DataClassification = CustomerContent;
}
field(55201; "SWC-SV SalesForce ID"; Text[50])
{
Caption = 'SalesForce ID';
DataClassification = CustomerContent;
}
field(55202; "SWC-SV Zendesk ID"; Code[50])
{
Caption = 'Zendesk ID';
DataClassification = CustomerContent;
}
field(55203; "SWC-SV Shopify User Email"; Text[150])
{
Caption = 'Shopify User Email';
DataClassification = CustomerContent;
}
field(55204; "SWC-SV Created By"; Code[50])
{
Caption = 'Created By';
DataClassification = CustomerContent;
TableRelation = "User Setup";
}
field(55205; "SWC-SV Modified By"; Code[50])
{
Caption = 'Modified By';
DataClassification = CustomerContent;
TableRelation = "User Setup";
}
field(55206; "SWC-SV Created Date"; Date)
{
Caption = 'Created Date';
DataClassification = CustomerContent;
}
field(55207; "SWC-SV Created DateTime"; DateTime)
{
Caption = 'Created Date-Time';
DataClassification = CustomerContent;
}
field(55208; "SWC-SV Modified Date"; Date)
{
Caption = 'Modified Date';
DataClassification = CustomerContent;
}
field(55209; "SWC-SV Modified DateTime"; DateTime)
{
Caption = 'Modified Date-Time';
DataClassification = CustomerContent;
}
field(55210; "SWC-SV Modified on Behalf"; text[50])
{
//This is the modifying user in the other system pushed in by Sync.
Caption = 'Modified on Behalf';
DataClassification = CustomerContent;
}
field(55211; "SWC-SV Apply Template"; Code[10])
{
//on validate to trigger the apply template process for that template.
Caption = 'Template to Apply';
DataClassification = CustomerContent;
TableRelation = "Config. Template Header".Code where("Table ID" = const(18));
trigger OnValidate();
var
ConfigTemplateHeader: record "Config. Template Header";
DimensionsTemplate: Record "Dimensions Template";
ConfigTemplateManagement: Codeunit "Config. Template Management";
RecRef: RecordRef;
begin
if ("SWC-SV Apply Template" <> '') AND (xRec."SWC-SV Apply Template" <> "SWC-SV Apply Template") then begin
ConfigTemplateHeader.Get("SWC-SV Apply Template");
RecRef.GetTable(Rec);
ConfigTemplateManagement.UpdateRecord(ConfigTemplateHeader, RecRef);
DimensionsTemplate.InsertDimensionsFromTemplates(ConfigTemplateHeader, "No.", database::Customer);
recref.SetTable(Rec);
end;
end;
}
field(55212; "SWC-SV Shopify Activ URL"; Boolean)
{
//This is ment to trigger a post script to shopify to send the customer an activation url.
//POST /admin/api/2019-04/customers/#{customer_id}/account_activation_url.json
Caption = 'Send Shopify Activation URL';
DataClassification = CustomerContent;
}
field(55213; "SWC-SV Shopify Invite"; Boolean)
{
//This is ment to trigger a post script to shopify to send the customer a welcome email.
//POST /admin/api/2019-04/customers/#{customer_id}/send_invite.json
Caption = 'Send Shopify Invite Email';
DataClassification = CustomerContent;
}
field(55214; "SWC-SV Shopify Activ URL Date"; DateTime)
{
//This is ment to be backfilled by eOne after succesful change
Caption = 'Shopify Activation URL Sent on';
DataClassification = CustomerContent;
}
field(55215; "SWC-SV Shopify Invite Date"; DateTime)
{
//This is ment to be backfilled by eOne after succesful change
Caption = 'Shopify Invite Email Sent on';
DataClassification = CustomerContent;
}
field(55216; "SWC-SV Set Territory Dim."; Boolean)
{
//This is ment to be triggered when a new customer is created.
Caption = 'Set Territory Dim. Code';
DataClassification = CustomerContent;
trigger OnValidate();
begin
IF "SWC-SV Set Territory Dim." THEN BEGIN
UpdateTeritoryDimension();
END;
END;
}
field(55217; "SWC-SV SP SF Owner ID"; Text[50])
{
Caption = 'Sales Person Owner ID';
FieldClass = FlowField;
CalcFormula = LOOKUP ("Salesperson/Purchaser"."SWC-SV SalesForce Owner ID" WHERE("Code" = FIELD("Salesperson Code")));
}
field(55218; "SWC-SV Shopify Prevent Sync"; Boolean)
{
Caption = 'Shopify Prevent Sync';
}
field(55219; "SWC-SV Shopify Address ID"; Code[20])
{
Caption = 'Shopify Default Address ID';
}
field(55220; "SWC-SV Customer Class"; Text[50])
{
//on validate to trigger the apply template process for that template.
Caption = 'Customer Classification';
DataClassification = CustomerContent;
TableRelation = "SWC-SV00 Customer Class".Classifcation;
}
field(55221; "SWC-SV SalesForce Prevent Sync"; Boolean)
{
Caption = 'SalesForce Prevent Sync';
}
}
//Added Sync key to aid in odata lookup of record for insert/update
keys
{
key(Sync; "SWC-SV Shopify ID", "SWC-SV SalesForce ID", "SWC-SV Zendesk ID", "SWC-SV Shopify User Email")
{
//Unique = true; //Cannot do in table extension
}
}
fieldgroups
{
addlast(DropDown;
"E-Mail")
{
}
}
//Event Triggers
trigger OnBeforeInsert()
var
customer: record Customer;
begin
//Since Key Unique is not available for table extension
if "SWC-SV Shopify ID" <> '' then begin
customer.reset();
customer.SetFilter("SWC-SV Shopify ID", rec."SWC-SV Shopify ID");
if not customer.IsEmpty() then Error('Shopify ID: %1 already in use, cannot insert duplicate id', rec."SWC-SV Shopify ID");
END;
if "SWC-SV SalesForce ID" <> '' then begin
customer.reset();
customer.SetFilter("SWC-SV SalesForce ID", rec."SWC-SV SalesForce ID");
if not customer.IsEmpty() then Error('SalesForce ID: %1 already in use, cannot insert duplicate id', rec."SWC-SV SalesForce ID");
END;
if "SWC-SV Zendesk ID" <> '' then begin
customer.reset();
customer.SetFilter("SWC-SV Zendesk ID", rec."SWC-SV Zendesk ID");
if not customer.IsEmpty() then Error('Zendesk ID: %1 already in use, cannot insert duplicate id', rec."SWC-SV Zendesk ID");
END;
end;
trigger OnInsert();
var
customer: record Customer;
begin
//Since Key Unique is not available for table extension
if "SWC-SV Shopify ID" <> '' then begin
customer.reset();
customer.SetFilter("SWC-SV Shopify ID", rec."SWC-SV Shopify ID");
if not customer.IsEmpty() then Error('Shopify ID: %1 already in use, cannot insert duplicate id', rec."SWC-SV Shopify ID");
END;
if "SWC-SV SalesForce ID" <> '' then begin
customer.reset();
customer.SetFilter("SWC-SV SalesForce ID", rec."SWC-SV SalesForce ID");
if not customer.IsEmpty() then Error('SalesForce ID: %1 already in use, cannot insert duplicate id', rec."SWC-SV SalesForce ID");
END;
if "SWC-SV Zendesk ID" <> '' then begin
customer.reset();
customer.SetFilter("SWC-SV Zendesk ID", rec."SWC-SV Zendesk ID");
if not customer.IsEmpty() then Error('Zendesk ID: %1 already in use, cannot insert duplicate id', rec."SWC-SV Zendesk ID");
END;
"SWC-SV Created By" := UserId();
"SWC-SV Created Date" := Today();
"SWC-SV Created DateTime" := CurrentDateTime();
end;
trigger OnModify();
var
SmokingVaporSetup: Record "SWC-SV00 Smoking Vapor Setup";
begin
"SWC-SV Modified By" := UserId();
"SWC-SV Modified Date" := Today();
"SWC-SV Modified DateTime" := CurrentDateTime();
//for the shopify sync to prevent rubberbanding. Salesforce syncs directly set this to false.
SmokingVaporSetup.Get();
If UserId() <> SmokingVaporSetup."Integration User ID" then begin
"SWC-SV Shopify Prevent Sync" := False;
"SWC-SV SalesForce Prevent Sync" := False;
end;
end;
procedure UpdateTeritoryDimension()
var
SalesSetup: Record "Sales & Receivables Setup";
GeneralLedgerSetup: Record "General Ledger Setup";
DefaultDimension: Record "Default Dimension";
PostCode: Record "Post Code";
PoastalCodeCounties: Record "SWC-SV00 Postal Code Counties";
begin
SalesSetup.GET();
SalesSetup.TESTFIELD("SWC-SV Territory Dim. Code");
GeneralLedgerSetup.GET();
IF SalesSetup."SWC-SV Territory Dim. Code" IN [GeneralLedgerSetup."Global Dimension 1 Code", GeneralLedgerSetup."Global Dimension 2 Code"] THEN BEGIN
IF (PostCode.GET("Post Code", City)) AND (PoastalCodeCounties.GET(PostCode.County, PostCode."SWC-SV County Name")) AND (PoastalCodeCounties."Territory Dimension Code" <> '') THEN BEGIN
IF SalesSetup."SWC-SV Territory Dim. Code" = GeneralLedgerSetup."Global Dimension 1 Code" THEN BEGIN
VALIDATE("Global Dimension 1 Code", PoastalCodeCounties."Territory Dimension Code");
END;
IF SalesSetup."SWC-SV Territory Dim. Code" = GeneralLedgerSetup."Global Dimension 2 Code" THEN BEGIN
VALIDATE("Global Dimension 2 Code", PoastalCodeCounties."Territory Dimension Code");
END;
END
ELSE BEGIN
IF SalesSetup."SWC-SV Territory Dim. Code" = GeneralLedgerSetup."Global Dimension 1 Code" THEN BEGIN
VALIDATE("Global Dimension 1 Code", '');
END;
IF SalesSetup."SWC-SV Territory Dim. Code" = GeneralLedgerSetup."Global Dimension 2 Code" THEN BEGIN
VALIDATE("Global Dimension 2 Code", '');
END;
END;
END
ELSE BEGIN
IF (PostCode.GET("Post Code", City)) AND (PoastalCodeCounties.GET(PostCode.County, PostCode."SWC-SV County Name")) AND (PoastalCodeCounties."Territory Dimension Code" <> '') THEN BEGIN
DefaultDimension.RESET();
DefaultDimension.SETRANGE("Table ID", DATABASE::Customer);
DefaultDimension.SETRANGE("No.", "No.");
DefaultDimension.SETRANGE("Dimension Code", SalesSetup."SWC-SV Territory Dim. Code");
IF DefaultDimension.FIND('-') THEN BEGIN
DefaultDimension.VALIDATE("Dimension Value Code", PoastalCodeCounties."Territory Dimension Code");
DefaultDimension.MODIFY(TRUE);
END
ELSE BEGIN
DefaultDimension.INIT();
DefaultDimension.VALIDATE("Table ID", DATABASE::Customer);
DefaultDimension.VALIDATE("No.", "No.");
DefaultDimension.VALIDATE("Dimension Code", SalesSetup."SWC-SV Territory Dim. Code");
DefaultDimension.VALIDATE("Dimension Value Code", PoastalCodeCounties."Territory Dimension Code");
DefaultDimension.INSERT(TRUE);
END;
END
ELSE BEGIN
DefaultDimension.RESET();
DefaultDimension.SETRANGE("Table ID", DATABASE::Customer);
DefaultDimension.SETRANGE("No.", "No.");
DefaultDimension.SETRANGE("Dimension Code", SalesSetup."SWC-SV Territory Dim. Code");
IF DefaultDimension.FIND('-') THEN BEGIN
DefaultDimension.DELETE(TRUE);
END;
END;
END;
end;
}
Salesperson/Purchaser Table Extension:
[embed:dc8ab71f-3b98-42d9-b0f6-e21e02a0f8e2:09a7716c-71d3-4335-ac21-954db54a550b:type=text&text=tableextension%2055207%20%22SWC-SV00%20Salesperson%2FPurchaser%22%20extends%20%22Salesperson%2FPurchaser%22%20%2F%2FMyTargetTableId%0D%0A%7B%0D%0A%20%20%20%20fields%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20field%2855200%3B%20%22SWC-SV%20SalesForce%20Owner%20ID%22%3B%20Text%5B50%5D%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27SalesForce%20Owner%20ID%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855201%3B%20%22SWC-SV%20Zendesk%20ID%22%3B%20Code%5B50%5D%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Zendesk%20ID%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855204%3B%20%22SWC-SV%20Created%20By%22%3B%20Code%5B50%5D%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Created%20By%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20TableRelation%20%3D%20%22User%20Setup%22%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855205%3B%20%22SWC-SV%20Modified%20By%22%3B%20Code%5B50%5D%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Modified%20By%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20TableRelation%20%3D%20%22User%20Setup%22%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855206%3B%20%22SWC-SV%20Created%20Date%22%3B%20Date%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Created%20Date%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855207%3B%20%22SWC-SV%20Created%20DateTime%22%3B%20DateTime%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Created%20Date-Time%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855208%3B%20%22SWC-SV%20Modified%20Date%22%3B%20Date%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Modified%20Date%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855209%3B%20%22SWC-SV%20Modified%20DateTime%22%3B%20DateTime%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Modified%20Date-Time%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20field%2855210%3B%20%22SWC-SV%20Modified%20on%20Behalf%22%3B%20text%5B50%5D%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2FThis%20is%20the%20modifying%20user%20in%20the%20other%20system%20pushed%20in%20by%20Sync.%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20Caption%20%3D%20%27Modified%20on%20Behalf%27%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20DataClassification%20%3D%20CustomerContent%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20%2F%2FAdded%20Sync%20key%20to%20aid%20in%20odata%20lookup%20of%20record%20for%20insert%2Fupdate%20%20%20%0D%0A%20%20%20%20keys%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20key%28Sync%3B%20%22SWC-SV%20SalesForce%20Owner%20ID%22%29%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2FUnique%20%3D%20true%3B%20%20%2F%2FCannot%20do%20in%20table%20extension%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20%2F%2FEvent%20Triggers%0D%0A%20%20%20%20trigger%20OnInsert%28%29%3B%0D%0A%20%20%20%20begin%0D%0A%20%20%20%20%20%20%20%20%22SWC-SV%20Created%20By%22%20%3A%3D%20UserId%28%29%3B%0D%0A%20%20%20%20%20%20%20%20%22SWC-SV%20Created%20Date%22%20%3A%3D%20Today%28%29%3B%0D%0A%20%20%20%20%20%20%20%20%22SWC-SV%20Created%20DateTime%22%20%3A%3D%20CurrentDateTime%28%29%3B%0D%0A%20%20%20%20end%3B%0D%0A%0D%0A%20%20%20%20trigger%20OnAfterInsert%28%29%3B%0D%0A%20%20%20%20begin%0D%0A%20%20%20%20%20%20%20%20UpdateDimensionValue_gFnc%280%29%3B%0D%0A%20%20%20%20end%3B%0D%0A%0D%0A%20%20%20%20trigger%20OnModify%28%29%3B%0D%0A%20%20%20%20begin%0D%0A%20%20%20%20%20%20%20%20%22SWC-SV%20Modified%20By%22%20%3A%3D%20UserId%28%29%3B%0D%0A%20%20%20%20%20%20%20%20%22SWC-SV%20Modified%20Date%22%20%3A%3D%20Today%28%29%3B%0D%0A%20%20%20%20%20%20%20%20%22SWC-SV%20Modified%20DateTime%22%20%3A%3D%20CurrentDateTime%28%29%3B%0D%0A%20%20%20%20%20%20%20%20UpdateDimensionValue_gFnc%281%29%3B%0D%0A%20%20%20%20end%3B%0D%0A%0D%0A%20%20%20%20trigger%20OnBeforeDelete%28%29%3B%0D%0A%20%20%20%20begin%0D%0A%20%20%20%20%20%20%20%20UpdateDimensionValue_gFnc%282%29%3B%0D%0A%20%20%20%20end%3B%0D%0A%0D%0A%20%20%20%20trigger%20OnAfterRename%28%29%3B%0D%0A%20%20%20%20begin%0D%0A%20%20%20%20%20%20%20%20UpdateDimensionValue_gFnc%283%29%3B%0D%0A%20%20%20%20end%3B%0D%0A%0D%0A%20%20%20%20procedure%20UpdateDimensionValue_gFnc%28KeyChange_pOpt%3A%20Option%20Insert%2CModify%2CDelete%2CRename%29%0D%0A%20%20%20%20var%0D%0A%20%20%20%20%20%20%20%20DimensionValue_lRec%3A%20Record%20%22Dimension%20Value%22%3B%0D%0A%20%20%20%20%20%20%20%20DefaultDimension_lRec%3A%20Record%20%22Default%20Dimension%22%3B%0D%0A%20%20%20%20%20%20%20%20SalesSetup_lRec%3A%20Record%20%22Sales%20%26%20Receivables%20Setup%22%3B%0D%0A%20%20%20%20%20%20%20%20GeneralLedgerSetup_lRec%3A%20Record%20%22General%20Ledger%20Setup%22%3B%0D%0A%20%20%20%20begin%0D%0A%20%20%20%20%20%20%20%20SalesSetup_lRec.Get%28%29%3B%0D%0A%20%20%20%20%20%20%20%20SalesSetup_lRec.TESTFIELD%28%22Salesperson%20Dimension%20Code%22%29%3B%0D%0A%20%20%20%20%20%20%20%20case%20KeyChange_pOpt%20of%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20KeyChange_pOpt%3A%3AInsert%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20begin%0D%0A%20