Banking_System_Server  1.0.0
Qt-based banking app for user/admin account management, transactions, secure server communication via PostgreSQL/Supabase.
MakeTransactionRequest.h
Go to the documentation of this file.
1 
8 #ifndef MAKETRANSACTIONREQUEST_H
9 #define MAKETRANSACTIONREQUEST_H
10 
11 #include "Request.h"
12 #include "db.h"
13 
20 {
21 private:
22  DB::DatabaseManager* dbManager = nullptr;
23 
24 public:
30  MakeTransactionRequest() : dbManager(DB::DatabaseManager::createInstance())
31  {
32  // Log to database log table (if needed)
33  }
34 
45  QJsonObject execute(const QJsonObject& jsonObj, QMutex& m) override
46  {
47  QMutexLocker locker(&m); // Lock the mutex for the duration of this function
48 
49  int from_account_number{};
50  int to_account_number{};
51  QString to_email{};
52  double amount{};
53 
54  QJsonObject response;
55  QJsonObject data;
56 
57  response.insert("Response", 5);
58 
59  // Extract the data array
60  if (jsonObj.contains("Data"))
61  {
62  QJsonObject dataObj = jsonObj["Data"].toObject();
63 
64  if (dataObj.contains("from_account_number"))
65  {
66  from_account_number = dataObj.value("from_account_number").toInt();
67  }
68  if (dataObj.contains("to_account_number"))
69  {
70  to_account_number = dataObj.value("to_account_number").toInt();
71  }
72  if (dataObj.contains("transaction_amount"))
73  {
74  amount = dataObj.value("transaction_amount").toDouble();
75  }
76  if (dataObj.contains("to_email"))
77  {
78  to_email = dataObj.value("to_email").toString();
79  }
80  }
81  else
82  {
83  qCritical() << "Data not found";
84  }
85 
86  do
87  {
88  if (!isDBConnectionValid(dbManager))
89  {
90  return CreateDBConnectionError(response, data);
91  }
92 
93  if (!to_email.isEmpty())
94  {
95  // check if email is valid and get the account number associated with it
96  DB::DbResult result = dbManager->select("account_number")
97  ->table("Users U")
98  ->join("JOIN Accounts A ON U.id = A.user_id")
99  ->where("U.email =", to_email)
100  ->exec();
101 
102  if (result.isEmpty())
103  {
104  return CreateErrorResponse(response, data, "This email is not associated with any account");
105  }
106 
107  to_account_number = result.first().value("account_number").toInt();
108  }
109 
110  DB::DbResult fromAccountResult =
111  dbManager->select("balance")->table("Accounts")->where("account_number =", from_account_number)->exec();
112 
113  if (fromAccountResult.isEmpty())
114  {
115  return CreateErrorResponse(response, data, "You don't have an account");
116  }
117 
118  DB::DbResult toAccountResult =
119  dbManager->select("balance")->table("Accounts")->where("account_number =", to_account_number)->exec();
120 
121  if (toAccountResult.isEmpty())
122  {
123  return CreateErrorResponse(response, data, "Invalid to account number");
124  }
125 
126  double fromAccountBalance = fromAccountResult.first().value("balance").toDouble();
127 
128  if (fromAccountBalance < amount)
129  {
130  return CreateErrorResponse(response, data, "Insufficient balance");
131  }
132 
133  double toAccountBalance = toAccountResult.first().value("balance").toDouble();
134 
135  // Update balances
136  fromAccountBalance -= amount;
137  toAccountBalance += amount;
138  qDebug() << "fromAccountBalance: " << fromAccountBalance;
139  qDebug() << "toAccountBalance: " << toAccountBalance;
140  qDebug() << "amount: " << amount;
141 
142  // log transaction and update account balances
143  bool success = dbManager->insert("Transactions", {{"account_number", from_account_number},
144  {"from_account_number", from_account_number},
145  {"to_account_number", to_account_number},
146  {"amount", amount}});
147 
148  if (!success)
149  {
150  return CreateErrorResponse(response, data, "Failed to log transaction");
151  }
152 
153  // Update the account balances (from)
154  dbManager->where("account_number = ", from_account_number)
155  ->update("Accounts", {{"balance", fromAccountBalance}});
156 
157  // Update the account balances (to)
158  dbManager->where("account_number = ", to_account_number)
159  ->update("Accounts", {{"balance", toAccountBalance}});
160 
161  data.insert("status", int(true));
162  data.insert("message", "Transaction successful");
163 
164  response.insert("Data", data);
165  } while (false);
166 
167  // Convert response to JSON
168  QJsonDocument responseDoc(response);
169  QByteArray responseData = responseDoc.toJson();
170 
171  // Send response
172  qDebug().noquote() << "<-- MakeTransaction::Response :\n" << responseDoc.toJson(QJsonDocument::Indented);
173 
174  return response;
175  }
176 };
177 
178 #endif // MAKETRANSACTIONREQUEST_H
This file contains the declaration of the Request class, which is an abstract base class for handling...
Manages database connections and SQL operations.
Definition: db.h:80
bool update(const QString &table, const QVariantMap &data)
Updates data in a specified table.
Definition: db.cpp:361
DatabaseManager * table(const QString &value)
Sets the table for the query.
Definition: db.cpp:115
DatabaseManager * where(const QString &value, const QVariant &val=QVariant())
Adds a WHERE clause to the query.
Definition: db.cpp:121
DbResult exec()
Executes the built query.
Definition: db.cpp:266
DatabaseManager * select(const QString &value)
Selects columns for the query.
Definition: db.cpp:107
bool insert(const QString &table, const QVariantMap &data)
Inserts data into a specified table.
Definition: db.cpp:327
DatabaseManager * join(const QString &value)
Adds a JOIN clause to the query.
Definition: db.cpp:188
The DbResult class represents a result set returned from a database query.
Definition: dbresult.h:24
QJsonObject first() const
Retrieves the first item in the result set.
Definition: dbresult.cpp:25
bool isEmpty() const
Checks if the result set is empty.
Definition: dbresult.cpp:20
The MakeTransactionRequest class handles transaction requests between accounts.
Definition: MakeTransactionRequest.h:20
QJsonObject execute(const QJsonObject &jsonObj, QMutex &m) override
Executes the transaction request.
Definition: MakeTransactionRequest.h:45
MakeTransactionRequest()
Constructor for the MakeTransactionRequest class.
Definition: MakeTransactionRequest.h:30
The Request class is an abstract base class for handling different types of requests.
Definition: Request.h:25
QJsonObject CreateErrorResponse(QJsonObject &response, QJsonObject &dataObj, QString message)
Creates a generic error JSON response.
Definition: Request.h:90
QJsonObject CreateDBConnectionError(QJsonObject &response, QJsonObject &dataObj)
Creates a JSON response indicating a database connection error.
Definition: Request.h:65
bool isDBConnectionValid(DB::DatabaseManager *dbManager)
Checks if the database connection is valid.
Definition: Request.h:36
Database management classes for handling database connections and operations.