codegen.py (4957B)
1 #!/usr/bin/python3 2 # Update EBICS constants file using latest external code sets files 3 4 from io import BytesIO 5 from zipfile import ZipFile 6 7 import polars as pl 8 import requests 9 10 11 def iso20022codegenExternalCodeSet(): 12 # Get XLSX zip file from server 13 r = requests.get( 14 "https://www.iso20022.org/sites/default/files/media/file/ExternalCodeSets_XLSX.zip" 15 ) 16 assert r.status_code == 200 17 18 # Unzip the XLSX file 19 zip = ZipFile(BytesIO(r.content)) 20 files = zip.namelist() 21 assert len(files) == 1 22 bytes = zip.read(files[0]) 23 24 # Parse excel 25 df = pl.read_excel(bytes, sheet_name="AllCodeSets") 26 27 def extractCodeSet(setName: str, className: str) -> str: 28 out = f"enum class {className}(val isoCode: String, val description: String) {{" 29 30 for row in ( 31 df.filter(pl.col("Code Set") == setName).sort("Code Value").rows(named=True) 32 ): 33 (value, isoCode, description) = ( 34 row["Code Value"], 35 row["Code Name"], 36 row["Code Definition"].split("\n", 1)[0].strip().replace("_x000D_", ""), 37 ) 38 out += f'\n\t{value}("{isoCode}", "{description}"),' 39 40 out += "\n}" 41 return out 42 43 # Write kotlin file 44 kt = f"""/* 45 * This file is part of LibEuFin. 46 * Copyright (C) 2024 Taler Systems S.A. 47 48 * LibEuFin is free software; you can redistribute it and/or modify 49 * it under the terms of the GNU Affero General Public License as 50 * published by the Free Software Foundation; either version 3, or 51 * (at your option) any later version. 52 53 * LibEuFin is distributed in the hope that it will be useful, but 54 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 55 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General 56 * Public License for more details. 57 58 * You should have received a copy of the GNU Affero General Public 59 * License along with LibEuFin; see the file COPYING. If not, see 60 * <http://www.gnu.org/licenses/> 61 */ 62 63 // THIS FILE IS GENERATED, DO NOT EDIT 64 65 package tech.libeufin.nexus.iso20022 66 67 {extractCodeSet("ExternalStatusReason1Code", "ExternalStatusReasonCode")} 68 69 {extractCodeSet("ExternalPaymentGroupStatus1Code", "ExternalPaymentGroupStatusCode")} 70 71 {extractCodeSet("ExternalPaymentTransactionStatus1Code", "ExternalPaymentTransactionStatusCode")} 72 73 {extractCodeSet("ExternalReturnReason1Code", "ExternalReturnReasonCode")} 74 75 """ 76 with open( 77 "src/main/kotlin/tech/libeufin/nexus/iso20022/ExternalCodeSets.kt", "w" 78 ) as file1: 79 file1.write(kt) 80 81 82 def iso20022codegenBankTransactionCode(): 83 # Get XLSX zip file from server 84 r = requests.get( 85 "https://www.iso20022.org/sites/default/files/media/file/BTC_Codification_21March2024.xlsx" 86 ) 87 assert r.status_code == 200 88 89 # Get the XLSX file 90 bytes = r.content 91 92 # Parse excel 93 df = pl.read_excel( 94 bytes, 95 sheet_name="BTC_Codification", 96 read_options={"header_row": 2}, 97 ).rename(lambda name: name.splitlines()[0]) 98 99 def extractCodeSet(setName: str, className: str) -> str: 100 out = f"enum class {className}(val description: String) {{" 101 codeName = f"{setName} Code" 102 for row in ( 103 df.group_by(codeName) 104 .agg(pl.col(setName).unique().sort()) 105 .sort(codeName) 106 .rows(named=True) 107 ): 108 if len(row[setName]) > 1: 109 print(row) 110 111 (code, description) = ( 112 row[codeName].strip().replace("\xa0", ""), 113 row[setName][0].strip(), 114 ) 115 out += f'\n\t{code}("{description}"),' 116 117 out += "\n}" 118 return out 119 120 # Write kotlin file 121 kt = f"""/* 122 * This file is part of LibEuFin. 123 * Copyright (C) 2024 Taler Systems S.A. 124 125 * LibEuFin is free software; you can redistribute it and/or modify 126 * it under the terms of the GNU Affero General Public License as 127 * published by the Free Software Foundation; either version 3, or 128 * (at your option) any later version. 129 130 * LibEuFin is distributed in the hope that it will be useful, but 131 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 132 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General 133 * Public License for more details. 134 135 * You should have received a copy of the GNU Affero General Public 136 * License along with LibEuFin; see the file COPYING. If not, see 137 * <http://www.gnu.org/licenses/> 138 */ 139 140 // THIS FILE IS GENERATED, DO NOT EDIT 141 142 package tech.libeufin.nexus.iso20022 143 144 {extractCodeSet("Domain", "ExternalBankTransactionDomainCode")} 145 146 {extractCodeSet("Family", "ExternalBankTransactionFamilyCode")} 147 148 {extractCodeSet("SubFamily", "ExternalBankTransactionSubFamilyCode")} 149 150 """ 151 with open( 152 "src/main/kotlin/tech/libeufin/nexus/iso20022/BankTransactionCode.kt", "w" 153 ) as file1: 154 file1.write(kt) 155 156 157 iso20022codegenExternalCodeSet() 158 iso20022codegenBankTransactionCode()