Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| import os | |
| class DeleteTab: | |
| def __init__(self, get_sheet_func, get_farmers_func, format_indian_currency_func, format_date_display_func): | |
| """ | |
| Initialize the Delete Tab | |
| Args: | |
| get_sheet_func: Function to get Google Sheet | |
| get_farmers_func: Function to get list of farmers | |
| format_indian_currency_func: Function to format currency in Indian style | |
| format_date_display_func: Function to format date display | |
| """ | |
| self.get_sheet = get_sheet_func | |
| self.get_farmers = get_farmers_func | |
| self.format_indian_currency = format_indian_currency_func | |
| self.format_date_display = format_date_display_func | |
| def refresh_farmers(self): | |
| """Refresh farmer dropdown""" | |
| return gr.Dropdown(choices=self.get_farmers()) | |
| def get_farmer_transactions_for_deletion(self, farmer_name): | |
| """Get all transactions for a farmer with row indices""" | |
| try: | |
| if not farmer_name or not farmer_name.strip(): | |
| return None, "β Please select a farmer" | |
| farmer_name = farmer_name.strip() | |
| spreadsheet = self.get_sheet() | |
| trans_sheet = spreadsheet.worksheet("Transactions") | |
| data = trans_sheet.get_all_values() | |
| if len(data) <= 1: | |
| return None, f"β No transactions found for farmer '{farmer_name}'" | |
| # Create DataFrame with row indices | |
| df = pd.DataFrame(data[1:], columns=data[0]) | |
| df['Sheet_Row'] = range(2, len(data) + 1) | |
| # Filter by farmer | |
| farmer_df = df[df['Farmer Name'] == farmer_name].copy() | |
| if farmer_df.empty: | |
| return None, f"β No transactions found for farmer '{farmer_name}'" | |
| # Convert amount and date | |
| farmer_df['Amount'] = pd.to_numeric(farmer_df['Amount'], errors='coerce') | |
| farmer_df['Date'] = pd.to_datetime(farmer_df['Date'], errors='coerce') | |
| farmer_df = farmer_df.sort_values('Date') | |
| # Create display dataframe | |
| display_df = farmer_df[['Sheet_Row', 'Date', 'Type', 'Bank Account', 'Amount']].copy() | |
| display_df.columns = ['Row #', 'Date', 'Description', 'Bank Account', 'Amount (βΉ)'] | |
| display_df['Date'] = display_df['Date'].apply(lambda x: self.format_date_display(str(x)[:10])) | |
| display_df['Amount (βΉ)'] = display_df['Amount (βΉ)'].apply(self.format_indian_currency) | |
| return display_df, f"β Found {len(farmer_df)} transaction(s) for {farmer_name}" | |
| except Exception as e: | |
| import traceback | |
| traceback.print_exc() | |
| return None, f"β Error loading transactions: {str(e)}" | |
| def delete_single_transaction(self, row_number): | |
| """Delete a single transaction by row number""" | |
| try: | |
| if not row_number: | |
| return "β Please select a row to delete" | |
| row_number = int(row_number) | |
| spreadsheet = self.get_sheet() | |
| trans_sheet = spreadsheet.worksheet("Transactions") | |
| # Delete the row | |
| trans_sheet.delete_rows(row_number) | |
| return f"β Successfully deleted transaction at row {row_number}" | |
| except Exception as e: | |
| return f"β Error deleting transaction: {str(e)}" | |
| def delete_all_farmer_data(self, farmer_name): | |
| """Delete all data for a farmer including transactions and farmer registration""" | |
| try: | |
| if not farmer_name or not farmer_name.strip(): | |
| return "β Please enter a farmer name" | |
| farmer_name = farmer_name.strip() | |
| spreadsheet = self.get_sheet() | |
| # 1. Delete all transactions for this farmer | |
| trans_sheet = spreadsheet.worksheet("Transactions") | |
| data = trans_sheet.get_all_values() | |
| if len(data) > 1: | |
| # Find rows to delete (from bottom to top to avoid index shifting) | |
| rows_to_delete = [] | |
| for idx, row in enumerate(data[1:], start=2): | |
| if len(row) > 1 and row[1] == farmer_name: # Column 1 is Farmer Name | |
| rows_to_delete.append(idx) | |
| # Delete rows from bottom to top | |
| for row_num in sorted(rows_to_delete, reverse=True): | |
| trans_sheet.delete_rows(row_num) | |
| transactions_deleted = len(rows_to_delete) | |
| else: | |
| transactions_deleted = 0 | |
| # 2. Remove farmer from metadata | |
| meta_sheet = spreadsheet.worksheet("Metadata") | |
| meta_data = meta_sheet.get_all_values() | |
| for idx, row in enumerate(meta_data): | |
| if len(row) >= 2 and row[0] == 'farmer': | |
| current_farmers = row[1] | |
| farmers_list = [f.strip() for f in current_farmers.split(',') if f.strip()] | |
| if farmer_name in farmers_list: | |
| farmers_list.remove(farmer_name) | |
| new_farmers = ','.join(farmers_list) | |
| meta_sheet.update_cell(idx + 1, 2, new_farmers) | |
| return f"β Successfully deleted farmer '{farmer_name}' from system.\n" \ | |
| f"Deleted {transactions_deleted} transaction(s).\n" \ | |
| f"Removed farmer from registration list." | |
| if transactions_deleted > 0: | |
| return f"β οΈ Deleted {transactions_deleted} transaction(s) but farmer was not found in registration list" | |
| else: | |
| return f"β Farmer '{farmer_name}' not found in system" | |
| except Exception as e: | |
| import traceback | |
| traceback.print_exc() | |
| return f"β Error deleting farmer data: {str(e)}" | |
| def get_banks(self): | |
| """Get list of registered bank accounts""" | |
| try: | |
| spreadsheet = self.get_sheet() | |
| meta_sheet = spreadsheet.worksheet("Metadata") | |
| data = meta_sheet.get_all_values() | |
| banks = [] | |
| for row in data: | |
| if len(row) >= 2 and row[0] == 'bank' and row[1]: | |
| banks.extend([b.strip() for b in row[1].split(',') if b.strip()]) | |
| return sorted(list(set(banks))) | |
| except Exception as e: | |
| print(f"Error getting banks: {str(e)}") | |
| return [] | |
| def refresh_banks(self): | |
| """Refresh bank dropdown""" | |
| return gr.Dropdown(choices=self.get_banks()) | |
| def delete_bank(self, bank_name): | |
| """Delete a bank from the registration list""" | |
| try: | |
| if not bank_name or not bank_name.strip(): | |
| return "β Please select a bank account" | |
| bank_name = bank_name.strip() | |
| spreadsheet = self.get_sheet() | |
| meta_sheet = spreadsheet.worksheet("Metadata") | |
| meta_data = meta_sheet.get_all_values() | |
| for idx, row in enumerate(meta_data): | |
| if len(row) >= 2 and row[0] == 'bank': | |
| current_banks = row[1] | |
| banks_list = [b.strip() for b in current_banks.split(',') if b.strip()] | |
| if bank_name in banks_list: | |
| banks_list.remove(bank_name) | |
| new_banks = ','.join(banks_list) | |
| meta_sheet.update_cell(idx + 1, 2, new_banks) | |
| return f"β Successfully deleted bank account '{bank_name}' from registration list" | |
| return f"β Bank account '{bank_name}' not found in registration list" | |
| except Exception as e: | |
| import traceback | |
| traceback.print_exc() | |
| return f"β Error deleting bank: {str(e)}" | |
| def clear_delete_bank(self): | |
| """Clear bank deletion interface""" | |
| return "" | |
| def clear_delete_single(self): | |
| """Clear single deletion interface""" | |
| return None, "", "" | |
| def clear_delete_all(self): | |
| """Clear complete deletion interface""" | |
| return "" | |
| def create_tab(self): | |
| """Create the Delete tab interface""" | |
| with gr.Tab("ποΈ Delete Records"): | |
| gr.Markdown("## Delete Transaction Records") | |
| gr.Markdown("β οΈ **Warning**: Deletion is permanent and cannot be undone!") | |
| # Section 1: Delete Single Transaction | |
| with gr.Accordion("π Delete Individual Transaction", open=False): | |
| gr.Markdown("*Search for a farmer and delete specific transactions*") | |
| with gr.Row(): | |
| delete_single_farmer = gr.Dropdown( | |
| label="Select Farmer", | |
| choices=[], | |
| allow_custom_value=True, | |
| scale=9 | |
| ) | |
| refresh_delete_single_btn = gr.Button("π", scale=1, size="sm") | |
| load_delete_trans_btn = gr.Button("Load Transactions", variant="primary") | |
| delete_single_status = gr.Textbox(label="Status", interactive=False, show_label=False) | |
| delete_trans_df = gr.Dataframe( | |
| label="Transactions for Selected Farmer", | |
| interactive=False, | |
| wrap=True | |
| ) | |
| gr.Markdown("### Select Transaction to Delete") | |
| gr.Markdown("*Enter the Row # from the table above*") | |
| with gr.Row(): | |
| delete_row_input = gr.Textbox( | |
| label="Enter Row Number to Delete", | |
| placeholder="e.g., 15", | |
| scale=3 | |
| ) | |
| delete_single_btn = gr.Button("Delete Selected Row", variant="stop", size="lg", scale=1) | |
| delete_result = gr.Textbox(label="Deletion Result", interactive=False) | |
| gr.Markdown("---") | |
| # Section 2: Delete All Farmer Data | |
| with gr.Accordion("β οΈ Delete All Farmer Data", open=False): | |
| gr.Markdown("*Permanently delete ALL transactions and registration for a farmer*") | |
| gr.Markdown("**This will:**") | |
| gr.Markdown("- Delete all transaction records for this farmer") | |
| gr.Markdown("- Remove farmer from the registration list") | |
| gr.Markdown("- **Cannot be undone!**") | |
| with gr.Row(): | |
| delete_all_farmer = gr.Dropdown( | |
| label="Select Farmer to Delete Completely", | |
| choices=[], | |
| allow_custom_value=True, | |
| scale=9 | |
| ) | |
| refresh_delete_all_btn = gr.Button("π", scale=1, size="sm") | |
| delete_all_confirm = gr.Checkbox( | |
| label="I understand this action is permanent and cannot be undone", | |
| value=False | |
| ) | |
| delete_all_btn = gr.Button( | |
| "Delete All Data for This Farmer", | |
| variant="stop", | |
| size="lg" | |
| ) | |
| delete_all_result = gr.Textbox(label="Deletion Result", interactive=False) | |
| with gr.Accordion("π¦ Delete Bank Account", open=False): | |
| gr.Markdown("*Remove a bank account from the registration list*") | |
| gr.Markdown("β οΈ **Note**: This only removes the bank from the dropdown list. Existing transactions with this bank will remain.") | |
| with gr.Row(): | |
| delete_bank_dropdown = gr.Dropdown( | |
| label="Select Bank Account to Delete", | |
| choices=[], | |
| allow_custom_value=True, | |
| scale=9 | |
| ) | |
| refresh_delete_bank_btn = gr.Button("π", scale=1, size="sm") | |
| delete_bank_confirm = gr.Checkbox( | |
| label="I confirm I want to delete this bank account from the registration list", | |
| value=False | |
| ) | |
| delete_bank_btn = gr.Button( | |
| "Delete Bank Account", | |
| variant="stop", | |
| size="lg" | |
| ) | |
| delete_bank_result = gr.Textbox(label="Deletion Result", interactive=False) | |
| # Event handlers - Delete Single Transaction | |
| refresh_delete_single_btn.click( | |
| fn=self.refresh_farmers, | |
| outputs=[delete_single_farmer] | |
| ) | |
| load_delete_trans_btn.click( | |
| fn=self.get_farmer_transactions_for_deletion, | |
| inputs=[delete_single_farmer], | |
| outputs=[delete_trans_df, delete_single_status] | |
| ) | |
| # Replace the delete_single_btn.click handler: | |
| def delete_and_refresh(row_number, farmer_name): | |
| """Delete transaction and refresh the list""" | |
| if not row_number or not row_number.strip(): | |
| return "β Please enter a row number", None, "" | |
| result = self.delete_single_transaction(row_number.strip()) | |
| # Reload transactions after deletion if deletion was successful | |
| if "Successfully deleted" in result: | |
| new_df, new_status = self.get_farmer_transactions_for_deletion(farmer_name) | |
| return result, new_df, new_status | |
| else: | |
| return result, None, "" | |
| delete_single_btn.click( | |
| fn=delete_and_refresh, | |
| inputs=[delete_row_input, delete_single_farmer], | |
| outputs=[delete_result, delete_trans_df, delete_single_status] | |
| ) | |
| # Event handlers - Delete All Farmer Data | |
| refresh_delete_all_btn.click( | |
| fn=self.refresh_farmers, | |
| outputs=[delete_all_farmer] | |
| ) | |
| # Event handlers - Delete Bank Account | |
| refresh_delete_bank_btn.click( | |
| fn=self.refresh_banks, | |
| outputs=[delete_bank_dropdown] | |
| ) | |
| def delete_bank_with_confirmation(bank_name, confirmed): | |
| if not confirmed: | |
| return "β Please check the confirmation box to proceed with deletion" | |
| return self.delete_bank(bank_name) | |
| delete_bank_btn.click( | |
| fn=delete_bank_with_confirmation, | |
| inputs=[delete_bank_dropdown, delete_bank_confirm], | |
| outputs=[delete_bank_result] | |
| ).then( | |
| fn=lambda: False, # Uncheck the confirmation box | |
| outputs=[delete_bank_confirm] | |
| ) | |
| def delete_all_with_confirmation(farmer_name, confirmed): | |
| if not confirmed: | |
| return "β Please check the confirmation box to proceed with deletion" | |
| return self.delete_all_farmer_data(farmer_name) | |
| delete_all_btn.click( | |
| fn=delete_all_with_confirmation, | |
| inputs=[delete_all_farmer, delete_all_confirm], | |
| outputs=[delete_all_result] | |
| ).then( | |
| fn=lambda: False, # Uncheck the confirmation box | |
| outputs=[delete_all_confirm] | |
| ) |