from datetime import datetime
from tkinter import filedialog, ttk
def get_conversion_rate(date, currency):
('GBP', '2024-03-31'): 1.0,
('EUR', '2024-03-31'): 1.18,
('USD', '2024-03-31'): 1.31,
('CAD', '2024-03-31'): 1.74,
return conversion_rates.get((currency, str(date)[:10]), 1.0)
def prepare_files_with_duplicates(df, wise_df):
files = {} # Initialize the files dictionary
for index, row in wise_df.iterrows():
# Skip rows where 'Status' is 'CANCELLED'
if row['Status'] == 'CANCELLED':
currency = row['Target currency']
direction = row['Direction']
base_row = df.iloc[index].copy()
# Handle NaN or empty 'Target name' and 'Source name'
base_row['Description'] = "none" if pd.isna(row['Target name']) or row['Target name'].strip() == "" else row['Target name']
base_row['Payee'] = "none" if pd.isna(row['Source name']) or row['Source name'].strip() == "" else row['Source name']
# Adjusting amounts based on currency and direction
if (direction == 'OUT' or direction == 'NEUTRAL') and row['Source currency'] != row['Target currency']:
# Append currency conversion information to the Description
base_row['Description'] += f" {row['Source currency']} to {row['Target currency']}"
base_row['*Amount'] = -abs(row['Source amount (after fees)'])
currency = row['Source currency']
elif direction == 'NEUTRAL':
base_row['Description'] += " NEUTRAL"
# For NEUTRAL, handle IN and OUT separately
neutral_row_in = base_row.copy()
neutral_row_in['*Amount'] = abs(row['Target amount (after fees)'])
files[currency]['IN'].append(neutral_row_in)
neutral_row_out = base_row.copy()
neutral_row_out['*Amount'] = -abs(row['Source amount (after fees)'])
source_currency = row['Source currency']
if source_currency not in files:
files[source_currency] = {'IN': [], 'OUT': []}
files[source_currency]['OUT'].append(neutral_row_out)
base_row['*Amount'] = -abs(row['Target amount (after fees)'])
base_row['*Amount'] = abs(row['Target amount (after fees)'])
if direction == 'NEUTRAL':
base_row['Description'] += " NEUTRAL"
neutral_row_in = base_row.copy()
neutral_row_in['*Amount'] = abs(row['Target amount (after fees)'])
files[currency]['IN'].append(neutral_row_in)
neutral_row_out = base_row.copy()
neutral_row_out['*Amount'] = -abs(row['Target amount (after fees)'])
files[currency]['OUT'].append(neutral_row_out)
# Ensure currency keys exist in the files dictionary
if currency not in files:
files[currency] = {'IN': [], 'OUT': []}
files[currency][direction].append(base_row.copy())
# Duplicate handling for source fee, with NEUTRAL append
if pd.notna(row['Source fee amount']) and row['Source fee amount'] > 0:
duplicate_row = base_row.copy()
duplicate_currency = row['Source fee currency']
duplicate_row['*Amount'] = -abs(row['Source fee amount'])
duplicate_row['Description'] += '_BANK_FEES'
if direction == 'NEUTRAL':
duplicate_row['Description'] += " NEUTRAL"
if duplicate_currency not in files:
files[duplicate_currency] = {'IN': [], 'OUT': []}
files[duplicate_currency]['OUT'].append(duplicate_row)
return files # Make sure to return files from the function
def load_and_process_files(wise_report_path, xero_report_path):
wise_df = pd.read_excel(wise_report_path, sheet_name='Wise Report')
mappings_df = pd.read_excel(wise_report_path, sheet_name='mappings')
xero_df = pd.read_excel(xero_report_path)
# Map data and process files
mapped_data = pd.DataFrame(columns=xero_df.columns)
for wise_col, xero_col in dict(zip(mappings_df['wise report'], mappings_df['xero report'])).items():
if xero_col in mapped_data.columns:
mapped_data[xero_col] = wise_df[wise_col]
files_dict = prepare_files_with_duplicates(mapped_data, wise_df)
current_time = datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
output_directory = f'wise_transactions_{current_time}'
os.makedirs(output_directory, exist_ok=True)
for currency, directions in files_dict.items():
for direction, rows in directions.items():
df_to_save = pd.DataFrame(rows)
file_name = os.path.join(output_directory, f'{currency}_{direction}.xlsx')
df_to_save.to_excel(file_name, index=False)
return f"Files have been successfully created in {output_directory}."
def browse_file(path_label):
filename = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx *.xls")])
def on_run_pressed(root, wise_report_path, xero_report_path):
print(load_and_process_files(wise_report_path, xero_report_path))
root.destroy() # Closes the Tkinter window after processing
root.title("Wise to Xero Processing Tool")
# Set the window size and disable resizing
root.geometry("600x200") # Set initial size of the window
root.resizable(False, False) # Disable resizing
style.theme_use('default') # Modern theme
# Setup variable to store file paths
wise_path_label = tk.StringVar(root)
xero_path_label = tk.StringVar(root)
# Configure grid to expand buttons
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_rowconfigure(2, weight=1)
# Create and place buttons
browse_wise_button = ttk.Button(root, text="Select Wise Report", command=lambda: browse_file(wise_path_label))
browse_wise_button.grid(row=0, column=0, sticky="nsew", padx=1, pady=1)
browse_xero_button = ttk.Button(root, text="Select Xero Report", command=lambda: browse_file(xero_path_label))
browse_xero_button.grid(row=1, column=0, sticky="nsew", padx=1, pady=1)
run_button = ttk.Button(root, text="Run", command=lambda: on_run_pressed(root, wise_path_label.get(), xero_path_label.get()))
run_button.grid(row=2, column=0, sticky="nsew", padx=1, pady=1)
if __name__ == "__main__":