Automatyczne odświeżanie formatki Dynamics 365 CE w momencie aktualizacji rekordu podrzędnego

Dynamics 365, Dynamics CRM

Kto nie spotkał się nigdy z opisanym poniżej wymaganiem funkcjonalnym, palec do budki! 🙂

  • W systemie Dynamics 365 CE istnieją encje: foo_parententity i foo_childentity. Są one powiązane relacją 1:N.
  • W momencie utworzenia, aktualizacji bądź usunięcia rekordu foo_childentity następuje synchroniczne (plugin, workflow, itp.) przeliczenie wartości w nadrzędnym rekordzie foo_parententity.
  • W przypadku modyfikacji rekordu „dziecka” z poziomu tabeli na formatce „rodzica” – wymagane jest automatyczne odświeżenie danych na tejże formatce.

Temat na pierwszy rzut oka wydaje się być banalnym. API systemu Dynamics 365 CE oferuje możliwość uruchomienia dowolnego kodu JavaScript w momencie odświeżenia danych w tabeli. Zgodnie z dokumentacją w przypadku edytowalnego grida możemy użyć funkcji podłączonej do zdarzenia OnSave. W przypadku tabeli „tylko do odczytu” możemy natomiast uruchomić dowolny kod przy przeładowaniu jej zawartości. Wygląda to w następujący sposób:

myGridFooChildrenControl.addOnLoad(function(){
    //TODO: My code goes here…
});

Wydawałoby się, że wystarczy już tylko wywołać metodę  formContext.data.refresh(save) (Dynamics 365 9.0) lub Xrm.Page.data.refresh(save) (Dyn365 8.x i starsze wersje) i sprawa jest załatwiona. Otóż nie do końca…

Poniżej znajdziecie opis kilku sytuacji w których użycie opisanego powyżej sposobu nie zadziała w oczekiwany sposób:

  • [Read-only Grid] W przypadku tabeli „tylko do odczytu” wywołanie funkcji formContext.data.refresh w momencie aktualizacji danych w tabeli spowoduje  przeładowanie całej formatki wraz z tabelą, która była źródłem zdarzenia. Efektem tego działania jest nieskończony łańcuch wywołań przed którym musimy zabezpieczyć się w kodzie. Jest to oczywiście możliwe, aczkolwiek powoduje konieczność implementacji dodatkowej logiki.  Nie chroni również przed jakże niepożądanym efektem chwilowego „migotania” (spowodowanego asynchronicznym przeładowywaniem danych) formatki Dynamics 365.
  • [Read-only Grid] W przypadku usuwania rekordu z tabeli funkcja obsługująca zdarzenia OnLoad na tabeli zostanie wywołana dwukrotnie. Pierwszy raz w momencie naciśnięcia ikony „kosza na śmieci” przy rekordzie w tabeli. Drugi raz – w momencie potwierdzenia operacji usunięcia rekordu w oknie które pojawi się po wykonaniu pierwszej z omawianych operacji. Może doprowadzić to do sytuacji w której dojdzie do niepotrzebnego przeładowania danych na formatce w sytuacji w której użytkownik najpierw naciśnie przycisk usuwania na rekordzie w tabeli, a następnie w oknie służącym do potwierdzenie tej operacji – pacnie w przycisk „Anuluj”.
  • W przypadku w którym użytkownik zmodyfikuje dane w tabeli, posiadając jednocześnie wprowadzone, ale niezapisane dane na obiekcie nadrzędnym, system automatycznie zapisze te dane (w przypadku następującego wywołania funkcji: formContext.data.refresh(true)) lub wyświetli użytkownikowi okno w którym będzie musiał on potwierdzić operacje ich zapisania (formContext.data.refresh(false)). W obu przypadkach może dojść do zapisania niepożądanych danych lub (w  przypadku numer 2) do nieodświeżenia zawartości formatki.
  • W przypadku aktualizacji rekordu w tabeli w osobnym oknie – zawartość tabeli na formatce „rodzicu” odświeżana jest tylko w przypadku w którym użytkownik naciśnie na formatce edytowanego rekordu przycisk „Zapisz” („Save”). Tymczasem aktualizacja danych na podrzędnym rekordzie może zajść nie tylko w wyniku ww. zdarzania. Efektem tego będą  ponownie nieodświeżone dane na formatce rekordu nadrzędnego. Do zachowania tego typu może dojść w następującej sytuacji:
    • W systemie istnieją encje: foo_parent, foo_child (w relacji N:1 do foo_parent) oraz foo_grandchild (w relacji N:1 do foo_child).
    • Formatka foo_parent zawiera tabelę prezentującą rekordy encji foo_child (do tworzenia których używamy standardowej formatki).
    • Formatka foo_child zawiera tabelę prezentującą rekordy encji foo_grandchild (do tworzenia których wykorzystamy formatkę typu „Quick Create”).
    • Utworzenie lub aktualizacja rekordu foo_grandchild powoduje synchroniczne przeliczenie danych prezentowanych na formatce foo_child. Formatka foo_child jest odświeżana w momencie aktualizacji danych w tabeli foo_grandchild.
    • Utworzenie lub aktualizacja rekordu foo_child powoduje synchroniczne przeliczenie danych prezentowanych na formatce foo_parent. Formatka foo_parent jest odświeżana w momencie aktualizacji danych w tabeli foo_child.
    • Do istniejącego rekordu foo_parent dodajemy rekord podrzędny typu foo_child. Ponieważ foo_child nie posiada formatki szybkiego tworzenia nowego rekordu – jest on dodawany w nowym oknie przeglądarki (popup).
    • Do nowoutworzonego rekordu foo_child (otwartego cały czas w osobnym oknie przeglądarki)  dodajemy rekord podrzędny foo_grandchild. Możemy w tym przypadku skorzystać z formatki szybkiego tworzenia rekordu.
    • Dodanie rekordu foo_grandchild spowoduje aktualizacje danych i odświeżenie formatki foo_child. Jednak ponieważ operacja ta odbywa się bez udziału użytkownika (nie występuje naciśnięcie przycisku zapisu na formatce foo_child)  – formatka foo_parent nie otrzymuje informacji o tym, że dane na jej obiekcie podrzędnym zostały zaktualizowane i nie dochodzi do odświeżenia zaktualizowanych danych, która to operacja byłoby w tym  momencie pożądana.

Powyższa lista nie wyczerpuje na pewno przypadków w których możemy napotkać problemy przy implementacji opisanej na początku artykułu funkcjonalności. W jaki sposób powinniśmy w takim razie podejść do omawianego zagadnienia? Osobiście uważam, że najlepszym sposobem byłoby wyświetlenie (np. za pomocą funkcji: addNotification) stosownego,  informującego o potencjalnie nieaktualnych danych na formatce, monitu dla użytkownika w momencie przeładowania danych w gridzie. Dodatkowo w menu Dynamics 365 CE możemy dodać niestandardowy przycisk pozwalający użytkownikowi na odświeżenie danych w oknie systemu bez jej całkowitego przeładowania w przeglądarce. Powyższe rozwiązanie nie jest może idealne (wymaga dodatkowej akcji wykonywanej przez użytkownika), ale moim skromnym zdaniem i tak jest lepsze od prezentowania nieaktualnych wartości w sytuacji, w której użytkownik systemu oczekuje, że widoczne dane będą zawsze odświeżane w sposób automatyczny.

Total Views: 343 ,