Alibrown commited on
Commit
ce4657d
·
verified ·
1 Parent(s): e5659d2

Update app/bank.py

Browse files
Files changed (1) hide show
  1. app/bank.py +312 -54
app/bank.py CHANGED
@@ -1,102 +1,360 @@
1
- # bank.py
2
- # functionen für die Community Bank
3
  from flask import jsonify
4
- import logging
5
- import datetime
6
- import random
7
-
8
  from datetime import datetime, timedelta
9
 
10
  class BankAccount:
11
  def __init__(self, user_id, balance=0.0, interest_rate=0.0):
12
- """Initialisiert ein neues Bankkonto für den Benutzer."""
 
 
 
 
13
  self.user_id = user_id
14
- self.balance = balance
15
- self.interest_rate = interest_rate # z.B. 0.05 für 5% Zinsen, -0.05 für -5% (negative Zinsen)
16
  self.last_interest_time = datetime.now()
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  def deposit(self, amount):
19
- """Funktion zum Einzahlen auf das Konto."""
20
  if amount <= 0:
21
  raise ValueError("Einzahlungsbetrag muss positiv sein.")
22
  self.balance += amount
 
23
  return self.balance
24
 
25
  def withdraw(self, amount):
26
- """Funktion zum Abheben vom Konto."""
27
  if amount <= 0:
28
  raise ValueError("Abhebungsbetrag muss positiv sein.")
29
  if amount > self.balance:
30
  raise ValueError("Nicht genügend Geld auf dem Konto.")
31
  self.balance -= amount
 
32
  return self.balance
33
 
34
  def apply_interest(self):
35
- """Berechnet die Zinsen und fügt sie dem Konto hinzu (positive oder negative Zinsen)."""
36
  current_time = datetime.now()
37
  time_difference = current_time - self.last_interest_time
38
-
39
- # Zinsen werden z.B. täglich angewendet (kann angepasst werden)
40
  if time_difference >= timedelta(days=1):
41
  days_passed = time_difference.days
42
- # Zinsen anwenden für jeden Tag, der seit der letzten Berechnung vergangen ist
43
- for _ in range(days_passed):
44
- self.balance += self.balance * self.interest_rate
 
 
 
45
  self.last_interest_time = current_time
 
46
  return self.balance
47
 
48
  def get_balance(self):
49
- """Gibt den aktuellen Kontostand zurück (nach Zinsberechnung)."""
50
  self.apply_interest()
51
  return self.balance
52
 
 
 
53
 
54
- # Beispiel für die Verwendung der Klassen und Funktionen
55
- #if __name__ == "__main__":
56
- # Erstellen eines Kontos für einen Spieler mit 100 Einheiten und 5% Zinsen
57
- # player_account = BankAccount(user_id=12345, balance=100.0, interest_rate=0.05)
58
-
59
- # Einzahlung
60
- # player_account.deposit(50)
61
- # print(f"Neuer Kontostand nach Einzahlung: {player_account.get_balance()}")
62
 
63
- # Abheben
64
- # player_account.withdraw(30)
65
- # print(f"Neuer Kontostand nach Abhebung: {player_account.get_balance()}")
66
 
67
- # Zinsen anwenden (nur zur Demonstration, normalerweise täglich automatisch)
68
- # player_account.apply_interest()
69
- # print(f"Kontostand nach Zinsanwendung: {player_account.get_balance()}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- # b) /send Money to user
72
  def send_money_command(from_user_id, to_user_id, amount):
73
  if amount <= 0:
74
  return jsonify({"type": 4, "data": {"content": "Ungültiger Betrag!"}})
75
 
76
- # Überprüfe, ob der Absender genug Credits hat
77
- from_user_data = get_user_data(from_user_id)
78
- if from_user_data['credits'] < amount:
79
- return jsonify({"type": 4, "data": {"content": "Nicht genug Credits!"}})
80
-
81
- # Transaktion durchführen
82
- update_user_data(from_user_id, {'credits': from_user_data['credits'] - amount})
83
- to_user_data = get_user_data(to_user_id)
84
- update_user_data(to_user_id, {'credits': to_user_data['credits'] + amount})
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
- return jsonify({"type": 4, "data": {"content": f"Erfolgreich {amount} Credits an den Benutzer gesendet!"}})
87
-
88
- # c) /daily (Tägliche Belohnung)
 
 
 
 
 
 
89
  def daily_reward(user_id):
90
  """Gives daily reward of 100 credits to the user"""
91
- user_data = get_user_data(user_id)
92
- last_claimed = user_data.get('last_claimed', None)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
- if last_claimed:
95
- if last_claimed.date() == datetime.datetime.now().date():
96
- return jsonify({"type": 4, "data": {"content": "Du hast bereits deine tägliche Belohnung erhalten!"}})
97
 
98
- # Tägliche Belohnung vergeben
99
- new_credits = user_data.get('credits', 0) + 100 # Beispiel für eine tägliche Belohnung
100
- update_user_data(user_id, {'credits': new_credits, 'last_claimed': datetime.datetime.now()})
101
 
102
- return jsonify({"type": 4, "data": {"content": "Du hast deine tägliche Belohnung erhalten: 100 Credits!"}})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from flask import jsonify
 
 
 
 
2
  from datetime import datetime, timedelta
3
 
4
  class BankAccount:
5
  def __init__(self, user_id, balance=0.0, interest_rate=0.0):
6
+ if not isinstance(user_id, (int, str)):
7
+ raise ValueError("user_id muss eine Zahl oder String sein")
8
+ if balance < 0:
9
+ raise ValueError("Startguthaben kann nicht negativ sein")
10
+
11
  self.user_id = user_id
12
+ self.balance = float(balance)
13
+ self.interest_rate = float(interest_rate)
14
  self.last_interest_time = datetime.now()
15
+ self.transaction_history = []
16
+
17
+ def add_transaction(self, transaction_type, amount, description=""):
18
+ transaction = {
19
+ "timestamp": datetime.now(),
20
+ "type": transaction_type,
21
+ "amount": amount,
22
+ "balance_after": self.balance,
23
+ "description": description
24
+ }
25
+ self.transaction_history.append(transaction)
26
 
27
  def deposit(self, amount):
 
28
  if amount <= 0:
29
  raise ValueError("Einzahlungsbetrag muss positiv sein.")
30
  self.balance += amount
31
+ self.add_transaction("deposit", amount)
32
  return self.balance
33
 
34
  def withdraw(self, amount):
 
35
  if amount <= 0:
36
  raise ValueError("Abhebungsbetrag muss positiv sein.")
37
  if amount > self.balance:
38
  raise ValueError("Nicht genügend Geld auf dem Konto.")
39
  self.balance -= amount
40
+ self.add_transaction("withdraw", amount)
41
  return self.balance
42
 
43
  def apply_interest(self):
 
44
  current_time = datetime.now()
45
  time_difference = current_time - self.last_interest_time
46
+
 
47
  if time_difference >= timedelta(days=1):
48
  days_passed = time_difference.days
49
+ old_balance = self.balance
50
+ self.balance *= (1 + self.interest_rate) ** days_passed
51
+ interest_earned = self.balance - old_balance
52
+
53
+ self.add_transaction("interest", interest_earned,
54
+ f"Zinsen für {days_passed} Tage")
55
  self.last_interest_time = current_time
56
+
57
  return self.balance
58
 
59
  def get_balance(self):
 
60
  self.apply_interest()
61
  return self.balance
62
 
63
+ def get_transaction_history(self):
64
+ return self.transaction_history
65
 
66
+ def transfer(self, target_account, amount):
67
+ if not isinstance(target_account, BankAccount):
68
+ raise ValueError("Ungültiges Zielkonto")
69
+ self.withdraw(amount)
70
+ target_account.deposit(amount)
71
+ self.add_transaction("transfer_out", amount, f"Transfer an {target_account.user_id}")
72
+ target_account.add_transaction("transfer_in", amount, f"Transfer von {self.user_id}")
 
73
 
74
+ def format_balance(self):
75
+ return f"{self.balance:,.2f} Credits"
 
76
 
77
+ class BankSystem:
78
+ def __init__(self):
79
+ self.accounts = {}
80
+
81
+ def create_account(self, user_id, initial_balance=0.0, interest_rate=0.05):
82
+ if user_id in self.accounts:
83
+ raise ValueError("Konto existiert bereits")
84
+ account = BankAccount(user_id, initial_balance, interest_rate)
85
+ self.accounts[user_id] = account
86
+ return account
87
+
88
+ def get_account(self, user_id):
89
+ return self.accounts.get(user_id)
90
+
91
+ def transfer_between_accounts(self, from_user_id, to_user_id, amount):
92
+ from_account = self.get_account(from_user_id)
93
+ to_account = self.get_account(to_user_id)
94
+ if not from_account or not to_account:
95
+ raise ValueError("Ein oder beide Konten existieren nicht")
96
+ from_account.transfer(to_account, amount)
97
 
 
98
  def send_money_command(from_user_id, to_user_id, amount):
99
  if amount <= 0:
100
  return jsonify({"type": 4, "data": {"content": "Ungültiger Betrag!"}})
101
 
102
+ try:
103
+ # Überprüfe, ob der Absender genug Credits hat
104
+ from_user_data = get_user_data(from_user_id)
105
+ if from_user_data['credits'] < amount:
106
+ return jsonify({"type": 4, "data": {"content": "Nicht genug Credits!"}})
107
+
108
+ # Transaktion durchführen
109
+ update_user_data(from_user_id, {'credits': from_user_data['credits'] - amount})
110
+ to_user_data = get_user_data(to_user_id)
111
+ update_user_data(to_user_id, {'credits': to_user_data['credits'] + amount})
112
+
113
+ # Transaktion in History dokumentieren
114
+ transaction_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
115
+ log_transaction(from_user_id, to_user_id, amount, transaction_time)
116
+
117
+ return jsonify({
118
+ "type": 4,
119
+ "data": {
120
+ "content": f"Erfolgreich {amount:,.2f} Credits an den Benutzer {to_user_id} gesendet!"
121
+ }
122
+ })
123
 
124
+ except Exception as e:
125
+ logging.error(f"Fehler bei der Überweisung: {str(e)}")
126
+ return jsonify({
127
+ "type": 4,
128
+ "data": {
129
+ "content": "Ein Fehler ist bei der Überweisung aufgetreten!"
130
+ }
131
+ })
132
+
133
  def daily_reward(user_id):
134
  """Gives daily reward of 100 credits to the user"""
135
+ try:
136
+ user_data = get_user_data(user_id)
137
+ last_claimed = user_data.get('last_claimed', None)
138
+
139
+ if last_claimed:
140
+ last_claimed_date = datetime.fromisoformat(str(last_claimed))
141
+ if last_claimed_date.date() == datetime.now().date():
142
+ return jsonify({
143
+ "type": 4,
144
+ "data": {
145
+ "content": "Du hast bereits deine tägliche Belohnung erhalten!"
146
+ }
147
+ })
148
+
149
+ # Zufällige Belohnung zwischen 50 und 150 Credits
150
+ reward_amount = random.randint(50, 150)
151
+ new_credits = user_data.get('credits', 0) + reward_amount
152
+
153
+ # Update user data
154
+ update_user_data(user_id, {
155
+ 'credits': new_credits,
156
+ 'last_claimed': datetime.now()
157
+ })
158
+
159
+ return jsonify({
160
+ "type": 4,
161
+ "data": {
162
+ "content": f"Du hast deine tägliche Belohnung erhalten: {reward_amount} Credits!"
163
+ }
164
+ })
165
+
166
+ except Exception as e:
167
+ logging.error(f"Fehler bei der täglichen Belohnung: {str(e)}")
168
+ return jsonify({
169
+ "type": 4,
170
+ "data": {
171
+ "content": "Ein Fehler ist beim Abholen der täglichen Belohnung aufgetreten!"
172
+ }
173
+ })
174
+
175
+ # Hilfsfunktionen (müssen implementiert werden)
176
+ def get_user_data(user_id):
177
+ """Implementiere diese Funktion, um Benutzerdaten aus der Datenbank zu holen"""
178
+ pass
179
+
180
+ def update_user_data(user_id, data):
181
+ """Implementiere diese Funktion, um Benutzerdaten in der Datenbank zu aktualisieren"""
182
+ pass
183
+ def log_transaction(from_user_id, to_user_id, amount, timestamp):
184
+ """Implementiere diese Funktion, um Transaktionen in einem Log festzuhalten"""
185
+ try:
186
+ transaction_log = {
187
+ "from_user": from_user_id,
188
+ "to_user": to_user_id,
189
+ "amount": amount,
190
+ "timestamp": timestamp,
191
+ "transaction_id": generate_transaction_id()
192
+ }
193
+
194
+ # Hier könnte die Speicherung in einer Datenbank erfolgen
195
+ save_transaction_to_db(transaction_log)
196
+
197
+ logging.info(f"Transaktion erfolgreich protokolliert: {transaction_log}")
198
+ return True
199
+
200
+ except Exception as e:
201
+ logging.error(f"Fehler beim Protokollieren der Transaktion: {str(e)}")
202
+ return False
203
+
204
+ def generate_transaction_id():
205
+ """Generiert eine einzigartige Transaktions-ID"""
206
+ timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
207
+ random_suffix = ''.join(random.choices('0123456789ABCDEF', k=6))
208
+ return f"TRX-{timestamp}-{random_suffix}"
209
+
210
+ def save_transaction_to_db(transaction_data):
211
+ """Implementiere diese Funktion zur Speicherung in der Datenbank"""
212
+ pass
213
+
214
+ def get_user_transaction_history(user_id):
215
+ """Gibt die Transaktionshistorie eines Benutzers zurück"""
216
+ try:
217
+ # Implementiere hier die Datenbankabfrage
218
+ transactions = [] # Hole Transaktionen aus der Datenbank
219
+ return jsonify({
220
+ "type": 4,
221
+ "data": {
222
+ "content": "Transaktionshistorie",
223
+ "transactions": transactions
224
+ }
225
+ })
226
+ except Exception as e:
227
+ logging.error(f"Fehler beim Abrufen der Transaktionshistorie: {str(e)}")
228
+ return jsonify({
229
+ "type": 4,
230
+ "data": {
231
+ "content": "Fehler beim Abrufen der Transaktionshistorie"
232
+ }
233
+ })
234
+
235
+ def check_account_status(user_id):
236
+ """Überprüft den Status eines Bankkontos"""
237
+ try:
238
+ user_data = get_user_data(user_id)
239
+ account = BankAccount(user_id, user_data.get('credits', 0))
240
+
241
+ status_info = {
242
+ "balance": account.format_balance(),
243
+ "last_transaction": user_data.get('last_transaction'),
244
+ "account_age": calculate_account_age(user_data.get('created_at')),
245
+ "interest_rate": f"{account.interest_rate * 100}%"
246
+ }
247
+
248
+ return jsonify({
249
+ "type": 4,
250
+ "data": {
251
+ "content": "Kontostatus",
252
+ "status": status_info
253
+ }
254
+ })
255
+ except Exception as e:
256
+ logging.error(f"Fehler beim Abrufen des Kontostatus: {str(e)}")
257
+ return jsonify({
258
+ "type": 4,
259
+ "data": {
260
+ "content": "Fehler beim Abrufen des Kontostatus"
261
+ }
262
+ })
263
+
264
+ def calculate_account_age(created_at):
265
+ """Berechnet das Alter eines Kontos"""
266
+ if not created_at:
267
+ return "Unbekannt"
268
+
269
+ created_date = datetime.fromisoformat(str(created_at))
270
+ age = datetime.now() - created_date
271
+ return f"{age.days} Tage"
272
+
273
+ # Error Handler
274
+ def handle_transaction_error(error_type, message):
275
+ """Zentrale Fehlerbehandlung für Transaktionen"""
276
+ logging.error(f"Transaktionsfehler: {error_type} - {message}")
277
+ return jsonify({
278
+ "type": 4,
279
+ "data": {
280
+ "content": f"Ein Fehler ist aufgetreten: {message}",
281
+ "error_type": error_type,
282
+ "timestamp": datetime.now().isoformat()
283
+ }
284
+ })
285
+
286
+ class TransactionError(Exception):
287
+ """Benutzerdefinierte Exception für Transaktionsfehler"""
288
+ def __init__(self, message, error_type="TRANSACTION_ERROR"):
289
+ self.message = message
290
+ self.error_type = error_type
291
+ super().__init__(self.message)
292
+
293
+ # Hilfreiche Utility-Funktionen
294
+ def validate_transaction(from_user_id, to_user_id, amount):
295
+ """Überprüft, ob eine Transaktion gültig ist"""
296
+ if from_user_id == to_user_id:
297
+ raise TransactionError("Selbstüberweisung nicht möglich", "SELF_TRANSACTION_ERROR")
298
 
299
+ if amount <= 0:
300
+ raise TransactionError("Ungültiger Betrag", "INVALID_AMOUNT_ERROR")
 
301
 
302
+ if not isinstance(amount, (int, float)):
303
+ raise TransactionError("Betrag muss eine Zahl sein", "INVALID_TYPE_ERROR")
 
304
 
305
+ return True
306
+
307
+ def format_currency(amount):
308
+ """Formatiert einen Geldbetrag"""
309
+ return f"{amount:,.2f} Credits"
310
+
311
+ def get_account_summary(user_id):
312
+ """Erstellt eine Zusammenfassung des Kontos"""
313
+ try:
314
+ account = get_user_data(user_id)
315
+ if not account:
316
+ raise TransactionError("Konto nicht gefunden", "ACCOUNT_NOT_FOUND")
317
+
318
+ return {
319
+ "user_id": user_id,
320
+ "balance": format_currency(account.get('credits', 0)),
321
+ "last_transaction": account.get('last_transaction'),
322
+ "account_status": "aktiv" if account.get('is_active', True) else "inaktiv",
323
+ "created_at": account.get('created_at'),
324
+ "last_daily_claim": account.get('last_claimed')
325
+ }
326
+ except Exception as e:
327
+ logging.error(f"Fehler beim Erstellen der Kontozusammenfassung: {str(e)}")
328
+ raise
329
+
330
+ # Initialisierung des Logging-Systems
331
+ def setup_logging():
332
+ """Konfiguriert das Logging-System"""
333
+ logging.basicConfig(
334
+ level=logging.INFO,
335
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
336
+ handlers=[
337
+ logging.FileHandler('bank_transactions.log'),
338
+ logging.StreamHandler()
339
+ ]
340
+ )
341
+
342
+ # Hauptfunktion zum Starten des Bank-Systems
343
+ def initialize_bank_system():
344
+ """Initialisiert das Bank-System"""
345
+ try:
346
+ setup_logging()
347
+ logging.info("Bank-System wird gestartet...")
348
+ bank_system = BankSystem()
349
+ logging.info("Bank-System erfolgreich initialisiert")
350
+ return bank_system
351
+ except Exception as e:
352
+ logging.error(f"Fehler beim Initialisieren des Bank-Systems: {str(e)}")
353
+ raise
354
+
355
+ if __name__ == "__main__":
356
+ try:
357
+ bank_system = initialize_bank_system()
358
+ logging.info("Bank-System läuft und ist bereit")
359
+ except Exception as e:
360
+ logging.critical(f"Kritischer Fehler beim Starten des Bank-Systems: {str(e)}")