# Haven Grazuri Accounting System Setup # Run this via Django shell: python manage.py shell < setup_accounting_via_shell.txt import os from datetime import datetime, timedelta from decimal import Decimal print("\n" + "="*60) print("Haven Grazuri Accounting System Setup") print("="*60 + "\n") # Import models from accounting.models import Account, FiscalPeriod from users.models import CustomUser # Get system user system_user = CustomUser.objects.filter(role='admin').first() print("="*60) print("Creating Chart of Accounts") print("="*60 + "\n") # Define accounts accounts_data = [ # ASSETS (202xxx) {'code': '202001', 'name': 'Loan Portfolio - Principal', 'account_type': 'asset', 'subtype': 'loan_portfolio', 'description': 'Outstanding principal balance of all active loans', 'is_system_account': True}, {'code': '202002', 'name': 'Accrued Interest Receivable', 'account_type': 'asset', 'subtype': 'current_asset', 'description': 'Interest earned but not yet collected', 'is_system_account': True}, {'code': '202003', 'name': 'Cash on Hand', 'account_type': 'asset', 'subtype': 'current_asset', 'description': 'Physical cash in branches', 'is_system_account': True}, {'code': '202004', 'name': 'Bank Account - Main', 'account_type': 'asset', 'subtype': 'current_asset', 'description': 'Main operating bank account', 'is_system_account': True}, {'code': '202005', 'name': 'M-Pesa Account', 'account_type': 'asset', 'subtype': 'current_asset', 'description': 'M-Pesa business account balance', 'is_system_account': True}, {'code': '202006', 'name': 'Allowance for Loan Losses', 'account_type': 'asset', 'subtype': 'loan_portfolio', 'description': 'Reserve for expected loan defaults (contra-asset)', 'is_system_account': True}, # LIABILITIES (302xxx) {'code': '302001', 'name': 'Client Savings Deposits', 'account_type': 'liability', 'subtype': 'client_savings', 'description': 'Savings deposits from microfinance clients', 'is_system_account': True}, {'code': '302003', 'name': 'Accrued Expenses Payable', 'account_type': 'liability', 'subtype': 'current_liability', 'description': 'Expenses incurred but not yet paid', 'is_system_account': True}, # EQUITY (320xxx) {'code': '320001', 'name': 'Share Capital', 'account_type': 'equity', 'subtype': None, 'description': 'Owner investment in the institution', 'is_system_account': True}, {'code': '320002', 'name': 'Retained Earnings', 'account_type': 'equity', 'subtype': None, 'description': 'Accumulated profits retained in the business', 'is_system_account': True}, {'code': '320003', 'name': 'Current Year Earnings', 'account_type': 'equity', 'subtype': None, 'description': 'Net income for the current fiscal year', 'is_system_account': True}, # INCOME (401xxx) {'code': '401001', 'name': 'Interest Income - Loans', 'account_type': 'income', 'subtype': 'interest_income', 'description': 'Interest earned from loan products', 'is_system_account': True}, {'code': '401002', 'name': 'Fee Income - Processing Fees', 'account_type': 'income', 'subtype': 'fee_income', 'description': 'Loan processing and application fees', 'is_system_account': True}, {'code': '401003', 'name': 'Fee Income - Late Payment Penalties', 'account_type': 'income', 'subtype': 'fee_income', 'description': 'Penalties charged on late loan payments', 'is_system_account': True}, # EXPENSES (501xxx) {'code': '501001', 'name': 'Salaries and Wages', 'account_type': 'expense', 'subtype': 'staff_costs', 'description': 'Employee salaries and wages', 'is_system_account': True}, {'code': '501002', 'name': 'Rent Expense', 'account_type': 'expense', 'subtype': 'operating_expense', 'description': 'Office and branch rent payments', 'is_system_account': False}, {'code': '501003', 'name': 'Utilities Expense', 'account_type': 'expense', 'subtype': 'operating_expense', 'description': 'Electricity, water, and internet expenses', 'is_system_account': False}, {'code': '501007', 'name': 'Loan Loss Provision Expense', 'account_type': 'expense', 'subtype': 'loan_loss_provision', 'description': 'Expense for expected loan defaults', 'is_system_account': True}, ] created_count = 0 existing_count = 0 for account_data in accounts_data: account, created = Account.objects.get_or_create( code=account_data['code'], defaults={ 'name': account_data['name'], 'account_type': account_data['account_type'], 'subtype': account_data['subtype'], 'description': account_data['description'], 'is_system_account': account_data['is_system_account'], 'is_active': True, 'created_by': system_user } ) if created: created_count += 1 print(f'[+] Created: {account.code} - {account.name}') else: existing_count += 1 print(f'[ ] Exists: {account.code} - {account.name}') print(f'\nChart of Accounts Summary:') print(f' Created: {created_count} accounts') print(f' Already existed: {existing_count} accounts') print(f' Total: {created_count + existing_count} accounts') # Create Fiscal Periods print("\n" + "="*60) print("Creating Fiscal Periods") print("="*60 + "\n") year = datetime.now().year period_created = 0 period_existing = 0 # Create monthly periods for month in range(1, 13): start_date = datetime(year, month, 1).date() if month == 12: end_date = datetime(year, 12, 31).date() else: end_date = (datetime(year, month + 1, 1) - timedelta(days=1)).date() period_name = start_date.strftime('%B %Y') period, created = FiscalPeriod.objects.get_or_create( start_date=start_date, end_date=end_date, defaults={ 'name': period_name, 'period_type': 'monthly', 'status': 'open' } ) if created: period_created += 1 print(f'[+] Created: {period.name}') else: period_existing += 1 # Create annual period period, created = FiscalPeriod.objects.get_or_create( name=f'FY {year}', period_type='annual', defaults={ 'start_date': datetime(year, 1, 1).date(), 'end_date': datetime(year, 12, 31).date(), 'status': 'open' } ) if created: period_created += 1 print(f'[+] Created: FY {year}') else: period_existing += 1 print(f'\nFiscal Periods Summary:') print(f' Created: {period_created} periods') print(f' Already existed: {period_existing} periods') # Final Summary print("\n" + "="*60) print("Setup Complete!") print("="*60) print(f"\nAccounts in system: {Account.objects.count()}") print(f"Fiscal periods: {FiscalPeriod.objects.count()}") print(f"Active accounts: {Account.objects.filter(is_active=True).count()}") print("\nNext steps:") print("1. Access: /accounting/dashboard/") print("2. Configure user permissions") print("3. Test loan integration") print("")