Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions src/Apps/W1/SimplifiedBankStatementImport/App/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Simplified Bank Statement Import

Wizard-based app that guides users through defining a CSV bank statement
import format. No coding required -- upload a sample CSV file and the app
detects separator, date format, amount format, and column positions, then
generates a full Data Exchange Definition.

## Quick reference

**Path:** `App/BCApps/src/Apps/W1/SimplifiedBankStatementImport/App/`
**ID range:** 8850-8862
**Object count:** 23 (1 codeunit, 1 temporary table, 2 pages, 2 page extensions, 17 permission objects)
**Dependencies:** None
**Entry point:** Page 8850 "Bank Statement Import Wizard" (NavigatePage)

## How it works

### Wizard flow (8 steps)

1. **Welcome** -- intro screen
2. **Upload** -- user uploads sample CSV file
3. **Header Lines** -- detect/confirm how many header lines to skip
4. **Separator & Column Count** -- detect comma vs semicolon, count columns
5. **Column Mapping** -- map which columns contain Date, Amount, Description
6. **Format Details** -- detect date and amount formats via regex
7. **Try It Out** -- preview parsed data with validation coloring (red = errors)
8. **Finish** -- create Data Exchange Definition and Bank Export/Import Setup

### Format detection

**Date patterns:** 11+ regex patterns including dd-MM-yyyy, MM/dd/yyyy,
yyyyMMdd, dd.MM.yyyy, yyyy-MM-dd, and variations. First valid match wins.

**Amount patterns:** Two styles detected:
- Dot decimal (1,234.56) -- uses en-US locale
- Comma decimal (1.234,56 or 1'234,56) -- uses es-ES locale

Single-quote thousands separator (') handled for Swiss/EU formats.

### Data created on finish

The wizard creates 8 records:

- 1 Data Exch. Def (parent container)
- 1 Data Exch. Line Def (line structure)
- 1 Data Exch. Mapping (maps to Bank Acc. Reconciliation Line table)
- 3 Data Exch. Field Mapping (Date -> Transaction Date, Amount -> Statement Amount, Description -> Transaction Text)
- 3 Data Exch. Column Def (column positions and transformations)
- 1 Bank Export/Import Setup (links def to "BANKSTMT-IMPORT" code)
- Optionally updates Bank Account record if user selects one

## Structure

**Page 8850 Bank Statement Import Wizard** -- NavigatePage with 8 steps.
Contains all wizard logic (25 local procedures). Heavy lifting happens here:
- `ParseCsvFile()` -- splits CSV into temp table rows/columns
- `DetectSeparator()` -- tries comma and semicolon, picks best match
- `DetectHeaderLines()` -- counts lines before data starts
- `DetectDateFormat()` -- tries 11+ regex patterns
- `DetectAmountFormat()` -- tries dot/comma decimal patterns
- `CreateDataExchangeDefinition()` -- generates 8 records on finish

**Page 8851 Bank Statement Import Preview** -- List page showing temp
table with parsed columns. Red text indicates validation failures. Used
in step 7 (Try It Out).

**Table 8850 Temp Bank Import File Line** -- temporary table holding
parsed CSV data during wizard session. Not persisted.

**Codeunit 8850 Bank Statement Import Wizard** -- thin wrapper (4 procedures):
- `Run()` -- opens wizard page
- `GetWizardPageID()` -- returns page ID for Guided Experience integration
- `OnBeforeUploadBankFile()` integration event for extensibility/testing
- `IsEnabled()` -- feature flag check

**Page extensions:**
- 8850 extends Bank Account Card -- shows notification when no import format assigned, with action to launch wizard
- 8851 extends Payment Reconciliation Journal -- adds action to launch wizard

**Permission objects:** 17 permission sets for different roles (read/execute/edit combinations)

## Documentation

See `SimplifiedBankStatementImport.md` in app folder for user guide and screenshots.

## Things to know

**All logic lives in the wizard page** -- Codeunit 8850 is just a thin
entry point. If you need to debug format detection or data creation logic,
look in Page 8850's local procedures.

**Regex-based detection is greedy** -- first matching pattern wins. If
date/amount detection fails, add new patterns to the `DetectDateFormat()`
or `DetectAmountFormat()` procedures.

**Preview validates live** -- Step 7 parses the CSV with the detected
format and colors errors red. If preview shows red, user must go back and
fix column mapping or format settings.

**Locale codes matter** -- Amount format detection sets
`TransformationRule.DataExchangeType` to "POSITIVEPAY-EFT" (dot decimal,
en-US) or "SEPA" (comma decimal, es-ES). These control how the import
engine parses decimals.

**Single Data Exch. Def per wizard run** -- Each execution creates a new
definition. No editing/updating existing defs. To change a format, re-run
the wizard and create a new def.

**Guided Experience integration** -- Registered as Assisted Setup via
`GuidedExperience.InsertAssistedSetup()`. Appears in "Ready for Business"
group in the Assisted Setup page.

**Extensibility hook** -- `OnBeforeUploadBankFile()` integration event
fires before file upload dialog. Extensions can inject test files or
bypass upload for automated testing.

**No advanced features** -- Does not support multi-line statements,
conditional logic, or custom transformations. For complex imports, use
full Data Exchange Definition setup manually.
131 changes: 131 additions & 0 deletions src/Apps/W1/SimplifiedBankStatementImport/App/docs/business-logic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Business Logic

## Wizard Flow

The Simplified Bank Statement Import wizard (Page 8850) guides users through an 8-step process to configure bank statement import from CSV files.

```mermaid
flowchart TD
A[1. Welcome] --> B[2. File Upload]
B --> C[3. Header Lines]
C --> D[4. Separator/Count]
D --> E[5. Column Mapping]
E --> F[6. Format Details]
F --> G[7. Try It Out]
G --> H[8. Finish]

B -->|OnBeforeUploadBankFile| I[Custom File Source]
I -->|TempBlob| J[ReadBankFile]
J -->|Detect separators| C

E -->|Auto-detect| K[GetColumnsFromBankFile]
K -->|Header keywords| E
K -->|Data patterns| E

F -->|Auto-detect| L[GetFormatsFromBankFile]
L -->|11 date patterns| F
L -->|2 amount patterns| F

G -->|GeneratePreviewData| M[Preview Table]
M -->|TypeHelper.Evaluate| N[Validation]
N -->|Invalid fields| O[Red highlighting]

H -->|StoreRecords| P[Data Exch. Def]
H -->|StoreRecords| Q[Bank Export/Import Setup]
```

### Step 1: Welcome

Displays instructions and provides a sample CSV download link. The sample download is only available in demonstration companies.

### Step 2: File Upload

The file upload process follows this sequence:

1. **OnBeforeUploadBankFile** integration event fires, allowing custom file sources (e.g., API integration). If handled externally, the wizard skips the standard upload dialog.
2. **BLOBImportWithFilter** prompts the user to select a CSV file from disk.
3. **ReadBankFile()** analyzes the uploaded content:
- Detects line separator (CRLF, CR, or LF)
- Reads the first 50 lines
- Uses regex to detect whether the file uses comma or semicolon as the field separator
- Identifies the number of header lines by analyzing line structure

### Step 3: Header Lines

The user can adjust the header line skip count. A preview pane highlights which lines are treated as headers versus data rows.

### Step 4: Separator/Count

The user selects the field separator (Space, Comma, or Semicolon). The wizard validates consistency by checking separator usage across 20 sample lines, then populates the column count.

### Step 5: Column Mapping

The user specifies which column numbers contain Date, Amount, and Description data. **GetColumnsFromBankFile()** attempts to auto-detect these columns using:

1. **Header keyword matching**: Case-insensitive search for "Date", "Amount", and "Description" or "Detail" in the header row.
2. **Data pattern matching**: If keyword matching fails, the wizard applies regex patterns to detect:
- Date columns (using the 11 date patterns described below)
- Amount columns (numeric patterns with decimal separators)

### Step 6: Format Details

The user specifies the date format (free text) and decimal separator (Space, Dot, or Comma). **GetFormatsFromBankFile()** auto-detects these formats by testing:

- **11 date regex patterns** covering:
- dd/MM/yyyy
- MM/dd/yyyy
- yyyyMMdd
- Variations with dot, dash, and slash separators
- **2 amount patterns**:
- Dot as decimal separator, with optional comma or quote thousands separators
- Comma as decimal separator, with optional dot thousands separator
- Swiss single-quote thousands separator (stripped before parsing)

### Step 7: Try It Out

**GeneratePreviewData()** populates the first 10 rows into the Bank Statement Import Preview table. The preview page validates each field using **TypeHelper.Evaluate()** with the appropriate culture context. Invalid fields are highlighted in red, allowing the user to adjust mappings or format settings before finalizing the configuration.

### Step 8: Finish

**StoreRecords()** creates the complete import configuration:

1. **Data Exch. Def** record:
- Type: Bank Statement Import
- File Type: Fixed Text
- Reading/Writing XMLport: Data Exch. Import - CSV
2. **Data Exch. Line Def** record
3. **Data Exch. Mapping** record (target table: Bank Acc. Reconciliation Line)
4. **Three Data Exch. Field Mapping** records:
- Date -> Field 5
- Amount -> Field 7
- Description -> Field 23
5. **Three Data Exch. Column Def** records (one for each mapped column)
6. **Bank Export/Import Setup** record (direction: Import)
7. Optionally updates the **Bank Account** record to link the new import format

## Format Detection Details

### Date Patterns

The wizard tests 11 regex patterns to identify date columns and formats:

- dd/MM/yyyy
- MM/dd/yyyy
- yyyy/MM/dd
- dd-MM-yyyy
- MM-dd-yyyy
- yyyy-MM-dd
- dd.MM.yyyy
- MM.dd.yyyy
- yyyy.MM.dd
- yyyyMMdd
- ddMMyyyy

### Amount Patterns

Two primary patterns detect amount columns:

1. **Dot decimal**: Matches numbers with a dot as the decimal separator. Supports comma or single-quote thousands separators (e.g., 1,234.56 or 1'234.56).
2. **Comma decimal**: Matches numbers with a comma as the decimal separator. Supports dot thousands separators (e.g., 1.234,56).

Swiss-style single-quote thousands separators are stripped from the text before parsing to ensure compatibility with TypeHelper.Evaluate().
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Extensibility

The Simplified Bank Statement Import app is designed as a closed configuration wizard. It provides limited extensibility points for custom file sources and UI integration, but does not expose a public API for programmatic extension by ISVs.

## Integration Events

### OnBeforeUploadBankFile

**Codeunit 8850** publishes the **OnBeforeUploadBankFile** integration event, allowing external code to provide custom file sources instead of the standard file upload dialog.

**Parameters:**
- `FileName` (out, Text): The name of the file being imported
- `TempBlob` (out, Codeunit "Temp Blob"): The file content as a binary large object
- `IsHandled` (out, Boolean): Set to true to skip the standard upload dialog

**Use cases:**
- Loading bank statements from an API endpoint
- Injecting mock CSV files during automated testing (used by the app's test framework)
- Integrating with document management systems

**Example usage:**
```al
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Bank Statement File Wizard", 'OnBeforeUploadBankFile', '', false, false)]
local procedure HandleCustomFileSource(var FileName: Text; var TempBlob: Codeunit "Temp Blob"; var IsHandled: Boolean)
begin
if not ShouldHandleUpload() then
exit;

// Load file content into TempBlob
LoadFileFromAPI(TempBlob);
FileName := 'bank-statement.csv';
IsHandled := true;
end;
```

## Guided Experience Integration

The wizard registers itself with the Guided Experience framework by subscribing to the **OnRegisterAssistedSetup** event.

**Registration details:**
- **Group**: "Ready for Business"
- **Object Type**: Page
- **Object ID**: 8850 (Bank Statement File Wizard)
- **Multi-language support**: Calls `AddTranslationForSetupObjectTitle()` to register translated titles for each language

This registration makes the wizard discoverable through the standard Assisted Setup page and related UI entry points.

## UI Entry Points

### Bank Account Card Notification

The **Bank Account Card** page extension creates a notification when a bank account has no import format assigned. The notification:

- Stores the bank account code in notification data
- Displays an action that triggers **RunBankStatementFileWizard()**
- Guides users directly to the wizard from the bank account card

### Bank Export/Import Setup Action

The **Bank Export/Import Setup** list page extension adds a **"Bank Statement File Format Wizard"** action, providing direct access to the wizard from the setup list.

## Design Philosophy

This app follows a **closed configuration wizard** pattern:

- All codeunit and page procedures are marked as `local` or `internal`
- No public API is exposed for ISVs to call
- The wizard is designed for end-user interaction, not programmatic automation
- The only extension point for external code is the **OnBeforeUploadBankFile** event

This design ensures a consistent user experience while allowing targeted integration for custom file sources. If you need to extend the import process beyond file sourcing, consider building a separate Data Exchange Definition using the standard Business Central framework rather than extending this wizard.
Loading