Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Modules\Resubmission\Service;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\Resubmission\Exception\ResubmissionNotFoundException;
|
||||
use Xentral\Modules\Resubmission\Exception\TextFieldConfigNotFoundException;
|
||||
|
||||
final class ResubmissionTextFieldGateway
|
||||
{
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/** @var ResubmissionGateway $resubmissionGateway */
|
||||
private $resubmissionGateway;
|
||||
|
||||
/**
|
||||
* @param Database $database
|
||||
* @param ResubmissionGateway $resubmissionGateway
|
||||
*/
|
||||
public function __construct(Database $database, ResubmissionGateway $resubmissionGateway)
|
||||
{
|
||||
$this->db = $database;
|
||||
$this->resubmissionGateway = $resubmissionGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $configId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function existsConfig($configId)
|
||||
{
|
||||
$sql =
|
||||
'SELECT COUNT(wfk.id) AS `config_count`
|
||||
FROM `wiedervorlage_freifeld_konfiguration` AS `wfk`
|
||||
WHERE wfk.id = :config_id';
|
||||
$configCount = (int)$this->db->fetchValue($sql, ['config_id' => (int)$configId]);
|
||||
|
||||
return $configCount === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $configId
|
||||
*
|
||||
* @throws TextFieldConfigNotFoundException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConfigById($configId)
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
wfk.id,
|
||||
wfk.title,
|
||||
wfk.available_from_stage_id,
|
||||
wfk.required_from_stage_id,
|
||||
wfk.show_in_pipeline,
|
||||
wfk.show_in_tables
|
||||
FROM `wiedervorlage_freifeld_konfiguration` AS `wfk`
|
||||
WHERE wfk.id = :config_id';
|
||||
|
||||
$result = $this->db->fetchRow($sql, ['config_id' => (int)$configId]);
|
||||
if (empty($result)) {
|
||||
throw new TextFieldConfigNotFoundException(sprintf(
|
||||
'Text field config not found: ID%s', $configId
|
||||
));
|
||||
}
|
||||
|
||||
if (empty($result['available_from_stage_id'])) {
|
||||
$result['available_from_stage_id'] = 0;
|
||||
}
|
||||
if (empty($result['required_from_stage_id'])) {
|
||||
$result['required_from_stage_id'] = 0;
|
||||
}
|
||||
$result['show_in_pipeline'] = (int)$result['show_in_pipeline'] === 1;
|
||||
$result['show_in_tables'] = (int)$result['show_in_tables'] === 1;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @example Rückgabe: ['freifeld1' => 'Mein Freifeld 1', 'freifeld2' => 'Mein Freifeld 2']
|
||||
*
|
||||
* @param int $viewId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTextFieldsForTableView($viewId)
|
||||
{
|
||||
$stages = $this->resubmissionGateway->getStagesByView($viewId);
|
||||
$stageIds = array_column($stages, 'id');
|
||||
|
||||
if (empty($stageIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql =
|
||||
'SELECT CONCAT(\'freifeld\', wfk.id) AS name, wfk.title
|
||||
FROM `wiedervorlage_freifeld_konfiguration` AS `wfk`
|
||||
WHERE wfk.show_in_tables = 1
|
||||
AND (
|
||||
wfk.available_from_stage_id = 0
|
||||
OR wfk.available_from_stage_id IN (:stages_ids)
|
||||
OR wfk.required_from_stage_id IN (:stages_ids)
|
||||
)';
|
||||
|
||||
return $this->db->fetchPairs($sql, ['stages_ids' => $stageIds]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @example Rückgabe: ['freifeld1' => 'Mein Freifeld 1', 'freifeld2' => 'Mein Freifeld 2']
|
||||
*
|
||||
* @param int $viewId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTextFieldsForPipelineView($viewId)
|
||||
{
|
||||
$stages = $this->resubmissionGateway->getStagesByView($viewId);
|
||||
$stageIds = array_column($stages, 'id');
|
||||
|
||||
if (empty($stageIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql =
|
||||
'SELECT CONCAT(\'freifeld\', wfk.id) AS name, wfk.title
|
||||
FROM `wiedervorlage_freifeld_konfiguration` AS `wfk`
|
||||
WHERE wfk.show_in_pipeline = 1
|
||||
AND (
|
||||
wfk.available_from_stage_id = 0
|
||||
OR wfk.available_from_stage_id IN (:stages_ids)
|
||||
OR wfk.required_from_stage_id IN (:stages_ids)
|
||||
)';
|
||||
|
||||
return $this->db->fetchPairs($sql, ['stages_ids' => $stageIds]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt alle Freitextfelder die in der übergebenen Stage ein Pflichtfeld sind
|
||||
*
|
||||
* @param int $stageId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequiredTextFieldsForStage($stageId)
|
||||
{
|
||||
// Schritt 1
|
||||
// Alle Stage-IDs ermittlen für die wir die Freitextfelder laden sollen
|
||||
// d.h. alle Stages die in der Reihenfolge vor der aktuellen Stage kommen; inklusive der aktuellen Stage
|
||||
$validStages = $this->getStagesUntilStageId($stageId);
|
||||
$validStageIds = array_column($validStages, 'id');
|
||||
|
||||
// Schritt 2
|
||||
// Alle Pflicht-Freitextfelder für die Stages aus Schritt 1 ermitteln
|
||||
$sql =
|
||||
'SELECT
|
||||
wfk.id AS `config_id`,
|
||||
wfk.title AS `label`,
|
||||
wfk.available_from_stage_id,
|
||||
wfk.required_from_stage_id,
|
||||
ws.name AS `required_from_stage_name`,
|
||||
wfk.show_in_pipeline,
|
||||
wfk.show_in_tables
|
||||
FROM `wiedervorlage_freifeld_konfiguration` AS `wfk`
|
||||
LEFT JOIN `wiedervorlage_stages` AS `ws` ON wfk.required_from_stage_id = ws.id
|
||||
WHERE wfk.required_from_stage_id IN (:valid_stage_ids)';
|
||||
|
||||
return $this->db->fetchAll($sql, [
|
||||
'valid_stage_ids' => $validStageIds,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt alle Stages die in der Reihenfolge vor der übergebenen Stage liegen
|
||||
*
|
||||
* @refactor ResubmissionGateway
|
||||
*
|
||||
* @param int $stageId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getStagesUntilStageId($stageId)
|
||||
{
|
||||
// Alle Stages in der gleichen View ermitteln
|
||||
$stageId = (int)$stageId;
|
||||
$stages = $this->resubmissionGateway->getSiblingStages($stageId);
|
||||
|
||||
// Rang der übergebenen Stage ermitteln
|
||||
$currentRank = 0;
|
||||
foreach ($stages as $stage) {
|
||||
if ($stage['id'] === $stageId) {
|
||||
$currentRank = $stage['rank'];
|
||||
}
|
||||
}
|
||||
|
||||
// Alle Stages filtern die VOR der übergebenen Stage liegen (inklusive der übergebenen Stage)
|
||||
$validStages = [];
|
||||
foreach ($stages as $stage) {
|
||||
if ($stage['rank'] <= $currentRank) {
|
||||
$validStages[] = $stage;
|
||||
}
|
||||
}
|
||||
|
||||
return $validStages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt alle Freifelder die das Verschieben einer Wiedervorlage blockieren
|
||||
*
|
||||
* @param int $resubmissionId
|
||||
* @param int $targetStageId
|
||||
*
|
||||
* @return array Empty array if none item is blocking
|
||||
*/
|
||||
public function getBlockingTextFieldsForTargetStage($resubmissionId, $targetStageId)
|
||||
{
|
||||
$resubmissionId = (int)$resubmissionId;
|
||||
$targetStageId = (int)$targetStageId;
|
||||
|
||||
$textfields = $this->getTextFieldsForResubmission($resubmissionId);
|
||||
|
||||
$blocking = [];
|
||||
foreach ($textfields as $textfield) {
|
||||
if (!empty($textfield['content'])) {
|
||||
continue; // Textfeld ist ausgefüllt > Textfeld darf in jede Stage geschoben werden
|
||||
}
|
||||
if ((int)$textfield['required_from_stage_id'] === 0) {
|
||||
continue; // Textfeld hat keine Fertigstellungs-Stage hinterlegt > Textfeld darf in jede Stage geschoben werden
|
||||
}
|
||||
|
||||
$distance = $this->resubmissionGateway->getDistanceBetweenStages(
|
||||
$targetStageId, $textfield['required_from_stage_id']
|
||||
);
|
||||
if ($distance <= 0) {
|
||||
$blocking[] = [
|
||||
'config_id' => $textfield['config_id'],
|
||||
'content_id' => $textfield['content_id'],
|
||||
'label' => $textfield['label'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $blocking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt alle Freitextfelder für eine Wiedervorlage
|
||||
*
|
||||
* @param int $resubmissionId
|
||||
*
|
||||
* @throws ResubmissionNotFoundException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTextFieldsForResubmission($resubmissionId)
|
||||
{
|
||||
$stage = $this->resubmissionGateway->getStageByResubmission($resubmissionId);
|
||||
$viewId = (int)$stage['view_id']; // View-ID `0` ist zulässig
|
||||
|
||||
// 1. Alle Stage-IDs ermittlen für die wir die Freitextfelder laden sollen
|
||||
// d.h. alle Stages die in der Reihenfolge vor der aktuellen Stage kommen; inklusive der aktuellen Stage
|
||||
$validStages = $this->getStagesUntilStageId($stage['id']);
|
||||
$validStageIds = array_column($validStages, 'id');
|
||||
|
||||
// 2. Alle Freitextfelder für die Stages aus Schritt 1 ermitteln
|
||||
$sql =
|
||||
'SELECT
|
||||
wfk.id AS `config_id`,
|
||||
wfi.id AS `content_id`,
|
||||
wfk.title AS `label`,
|
||||
wfk.available_from_stage_id,
|
||||
wfk.required_from_stage_id,
|
||||
wfk.show_in_pipeline,
|
||||
wfk.show_in_tables
|
||||
FROM `wiedervorlage_freifeld_konfiguration` AS `wfk`
|
||||
LEFT JOIN `wiedervorlage_freifeld_inhalt` AS `wfi`
|
||||
ON wfi.resubmission_id = :resubmission_id
|
||||
LEFT JOIN `wiedervorlage_stages` AS ws1
|
||||
ON wfk.required_from_stage_id = ws1.id
|
||||
LEFT JOIN `wiedervorlage_stages` AS ws2
|
||||
ON wfk.available_from_stage_id = ws2.id
|
||||
WHERE wfk.available_from_stage_id = 0
|
||||
OR wfk.available_from_stage_id IN (:valid_stage_ids)
|
||||
OR wfk.required_from_stage_id IN (:valid_stage_ids)
|
||||
ORDER BY wfk.required_from_stage_id != 0 DESC, ws1.sort, ws2.sort, wfk.title';
|
||||
// Erklärung Sortierung:
|
||||
// 1. `wfk.required_from_stage_id != 0 DESC` = Felder mit Pflicht-Stage oben anzeigen
|
||||
// 2. `ws1.sort, ws2.sort` = Felder nach Reihenfolge der Stages anzeigen
|
||||
|
||||
$textFields = $this->db->fetchAll($sql, [
|
||||
'resubmission_id' => $resubmissionId,
|
||||
'valid_stage_ids' => $validStageIds,
|
||||
'view_id' => $viewId,
|
||||
]);
|
||||
|
||||
// Freitextfeld-Inhalte ergänzen
|
||||
$contents = $this->getTextFieldContentsForResubmission($resubmissionId);
|
||||
foreach ($textFields as &$textField) {
|
||||
$configId = (int)$textField['config_id'];
|
||||
$textField['content'] = $contents[$configId];
|
||||
}
|
||||
unset($textField);
|
||||
|
||||
return $textFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $resubmissionId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTextFieldContentsForResubmission($resubmissionId)
|
||||
{
|
||||
$columnNames = $this->getTextFieldColumnNames();
|
||||
|
||||
$contentsAll = $this->db->fetchRow(
|
||||
'SELECT wfi.* FROM `wiedervorlage_freifeld_inhalt` AS `wfi`
|
||||
WHERE wfi.resubmission_id = :resubmission_id LIMIT 1',
|
||||
['resubmission_id' => (int)$resubmissionId]
|
||||
);
|
||||
|
||||
$contents = [];
|
||||
foreach ($columnNames as $configId => $columnName) {
|
||||
if (isset($contentsAll[$columnName])) {
|
||||
$contents[$configId] = $contentsAll[$columnName];
|
||||
} else {
|
||||
$contents[$configId] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $tableAlias
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTextFieldColumnNames($tableAlias = null)
|
||||
{
|
||||
$sql = 'SELECT wfk.id FROM `wiedervorlage_freifeld_konfiguration` AS `wfk` WHERE 1';
|
||||
$configIds = $this->db->fetchCol($sql);
|
||||
|
||||
$columnNames = [];
|
||||
$columnPrefix = $tableAlias !== null ? sprintf('%s.', $tableAlias) : '';
|
||||
foreach ($configIds as $configId) {
|
||||
$columnNames[$configId] = sprintf('%sfreifeld%s', $columnPrefix, $configId);
|
||||
}
|
||||
|
||||
return $columnNames;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user