Dokumentit: kokousmuistiot, kansiorakenne, sub-tabit, asiakaslinkkaus
- Uusi dokumenttityyppi "kokousmuistio" jolla inline tekstieditori (ei tiedostopohjainen) - document_versions.content -sarake kokousmuistioiden tekstin tallennukseen - Sub-tabit Dokumentit-välilehdelle (Kaikki / Kokoukset) Tekniikka-mallin mukaan - Kansiorakenne: document_folders-taulu, kansionavigaatio breadcrumbsilla - Uudet API-endpointit: document_folders, document_folder_save/delete, document_content_save, document_move - Asiakasprofiilin Dokumentit-osio: näyttää linkitetyt dokumentit + pikanapit luontiin - Asiakasprofiilista voi avata dokumentin suoraan tai luoda uuden linkitettynä asiakkaaseen Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
63
db.php
63
db.php
@@ -542,6 +542,18 @@ function initDatabase(): void {
|
||||
INDEX idx_document (document_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS document_folders (
|
||||
id VARCHAR(20) PRIMARY KEY,
|
||||
company_id VARCHAR(50) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
parent_id VARCHAR(20) DEFAULT NULL,
|
||||
created_by VARCHAR(100) DEFAULT '',
|
||||
luotu DATETIME,
|
||||
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
|
||||
INDEX idx_company (company_id),
|
||||
INDEX idx_parent (parent_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS laitetilat (
|
||||
id VARCHAR(20) PRIMARY KEY,
|
||||
company_id VARCHAR(50) NOT NULL,
|
||||
@@ -599,6 +611,8 @@ function initDatabase(): void {
|
||||
"ALTER TABLE companies ADD COLUMN allowed_ips TEXT DEFAULT '' AFTER enabled_modules",
|
||||
"ALTER TABLE todos ADD COLUMN category VARCHAR(30) DEFAULT '' AFTER priority",
|
||||
"ALTER TABLE user_companies ADD COLUMN role VARCHAR(20) DEFAULT 'user' AFTER company_id",
|
||||
"ALTER TABLE documents ADD COLUMN folder_id VARCHAR(20) DEFAULT NULL AFTER customer_id",
|
||||
"ALTER TABLE document_versions ADD COLUMN content MEDIUMTEXT DEFAULT NULL AFTER mime_type",
|
||||
];
|
||||
foreach ($alters as $sql) {
|
||||
try { $db->query($sql); } catch (\Throwable $e) { /* sarake on jo olemassa / jo ajettu */ }
|
||||
@@ -1736,6 +1750,43 @@ function dbDeleteTodoSubtask(string $subtaskId): void {
|
||||
_dbExecute("DELETE FROM todo_subtasks WHERE id = ?", [$subtaskId]);
|
||||
}
|
||||
|
||||
// ==================== DOKUMENTTIKANSIOT ====================
|
||||
|
||||
function dbLoadFolders(string $companyId): array {
|
||||
return _dbFetchAll("SELECT * FROM document_folders WHERE company_id = ? ORDER BY name", [$companyId]);
|
||||
}
|
||||
|
||||
function dbSaveFolder(string $companyId, array $folder): string {
|
||||
$id = $folder['id'] ?? generateId();
|
||||
$now = date('Y-m-d H:i:s');
|
||||
_dbExecute("
|
||||
INSERT INTO document_folders (id, company_id, name, parent_id, created_by, luotu)
|
||||
VALUES (:id, :companyId, :name, :parentId, :createdBy, :luotu)
|
||||
ON DUPLICATE KEY UPDATE name = VALUES(name), parent_id = VALUES(parent_id)
|
||||
", [
|
||||
'id' => $id,
|
||||
'companyId' => $companyId,
|
||||
'name' => $folder['name'] ?? '',
|
||||
'parentId' => !empty($folder['parent_id']) ? $folder['parent_id'] : null,
|
||||
'createdBy' => $folder['created_by'] ?? '',
|
||||
'luotu' => $folder['luotu'] ?? $now
|
||||
]);
|
||||
return $id;
|
||||
}
|
||||
|
||||
function dbDeleteFolder(string $companyId, string $folderId): bool {
|
||||
$folder = _dbFetchOne("SELECT parent_id FROM document_folders WHERE id = ? AND company_id = ?", [$folderId, $companyId]);
|
||||
if (!$folder) return false;
|
||||
// Siirrä kansion dokumentit ylätasolle
|
||||
_dbExecute("UPDATE documents SET folder_id = ? WHERE folder_id = ? AND company_id = ?",
|
||||
[$folder['parent_id'], $folderId, $companyId]);
|
||||
// Siirrä alikansiot ylätasolle
|
||||
_dbExecute("UPDATE document_folders SET parent_id = ? WHERE parent_id = ? AND company_id = ?",
|
||||
[$folder['parent_id'], $folderId, $companyId]);
|
||||
_dbExecute("DELETE FROM document_folders WHERE id = ? AND company_id = ?", [$folderId, $companyId]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ==================== DOKUMENTIT ====================
|
||||
|
||||
function dbLoadDocuments(string $companyId, ?string $customerId = null): array {
|
||||
@@ -1767,19 +1818,21 @@ function dbSaveDocument(string $companyId, array $doc): string {
|
||||
$id = $doc['id'] ?? generateId();
|
||||
$now = date('Y-m-d H:i:s');
|
||||
_dbExecute("
|
||||
INSERT INTO documents (id, company_id, customer_id, title, description, category, current_version, created_by, luotu, muokattu, muokkaaja)
|
||||
VALUES (:id, :companyId, :customerId, :title, :description, :category, :currentVersion, :createdBy, :luotu, :muokattu, :muokkaaja)
|
||||
INSERT INTO documents (id, company_id, customer_id, folder_id, title, description, category, current_version, created_by, luotu, muokattu, muokkaaja)
|
||||
VALUES (:id, :companyId, :customerId, :folderId, :title, :description, :category, :currentVersion, :createdBy, :luotu, :muokattu, :muokkaaja)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
title = VALUES(title),
|
||||
description = VALUES(description),
|
||||
category = VALUES(category),
|
||||
customer_id = VALUES(customer_id),
|
||||
folder_id = VALUES(folder_id),
|
||||
muokattu = VALUES(muokattu),
|
||||
muokkaaja = VALUES(muokkaaja)
|
||||
", [
|
||||
'id' => $id,
|
||||
'companyId' => $companyId,
|
||||
'customerId' => !empty($doc['customer_id']) ? $doc['customer_id'] : null,
|
||||
'folderId' => !empty($doc['folder_id']) ? $doc['folder_id'] : null,
|
||||
'title' => $doc['title'] ?? '',
|
||||
'description' => $doc['description'] ?? '',
|
||||
'category' => $doc['category'] ?? 'muu',
|
||||
@@ -1807,7 +1860,7 @@ function dbAddDocumentVersion(string $documentId, array $version): void {
|
||||
$maxVersion = _dbFetchScalar("SELECT COALESCE(MAX(version_number), 0) FROM document_versions WHERE document_id = ?", [$documentId]);
|
||||
$nextVersion = (int)$maxVersion + 1;
|
||||
|
||||
_dbExecute("INSERT INTO document_versions (id, document_id, version_number, filename, original_name, file_size, mime_type, change_notes, created_by, luotu) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
||||
_dbExecute("INSERT INTO document_versions (id, document_id, version_number, filename, original_name, file_size, mime_type, content, change_notes, created_by, luotu) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
||||
$version['id'] ?? generateId(),
|
||||
$documentId,
|
||||
$nextVersion,
|
||||
@@ -1815,6 +1868,7 @@ function dbAddDocumentVersion(string $documentId, array $version): void {
|
||||
$version['original_name'] ?? '',
|
||||
$version['file_size'] ?? 0,
|
||||
$version['mime_type'] ?? '',
|
||||
$version['content'] ?? null,
|
||||
$version['change_notes'] ?? '',
|
||||
$version['created_by'] ?? '',
|
||||
$now
|
||||
@@ -1836,7 +1890,7 @@ function dbRestoreDocumentVersion(string $documentId, string $versionId, string
|
||||
$nextVersion = (int)$maxVersion + 1;
|
||||
$newId = generateId();
|
||||
|
||||
_dbExecute("INSERT INTO document_versions (id, document_id, version_number, filename, original_name, file_size, mime_type, change_notes, created_by, luotu) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
||||
_dbExecute("INSERT INTO document_versions (id, document_id, version_number, filename, original_name, file_size, mime_type, content, change_notes, created_by, luotu) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
||||
$newId,
|
||||
$documentId,
|
||||
$nextVersion,
|
||||
@@ -1844,6 +1898,7 @@ function dbRestoreDocumentVersion(string $documentId, string $versionId, string
|
||||
$oldVersion['original_name'],
|
||||
$oldVersion['file_size'],
|
||||
$oldVersion['mime_type'],
|
||||
$oldVersion['content'] ?? null,
|
||||
'Palautettu versiosta ' . $oldVersion['version_number'],
|
||||
$user,
|
||||
$now
|
||||
|
||||
Reference in New Issue
Block a user