Differentiate credits and debts
This commit is contained in:
		
							parent
							
								
									06c08ef93b
								
							
						
					
					
						commit
						9fb888c59d
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -7,3 +7,4 @@ coverage | ||||
| @types | ||||
| 
 | ||||
| public/*.js | ||||
| /public/bundle.js.map | ||||
|  | ||||
							
								
								
									
										27
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										27
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -7,6 +7,7 @@ | ||||
| 		"": { | ||||
| 			"name": "mbank-mt940", | ||||
| 			"version": "0.1.0", | ||||
| 			"hasInstallScript": true, | ||||
| 			"license": "ISC", | ||||
| 			"dependencies": { | ||||
| 				"@types/mocha": "^10.0.1", | ||||
| @ -20,8 +21,10 @@ | ||||
| 			}, | ||||
| 			"devDependencies": { | ||||
| 				"@istanbuljs/nyc-config-typescript": "^1.0.2", | ||||
| 				"@types/diff": "^5.2.1", | ||||
| 				"@typescript-eslint/eslint-plugin": "^5.58.0", | ||||
| 				"@typescript-eslint/parser": "^5.58.0", | ||||
| 				"diff": "^5.2.0", | ||||
| 				"eslint": "^8.38.0", | ||||
| 				"eslint-config-prettier": "^8.8.0", | ||||
| 				"eslint-plugin-prettier": "^4.2.1", | ||||
| @ -1144,6 +1147,13 @@ | ||||
| 			"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"node_modules/@types/diff": { | ||||
| 			"version": "5.2.1", | ||||
| 			"resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.1.tgz", | ||||
| 			"integrity": "sha512-uxpcuwWJGhe2AR1g8hD9F5OYGCqjqWnBUQFD8gMZsDbv8oPHzxJF6iMO6n8Tk0AdzlxoaaoQhOYlIg/PukVU8g==", | ||||
| 			"dev": true, | ||||
| 			"license": "MIT" | ||||
| 		}, | ||||
| 		"node_modules/@types/json-schema": { | ||||
| 			"version": "7.0.11", | ||||
| 			"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", | ||||
| @ -2190,10 +2200,11 @@ | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/diff": { | ||||
| 			"version": "5.0.0", | ||||
| 			"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", | ||||
| 			"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", | ||||
| 			"version": "5.2.0", | ||||
| 			"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", | ||||
| 			"integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", | ||||
| 			"dev": true, | ||||
| 			"license": "BSD-3-Clause", | ||||
| 			"engines": { | ||||
| 				"node": ">=0.3.1" | ||||
| 			} | ||||
| @ -3696,6 +3707,16 @@ | ||||
| 				"wrap-ansi": "^7.0.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/mocha/node_modules/diff": { | ||||
| 			"version": "5.0.0", | ||||
| 			"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", | ||||
| 			"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", | ||||
| 			"dev": true, | ||||
| 			"license": "BSD-3-Clause", | ||||
| 			"engines": { | ||||
| 				"node": ">=0.3.1" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/mocha/node_modules/js-yaml": { | ||||
| 			"version": "4.1.0", | ||||
| 			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", | ||||
|  | ||||
| @ -19,8 +19,10 @@ | ||||
| 	"license": "ISC", | ||||
| 	"devDependencies": { | ||||
| 		"@istanbuljs/nyc-config-typescript": "^1.0.2", | ||||
| 		"@types/diff": "^5.2.1", | ||||
| 		"@typescript-eslint/eslint-plugin": "^5.58.0", | ||||
| 		"@typescript-eslint/parser": "^5.58.0", | ||||
| 		"diff": "^5.2.0", | ||||
| 		"eslint": "^8.38.0", | ||||
| 		"eslint-config-prettier": "^8.8.0", | ||||
| 		"eslint-plugin-prettier": "^4.2.1", | ||||
| @ -40,7 +42,7 @@ | ||||
| 		"esbuild": "^0.19.9", | ||||
| 		"http-server": "^14.1.1", | ||||
| 		"iconv-lite": "^0.6.3", | ||||
| 		"yargs": "^17.7.2", | ||||
| 		"typescript": "^5.0.4" | ||||
| 		"typescript": "^5.0.4", | ||||
| 		"yargs": "^17.7.2" | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										54
									
								
								src/index.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/index.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| import { promises as fs } from "fs"; | ||||
| import path from "node:path"; | ||||
| import iconv from "iconv-lite"; | ||||
| import { convert } from "."; | ||||
| import assert from "node:assert"; | ||||
| import * as Diff from "diff"; | ||||
| 
 | ||||
| describe("mt940 converter", () => { | ||||
| 	it("converts properly", async () => { | ||||
| 		const content = await fs.readFile( | ||||
| 			path.resolve(__dirname, "../tests/real_csv.csv"), | ||||
| 			{ | ||||
| 				encoding: null, | ||||
| 			} | ||||
| 		); | ||||
| 		const result = convert(iconv.decode(content, "cp1250")); | ||||
| 		const expected_result = await fs.readFile( | ||||
| 			path.resolve(__dirname, "../tests/real_mt940.txt"), | ||||
| 			"utf-8" | ||||
| 		); | ||||
| 		try { | ||||
| 			assert.strictEqual(result.output, expected_result); | ||||
| 		} catch (e) { | ||||
| 			console.error("There was a difference. Fixes to apply:"); | ||||
| 			console.log( | ||||
| 				Diff.createPatch("mt940", result.output, expected_result) | ||||
| 			); | ||||
| 			throw new Error("Texts differ"); | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	it.only("converts properly", async () => { | ||||
| 		const content = await fs.readFile( | ||||
| 			path.resolve(__dirname, "../tests/real_csv_2.csv"), | ||||
| 			{ | ||||
| 				encoding: null, | ||||
| 			} | ||||
| 		); | ||||
| 		const result = convert(iconv.decode(content, "cp1250")); | ||||
| 		const expected_result = await fs.readFile( | ||||
| 			path.resolve(__dirname, "../tests/real_mt940_2.txt"), | ||||
| 			"utf-8" | ||||
| 		); | ||||
| 		try { | ||||
| 			assert.strictEqual(result.output, expected_result); | ||||
| 		} catch (e) { | ||||
| 			console.error("There was a difference. Fixes to apply:"); | ||||
| 			console.log( | ||||
| 				Diff.createPatch("mt940", result.output, expected_result) | ||||
| 			); | ||||
| 			throw new Error("Texts differ"); | ||||
| 		} | ||||
| 	}); | ||||
| }); | ||||
							
								
								
									
										49
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								src/index.ts
									
									
									
									
									
								
							| @ -42,21 +42,55 @@ class Transaction { | ||||
| 	} | ||||
| 
 | ||||
| 	formatPerson() { | ||||
| 		return addLineNumbers( | ||||
| 		const ret = addLineNumbers( | ||||
| 			fillWithEmpty( | ||||
| 				chunks(removeRepeatingSpace(this.person).trim(), 27), | ||||
| 				2 | ||||
| 			).slice(0, 2), | ||||
| 			32 | ||||
| 		).join("\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	toMT940() { | ||||
| 		const prefixes = { incoming: "150", outcoming: "169" }; | ||||
| 		const prefix = this.amount > 0 ? prefixes.incoming : prefixes.outcoming; | ||||
| 		return `:61:${mtDate(this.acc_date)}${mtDate(this.op_date).slice( | ||||
| 			2 | ||||
| 		)}C${mtAmount(this.amount)}S${prefix}${Transaction.counter.next().value} | ||||
| 		// just a bunch of heuristics
 | ||||
| 		const prefix_fns = [ | ||||
| 			() => | ||||
| 				this.description.includes("OPŁATA-PRZELEW WEWN.") | ||||
| 					? "169" | ||||
| 					: false, | ||||
| 			() => | ||||
| 				this.description.includes("PRZELEW WEWNĘTRZNY PRZY") | ||||
| 					? "160" | ||||
| 					: false, | ||||
| 			() => | ||||
| 				this.description.includes("OPŁATA-PRZELEW WEWN. DO") | ||||
| 					? "755" | ||||
| 					: false, | ||||
| 			() => | ||||
| 				this.description.includes("PRZELEW ZEWNĘTRZNY WYCH") | ||||
| 					? "152" | ||||
| 					: false, | ||||
| 			() => | ||||
| 				this.description.includes("OPŁATA PRZELEW ZEW.DOWO") | ||||
| 					? "771" | ||||
| 					: false, | ||||
| 			() => (this.amount > 0 ? "150" : false), | ||||
| 			() => "169", | ||||
| 		]; | ||||
| 		let prefix = ""; | ||||
| 		for (const fn of prefix_fns) { | ||||
| 			const result = fn(); | ||||
| 			if (result !== false) { | ||||
| 				prefix = result; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		const result = `:61:${mtDate(this.acc_date)}${mtDate( | ||||
| 			this.op_date | ||||
| 		).slice(2)}${this.amount > 0 ? "C" : "D"}${mtAmount( | ||||
| 			this.amount | ||||
| 		)}S${prefix}${Transaction.counter.next().value} | ||||
| :86:${prefix} | ||||
| :86:${prefix}~00B${prefix}${this.description.slice(0, 23)} | ||||
| ${this.formatTitle()} | ||||
| @ -68,6 +102,7 @@ ${this.formatPerson()} | ||||
| ~38PL${this.account_number} | ||||
| ~62 | ||||
| ~63`;
 | ||||
| 		return result; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -166,7 +201,7 @@ function mtDate(d: Date) { | ||||
| } | ||||
| 
 | ||||
| function mtAmount(n: number) { | ||||
| 	return Math.abs(n).toString().replace(".", ","); | ||||
| 	return Math.abs(n).toFixed(2).replace(".", ","); | ||||
| } | ||||
| 
 | ||||
| export function convert(csv_utf8: string): { output: string; range: Range } { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user