optimize and clean up
This commit is contained in:
parent
491eb038ca
commit
5333f111dd
50
app/app.py
50
app/app.py
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user