> For the complete documentation index, see [llms.txt](https://docs.eximee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eximee.com/zarzadzanie-aplikacja-biznesowa/zarzadzanie-konfiguracja/sterowanie-dostepnoscia-wniosku.md).

# Sterowanie dostępnością wniosku

**Mechanizm czasowej blokady** pozwala sterować dostępnością wniosku na podstawie parametrów konfiguracji biznesowej. Może być stosowany z przyczyn biznesowych lub technicznych. W przypadku aktywnej blokady użytkownik nie może rozpocząć składania wniosku i zostaje przekierowany na stronę z komunikatem o niedostępności.

Przykłady zastosowania:

* Awarie i krytyczne błędy - wyłączenie wniosku w przypadku znalezienia błędu. Dzięki temu klienci nie korzystają z wadliwego procesu, a deweloperzy mają czas na analizę i wdrożenie poprawki przed jego ponownym uruchomieniem.
* Przerwy techniczne i serwisowe - czasowe wyłączanie wniosku ze względu na zaplanowaną niedostępność systemów wewnętrznych lub zewnętrznych, od których zależy działanie wniosku (np. przerwa techniczna usług w dniu 12.08 w godzinach 21:00–00:00).
* Okresowa dostępność - ograniczenie możliwości składania wniosku wyłącznie do ściśle określonych ram czasowych (np. czasowo limitowane lokaty, wnioski rządowe).

**Parametry sterujące dostępnością** wniosku można definiować i edytować w zakładce **Konfiguracja** w widoku aplikacji w Eximee Designer. Szczegóły: [Konfiguracja z poziomu Low-code](/zarzadzanie-aplikacja-biznesowa/zarzadzanie-konfiguracja/konfiguracja-aplikacji-biznesowej-serwer-konfiguracji/konfiguracja-z-poziomu-low-code.md).

Aby zmienić wartości parametrów w dowolnym momencie, bez konieczności wydawania nowej wersji aplikacji, można nadpisać je w zakładce **Konfiguracja aplikacji** w Eximee Dashboard. Operacja jest dostępna dla użytkowników posiadających odpowiednie uprawnienia. Więcej informacji: [Modyfikacja (runtime) konfiguracji biznesowych](/zarzadzanie-aplikacja-biznesowa/zarzadzanie-konfiguracja/konfiguracja-aplikacji-biznesowej-serwer-konfiguracji/modyfikacja-runtime-konfiguracji-biznesowych.md).

## Przykładowa struktura Konfiguracji

Konfiguracja podzielona została na trzy logiczne bloki, dotyczące typu niedostępności wniosku:

* status globalny - związany z nastąpieniem nagłej awarii,
* przerwa techniczna - dotycząca planowanej, określonej w ramach czasowych blokady procesu,
* harmonogram - dostępność według określonych dat (i godzin).

```js
# --- 1. STATUS GLOBALNY (AWARIA) ---
form.globalStatus.isOutage=false
form.globalStatus.textContent=formUnavailabilityFailure-*

# --- 2. PRZERWA TECHNICZNA (MAINTENANCE) ---
form.maintenance.isScheduled=true
form.maintenance.startDate=2026-07-22T13:00:00
form.maintenance.endDate=2026-07-22T15:00:00
form.maintenance.textContent=formUnavailabilityMaintenance-*

# --- 3. HARMONOGRAM (SCHEDULE) ---
# Wartości: ALWAYS_AVAILABLE, EXACT_DATE_TIME, YEARLY_RECURRING
form.schedule.ruleType=YEARLY_RECURRING
form.schedule.textContent=formUnavailabilityScheduled-*

# Dla reguły: EXACT_DATE_TIME
form.schedule.exact.startDateTime=2026-01-01T08:00:00
form.schedule.exact.endDateTime=2026-12-31T23:59:59

# Dla reguły: YEARLY_RECURRING (Format MM-DD)
form.schedule.recurring.startMonthDay=07-01
form.schedule.recurring.endMonthDay=11-30
```

## Zasady i priorytety walidacji

Mechanizm działa w oparciu o architekturę kaskadową. Sprawdza warunki od najbardziej krytycznych do najbardziej ogólnych. Spełnienie warunku blokującego powoduje przerwanie obsługi formularza i wyświetlenie użytkownikowi odpowiedniego komunikatu o niedostępności.

| Parametr                                            | Format / Wartości                                                         | Opis                                                                                                                                                                       |
| --------------------------------------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| form.globalStatus.isOutage                          | true / false                                                              | Priorytet 1: Natychmiastowa blokada wniosku, ignoruje pozostałe ustawienia.                                                                                                |
| form.maintenance.isScheduled                        | true / false                                                              | Priorytet 2: Blokada wniosku w zdefiniowanym oknie czasowym przerwy technicznej.                                                                                           |
| form.schedule.ruleType                              | <p>ALWAYS\_AVAILABLE<br>EXACT\_DATE\_TIME<br>YEARLY\_RECURRING</p>        | Priorytet 3: Reguła harmonogramu sprawdzana, gdy nie ma awarii ani przerwy technicznej.                                                                                    |
| form.\*.textContent                                 | <p>nazwa artefaktu<br>(w formacie <code>nazwaArtefaktu-wersja</code>)</p> | <p>Treść odpowiedniego komunikatu błędu wyświetlanego użytkownikowi.<br><em>Zapis nazwaArtefaktu-\* oznacza najnowszą dostępną wersję artefaktu o podanej nazwie</em>.</p> |
| form.maintenance.startDate / endDate                | <p>data i godzina (w formacie<br><code>YYYY-MM-DDTHH:MM:SS</code>)</p>    | Początek i koniec planowanej przerwy technicznej.                                                                                                                          |
| form.schedule.exact.startDateTime / endDateTime     | <p>data i godzina (w formacie<br><code>YYYY-MM-DDTHH:MM:SS</code>)</p>    | Początek i koniec ścisłego, jednorazowego harmonogramu działania wniosku.                                                                                                  |
| form.schedule.recurring.startMonthDay / endMonthDay | data (w formacie `MM-DD`)                                                 | Miesiąc i dzień początku oraz końca cyklicznego działania wniosku.                                                                                                         |

Jeśli żaden warunek nie zostanie spełniony, skrypt kończy działanie bez błędu, co system interpretuje jako pełną dostępność wniosku.

## Konfiguracja dla poszczególnych środowisk

Parametry konfiguracji mogą przyjmować różne wartości w zależności od środowiska. Jest to przydatne na przykład wtedy, gdy wniosek powinien zostać zablokowany na środowisku produkcyjnym, ale nadal ma być dostępny na środowiskach deweloperskich i testowych, aby umożliwić jego uruchamianie i weryfikację przez deweloperów low-code oraz testerów.

Przykładowo parametr globalnej blokady może mieć wartość `true` wyłącznie na środowisku produkcyjnym:

```
form.globalStatus.isOutage=false
form.globalStatus.isOutage|prod=true
```

Wartości parametrów sterujących dostępnością należy przypisać do odpowiednich środowisk. Sposób oznaczania środowiska w kluczu konfiguracji oraz zasady wyboru wartości opisano na stronie: [Konfiguracja z poziomu Low-code](/zarzadzanie-aplikacja-biznesowa/zarzadzanie-konfiguracja/konfiguracja-aplikacji-biznesowej-serwer-konfiguracji/konfiguracja-z-poziomu-low-code.md#konfiguracjazpoziomulowcode-ustaleniesrodowiska).

## Przykład skryptu sterującego dostępnością wniosku

Skrypt weryfikuje, czy klient może otworzyć formularz wniosku, na podstawie zadeklarowanej konfiguracji. Walidacja opiera się na strukturze kaskadowej (priorytetowej), gdzie spełnienie jednego z warunków blokujących natychmiastowo przerywa procesowanie i wyświetla odpowiedni ekran błędu.

```js
function callService(context) {
   const globalStatusFlag = api.config.v1.getOrDefault('form.globalStatus.isOutage', 'false');
   const maintenanceFlag = api.config.v1.getOrDefault('form.maintenance.isScheduled', 'false');

   const maintenanceStartDate = api.config.v1.getOrDefault('form.maintenance.startDate', '');
   const maintenanceEndDate = api.config.v1.getOrDefault('form.maintenance.endDate', '');

   const scheduleRuleType = api.config.v1.getOrDefault('form.schedule.ruleType', 'ALWAYS_AVAILABLE'); 
   const scheduleExactStartDateTime = api.config.v1.getOrDefault('form.schedule.exact.startDateTime', ''); 
   const scheduleExactEndDateTime = api.config.v1.getOrDefault('form.schedule.exact.endDateTime', ''); 
   const scheduleRecurringStartMonthDay = api.config.v1.getOrDefault('form.schedule.recurring.startMonthDay', ''); 
   const scheduleRecurringEndMonthDay = api.config.v1.getOrDefault('form.schedule.recurring.endMonthDay', '');

   const globalStatusTextContent = api.config.v1.getOrDefault('form.globalStatus.textContent', 'formUnavailabilityFailure-*');
   const maintenanceTextContent = api.config.v1.getOrDefault('form.maintenance.textContent', 'formUnavailabilityMaintenance-*');
   const scheduleTextContent = api.config.v1.getOrDefault('form.schedule.textContent', 'formUnavailabilityScheduled-*');

   const now = new Date();

   // Priorytet 1: Awaria
   if (globalStatusFlag === 'true') {
       Logger.info("Zablokowano dostęp do wniosku. " + "globalStatusFlag=" + globalStatusFlag);
       throwBusinessError(globalStatusTextContent, "Wniosek niedostępny z powodu awarii");
   }

   // Priorytet 2: Przerwa techniczna
   if (maintenanceFlag === 'true') {
       const maintenanceStart = new Date(maintenanceStartDate);
       const maintenanceEnd = new Date(maintenanceEndDate);

       if (now >= maintenanceStart && now <= maintenanceEnd) {
           Logger.info(
               "Zablokowano dostęp do wniosku. " +
               "maintenanceFlag=" + maintenanceFlag +
               ", maintenanceStartDate=" + maintenanceStartDate +
               ", maintenanceEndDate=" + maintenanceEndDate
           );
           throwBusinessError(maintenanceTextContent, "Wniosek niedostępny z powodu planowanej przerwy technicznej");
       }
   }

   // Priorytet 3: Harmonogram
   if (scheduleRuleType === "EXACT_DATE_TIME") {
       const startDateTime = new Date(scheduleExactStartDateTime);
       const endDateTime = new Date(scheduleExactEndDateTime);

       if (now < startDateTime || now > endDateTime) {
           Logger.info(
               "Zablokowano dostęp do wniosku. " +
               "scheduleRuleType=" + scheduleRuleType +
               ", startDateTime=" + scheduleExactStartDateTime +
               ", endDateTime=" + scheduleExactEndDateTime
           );
           throwBusinessError(scheduleTextContent, "Wniosek niedostępny poza skonfigurowanym okresem dostępności");
       }
   } 
   // Uwaga: brak obsługi dla zakresu dat przechodzącego przez nowy rok (np. grudzień 2026 - luty 2027)
   else if (scheduleRuleType === "YEARLY_RECURRING") {
       const currentYear = now.getFullYear();
       const cycleStart = new Date(`${currentYear}-${scheduleRecurringStartMonthDay}T00:00:00`);
       const cycleEnd = new Date(`${currentYear}-${scheduleRecurringEndMonthDay}T23:59:59`);

       if (now < cycleStart || now > cycleEnd) {
           Logger.info(
               "Zablokowano dostęp do wniosku. " +
               "scheduleRuleType=" + scheduleRuleType +
               ", recurringStartMonthDay=" + scheduleRecurringStartMonthDay +
               ", recurringEndMonthDay=" + scheduleRecurringEndMonthDay
           );
           throwBusinessError(scheduleTextContent, "Wniosek niedostępny poza cyklicznym okresem dostępności");
       }
   }

   /**
   * Wyrzucenie błędu biznesowego
   */
   function throwBusinessError(textcontentName, errorDescription) {
       const builder = context.getErrorPageDefinitionBuilder();
       builder.bodyTextContent(textcontentName);
       builder.msg(errorDescription);
       context.throwBusinessException(builder);
   }
}
```

{% hint style="info" %}
Do pobierania parametrów konfiguracji użyto metody `getOrDefault()`. Jeśli wskazany klucz nie istnieje, metoda zwraca określoną w skrypcie wartość domyślną.
{% endhint %}

{% hint style="info" %}
Dobrą praktyką jest używanie metody `.msg` przy wywołaniu błędu biznesowego. Należy przekazywać w niej czytelny komunikat biznesowy - np. `.msg("Wniosek niedostępny")`. Zdefiniowany komunikat zostanie wypisany w logach, co ułatwi analizę i identyfikację błędów. Więcej informacji o błędach biznesowych: [Strony błędów](/budowanie-aplikacji/interfejs-uzytkownika/formularze/tworzenie-formularza/strony-bledow.md).
{% endhint %}

W celu zapewnienia poprawności działania mechanizmu, opisywany skrypt należy podpiąć na wniosek jako **EntryService** (zakładka Właściwości).

<figure><img src="/files/F15SBmPFFogH5rUqZRLd" alt=""><figcaption><p><em><strong>Ilustracja 1.</strong> Podpięcie skryptu jako Serwis wejścia na wniosek</em></p></figcaption></figure>

## Przykłady użycia (Scenariusze biznesowe)

| Sytuacja biznesowa                                 | Konfiguracja                                                                                                                                                                                            | Rezultat                                                                                                                |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Nagły błąd bazy danych                             | <ul><li><code>form.globalStatus.isOutage=true</code></li><li>Pozostałe parametry bez zmian</li></ul>                                                                                                    | Wniosek staje się natychmiast niedostępny.                                                                              |
| Wdrożenie nowej wersji zaplanowane na weekend      | <ul><li><code>form.maintenance.isScheduled=true</code></li><li><code>form.maintenance.startDate=2026-07-22T13:00:00</code></li><li><code>form.maintenance.endDate=2026-07-22T15:00:00</code></li></ul>  | Wniosek będzie niedostępny we wskazanym przedziale, a po jego zakończeniu zostanie automatycznie ponownie udostępniony. |
| Cykliczna dostępność programu “Dobry Start” (300+) | <ul><li><code>form.schedule.ruleType=YEARLY\_RECURRING</code></li><li><code>form.schedule.recurring.startMonthDay=07-01</code></li><li><code>form.schedule.recurring.endMonthDay=11-30</code></li></ul> | Wniosek będzie dostępny co roku we wskazanym okresie.                                                                   |
| Standardowy wniosek bez ograniczeń czasowych       | <ul><li><code>form.schedule.ruleType=ALWAYS\_AVAILABLE</code></li><li><code>form.globalStatus.isOutage=false</code></li><li><code>form.maintenance.isScheduled=false</code></li></ul>                   | Wniosek dostępny bez ograniczeń.                                                                                        |

## Przykłady komunikatów o niedostępności

W bankowości elektronicznej i mobilnej dobór słów w komunikatach (tzw. **UX writing**) bezpośrednio wpływa na poczucie bezpieczeństwa oraz zaufanie klienta. W Eximee Designer, treść wyświetlanego komunikatu jest definiowana w artefakcie **Treść formatowana** ([TextContent](/budowanie-aplikacji/interfejs-uzytkownika/formularze/biblioteka-komponentow-bazowych/4-tresci/tresc-formatowana-textcontent.md)) wskazanym w konfiguracji odpowiedniego rodzaju blokady.

### Dostępność wniosku co roku w określonym terminie

Komunikat powinien informować użytkownika, w jakim okresie wniosek jest dostępny, oraz zachęcać do ponownego skorzystania z niego w tym terminie.

* **Tytuł:** Wniosek będzie dostępny od 1 lipca
* **Treść:** Ten wniosek możesz złożyć od 1 lipca do 30 listopada. Zapraszamy do powrotu w tym terminie.

<figure><img src="/files/tNrmWQ5MwHpP6EegeLFj" alt=""><figcaption><p><em><strong>Ilustracja 2.</strong> Przykład komunikatu o harmonogramowej niedostępności wniosku</em></p></figcaption></figure>

### Awaria („Pracujemy nad tym”)

Komunikat powinien krótko wyjaśniać sytuację, informować o trwających pracach nad rozwiązaniem problemu oraz wskazywać użytkownikowi dalsze postępowanie. Nie należy umieszczać w nim szczegółów technicznych ani kodów błędów.

* **Tytuł:** Wniosek jest chwilowo niedostępny<br>
* **Treść:** Przepraszamy, występują trudności techniczne. Złożenie wniosku jest obecnie niemożliwe. Wiemy o problemie i pracujemy nad jego rozwiązaniem. Spróbuj ponownie za jakiś czas.

<figure><img src="/files/zzpn3hxUcZ5Dwxmufrya" alt=""><figcaption><p><em><strong>Ilustracja 3.</strong> Przykład komunikatu o niedostępności wniosku z powodu awarii</em></p></figcaption></figure>

### Przerwa techniczna

Treść komunikatu w trakcie trwania przerwy technicznej powinna jasno przedstawiać, w jakim terminie wniosek będzie ponownie dostępny.

* **Tytuł:** Trwają prace serwisowe<br>
* **Treść:** Ten wniosek jest niedostępny z powodu zaplanowanych prac technicznych. Prace potrwają do godziny 16:00. Przepraszamy za utrudnienia i zapraszamy ponownie po tej godzinie.

<figure><img src="/files/quqRmRCprLg17l6yJcgZ" alt=""><figcaption><p><em><strong>Ilustracja 4.</strong> Przykład komunikatu o niedostępności wniosku z powodu przerwy technicznej</em></p></figcaption></figure>

{% hint style="info" %}
Aplikacja demo: demoFormUnavailability\_app
{% endhint %}

{% hint style="info" %}
Pobierz plik i zaimportuj go w Eximee Designer, aby uruchomić aplikację na swoim środowisku.
{% endhint %}

{% file src="/files/ktMkzG4MY8XJJVjyFwOQ" %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.eximee.com/zarzadzanie-aplikacja-biznesowa/zarzadzanie-konfiguracja/sterowanie-dostepnoscia-wniosku.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
