$event, 'data' => $data, 'company_id' => $company_id]; if ($target) $payload['target'] = $target; if ($user_id) $payload['user_id'] = $user_id; $body = json_encode($payload); $ch = curl_init(defined('NODE_EMIT_URL') ? NODE_EMIT_URL : 'http://127.0.0.1:3000/emit'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'x-emit-secret: ' . (defined('NODE_EMIT_SECRET') ? NODE_EMIT_SECRET : ''), ], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 1, // never block PHP CURLOPT_CONNECTTIMEOUT => 1, ]); curl_exec($ch); curl_close($ch); } /** * emit_notification — push a real-time notification to all browser tabs in a company. * * The browser shows a toast immediately and adds the item to the bell dropdown. * * @param int $company_id Target company * @param string $title Short heading, e.g. 'PO Approved' * @param string $message Detail line, e.g. 'PO-2605-00042 has been approved.' * @param string $type 'success' | 'info' | 'warning' | 'danger' (default 'info') */ // Company-wide notification — all users in the company see the toast. function emit_notification(int $company_id, string $title, string $message, string $type = 'info'): void { notify_node('notification', [ 'title' => $title, 'message' => $message, 'type' => $type, ], $company_id); } // Document notification — the acting user + all admins/owners see the toast. Other staff/viewers do not. function emit_notification_user(int $company_id, int $user_id, string $title, string $message, string $type = 'info'): void { notify_node('notification', [ 'title' => $title, 'message' => $message, 'type' => $type, ], $company_id, 'user', $user_id); } function gl_posted_payload(string $doc_type, int $id, string $action, array $lines): array { $has_revenue = false; $has_expense = false; foreach ($lines as $line) { $code = (int)($line['account_code'] ?? 0); if ($code >= 4000 && $code < 5000) $has_revenue = true; if ($code >= 5000) $has_expense = true; } return [ 'doc_type' => $doc_type, 'id' => $id, 'action' => $action, 'has_revenue' => $has_revenue, 'has_expense' => $has_expense, ]; }