File size: 12,932 Bytes
1a5fbd2
 
 
 
 
ce4657d
 
 
 
 
1a5fbd2
ce4657d
 
1a5fbd2
ce4657d
 
 
 
 
 
 
 
 
 
 
1a5fbd2
 
 
 
 
ce4657d
1a5fbd2
 
 
 
 
 
 
 
ce4657d
1a5fbd2
 
 
 
 
ce4657d
1a5fbd2
 
ce4657d
 
 
 
 
 
1a5fbd2
ce4657d
1a5fbd2
 
 
 
 
 
ce4657d
 
1a5fbd2
ce4657d
 
 
 
 
 
 
1a5fbd2
ce4657d
 
1a5fbd2
ce4657d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a5fbd2
 
 
 
 
ce4657d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a5fbd2
ce4657d
 
 
 
 
 
 
 
 
1a5fbd2
 
ce4657d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a5fbd2
ce4657d
 
1a5fbd2
ce4657d
 
1a5fbd2
ce4657d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
from flask import jsonify
from datetime import datetime, timedelta

class BankAccount:
    def __init__(self, user_id, balance=0.0, interest_rate=0.0):
        if not isinstance(user_id, (int, str)):
            raise ValueError("user_id muss eine Zahl oder String sein")
        if balance < 0:
            raise ValueError("Startguthaben kann nicht negativ sein")
        
        self.user_id = user_id
        self.balance = float(balance)
        self.interest_rate = float(interest_rate)
        self.last_interest_time = datetime.now()
        self.transaction_history = []

    def add_transaction(self, transaction_type, amount, description=""):
        transaction = {
            "timestamp": datetime.now(),
            "type": transaction_type,
            "amount": amount,
            "balance_after": self.balance,
            "description": description
        }
        self.transaction_history.append(transaction)

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Einzahlungsbetrag muss positiv sein.")
        self.balance += amount
        self.add_transaction("deposit", amount)
        return self.balance

    def withdraw(self, amount):
        if amount <= 0:
            raise ValueError("Abhebungsbetrag muss positiv sein.")
        if amount > self.balance:
            raise ValueError("Nicht genügend Geld auf dem Konto.")
        self.balance -= amount
        self.add_transaction("withdraw", amount)
        return self.balance

    def apply_interest(self):
        current_time = datetime.now()
        time_difference = current_time - self.last_interest_time
        
        if time_difference >= timedelta(days=1):
            days_passed = time_difference.days
            old_balance = self.balance
            self.balance *= (1 + self.interest_rate) ** days_passed
            interest_earned = self.balance - old_balance
            
            self.add_transaction("interest", interest_earned, 
                               f"Zinsen für {days_passed} Tage")
            self.last_interest_time = current_time
        
        return self.balance

    def get_balance(self):
        self.apply_interest()
        return self.balance

    def get_transaction_history(self):
        return self.transaction_history

    def transfer(self, target_account, amount):
        if not isinstance(target_account, BankAccount):
            raise ValueError("Ungültiges Zielkonto")
        self.withdraw(amount)
        target_account.deposit(amount)
        self.add_transaction("transfer_out", amount, f"Transfer an {target_account.user_id}")
        target_account.add_transaction("transfer_in", amount, f"Transfer von {self.user_id}")

    def format_balance(self):
        return f"{self.balance:,.2f} Credits"

class BankSystem:
    def __init__(self):
        self.accounts = {}
        
    def create_account(self, user_id, initial_balance=0.0, interest_rate=0.05):
        if user_id in self.accounts:
            raise ValueError("Konto existiert bereits")
        account = BankAccount(user_id, initial_balance, interest_rate)
        self.accounts[user_id] = account
        return account
    
    def get_account(self, user_id):
        return self.accounts.get(user_id)
    
    def transfer_between_accounts(self, from_user_id, to_user_id, amount):
        from_account = self.get_account(from_user_id)
        to_account = self.get_account(to_user_id)
        if not from_account or not to_account:
            raise ValueError("Ein oder beide Konten existieren nicht")
        from_account.transfer(to_account, amount)

def send_money_command(from_user_id, to_user_id, amount):
    if amount <= 0:
        return jsonify({"type": 4, "data": {"content": "Ungültiger Betrag!"}})
    
    try:
        # Überprüfe, ob der Absender genug Credits hat
        from_user_data = get_user_data(from_user_id)
        if from_user_data['credits'] < amount:
            return jsonify({"type": 4, "data": {"content": "Nicht genug Credits!"}})
        
        # Transaktion durchführen
        update_user_data(from_user_id, {'credits': from_user_data['credits'] - amount})
        to_user_data = get_user_data(to_user_id)
        update_user_data(to_user_id, {'credits': to_user_data['credits'] + amount})
        
        # Transaktion in History dokumentieren
        transaction_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_transaction(from_user_id, to_user_id, amount, transaction_time)
        
        return jsonify({
            "type": 4, 
            "data": {
                "content": f"Erfolgreich {amount:,.2f} Credits an den Benutzer {to_user_id} gesendet!"
            }
        })
    
    except Exception as e:
        logging.error(f"Fehler bei der Überweisung: {str(e)}")
        return jsonify({
            "type": 4, 
            "data": {
                "content": "Ein Fehler ist bei der Überweisung aufgetreten!"
            }
        })

def daily_reward(user_id):
    """Gives daily reward of 100 credits to the user"""
    try:
        user_data = get_user_data(user_id)
        last_claimed = user_data.get('last_claimed', None)
        
        if last_claimed:
            last_claimed_date = datetime.fromisoformat(str(last_claimed))
            if last_claimed_date.date() == datetime.now().date():
                return jsonify({
                    "type": 4, 
                    "data": {
                        "content": "Du hast bereits deine tägliche Belohnung erhalten!"
                    }
                })
        
        # Zufällige Belohnung zwischen 50 und 150 Credits
        reward_amount = random.randint(50, 150)
        new_credits = user_data.get('credits', 0) + reward_amount
        
        # Update user data
        update_user_data(user_id, {
            'credits': new_credits,
            'last_claimed': datetime.now()
        })
        
        return jsonify({
            "type": 4,
            "data": {
                "content": f"Du hast deine tägliche Belohnung erhalten: {reward_amount} Credits!"
            }
        })
    
    except Exception as e:
        logging.error(f"Fehler bei der täglichen Belohnung: {str(e)}")
        return jsonify({
            "type": 4,
            "data": {
                "content": "Ein Fehler ist beim Abholen der täglichen Belohnung aufgetreten!"
            }
        })

# Hilfsfunktionen (müssen implementiert werden)
def get_user_data(user_id):
    """Implementiere diese Funktion, um Benutzerdaten aus der Datenbank zu holen"""
    pass

def update_user_data(user_id, data):
    """Implementiere diese Funktion, um Benutzerdaten in der Datenbank zu aktualisieren"""
    pass
def log_transaction(from_user_id, to_user_id, amount, timestamp):
    """Implementiere diese Funktion, um Transaktionen in einem Log festzuhalten"""
    try:
        transaction_log = {
            "from_user": from_user_id,
            "to_user": to_user_id,
            "amount": amount,
            "timestamp": timestamp,
            "transaction_id": generate_transaction_id()
        }
        
        # Hier könnte die Speicherung in einer Datenbank erfolgen
        save_transaction_to_db(transaction_log)
        
        logging.info(f"Transaktion erfolgreich protokolliert: {transaction_log}")
        return True
    
    except Exception as e:
        logging.error(f"Fehler beim Protokollieren der Transaktion: {str(e)}")
        return False

def generate_transaction_id():
    """Generiert eine einzigartige Transaktions-ID"""
    timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
    random_suffix = ''.join(random.choices('0123456789ABCDEF', k=6))
    return f"TRX-{timestamp}-{random_suffix}"

def save_transaction_to_db(transaction_data):
    """Implementiere diese Funktion zur Speicherung in der Datenbank"""
    pass

def get_user_transaction_history(user_id):
    """Gibt die Transaktionshistorie eines Benutzers zurück"""
    try:
        # Implementiere hier die Datenbankabfrage
        transactions = []  # Hole Transaktionen aus der Datenbank
        return jsonify({
            "type": 4,
            "data": {
                "content": "Transaktionshistorie",
                "transactions": transactions
            }
        })
    except Exception as e:
        logging.error(f"Fehler beim Abrufen der Transaktionshistorie: {str(e)}")
        return jsonify({
            "type": 4,
            "data": {
                "content": "Fehler beim Abrufen der Transaktionshistorie"
            }
        })

def check_account_status(user_id):
    """Überprüft den Status eines Bankkontos"""
    try:
        user_data = get_user_data(user_id)
        account = BankAccount(user_id, user_data.get('credits', 0))
        
        status_info = {
            "balance": account.format_balance(),
            "last_transaction": user_data.get('last_transaction'),
            "account_age": calculate_account_age(user_data.get('created_at')),
            "interest_rate": f"{account.interest_rate * 100}%"
        }
        
        return jsonify({
            "type": 4,
            "data": {
                "content": "Kontostatus",
                "status": status_info
            }
        })
    except Exception as e:
        logging.error(f"Fehler beim Abrufen des Kontostatus: {str(e)}")
        return jsonify({
            "type": 4,
            "data": {
                "content": "Fehler beim Abrufen des Kontostatus"
            }
        })

def calculate_account_age(created_at):
    """Berechnet das Alter eines Kontos"""
    if not created_at:
        return "Unbekannt"
    
    created_date = datetime.fromisoformat(str(created_at))
    age = datetime.now() - created_date
    return f"{age.days} Tage"

# Error Handler
def handle_transaction_error(error_type, message):
    """Zentrale Fehlerbehandlung für Transaktionen"""
    logging.error(f"Transaktionsfehler: {error_type} - {message}")
    return jsonify({
        "type": 4,
        "data": {
            "content": f"Ein Fehler ist aufgetreten: {message}",
            "error_type": error_type,
            "timestamp": datetime.now().isoformat()
        }
    })

class TransactionError(Exception):
    """Benutzerdefinierte Exception für Transaktionsfehler"""
    def __init__(self, message, error_type="TRANSACTION_ERROR"):
        self.message = message
        self.error_type = error_type
        super().__init__(self.message)

# Hilfreiche Utility-Funktionen
def validate_transaction(from_user_id, to_user_id, amount):
    """Überprüft, ob eine Transaktion gültig ist"""
    if from_user_id == to_user_id:
        raise TransactionError("Selbstüberweisung nicht möglich", "SELF_TRANSACTION_ERROR")
    
    if amount <= 0:
        raise TransactionError("Ungültiger Betrag", "INVALID_AMOUNT_ERROR")
    
    if not isinstance(amount, (int, float)):
        raise TransactionError("Betrag muss eine Zahl sein", "INVALID_TYPE_ERROR")
    
    return True

def format_currency(amount):
    """Formatiert einen Geldbetrag"""
    return f"{amount:,.2f} Credits"

def get_account_summary(user_id):
    """Erstellt eine Zusammenfassung des Kontos"""
    try:
        account = get_user_data(user_id)
        if not account:
            raise TransactionError("Konto nicht gefunden", "ACCOUNT_NOT_FOUND")
        
        return {
            "user_id": user_id,
            "balance": format_currency(account.get('credits', 0)),
            "last_transaction": account.get('last_transaction'),
            "account_status": "aktiv" if account.get('is_active', True) else "inaktiv",
            "created_at": account.get('created_at'),
            "last_daily_claim": account.get('last_claimed')
        }
    except Exception as e:
        logging.error(f"Fehler beim Erstellen der Kontozusammenfassung: {str(e)}")
        raise

# Initialisierung des Logging-Systems
def setup_logging():
    """Konfiguriert das Logging-System"""
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.FileHandler('bank_transactions.log'),
            logging.StreamHandler()
        ]
    )

# Hauptfunktion zum Starten des Bank-Systems
def initialize_bank_system():
    """Initialisiert das Bank-System"""
    try:
        setup_logging()
        logging.info("Bank-System wird gestartet...")
        bank_system = BankSystem()
        logging.info("Bank-System erfolgreich initialisiert")
        return bank_system
    except Exception as e:
        logging.error(f"Fehler beim Initialisieren des Bank-Systems: {str(e)}")
        raise

if __name__ == "__main__":
    try:
        bank_system = initialize_bank_system()
        logging.info("Bank-System läuft und ist bereit")
    except Exception as e:
        logging.critical(f"Kritischer Fehler beim Starten des Bank-Systems: {str(e)}")