optimize and clean up

This commit is contained in:
lelo 2025-05-28 15:32:52 +00:00
parent 491eb038ca
commit 5333f111dd

View File

@ -302,27 +302,24 @@ def get_merged_df(table_name):
for i, row in result.iterrows():
if (pd.isna(row.get('norm_email')) or row.get('norm_email') == '') and pd.notna(row.get('E-Mail-Adresse')):
result.at[i, 'norm_email'] = f"{row.get('E-Mail-Adresse')}".strip()
# only keep required columns
result = result[[
'norm_name', 'norm_date', 'norm_email', 'norm_amount','norm_currency', 'norm_zweck'
]]
# rename columns to match CAMT format
# rename columns
result = result.rename(columns={
'norm_name': 'name',
'norm_date': 'booking_date',
'norm_email': 'E-Mail',
'norm_email': 'email',
'norm_amount': 'amount',
'norm_currency': 'currency',
'norm_zweck': 'remittance'
'norm_zweck': 'reference'
})
# copy booking_date to value_date
result['value_date'] = result['booking_date']
# add sign column based on amount
result['sign'] = result['amount'].apply(lambda x: 'CRDT' if x >= 0 else 'DBIT')
result['credit_debit'] = result['amount'].apply(lambda x: 'CRDT' if x >= 0 else 'DBIT')
# sort columns
result = result[[
'booking_date', 'name', 'email', 'amount', 'currency', 'sign', 'reference'
]]
else:
raise ValueError(f"Unknown table_name '{table_name}'")
@ -486,11 +483,10 @@ def generate_mt940(df: pd.DataFrame,
df : pd.DataFrame
Columns required:
- 'booking_date' (datetime or str YYYY-MM-DD)
- 'value_date' (datetime or str YYYY-MM-DD)
- 'amount' (float)
- 'currency' (str, e.g. 'EUR')
- 'credit_debit' (str, 'CRDT' or 'DBIT')
- 'remittance' (str, used inside your info_prefix section)
- 'sign' (str, 'CRDT' or 'DBIT')
- 'reference' (str, used inside your info_prefix section)
- 'name' (str, appended after ?32 in tag 86)
account_iban : str
Goes into tag 25 exactly as you want it (e.g. "11223344/55667788").
@ -507,8 +503,8 @@ def generate_mt940(df: pd.DataFrame,
The literal reference after that code (default "NONREF")
info_prefix : str, optional
If you set e.g. "169?00RAISENOW??20", your tag 86 lines become
169?00RAISENOW??20<remittance> ?32<name>
If you leave it `None`, we fall back to a simple `<name> <remittance>` join.
169?00RAISENOW??20<reference> ?32<name>
If you leave it `None`, we fall back to a simple `<name> <reference>` join.
Returns
-------
@ -516,9 +512,8 @@ def generate_mt940(df: pd.DataFrame,
"""
# normalize & sort
df2 = df.copy()
df2['value_date'] = pd.to_datetime(df2['value_date'])
df2['booking_date'] = pd.to_datetime(df2['booking_date'])
df2.sort_values('value_date', inplace=True)
df2.sort_values('booking_date', inplace=True)
# constant currency
currency = df2['currency'].iat[0]
@ -533,7 +528,7 @@ def generate_mt940(df: pd.DataFrame,
lines.append(f":28C:{statement_number}")
# opening balance
first_dt = df2['value_date'].iat[0]
first_dt = df2['booking_date'].iat[0]
ob_sign = 'C' if opening_balance >= 0 else 'D'
ob_amt = abs(opening_balance)
ob_str = f"{ob_amt:.2f}".replace('.', ',')
@ -541,44 +536,43 @@ def generate_mt940(df: pd.DataFrame,
# transactions
for _, row in df2.iterrows():
vd = row['value_date']
bd = row['booking_date']
sign = 'C' if row['credit_debit']=='CRDT' else 'D'
sign = 'C' if row['sign']=='CRDT' else 'D'
amt = abs(row['amount'])
amt_str = f"{amt:.2f}".replace('.', ',')
# :61:YYMMDDMMDD[C|D]amount<txn_code><txn_ref>
lines.append(
f":61:{vd.strftime('%y%m%d')}"
f":61:{bd.strftime('%y%m%d')}"
f"{bd.strftime('%m%d')}"
f"{sign}{amt_str}"
f"{txn_code}{txn_ref}"
)
# :86: either structured or simple fallback
raw_rem = row.get('remittance', '')
raw_rem = row.get('reference', '')
raw_name = row.get('name', '')
rem = '' if pd.isna(raw_rem) else str(raw_rem)
name = '' if pd.isna(raw_name) else str(raw_name)
if info_prefix:
# your “169?00RAISENOW??20<remittance> ?32<name>”
# your “169?00RAISENOW??20<reference> ?32<name>”
lines.append(f":86:{info_prefix}{rem} ?32{name}")
else:
# old-style "<name> <remittance>"
# old-style "<name> <reference>"
info = " ".join(filter(None, [name, rem]))
lines.append(f":86:{info}")
# closing balance
net_mv = sum(
row['amount'] if row['credit_debit']=='CRDT' else -row['amount']
row['amount'] if row['sign']=='CRDT' else -row['amount']
for _, row in df2.iterrows()
)
closing = opening_balance + net_mv
cb_sign = 'C' if closing >= 0 else 'D'
cb_amt = abs(closing)
cb_str = f"{cb_amt:.2f}".replace('.', ',')
last_dt = df2['value_date'].iat[-1]
last_dt = df2['booking_date'].iat[-1]
lines.append(f":62F:{cb_sign}{last_dt.strftime('%y%m%d')}{currency}{cb_str}")
file_str = "\r\n".join(lines)