wiki:Documentatie/Ontwikkelaar/OpenAC3/Scriptfuncties

Version 21 (modified by henk, 6 years ago) (diff)

--

TOC(heading=Scriptfuncties)? TOC(heading=OpenAC3, sectionindex, compact, depth=3, allactive, Documentatie/Ontwikkelaar/OpenAC3/)? TOC(heading=Ontwikkelaar, sectionindex, compact, depth=2, allactive, Documentatie/Ontwikkelaar/)? TOC(heading=Documentatie, sectionindex, compact, depth=1, allactive, Documentatie/)?

Scriptfuncties

NoteBox(tip, Deze pagina moet tzt een andere plek krijgen.)?

Het doel van OpenAC 3 scriptfuncties is:

  • een nabewerking uitvoeren nadat een entry is opgeslagen. Voorbeeld: nadat een AP-verrichting is ingevoerd moet het subtraject opnieuw worden uitgerekend.
  • een controle uitvoeren voordat een entry wordt opgeslagen.

Context

Scriptfuncties worden uitgevoerd binnen een bepaalde context. De context bestaat uit 3 elementen:

  1. Entiteit: bijvoorbeeld Bezoek of Zorgtraject
  2. Type actie: bijvoorbeeld UPDATE of DELETE
  3. Wanneer: voor- of nadat de actie is uitgevoerd

Entiteit

De entiteit wordt aangeduid met een notatie die overeenkomt met het ACL-pad:

  • Zorgtraject: patient/behandelingen
  • Bezoek: patient/behandelingen/behandeldagen

Type actie

Scriptfuncties kunnen worden uitgevoerd voor de volgende acties:

  • CREATE
  • DELETE
  • UPDATE
  • LOAD

Wanneer

Scriptfuncties kunnen worden uitgevoerd voor of na een actie, aangeduid met:

  • BEFORE
  • AFTER

Uitvoeren van scriptfuncties

Het uitvoeren van scriptfuncties wordt aangevraagd door een controller. Een controller geeft hiertoe de context op waarbinnen scriptfuncties moeten worden uitgevoerd. De controller zegt in gewoon nederlands:

  1. Voer alle scriptfuncties uit voor entiteit Bezoek. De actie is UPDATE en de actie is al uitgevoerd (AFTER)
  2. Voer alle scriptfuncties uit voor entiteit Bezoek. De actie is DELETE en de actie is nog niet uitgevoerd (BEFORE)

Scriptfuncties worden uitgevoerd voor alle geregistreerde contexten. Als er meerdere scriptfuncties zijn geregistreerd voor één context dan worden ze allemaal uitgevoerd. Zie Registratie voor informatie over het registreren van scriptfuncties.

Om scriptfuncties uit te voeren moet eerst klasse TabelScriptRunner worden geïnstantieerd:

var scriptRunner = new TabelScriptRunner();

Vervolgens kan het uitvoeren van tabelscripts voor een context worden aangevraagd:

var result = await scriptRunner.ExecuteAsync(new PathElement("patient(ACH-H12345)/behandelingen(ACH-H54321)"), HubCommand.UPDATE, TabelScriptWhen.AFTER, new TabelScriptResult());

Bovenstaande aanroep zorgt ervoor dat alle scriptfuncties worden uitgevoerd die voor deze context zijn geregistreerd.

In echte code wordt de PathElement instantie al eerder aangemaakt, met als argument een aan de controller meegegeven pad. TabelScripts gebruikt PathElement.ACLPath om alle scriptfuncties uit te voeren die zijn geregistreerd voor "patient/behandelingen" en AFTER UPDATE. Scriptfuncties gebruiken PathElement.Key om zorgtraject ACH-H54321 op te halen als deze niet is meegegeven of door een eerder uitgevoerde scriptfunctie is opgehaald.

Een nieuwe scriptfunctie maken

Je kunt een nieuwe scriptfunctie maken door interface ITabelScript te implementeren:

public interface ITabelScript
{
    IEnumerable<TabelScriptRegistration> RegisterFor { get; }
    Task<TabelScriptResult> ExecuteAsync(IServiceProvider serviceProvider, PathElement path, string command, TabelScriptWhen when, TabelScriptResult scriptResult);
}


Scriptfuncties die horen bij de kern van OpenAC staan in OpenACLogica\Modules\Tabellen\Scripts. Scriptfuncties specifiek voor module <x> horen thuis in OpenACLogica\Modules\<x>\Scripts. Geef scriptfuncties een naam die past bij de entiteit waar ze betrekking op hebben met suffix Script, zoals ZorgtrajectScript.

Te implementeren functies

RegisterFor

Deze functie geeft één of meerdere contexten terug waarvoor het script moet worden geregistreerd. Bijvoorbeeld:

public IEnumerable<TabelScriptContext > RegisterFor => new List<TabelScriptRegistration> {
    new TabelScriptContext { Command = HubCommand.DELETE, When = TabelScriptWhen.BEFORE, Path = "patient/behandelingen/fin_trajecten" },
    new TabelScriptContext { Command = HubCommand.DELETE, When = TabelScriptWhen.AFTER, Path = "patient/behandelingen/fin_trajecten" },
    new TabelScriptContext { Command = HubCommand.UPDATE, When = TabelScriptWhen.AFTER, Path = "patient/behandelingen/fin_trajecten" }        
};

Je hoeft de scriptfunctie niet zelf te registeren, dat gebeurt "automatisch". Zie Registratie voor een technische beschrijving van dit proces.

ExecuteAsync

ExecuteAsync wordt aangeroepen als een controller voor een bepaalde context scriptRunner.ExecuteAsync aanroept. Dit gebeurt voor alle scriptfuncties waarvoor de opgegeven context is geregistreerd.

De functie krijgt een TabelScriptResult mee als argument en geeft ook een TabelelScriptResult terug. Op die manier kunnen meerdere scriptfuncties iets toevoegen aan het uiteindelijke resultaat.

Data en ParentData

In de ExecuteAsync method zijn data die nodig zijn om een UPDATE scriptfunctie uit te voeren beschikbaar in scriptResult.Data. Soms is het ook nodig om te beschikken over de data van een parent. Bijvoorbeeld in een scriptfunctie voor een bezoek kan het nodig zijn om te beschikken over de data van het zorgtraject waar het bezoek bij hoort. Parent data kan worden opgevraagd met de functie scriptResult.GetParent() . Deze functie kan null teruggeven. In dat geval is de conventie om de parent data op te halen en toe te voegen aan scriptResult met scriptResult.SetParent() .

var zorgtrajectData = scriptResult.GetParent("behandeling");
var zorgtrajectPad = path.Pop();
if (zorgtrajectData == null)
{
    var tabelRepo = serviceProvider.GetService<ITabelRepo<Tabel>>();
    zorgtrajectData = await tabelRepo.GetData("behandeling", zorgtrajectPad.Key);
    scriptResult.SetParent("behandeling", zorgtrajectData);
}

Als er meerdere scriptfuncties zijn geregistreerd voor hetzelfde event zorgt bovenstaande design pattern ervoor dat er maar één keer een query wordt uitgevoerd om gegevens van de parent op te halen.

Registratie

Alle scriptfuncties worden automatisch geregistreerd door TabelScriptRunner . Dit gebeurt door de static constructor. Dit is een constructor die gegarandeerd maar één keer uitgevoerd, de eerste keer dat een reguliere constructor van die klasse wordt uitgevoerd. TabelScriptRunner zoekt met behulp van reflectie alle klassen op die interface ITabelScript implementeren en registreert deze voor de contexten die RegisterFor teruggeeft.