diff --git a/public/modules/custom/grants_admin_applications/src/Form/DeleteApplicationsForm.php b/public/modules/custom/grants_admin_applications/src/Form/DeleteApplicationsForm.php index 79d0071ec..df10408cf 100644 --- a/public/modules/custom/grants_admin_applications/src/Form/DeleteApplicationsForm.php +++ b/public/modules/custom/grants_admin_applications/src/Form/DeleteApplicationsForm.php @@ -189,7 +189,12 @@ public function buildForm(array $form, FormStateInterface $form_state): array { // Build the application listing form elements. if ($uuid || $businessId) { - $this->buildApplicationList($uuid, $businessId, $appEnv, $type, $status, $form_state, $form); + try { + $this->buildApplicationList($uuid, $businessId, $appEnv, $type, $status, $form_state, $form); + } + catch (\Throwable $e) { + $this->messenger()->addError($e->getMessage()); + } } $form['actions']['delete_selected'] = [ @@ -365,6 +370,8 @@ private function deleteDraftDocuments(array $documents): void { * The form state. * @param array $form * The form. + * + * @throws \Drupal\helfi_helsinki_profiili\TokenExpiredException */ private function buildApplicationList( mixed $uuid, @@ -384,6 +391,13 @@ private function buildApplicationList( return; } + // Extract the transaction_id values and join them into a string. + $transactionIds = array_map(function ($document) { + return $document->getTransactionId(); + }, $documents); + + $applicationNumberList = implode(',', $transactionIds); + $form_state->setStorage(['documents' => $documents]); $documentsByType = $this->sortDocuments($documents); @@ -413,6 +427,15 @@ private function buildApplicationList( ]; } } + + // Add the application numbers list to a form element. + $form['appData']['application_numbers'] = [ + '#type' => 'textarea', + '#title' => $this->t('Application numbers in copyable list.'), + '#value' => $applicationNumberList, + '#description' => $this->t('Total number of results: @count', ['@count' => count($transactionIds)]), + '#disabled' => TRUE, + ]; } catch (AtvDocumentNotFoundException | AtvFailedToConnectException | GuzzleException $e) { $this->messenger()->addError('Failed fetching applications.'); diff --git a/public/modules/custom/grants_events/src/EventsService.php b/public/modules/custom/grants_events/src/EventsService.php index 8e88fd2f7..8ffa9df10 100644 --- a/public/modules/custom/grants_events/src/EventsService.php +++ b/public/modules/custom/grants_events/src/EventsService.php @@ -7,6 +7,7 @@ use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\grants_handler\DebuggableTrait; use Drupal\grants_metadata\AtvSchema; +use Drupal\helfi_atv\AtvDocument; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use Ramsey\Uuid\Uuid; @@ -67,6 +68,7 @@ class EventsService { 'MESSAGE_READ' => 'MESSAGE_READ', 'MESSAGE_RESEND' => 'MESSAGE_RESEND', 'HANDLER_ATT_OK' => 'HANDLER_ATT_OK', + 'HANDLER_SEND_INTEGRATION' => 'HANDLER_SEND_INTEGRATION', 'HANDLER_ATT_DELETE' => 'HANDLER_ATT_DELETE', 'HANDLER_RESEND_APP' => 'HANDLER_RESEND_APP', 'HANDLER_APP_COPIED' => 'HANDLER_APP_COPIED', @@ -139,7 +141,7 @@ public function logEvent( ): ?array { if (empty($eventData)) { - $eventData = self::getEventData($eventType, $applicationNumber, $eventDescription, $eventTarget); + $eventData = $this->getEventData($eventType, $applicationNumber, $eventDescription, $eventTarget); } $eventDataJson = Json::encode($eventData); @@ -212,7 +214,7 @@ public function filterEvents(array $events, string $typeKey): array { * @param string $eventDescription * Event description. * @param string $eventTarget - * Eent target. + * Event target. * * @return array * Event data in array. @@ -245,4 +247,22 @@ public function getEventData(string $eventType, string $applicationNumber, strin return $eventData; } + /** + * Add new event to application document. + * + * @param \Drupal\helfi_atv\AtvDocument $document + * Document to be updated. + * @param array $eventData + * Event data to be added. + */ + public function addNewEventForApplication(AtvDocument &$document, array $eventData): void { + $documentContent = $document->getContent(); + $documentEvents = $documentContent['events'] ?? []; + $documentEvents[] = $eventData; + $documentContent['events'] = $documentEvents; + + $document->setContent($documentContent); + + } + } diff --git a/public/modules/custom/grants_handler/grants_handler.services.yml b/public/modules/custom/grants_handler/grants_handler.services.yml index 12ba9cd06..103f38847 100644 --- a/public/modules/custom/grants_handler/grants_handler.services.yml +++ b/public/modules/custom/grants_handler/grants_handler.services.yml @@ -157,7 +157,8 @@ services: '@helfi_helsinki_profiili.userdata', '@grants_attachments.attachment_fixer_service', '@current_user', - '@database' + '@database', + '@grants_events.events_service' ] grants_handler.application_access_handler: diff --git a/public/modules/custom/grants_handler/src/ApplicationUploaderService.php b/public/modules/custom/grants_handler/src/ApplicationUploaderService.php index 9add608ed..e6fec073d 100644 --- a/public/modules/custom/grants_handler/src/ApplicationUploaderService.php +++ b/public/modules/custom/grants_handler/src/ApplicationUploaderService.php @@ -15,6 +15,7 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\grants_attachments\AttachmentFixerService; +use Drupal\grants_events\EventsService; use Drupal\grants_metadata\AtvSchema; use Drupal\helfi_atv\AtvDocument; use Drupal\helfi_atv\AtvService; @@ -83,6 +84,7 @@ public function __construct( private readonly AttachmentFixerService $attachmentFixerService, private readonly AccountInterface $currentUser, private readonly Connection $database, + private readonly EventsService $eventsService, ) { $this->logger = $this->loggerChannelFactory->get('application_uploader_service'); @@ -185,6 +187,7 @@ public function handleApplicationUploadToAtv( * @throws \Drupal\helfi_atv\AtvFailedToConnectException * @throws \GuzzleHttp\Exception\GuzzleException * @throws \Drupal\helfi_helsinki_profiili\TokenExpiredException + * @throws \Drupal\grants_events\EventException */ public function handleApplicationUploadViaIntegration( TypedDataInterface $applicationData, @@ -199,6 +202,25 @@ public function handleApplicationUploadViaIntegration( * for some reason. */ $updatedDocumentFromAtv = $this->handleApplicationUploadToAtv($applicationData, $applicationNumber, $submittedFormData); + + // Create new saveid before sending data to integration, + // so we can add it to event data. + $newSaveId = $this->logSubmissionSaveid( + NULL, + $applicationNumber, + $this->helfiHelsinkiProfiiliUserdata->getUserData() + ); + + // Add new event for sending it to integration. + $this->eventsService->addNewEventForApplication( + $updatedDocumentFromAtv, + $this->eventsService->getEventData( + $this->eventsService->getEventTypes()['HANDLER_SEND_INTEGRATION'], + $applicationNumber, + 'Send application to integration.', + $newSaveId + )); + $myJSON = Json::encode($updatedDocumentFromAtv->getContent()); // No matter what the debug value is, we do NOT log json in PROD. @@ -232,12 +254,8 @@ public function handleApplicationUploadViaIntegration( // Set application number to meta as well to enable better searches. $headers['X-hki-applicationNumber'] = $applicationNumber; - // Set new saveid and save it to db. - $headers['X-hki-saveId'] = $this->logSubmissionSaveid( - NULL, - $applicationNumber, - $this->helfiHelsinkiProfiiliUserdata->getUserData() - ); + // Set new saveid to header. + $headers['X-hki-saveId'] = $newSaveId; $res = $this->httpClient->post($this->endpoint, [ 'auth' => [ @@ -335,14 +353,13 @@ public function logSubmissionSaveid( 'saveid' => $saveId, 'uid' => $this->currentUser->id(), 'user_uuid' => $userData['sub'] ?? '', - 'timestamp' => (string) (new Time)->getRequestTime(), + 'timestamp' => (string) (new Time())->getRequestTime(), ]; $query = $this->database->insert(ApplicationHelpers::TABLE, $fields); $query->fields($fields)->execute(); return $saveId; - } } diff --git a/public/modules/custom/grants_handler/src/EventsService.php b/public/modules/custom/grants_handler/src/EventsService.php deleted file mode 100644 index 64e201a3b..000000000 --- a/public/modules/custom/grants_handler/src/EventsService.php +++ /dev/null @@ -1,247 +0,0 @@ - 'AVUSTUS2_MSG_OK', - 'AVUSTUS2_ATT_OK' => 'AVUSTUS2_ATT_OK', - 'STATUS_UPDATE' => 'STATUS_UPDATE', - 'MESSAGE_AVUS2' => 'MESSAGE_AVUS2', - 'MESSAGE_APP' => 'MESSAGE_APP', - 'MESSAGE_READ' => 'MESSAGE_READ', - 'MESSAGE_RESEND' => 'MESSAGE_RESEND', - 'HANDLER_ATT_OK' => 'HANDLER_ATT_OK', - 'HANDLER_ATT_DELETE' => 'HANDLER_ATT_DELETE', - 'HANDLER_RESEND_APP' => 'HANDLER_RESEND_APP', - 'HANDLER_APP_COPIED' => 'HANDLER_APP_COPIED', - 'INTEGRATION_INFO_ATT_OK' => 'INTEGRATION_INFO_ATT_OK', - 'INTEGRATION_INFO_APP_OK' => 'INTEGRATION_INFO_APP_OK', - 'EVENT_INFO' => 'EVENT_INFO', - 'HANDLER_ATT_DELETED' => 'HANDLER_ATT_DELETED', - 'INTEGRATION_ERROR_AVUS2' => 'INTEGRATION_ERROR_AVUS2', - 'INTEGRATION_ERROR_ATV_ATT' => 'INTEGRATION_ERROR_ATV_ATT', - ]; - - /** - * Constructs a MessageService object. - * - * @param \GuzzleHttp\Client $http_client - * Client to post data. - * @param \Drupal\Core\Logger\LoggerChannelFactory $loggerFactory - * Log things. - */ - public function __construct( - Client $http_client, - LoggerChannelFactoryInterface $loggerFactory, - ) { - $this->httpClient = $http_client; - $this->logger = $loggerFactory->get('grants_handler_events_service'); - - $this->endpoint = getenv('AVUSTUS2_EVENT_ENDPOINT'); - $this->username = getenv('AVUSTUS2_USERNAME'); - $this->password = getenv('AVUSTUS2_PASSWORD'); - - $this->setDebug(NULL); - - } - - /** - * Get event types. - * - * @return array|string[] - * Event types. - */ - public function getEventTypes(): array { - return $this->eventTypes; - } - - /** - * Log event to document via event integration. - * - * @param string $applicationNumber - * Application to be logged. - * @param string $eventType - * Type of event, must be configured in this class as active one. - * @param string $eventDescription - * Free message to be added. - * @param string $eventTarget - * Target ID for event. - * @param array $eventData - * If we have already built-up event data, use this. - * - * @return array|null - * EventID if success, otherways NULL - * - * @throws \Drupal\grants_handler\EventException - */ - public function logEvent( - string $applicationNumber, - string $eventType, - string $eventDescription, - string $eventTarget, - array $eventData = [], - ): ?array { - - if (empty($eventData)) { - $eventData = self::getEventData($eventType, $applicationNumber, $eventDescription, $eventTarget); - } - - $eventDataJson = Json::encode($eventData); - - if (TRUE === $this->debug) { - $this->logger->debug( - 'Event ID: %eventId, JSON: %json', - [ - '%eventId' => $eventData['eventID'], - '%json' => $eventDataJson, - ]); - } - - try { - - $res = $this->httpClient->post($this->endpoint, [ - 'auth' => [$this->username, $this->password, "Basic"], - 'body' => $eventDataJson, - ]); - - if ($res->getStatusCode() == 200) { - $this->logger->info('Event logged: %eventId, message sent.', ['%eventId' => $eventData['eventID']]); - return $eventData; - } - - } - catch (\Exception $e) { - throw new EventException($e->getMessage()); - } - catch (GuzzleException $e) { - throw new EventException($e->getMessage()); - } - - return NULL; - } - - /** - * Filter events by given key. - * - * @param array $events - * Events to be filtered. - * @param string $typeKey - * Event type wanted. - * - * @return array - * Filtered events. - */ - public function filterEvents(array $events, string $typeKey): array { - $messageEvents = array_filter($events, function ($event) use ($typeKey) { - if ($event['eventType'] == $this->eventTypes[$typeKey]) { - return TRUE; - } - return FALSE; - }); - - return [ - 'events' => $messageEvents, - 'event_targets' => array_column($messageEvents, 'eventTarget'), - 'event_ids' => array_column($messageEvents, 'eventID'), - ]; - } - - /** - * Build event object/array from given data. - * - * @param string $eventType - * Type of event, must be in self::$eventTypes. - * @param string $applicationNumber - * Application number for event. - * @param string $eventDescription - * Event description. - * @param string $eventTarget - * Eent target. - * - * @return array - * Event data in array. - * - * @throws \Drupal\grants_handler\EventException - */ - public function getEventData(string $eventType, string $applicationNumber, string $eventDescription, string $eventTarget): array { - $eventData = []; - - if (!in_array($eventType, $this->eventTypes)) { - throw new EventException('Not valid event type: ' . $eventType); - } - else { - $eventData['eventType'] = $eventType; - } - - $eventData['eventID'] = Uuid::uuid4()->toString(); - $eventData['caseId'] = $applicationNumber; - $eventData['eventDescription'] = AtvSchema::sanitizeInput($eventDescription); - $eventData['eventTarget'] = $eventTarget; - - if (!isset($eventData['eventSource'])) { - $eventData['eventSource'] = getenv('EVENTS_SOURCE'); - } - - $dt = new \DateTime(); - $dt->setTimezone(new \DateTimeZone('Europe/Helsinki')); - - $eventData['timeCreated'] = $eventData['timeUpdated'] = $dt->format('Y-m-d\TH:i:s'); - return $eventData; - } - -}