---
id: object/codeunit/6973
type: object
title: Codeunit 6973 "Create Expense Categories"
summary: Codeunit 6973 "Create Expense Categories" in ExpenseAgent (Microsoft.ExpenseAgent). 68 public procedures, 13 events. Introduced in BC29, still in BC30, changed in BC30.
tier: official
language: en
tags:
  - codeunit
  - expenseagent
versions:
  introduced: "29"
  last_changed: "30"
  deprecated: null
review:
  state: derived
  by: null
  at: null
  flags: []
generated:
  at: "2026-10-11T00:31:51.816Z"
  pipeline: 0.2.0
  prompts: {}
  input_hash: b644d219cc0233bfa413807d27c409ea267e6a8c13d579932187f93d44f12fac
evidence:
  - kind: code
    url: https://github.com/microsoft/BCApps/blob/ea08af5ef2d6a9b5c5af4a029288abbe2c883220/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseCategories.Codeunit.al
    title: src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseCategories.Codeunit.al (releases/29.x)
    date: null
    commit: ea08af5ef2d6a9b5c5af4a029288abbe2c883220
    t: null
    quote: null
links:
  learn: []
  objects: []
  features: []
  topics: []
  localizations: []
  videos: []
  posts: []
  guidelines: []
  changes:
    - change/bcapps/11425
    - change/bcapps/10990
    - change/bcapps/10155
    - change/bcapps/10637
    - change/bcapps/9859
object_type: codeunit
object_id: 6973
name: Create Expense Categories
namespace: Microsoft.ExpenseAgent
app: ExpenseAgent
extends: null
first_version: "29"
last_version: "30"
present_in:
  - "29"
  - "30"
changed_in:
  - "30"
source_major: "29"
obsolete: null
countries: []
ms_search_form_ids: []
counts:
  fields: 0
  procedures: 88
  events: 13
  subscribers: 0
relations:
  out: 0
  referenced_by: 0
  pages: 0
  extended_by: 0
  event_subscribers: 0
  calls: 5
  called_by: 8
  implements: 0
---

# Codeunit 6973 "Create Expense Categories"

> Codeunit 6973 "Create Expense Categories" in ExpenseAgent (Microsoft.ExpenseAgent). 68 public procedures, 13 events. Introduced in BC29, still in BC30, changed in BC30.

ExpenseAgent · Microsoft.ExpenseAgent · BC29-30 · [source at ea08af5e](https://github.com/microsoft/BCApps/blob/ea08af5ef2d6a9b5c5af4a029288abbe2c883220/src/Apps/W1/ExpenseAgent/app/src/Setup/Codeunits/CreateExpenseCategories.Codeunit.al) · facts from BC29

## Properties

| Property | Value |
|---|---|
| Access | Internal |

## Events published

- `OnAfterBuildPostingGroupSeeds(var TempPostingGroup: Record "Expense Posting Group" temporary)` (integration)
- `OnAfterBuildCategorySeeds(var TempCategory: Record "Expense Category" temporary)` (integration)
- `OnAfterBuildSubcategorySeeds(var TempSubcategory: Record "Expense Subcategory" temporary)` (integration)
- `OnAfterBuildRuleSeeds(var TempRuleHeader: Record "Expense Rule Header" temporary)` (integration)
- `OnAfterBuildRuleConditionSeeds(var TempRuleCondition: Record "Expense Rule Condition" temporary)` (integration)
- `OnBeforeInsertPostingGroupSeed(var TempPostingGroup: Record "Expense Posting Group" temporary)` (integration)
- `OnBeforeAddPostingGroupSeed(Code: Code[20]; Description: Text[100]; RefundableDebitAccount: Code[20]; var IsHandled: Boolean)` (integration)
- `OnBeforeUpdateEmployeePostingGroup(Code: Code[20]; ExpenseReportPayableAccount: Code[20]; ExpensePayableBankPaidAccount: Code[20]; ExpensePayableCardPaidAccount: Code[20]; ExpenseReportPrepaymentAccount: Code[20]; var IsHandled: Boolean)` (integration)
- `OnBeforeInsertRuleSeed(var TempRuleHeader: Record "Expense Rule Header" temporary)` (integration)
- `OnBeforeAddCategorySeed(Code: Code[20]; Description: Text[250]; PostingDescription: Text[100]; ExpenseGroupCode: Code[20]; PostingGroupCode: Code[20]; PaymentMethod: Code[10]; IsRefundable: Boolean; IsPrepayment: Boolean; AttachmentEnforcement: Enum "Expense Attachment Enforcement"; DetailRequired: Enum "Expense Detail Needed"; var IsHandled: Boolean)` (integration)
- `OnBeforeAddSubcategorySeed(SubcategoryCode: Code[20]; CategoryCode: Code[20]; Description: Text[250]; PostingDescription: Text[100]; Refundable: Boolean; DescriptionMandatory: Boolean; var IsHandled: Boolean)` (integration)
- `OnBeforeAddRuleSeed(var TempRuleHeader: Record "Expense Rule Header"; var CategoryCode: Code[20]; var ExpenseLocationCode: Code[20]; var CurrencyCode: Code[10]; var JustificationRequired: Enum "Expense Justification"; var IsHandled: Boolean)` (integration)
- `OnBeforeAddRuleConditionSeed(var TempRuleCondition: Record "Expense Rule Condition"; var CategoryCode: Code[20]; var ExpenseLocationCode: Code[20]; var ConditionType: Enum "Expense Rule Condition Type"; var Value: Decimal; var IsHandled: Boolean)` (integration)

## Procedures

- `InsertAccountingDefaults()` (internal)
- `InsertManagementDefaults()` (internal)
- `InsertDefaultPostingGroups()` (internal)
- `BuildPostingGroupSeeds(var TempPostingGroup: Record "Expense Posting Group" temporary)` (internal): Returns the catalogue of default expense posting groups without writing anything to the database. Use this for previewing what InsertDefaultPostingGroups would create.
- `LoadPostingGroupsPreview(var TempPostingGroup: Record "Expense Posting Group" temporary)` (internal): Builds the preview record set for expense posting groups: existing rows plus seeds that do not yet exist. No database writes are performed.
- `AddPostingGroupSeed(var TempPostingGroup: Record "Expense Posting Group" temporary; Code: Code[20]; Description: Text[100]; RefundableDebitAccount: Code[20])` (internal)
- `InsertDefaultExpenseCategories()` (internal)
- `BuildCategorySeeds(var TempCategory: Record "Expense Category" temporary)` (internal): Returns the catalogue of default expense categories without writing anything to the database.
- `BuildSubcategorySeeds(var TempSubcategory: Record "Expense Subcategory" temporary)` (internal): Returns the catalogue of default expense subcategories without writing anything to the database.
- `GetTRAVELTxt(): Code[20]` (internal)
- `GetCASHTxt(): Code[10]` (internal)
- `GetPERDIEMTxt(): Code[20]` (internal)
- `GetCANADAALLTxt(): Code[20]` (internal)
- `GetDENMARKALLTxt(): Code[20]` (internal)
- `GetDOMESTICTxt(): Code[20]` (internal)
- `GetFRANCEALLTxt(): Code[20]` (internal)
- `GetGERMANYALLTxt(): Code[20]` (internal)
- `GetUKOTHERTxt(): Code[20]` (internal)
- `GetEXPENSETRAVELTxt(): Code[20]` (internal)
- `GetUSAOTHERTxt(): Code[20]` (internal)
- `GetEXPENSEPERDIEMTxt(): Code[20]` (internal)
- `GetEXPENSEOTHERTxt(): Code[20]` (internal)
- `GetEXPENSEMILEAGETxt(): Code[20]` (internal)
- `GetEXPENSEMEALSTxt(): Code[20]` (internal)
- `GetEXPENSEENTERTAINTxt(): Code[20]` (internal)
- `GetHOTELSTxt(): Code[20]` (internal)
- `GetMEALSTxt(): Code[20]` (internal)
- `GetMileageTxt(): Code[20]` (internal)
- `GetMoraleTxt(): Code[20]` (internal)
- `GetAIRLINETxt(): Code[20]` (internal)
- `GetGROUNDTRANSTxt(): Code[20]` (internal)
- `GetRENTALCARSTxt(): Code[20]` (internal)
- `GetCARTxt(): Code[20]` (internal)
- `GetEVENTSTxt(): Code[20]` (internal)
- `GetENTERTAINTxt(): Code[20]` (internal)
- `GetFOODTxt(): Code[20]` (internal)
- `GetALCOHOLTxt(): Code[20]` (internal)
- `GetROOMTxt(): Code[20]` (internal)
- `GetBREAKFASTTxt(): Code[20]` (internal)
- `GetDEPOSITTxt(): Code[20]` (internal)
- `GetTAXTxt(): Code[20]` (internal)
- `GetFEETxt(): Code[20]` (internal)
- `GetPHONETxt(): Code[20]` (internal)
- `GetINTERNETTxt(): Code[20]` (internal)
- `GetINCIDENTSTxt(): Code[20]` (internal)
- `GetLAUNDRYTxt(): Code[20]` (internal)
- `GetROOMSERVICETxt(): Code[20]` (internal)
- `GetPARKINGTxt(): Code[20]` (internal)
- `GetOTHERTxt(): Code[20]` (internal)
- `GetTIPSTxt(): Code[20]` (internal)
- `GetTRANSPORTTxt(): Code[20]` (internal)
- `LoadCategoriesPreview(var TempCategory: Record "Expense Category" temporary; var TempSubcategory: Record "Expense Subcategory" temporary)` (internal): Builds the preview record set for expense categories and subcategories: existing rows plus seeds that do not yet exist. Seed subcategories are only proposed for categories that the defaults run will actually create; pre-existing categories are left alone, and so are their children. No database write...
- `AddCategorySeed(var TempCategory: Record "Expense Category" temporary; Code: Code[20]; Description: Text[250]; PostingDescription: Text[100]; ExpenseGroupCode: Code[20]; PostingGroupCode: Code[20]; PaymentMethod: Code[10]; IsRefundable: Boolean; IsPrepayment: Boolean; AttachmentEnforcement: Enum "Expense Attachment Enforcement"; DetailRequired: Enum "Expense Detail Needed")` (internal)
- `AddSubcategorySeed(var TempSubcategory: Record "Expense Subcategory" temporary; SubcategoryCode: Code[20]; CategoryCode: Code[20]; Description: Text[250]; PostingDescription: Text[100]; Refundable: Boolean; DescriptionMandatory: Boolean)` (internal)
- `InsertDefaultExpenseLocations()` (internal)
- `SeedLocationShouldBeSkipped(SeedLocation: Record "Expense Location"): Boolean` (internal)
- `BuildSkippedSeedLocations(var TempSkippedLocation: Record "Expense Location" temporary)` (internal)
- `BuildLocationSeeds(var TempExpenseLocation: Record "Expense Location" temporary)` (internal): Returns the catalogue of default expense locations without writing anything to the database.
- `LoadLocationsPreview(var TempExpenseLocation: Record "Expense Location" temporary)` (internal): Builds the preview record set for expense locations: existing rows plus seeds that do not yet exist. No database writes are performed.
- `InsertDefaultManagementRules()` (internal)
- `BuildRuleSeeds(var TempRuleHeader: Record "Expense Rule Header" temporary)` (internal): Returns the catalogue of default expense rule headers without writing anything to the database.
- `BuildRuleConditionSeeds(var TempRuleCondition: Record "Expense Rule Condition" temporary)` (internal): Returns the catalogue of default expense rule conditions without writing anything to the database.
- `LoadRulesPreview(var TempRuleHeader: Record "Expense Rule Header" temporary; var TempRuleCondition: Record "Expense Rule Condition" temporary)` (internal): Builds the preview record set for expense management rules: existing rows plus seeds that do not yet exist. Seed conditions are only proposed for rule headers that the defaults run will actually create; pre-existing rule headers are left alone, and so are their conditions. No database writes are per...
- `AddRuleSeed(var TempRuleHeader: Record "Expense Rule Header" temporary; CategoryCode: Code[20]; ExpenseLocationCode: Code[20]; CurrencyCode: Code[10]; JustificationRequired: Enum "Expense Justification")` (internal)
- `AddRuleConditionSeed(var TempRuleCondition: Record "Expense Rule Condition" temporary; CategoryCode: Code[20]; ExpenseLocationCode: Code[20]; ConditionType: Enum "Expense Rule Condition Type"; Value: Decimal)` (internal)
- `InsertExpenseCategory(Code: Code[20]; Description: Text[250]; PostingDescription: Text[100]; ExpenseGroupCode: Code[20]; PostingGroupCode: Code[20]; PaymentMethod: Code[10]; IsRefundable: Boolean; IsPrepayment: Boolean; AttachmentEnforcement: Enum "Expense Attachment Enforcement"; DetailRequired: Enum "Expense Detail Needed")` (internal)
- `InsertExpenseSubcategory(SubcategoryCode: Code[20]; CategoryCode: Code[20]; Description: Text[250]; PostingDescription: Text[100]; Refundable: Boolean; DescriptionMandatory: Boolean)` (internal)
- `UpdateEmployeePostingGroup(Code: Code[20]; ExpenseReportPayableAccount: Code[20]; ExpensePayableBankPaidAccount: Code[20]; ExpensePayableCardPaidAccount: Code[20]; ExpenseReportPrepaymentAccount: Code[20])` (internal)

Plus 7 local procedures.

## Triggers

OnRun

## Calls

From the extracted call graph of BC29 (graphify-al on the snapshot checkout): calls whose target is known from a declared type or an `Object::"Name"` argument. Interface dispatch and calls through events are not counted, so the list is not complete.

- [Codeunit 6971 "Create Expense GL Account"](../codeunit/6971.md) (17 calls: `AddPostingGroupSeed → ExpenseCreditRoundingAccountNo`, `AddPostingGroupSeed → ExpenseDebitRoundingAccountNo`, `AddPostingGroupSeed → ExpenseMealNonRefundableDebitAccountNo`, …)
- [Codeunit 6975 "Create Expense VAT Rates"](../codeunit/6975.md) (1 call: `OnRun → (object)`)
- [Codeunit 7124 "Create Expense Locations"](../codeunit/7124.md) (1 call: `BuildLocationSeeds → (object)`)
- [Codeunit 7126 "Create Expense Rule Conditions"](../codeunit/7126.md) (1 call: `BuildRuleConditionSeeds → (object)`)
- [Codeunit 7128 "Create Expense Rule Headers"](../codeunit/7128.md) (1 call: `BuildRuleSeeds → (object)`)

## Called by

- [Codeunit 6975 "Create Expense VAT Rates"](../codeunit/6975.md) (772 calls: `CreateVATRatesAT → GetAIRLINETxt`, `CreateVATRatesAT → GetBREAKFASTTxt`, `CreateVATRatesAT → GetCARTxt`, …)
- [Codeunit 7128 "Create Expense Rule Headers"](../codeunit/7128.md) (6 calls: `InsertExpenseRuleHeader → OnBeforeAddRuleSeed`, `InsertExpenseRuleHeaders → GetENTERTAINTxt`, `InsertExpenseRuleHeaders → GetHOTELSTxt`, …)
- [Codeunit 7126 "Create Expense Rule Conditions"](../codeunit/7126.md) (4 calls: `CreateExpenseRuleConditions → GetENTERTAINTxt`, `CreateExpenseRuleConditions → GetMileageTxt`, `CreateExpenseRuleConditions → GetPERDIEMTxt`, …)
- [Table 6930 "Expense Agent Setup"](../table/6930.md) (4 calls: `CreateExpenseCategoriesDefaults → InsertDefaultExpenseCategories`, `CreateExpenseLocationsDefaults → InsertDefaultExpenseLocations`, `CreateManagementRulesDefaults → InsertDefaultManagementRules`, …)
- [Page 6959 "Exp. Rules Preview"](../page/6959.md) (1 call: `ReloadPreview → LoadRulesPreview`)
- [Page 6966 "Exp. Categories Preview"](../page/6966.md) (1 call: `ReloadPreview → LoadCategoriesPreview`)
- [Page 6970 "Exp. Locations Preview"](../page/6970.md) (1 call: `ReloadPreview → LoadLocationsPreview`)
- [Page 6985 "Exp. Posting Groups Preview"](../page/6985.md) (1 call: `ReloadPreview → LoadPostingGroupsPreview`)

## Recent changes

- 2026-09-15 [#11425 Bug 650137: [29.x] Expense Locations and Per-diem rules in configuration - Backport](../../changes/bcapps/11425.md) (releases/29.x, BC29, feature)
- 2026-09-10 [#10990 Add-Expense-VAT-settings-to-Contoso-demo-tool](../../changes/bcapps/10990.md) (main, BC30, feature)
- 2026-09-10 [#10155 Slice 641293: [Expense Agent] Expense Locations and Per-diem rules in configurationAdded more locations](../../changes/bcapps/10155.md) (main, BC30, feature)
- 2026-08-28 [#10637 [Master] - Bug 639548 [Expense Agent] Consolidate country demo data into single W1 app](../../changes/bcapps/10637.md) (main, BC30, refactor)
- 2026-08-04 [#9859 [Master] - Move Expense Agent (Preview) app into BCApps](../../changes/bcapps/9859.md) (main, BC30, feature, added)

## Across versions

- Present in: BC29-30
- Changed (declaration) in: BC30

Source: AL metadata extracted from the code (names, ids, signatures, properties); no code bodies (D10).

## Ask your agent

Procedure bodies are not stored here (D10). The call sections above are our own, per object, from the BC29 call graph. For a procedure body or the calls of one procedure, ask bc-code-atlas (external, by Stefan Maron, MIT; default corpus w1-28), which the bc-observatory plugin connects: `bcatlas_resolve_node(object_type: "codeunit", object_name: "Create Expense Categories")`, then `bcatlas_get_procedure_body` or `bcatlas_get_neighbors` on the returned id.
