Personal Finances Application — konsolowy zarządca finansów w C++
Projekt C++ · OOP · XML · Aplikacja konsolowa

Personal Finances Application — zarządca finansów w C++

Wieloużytkownikowa aplikacja konsolowa napisana w C++ do śledzenia przychodów i wydatków. Pełny system logowania z rate limitingiem (3 próby hasła), persystencja danych przez pliki XML, walidacja dat z obsługą roku przestępnego, bilansy za bieżący miesiąc, poprzedni miesiąc lub dowolny okres — wszystko w obiektowej architekturze z dziedziczeniem i oddzielonymi warstwami.

C++ OOP + dziedziczenie XML (CMarkup) std::vector std::sort + komparator Aplikacja konsolowa

01Wygląd aplikacji — terminal

Aplikacja działa w trybie konsolowym — czyste menu tekstowe, nawigacja przez pojedynczy znak wpisany z klawiatury, każde działanie daje informację zwrotną w terminalu. Dwa menu: główne (dla niezalogowanych) i użytkownika (po zalogowaniu).

Menu główne i logowanie

PersonalFinancesAplication.exe
== PERSONAL FINANCES APLICATION == == 1. register new user == == 2. user log in == == 9. exit program == > 2 Enter login: szymon Enter password. Attempts left: 3: •••••••• You have logged in.

ekran logowania — rate limiter odlicza pozostałe próby przy każdej błędnej

Menu użytkownika

PersonalFinancesAplication.exe — zalogowany: szymon
=========== USER MENU =========== == 1. add income == == 2. add outcome == == 3. current month balance == == 4. previous month balance == == 5. any period balance == == 6. change password == == 7. sign out == > _

menu użytkownika — 7 opcji, pętla while(true) do wylogowania

Dodawanie przychodu

PersonalFinancesAplication.exe — add income
Add Income with todays date – press ‘1’ Add Income with different date – press ‘2’ > 1 Enter item: Wypłata listopad Enter amount: 5800 Income has been added succesfully…

dodawanie przychodu — wybór daty (dziś / inna), opis, kwota z walidacją

Dodawanie wydatku z własną datą

PersonalFinancesAplication.exe — add outcome
Add Outcome with todays date – press ‘1’ Add Outcome with different date – press ‘2’ > 2 enter date in the following format yyyy-mm-dd: 2024-11-05 Enter item: Czynsz Enter amount: abc It is not number, try again Enter amount: 1800 Outcome has been added succesfully…

wydatek z własną datą — walidacja kwoty (tylko cyfry), pętla do momentu poprawnego wpisu

Bilans bieżącego miesiąca

PersonalFinancesAplication.exe — current month balance
confirm by entering ‘y’ button. Press any other button to abort… start date : 2024-11-01 end date : 2024-11-21 > y == Incomes == Date: 2024-11-01, Item: Wyplata listopad, Amount: 5800 Date: 2024-11-15, Item: Premia, Amount: 800 Incomes sum = 6600 == Outcomes == Date: 2024-11-03, Item: Jedzenie, Amount: 450 Date: 2024-11-05, Item: Czynsz, Amount: 1800 Date: 2024-11-10, Item: Internet, Amount: 60 Date: 2024-11-18, Item: Kino, Amount: 45 Outcomes sum = 2355 Balance: 4245

bilans bieżącego miesiąca — lista operacji posortowana chronologicznie + sumy + wynik

Bilans za dowolny okres

PersonalFinancesAplication.exe — any period balance
Enter start date of expenses comparison in yyyy-mm-dd format 2024-10-01 Enter end date of expenses comparison in yyyy-mm-dd format 2024-10-31 confirm by entering ‘y’ button. Press any other button to abort… start date : 2024-10-01 end date : 2024-10-31 > y == Incomes == Date: 2024-10-01, Item: Wyplata pazdziernik, Amount: 5800 Incomes sum = 5800 == Outcomes == Date: 2024-10-04, Item: Czynsz, Amount: 1800 Date: 2024-10-08, Item: Jedzenie, Amount: 520 Date: 2024-10-15, Item: Ubezpieczenie, Amount: 200 Date: 2024-10-22, Item: Spotify, Amount: 25 Outcomes sum = 2545 Balance: 3255

bilans za dowolny okres — zakres dat wpisywany ręcznie, walidacja formatu i zakresu

Rejestracja nowego użytkownika

PersonalFinancesAplication.exe — register
Enter login: anna Enter password: •••••• Enter name: Anna Enter surname: Kowalska Account has been succesfully created

rejestracja — login sprawdzany pod kątem unikalności, dane zapisywane do users.xml

02Funkcjonalności

👤

Wielu użytkowników

Rejestracja z weryfikacją unikalności loginu. Logowanie z 3 próbami hasła (rate limit). Zmiana hasła. Dane w users.xml.

💰

Przychody i wydatki

Dodawanie z datą dzisiejszą lub własną. Walidacja kwoty (tylko cyfry, pętla do momentu poprawnego wpisu). Opis pozycji.

📊

Trzy tryby bilansu

Bieżący miesiąc, poprzedni miesiąc (z obsługą przełomu roku) i dowolny okres. Operacje posortowane chronologicznie, sumy, wynik.

🗓️

Walidacja dat

Format YYYY-MM-DD, zakres 2000–dziś, poprawność dnia w miesiącu z obsługą roku przestępnego (luty 28/29).

💾

Persystencja XML

Dane w trzech plikach XML przez bibliotekę CMarkup. Odczyt przy starcie, zapis przy każdej operacji. Izolacja danych per userId.

🏗️

Architektura OOP

9 klas z jasną odpowiedzialnością. Dziedziczenie XmlFileUsersFile/FinancesFile. Wskaźnik do FinanceManager tworzony po zalogowaniu.

03Architektura — klasy i dziedziczenie

PersonalFinancesApp menu() · chooseOption() UserManager registration · login · logout FinanceManager* addIncome · balance() User login · password · name Operation id · date(int) · item · amount XmlFile «base» isFileEmpty() · getFileName() UsersFile : XmlFile · CRUD users FinancesFile : XmlFile · CRUD operations DatesSupportingMethods getCurrentDate() · howManyDays() SupportingMethods readLine() · readChar() · validate() dziedziczenie użycie

04Persystencja danych — XML

Dane przechowywane w trzech plikach XML przez bibliotekę CMarkup. Daty jako liczby całkowite (YYYYMMDD) — porównanie zakresów to zwykłe >= i <=.

<!-- incomes.xml — przykładowy rekord -->
<INCOMES>
  <INCOME>
    <incomeId>1</incomeId>
    <userId>1</userId>
    <date>20241101</date>   <!-- int YYYYMMDD → proste porównanie -->
    <item>Wyplata listopad</item>
    <amount>5800.000000</amount>
  </INCOME>
</INCOMES>

05Logika dat i sortowanie

// Rok przestępny — własna implementacja, bez zewnętrznych bibliotek
int DatesSupportingMethods::howManyDays(int year, int month) {
    const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int result = days[month - 1];
    if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
        result = 29; // luty w roku przestępnym
    return result;
}

// std::sort z komparatorem zdefiniowanym jako statyczna metoda klasy
std::sort(input.begin(), input.end(), Operation::compareByDate);

// Porównanie dat to porównanie intów — daty przechowywane jako YYYYMMDD
if ((dateToCompare >= comparisonStart) && (dateToCompare <= comparisonEnd)) {
    operations.push_back(operation);
}

06Czego dowodzi ten projekt

C++ OOP

Klasy, dziedziczenie, enkapsulacja, konstruktory z inicjalizatorami, wskaźnik tworzony dynamicznie po zalogowaniu.

Separation of concerns

Każda klasa ma jedną odpowiedzialność — UserManager nie wie nic o XML, FinancesFile nie wie nic o interfejsie.

STL w praktyce

std::vector<Operation>, std::sort z komparatorem, std::stringstream, range-for.

Własna logika daty

Rok przestępny, poprzedni miesiąc z przełomem roku, walidacja formatu i zakresu — bez bibliotek zewnętrznych.

Persystencja plików

Odczyt XML przy starcie, zapis przy każdej zmianie, izolacja danych per userId, obsługa błędów.

Punkt startowy

Ten projekt poprzedza całe portfolio webowe. Ewolucja: od C++ i XML do Python/FastAPI/pgvector i OpenAI.

Zobacz kod na GitHubie

Pełny kod C++ — ~7400 linii rozłożonych na 9 klas w osobnych plikach .h/.cpp.

Zobacz kod na GitHub
· · ·
Udostępnij jeśli spodobał Ci się mój projekt