Pierwsze procesy
This commit is contained in:
parent
3b1a26adc9
commit
4674e7458b
@ -405,12 +405,19 @@ class WorkflowEngine {
|
||||
}
|
||||
|
||||
public function getOrCreateInstanceByDefId(int $personId, int $processDefinitionId, int $userId): ?array {
|
||||
if (!is_int($processDefinitionId) || $processDefinitionId <= 0) {
|
||||
throw new InvalidArgumentException("processDefinitionId must be a positive integer.");
|
||||
}
|
||||
if (!is_int($personId) || $personId <= 0) {
|
||||
throw new InvalidArgumentException("personId must be a positive integer.");
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE `person_id` = ? AND `process_definition_id` = ?");
|
||||
$stmt->execute([$personId, $processDefinitionId]);
|
||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$instance) {
|
||||
$stmt_def = $this->pdo->prepare("SELECT definition_json, code FROM process_definitions WHERE id = ?");
|
||||
$stmt_def = $this->pdo->prepare("SELECT definition_json, code, is_active FROM process_definitions WHERE id = ?");
|
||||
$stmt_def->execute([$processDefinitionId]);
|
||||
$definition = $stmt_def->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
@ -418,7 +425,14 @@ class WorkflowEngine {
|
||||
throw new WorkflowNotFoundException("Process definition #$processDefinitionId not found.");
|
||||
}
|
||||
|
||||
$this->checkEligibility($personId, $definition);
|
||||
if (empty($definition['is_active'])) {
|
||||
throw new WorkflowNotAllowedException("Process is not active and cannot be started.");
|
||||
}
|
||||
|
||||
$eligibility = $this->checkEligibility($personId, $processDefinitionId);
|
||||
if (!$eligibility['is_eligible']) {
|
||||
throw new WorkflowEligibilityException("Person is not eligible to start this process.", $eligibility['reasons']);
|
||||
}
|
||||
|
||||
$definition_json = !empty($definition['definition_json']) ? json_decode($definition['definition_json'], true) : [];
|
||||
|
||||
|
||||
@ -1,29 +1,44 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'WorkflowEngine.php';
|
||||
require_once 'lib/ErrorHandler.php';
|
||||
require_once 'lib/WorkflowExceptions.php';
|
||||
register_error_handler();
|
||||
|
||||
require_once 'db/config.php';
|
||||
require_once 'WorkflowEngine.php';
|
||||
|
||||
if (session_status() == PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
throw new WorkflowNotAllowedException('Authentication required.');
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => ['message' => 'Authentication required.']]);
|
||||
exit;
|
||||
}
|
||||
$userId = $_SESSION['user_id'];
|
||||
|
||||
$personId = $_GET['personId'] ?? null;
|
||||
$processDefinitionId = $_GET['processId'] ?? null;
|
||||
$userId = $_SESSION['user_id'];
|
||||
$personId = filter_input(INPUT_POST, 'person_id', FILTER_VALIDATE_INT);
|
||||
$processDefinitionId = filter_input(INPUT_POST, 'process_id', FILTER_VALIDATE_INT);
|
||||
|
||||
if (!$personId || !$processDefinitionId) {
|
||||
throw new WorkflowRuleFailedException('Missing parameters for process initialization.');
|
||||
// InvalidArgumentException will be caught by the handler and result in a 400 Bad Request
|
||||
throw new InvalidArgumentException('Invalid or missing person_id or process_id.');
|
||||
}
|
||||
|
||||
$engine = new WorkflowEngine();
|
||||
|
||||
// The getOrCreateInstanceByDefId method is now responsible for all checks:
|
||||
// 1. Validating the process definition exists.
|
||||
// 2. Checking if the process is active.
|
||||
// 3. Checking if the person is eligible.
|
||||
// 4. Creating the instance if it doesn't exist.
|
||||
// It will throw specific exceptions (WorkflowNotFoundException, WorkflowNotAllowedException, WorkflowEligibilityException) which our ErrorHandler will turn into 404, 409, and 422 responses.
|
||||
$instance = $engine->getOrCreateInstanceByDefId($personId, $processDefinitionId, $userId);
|
||||
|
||||
if ($instance) {
|
||||
$_SESSION['success_message'] = "Process initialized successfully.";
|
||||
echo json_encode(['success' => true, 'message' => 'Process initialized successfully.', 'instance_id' => $instance['id']]);
|
||||
} else {
|
||||
$_SESSION['error_message'] = "Failed to initialize process.";
|
||||
// This case should not be reached if the engine works as expected, as failures should throw exceptions.
|
||||
throw new Exception("Failed to initialize process for an unknown reason.");
|
||||
}
|
||||
|
||||
header('Location: index.php');
|
||||
exit();
|
||||
|
||||
64
index.php
64
index.php
@ -607,6 +607,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
handleAddNote(noteBtn);
|
||||
return;
|
||||
}
|
||||
|
||||
const startBtn = event.target.closest('#startProcessBtn');
|
||||
if (startBtn) {
|
||||
handleStartProcess(startBtn);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
instanceModal.addEventListener('change', function(event) {
|
||||
@ -708,6 +714,22 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
submitRequestAndReloadModal('_apply_transition.php', formData);
|
||||
}
|
||||
|
||||
function handleStartProcess(button) {
|
||||
const personId = button.dataset.personId;
|
||||
const processId = button.dataset.processId;
|
||||
|
||||
if (!personId || !processId) {
|
||||
alert('Missing data for starting process. Please close the modal and try again.');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('person_id', personId);
|
||||
formData.append('process_id', processId);
|
||||
|
||||
submitRequestAndReloadModal('_init_single_instance.php', formData);
|
||||
}
|
||||
|
||||
function submitRequestAndReloadModal(url, formData) {
|
||||
const modalBody = instanceModal.querySelector('.modal-body');
|
||||
showLoading(modalBody);
|
||||
@ -718,14 +740,50 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
// If response is not OK, it's an error. Clone the response to read it twice.
|
||||
const clone = response.clone();
|
||||
return response.json()
|
||||
.then(json => {
|
||||
// We have a JSON error body, throw a custom error with its details
|
||||
const error = new Error(json.error?.message || 'An unkown error occurred.');
|
||||
error.correlation_id = json.correlation_id;
|
||||
error.response = response; // Attach full response
|
||||
throw error;
|
||||
})
|
||||
.catch(() => {
|
||||
// If JSON parsing fails, fall back to the text body
|
||||
return clone.text().then(text => {
|
||||
const error = new Error(text || 'Network response was not ok and could not parse error body.');
|
||||
error.response = response;
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
}
|
||||
// Reload modal content after successful submission
|
||||
return response.json(); // On success, just parse the JSON
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Reload modal content for the same person/process after successful submission
|
||||
fetchAndRenderModalContent(currentPersonId, currentProcessId);
|
||||
} else {
|
||||
// Handle cases where the server returns 200 OK but with success: false
|
||||
const error = new Error(data.message || 'An unknown error occurred.');
|
||||
if (data.correlation_id) {
|
||||
error.correlation_id = data.correlation_id;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error submitting request:', error);
|
||||
modalBody.innerHTML = `<div class="alert alert-danger">Wystąpił błąd sieciowy.</div>`;
|
||||
|
||||
let errorMessage = `<div class="alert alert-danger">`;
|
||||
errorMessage += `<strong>Error:</strong> ${error.message}`;
|
||||
if (error.correlation_id) {
|
||||
errorMessage += `<br><small class="text-muted">Correlation ID: ${error.correlation_id}</small>`;
|
||||
}
|
||||
errorMessage += `</div>`;
|
||||
modalBody.innerHTML = errorMessage;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,44 +1,18 @@
|
||||
<?php
|
||||
|
||||
class WorkflowException extends Exception {
|
||||
protected $httpCode;
|
||||
protected $details;
|
||||
class WorkflowNotFoundException extends Exception {}
|
||||
class WorkflowNotAllowedException extends Exception {}
|
||||
class WorkflowRuleFailedException extends Exception {}
|
||||
|
||||
public function __construct($message = "", $code = 0, $httpCode = 500, $details = [], Throwable $previous = null) {
|
||||
class WorkflowEligibilityException extends Exception {
|
||||
private $reasons;
|
||||
|
||||
public function __construct($message = "", $reasons = [], $code = 0, Throwable $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->httpCode = $httpCode;
|
||||
$this->details = $details;
|
||||
$this->reasons = $reasons;
|
||||
}
|
||||
|
||||
public function getHttpCode() {
|
||||
return $this->httpCode;
|
||||
}
|
||||
|
||||
public function getDetails() {
|
||||
return $this->details;
|
||||
}
|
||||
}
|
||||
|
||||
class WorkflowNotFoundException extends WorkflowException {
|
||||
public function __construct($message = "Not Found", $details = [], Throwable $previous = null) {
|
||||
parent::__construct($message, 404, 404, $details, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
class WorkflowNotAllowedException extends WorkflowException {
|
||||
public function __construct($message = "Bad Request", $details = [], Throwable $previous = null) {
|
||||
parent::__construct($message, 400, 400, $details, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
class WorkflowRuleFailedException extends WorkflowException {
|
||||
public function __construct($message = "Unprocessable Entity", $details = [], Throwable $previous = null) {
|
||||
parent::__construct($message, 422, 422, $details, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
class WorkflowConflictException extends WorkflowException {
|
||||
public function __construct($message = "Conflict", $details = [], Throwable $previous = null) {
|
||||
parent::__construct($message, 409, 409, $details, $previous);
|
||||
public function getReasons() {
|
||||
return $this->reasons;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user