new module AKTIEN - see README.md for details V.2.0
This commit is contained in:
parent
c927cb5b5c
commit
d47b84fa22
20 changed files with 1231 additions and 11 deletions
17
README.md
17
README.md
|
|
@ -1,6 +1,23 @@
|
|||
# FSCash
|
||||
|
||||
Dokumentiere Ausgaben on-the-go als Webapp
|
||||
& behalte den Überblick über Dein Aktiendepot
|
||||
|
||||
## ToDo
|
||||
|
||||
- [ ] Zusammenfassen von mehreren Einträgen zu einer Aktie
|
||||
- [ ] Prüfen ob APIKEYS leer sind und ggfs die Aktualisierung ausblenden
|
||||
|
||||
## V.2.0
|
||||
|
||||
- [X] neue Haupt-Funktion: Aktien zeigt eine Liste mit gespeicherten, zu beobachtenden Aktien
|
||||
- [X] Die Tabelle errechnet automatisch den aktuellen Gewinn oder Verluststand jeder Aktieneintragung
|
||||
- [X] neue Aktie hinzufügen mit Kaufdatum und Kaufpreis, wird je Benutzer separat hinterlegt (user_id)
|
||||
- [X] es KANN eine ISIN oder WKN eingetragen werden
|
||||
- [X] Beim Abruf von aktuellen Kursdaten muss vorher ein API Key von https://www.alphavantage.co/support/#api-key beantragt werden.
|
||||
- [X] Suchen von Symbolen passend zur ISIN geht über einen API Key von https://www.openfigi.com/user/signup
|
||||
- [X] Alternativ kann auch nach dem Aktiennamen bei alphavantage gesucht werden - dafür muss man auf den Namen klicken
|
||||
- [X] Aktien können geändert und gelöscht werden.
|
||||
|
||||
## V.1.2
|
||||
|
||||
|
|
|
|||
132
html/.Trash-1000/files/aktien2.php
Normal file
132
html/.Trash-1000/files/aktien2.php
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
require 'config.php';
|
||||
error_log('Session user_id: ' . (isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 'nicht gesetzt'));
|
||||
// 1. Session-Prüfung (nur für geschützte Seiten)
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Ab hier: Nur für angemeldete Benutzer
|
||||
error_log($_SESSION['user_id']);
|
||||
|
||||
// Prüfen, ob die user_id im Admin-Array ist
|
||||
if (in_array($_SESSION['user_id'], $admin_ids, true)) {
|
||||
$is_admin = "true";
|
||||
}
|
||||
// Prüfen, ob die user_id im Aktien-Array ist
|
||||
if (in_array($_SESSION['user_id'], $aktien_ids, true)) {
|
||||
$is_aktien = "true";
|
||||
}
|
||||
|
||||
// Aktuelles Jahr und Monat ermitteln, ggf. aus GET-Parametern
|
||||
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
|
||||
$month = isset($_GET['month']) ? (int)$_GET['month'] : (int)date('m');
|
||||
|
||||
// Monats- und Jahresgrenzen prüfen und anpassen
|
||||
if ($month < 1) {
|
||||
$month = 12;
|
||||
$year--;
|
||||
} elseif ($month > 12) {
|
||||
$month = 1;
|
||||
$year++;
|
||||
}
|
||||
|
||||
// Daten abrufen
|
||||
$sql="SELECT
|
||||
id,
|
||||
WKNISIN,
|
||||
Aktie,
|
||||
kaufdatum,
|
||||
kaufpreis,
|
||||
anzahl,
|
||||
(kaufpreis * anzahl) AS Kaufsumme
|
||||
FROM
|
||||
aktien;
|
||||
";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([
|
||||
'year' => $year,
|
||||
'month' => $month
|
||||
]);
|
||||
$entries = $stmt->fetchAll();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<title>FSCash - Dashboard</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Navigation -->
|
||||
<nav class="nav">
|
||||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<?php if ($is_aktien === "true") echo '<li><a href="aktien.php">Aktien</a></li>'; ?>
|
||||
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
|
||||
<li><a href="rep-month.php">Report Monat</a></li>
|
||||
<li><a href="rep-person.php">Report Personen</a></li>
|
||||
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
|
||||
</ul>
|
||||
<!-- Container für die rechten Buttons -->
|
||||
<div class="nav-right">
|
||||
<a href="?year=<?= $year ?>&month=<?= $month - 1 ?>" class="nav-button"> < </a>
|
||||
<a href="?year=<?= $year ?>&month=<?= $month + 1 ?>" class="nav-button"> > </a>
|
||||
<a href="logout.php" class="logout">Logout</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<h2><?= strftime('%B %Y', mktime(0, 0, 0, $month, 1, $year)) ?></h2>
|
||||
|
||||
<!-- Tabelle -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>WKN/ISIN</th>
|
||||
<th>Aktie</th>
|
||||
<th>Kaufdatum</th>
|
||||
<th>Kaufpreis</th>
|
||||
<th>Anzahl</th>
|
||||
<th>Kaufsumme</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($entries as $entry): ?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($entry['id']) ?></td>
|
||||
<td><?= htmlspecialchars($entry['WKNISIN']) ?></td>
|
||||
<td><?= htmlspecialchars($entry['Aktie']) ?></td>
|
||||
<td><?= htmlspecialchars($entry['kaufdatum']) ?></td>
|
||||
<td class="align-right"><?= htmlspecialchars(number_format($entry['kaufpreis'], 2, ',', '.')) ?></td>
|
||||
<td class="align-right"><?= htmlspecialchars(number_format($entry['anzahl'], 4, ',', '.')) ?></td>
|
||||
<td class="align-right"><?= htmlspecialchars(number_format($entry['kaufpreis'] * $entry['anzahl'], 2, ',', '.')) ?></td>
|
||||
<td>
|
||||
<a href="edit_entry.php?id=<?= $entry['id'] ?>">
|
||||
<img class="pencil" src="/assets/img/pencil.png" width="20px" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<!-- Neu-Button -->
|
||||
<a href="new_entry.php" class="btn-xr">+</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Hamburger-Menü-Funktion
|
||||
document.querySelector('.hamburger').addEventListener('click', function() {
|
||||
document.querySelector('.nav-list').classList.toggle('show');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3
html/.Trash-1000/info/aktien2.php.trashinfo
Normal file
3
html/.Trash-1000/info/aktien2.php.trashinfo
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[Trash Info]
|
||||
Path=aktien2.php
|
||||
DeletionDate=2026-02-16T15:16:44
|
||||
397
html/aktien.php
Normal file
397
html/aktien.php
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
<?php
|
||||
require 'config.php';
|
||||
error_log('Session user_id: ' . (isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 'nicht gesetzt'));
|
||||
// 1. Session-Prüfung (nur für geschützte Seiten)
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Ab hier: Nur für angemeldete Benutzer
|
||||
error_log($_SESSION['user_id']);
|
||||
$userid = $_SESSION['user_id'];
|
||||
|
||||
// Prüfen, ob die user_id im Admin-Array ist
|
||||
if (in_array($_SESSION['user_id'], $admin_ids, true)) {
|
||||
$is_admin = "true";
|
||||
}
|
||||
// Prüfen, ob die user_id im Aktien-Array ist
|
||||
if (in_array($_SESSION['user_id'], $aktien_ids, true)) {
|
||||
$is_aktien = "true";
|
||||
}
|
||||
|
||||
// Aktuelles Jahr und Monat ermitteln, ggf. aus GET-Parametern
|
||||
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
|
||||
$month = isset($_GET['month']) ? (int)$_GET['month'] : (int)date('m');
|
||||
|
||||
// Monats- und Jahresgrenzen prüfen und anpassen
|
||||
if ($month < 1) {
|
||||
$month = 12;
|
||||
$year--;
|
||||
} elseif ($month > 12) {
|
||||
$month = 1;
|
||||
$year++;
|
||||
}
|
||||
|
||||
// Daten abrufen
|
||||
$sql="SELECT
|
||||
id,
|
||||
user_id,
|
||||
WKNISIN,
|
||||
Symbol,
|
||||
Aktie,
|
||||
kaufdatum,
|
||||
kaufpreis,
|
||||
anzahl,
|
||||
kurs,
|
||||
kursdatum,
|
||||
(kaufpreis * anzahl) AS Kaufsumme
|
||||
FROM
|
||||
aktien
|
||||
WHERE user_id = :userid;
|
||||
";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([
|
||||
'userid' => $userid
|
||||
]);
|
||||
$entries = $stmt->fetchAll();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<title>FSCash - Dashboard</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Navigation -->
|
||||
<nav class="nav">
|
||||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
|
||||
</ul>
|
||||
<!-- Container für die rechten Buttons -->
|
||||
<div class="nav-right">
|
||||
<a href="#" id="openUpdate" title="Hier klicken, um Kurse zu aktualisieren">
|
||||
<svg class="update" xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21.5 2v6h-6M2.5 22v-6h6M22 11.5a10 10 0 0 1-10 10 10 10 0 0 1-10-10 10 10 0 0 1 10-10 10 10 0 0 1 10 10z"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="logout.php" class="logout">Logout</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- h2><?= strftime('%B %Y', mktime(0, 0, 0, $month, 1, $year)) ?></h2 -->
|
||||
|
||||
<!-- Tabelle -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>ISIN/Symbol</th>
|
||||
<th>Aktie</th>
|
||||
<th>Kaufdatum</th>
|
||||
<th>Kaufpreis</th>
|
||||
<th>Anzahl</th>
|
||||
<th>Kaufsumme</th>
|
||||
<th>Kurs</th>
|
||||
<th>GuV</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php
|
||||
$sumKaufSumme = 0;
|
||||
$sumAktuellerWert = 0;
|
||||
$sumGuV = 0;
|
||||
foreach ($entries as $entry):
|
||||
|
||||
$kaufpreis = (float)$entry['kaufpreis'];
|
||||
$anzahl = (float)$entry['anzahl'];
|
||||
$kaufSumme = $kaufpreis * $anzahl;
|
||||
|
||||
$kurs = isset($entry['kurs']) ? (float)$entry['kurs'] : 0;
|
||||
$kursdatum = $entry['kursdatum'];
|
||||
|
||||
$aktuellerWert = $anzahl * $kurs;
|
||||
$guv = $aktuellerWert - $kaufSumme;
|
||||
$sumKaufSumme += $kaufSumme;
|
||||
$sumAktuellerWert += $aktuellerWert;
|
||||
$sumGuV += $guv;
|
||||
|
||||
$guvClass = '';
|
||||
if ($guv > 0) {
|
||||
$guvClass = 'guv-positive';
|
||||
} elseif ($guv < 0) {
|
||||
$guvClass = 'guv-negative';
|
||||
}
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td><?= htmlspecialchars($entry['id']) ?></td>
|
||||
|
||||
<td class="kurs-cell" style="white-space: nowrap;">
|
||||
<?= htmlspecialchars($entry['WKNISIN']) ?><br>
|
||||
<span style="font-size: inherit;"><?= htmlspecialchars($entry['Symbol']) ?></span>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="#" class="isin-link" data-id="<?= $entry['id'] ?>" data-name="<?= htmlspecialchars($entry['Aktie'], ENT_QUOTES) ?>" title="Hier klicken, um das Symbol zu suchen">
|
||||
<?= htmlspecialchars($entry['Aktie']) ?>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td><?= htmlspecialchars($entry['kaufdatum']) ?></td>
|
||||
|
||||
<td class="align-right">
|
||||
<?= number_format($kaufpreis, 2, ',', '.') ?>
|
||||
</td>
|
||||
|
||||
<td class="align-right">
|
||||
<?= number_format($anzahl, 4, ',', '.') ?>
|
||||
</td>
|
||||
|
||||
<td class="align-right">
|
||||
<?= number_format($kaufSumme, 2, ',', '.') ?>
|
||||
</td>
|
||||
|
||||
<td class="align-right kurs-cell">
|
||||
<?php if ($kurs > 0): ?>
|
||||
<?= number_format($kurs, 2, ',', '.') ?><br>
|
||||
<span class="kurs-datum"><?= htmlspecialchars($kursdatum) ?></span>
|
||||
<?php else: ?>
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<td class="align-right kurs-cell">
|
||||
|
||||
<?php if ($kurs > 0): ?>
|
||||
|
||||
<!-- Aktueller Gesamtwert -->
|
||||
<?= number_format($aktuellerWert, 2, ',', '.') ?><br>
|
||||
|
||||
<!-- Gewinn / Verlust -->
|
||||
<span class="<?= $guvClass ?>">
|
||||
<?= number_format($guv, 2, ',', '.') ?>
|
||||
</span>
|
||||
|
||||
<?php else: ?>
|
||||
-
|
||||
<?php endif; ?>
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
<a href="edit_aktie.php?id=<?= $entry['id'] ?>">
|
||||
<img class="pencil" src="/assets/img/pencil.png" width="20px" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="sum-row">
|
||||
<td colspan="6" class="align-right"><strong>Summe:</strong></td>
|
||||
|
||||
<td class="align-right">
|
||||
<strong><?= number_format($sumKaufSumme, 2, ',', '.') ?></strong>
|
||||
</td>
|
||||
|
||||
<td></td>
|
||||
|
||||
<td class="align-right">
|
||||
<strong><?= number_format($sumAktuellerWert, 2, ',', '.') ?></strong><br>
|
||||
<span class="<?= $sumGuV > 0 ? 'guv-positive' : ($sumGuV < 0 ? 'guv-negative' : '') ?>">
|
||||
<strong><?= number_format($sumGuV, 2, ',', '.') ?></strong>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<!-- Neu-Button -->
|
||||
<a href="new_aktie.php" class="btn-xr">+</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Modal -->
|
||||
<div id="updateModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h3>Kursaktualisierung</h3>
|
||||
<div id="updateOutput" class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
<button id="closeModal" class="btn">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal für ISIN-Suche -->
|
||||
<div id="isinModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h3>Symbol suchen</h3>
|
||||
<div id="isinOutput" class="modal-body">
|
||||
<p>Lade Ergebnisse...</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="saveSymbol" class="btn">Speichern</button>
|
||||
<button id="closeIsinModal" class="btn">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
|
||||
// Hamburger-Menü
|
||||
const hamburger = document.querySelector('.hamburger');
|
||||
if (hamburger) {
|
||||
hamburger.addEventListener('click', function() {
|
||||
document.querySelector('.nav-list').classList.toggle('show');
|
||||
});
|
||||
}
|
||||
|
||||
// Modal-Elemente
|
||||
const modal = document.getElementById('updateModal');
|
||||
const openBtn = document.getElementById('openUpdate');
|
||||
const closeBtn = document.getElementById('closeModal');
|
||||
const output = document.getElementById('updateOutput');
|
||||
|
||||
if (!modal || !openBtn || !closeBtn || !output) {
|
||||
console.error("Modal-Elemente nicht gefunden!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Modal öffnen + Script laden
|
||||
openBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
modal.style.display = 'flex';
|
||||
output.innerHTML = "Starte Kursaktualisierung...<br>";
|
||||
|
||||
fetch('update_kurse.php')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
output.innerHTML += data.replace(/\n/g, "<br>");
|
||||
output.scrollTop = output.scrollHeight;
|
||||
})
|
||||
.catch(error => {
|
||||
output.innerHTML += "Fehler beim Laden.<br>";
|
||||
});
|
||||
});
|
||||
|
||||
// Modal schließen
|
||||
closeBtn.addEventListener('click', function() {
|
||||
modal.style.display = 'none';
|
||||
location.reload();
|
||||
});
|
||||
|
||||
// Klick außerhalb schließt Modal
|
||||
window.addEventListener('click', function(e) {
|
||||
if (e.target === modal) {
|
||||
modal.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const isinLinks = document.querySelectorAll('.isin-link');
|
||||
const isinModal = document.getElementById('isinModal');
|
||||
const isinOutput = document.getElementById('isinOutput');
|
||||
const closeIsinModal = document.getElementById('closeIsinModal');
|
||||
const saveSymbolBtn = document.getElementById('saveSymbol');
|
||||
|
||||
let selectedEntryId = null;
|
||||
let selectedSymbol = null;
|
||||
|
||||
// ISIN anklicken -> Modal öffnen
|
||||
isinLinks.forEach(link => {
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
selectedEntryId = this.dataset.id;
|
||||
const aktienName = this.dataset.name;
|
||||
isinModal.style.display = 'flex';
|
||||
isinOutput.innerHTML = "Suche Symbole für " + aktienName + "...<br>";
|
||||
|
||||
// API abfragen
|
||||
fetch('search_symbol.php?name=' + encodeURIComponent(aktienName))
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (!data || data.length === 0) {
|
||||
isinOutput.innerHTML = "Keine Ergebnisse gefunden.";
|
||||
return;
|
||||
}
|
||||
// Radioboxen anzeigen
|
||||
let html = '<form id="symbolForm">';
|
||||
data.forEach((item, idx) => {
|
||||
html += `<label>
|
||||
<input type="radio" name="symbol" value="${item.symbol}" ${idx===0 ? 'checked' : ''}>
|
||||
${item.symbol} (${item.name}, ${item.region})
|
||||
</label><br>`;
|
||||
});
|
||||
html += '</form>';
|
||||
isinOutput.innerHTML = html;
|
||||
})
|
||||
.catch(err => {
|
||||
isinOutput.innerHTML = "Fehler bei der Suche.";
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Modal schließen
|
||||
closeIsinModal.addEventListener('click', () => isinModal.style.display = 'none');
|
||||
|
||||
window.addEventListener('click', function(e) {
|
||||
if (e.target === isinModal) {
|
||||
isinModal.style.display = 'none';
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
// Symbol speichern
|
||||
saveSymbolBtn.addEventListener('click', () => {
|
||||
const form = document.getElementById('symbolForm');
|
||||
if (!form) return;
|
||||
const formData = new FormData(form);
|
||||
selectedSymbol = formData.get('symbol');
|
||||
if (!selectedSymbol) return;
|
||||
|
||||
fetch('save_symbol.php', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({ id: selectedEntryId, symbol: selectedSymbol })
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert(data.message);
|
||||
isinModal.style.display = 'none';
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -30,6 +30,35 @@ h1 {
|
|||
color: var(--dark-color);
|
||||
}
|
||||
|
||||
.kurs-cell {
|
||||
font-size: 0.85em;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
||||
.kurs-datum {
|
||||
font-size: 0.75em;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.guv-positive {
|
||||
color: #1a7f37;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.guv-negative {
|
||||
color: #c62828;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sum-row {
|
||||
background-color: #f3f3f3;
|
||||
border-top: 2px solid #999;
|
||||
}
|
||||
|
||||
.sum-row td {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.debug_hidden {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -289,6 +318,15 @@ tr:hover {
|
|||
}
|
||||
}
|
||||
|
||||
.update {
|
||||
color: white;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
/* Button */
|
||||
.btn-xr {
|
||||
position: fixed;
|
||||
|
|
@ -380,7 +418,7 @@ max-height: 0;
|
|||
}
|
||||
|
||||
/* Modal */
|
||||
.modal {
|
||||
.modal-l {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
|
@ -393,7 +431,7 @@ max-height: 0;
|
|||
z-index: 1001;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
.modal-l-content {
|
||||
background: white;
|
||||
padding: 40px;
|
||||
border-radius: var(--border-radius);
|
||||
|
|
@ -405,14 +443,14 @@ max-height: 0;
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.modal-content h2 {
|
||||
.modal-l-content h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.modal-content input[type="text"],
|
||||
.modal-content input[type="password"] {
|
||||
.modal-l-content input[type="text"],
|
||||
.modal-l-content input[type="password"] {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin: 10px 0;
|
||||
|
|
@ -423,13 +461,13 @@ max-height: 0;
|
|||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
.modal-content input[type="text"]:focus,
|
||||
.modal-content input[type="password"]:focus {
|
||||
.modal-l-content input[type="text"]:focus,
|
||||
.modal-l-content input[type="password"]:focus {
|
||||
border-color: var(--primary-color);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.modal-content button {
|
||||
.modal-l-content button {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
background-color: var(--primary-color);
|
||||
|
|
@ -474,6 +512,59 @@ input[type="number"] {
|
|||
.modal-content input[type="password"],
|
||||
.modal-content button {
|
||||
font-size: 14px;
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Modales Fenster 2 */
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: #fff;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
max-width: 1000px;
|
||||
max-height: 800px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background: #f8f8f8;
|
||||
padding: 10px;
|
||||
font-family: monospace;
|
||||
font-size: 14px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
text-align: right;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
background: #333;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
|
|
|||
BIN
html/assets/img/update.png
Normal file
BIN
html/assets/img/update.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
|
|
@ -12,7 +12,14 @@ $charset = 'utf8mb4';
|
|||
|
||||
$selectedCategories = [1, 2, 3]; // Anpassen! Dies sind die Standard-Ketegorien die für rep_person als default angenommen werden.
|
||||
$admin_ids = [1,2];
|
||||
$aktien_ids = [1,2];
|
||||
// Standard: kein Admin, keine Aktien
|
||||
$is_admin = "false";
|
||||
$is_aktien = "false";
|
||||
|
||||
// API Keys
|
||||
$alphaApiKey = '98JPDX06439OYCVD';
|
||||
$openFigiApiKey = '62d16cf8-457d-41a6-83d0-84b26b8d5e6c';
|
||||
|
||||
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
|
||||
$options = [
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ error_log($_SESSION['user_id']);
|
|||
if (in_array($_SESSION['user_id'], $admin_ids, true)) {
|
||||
$is_admin = "true";
|
||||
}
|
||||
// Prüfen, ob die user_id im Aktien-Array ist
|
||||
if (in_array($_SESSION['user_id'], $aktien_ids, true)) {
|
||||
$is_aktien = "true";
|
||||
}
|
||||
|
||||
// Aktuelles Jahr und Monat ermitteln, ggf. aus GET-Parametern
|
||||
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
|
||||
|
|
@ -82,6 +86,7 @@ $entries = $stmt->fetchAll();
|
|||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<?php if ($is_aktien === "true") echo '<li><a href="aktien.php">Aktien</a></li>'; ?>
|
||||
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
|
||||
<li><a href="rep-month.php">Report Monat</a></li>
|
||||
<li><a href="rep-person.php">Report Personen</a></li>
|
||||
|
|
|
|||
161
html/edit_aktie.php
Normal file
161
html/edit_aktie.php
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
require 'config.php';
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Prüfen, ob die ID im GET-Parameter vorhanden ist
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
header('Location: aktien.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$aktie_id = (int)$_GET['id'];
|
||||
$aktie = null;
|
||||
$data_saved = "nix";
|
||||
|
||||
// Daten des Eintrags laden
|
||||
try {
|
||||
$stmtAktie = $pdo->prepare("
|
||||
SELECT * FROM aktien
|
||||
WHERE id = :id
|
||||
");
|
||||
$stmtAktie->bindParam(':id', $aktie_id, PDO::PARAM_INT);
|
||||
$stmtAktie->execute();
|
||||
$aktie = $stmtAktie->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$aktie) {
|
||||
header('Location: aktien.php');
|
||||
exit;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$data_saved = "Fehler: Aktie konnte nicht geladen werden.";
|
||||
}
|
||||
|
||||
// Lösch-Logik
|
||||
if (isset($_POST['delete'])) {
|
||||
try {
|
||||
$stmt = $pdo->prepare("DELETE FROM aktien WHERE id = :id");
|
||||
$stmt->bindParam(':id', $aktie_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
echo '<meta http-equiv="refresh" content="5;url=aktien.php">Aktie wurde gelöscht. Weiterleitung…'; exit;
|
||||
} catch (PDOException $e) {
|
||||
$data_saved = "Fehler: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// Speicher-Logik
|
||||
if (!empty($_POST) && !isset($_POST['delete'])) {
|
||||
$WKNISIN = isset($_POST['WKNISIN']) ? trim($_POST['WKNISIN']) : '';
|
||||
$Aktie = isset($_POST['Aktie']) ? trim($_POST['Aktie']) : '';
|
||||
$kaufdatum = isset($_POST['kaufdatum']) ? trim($_POST['kaufdatum']) : '';
|
||||
$kaufpreis = isset($_POST['kaufpreis']) ? (float)$_POST['kaufpreis'] : 0.0;
|
||||
$anzahl = isset($_POST['anzahl']) ? (float)$_POST['anzahl'] : 0.0;
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("
|
||||
UPDATE aktien
|
||||
SET
|
||||
WKNISIN = :WKNISIN,
|
||||
Aktie = :Aktie,
|
||||
kaufdatum = :kaufdatum,
|
||||
kaufpreis = :kaufpreis,
|
||||
anzahl = :anzahl
|
||||
WHERE id = :id
|
||||
");
|
||||
$stmt->bindParam(':id', $aktie_id, PDO::PARAM_INT);
|
||||
$stmt->bindParam(':WKNISIN', $WKNISIN);
|
||||
$stmt->bindParam(':Aktie', $Aktie);
|
||||
$stmt->bindParam(':kaufdatum', $kaufdatum);
|
||||
$stmt->bindParam(':kaufpreis', $kaufpreis);
|
||||
$stmt->bindParam(':anzahl', $anzahl);
|
||||
|
||||
$stmt->execute();
|
||||
$data_saved = "true";
|
||||
} catch (PDOException $e) {
|
||||
$data_saved = "Fehler: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<title>Aktie bearbeiten</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<style>
|
||||
.data-notice {
|
||||
display: none;
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
.data-notice.success {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php if ($data_saved == "true"): ?>
|
||||
<div id="data-notice" class="data-notice success">
|
||||
Aktie erfolgreich aktualisiert! Sie werden in 5 Sekunden weitergeleitet ...
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(function() {
|
||||
window.location.href = 'aktien.php';
|
||||
}, 5000);
|
||||
</script>
|
||||
<?php elseif ($data_saved != "nix"): ?>
|
||||
<div id="data-notice" class="data-notice error">
|
||||
<?php echo $data_saved; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav">
|
||||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<li><a href="aktien.php">Aktien</a></li>
|
||||
<li><a href="logout.php" class="logout">Logout</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<form action="edit_aktie.php?id=<?= $aktie_id ?>" method="post" class="form-container">
|
||||
<div class="form-group">
|
||||
<label for="WKNISIN">WKN/ISIN</label>
|
||||
<input type="text" name="WKNISIN" value="<?= htmlspecialchars($aktie['WKNISIN']) ?>" placeholder="WKN oder ISIN" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Aktie">Aktie</label>
|
||||
<input type="text" name="Aktie" value="<?= htmlspecialchars($aktie['Aktie']) ?>" placeholder="Name der Aktie" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="kaufdatum">Kaufdatum</label>
|
||||
<input type="date" name="kaufdatum" value="<?= htmlspecialchars($aktie['kaufdatum']) ?>" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="kaufpreis">Kaufpreis</label>
|
||||
<input type="number" name="kaufpreis" step="0.01" value="<?= htmlspecialchars($aktie['kaufpreis']) ?>" placeholder="Kaufpreis" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="anzahl">Anzahl</label>
|
||||
<input type="number" name="anzahl" step="0.0001" value="<?= htmlspecialchars($aktie['anzahl']) ?>" placeholder="Anzahl" required>
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<button type="submit" name="delete" class="btn-xr1l" style="background-color: #d9534f;">Löschen</button>
|
||||
<button type="submit" class="btn-xr">Speichern</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<script src="assets/js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
63
html/get_symbol.php
Normal file
63
html/get_symbol.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
function get2symbol(string $isin, string $openFigiApiKey): ?string
|
||||
{
|
||||
$url = "https://api.openfigi.com/v3/mapping";
|
||||
|
||||
$postData = json_encode([
|
||||
[
|
||||
"idType" => "ID_ISIN",
|
||||
"idValue" => $isin
|
||||
]
|
||||
]);
|
||||
|
||||
$headers = [
|
||||
"Content-Type: application/json",
|
||||
"X-OPENFIGI-APIKEY: $openFigiApiKey"
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch)) {
|
||||
curl_close($ch);
|
||||
return null;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if (!isset($data[0]['data']) || empty($data[0]['data'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Wir suchen zuerst nach einem Eintrag mit deutschem Handelsplatz (DE)
|
||||
$symbolEntry = null;
|
||||
foreach ($data[0]['data'] as $entry) {
|
||||
if (isset($entry['exchCode']) && $entry['exchCode'] === 'XETR') { // XETR = Deutsche Börse Xetra
|
||||
$symbolEntry = $entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Wenn kein DE/XETR Eintrag gefunden, nehmen wir einfach den ersten
|
||||
if ($symbolEntry === null) {
|
||||
$symbolEntry = $data[0]['data'][0];
|
||||
}
|
||||
|
||||
if (isset($symbolEntry['ticker']) && !empty($symbolEntry['ticker'])) {
|
||||
// Kombiniere Ticker und Exchange, um ein vollständiges Symbol zu liefern
|
||||
$exchange = $symbolEntry['exchCode'] ?? '';
|
||||
return $exchange ? "{$symbolEntry['ticker']}.{$exchange}" : $symbolEntry['ticker'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -43,8 +43,8 @@ Mit der weiteren Nutzung der Webseite erklären Sie sich mit dem Einsatz dieser
|
|||
</div>
|
||||
|
||||
<!-- Modal Login Dialog -->
|
||||
<div id="login-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div id="login-modal" class="modal-l">
|
||||
<div class="modal-l-content">
|
||||
<img src="assets/img/euro.gif"/>
|
||||
<h2>FSCash</h2>
|
||||
<?php if ($error): ?>
|
||||
|
|
|
|||
119
html/new_aktie.php
Normal file
119
html/new_aktie.php
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
require 'config.php';
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<title>Neue Aktie erfassen</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<style>
|
||||
.data-notice {
|
||||
display: none;
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
.data-notice.success {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$data_saved = "nix";
|
||||
$debug = "";
|
||||
$currentDate = date('Y-m-d');
|
||||
|
||||
// save-Logik
|
||||
if (!empty($_POST)) {
|
||||
$WKNISIN = isset($_POST['WKNISIN']) ? trim($_POST['WKNISIN']) : '';
|
||||
$Aktie = isset($_POST['Aktie']) ? trim($_POST['Aktie']) : '';
|
||||
$kaufdatum = isset($_POST['kaufdatum']) ? trim($_POST['kaufdatum']) : '';
|
||||
$kaufpreis = isset($_POST['kaufpreis']) ? (float)$_POST['kaufpreis'] : 0.0;
|
||||
$anzahl = isset($_POST['anzahl']) ? (float)$_POST['anzahl'] : 0.0;
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO aktien (WKNISIN, user_id, Aktie, kaufdatum, kaufpreis, anzahl)
|
||||
VALUES (:WKNISIN, :user_id, :Aktie, :kaufdatum, :kaufpreis, :anzahl)
|
||||
");
|
||||
$stmt->bindParam(':WKNISIN', $WKNISIN);
|
||||
$stmt->bindParam(':Aktie', $Aktie);
|
||||
$stmt->bindParam(':kaufdatum', $kaufdatum);
|
||||
$stmt->bindParam(':kaufpreis', $kaufpreis);
|
||||
$stmt->bindParam(':anzahl', $anzahl);
|
||||
$stmt->bindParam(':user_id', $_SESSION['user_id']);
|
||||
|
||||
$stmt->execute();
|
||||
$data_saved = "true";
|
||||
} catch (PDOException $e) {
|
||||
$data_saved = "Fehler: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<?php if ($data_saved == "true"): ?>
|
||||
<div id="data-notice" class="data-notice success">
|
||||
Aktie erfolgreich gespeichert! Sie werden in 5 Sekunden weitergeleitet ...
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(function() {
|
||||
window.location.href = 'aktien.php';
|
||||
}, 5000);
|
||||
</script>
|
||||
<?php elseif ($data_saved != "nix"): ?>
|
||||
<div id="data-notice" class="data-notice error">
|
||||
<?php echo $data_saved; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="nav">
|
||||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<li><a href="aktien.php">Aktien</a></li>
|
||||
<li><a href="rep-month.php">Report Monat</a></li>
|
||||
<li><a href="logout.php" class="logout">Logout</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<form action="new_aktie.php" method="post" class="form-container">
|
||||
<div class="form-group">
|
||||
<label for="WKNISIN">WKN/ISIN</label>
|
||||
<input type="text" name="WKNISIN" placeholder="WKN oder ISIN" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Aktie">Aktie</label>
|
||||
<input type="text" name="Aktie" placeholder="Name der Aktie" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="kaufdatum">Kaufdatum</label>
|
||||
<input type="date" name="kaufdatum" value="<?php echo $currentDate; ?>" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="kaufpreis">Kaufpreis</label>
|
||||
<input type="number" name="kaufpreis" step="0.01" placeholder="Kaufpreis" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="anzahl">Anzahl</label>
|
||||
<input type="number" name="anzahl" step="0.0001" placeholder="Anzahl" required>
|
||||
</div>
|
||||
<button type="submit" class="btn-xr">Speichern</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<script src="assets/js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -8,6 +8,15 @@ if (!isset($_SESSION['user_id'])) {
|
|||
// echo $_SESSION['user_id'];
|
||||
error_log($_SESSION['user_id']);
|
||||
|
||||
// Prüfen, ob die user_id im Admin-Array ist
|
||||
if (in_array($_SESSION['user_id'], $admin_ids, true)) {
|
||||
$is_admin = "true";
|
||||
}
|
||||
// Prüfen, ob die user_id im Aktien-Array ist
|
||||
if (in_array($_SESSION['user_id'], $aktien_ids, true)) {
|
||||
$is_aktien = "true";
|
||||
}
|
||||
|
||||
|
||||
// Verbindung herstellen
|
||||
$conn = new mysqli($host, $user, $pass, $db);
|
||||
|
|
@ -53,7 +62,7 @@ $conn->close();
|
|||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<li><a href="register.php" style="display: none;">Neue User</a></li>
|
||||
<?php if ($is_aktien === "true") echo '<li><a href="aktien.php">Aktien</a></li>'; ?>
|
||||
<li><a href="rep-month.php">Report Monat</a></li>
|
||||
<li><a href="rep-person.php">Report Personen</a></li>
|
||||
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ if (!isset($_SESSION['user_id'])) {
|
|||
if (in_array($_SESSION['user_id'], $admin_ids, true)) {
|
||||
$is_admin = "true";
|
||||
}
|
||||
// Prüfen, ob die user_id im Aktien-Array ist
|
||||
if (in_array($_SESSION['user_id'], $aktien_ids, true)) {
|
||||
$is_aktien = "true";
|
||||
}
|
||||
|
||||
// Aktuelles Jahr und Monat ermitteln, ggf. aus GET-Parametern
|
||||
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
|
||||
|
|
@ -120,6 +124,7 @@ if (isset($_GET['export']) && $_GET['export'] === 'csv') {
|
|||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<?php if ($is_aktien === "true") echo '<li><a href="aktien.php">Aktien</a></li>'; ?>
|
||||
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
|
||||
<li><a href="rep-person.php">Report Personen</a></li>
|
||||
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ if (!isset($_SESSION['user_id'])) {
|
|||
if (in_array($_SESSION['user_id'], $admin_ids, true)) {
|
||||
$is_admin = "true";
|
||||
}
|
||||
// Prüfen, ob die user_id im Aktien-Array ist
|
||||
if (in_array($_SESSION['user_id'], $aktien_ids, true)) {
|
||||
$is_aktien = "true";
|
||||
}
|
||||
|
||||
// Aktuelles Jahr und Monat ermitteln, ggf. aus GET-Parametern
|
||||
$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
|
||||
|
|
@ -72,6 +76,7 @@ $entries = $stmt->fetchAll();
|
|||
<button class="hamburger">☰</button>
|
||||
<ul class="nav-list">
|
||||
<li><a href="dashboard.php">Start</a></li>
|
||||
<?php if ($is_aktien === "true") echo '<li><a href="aktien.php">Aktien</a></li>'; ?>
|
||||
<?php if ($is_admin === "true") echo '<li><a href="register.php">Neue User</a></li>'; ?>
|
||||
<li><a href="rep-month.php">Report Monat</a></li>
|
||||
<li><a href="menu5.php" style="display: none;">Menüpunkt 5</a></li>
|
||||
|
|
|
|||
45
html/save_symbol.php
Normal file
45
html/save_symbol.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
require 'config.php';
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// JSON-Input einlesen
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
$id = $data['id'] ?? null;
|
||||
$symbol = $data['symbol'] ?? null;
|
||||
|
||||
// Input validieren
|
||||
if (!$id || !$symbol) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Ungültige Eingabedaten.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("UPDATE aktien SET Symbol = :symbol WHERE id = :id AND user_id = :userid");
|
||||
$stmt->execute([
|
||||
'symbol' => $symbol,
|
||||
'id' => $id,
|
||||
'userid' => $_SESSION['user_id']
|
||||
]);
|
||||
|
||||
// Prüfen, ob ein Datensatz tatsächlich aktualisiert wurde
|
||||
if ($stmt->rowCount() > 0) {
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'symbol' => $symbol,
|
||||
'message' => "Symbol erfolgreich gespeichert: $symbol"
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Keine Änderung – evtl. ID existiert nicht oder gehört nicht zum Benutzer.'
|
||||
]);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Datenbankfehler: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
32
html/search_symbol.php
Normal file
32
html/search_symbol.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
require 'config.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($_GET['name'])) {
|
||||
echo json_encode([]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$name = $_GET['name'];
|
||||
$url = 'https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords=' . urlencode($name) . '&apikey=' . $alphaApiKey;
|
||||
|
||||
$response = file_get_contents($url);
|
||||
if (!$response) {
|
||||
echo json_encode([]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = json_decode($response, true);
|
||||
$matches = $data['bestMatches'] ?? [];
|
||||
|
||||
$result = [];
|
||||
foreach ($matches as $match) {
|
||||
$result[] = [
|
||||
'symbol' => $match['1. symbol'],
|
||||
'name' => $match['2. name'],
|
||||
'region' => $match['4. region']
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
101
html/update_kurse.php
Normal file
101
html/update_kurse.php
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
require 'config.php';
|
||||
require 'get_symbol.php';
|
||||
|
||||
|
||||
try {
|
||||
|
||||
// Jetzt auch symbol mit abrufen!
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT id, WKNISIN, symbol
|
||||
FROM aktien
|
||||
WHERE WKNISIN IS NOT NULL
|
||||
");
|
||||
$stmt->execute();
|
||||
$aktien = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($aktien as $aktie) {
|
||||
|
||||
$id = $aktie['id'];
|
||||
$isin = trim($aktie['WKNISIN']);
|
||||
$symbol = $aktie['symbol'];
|
||||
|
||||
// 🔹 Wenn noch kein Symbol vorhanden → über OpenFIGI holen
|
||||
if (empty($symbol)) {
|
||||
|
||||
echo "Hole Symbol für ISIN $isin...\n";
|
||||
|
||||
$symbol = get2symbol($isin, $openFigiApiKey);
|
||||
|
||||
if ($symbol) {
|
||||
|
||||
// Symbol in DB speichern
|
||||
$symbolUpdate = $pdo->prepare("
|
||||
UPDATE aktien
|
||||
SET symbol = :symbol
|
||||
WHERE id = :id
|
||||
");
|
||||
$symbolUpdate->bindParam(':symbol', $symbol);
|
||||
$symbolUpdate->bindParam(':id', $id);
|
||||
$symbolUpdate->execute();
|
||||
|
||||
echo "Symbol $symbol gespeichert.\n";
|
||||
|
||||
// OpenFIGI Limit beachten
|
||||
sleep(1);
|
||||
|
||||
} else {
|
||||
echo "Kein Symbol für ISIN $isin gefunden. Überspringe...\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 🔹 Kurs über Alpha Vantage abrufen
|
||||
$url = "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$symbol&apikey=$alphaApiKey";
|
||||
// echo " rufe: $url";
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$json = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$data = json_decode($json, true);
|
||||
|
||||
if (isset($data['Global Quote']['05. price'])) {
|
||||
|
||||
$kurs = (float)$data['Global Quote']['05. price'];
|
||||
$kursdatum = date('Y-m-d');
|
||||
|
||||
// 🔹 Kurs UND Symbol speichern
|
||||
$updateStmt = $pdo->prepare("
|
||||
UPDATE aktien
|
||||
SET kurs = :kurs,
|
||||
kursdatum = :kursdatum,
|
||||
symbol = :symbol
|
||||
WHERE id = :id
|
||||
");
|
||||
|
||||
$updateStmt->bindParam(':kurs', $kurs);
|
||||
$updateStmt->bindParam(':kursdatum', $kursdatum);
|
||||
$updateStmt->bindParam(':symbol', $symbol);
|
||||
$updateStmt->bindParam(':id', $id);
|
||||
$updateStmt->execute();
|
||||
|
||||
echo "Aktie ID $id ($isin / $symbol): Kurs auf $kurs aktualisiert.\n";
|
||||
|
||||
} else {
|
||||
echo "Kurs für $symbol konnte nicht abgerufen werden.\n";
|
||||
}
|
||||
|
||||
// Alpha Vantage Limit: 5 Anfragen / Minute
|
||||
sleep(13);
|
||||
}
|
||||
|
||||
echo "Kursaktualisierung abgeschlossen.\n";
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo "Datenbankfehler: " . $e->getMessage() . "\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Fehler: " . $e->getMessage() . "\n";
|
||||
}
|
||||
?>
|
||||
15
init.sql
15
init.sql
|
|
@ -56,3 +56,18 @@ INSERT INTO payment_methods (name) VALUES
|
|||
('Bar'),
|
||||
('Karte'),
|
||||
('Paypal');
|
||||
|
||||
CREATE TABLE aktien (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
user_id INT NOT NULL,
|
||||
WKNISIN VARCHAR(20) NOT NULL,
|
||||
Symbol VARCHAR(20) NULL,
|
||||
Aktie VARCHAR(100) NOT NULL,
|
||||
kaufdatum DATE NOT NULL,
|
||||
kaufpreis DECIMAL(10, 2) NOT NULL,
|
||||
anzahl DECIMAL(10, 4) NOT NULL,
|
||||
kursdatum DATE NULL,
|
||||
kurs DECIMAL(10, 2) NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
|
|
|
|||
13
update.sql
13
update.sql
|
|
@ -0,0 +1,13 @@
|
|||
CREATE TABLE aktien (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
user_id INT NOT NULL,
|
||||
WKNISIN VARCHAR(20) NOT NULL,
|
||||
Symbol VARCHAR(20) NULL,
|
||||
Aktie VARCHAR(100) NOT NULL,
|
||||
kaufdatum DATE NOT NULL,
|
||||
kaufpreis DECIMAL(10, 2) NOT NULL,
|
||||
anzahl DECIMAL(10, 4) NOT NULL,
|
||||
kursdatum DATE NULL,
|
||||
kurs DECIMAL(10, 2) NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
Loading…
Add table
Reference in a new issue