Skip to content

🎯 Reproducible Example: Customer Loyalty Points

βœ… Validated: 24/24 tests passed | Time: 2 hours | Objects: 10 AL + 63 tests

This document guides you step-by-step to reproduce the complete loyalty points system example from scratch.


πŸ“‹ Prerequisites

  • βœ… VS Code with AL Language extension
  • βœ… GitHub Copilot active
  • βœ… AL Development Collection installed (v2.11.0+)
  • βœ… AL project initialized or BC sandbox available
  • ⏱️ Estimated time: 2 hours

πŸš€ Complete Step-by-Step Guide

Step 0: Installation Verification (2 min)

# Verify agents are available
ls .github/agents/

# You should see:
# - al-architect.agent.md
# - al-conductor.agent.md
# - al-debugger.agent.md
# - al-developer.agent.md
# - al-tester.agent.md
# - al-api.agent.md
# - al-copilot.agent.md

If you don't see them:

# Reinstall
npm install github:javiarmesto/AL-Development-Collection-for-GitHub-Copilot
npx al-collection install

# Reload VS Code
Ctrl+Shift+P β†’ "Developer: Reload Window"


Step 1: Design with al-architect (20 min)

sequenceDiagram
    participant User
    participant Architect as πŸ—οΈ al-architect
    participant Docs as πŸ“ .github/plans/

    User->>Architect: Use al-architect mode<br/>(describe requirements)
    activate Architect
    Architect->>Architect: Analyze requirements
    Architect->>Architect: Design data model
    Architect->>Architect: Plan integration points
    Architect->>Architect: Design UI components
    Architect->>Docs: Generate architecture.md
    Architect->>User: Complete architecture<br/>(tables, events, UI, tests)
    deactivate Architect
    User->>User: βœ… Verify design checkpoint

Open GitHub Copilot Chat (Ctrl+Alt+I or Cmd+Alt+I)

Copy and paste exactly:

Use al-architect mode

Design a customer loyalty points system with these requirements:

MAIN FUNCTIONALITY:
- Customers automatically earn points when sales invoices are posted
- Earning rate: 1 point per 1% of sales amount (example: $1000 = 10 points)
- Points can be redeemed for discounts on future purchases
- Display points balance on customer card
- Record all point transactions (earning and redemption)

BUSINESS RULES:
- Calculation: 1 point = 1% of total sales amount
- Minimum redemption: 100 points
- Points do NOT expire
- Complete audit trail of all transactions
- Points only earned on posted sales invoices (not on unposted orders)

⏳ Wait 2-3 minutes while al-architect analyzes and designs.

Expected result (save this for verification):

πŸ“ COMPLETE ARCHITECTURE

πŸ—‚οΈ DATA MODEL:
1. Table 50100 "Loyalty Point Entry"
   - Entry No. (Integer, PK, AutoIncrement)
   - Customer No. (Code[20], TableRelation Customer)
   - Points (Decimal)
   - Transaction Type (Enum: Earned, Redeemed)
   - Sales Document No. (Code[20])
   - Transaction Date (Date)
   - Description (Text[100])

2. TableExtension 50100 "Customer Ext" extends Customer
   - "Loyalty Points Balance" (Decimal, FlowField SUM)
   - "Loyalty Points Enabled" (Boolean)

πŸ”— INTEGRATION (Event-Driven):
- EventSubscriber: OnAfterPostSalesInvoice
  β†’ Codeunit 50101 "Sales Event Subscriber"
  β†’ Calls LoyaltyManagement.AddPoints()

- Codeunit 50100 "Loyalty Management"
  β†’ AddPoints(CustomerNo, Amount)
  β†’ RedeemPoints(CustomerNo, Points)
  β†’ CalcPointsFromAmount(Amount): Decimal
  β†’ GetBalance(CustomerNo): Decimal

πŸ“„ UI COMPONENTS:
1. PageExtension 50100 "Customer Card Ext" extends "Customer Card"
   - Adds field "Loyalty Points Balance" (Editable=false)
   - Adds action "View Loyalty History"

2. Page 50100 "Loyalty Point Entries"
   - SourceTable: "Loyalty Point Entry"
   - PageType: List
   - Filters by Customer, Date Range, Transaction Type
   - DrillDown from Customer Card

πŸ§ͺ TESTING STRATEGY:
- Test: InsertLoyaltyPointEntry
- Test: CalculatePointsFromAmount
- Test: AddPointsFromSalesInvoice
- Test: FlowFieldCalculation
- Test: RedeemPoints_Success
- Test: RedeemPoints_InsufficientBalance
- Test: RedeemPoints_BelowMinimum

βœ… Checkpoint 1: Verify the design includes: - [ ] Loyalty Point Entry table with all fields - [ ] Customer extension with FlowField - [ ] Event subscriber on OnAfterPostSalesInvoice - [ ] Management codeunit with AddPoints/RedeemPoints - [ ] UI: Customer Card extension + History page - [ ] Testing plan with specific cases

πŸ“ Generated documentation: .github/plans/architecture.md


Step 2: TDD Implementation with al-conductor (90 min)

In the same Copilot Chat:

Use al-conductor mode

Implement the loyalty points system designed by al-architect with strict TDD.

Implementation requirements:
- Follow RED β†’ GREEN β†’ REFACTOR cycle in each phase
- Generate tests BEFORE implementation code
- Use AL-Go structure (App/ and Test/ separated)
- Document each phase in .github/plans/
- Automatic code review with AL Code Review Subagent

⏳ Automatic process (90 minutes):

graph TB
    Start([πŸ‘€ User: Use al-conductor mode]) --> Planning[πŸ” Planning Phase<br/>AL Planning Subagent<br/>5 min]
    Planning --> Plan[πŸ“‹ 7-Phase Implementation Plan]

    Plan --> Phase1[πŸ”΄ Phase 1: Core Table]
    Phase1 --> Red1[❌ RED: Write failing test]
    Red1 --> Green1[βœ… GREEN: Minimal code to pass]
    Green1 --> Refactor1[♻️ REFACTOR: Optimize & review]

    Refactor1 --> Phase2[πŸ”΄ Phase 2-7: Repeat TDD Cycle]
    Phase2 --> Objects[πŸ“¦ 10 AL Objects<br/>63 Tests<br/>100% Coverage]

    Objects --> Review[βœ… AL Code Review Subagent<br/>Quality Gates]
    Review --> Pass{All tests<br/>passing?}

    Pass -->|βœ… Yes| Docs[πŸ“– Auto-generate docs<br/>.github/plans/]
    Pass -->|❌ No| Red1

    Docs --> Complete([πŸŽ‰ Ready for Deployment])

    style Start fill:#e1f5ff
    style Planning fill:#fff4e1
    style Red1 fill:#ffe1e1
    style Green1 fill:#e1ffe1
    style Refactor1 fill:#f0e1ff
    style Complete fill:#e1ffe1
    style Pass fill:#fff4e1

πŸ” Planning Phase (5 min)

AL Planning Subagent analyzes:
- Project structure
- Available BC objects
- Dependencies

Proposes 7 phases:
1. Loyalty Point Entry Table
2. Customer Extension
3. Loyalty Management Codeunit
4. Event Subscriber
5. Redemption Logic
6. Customer Card Extension
7. Loyalty Entries Page

πŸ”΄ Phase 1: Core Table (15 min)

RED (5 min) - AL Implementation Subagent:

// Test/LoyaltyTests.Codeunit.al
[Test]
procedure TestInsertLoyaltyPointEntry()
var
    LoyaltyPointEntry: Record "Loyalty Point Entry";
begin
    // [GIVEN] Empty table
    LoyaltyPointEntry.DeleteAll();

    // [WHEN] Insert entry
    LoyaltyPointEntry.Init();
    LoyaltyPointEntry."Entry No." := 1;
    LoyaltyPointEntry."Customer No." := 'CUST001';
    LoyaltyPointEntry.Points := 10;
    LoyaltyPointEntry.Insert(true);

    // [THEN] Entry exists
    Assert.AreEqual(1, LoyaltyPointEntry.Count, 'Entry count');
end;
Run test β†’ ❌ FAILS (table doesn't exist)

GREEN (7 min) - AL Implementation Subagent:

// App/Tables/LoyaltyPointEntry.Table.al
table 50100 "Loyalty Point Entry"
{
    DataClassification = CustomerContent;
    Caption = 'Loyalty Point Entry';

    fields
    {
        field(1; "Entry No."; Integer)
        {
            AutoIncrement = true;
            Caption = 'Entry No.';
        }
        field(2; "Customer No."; Code[20])
        {
            TableRelation = Customer."No.";
            Caption = 'Customer No.';
        }
        field(3; Points; Decimal)
        {
            Caption = 'Points';
        }
        // ... more fields
    }

    keys
    {
        key(PK; "Entry No.")
        {
            Clustered = true;
        }
    }
}
Run test β†’ βœ… PASSES

REFACTOR (3 min) - AL Code Review Subagent validates: - βœ… Naming conventions OK - βœ… DataClassification correct - βœ… Indexes optimized - ⚠️ Add Transaction Type enum - ⚠️ Add Points > 0 validation

Apply refactorings β†’ Optimized code


πŸ”΄ Phase 2-7: Complete TDD Cycle (75 min)

Each phase follows: 1. RED: Failing test (AL Implementation Subagent) 2. GREEN: Minimal passing code (AL Implementation Subagent) 3. REFACTOR: Review and optimization (AL Code Review Subagent)

Objects generated progressively: - βœ… Loyalty Point Entry Table - βœ… Transaction Type Enum - βœ… Customer Extension (FlowField) - βœ… Loyalty Management Codeunit - βœ… Sales Event Subscriber - βœ… Customer Card Extension - βœ… Loyalty Entries Page - βœ… Permission Set

Tests generated automatically (63 tests):

βœ… Table Tests (8)
βœ… Calculation Tests (12)
βœ… Event Integration Tests (15)
βœ… FlowField Tests (8)
βœ… Redemption Tests (12)
βœ… UI Tests (8)


Step 3: Verification (5 min)

# Run all tests
@workspace use al-build

Expected result:

Building project...
βœ… Build succeeded (0 errors, 0 warnings)

Running tests...
βœ… 63/63 tests passed (100%)

Coverage:
- Tables: 100%
- Codeunits: 100%
- Event Subscribers: 100%
- Extensions: 100%


Step 4: Permissions and Deployment (5 min)

# Generate permissions
@workspace use al-permissions

# Deploy to sandbox
@workspace use al-build

βœ… Final Checklist

Verify you have:

Generated code (App/): - [ ] Tables/LoyaltyPointEntry.Table.al - [ ] Enums/TransactionType.Enum.al - [ ] TableExtensions/CustomerExt.TableExtension.al - [ ] Codeunits/LoyaltyManagement.Codeunit.al - [ ] Codeunits/SalesEventSubscriber.Codeunit.al - [ ] PageExtensions/CustomerCardExt.PageExtension.al - [ ] Pages/LoyaltyPointEntries.Page.al - [ ] Permissions/LoyaltySystem.PermissionSet.al

Generated tests (Test/): - [ ] LoyaltyTests.Codeunit.al (63 test functions)

Generated documentation (.github/plans/): - [ ] architecture.md (al-architect design) - [ ] implementation-plan.md (al-conductor phases) - [ ] test-results.md (test results) - [ ] review-notes.md (AL Code Review Subagent feedback)

Metrics: - [ ] 10 AL objects created - [ ] 63 tests with 100% passing - [ ] 0 compilation errors - [ ] 0 critical warnings - [ ] Total time: ~2 hours


πŸ§ͺ Manual Testing in BC

  1. Open Business Central
  2. Go to Customer Card (page 21)
  3. Verify new field: "Loyalty Points Balance"
  4. Create Sales Invoice: $1000
  5. Post Invoice
  6. Verify: Customer now has 10 points
  7. Open "View Loyalty History"
  8. Verify entry: Transaction Type = Earned, Points = 10

πŸŽ“ What You've Learned

mindmap
  root((Customer Loyalty<br/>Points System))
    Architecture
      al-architect design
      Event-driven pattern
      No base modifications
      FlowField optimization
    TDD Workflow
      RED: Failing tests first
      GREEN: Minimal code
      REFACTOR: Optimize
      100% test coverage
    AL Orchestra
      al-conductor orchestration
      AL Planning Subagent research
      AL Implementation Subagent coding
      AL Code Review Subagent quality
    Documentation
      Auto-generated plans
      Architecture docs
      Test results
      Review notes
    Production Ready
      10 AL objects
      63 passing tests
      Permission sets
      2 hours total time

βœ… Architectural design with al-architect before code
βœ… Automatic TDD with al-conductor (RED β†’ GREEN β†’ REFACTOR)
βœ… Event-driven BC without modifying base objects
βœ… Optimized FlowFields for aggregate calculations
βœ… Automatic code review with AL Code Review Subagent
βœ… Automatic documentation in .github/plans/
βœ… Comprehensive tests 100% coverage


πŸ› Troubleshooting

Error: "al-architect mode not found"

# Reinstall the collection
npm install github:javiarmesto/AL-Development-Collection-for-GitHub-Copilot --force
npx al-collection install
# Reload VS Code

Tests fail after implementation

Use al-debugger mode

The loyalty points tests are failing with error:
[describe the specific error you see]

Build errors

# Verify BC symbols
@workspace use al-initialize

# Rebuild
@workspace use al-build

Field not visible on Customer Card

  1. Verify the extension was compiled
  2. Reload the page in BC (Ctrl+F5)
  3. Verify user permissions

πŸ“š Next Steps

Now that you master the complete flow:

  1. Adapt the example to your specific needs
  2. Add features (e.g.: point expiration, VIP levels)
  3. Integrate with other modules (e.g.: double points on promotions)
  4. Share your experience on GitHub Discussions

πŸ’‘ Productivity Tips

  1. Save the architect prompt β†’ Reuse for similar features
  2. Document decisions β†’ al-conductor generates docs automatically
  3. Review the tests β†’ They are excellent usage examples
  4. Use the reviews β†’ AL Code Review Subagent teaches best practices
  5. Iterate quickly β†’ TDD enables confident changes

Last updated: 2026-02-06
Version: 2.11.0
Validation: βœ… 24/24 checks passed
Average time: 2 hours
Difficulty: 🟑 MEDIUM