Aplikacja rezerwacji sal konferencyjnych w Power Apps - od pomysłu do działającej aplikacji

Karolina RudaKarolina Ruda
15 min read

Rezerwacja sali konferencyjnej to jedno z zadań, z którym możemy spotkać się w codziennej pracy biurowej. W tym artykule pokażę, jak zbudowałam w Power Apps aplikację Canvas App Sala+, umożliwiającą rezerwację sal konferencyjnych – od zaprojektowania struktury danych w Dataverse, przez formularze i walidację rezerwacji, aż po automatyczną aktualizacje statusów i wysyłanie powiadomień.

1. Założenia projektu

Celem projektu jest stworzenie profesjonalnej aplikacji biznesowej, która umożliwi pracownikom firmy łatwe i bezproblemowe rezerwowanie dostępnych sal konferencyjnych. Aplikacja powinna łączyć intuicyjny interfejs z wydajną logiką biznesową oraz zapewniać pełną kontrolę nad danymi w backendzie.

Użytkownicy aplikacji powinni mieć możliwość:

  • Przeglądania listy dostępnych sal konferencyjnych wraz z ich opisem, lokalizacją, wyposażeniem i aktualnym statusem dostępności.

  • Korzystania z widoku kalendarza, który pokazuje zajęte i wolne terminy sal.

  • Dodawania rezerwacji poprzez formularz, z uwzględnieniem walidacji danych oraz sprawdzaniem kolizji terminów.

  • Przeglądania własnych rezerwacji oraz anulowania ich w razie potrzeby, z ograniczeniem: anulowanie rezerwacji jest niedozwolone na mniej niż 2 godziny przed rozpoczęciem spotkania.

  • (Dla użytkowników z uprawnieniami administratora) Zarządzania salami i rezerwacjami w panelu administracyjnym – dodawanie oraz edycja sal konferencyjnych oraz edycja rezerwacji.

Podczas implementacji funkcjonalności należy uwzględnić:

  • Walidację formularzy - tak aby wymagane pola były wypełnione, a wprowadzone dane poprawne.

  • Sprawdzanie kolizji terminów - aby jedna sala nie mogła być zarezerwowana w tym samym czasie przez różnych użytkowników.

  • Automatyczną aktualizację statusów rezerwacji po upływie terminu spotkania (np. zmiana statusu na „Zakończona”).

  • Bezpieczeństwo danych, poprzez przypisanie odpowiednich ról użytkownikom i ograniczenie widoczności oraz możliwości edycji danych w zależności od uprawnień.

  • Wsparcie dla automatycznych powiadomień i przypomnień o rezerwacjach

Dzięki tym założeniom aplikacja będzie nie tylko praktyczna i funkcjonalna, ale również bezpieczna i łatwa w użyciu, spełniając potrzeby zarówno zwykłych użytkowników, jak i administratorów systemu.

2. Tworzenie tabel i relacji w Dataverse

Podstawą każdej aplikacji biznesowej jest dobrze zaprojektowany model danych. W tym projekcie wykorzystaliśmy Microsoft Dataverse do przechowywania informacji o salach konferencyjnych oraz rezerwacjach.

2.1. Tabela SaleKonferencyjne

Ta tabela przechowuje wszystkie informacje o dostępnych salach w firmie. Zawiera kolumny takie jak:

  • SalaID (Autonumber) - unikalny identyfikator sali

  • NazwaSali (Text) - nazwa sali (wymagane)

  • Lokalizacja (Text) - lokalizacja sali (wymagane)

  • LiczbaMiejsc (Whole number) - liczba miejsc sali (wymagane)

  • Opis (Text) - opis sali (wymagane)

  • Dostępność (Yes/no) - informacja czy sala jest aktywna (wymagane)

  • Wyposażenie (Multiselect choice) - np. projektor, TV, flipchart (opcjonalne)

  • Zdjęcie (Image) - zdjęcie sali (opcjonalne)

2.2. Tabela RezerwacjeSal

Tabela RezerwacjeSal odpowiada za przechowywanie wszystkich dokonanych rezerwacji. Zawiera kolumny:

  • RezerwacjaID (Autonumber) - unikalny identyfikator rezerwacji

  • SalaID (Lookup do SaleKonferencyjne) - powiązanie z zarezerwowaną salą (wymagane)

  • StartRezerwacji (Date and time) - początek rezerwacji (wymagane)

  • KoniecRezerwacji (Date and time) - koniec rezerwacji (wymagane)

  • StatusRezerwacji (Choice) - aktualny status rezerwacji: “Aktywna“, “Anulowana“ lub “Zakończona“ (wymagane)

  • Cel (Text area) - cel spotkania (opcjonalne)

W Dataverse każda tabela posiada systemową kolumnę CreatedBy, przechowującą informacje o użytkowniku, który utworzył dany rekord. W naszym projekcie kolumna ta niejednokrotnie będzie wykorzystywana m.in. do filtrowania rekordów oraz wyświetlania informacji o osobie, która dokonała konkretnej rezerwacji.

2.3. Relacje między tabelami

W projekcie zastosowano relację jeden-do-wielu między tabelą SaleKonferencyjne a RezerwacjeSal. Oznacza to, że każda sala może mieć wiele rezerwacji, a każda rezerwacja jest przypisana tylko do jednej sali. Dzięki takiej strukturze łatwo filtrować rezerwacje dla konkretnej sali i utrzymać spójność danych w całym systemie.

3. Projektowanie UI - przegląd ekranów aplikacji

Aplikacja Sala+ została zaprojektowana z myślą o intuicyjnym i minimalistycznym interfejsie, który umożliwia użytkownikom łatwe przeglądanie dostępnych sal, zarządzanie rezerwacjami oraz kontrolowanie nadchodzących spotkań. Dodatkowo, dzięki zdefiniowaniu zmiennych przechowujących wartości kolorów w trigerze App OnStart, kolorystyka interfejsu może zostać w prosty sposób zmodyfikowana i dostosowana do aktualnych potrzeb.

Poniżej przedstawiam główne ekrany aplikacji wraz z opisem ich funkcjonalności i wizualnym podglądem.

3.1. Ekran startowy

Ekran startowy pełni funkcję powitalną. Użytkownik widzi nazwę i logo aplikacji oraz spersonalizowane powitanie. Przycisk „Rozpocznij” pozwala przejść do głównych funkcjonalności aplikacji.

3.2. Ekran “Sale Konferencyjne”

Ten ekran umożliwia użytkownikom przeglądanie dostępnych sal konferencyjnych. Zawiera listę sal wraz z podstawowymi informacjami, takimi jak nazwa oraz opis.

Po kliknięciu w “Szczegóły“ użytkownik może zapoznać się z bardziej szczegółowymi informacjami na temat wybranej sali oraz przejść do formularza rezerwacji sal po kliknięciu przycisku “Zarezerwuj“.

3.3. Ekran “Kalendarz rezerwacji“

Ekran „Kalendarz rezerwacji” pozwala użytkownikowi łatwo przeglądać wszystkie dokonane rezerwacje w formie wizualnej. Kontrolka kalendarza wskazuje dni z rezerwacjami za pomocą kropek, a po kliknięciu w konkretną datę wyświetlana jest lista rezerwacji na ten dzień – w tym nazwa sali, godziny rozpoczęcia i zakończenia oraz osoba, która dokonała rezerwacji. Dodatkowo użytkownik może filtrować rezerwacje po nazwie sali lub szybko wyczyścić filtry, aby zobaczyć pełny harmonogram.

3.4. Ekran “Dokonaj rezerwacji“

Ekran „Dokonaj rezerwacji” umożliwia użytkownikowi dodanie nowej rezerwacji poprzez intuicyjny formularz. Po prawej stronie znajduje się formularz, w którym użytkownik wybiera nazwę sali, datę i godzinę rozpoczęcia i zakończenia oraz cel spotkania. Po lewej stronie widoczny jest skrócony widok wybranej sali – nazwa, zdjęcie, liczba miejsc i wyposażenie – co pozwala użytkownikowi szybko zweryfikować szczegóły przed potwierdzeniem rezerwacji.

3.5. Ekran “Moje rezerwacje“

Ekran „Moje rezerwacje” umożliwia użytkownikowi szybki podgląd wszystkich swoich rezerwacji. Na liście widoczna jest nazwa sali, godziny rozpoczęcia i zakończenia, status rezerwacji oraz jej cel. Jeśli rezerwacja ma status „Aktywna” i rozpoczęcie spotkania jest odległe o więcej niż 2 godziny, użytkownik widzi przycisk pozwalający na jej anulowanie. Dodatkowo możliwe jest filtrowanie rezerwacji po statusie, nazwie sali lub dacie oraz szybkie wyczyszczenie wszystkich filtrów, co ułatwia odnalezienie interesujących informacji.

Po kliknięciu przycisku “Anuluj rezerwację“ pojawia się popup z zapytaniem, czy użytkownik na pewno chce anulować rezerwację.

3.6. Ekran “Panel Administratora“ zakładka “Rezerwacje“

Ekran „Panel administratora” – zakładka Rezerwacje umożliwia przeglądanie wszystkich rezerwacji dokonanych przez użytkowników. Na liście widoczna jest nazwa sali, godziny rozpoczęcia i zakończenia, status rezerwacji oraz użytkownik, który ją utworzył. Administrator ma możliwość edycji lub usunięcia każdej rezerwacji. Dodatkowo dostępne są filtry pozwalające wyszukiwać rezerwacje według nazwy użytkownika, statusu, nazwy sali oraz daty, a także opcja szybkiego wyczyszczenia wszystkich zastosowanych filtrów.

Po kliknięciu przycisku “Edytuj“ pojawia się formularz edycji wybranej rezerwacji.

Po kliknięciu przycisku “Usuń rezerwację“ pojawia się popup z zapytaniem, czy administrator na pewno chce usunąć rezerwację.

3.7. Ekran “Panel Administratora“ zakładka “Sale Konferencyjne“

Ekran „Panel administratora” – zakładka Sale Konferencyjne umożliwia przeglądanie wszystkich sal konferencyjnych w systemie. Administrator może przejść do edycji wybranej sali lub dodać nową salę konferencyjną, dzięki czemu łatwo zarządza zasobami dostępnymi dla użytkowników.

Po kliknięciu przycisku “Edytuj“ pojawia się formularz edycji sali.

Po kliknięciu przycisku “+“ z opisem “Dodaj nową salę“ pojawia się formularz umożliwiający dodanie nowej sali konferencyjnej.

4. Walidacje i logika biznesowa

Sama struktura danych oraz ekrany aplikacji nie wystarczą, aby zapewnić poprawne działanie systemu rezerwacji. Kluczowym elementem jest odpowiednia logika biznesowa oraz walidacje, które gwarantują spójność i bezpieczeństwo danych, a także komfort pracy użytkowników. W projekcie zaimplementowano szereg mechanizmów kontrolnych – od sprawdzania poprawności wypełnianych formularzy, przez zapobieganie kolizjom terminów, aż po automatyczne zmiany statusów rezerwacji i ograniczenia związane z możliwością anulowania spotkań.

4.1. Walidacja dat i godzin oraz sprawdzanie dostępności sali

Tworząc formularz dodawania nowej rezerwacji, należało zadbać o następujące zasady walidacji:

  • Wszystkie pola oznaczone jako wymagane muszą zostać wypełnione.

  • Rezerwacja nie może być dodana z datą lub godziną w przeszłości.

  • Godzina zakończenia rezerwacji nie może być wcześniejsza niż godzina rozpoczęcia.

  • Rezerwacja nie może zostać dodana, jeśli w wybranej sali istnieje już inna rezerwacja w tym samym przedziale czasowym.

Kod trigera OnSelect przycisku „Zatwierdź rezerwację” zawiera pełną logikę walidacji danych wprowadzanych przez użytkownika. W skrócie:

  1. Tworzone są zmienne DateTimeStart i DateTimeEnd, które wskazują na datę i godzinę rozpoczęcia oraz zakończenia rezerwacji na podstawie wartości wybranych w formularzu.

  2. Sprawdzana jest poprawność dat:

    • data rozpoczęcia nie może być przeszła,

    • data zakończenia musi być późniejsza niż data rozpoczęcia.

  3. Następnie następuje weryfikacja dostępności sali – w wybranym terminie nie może istnieć już aktywna rezerwacja dla tej samej sali.

  4. Jeżeli wszystkie warunki zostaną spełnione, formularz jest zatwierdzany (SubmitForm), użytkownik otrzymuje powiadomienie o powodzeniu operacji, a formularz jest resetowany, przygotowując go do wprowadzenia kolejnej rezerwacji.

//tworzenie zmiennych wskazujących na datę rozpoczęcia i zakończenia rezerwacji
Set(
    DateTimeStart,
    DateAdd(
        DateAdd(
            DateValue5.SelectedDate,
            Value(HourValue5.Selected.Value),
            TimeUnit.Hours
        ),
        Value(MinuteValue5.Selected.Value),
        TimeUnit.Minutes
    )
);
Set(
    DateTimeEnd,
    DateAdd(
        DateAdd(
            DateValue4.SelectedDate,
            Value(HourValue4.Selected.Value),
            TimeUnit.Hours
        ),
        Value(MinuteValue4.Selected.Value),
        TimeUnit.Minutes
    )
);

//sprawdzanie czy data rozpoczęcia nie jest datą przeszłą
If(
    DateTimeStart < DateAdd(
        Now(),
        0,
        TimeUnit.Minutes
    ),
    Notify(
        "Rezerwacja nie może zostać dokonana z datą przeszłą.",
        NotificationType.Error
    ),

//sprawdzanie czy data rozpoczęcia nie jest późniejsza niż data zakończenia rezerwacji
    If(
        DateTimeStart >= DateTimeEnd,
        Notify(
            "Data i godzina zakończenia muszą być późniejsze niż data i godzina rozpoczęcia.",
            NotificationType.Error
        ),

//sprawdzanie dostępności sali w wybranym terminie
        If(
            CountRows(
                Filter(
                    'Rezerwacje Sal',
                    SalaID.SalaID = Dropdown1.Selected.SalaID && 'Start Rezerwacji' <= DateTimeEnd && 'Koniec Rezerwacji' >= DateTimeStart && 'Status Rezerwacji' <> [@'Status Rezerwacji'].Anulowana
                )
            ) > 0,
            Notify(
                "W tym terminie sala jest już zarezerwowana",
                NotificationType.Error
            ),

//zatwierdzanie rezerwacji i resetowanie formularza
            SubmitForm(Form2);
            Notify(
                "Rezerwacja dodana pomyślnie!",
                NotificationType.Success
            );
            Set(
                varRec,
                Form2.LastSubmit
            );
            ResetForm(Form2);
        )
    )
)

4.2. Filtrowanie i wyświetlanie danych w galeriach

W aplikacji wykorzystano kilka galerii, dlatego istotne było, aby rekordy były wyświetlane w odpowiedni sposób, zgodnie z kontekstem danego ekranu i oczekiwaniami użytkownika.

Galeria w widoku Kalendarz rezerwacji wyświetla rezerwacje w porządku rosnącym według godziny rozpoczęcia, ograniczając widok do wybranego dnia w kalendarzu. Rekordy z anulowanymi rezerwacjami są pomijane, a dodatkowo można filtrować je po nazwie sali. Funkcja użyta do tego celu wygląda następująco:

SortByColumns(
    Filter(
        'Rezerwacje Sal',
        'Start Rezerwacji' >= DateAdd(
            _dateSelected,
            0,
            TimeUnit.Days
        ) && 'Start Rezerwacji' < DateAdd(
            _dateSelected,
            1,
            TimeUnit.Days
        ) && (SalaID.'Nazwa Sali' = Dropdown3_9.Selected.Value || IsBlank(Dropdown3_9.Selected.Value) && 'Status Rezerwacji' <> [@'Status Rezerwacji'].Anulowana)
    ),
    "kr_startrezerwacji",
    SortOrder.Ascending
)

Galeria w widoku Moje rezerwacje wyświetla wszystkie rezerwacje dokonane przez zalogowanego użytkownika. Rekordy są sortowane w kolejności malejącej według daty rozpoczęcia, dzięki czemu najnowsze rezerwacje pojawiają się na górze listy. Dodatkowo użytkownik może filtrować widok według:

  • statusu rezerwacji,

  • nazwy sali,

  • daty rozpoczęcia rezerwacji.

Filtr uwzględnia tylko aktywne wartości w polach wyboru – jeśli filtr nie jest ustawiony, wszystkie odpowiadające rekordy są wyświetlane. Funkcja użyta do tego celu wygląda następująco:

SortByColumns(
    Filter(
        'Rezerwacje Sal',
        'Created By'.'Primary Email' = User().Email && (IsBlank(Dropdown3_3.Selected.Value) || 'Status Rezerwacji' = Dropdown3_3.Selected.Value) && (IsBlank(Dropdown3_4.Selected.Value) || SalaID.'Nazwa Sali' = Dropdown3_4.Selected.Value) && (IsBlank(DatePicker1.SelectedDate) || 'Start Rezerwacji' >= DateAdd(
            DatePicker1.SelectedDate,
            0,
            TimeUnit.Days
        ) && 'Start Rezerwacji' < DateAdd(
            DatePicker1.SelectedDate,
            1,
            TimeUnit.Days
        ))
    ),
    "kr_startrezerwacji",
    SortOrder.Descending
)

Galeria w widoku Panel Administratora – Rezerwacje umożliwia przeglądanie wszystkich rezerwacji w systemie. Rekordy są sortowane w kolejności malejącej według daty rozpoczęcia, dzięki czemu najnowsze rezerwacje pojawiają się na górze listy. Administrator może filtrować dane według:

  • użytkownika, który utworzył rezerwację,

  • statusu rezerwacji,

  • nazwy sali,

  • daty rozpoczęcia rezerwacji.

Filtry działają dynamicznie – jeśli pole wyboru jest puste, wszystkie odpowiadające rekordy są wyświetlane. Takie podejście pozwala administratorowi w szybki sposób odnaleźć interesujące rezerwacje i zarządzać nimi.

SortByColumns(
    Filter(
        'Rezerwacje Sal',
        (IsBlank(Dropdown3_7.Selected.Value) || 'Created By'.'Full Name' = Dropdown3_7.Selected.Value) && (IsBlank(Dropdown3_5.Selected.Value) || 'Status Rezerwacji' = Dropdown3_5.Selected.Value) && (IsBlank(Dropdown3_6.Selected.Value) || SalaID.'Nazwa Sali' = Dropdown3_6.Selected.Value) && (IsBlank(DatePicker1_1.SelectedDate) || 'Start Rezerwacji' >= DateAdd(
            DatePicker1_1.SelectedDate,
            0,
            TimeUnit.Days
        ) && 'Start Rezerwacji' < DateAdd(
            DatePicker1_1.SelectedDate,
            1,
            TimeUnit.Days
        ))
    ),
    "kr_startrezerwacji",
    SortOrder.Descending
)

4.3. Ograniczenia użytkowników

W aplikacji wprowadzono mechanizmy kontroli dostępu i ograniczenia funkcjonalne, mające na celu zapewnienie prawidłowego działania systemu oraz ochronę danych.

Pierwszą sytuacją uwzględnioną w ograniczeniach użytkowników jest brak możliwości rezerwacji sal oznaczonych jako „Niedostępna“. W takim przypadku przycisk „Zarezerwuj“ w widoku szczegółowym sali jest nieaktywny, a sama sala nie pojawia się w dropdownie formularza rezerwacji, uniemożliwiając jej wybór.

Wartość właściwości Items dropdowna służącego do wyboru sali została ustawiona za pomocą poniższego wyrażenia. Dzięki temu w dropdownie wyświetlane są tylko sale dostępne, posortowane rosnąco według nazwy sali:

Sort(
    Filter(
        'Sale Konferencyjne',
        Dostępność = true
    ),
    'Nazwa Sali',
    SortOrder.Ascending
)

Kolejną sytuacją jest widoczność sekcji Panel Administratora. W trigerze OnStart aplikacji ustawiana jest zmienna isAdmin. Kod sprawdza, czy aktualnie zalogowany użytkownik należy do określonej grupy Office 365. Jeśli tak – zmienna isAdmin przyjmuje wartość true, jeśli nie – isAdmin = false.

Set(
    isAdmin,
    !IsBlank(
        LookUp(Office365Groups.ListGroupMembers("899c8404-8f9d-4df7-aedf-ed6704503ead").value,
        mail = User().Email
    )
));

W menu bocznym, dla przycisku “Panel Administratora”, wartość właściwości Visible została ustawiona na isAdmin. Dzięki temu przycisk jest widoczny wyłącznie dla użytkowników należących do określonej grupy administracyjnej.

Dla realizacji tego mechanizmu w aplikacji został dodany konektor Office365Groups, umożliwiający pobieranie członków grupy Office 365 i weryfikację uprawnień użytkownika.

Widok menu bocznego dla użytkownika z uprawnieniami administratora:

Widok menu bocznego dla użytkownika bez uprawnień administratora:

4.4. Zarządzanie statusem rezerwacji

Status rezerwacji “Zakończona“

Jednym z założeń aplikacji było zapewnienie automatycznej aktualizacji statusów rezerwacji po upływie terminu spotkania. W docelowym rozwiązaniu mechanizm ten powinien zostać zaimplementowany przy pomocy Power Automate Flow, który uruchamiałby się cyklicznie i zmieniał statusy rezerwacji w bazie danych. Niestety, w przypadku darmowego konta developerskiego Power Platform istnieją ograniczenia – Dataverse jest traktowany jako connector premium, a jego obsługa w Power Automate nie jest dostępna w tej wersji.

Z tego względu zachowanie to zostało zasymulowane w aplikacji. W zdarzeniu App OnStart umieszczono wyrażenie:

UpdateIf(
    'Rezerwacje Sal',
    'Status Rezerwacji' = [@'Status Rezerwacji'].Aktywna && 'Koniec Rezerwacji' < DateAdd(
        Now(),
        0,
        TimeUnit.Minutes
    ),
    {'Status Rezerwacji': [@'Status Rezerwacji'].Zakończona}
);

Kod ten aktualizuje wszystkie rezerwacje posiadające status “Aktywna“, których czas zakończenia już minął, ustawiając im status “Zakończona”.

Należy jednak zaznaczyć, że rozwiązanie to nie jest idealne – wyrażenie uruchamia się dopiero w momencie startu aplikacji, więc do tego czasu statusy pozostają niezmienione. Ma ono jedynie na celu zasymulowanie poprawnego działania aplikacji. W pełnej wersji (z wykorzystaniem Power Automate i connectorów premium) taki mechanizm mógłby działać w sposób w pełni automatyczny.

Status rezerwacji “Anulowana“

Kolejnym założeniem dotyczącym zarządzania statusem rezerwacji jest możliwość anulowania danego rekordu przez użytkownika, z zaznaczeniem, że anulowanie rezerwacji jest niedozwolone na mniej niż 2 godziny przed rozpoczęciem spotkania.

W rekordach rezerwacji użytkownika przycisk „Anuluj rezerwację” jest widoczny tylko wtedy, gdy rezerwacja posiada status “Aktywna” i do rozpoczęcia rezerwacji pozostało więcej niż 2 godziny. W przeciwnym razie przycisk jest nieaktywny, a obok niego wyświetlana jest ikonka „i” z podpowiedzią:
„Nie można anulować rezerwacji — do rozpoczęcia pozostało mniej niż 2 godziny.”

Widok aktywnego przycisku “Anuluj rezerwację“:

Widok nieaktywnego przycisku oraz podpowiedzi:

4.5. Powiadomienia i integracja z kalendarzem

Kolejnym założeniem aplikacji było powiadamianie użytkowników o dokonanych rezerwacjach oraz przypominanie o nadchodzących spotkaniach. W idealnym scenariuszu mechanizmy te zostałyby zaimplementowane przy pomocy Power Automate Flow, które – w momencie utworzenia rekordu w tabeli Rezerwacje Sal – automatycznie wysyłałyby wiadomości e-mail z potwierdzeniami i przypomnieniami. Niestety, z uwagi na ograniczenia darmowego konta developerskiego (brak dostępu do connectorów premium, w tym Dataverse), konieczne było zastosowanie alternatywnego rozwiązania.

Potwierdzenie rezerwacji

Po pomyślnym zapisaniu formularza rezerwacji uruchamiane są dwie akcje w zdarzeniu OnSuccess:

  1. Wysłanie wiadomości e-mail z potwierdzeniem rezerwacji, zrealizowane przy użyciu connectora Office365Outlook i metody SendEmailV2(). Wiadomość zawiera dane takie jak: sala, termin spotkania oraz ewentualny cel rezerwacji. Dzięki formatowaniu HTML wiadomość jest czytelna i profesjonalna.
Office365Outlook.SendEmailV2(
    User().Email,
    "Potwierdzenie rezerwacji: " & LookUp(
        'Sale Konferencyjne',
        SalaID = varRec.SalaID.SalaID
    ).'Nazwa Sali',
    "Cześć " & User().FullName & ",<br><br>" & "Potwierdzamy dokonanie rezerwacji w czasie: " & Text(
        varRec.'Start Rezerwacji',
        "dd mmmm yyyy HH:mm",
        "pl-PL"
    ) & " - " & Text(
        varRec.'Koniec Rezerwacji',
        "dd mmmm yyyy HH:mm",
        "pl-PL"
    ) & "<br>Miejsce spotkania: " & LookUp(
        'Sale Konferencyjne',
        SalaID = varRec.SalaID.SalaID
    ).'Nazwa Sali' & If(
        !IsBlank(varRec.Cel),
        "<br>Cel spotkania: " & varRec.Cel
    ) & "<br><br>Pozdrawiamy," & "<br>Zespół Sala+",
    {IsHtml: true}
);

  1. Dodanie wydarzenia do kalendarza użytkownika (V4CalendarPostItem()) – zastosowane jako obejście problemu przypomnień. Każde wydarzenie ma ustawione automatyczne przypomnienie na 60 minut przed rozpoczęciem spotkania. W ten sposób udało się zasymulować mechanizm przypomnień, którego nie można było zrealizować poprzez Power Automate.
Office365Outlook.V4CalendarPostItem(
    "Calendar",
    "Rezerwacja: " & LookUp(
        'Sale Konferencyjne',
        SalaID = varRec.SalaID.SalaID
    ).'Nazwa Sali',
    Text(
        varRec.'Start Rezerwacji',
        DateTimeFormat.UTC
    ),
    Text(
        varRec.'Koniec Rezerwacji',
        DateTimeFormat.UTC
    ),
    "UTC",
    {
        Body: "Twoja rezerwacja sali konferencyjnej",
        Location: LookUp(
            'Sale Konferencyjne',
            SalaID = varRec.SalaID.SalaID
        ).'Nazwa Sali',
        IsReminderOn: true,
        ReminderMinutesBeforeStart: 60
    }
)

Potwierdzenie anulowania rezerwacji

Podobny mechanizm działa przy anulowaniu rezerwacji – użytkownik otrzymuje wiadomość e-mail z informacją o anulowaniu spotkania. Wiadomość zawiera również przypomnienie o konieczności ręcznego usunięcia wydarzenia z kalendarza, ponieważ obecna implementacja nie obsługuje tej operacji automatycznie.

Office365Outlook.SendEmailV2(
    User().Email,
    "Potwierdzenie anulowania rezerwacji: " & LookUp(
        'Sale Konferencyjne',
        SalaID = varRec.SalaID.SalaID
    ).'Nazwa Sali',
    "Cześć " & User().FullName & ",<br><br>" & "Właśnie anulowałeś rezerwację zaplanowaną na: " & Text(
        varRec.'Start Rezerwacji',
        "dd mmmm yyyy HH:mm",
        "pl-PL"
    ) & " - " & Text(
        varRec.'Koniec Rezerwacji',
        "dd mmmm yyyy HH:mm",
        "pl-PL"
    ) & " w " & LookUp(
        'Sale Konferencyjne',
        SalaID = varRec.SalaID.SalaID
    ).'Nazwa Sali' & ".<br>Nie zapomnij nanieść zmian w swoim kalendarzu." & "<br><br>Pozdrawiamy," & "<br>Zespół Sala+",
    {IsHtml: true}
);

Ograniczenia rozwiązania

Należy podkreślić, że jest to rozwiązanie zastępcze – dodawanie wydarzeń do kalendarza nie było pierwotnym założeniem aplikacji, a jedynie sposobem na obejście braku możliwości korzystania z Power Automate. Dzięki temu użytkownicy otrzymują przypomnienie o rezerwacji, jednak proces nie jest w pełni zautomatyzowany (np. brak możliwości automatycznego usuwania wydarzeń po anulowaniu). W docelowym wdrożeniu, przy pełnych licencjach, mechanizmy te mogłyby zostać zrealizowane w sposób bardziej profesjonalny i kompletny.

4.6. Uprawnienia użytkowników

Uprawnienia administratora

Na potrzeby aplikacji zostały utworzone konta pracowników firmy w Azure Entra ID. Dodatkowo stworzono dwie grupy typu security – Employees oraz Admins. Na tej podstawie weryfikowany jest dostęp do wspomnianego wcześniej Panelu Administratora:

  • użytkownicy przypisani do grupy Employees posiadają wyłącznie standardowe funkcjonalności aplikacji,

  • członkowie grupy Admins uzyskują dostęp do rozszerzonych funkcji administracyjnych.

Role bezpieczeństwa w Power Platform

Kolejnym krokiem było nadanie odpowiednich uprawnień w Power Platform Admin Center. W tym celu stworzono dwie nowe role bezpieczeństwa (security roles):

  • Employee Role – rola przypisana standardowym użytkownikom aplikacji.

    • Dla tabeli Rezerwacje Sal: uprawnienia Create: User, Read: Organization, Write: User, Delete: None.

    • Dla tabeli Sale Konferencyjne: uprawnienia ograniczone do Read: Organization (tylko odczyt).

  • Admin Role – rola przypisana administratorom.

    • Dla tabeli Rezerwacje Sal: pełny dostęp (Create, Read, Write, Delete: Organization).

    • Dla tabeli Sale Konferencyjne: pełny dostęp do edycji danych (Create, Read, Write, Delete: Organization).

Dzięki temu udało się odseparować standardowych użytkowników od administratorów, zapewniając właściwy podział ról i bezpieczeństwo danych w aplikacji.

5. Podsumowanie i wnioski

Celem projektu było przygotowanie aplikacji umożliwiającej rezerwację sal konferencyjnych w firmie, z uwzględnieniem logiki biznesowej, walidacji danych oraz kontroli dostępu użytkowników. W ramach realizacji zadania wdrożono mechanizmy: walidacji pól formularza, filtrowania i prezentacji danych w galeriach, obsługi statusów rezerwacji, a także ograniczeń w dostępie do funkcjonalności w zależności od roli użytkownika.

W trakcie pracy pojawiły się pewne ograniczenia wynikające z korzystania z darmowego konta Power Platform Developer – przede wszystkim brak możliwości wykorzystania Power Automate z konektorami premium. W związku z tym część funkcjonalności musiała zostać zasymulowana w kodzie aplikacji. Mimo tych ograniczeń udało się przygotować działające rozwiązanie, które w pełni spełnia początkowe założenia.

Wnioskiem z realizacji projektu jest potwierdzenie, że platforma Power Apps umożliwia w krótkim czasie zbudowanie użytecznej aplikacji biznesowej, nawet przy ograniczonych zasobach. Jednocześnie widać wyraźnie, że wykorzystanie pełnego środowiska produkcyjnego wraz z Power Automate oraz rozszerzonymi konektorami znacząco zwiększyłoby możliwości i pozwoliło na pełną automatyzację procesów.

0
Subscribe to my newsletter

Read articles from Karolina Ruda directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Karolina Ruda
Karolina Ruda

Zagłębiam się w świat Power Platform i dzielę się swoimi doświadczeniami, tworząc praktyczne i kreatywne rozwiązania.