Skip to content

bipaulr/HostelMoney

Repository files navigation

Payn - Group Expense Tracking App

A full-stack expense tracking and debt management application built with Flutter (frontend) and Node.js/Express (backend). Perfect for managing shared expenses in hostels, apartments, friend groups, or any shared living situations.

Features

Core Functionality

  • Ledger-Based Expense Tracking: All expenses are organized in ledgers (groups)
  • Flexible Expense Splitting:
    • Equal split among all members
    • Custom split with individual amounts
  • Smart Debt Calculation: Automatic debt tracking showing who owes whom
  • Settlement System: Easy debt settlement with automatic distribution
  • Transaction History: Complete history with filters and CSV export
  • Approval System: Smart auto-approval for expenses, manual approval for settlements

User Features

  • Dashboard: Quick overview of all debts across ledgers
  • Multiple Ledgers: Create and manage multiple expense groups
  • Friends System: Add friends and manage connections
  • Member Roles: Admin and member roles for ledger management
  • Real-time Updates: See debts update immediately after recording expenses

Technical Features

  • Auto-Approved Expenses: When you record an expense, it's approved instantly
  • Custom Split Support: Specify exact amounts each person owes
  • Debt Resolution: Calculates net balances to minimize transactions
  • CSV Export: Download transaction history for record-keeping
  • Material Design 3: Modern, beautiful UI with smooth animations

Architecture

HostelMoney/
├── payn/                    # Backend (Node.js + Express)
│   ├── src/
│   │   ├── index.js        # Main server file
│   │   └── routes/
│   │       └── db.js       # Database connection
│   └── package.json
│
├── payn_frontend/          # Frontend (Flutter)
│   ├── lib/
│   │   ├── main.dart
│   │   ├── models/         # Data models
│   │   ├── screens/        # UI screens
│   │   └── services/       # API services
│   └── pubspec.yaml
│
└── Documentation/
    ├── APPROVAL_SYSTEM.md
    ├── CUSTOM_SPLIT_FEATURE.md
    ├── FIX_DEBT_CALCULATION.md
    └── TESTING_DEBTS.md

Getting Started

Prerequisites

  • Backend:

    • Node.js (v14 or higher)
    • MySQL database
  • Frontend:

    • Flutter SDK (3.9.2 or higher)
    • Dart SDK
    • Android Studio / Xcode (for mobile deployment)

Database Setup

  1. Create a MySQL database named payn:
CREATE DATABASE payn;
  1. Create the required tables:
-- Users table
CREATE TABLE users (
    Uid INT PRIMARY KEY AUTO_INCREMENT,
    Uname VARCHAR(255) NOT NULL UNIQUE,
    Passhash VARCHAR(255) NOT NULL,
    Money DECIMAL(10, 2) DEFAULT 0.00
);

-- Ledgers table
CREATE TABLE ledgers (
    LedgerID INT PRIMARY KEY AUTO_INCREMENT,
    LedgerName VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Ledger members table
CREATE TABLE ledger_members (
    LedgerID INT NOT NULL,
    Uid INT NOT NULL,
    Role ENUM('admin', 'member') DEFAULT 'member',
    joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (LedgerID, Uid),
    FOREIGN KEY (LedgerID) REFERENCES ledgers(LedgerID) ON DELETE CASCADE,
    FOREIGN KEY (Uid) REFERENCES users(Uid) ON DELETE CASCADE
);

-- Transactions table
CREATE TABLE transactions (
    Tid INT PRIMARY KEY AUTO_INCREMENT,
    `From` INT NOT NULL,
    `To` INT NOT NULL,
    Amount DECIMAL(10, 2) NOT NULL,
    Approved ENUM('A', 'NA', 'R') DEFAULT 'NA',
    Resolved ENUM('Y', 'NA') DEFAULT 'NA',
    LedgerID INT,
    Description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (`From`) REFERENCES users(Uid),
    FOREIGN KEY (`To`) REFERENCES users(Uid),
    FOREIGN KEY (LedgerID) REFERENCES ledgers(LedgerID) ON DELETE CASCADE
);

-- Friends table
CREATE TABLE friends (
    Uid1 INT NOT NULL,
    Uid2 INT NOT NULL,
    Status ENUM('pending', 'accepted', 'rejected') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (Uid1, Uid2),
    FOREIGN KEY (Uid1) REFERENCES users(Uid) ON DELETE CASCADE,
    FOREIGN KEY (Uid2) REFERENCES users(Uid) ON DELETE CASCADE
);

Backend Setup

  1. Navigate to the backend directory:
cd payn
  1. Install dependencies:
npm install
  1. Configure database connection in src/routes/db.js:
const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'your_password',
    database: 'payn',
    // ...
});
  1. Start the server:
npm run start:dev

The server will start on http://localhost:8080

Frontend Setup

  1. Navigate to the frontend directory:
cd payn_frontend
  1. Get Flutter dependencies:
flutter pub get
  1. Update API endpoint in lib/services/api_service.dart:
static const String baseUrl = 'http://localhost:8080';
// For Android emulator: 'http://10.0.2.2:8080'
// For physical device: 'http://YOUR_IP:8080'
  1. Run the app:
flutter run

Usage Guide

Recording an Expense

  1. Click the + button on the dashboard
  2. Select "I Paid for Something"
  3. Choose the ledger (group)
  4. Enter the amount and description
  5. Choose split type:
    • Equal Split: Divides amount equally among all members
    • Custom Split: Enter specific amounts for each person
  6. Submit

Result: Everyone immediately sees they owe you their share!

Settling a Debt

Option 1: Quick Settle from Dashboard

  1. See orange debt cards on dashboard
  2. Click "Pay Now"
  3. Confirm the amount
  4. Submit

Option 2: Manual Settlement

  1. Click + button
  2. Select "Settle Up with Someone"
  3. Choose ledger and recipient
  4. Enter amount
  5. Submit (requires recipient's approval)

Managing Ledgers

  1. Create Ledger: Dashboard → Create Ledger button
  2. Add Members: Ledger Details → Members tab → Add Member
  3. View Debts: Ledger Details → Debt Tracking section
  4. View History: Ledger Details → Transaction History tab
  5. Export Data: Transaction History → Export to CSV

Key Concepts

Transaction Types

From To Type Meaning Auto-Approved?
You You Expense Record You paid for the group Yes
You Other Debt Settlement You're paying someone back No (needs approval)

Debt Calculation

Equal Split Example:

  • You record: "Paid $100 for dinner" (4 people)
  • System calculates: $100 ÷ 4 = $25 per person
  • Result: Each friend owes you $25

Custom Split Example:

  • You record: "Paid $100 for groceries"
  • Custom amounts: Alice $40, Bob $35, Charlie $25
  • Result: Each person owes their specified amount

Approval Workflow

Expenses (Auto-Approved):

Record expense → Transaction created with Approved='A' → Debts update immediately

Settlements (Needs Approval):

Submit settlement → Transaction created with Approved='NA' → 
Recipient approves → Approved='A' → Debts update

🛠️ API Endpoints

Authentication

  • POST /signup - Register new user
  • POST /login - User login

Ledgers

  • GET /ledgers/:uid - Get user's ledgers
  • POST /ledgers - Create ledger
  • GET /ledgers/:ledgerId/members - Get ledger members
  • POST /ledgers/:ledgerId/members - Add member
  • DELETE /ledgers/:ledgerId/members/:uid - Remove member

Transactions

  • POST /pay - Create transaction (expense or settlement)
  • GET /ledgers/:ledgerId/transactions - Get transaction history
  • GET /ledgers/:ledgerId/transactions/export - Export to CSV
  • POST /approve - Approve/reject transaction

Debts

  • GET /ledgers/:ledgerId/debts - Get debt balances
  • POST /ledgers/:ledgerId/settle - Settle net debt

Friends

  • GET /friends/:uid - Get friends list
  • POST /friends/add - Send friend request
  • POST /friends/respond - Accept/reject request

Database Schema

Key Tables

transactions

  • Stores all financial transactions
  • Approved: 'A' (Approved), 'NA' (Pending), 'R' (Rejected)
  • Resolved: 'Y' (Settled), 'NA' (Unresolved)
  • Special case: From = To indicates expense record

ledgers

  • Groups for expense sharing
  • Can have multiple members with different roles

ledger_members

  • Junction table linking users to ledgers
  • Stores role (admin/member) and join date

UI Screenshots

Main Screens

  • Dashboard: Overview of all ledgers and debts
  • Ledger Details: Members, debts, and transaction history
  • Pay Screen: Two-step expense recording or settlement
  • Approvals: Pending transactions requiring approval
  • Friends: Manage friend connections

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📝 Documentation

Detailed documentation available in the project:

  • APPROVAL_SYSTEM.md: Complete explanation of the approval workflow
  • CUSTOM_SPLIT_FEATURE.md: How to use and implement custom splits
  • FIX_DEBT_CALCULATION.md: Technical details of debt calculation
  • TESTING_DEBTS.md: Testing guide and troubleshooting

Known Issues & Solutions

Debts not showing?

  • Ensure transactions are approved (Approved = 'A')
  • Check transactions are unresolved (Resolved = 'NA')
  • Verify correct ledger ID

Custom splits not working?

  • Ensure amounts sum to total (within $0.01 tolerance)
  • Check description format: [Custom split: Name $amount, ...]

Future Enhancements

  • Optimal debt resolution algorithm
  • Push notifications for approvals
  • Receipt image uploads
  • Multiple currency support
  • Recurring expenses
  • Budget tracking per ledger
  • Mobile app deployment (iOS & Android)

Note: This is a full-stack application requiring both backend and frontend setup. Make sure both services are running for full functionality.

Happy expense tracking! 💰✨

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published