- LlmService: Auto-Discovery lokales Ollama + OpenAI-kompatibler Remote-API-Modus - KontierungsvorschlagService: PDF-Textextraktion (pdftotext) + Vision für Bilder - Async-Badge in Beleg-Detailansicht: "Analysiere..." → Formular vorausgefüllt - Einstellung in Settings (default: aus) mit Provider-Status-Anzeige - .env.example: Beispielkonfiguration für beide Provider-Typen (auskommentiert) - Dockerfile: poppler-utils für pdftotext - Migration 011: ki_vorschlag/ki_vorschlag_at in belege, ki_vorschlag_aktiv in settings - Test 11: saveKiVorschlag, JSON-Extraktion, isEnabled-Default
129 lines
8.8 KiB
PHP
129 lines
8.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
define('BASE_DIR', dirname(__DIR__));
|
|
|
|
require BASE_DIR . '/vendor/autoload.php';
|
|
|
|
use Steuerkram\Auth;
|
|
use Steuerkram\Config;
|
|
use Steuerkram\Router;
|
|
use Steuerkram\Controllers\AccountController;
|
|
use Steuerkram\Controllers\BelegController;
|
|
use Steuerkram\Controllers\BookingController;
|
|
use Steuerkram\Controllers\CustomerController;
|
|
use Steuerkram\Controllers\InvoiceController;
|
|
use Steuerkram\Controllers\SupplierController;
|
|
use Steuerkram\Controllers\UstvaController;
|
|
use Steuerkram\Controllers\EuerController;
|
|
use Steuerkram\Controllers\SettingsController;
|
|
use Steuerkram\Controllers\LoginController;
|
|
use Steuerkram\Controllers\UserAdminController;
|
|
|
|
Config::load();
|
|
|
|
$requestPath = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
|
|
if ($requestPath !== '/login') {
|
|
Auth::require();
|
|
}
|
|
|
|
$router = new Router();
|
|
|
|
// ── Dashboard ────────────────────────────────────────────────
|
|
$router->get('/', fn($p) => (new AccountController())->dashboard($p));
|
|
$router->get('/dashboard', fn($p) => (new AccountController())->dashboard($p));
|
|
|
|
// ── Kontenrahmen ─────────────────────────────────────────────
|
|
$router->get('/accounts', fn($p) => (new AccountController())->index($p));
|
|
$router->get('/accounts/new', fn($p) => (new AccountController())->create($p));
|
|
$router->post('/accounts', fn($p) => (new AccountController())->store($p));
|
|
$router->get('/accounts/{id}/edit', fn($p) => (new AccountController())->edit($p));
|
|
$router->post('/accounts/{id}', fn($p) => (new AccountController())->update($p));
|
|
$router->post('/accounts/{id}/delete', fn($p) => (new AccountController())->destroy($p));
|
|
$router->get('/accounts/search', fn($p) => (new AccountController())->search($p));
|
|
|
|
// ── Belege ───────────────────────────────────────────────────
|
|
$router->get('/belege', fn($p) => (new BelegController())->index($p));
|
|
$router->get('/belege/upload', fn($p) => (new BelegController())->uploadForm($p));
|
|
$router->post('/belege/upload', fn($p) => (new BelegController())->upload($p));
|
|
$router->get('/belege/{id}', fn($p) => (new BelegController())->show($p));
|
|
$router->get('/belege/{id}/file', fn($p) => (new BelegController())->serveFile($p));
|
|
$router->post('/belege/{id}/delete', fn($p) => (new BelegController())->destroy($p));
|
|
$router->post('/belege/{id}/meta', fn($p) => (new BelegController())->updateMeta($p));
|
|
$router->post('/belege/{id}/vorschlag/generate', fn($p) => (new BelegController())->generateVorschlag($p));
|
|
$router->post('/belege/{id}/vorschlag/reset', fn($p) => (new BelegController())->resetVorschlag($p));
|
|
|
|
// ── Buchungen ────────────────────────────────────────────────
|
|
$router->get('/journal', fn($p) => (new BookingController())->journal($p));
|
|
$router->get('/journal/export', fn($p) => (new BookingController())->export($p));
|
|
$router->post('/belege/{beleg_id}/bookings', fn($p) => (new BookingController())->store($p));
|
|
$router->post('/bookings/{id}/reverse', fn($p) => (new BookingController())->reverse($p));
|
|
$router->post('/bookings/{id}/delete', fn($p) => (new BookingController())->destroy($p));
|
|
|
|
// ── Lieferanten ──────────────────────────────────────────────
|
|
$router->get('/suppliers', fn($p) => (new SupplierController())->index($p));
|
|
$router->get('/suppliers/new', fn($p) => (new SupplierController())->create($p));
|
|
$router->post('/suppliers', fn($p) => (new SupplierController())->store($p));
|
|
$router->get('/suppliers/search', fn($p) => (new SupplierController())->search($p));
|
|
$router->get('/suppliers/{id}/edit', fn($p) => (new SupplierController())->edit($p));
|
|
$router->post('/suppliers/{id}', fn($p) => (new SupplierController())->update($p));
|
|
$router->post('/suppliers/{id}/delete', fn($p) => (new SupplierController())->destroy($p));
|
|
|
|
// ── Kunden ───────────────────────────────────────────────────
|
|
$router->get('/customers', fn($p) => (new CustomerController())->index($p));
|
|
$router->get('/customers/new', fn($p) => (new CustomerController())->create($p));
|
|
$router->post('/customers', fn($p) => (new CustomerController())->store($p));
|
|
$router->get('/customers/{id}', fn($p) => (new CustomerController())->show($p));
|
|
$router->get('/customers/{id}/edit', fn($p) => (new CustomerController())->edit($p));
|
|
$router->post('/customers/{id}', fn($p) => (new CustomerController())->update($p));
|
|
$router->post('/customers/{id}/archive', fn($p) => (new CustomerController())->archive($p));
|
|
|
|
// ── Rechnungen ───────────────────────────────────────────────
|
|
$router->get('/invoices', fn($p) => (new InvoiceController())->index($p));
|
|
$router->get('/invoices/new', fn($p) => (new InvoiceController())->create($p));
|
|
$router->post('/invoices', fn($p) => (new InvoiceController())->store($p));
|
|
$router->get('/invoices/{id}', fn($p) => (new InvoiceController())->show($p));
|
|
$router->get('/invoices/{id}/edit', fn($p) => (new InvoiceController())->edit($p));
|
|
$router->post('/invoices/{id}', fn($p) => (new InvoiceController())->update($p));
|
|
$router->post('/invoices/{id}/finalize', fn($p) => (new InvoiceController())->finalize($p));
|
|
$router->get('/invoices/{id}/pdf', fn($p) => (new InvoiceController())->pdf($p));
|
|
$router->get('/invoices/{id}/book', fn($p) => (new InvoiceController())->book($p));
|
|
$router->post('/invoices/{id}/bookings', fn($p) => (new InvoiceController())->storeBooking($p));
|
|
$router->post('/invoices/{id}/mark-paid', fn($p) => (new InvoiceController())->markPaid($p));
|
|
$router->post('/invoices/{id}/cancel', fn($p) => (new InvoiceController())->cancel($p));
|
|
$router->post('/invoices/{id}/lines', fn($p) => (new InvoiceController())->addLine($p));
|
|
$router->post('/invoices/{id}/lines/{line_id}/delete', fn($p) => (new InvoiceController())->deleteLine($p));
|
|
|
|
// ── UStVA ────────────────────────────────────────────────────
|
|
$router->get('/tax/ustva', fn($p) => (new UstvaController())->index($p));
|
|
$router->get('/tax/ustva/{year}/{month}', fn($p) => (new UstvaController())->show($p));
|
|
$router->post('/tax/ustva/{year}/{month}/save', fn($p) => (new UstvaController())->save($p));
|
|
$router->get('/tax/ustva/{year}/{month}/xml', fn($p) => (new UstvaController())->downloadXml($p));
|
|
$router->get('/tax/ustva/{year}/{month}/kz/{kz}', fn($p) => (new UstvaController())->showKzBookings($p));
|
|
|
|
// ── EÜR ─────────────────────────────────────────────────────
|
|
$router->get('/tax/euer', fn($p) => (new EuerController())->index($p));
|
|
$router->get('/tax/euer/{year}', fn($p) => (new EuerController())->show($p));
|
|
$router->get('/tax/euer/{year}/pdf', fn($p) => (new EuerController())->pdf($p));
|
|
$router->get('/tax/euer/{year}/konto/{konto_id}', fn($p) => (new EuerController())->kontoBookings($p));
|
|
|
|
// ── Einstellungen ────────────────────────────────────────────
|
|
$router->get('/settings', fn($p) => (new SettingsController())->show($p));
|
|
$router->post('/settings', fn($p) => (new SettingsController())->update($p));
|
|
$router->post('/settings/logo', fn($p) => (new SettingsController())->uploadLogo($p));
|
|
$router->post('/settings/logo/delete', fn($p) => (new SettingsController())->deleteLogo($p));
|
|
|
|
// ── Login / Logout ────────────────────────────────────────────
|
|
$router->get('/login', fn($p) => (new LoginController())->showLogin($p));
|
|
$router->post('/login', fn($p) => (new LoginController())->handleLogin($p));
|
|
$router->post('/logout', fn($p) => (new LoginController())->handleLogout($p));
|
|
|
|
// ── Benutzerverwaltung ────────────────────────────────────────
|
|
$router->get('/useradmin', fn($p) => (new UserAdminController())->index($p));
|
|
$router->post('/useradmin', fn($p) => (new UserAdminController())->store($p));
|
|
$router->post('/useradmin/{id}', fn($p) => (new UserAdminController())->update($p));
|
|
$router->post('/useradmin/{id}/delete', fn($p) => (new UserAdminController())->delete($p));
|
|
$router->post('/useradmin/{id}/toggle', fn($p) => (new UserAdminController())->toggleActive($p));
|
|
|
|
$router->dispatch();
|