======= ini_set('display_errors', 1); error_reporting(E_ALL); // ------------------------------------------------------------------------------------ // 1. DINE MYSQL OPLYSNINGER (INDTAST DINE DATA HER) // ------------------------------------------------------------------------------------ $dbHost = 'localhost'; // Usually 'localhost' on e-studio $dbName = 'doudomev_procurement'; // e.g. doudo_procurement $dbUser = 'doudomev_user'; // e.g. doudo_user $dbPass = 'Xc4aeYK-]Q^$$]j0'; // The password you set in e-studio try { $pdo = new PDO("mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4", $dbUser, $dbPass, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); // Opret tabeller automatisk hvis de ikke eksisterer $pdo->exec(" CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, full_name VARCHAR(150) NOT NULL, email VARCHAR(150) UNIQUE NOT NULL, department VARCHAR(100) NOT NULL, role ENUM('admin', 'procurement_manager', 'supplier') NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS events ( id INT AUTO_INCREMENT PRIMARY KEY, event_id_code VARCHAR(50) UNIQUE NOT NULL, title VARCHAR(255) NOT NULL, type_category ENUM('goods', 'services') DEFAULT 'services', template_name VARCHAR(100) DEFAULT 'No template', event_type VARCHAR(100) DEFAULT 'RFQ List', blindfold_type TINYINT(1) DEFAULT 0, status ENUM('Draft', 'Active', 'Settled', 'Finished') DEFAULT 'Draft', is_live_event TINYINT(1) DEFAULT 1, event_manager_id INT NOT NULL, department VARCHAR(100) DEFAULT 'COWI', description TEXT, comments TEXT, allow_supplier_upload TINYINT(1) DEFAULT 1, delivery_terms VARCHAR(100) DEFAULT 'On site', delivery_address TEXT, payment_terms VARCHAR(100) DEFAULT '60 days net', end_date DATETIME NULL, currency VARCHAR(10) DEFAULT 'DKK', offline_bid_list TINYINT(1) DEFAULT 0, allow_online_response TINYINT(1) DEFAULT 1, acceptance_prior TINYINT(1) DEFAULT 0, email_at_finalisation TINYINT(1) DEFAULT 1, locked_event TINYINT(1) DEFAULT 0, private_event TINYINT(1) DEFAULT 0, best_bid_total DECIMAL(15,2) DEFAULT 0, savings_total DECIMAL(15,2) DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS event_lines ( id INT AUTO_INCREMENT PRIMARY KEY, event_id INT NOT NULL, line_no INT NOT NULL, product_name VARCHAR(255) NOT NULL, unit VARCHAR(50) NOT NULL, quantity DECIMAL(12,2) NOT NULL DEFAULT 1, current_price DECIMAL(15,2) DEFAULT 0, reserve_price DECIMAL(15,2) DEFAULT 0, start_price DECIMAL(15,2) DEFAULT 0, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS event_participants ( id INT AUTO_INCREMENT PRIMARY KEY, event_id INT NOT NULL, participant_name VARCHAR(150) NOT NULL, email VARCHAR(150) NOT NULL, role_type ENUM('supplier', 'stakeholder', 'spectator') DEFAULT 'supplier', language_code VARCHAR(10) DEFAULT 'en', status VARCHAR(50) DEFAULT 'Invited', FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS event_notes ( id INT AUTO_INCREMENT PRIMARY KEY, event_id INT NOT NULL, author_name VARCHAR(100) NOT NULL, note_text TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS event_messages ( id INT AUTO_INCREMENT PRIMARY KEY, event_id INT NOT NULL, sender VARCHAR(100) NOT NULL, message_text TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; "); // Opret demo-data hvis tabellen er tom $uCheck = $pdo->query("SELECT COUNT(*) AS total FROM users")->fetch(); if ($uCheck['total'] == 0) { $pdo->exec("INSERT INTO users (full_name, email, department, role) VALUES ('Lars Jannik Pini', 'ljpi@cowi.com', 'COWI Group Procurement', 'procurement_manager')"); } $eCheck = $pdo->query("SELECT COUNT(*) AS total FROM events")->fetch(); if ($eCheck['total'] == 0) { $pdo->exec(" INSERT INTO events (event_id_code, title, type_category, event_type, status, is_live_event, event_manager_id, department, description, comments, currency, best_bid_total, savings_total, delivery_terms, delivery_address, payment_terms, end_date) VALUES ( '880260', 'Finance Transformation, 2nd Round - 06.2026', 'services', 'RFx List', 'Settled', 1, 1, 'COWI', 'Welcome to the 2 Round Tendering of the project: Finance Transformation. The purpose is to update proposals based on inputs from round 1.', 'By submitting an updated proposal, the vendor accepts the complete contract format and terms of the tender.', 'DKK', 17057616.00, 2442384.00, 'On site', 'COWI A/S, Parallelvej 2, 2800 Kongens Lyngby, Denmark', '60 days net', '2026-08-03 12:00:00' ); INSERT INTO event_lines (event_id, line_no, product_name, unit, quantity, current_price, reserve_price, start_price) VALUES (1, 1, 'Management Consulting Senior Advisory', 'Hours', 850, 1850.00, 1600.00, 1900.00); INSERT INTO event_participants (event_id, participant_name, email, role_type, status) VALUES (1, 'Deloitte (Jens Sønderkær)', 'jens@deloitte.dk', 'supplier', 'Shortlisted'); "); } } catch (PDOException $e) { die("

MySQL Forbindelsesfejl

" . htmlspecialchars($e->getMessage()) . "

Opdater \$dbHost, \$dbName, \$dbUser og \$dbPass i toppen af filen.

"); } // ------------------------------------------------------------------------------------ // 2. BACKEND ACTIONS (HANDLINGER OG POST-REQUESTS) // ------------------------------------------------------------------------------------ $action = $_REQUEST['action'] ?? ''; $eventId = (int)($_REQUEST['id'] ?? $_REQUEST['event_id'] ?? 0); // A. Opret ny event fra modalen if ($action === 'create_from_modal') { $eventType = $_POST['event_type'] ?? 'RFQ List'; $template = $_POST['template'] ?? 'No template'; $newCode = rand(800000, 999999); $category = (strpos($eventType, 'RFQ') !== false) ? 'goods' : 'services'; $stmt = $pdo->prepare("INSERT INTO events (event_id_code, title, type_category, template_name, event_type, status, event_manager_id, delivery_address, end_date) VALUES (?, 'New Tender Event', ?, ?, ?, 'Draft', 1, 'COWI A/S\nParallelvej 2\nKongens Lyngby\nDenmark', DATE_ADD(NOW(), INTERVAL 30 DAY))"); $stmt->execute([$newCode, $category, $template, $eventType]); $newId = $pdo->lastInsertId(); header("Location: index.php?view=edit&id={$newId}&tab=specs"); exit; } // B. Gem specifikationer (Tab 1) if ($action === 'save_specs' && $eventId) { $stmt = $pdo->prepare(" UPDATE events SET title = ?, description = ?, comments = ?, event_type = ?, type_category = ?, blindfold_type = ?, is_live_event = ?, delivery_terms = ?, delivery_address = ?, payment_terms = ?, end_date = ?, currency = ?, allow_supplier_upload = ?, offline_bid_list = ?, allow_online_response = ?, acceptance_prior = ?, email_at_finalisation = ?, locked_event = ?, private_event = ? WHERE id = ? "); $stmt->execute([ $_POST['title'] ?? 'Untitled', $_POST['description'] ?? '', $_POST['comments'] ?? '', $_POST['event_type'] ?? 'RFQ List', $_POST['type_category'] ?? 'services', isset($_POST['blindfold_type']) ? 1 : 0, (int)($_POST['is_live_event'] ?? 1), $_POST['delivery_terms'] ?? 'On site', $_POST['delivery_address'] ?? '', $_POST['payment_terms'] ?? '60 days net', !empty($_POST['end_date']) ? $_POST['end_date'] : null, $_POST['currency'] ?? 'DKK', isset($_POST['allow_supplier_upload']) ? 1 : 0, isset($_POST['offline_bid_list']) ? 1 : 0, isset($_POST['allow_online_response']) ? 1 : 0, isset($_POST['acceptance_prior']) ? 1 : 0, isset($_POST['email_at_finalisation']) ? 1 : 0, isset($_POST['locked_event']) ? 1 : 0, isset($_POST['private_event']) ? 1 : 0, $eventId ]); header("Location: index.php?view=edit&id={$eventId}&tab=specs&saved=1"); exit; } // C. Tilføj varelinje til Bid list (Tab 3) if ($action === 'add_bid_line' && $eventId) { $count = $pdo->prepare("SELECT COUNT(*) FROM event_lines WHERE event_id = ?"); $count->execute([$eventId]); $nextNo = ((int)$count->fetchColumn()) + 1; $stmt = $pdo->prepare("INSERT INTO event_lines (event_id, line_no, product_name, unit, quantity, current_price, reserve_price, start_price) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([ $eventId, $nextNo, $_POST['product_name'] ?: 'New Item ' . $nextNo, $_POST['unit'] ?: 'Pcs', $_POST['quantity'] ?: 10, $_POST['current_price'] ?: 0, $_POST['reserve_price'] ?: 0, $_POST['start_price'] ?: 0 ]); header("Location: index.php?view=edit&id={$eventId}&tab=bids"); exit; } // D. Tilføj deltager (Tab 2) if ($action === 'add_participant' && $eventId) { if (!empty($_POST['participant_name'])) { $stmt = $pdo->prepare("INSERT INTO event_participants (event_id, participant_name, email, role_type, language_code) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$eventId, $_POST['participant_name'], $_POST['email'], $_POST['role_type'], $_POST['language_code']]); } header("Location: index.php?view=edit&id={$eventId}&tab=participants"); exit; } // E. Tilføj intern note (Tab 4) if ($action === 'add_note' && $eventId) { if (!empty(trim($_POST['note_text']))) { $stmt = $pdo->prepare("INSERT INTO event_notes (event_id, author_name, note_text) VALUES (?, 'Lars Jannik Pini', ?)"); $stmt->execute([$eventId, trim($_POST['note_text'])]); } header("Location: index.php?view=edit&id={$eventId}&tab=notes"); exit; } // F. Send besked (Messaging knap) if ($action === 'send_message' && $eventId) { if (!empty(trim($_POST['message_text']))) { $stmt = $pdo->prepare("INSERT INTO event_messages (event_id, sender, message_text) VALUES (?, 'Lars Jannik Pini (Buyer)', ?)"); $stmt->execute([$eventId, trim($_POST['message_text'])]); } header("Location: index.php?view=edit&id={$eventId}&tab=" . ($_POST['return_tab'] ?? 'specs')); exit; } // G. Kopiér event if ($action === 'copy_event' && $eventId) { $ev = $pdo->prepare("SELECT * FROM events WHERE id = ?"); $ev->execute([$eventId]); $orig = $ev->fetch(); if ($orig) { $stmt = $pdo->prepare("INSERT INTO events (event_id_code, title, type_category, template_name, event_type, status, event_manager_id, department, description, comments, delivery_terms, delivery_address, payment_terms, end_date, currency) VALUES (?, ?, ?, ?, ?, 'Draft', ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([rand(800000, 999999), 'Copy of ' . $orig['title'], $orig['type_category'], $orig['template_name'], $orig['event_type'], $orig['event_manager_id'], $orig['department'], $orig['description'], $orig['comments'], $orig['delivery_terms'], $orig['delivery_address'], $orig['payment_terms'], $orig['end_date'], $orig['currency']]); $copyId = $pdo->lastInsertId(); header("Location: index.php?view=edit&id={$copyId}&tab=specs"); exit; } } // H. Slet event if ($action === 'delete_event' && $eventId) { $stmt = $pdo->prepare("DELETE FROM events WHERE id = ?"); $stmt->execute([$eventId]); header("Location: index.php?deleted=1"); exit; } // I. Excel/CSV rapport eksport if ($action === 'export_excel' && $eventId) { $ev = $pdo->prepare("SELECT * FROM events WHERE id = ?"); $ev->execute([$eventId]); $event = $ev->fetch(); $lines = $pdo->prepare("SELECT * FROM event_lines WHERE event_id = ?"); $lines->execute([$eventId]); $items = $lines->fetchAll(); header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename=Event_Report_' . $event['event_id_code'] . '.csv'); $out = fopen('php://output', 'w'); fputcsv($out, ['Event ID', 'Title', 'Type', 'Status', 'Currency', 'Delivery Address']); fputcsv($out, [$event['event_id_code'], $event['title'], $event['event_type'], $event['status'], $event['currency'], $event['delivery_address']]); fputcsv($out, []); fputcsv($out, ['Line No', 'Product', 'Unit', 'Quantity', 'Current Price', 'Reserve Price', 'Start Price']); foreach ($items as $it) { fputcsv($out, [$it['line_no'], $it['product_name'], $it['unit'], $it['quantity'], $it['current_price'], $it['reserve_price'], $it['start_price']]); } fclose($out); exit; } // ------------------------------------------------------------------------------------ // 3. ROUTING & VISNINGER (Dashboard vs. Event Workspace) // ------------------------------------------------------------------------------------ $view = $_GET['view'] ?? 'dashboard'; ?> ProcurePulse | procurement.doudo.me
⚡ Host: procurement.doudo.me • All-in-One Engine • e-studio Server