110 lines
5.3 KiB
Python
110 lines
5.3 KiB
Python
import re
|
|
|
|
with open('WorkflowEngine.php', 'r') as f:
|
|
content = f.read()
|
|
|
|
new_method = """
|
|
public function getOrCreateInstanceBySubject(string $subjectType, int $subjectId, string $processCode, int $userId, string $mode='resume_or_create'): array {
|
|
if (!in_array($subjectType, ['person', 'meeting', 'bni_group', 'organization'])) {
|
|
throw new InvalidArgumentException("Invalid subjectType.");
|
|
}
|
|
if ($subjectId <= 0) {
|
|
throw new InvalidArgumentException("subjectId must be > 0.");
|
|
}
|
|
if (empty($processCode)) {
|
|
throw new InvalidArgumentException("processCode cannot be empty.");
|
|
}
|
|
|
|
$inTransaction = $this->pdo->inTransaction();
|
|
if (!$inTransaction) { $this->pdo->beginTransaction(); }
|
|
|
|
try {
|
|
$sql = "SELECT * FROM process_definitions WHERE code = ? AND is_active = 1 AND subject_scope = ? ORDER BY version DESC, id DESC LIMIT 1";
|
|
$stmt = $this->pdo->prepare($sql);
|
|
$stmt->execute([$processCode, $subjectType]);
|
|
$definition = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$definition) {
|
|
$stmt = $this->pdo->prepare("SELECT * FROM process_definitions WHERE code = ? AND is_active = 1 ORDER BY version DESC, id DESC LIMIT 1");
|
|
$stmt->execute([$processCode]);
|
|
$definition = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
if (!$definition) {
|
|
throw new WorkflowNotFoundException("No active process definition found for code '$processCode'");
|
|
}
|
|
}
|
|
|
|
$defId = $definition['id'];
|
|
$defJson = json_decode($definition['definition_json'], true);
|
|
$startNodeId = $defJson['start_node_id'] ?? null;
|
|
if (!$startNodeId) {
|
|
throw new Exception("Process definition missing start_node_id");
|
|
}
|
|
|
|
$instance = null;
|
|
if ($mode === 'resume_or_create') {
|
|
$stmt = $this->pdo->prepare(
|
|
"SELECT pi.* FROM process_instances pi\n JOIN process_definitions pd ON pi.process_definition_id = pd.id\n WHERE pi.subject_type = ? AND pi.subject_id = ? AND pd.code = ?\n ORDER BY pi.id DESC LIMIT 1"
|
|
);
|
|
$stmt->execute([$subjectType, $subjectId, $processCode]);
|
|
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
if (!$instance) {
|
|
$stmt = $this->pdo->prepare(
|
|
"SELECT MAX(pi.run_number) \n FROM process_instances pi\n JOIN process_definitions pd ON pi.process_definition_id = pd.id\n WHERE pi.subject_type = ? AND pi.subject_id = ? AND pd.code = ?"
|
|
);
|
|
$stmt->execute([$subjectType, $subjectId, $processCode]);
|
|
$maxRun = (int)$stmt->fetchColumn();
|
|
$runNumber = $maxRun + 1;
|
|
|
|
$personIdVal = ($subjectType === 'person') ? $subjectId : null;
|
|
$status = $defJson['nodes'][$startNodeId]['ui_hints']['status'] ?? 'in_progress';
|
|
$reason = $defJson['nodes'][$startNodeId]['ui_hints']['reason'] ?? '';
|
|
$nextStep = $defJson['nodes'][$startNodeId]['ui_hints']['next_step'] ?? '';
|
|
|
|
$stmt = $this->pdo->prepare(
|
|
"INSERT INTO process_instances \n (subject_type, subject_id, person_id, process_definition_id, current_node_id, current_status, current_reason, suggested_next_step, run_number, last_activity_at, data_json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), '{}')"
|
|
);
|
|
$stmt->execute([
|
|
$subjectType, $subjectId, $personIdVal, $defId, $startNodeId, $status, $reason, $nextStep, $runNumber
|
|
]);
|
|
|
|
$instanceId = $this->pdo->lastInsertId();
|
|
$this->addEvent($instanceId, 'system', 'Process started.', $startNodeId, [], $userId);
|
|
|
|
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE id = ?");
|
|
$stmt->execute([$instanceId]);
|
|
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
if (!$inTransaction) { $this->pdo->commit(); }
|
|
|
|
return [
|
|
'instance_id' => $instance['id'],
|
|
'process_definition_id' => $instance['process_definition_id'],
|
|
'process_code' => $processCode,
|
|
'subject_type' => $instance['subject_type'],
|
|
'subject_id' => $instance['subject_id'],
|
|
'person_id' => $instance['person_id'],
|
|
'current_node_id' => $instance['current_node_id'],
|
|
'current_status' => $instance['current_status'],
|
|
'last_activity_at' => $instance['last_activity_at'],
|
|
'data_json' => $instance['data_json']
|
|
];
|
|
|
|
} catch (Exception $e) {
|
|
if (!$inTransaction) { $this->pdo->rollBack(); }
|
|
throw $e;
|
|
}
|
|
}
|
|
"
|
|
|
|
if "function getOrCreateInstanceBySubject" not in content:
|
|
last_brace_idx = content.rfind('}')
|
|
content = content[:last_brace_idx] + new_method + "\n}\n"
|
|
with open('WorkflowEngine.php', 'w') as f:
|
|
f.write(content)
|
|
print("Method added.")
|
|
else:
|
|
print("Method already exists.")
|