Files
KGV-Verein-Manager/includes/Schema.php
Ronny Grobel 7d3d543954 Release 1.16.0
Arbeitsstunden-Modul hinzugefuegt

- Pflichtstunden pro Jahr inkl. Preis je fehlender Stunde

- Arbeitsarten, Arbeitseintraege und Mehrfachzuordnung von Mitgliedern

- Mitgliederuebersicht mit Berechnung fehlender Stunden und Aufschlag

- Datenbankschema fuer Arbeitsstunden erweitert

- Stable Tag und Changelog in README/readme.txt aktualisiert
2026-04-16 21:38:59 +02:00

328 lines
9.8 KiB
PHP

<?php
/**
* Database schema management.
*
* @package KGV\VereinManager
*/
namespace KGV\VereinManager;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Schema {
/**
* Get the full table name by key.
*
* @param string $key Table key.
* @return string
*/
public static function table( $key ) {
global $wpdb;
$map = array(
'sections' => $wpdb->prefix . 'kgvvm_sections',
'parcels' => $wpdb->prefix . 'kgvvm_parcels',
'meters' => $wpdb->prefix . 'kgvvm_meters',
'tenants' => $wpdb->prefix . 'kgvvm_tenants',
'parcel_members' => $wpdb->prefix . 'kgvvm_parcel_members',
'parcel_tenants' => $wpdb->prefix . 'kgvvm_parcel_tenants',
'chat_messages' => $wpdb->prefix . 'kgvvm_chat_messages',
'meter_readings' => $wpdb->prefix . 'kgvvm_meter_readings',
'cost_years' => $wpdb->prefix . 'kgvvm_cost_years',
'cost_rates' => $wpdb->prefix . 'kgvvm_cost_rates',
'cost_entries' => $wpdb->prefix . 'kgvvm_cost_entries',
'work_jobs' => $wpdb->prefix . 'kgvvm_work_jobs',
'work_year_config' => $wpdb->prefix . 'kgvvm_work_year_config',
'work_logs' => $wpdb->prefix . 'kgvvm_work_logs',
'work_log_members' => $wpdb->prefix . 'kgvvm_work_log_members',
);
return isset( $map[ $key ] ) ? $map[ $key ] : '';
}
/**
* Create plugin tables.
*
* @return void
*/
public static function create_tables() {
global $wpdb;
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
$charset_collate = $wpdb->get_charset_collate();
$sql = array();
$sql[] = "CREATE TABLE " . self::table( 'sections' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(190) NOT NULL,
description TEXT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY name (name),
KEY status (status)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'parcels' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
label VARCHAR(100) NOT NULL,
section_id BIGINT UNSIGNED NOT NULL,
area DECIMAL(10,2) NULL,
annual_rent DECIMAL(12,2) NULL,
status VARCHAR(20) NOT NULL DEFAULT 'free',
note TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY section_label (section_id, label),
KEY status (status),
KEY section_id (section_id)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'meters' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
type VARCHAR(20) NOT NULL,
meter_number VARCHAR(100) NOT NULL,
section_id BIGINT UNSIGNED NOT NULL,
parcel_id BIGINT UNSIGNED NULL,
installed_at DATE NULL,
calibration_year SMALLINT UNSIGNED NULL,
is_main_meter TINYINT(1) NOT NULL DEFAULT 0,
is_active TINYINT(1) NOT NULL DEFAULT 1,
note TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY type_meter_number (type, meter_number),
KEY section_id (section_id),
KEY parcel_id (parcel_id),
KEY type (type),
KEY is_main_meter (is_main_meter),
KEY is_active (is_active)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'tenants' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
address TEXT NULL,
phone VARCHAR(100) NULL,
email VARCHAR(190) NULL,
contract_start DATE NOT NULL,
contract_end DATE NULL,
is_active TINYINT(1) NOT NULL DEFAULT 1,
note TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
KEY name_lookup (last_name, first_name),
KEY is_active (is_active)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'parcel_members' ) . " (
parcel_id BIGINT UNSIGNED NOT NULL,
user_id BIGINT UNSIGNED NOT NULL,
created_at DATETIME NOT NULL,
PRIMARY KEY (parcel_id, user_id),
KEY user_id (user_id)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'parcel_tenants' ) . " (
parcel_id BIGINT UNSIGNED NOT NULL,
tenant_id BIGINT UNSIGNED NOT NULL,
created_at DATETIME NOT NULL,
PRIMARY KEY (parcel_id, tenant_id),
KEY tenant_id (tenant_id)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'chat_messages' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
room_key VARCHAR(50) NOT NULL,
user_id BIGINT UNSIGNED NOT NULL,
message TEXT NOT NULL,
created_at DATETIME NOT NULL,
PRIMARY KEY (id),
KEY room_key (room_key),
KEY user_id (user_id),
KEY created_at (created_at)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'meter_readings' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
meter_id BIGINT UNSIGNED NOT NULL,
parcel_id BIGINT UNSIGNED NOT NULL,
reading_value DECIMAL(12,3) NOT NULL,
reading_date DATE NOT NULL,
note TEXT NULL,
submitted_by BIGINT UNSIGNED NOT NULL DEFAULT 0,
is_self_reading TINYINT(1) NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
PRIMARY KEY (id),
KEY meter_id (meter_id),
KEY parcel_id (parcel_id),
KEY reading_date (reading_date)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'cost_years' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
entry_year SMALLINT UNSIGNED NOT NULL,
power_price_per_kwh DECIMAL(12,4) NULL,
water_price_per_m3 DECIMAL(12,4) NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY entry_year (entry_year)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'cost_rates' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
entry_year SMALLINT UNSIGNED NOT NULL,
section_id BIGINT UNSIGNED NOT NULL,
power_price_per_kwh DECIMAL(12,4) NULL,
water_price_per_m3 DECIMAL(12,4) NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY year_section (entry_year, section_id),
KEY section_id (section_id)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'cost_entries' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
entry_year SMALLINT UNSIGNED NOT NULL,
name VARCHAR(190) NOT NULL,
distribution_type VARCHAR(20) NOT NULL DEFAULT 'parcel',
unit_amount DECIMAL(12,2) NULL,
total_cost DECIMAL(12,2) NOT NULL DEFAULT 0.00,
note TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
KEY entry_year (entry_year),
KEY name (name),
KEY distribution_type (distribution_type)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'work_jobs' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(190) NOT NULL,
description TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY name (name)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'work_year_config' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
entry_year SMALLINT UNSIGNED NOT NULL,
required_hours DECIMAL(8,2) NOT NULL DEFAULT 0.00,
price_per_missing_hour DECIMAL(12,2) NOT NULL DEFAULT 0.00,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY entry_year (entry_year)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'work_logs' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
job_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
work_date DATE NOT NULL,
note TEXT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
KEY job_id (job_id),
KEY work_date (work_date)
) {$charset_collate};";
$sql[] = "CREATE TABLE " . self::table( 'work_log_members' ) . " (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
log_id BIGINT UNSIGNED NOT NULL,
user_id BIGINT UNSIGNED NOT NULL,
hours DECIMAL(8,2) NOT NULL DEFAULT 0.00,
created_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY log_user (log_id, user_id),
KEY user_id (user_id),
KEY log_id (log_id)
) {$charset_collate};";
foreach ( $sql as $statement ) {
dbDelta( $statement );
}
}
/**
* Optimize plugin tables.
*
* @return void
*/
public static function optimize_tables() {
global $wpdb;
$tables = array(
self::table( 'sections' ),
self::table( 'parcels' ),
self::table( 'meters' ),
self::table( 'tenants' ),
self::table( 'parcel_members' ),
self::table( 'parcel_tenants' ),
self::table( 'chat_messages' ),
self::table( 'meter_readings' ),
self::table( 'cost_years' ),
self::table( 'cost_rates' ),
self::table( 'cost_entries' ),
self::table( 'work_jobs' ),
self::table( 'work_year_config' ),
self::table( 'work_logs' ),
self::table( 'work_log_members' ),
);
foreach ( $tables as $table ) {
if ( ! empty( $table ) ) {
$wpdb->query( 'OPTIMIZE TABLE `' . esc_sql( $table ) . '`' ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
}
}
}
/**
* Drop plugin tables during uninstall.
*
* @return void
*/
public static function drop_tables() {
global $wpdb;
$tables = array(
self::table( 'work_log_members' ),
self::table( 'work_logs' ),
self::table( 'work_year_config' ),
self::table( 'work_jobs' ),
self::table( 'cost_entries' ),
self::table( 'cost_rates' ),
self::table( 'cost_years' ),
self::table( 'chat_messages' ),
self::table( 'meter_readings' ),
self::table( 'parcel_members' ),
self::table( 'parcel_tenants' ),
self::table( 'meters' ),
self::table( 'parcels' ),
self::table( 'tenants' ),
self::table( 'sections' ),
);
foreach ( $tables as $table ) {
if ( $table ) {
$wpdb->query( "DROP TABLE IF EXISTS {$table}" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
}
}
}
}