dvsaudit's picture
Upload 4 files
85d9b2d verified
Raw
History Blame Contribute Delete
6.21 kB
import streamlit as st
import pandas as pd
import numpy as np
import io
# Page Config
st.set_page_config(page_title="Anomali THC Gabungan", layout="wide")
st.title('Anomali transaksi harian Format THC Gabungan')
st.write("""1. File yang dibutuhkan File menu ke-6""")
st.write("""2. Rapihkan data tersebut jadi seperti contoh ini: https://drive.google.com/file/d/14Ofz53dSVRFzlFrrc8snZmmkHq7CO-R2/view?usp=drive_link""")
st.write("""3. Hapus karakter spesial terlebih dahulu pada file excel nya, lengkapnya ada disini tutorialnya : https://drive.google.com/file/d/1xABUwrMatieKFsNeUbOWl2KuDh6BVLwy/view?usp=drive_link """)
## SESI UPLOAD FILE
uploaded_files = st.file_uploader("Upload files", accept_multiple_files=True, type=['xlsx'])
df_PDR = None
@st.cache_data
def load_excel(file):
# Menggunakan engine openpyxl untuk file xlsx
return pd.read_excel(file, engine='openpyxl')
if uploaded_files:
for file in uploaded_files:
if file.name.lower().endswith('.xlsx') and file.name == 'Format data THC gabungan.xlsx':
try:
with st.spinner(f"Membaca {file.name}..."):
df_PDR = load_excel(file)
except Exception as e:
st.error(f"Error membaca file: {e}")
if df_PDR is None:
st.info("Harap upload file dengan nama 'Format data THC gabungan.xlsx'")
else:
# --- FUNGSI PERHITUNGAN ---
def ambil_3_digit_akhir(val):
try:
if pd.isna(val) or val == 0:
return 0
return int(str(int(val))[-3:])
except:
return 0
def estimasi_nominal_kecil_menabung(val):
return ambil_3_digit_akhir(val)
def estimasi_nominal_kecil_penarikan(val):
return ambil_3_digit_akhir(val)
def estimasi_uang(val):
try:
if pd.isna(val) or val == 0:
return 0
return int(np.ceil(val / 1000.0) * 1000)
except:
return 0
def estimasi_nabung_2(x):
return x - 500 if x > 500 else 0
def estimasi_nabung_3(x):
return x + 500 if x < 500 else 0
def tf_1(row):
try:
if row["Estimasi Nabung 1"] < 500:
return (
(row["Estimasi Nabung 1"] == row["Estimasi Nominal Kecil Menabung"])
or (row["Estimasi Nabung 3"] == row["Estimasi Nominal Kecil Menabung"])
)
else:
return (
(row["Estimasi Nominal Kecil Menabung"] == row["Estimasi Nabung 1"])
or (row["Estimasi Nominal Kecil Menabung"] == row["Estimasi Nabung 2"])
)
except:
return False
def estimasi_penarikan_1(val):
return ambil_3_digit_akhir(val)
def estimasi_penarikan_2(x):
return x - 500 if x > 500 else 0
def tf2(row):
try:
if row["Estimasi Penarikan 1"] < 500:
return row["Estimasi Penarikan 1"] == row["Estimasi Nominal Kecil Penarikan"]
else:
return (
(row["Estimasi Nominal Kecil Penarikan"] == row["Estimasi Penarikan 1"])
or (row["Estimasi Nominal Kecil Penarikan"] == row["Estimasi Penarikan 2"])
)
except:
return False
def final_filter(row):
return bool(row["T/F 1"] or row["T/F2"])
# --- PROSES TAMBAHAN KOLUMN ---
with st.spinner("Sedang memproses anomali transaksi..."):
df = df_PDR.copy()
# Memastikan kolom yang dibutuhkan ada
required_cols = ["Db Total", "Cr Total", "Db Total2"]
missing = [c for c in required_cols if c not in df.columns]
if missing:
st.error(f"Kolom berikut tidak ditemukan dalam file: {missing}")
else:
df["Estimasi Nominal Kecil Menabung"] = df["Db Total"].apply(estimasi_nominal_kecil_menabung)
df["Estimasi Nominal Kecil Penarikan"] = df["Cr Total"].apply(estimasi_nominal_kecil_penarikan)
df["Estimasi Uang"] = df["Db Total2"].apply(estimasi_uang)
df["Estimasi Nabung 1"] = df["Estimasi Uang"] - df["Db Total2"]
df["Estimasi Nabung 2"] = df["Estimasi Nabung 1"].apply(estimasi_nabung_2)
df["Estimasi Nabung 3"] = df["Estimasi Nabung 1"].apply(estimasi_nabung_3)
df["Estimasi Penarikan 1"] = df["Db Total2"].apply(estimasi_penarikan_1)
df["Estimasi Penarikan 2"] = df["Estimasi Penarikan 1"].apply(estimasi_penarikan_2)
df["T/F 1"] = df.apply(tf_1, axis=1)
df["T/F2"] = df.apply(tf2, axis=1)
df["Final Filter"] = df.apply(final_filter, axis=1)
# Tampilkan hasil
st.success("Analisis selesai!")
st.write("Preview data (20 baris pertama):")
st.dataframe(df.head(20))
# Filter hanya yang anomali jika diinginkan user
show_anomalies_only = st.checkbox("Tampilkan hanya transaksi anomali (Final Filter = True)")
if show_anomalies_only:
df_display = df[df["Final Filter"] == True]
st.write(f"Ditemukan {len(df_display)} anomali.")
st.dataframe(df_display)
st.divider()
# Download hasil sebagai Excel
output = io.BytesIO()
with pd.ExcelWriter(output, engine='openpyxl') as writer:
df.to_excel(writer, index=False)
st.download_button(
label="Download Download THC Final Gabungan.xlsx",
data=output.getvalue(),
file_name="THC Final Gabungan.xlsx",
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
)