Files
KGV-Verein-Manager/includes/Services/ParcelService.php
2026-04-13 21:01:07 +02:00

148 lines
4.5 KiB
PHP

<?php
/**
* Business logic for parcel + relations.
*
* @package KGV\VereinManager
*/
namespace KGV\VereinManager\Services;
use KGV\VereinManager\Validator;
use KGV\VereinManager\Repositories\AssignmentRepository;
use KGV\VereinManager\Repositories\MeterRepository;
use KGV\VereinManager\Repositories\ParcelRepository;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class ParcelService {
/**
* Validator instance.
*
* @var Validator
*/
private $validator;
/**
* Parcel repository.
*
* @var ParcelRepository
*/
private $parcels;
/**
* Meter repository.
*
* @var MeterRepository
*/
private $meters;
/**
* Assignment repository.
*
* @var AssignmentRepository
*/
private $assignments;
/**
* Build service.
*/
public function __construct() {
$this->validator = new Validator();
$this->parcels = new ParcelRepository();
$this->meters = new MeterRepository();
$this->assignments = new AssignmentRepository();
}
/**
* Save parcel plus relations.
*
* @param int $id Optional parcel ID.
* @param array $raw_data Raw submitted data.
* @return int|\WP_Error
*/
public function save( $id, $raw_data ) {
$data = $this->validator->sanitize_parcel( $raw_data );
$errors = $this->validator->validate_parcel( $data );
$water_meter_id = absint( isset( $raw_data['water_meter_id'] ) ? $raw_data['water_meter_id'] : 0 );
$power_meter_id = absint( isset( $raw_data['power_meter_id'] ) ? $raw_data['power_meter_id'] : 0 );
$member_ids = array_values( array_unique( array_filter( array_map( 'absint', isset( $raw_data['member_ids'] ) ? (array) wp_unslash( $raw_data['member_ids'] ) : array() ) ) ) );
$tenant_ids = array_values( array_unique( array_filter( array_map( 'absint', isset( $raw_data['tenant_ids'] ) ? (array) wp_unslash( $raw_data['tenant_ids'] ) : array() ) ) ) );
if ( $this->parcels->label_exists( $data['label'], $data['section_id'], $id ) ) {
$errors->add( 'duplicate_label', __( 'Diese Parzellenbezeichnung existiert in der gewählten Sparte bereits.', KGVVM_TEXT_DOMAIN ) );
}
if ( $water_meter_id < 1 ) {
$errors->add( 'water_meter_required', __( 'Bitte einen freien Wasserzähler auswählen.', KGVVM_TEXT_DOMAIN ) );
}
if ( $power_meter_id < 1 ) {
$errors->add( 'power_meter_required', __( 'Bitte einen freien Stromzähler auswählen.', KGVVM_TEXT_DOMAIN ) );
}
$water_meter = $water_meter_id ? $this->meters->get_assignable_meter( $water_meter_id, 'water', $data['section_id'], $id ) : null;
$power_meter = $power_meter_id ? $this->meters->get_assignable_meter( $power_meter_id, 'power', $data['section_id'], $id ) : null;
if ( $water_meter_id && ! $water_meter ) {
$errors->add( 'invalid_water_meter', __( 'Der ausgewählte Wasserzähler ist nicht verfügbar oder gehört zu einer anderen Sparte.', KGVVM_TEXT_DOMAIN ) );
}
if ( $power_meter_id && ! $power_meter ) {
$errors->add( 'invalid_power_meter', __( 'Der ausgewählte Stromzähler ist nicht verfügbar oder gehört zu einer anderen Sparte.', KGVVM_TEXT_DOMAIN ) );
}
if ( ! $this->allow_multiple_member_parcels() ) {
foreach ( $member_ids as $user_id ) {
if ( $this->assignments->member_has_other_parcels( $user_id, $id ) ) {
$errors->add( 'member_conflict', __( 'Mindestens ein Mitglied ist bereits einer anderen Parzelle zugeordnet. Die Mehrfachzuordnung ist derzeit deaktiviert.', KGVVM_TEXT_DOMAIN ) );
break;
}
}
}
if ( $errors->has_errors() ) {
return $errors;
}
$parcel_id = $this->parcels->save( $data, $id );
if ( ! $parcel_id ) {
return new \WP_Error( 'save_failed', __( 'Die Parzelle konnte nicht gespeichert werden.', KGVVM_TEXT_DOMAIN ) );
}
$this->meters->release_parcel( $parcel_id );
$this->meters->assign_to_parcel( $water_meter_id, $parcel_id );
$this->meters->assign_to_parcel( $power_meter_id, $parcel_id );
$this->assignments->sync_member_ids( $parcel_id, $member_ids );
$this->assignments->sync_tenant_ids( $parcel_id, $tenant_ids );
return $parcel_id;
}
/**
* Delete a parcel and clean up relations.
*
* @param int $id Parcel ID.
* @return bool
*/
public function delete( $id ) {
$this->meters->release_parcel( $id );
$this->assignments->purge_parcel( $id );
return $this->parcels->delete( $id );
}
/**
* Determine whether a member may own multiple parcels.
*
* @return bool
*/
private function allow_multiple_member_parcels() {
$settings = get_option( 'kgvvm_settings', array() );
return ! isset( $settings['allow_multiple_member_parcels'] ) || 1 === (int) $settings['allow_multiple_member_parcels'];
}
}