feat(core): Added new afterburner logic for specific bank reference
This commit is contained in:
commit
71ca4a0c6d
20
.gitignore
vendored
Normal file
20
.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
.nogit/
|
||||
|
||||
# artifacts
|
||||
coverage/
|
||||
public/
|
||||
pages/
|
||||
|
||||
# installs
|
||||
node_modules/
|
||||
|
||||
# caches
|
||||
.yarn/
|
||||
.cache/
|
||||
.rpt2_cache
|
||||
|
||||
# builds
|
||||
dist/
|
||||
dist_*/
|
||||
|
||||
# custom
|
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "npm test",
|
||||
"name": "Run npm test",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
26
.vscode/settings.json
vendored
Normal file
26
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": ["/npmextra.json"],
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"npmci": {
|
||||
"type": "object",
|
||||
"description": "settings for npmci"
|
||||
},
|
||||
"gitzone": {
|
||||
"type": "object",
|
||||
"description": "settings for gitzone",
|
||||
"properties": {
|
||||
"projectType": {
|
||||
"type": "string",
|
||||
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
29
changelog.md
Normal file
29
changelog.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## 2024-07-06 - 1.1.0 - feat(core)
|
||||
Added new afterburner logic for specific bank reference
|
||||
|
||||
- Ensured proper accountId formatting for statements with referenceNumber 'BUNQ BV'
|
||||
- Added support for parsing MT940 files from buffers and strings
|
||||
- Enhanced testing suite with new test cases
|
||||
- Included detailed usage examples in readme
|
||||
|
||||
## 2024-07-02 - 1.0.6 - fix(core)
|
||||
Ensured proper accountId formatting for statements with referenceNumber 'BUNQ BV'
|
||||
|
||||
- Added condition to modify accountId format if referenceNumber is 'BUNQ BV' in parseMt940Buffer method
|
||||
|
||||
## 2023-11-15 - 1.0.5 - Minor Fixes
|
||||
- Fixes in core components for stability
|
||||
|
||||
## 2023-11-15 - 1.0.4 - Minor Fixes
|
||||
- Fixes in core components for stability
|
||||
|
||||
## 2023-11-15 - 1.0.3 - Minor Fixes
|
||||
- Fixes in core components for stability
|
||||
|
||||
## 2023-11-15 - 1.0.2 - Minor Fixes
|
||||
- Fixes in core components for stability
|
||||
|
||||
## 2022-12-06 - 1.0.2 - Minor Fixes
|
||||
- Fixes in core components for stability
|
31
npmextra.json
Normal file
31
npmextra.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"gitzone": {
|
||||
"projectType": "npm",
|
||||
"module": {
|
||||
"githost": "gitlab.com",
|
||||
"gitscope": "fin.cx",
|
||||
"gitrepo": "mt940parser",
|
||||
"description": "A parser to process and extract statements from MT940 format files, commonly used by banks for electronic account statements.",
|
||||
"npmPackagename": "@fin.cx/mt940parser",
|
||||
"license": "MIT",
|
||||
"projectDomain": "finance.plus",
|
||||
"keywords": [
|
||||
"MT940",
|
||||
"file parser",
|
||||
"financial statements",
|
||||
"banking",
|
||||
"finance",
|
||||
"TypeScript",
|
||||
"electronic account statements",
|
||||
"data extraction",
|
||||
"custom processing",
|
||||
"file handling",
|
||||
"error handling"
|
||||
]
|
||||
}
|
||||
},
|
||||
"npmci": {
|
||||
"npmGlobalTools": [],
|
||||
"npmAccessLevel": "public"
|
||||
}
|
||||
}
|
56
package.json
Normal file
56
package.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "@fin.cx/mt940parser",
|
||||
"version": "1.0.5",
|
||||
"private": false,
|
||||
"description": "A parser to process and extract statements from MT940 format files, commonly used by banks for electronic account statements.",
|
||||
"main": "dist_ts/index.js",
|
||||
"typings": "dist_ts/index.d.ts",
|
||||
"type": "module",
|
||||
"author": "Lossless GmbH",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "(tstest test/ --web)",
|
||||
"build": "(tsbuild --web --allowimplicitany)",
|
||||
"buildDocs": "(tsdoc)"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^2.1.25",
|
||||
"@git.zone/tsbundle": "^2.0.5",
|
||||
"@git.zone/tsrun": "^1.2.39",
|
||||
"@git.zone/tstest": "^1.0.84",
|
||||
"@push.rocks/tapbundle": "^5.0.3",
|
||||
"@push.rocks/tapbundle-fs": "^1.0.4",
|
||||
"@types/node": "^20.9.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 1 chrome versions"
|
||||
],
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
"ts_web/**/*",
|
||||
"dist/**/*",
|
||||
"dist_*/**/*",
|
||||
"dist_ts/**/*",
|
||||
"dist_ts_web/**/*",
|
||||
"assets/**/*",
|
||||
"cli.js",
|
||||
"npmextra.json",
|
||||
"readme.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"mt940-js": "^1.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"MT940",
|
||||
"file parser",
|
||||
"financial statements",
|
||||
"banking",
|
||||
"finance",
|
||||
"TypeScript",
|
||||
"electronic account statements",
|
||||
"data extraction",
|
||||
"custom processing",
|
||||
"file handling",
|
||||
"error handling"
|
||||
]
|
||||
}
|
6191
pnpm-lock.yaml
generated
Normal file
6191
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
0
readme.hints.md
Normal file
0
readme.hints.md
Normal file
332
readme.md
Normal file
332
readme.md
Normal file
@ -0,0 +1,332 @@
|
||||
# @fin.cx/mt940parser
|
||||
|
||||
A parser to process and extract statements from MT940 format files.
|
||||
|
||||
## Install
|
||||
|
||||
To install the `@fin.cx/mt940parser` package, you can use npm or yarn. Here is the command to install via npm:
|
||||
|
||||
```sh
|
||||
npm install @fin.cx/mt940parser
|
||||
```
|
||||
|
||||
Alternatively, if you are using yarn:
|
||||
|
||||
```sh
|
||||
yarn add @fin.cx/mt940parser
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`@fin.cx/mt940parser` is a library for parsing MT940 files, which are commonly used by banks for electronic account statements. This module enables you to easily parse the MT940 files into JavaScript objects for further processing. Below, we'll walk through various scenarios and features to help you get the most out of this library. We will use modern ECMAScript Module (ESM) syntax and TypeScript for code examples.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
To start parsing MT940 files using `@fin.cx/mt940parser`, you need to first import the library and create an instance of `Mt940Parser`. Here's a basic example of how to parse an MT940 file string:
|
||||
|
||||
```typescript
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
const parser = new Mt940Parser();
|
||||
const mt940FileString = `
|
||||
// your MT940 file content here
|
||||
`;
|
||||
|
||||
async function parseMT940() {
|
||||
try {
|
||||
const statements = await parser.parseMt940FileString(mt940FileString);
|
||||
console.log(statements);
|
||||
} catch (error) {
|
||||
console.error('Error parsing MT940 file:', error);
|
||||
}
|
||||
}
|
||||
|
||||
parseMT940();
|
||||
```
|
||||
|
||||
### Reading from a File
|
||||
|
||||
Often, you'll want to read MT940 data from a file. Below is an example of how to do that using Node.js built-in filesystem (fs) module:
|
||||
|
||||
```typescript
|
||||
import { promises as fs } from 'fs';
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
async function parseMT940FromFile(filePath: string) {
|
||||
try {
|
||||
const fileContent = await fs.readFile(filePath, 'utf-8');
|
||||
const parser = new Mt940Parser();
|
||||
const statements = await parser.parseMt940FileString(fileContent);
|
||||
console.log(statements);
|
||||
} catch (error) {
|
||||
console.error('Error parsing MT940 file:', error);
|
||||
}
|
||||
}
|
||||
|
||||
parseMT940FromFile('./path/to/your/mt940file.txt');
|
||||
```
|
||||
|
||||
### Parsing a Buffer
|
||||
|
||||
If you have the MT940 data in a buffer, you can use the `parseMt940Buffer` method to process it. Here’s an example to demonstrate this:
|
||||
|
||||
```typescript
|
||||
import { promises as fs } from 'fs';
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
async function parseMT940FromBuffer(filePath: string) {
|
||||
try {
|
||||
const fileBuffer = await fs.readFile(filePath);
|
||||
const parser = new Mt940Parser();
|
||||
const statements = await parser.parseMt940Buffer(fileBuffer.buffer);
|
||||
console.log(statements);
|
||||
} catch (error) {
|
||||
console.error('Error parsing MT940 buffer:', error);
|
||||
}
|
||||
}
|
||||
|
||||
parseMT940FromBuffer('./path/to/your/mt940file.txt');
|
||||
```
|
||||
|
||||
### Advanced Usage
|
||||
|
||||
#### Parsing with Custom Processing
|
||||
|
||||
The `parseMt940Buffer` method allows for further custom processing of parsed MT940 data. By leveraging this function, you can modify certain fields or process the data before utilizing it. Here’s an example:
|
||||
|
||||
```typescript
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
const customParser = new Mt940Parser();
|
||||
|
||||
customParser.parseMt940Buffer = async function (fileBuffer) {
|
||||
const parsedStatements = await customParser.parseMt940Buffer(fileBuffer);
|
||||
|
||||
// Custom processing: Example, removing all transactions with amount 0
|
||||
for (const statement of parsedStatements) {
|
||||
statement.transactions = statement.transactions.filter(transaction => transaction.amount !== 0);
|
||||
}
|
||||
|
||||
return parsedStatements;
|
||||
};
|
||||
|
||||
// Usage remains the same
|
||||
async function parseWithCustomProcessing(mt940FileString: string) {
|
||||
const textEncode = new TextEncoder();
|
||||
const fileBuffer = textEncode.encode(mt940FileString).buffer;
|
||||
const statements = await customParser.parseMt940Buffer(fileBuffer);
|
||||
console.log(statements);
|
||||
}
|
||||
|
||||
const mt940FileString = `
|
||||
// your MT940 file content here
|
||||
`;
|
||||
|
||||
parseWithCustomProcessing(mt940FileString);
|
||||
```
|
||||
|
||||
#### Combining Multiple MT940 Files
|
||||
|
||||
It is common to have multiple MT940 files covering different periods. You can combine the data from multiple files and parse them together. Here is an example:
|
||||
|
||||
```typescript
|
||||
import { promises as fs } from 'fs';
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
async function mergeMT940Files(filePaths: string[]) {
|
||||
const parser = new Mt940Parser();
|
||||
const allStatements = [];
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
try {
|
||||
const fileContent = await fs.readFile(filePath, 'utf-8');
|
||||
const statements = await parser.parseMt940FileString(fileContent);
|
||||
allStatements.push(...statements);
|
||||
} catch (error) {
|
||||
console.error(`Error parsing file ${filePath}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
return allStatements;
|
||||
}
|
||||
|
||||
// Example file paths array
|
||||
const filePaths = ['./path/to/first.mt940', './path/to/second.mt940'];
|
||||
|
||||
async function main() {
|
||||
const combinedStatements = await mergeMT940Files(filePaths);
|
||||
console.log(combinedStatements);
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
#### Filtering and Analyzing Transactions
|
||||
|
||||
Once you have parsed the MT940 file into JavaScript objects, you might want to filter or analyze the transactions contained in the statements. Here's how you can filter transactions that meet specific criteria:
|
||||
|
||||
```typescript
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
const parser = new Mt940Parser();
|
||||
|
||||
async function findLargeTransactions(mt940FileString: string, minAmount: number) {
|
||||
const statements = await parser.parseMt940FileString(mt940FileString);
|
||||
const largeTransactions = [];
|
||||
|
||||
for (const statement of statements) {
|
||||
for (const transaction of statement.transactions) {
|
||||
if (transaction.amount >= minAmount) {
|
||||
largeTransactions.push(transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return largeTransactions;
|
||||
}
|
||||
|
||||
const mt940FileString = `
|
||||
// your MT940 file content here
|
||||
`;
|
||||
|
||||
async function main() {
|
||||
const largeTransactions = await findLargeTransactions(mt940FileString, 1000); // Replace 1000 with your desired minimum amount
|
||||
console.log('Large Transactions:', largeTransactions);
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
#### Extending the Parser
|
||||
|
||||
If you need additional customization beyond what is provided, you can extend the `Mt940Parser` class and override the methods you need to change.
|
||||
|
||||
```typescript
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
class CustomMt940Parser extends Mt940Parser {
|
||||
async parseMt940FileString(fileString: string) {
|
||||
const statements = await super.parseMt940FileString(fileString);
|
||||
|
||||
// Custom logic: Example, add a new property customField to each statement
|
||||
for (const statement of statements) {
|
||||
statement.customField = 'your custom value';
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
}
|
||||
|
||||
// Usage remains the same
|
||||
async function parseWithCustomParser(mt940FileString: string) {
|
||||
const customParser = new CustomMt940Parser();
|
||||
const statements = await customParser.parseMt940FileString(mt940FileString);
|
||||
console.log(statements);
|
||||
}
|
||||
|
||||
const mt940FileString = `
|
||||
// your MT940 file content here
|
||||
`;
|
||||
|
||||
parseWithCustomParser(mt940FileString);
|
||||
```
|
||||
|
||||
#### Error Handling and Validation
|
||||
|
||||
Proper error handling and validation are crucial when processing financial data. Here’s how to catch and handle errors effectively:
|
||||
|
||||
```typescript
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
const parser = new Mt940Parser();
|
||||
|
||||
async function parseMT940WithErrorHandling(mt940FileString: string) {
|
||||
try {
|
||||
const statements = await parser.parseMt940FileString(mt940FileString);
|
||||
|
||||
// Example validation: Ensure that all statements have transactions
|
||||
for (const statement of statements) {
|
||||
if (!statement.transactions || statement.transactions.length === 0) {
|
||||
throw new Error(`Statement with reference ${statement.referenceNumber} has no transactions.`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Parsed Statements:', statements);
|
||||
} catch (error) {
|
||||
console.error('Error parsing MT940 file:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
const mt940FileString = `
|
||||
// your MT940 file content here
|
||||
`;
|
||||
|
||||
parseMT940WithErrorHandling(mt940FileString);
|
||||
```
|
||||
|
||||
### Comprehensive Feature Demonstration
|
||||
|
||||
To give you a comprehensive view, here’s a complete application example demonstrating multiple features — reading from a file, combining multiple files, custom processing, error handling, filtering, and extending the parser.
|
||||
|
||||
```typescript
|
||||
import { promises as fs } from 'fs';
|
||||
import { Mt940Parser } from '@fin.cx/mt940parser';
|
||||
|
||||
class ComprehensiveMt940Parser extends Mt940Parser {
|
||||
async parseMt940FileString(fileString: string) {
|
||||
const statements = await super.parseMt940FileString(fileString);
|
||||
|
||||
// Custom logic: Example, add a new property customField to each statement
|
||||
for (const statement of statements) {
|
||||
statement.customField = 'custom value';
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
}
|
||||
|
||||
async function parseAndProcessFiles(filePaths: string[], minAmount: number) {
|
||||
const parser = new ComprehensiveMt940Parser();
|
||||
const allStatements = [];
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
try {
|
||||
const fileContent = await fs.readFile(filePath, 'utf-8');
|
||||
const statements = await parser.parseMt940FileString(fileContent);
|
||||
allStatements.push(...statements);
|
||||
} catch (error) {
|
||||
console.error(`Error parsing file ${filePath}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
const largeTransactions = [];
|
||||
|
||||
for (const statement of allStatements) {
|
||||
for (const transaction of statement.transactions) {
|
||||
if (transaction.amount >= minAmount) {
|
||||
largeTransactions.push(transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { allStatements, largeTransactions };
|
||||
}
|
||||
|
||||
const filePaths = ['./path/to/first.mt940', './path/to/second.mt940'];
|
||||
const minAmount = 1000;
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const { allStatements, largeTransactions } = await parseAndProcessFiles(filePaths, minAmount);
|
||||
console.log('All Statements:', allStatements);
|
||||
console.log('Large Transactions:', largeTransactions);
|
||||
} catch (error) {
|
||||
console.error('Error in processing:', error);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
This example demonstrates a holistic approach to working with MT940 files using the `@fin.cx/mt940parser` library. It covers file reading, custom processing, error handling, filtering transactions, and extending the parser for additional functionality. This should give you a solid foundation to build upon and tailor the parser to your specific requirements.
|
||||
undefined
|
20
test/test.ts
Normal file
20
test/test.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { expect, expectAsync, tap } from '@push.rocks/tapbundle';
|
||||
import * as tapbundleFs from '@push.rocks/tapbundle-fs';
|
||||
import * as mt940parser from '../ts/index.js';
|
||||
|
||||
let testMt940Parser: mt940parser.Mt940Parser;
|
||||
|
||||
tap.test('should create a valid instance of Mt940Parser', async () => {
|
||||
testMt940Parser = new mt940parser.Mt940Parser();
|
||||
});
|
||||
|
||||
tap.test('should parse a set of files', async () => {
|
||||
const smartfiles = await tapbundleFs.smartfile.fs.fileTreeToObject('.nogit/', '*.mt940');
|
||||
console.log(smartfiles);
|
||||
for (const smartfile of smartfiles) {
|
||||
const statements = await testMt940Parser.parseMt940FileString(smartfile.contents.toString());
|
||||
console.log(JSON.stringify(statements, null, 2));
|
||||
}
|
||||
})
|
||||
|
||||
tap.start();
|
8
ts/00_commitinfo_data.ts
Normal file
8
ts/00_commitinfo_data.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* autocreated commitinfo by @push.rocks/commitinfo
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@fin.cx/mt940parser',
|
||||
version: '1.1.0',
|
||||
description: 'A parser to process and extract statements from MT940 format files, commonly used by banks for electronic account statements.'
|
||||
}
|
26
ts/index.ts
Normal file
26
ts/index.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as plugins from './mt940parser.plugins.js';
|
||||
|
||||
export class Mt940Parser {
|
||||
public async parseMt940FileString(fileStringArg: string) {
|
||||
// console.log(fileStringArg);
|
||||
const textEncode = new TextEncoder();
|
||||
const statements = await this.parseMt940Buffer(textEncode.encode(fileStringArg).buffer);
|
||||
|
||||
return statements;
|
||||
}
|
||||
|
||||
public async parseMt940Buffer(fileBufferArg: ArrayBufferLike) {
|
||||
// console.log(fileStringArg);
|
||||
const textEncode = new TextEncoder();
|
||||
const statements = await plugins.mt940Js.read(fileBufferArg);
|
||||
|
||||
// bank afterburner
|
||||
for (const statement of statements) {
|
||||
if (statement.referenceNumber === "BUNQ BV") {
|
||||
statement.accountId = statement.accountId.split(' ')[0];
|
||||
}
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
}
|
5
ts/mt940parser.plugins.ts
Normal file
5
ts/mt940parser.plugins.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import * as mt940Js from 'mt940-js';
|
||||
|
||||
export {
|
||||
mt940Js
|
||||
}
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true
|
||||
},
|
||||
"exclude": [
|
||||
"dist_*/**/*.d.ts"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user