The Customer Card is one of the most used pages in Business Central. Almost every implementation requires some level of customization — whether it’s adding industry-specific fields, validation rules, or custom actions.
In this article, I’ll walk you through a real-world example of extending the Customer Card.

The Business Requirement
Our client needs:
- A Credit Rating field (A, B, C, D) on each customer
- Automatic blocking of sales orders when a customer has a D rating
- A custom action to recalculate the rating based on payment history
Step 1: Extend the Customer Table
First, we add the new field to the Customer table:
tableextension 50101 CreditRatingExt extends Customer
{
fields
{
field(50101; "Credit Rating"; Enum "Credit Rating")
{
Caption = 'Credit Rating';
DataClassification = CustomerContent;
trigger OnValidate()
begin
if Rec."Credit Rating" = Rec."Credit Rating"::D then
Rec.Blocked := Rec.Blocked::All;
end;
}
}
}
enum 50101 "Credit Rating"
{
Extensible = true;
value(0; " ") { Caption = ' '; }
value(1; "A") { Caption = 'A - Excellent'; }
value(2; "B") { Caption = 'B - Good'; }
value(3; "C") { Caption = 'C - Fair'; }
value(4; "D") { Caption = 'D - Poor'; }
}
Step 2: Add it to the Customer Card
Now we display the field and add our custom action:
pageextension 50101 CreditRatingCardExt extends "Customer Card"
{
layout
{
addafter("Credit Limit (LCY)")
{
field("Credit Rating"; Rec."Credit Rating")
{
ApplicationArea = All;
ToolTip = 'Specifies the credit rating based on payment history.';
StyleExpr = CreditRatingStyle;
}
}
}
actions
{
addafter("Co&mments")
{
action(RecalculateRating)
{
ApplicationArea = All;
Caption = 'Recalculate Credit Rating';
Image = Calculate;
Promoted = true;
PromotedCategory = Process;
trigger OnAction()
var
CreditMgmt: Codeunit "Credit Rating Management";
begin
CreditMgmt.RecalculateRating(Rec);
CurrPage.Update();
end;
}
}
}
var
CreditRatingStyle: Text;
}
Step 3: Business Logic in a Codeunit
The actual rating calculation lives in a separate codeunit:
codeunit 50101 "Credit Rating Management"
{
procedure RecalculateRating(var Customer: Record Customer)
var
CustLedgerEntry: Record "Cust. Ledger Entry";
LatePayments: Integer;
TotalPayments: Integer;
begin
CustLedgerEntry.SetRange("Customer No.", Customer."No.");
CustLedgerEntry.SetRange("Document Type", CustLedgerEntry."Document Type"::Payment);
TotalPayments := CustLedgerEntry.Count;
CustLedgerEntry.SetFilter("Due Date", '<%1', CustLedgerEntry."Posting Date");
LatePayments := CustLedgerEntry.Count;
case true of
(TotalPayments = 0),
(LatePayments / TotalPayments < 0.1):
Customer."Credit Rating" := Customer."Credit Rating"::A;
(LatePayments / TotalPayments < 0.25):
Customer."Credit Rating" := Customer."Credit Rating"::B;
(LatePayments / TotalPayments < 0.5):
Customer."Credit Rating" := Customer."Credit Rating"::C;
else
Customer."Credit Rating" := Customer."Credit Rating"::D;
end;
Customer.Modify(true);
end;
}
Key Takeaways
- Always use enums instead of option fields — they’re extensible
- Put logic in codeunits, not in page triggers — better testability
- Use events when you need to hook into standard BC processes
- Test in a sandbox before deploying to production
This pattern — table extension + page extension + codeunit — is the foundation of almost every BC customization. Master it and you can build anything.