Articoli

Microsoft Dynamics 365 Business Central: i servizi di geolocalizzazione

Come implementare una mappa all’interno di una pagina, utilizzando le funzionalità standard di Business Central

Business Central può offrire numerosi spunti di personalizzazione già all’interno della Base Application, l’app basilare fornita da Microsoft che contiene tutte le funzionalità standard.
Un esempio può essere dato da una funzionalità che potrebbe passare inosservata tra le varie altre  ovvero la gestione dell’integrazione con i servizi di geolocalizzazione.

All’interno dell’anagrafica clienti, o fornitori (e anche in altri punti come ad esempio le risorse), dopo i vari dati dell’indirizzo nel gruppo “Indirizzo e contatto” è presente il tasto “Mostra su mappa

Cliccando sopra verranno richieste alcune informazioni su cosa si vuole vedere e procedendo si arriva all’apertura di una nuova scheda del browser con le indicazioni del percorso, oppure semplicemente con l’indirizzo dell’anagrafica visualizzato sulla mappa:

Il servizio utilizzato è quello di Bing, ma è possibile inserire il servizio di mappe preferito in quanto tutto è gestito tramite dal setup chiamato “Mappe in linea

A cui si accede alle varie pagine di setup dove è possibile inserire oltre a Bing altri setup di altri servizi.

Il funzionamento di tutto questo è molto semplice e Business Central utilizza la codeunit chiamata “Online map management” che contiene tutte le funzioni necessarie a rielaborare i setup immessi nella page indicata prima al fine di creare un indirizzo lanciabile tramite brower.

Grazie alla flessibilità data dagli eventi esposti dalla codeunit e il modo in cui sono state create le codeunit è possibile posizionare la funzionalità delle mappe su qualunque pagina di business central con pochi passaggi.

How to: i passaggi per l’implementazione

Il primo passaggio è la sottoscrizione di un evento al fine di “attivare” la funzionalità, per farlo basterà sottoscrivere questo evento impostando la variabile IsValid a true.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Online Map Management", 'OnAfterValidAddress', '', false, false)]
local procedure OnlineMapManagementOnAfterValidAddress(TableID: Integer; var IsValid: Boolean)
begin
end;

Il secondo passaggio è un secondo evento da sottoscrivere, questa volta per impostare l’indirizzo di “destinazione” o semplicemente l’indirizzo che verrà visualizzato nella mappa:

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Online Map Management", 'OnAfterGetAddress', '', false, false)]
local procedure OnlineMapManagementOnAfterGetAddress(TableID: Integer; RecPosition: Text; var Parameters: array[12] of Text[100]; var RecordRef: RecordRef)
Begin
end;

Impostando l’array Parameters con le informazioni relative all’indirizzo desiderato:

Parameters[1] := Addr;
Parameters[2] := City;
Parameters[3] := County;
Parameters[4] := PostCode;
Parameters[5] := CountryCode;

A questo punto il tutto è già impostato per funzionare, basterà creare una action sulla page desiderata in modo che lanci la funzione MakeSelection della codeunit Online Map Managemente e il gioco è fatto.

OnlineMapManagement.ProcessMap(DocumentRecRef.Number, DocumentRecRef.GetPosition())

La funzione riceve in ingresso dei recordref e gli eventi esposti espongono la tabella che ha generato l’evento in questo modo è possibile creare un’unica funzione in grado di accettare qualsiasi tabella e quindi indirizzo all’interno del database senza dover duplicare ulteriormente il codice.

In questo modo è stato replicato esattamente quello che lo standard fa sulle pagine in cui espone la possibilità di visualizzare la mappa, ma è possibile andare oltre con pochi passaggi e tramite l’utilizzo di un servizio diverso da Bing ovvero HereWeGo.

L’indirizzo infatti è possibile visualizzarlo direttamente all’interno della pagina di Business Central sfruttando in modo differente la stessa struttura che viene utilizzata per l’esposizione dei report PowerBi.

How to: aggiungere le funzionalità

Prima di andare a creare la pagina bisogna aggiungere un paio di funzionalità a quanto è stato creato in precedenza.

La prima è la funzione di restituzione della url che verrà mostrata all’interno della pagina sfruttando direttamente la funzione presente all’interno della codeunit di gestione delle mappe. La url però non è direttamente visibile in quanto l’apertura della scheda del browser è all’interno della funzione stessa di creazione della url. Bisogna recuperarla tramite un piccolo escamotage dichiarando la codeunit in cui vengono sottoscritti gli eventi come “singleinstance” e dichiarando una variabile globale “weburl” e una seconda variabile booleana “isPagePart” (il cui motivo verrà spiegato poco più avanti).

A questo punto si crea la funzione che restituirà la url alla pagina:


    procedure GetMapUrl(Document: Variant): Text
    var
        OnlineMapSetup: Record "Online Map Setup";
        OnlineMapManagement: Codeunit "Online Map Management";
        Err001: Label 'Please setup a valid map setup';
    begin
        isPagePart := true;
        DatatypeManagement.GetRecordRef(Document, DocumentRecRef);
        if OnlineMapSetup.FindFirst() then
            OnlineMapManagement.ProcessMap(DocumentRecRef.Number, DocumentRecRef.GetPosition())
        else
            Error(Err001);

        Exit(WebUrl);
    end;

Come si può notare in questa funzione non viene assegnata da nessuna parte la variabile WebUrl, questo perché in realtà la url viene composta dalla procedura ProcessMap, che non avendo nessun valore di ritorno espone un evento che si andrà a sottoscrivere:

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Online Map Management", 'OnAfterProcessWebMap', '', false, false)]
    local procedure MapManagementOnAfterProcessWebMap(url: Text[1024]; var IsHandled: Boolean)
    begin
        if not isPagePart then exit;
        WebUrl := url;
        IsHandled := true;
        isPagePart := false;
    end;

Da questo evento possiamo ricavare la url assegnandola alla variabile WebUrl e impostando la variabile isHandled a true evitiamo l’apertura della scheda del browser. Come si può notare viene controllata la variabile isPagePart (impostata a true nella funzione) questo serve a mantenere inalterata la funzionalità del tasto standard.
A questo punto si può creare la page part, riferita alla sourcetable della pagina in cui verrà visualizzata la mappa.
Al suo interno non si andrà a dichiarare alcun campo ma solo un usercontrol fatto in questo modo:

layout
    {
        area(Content)
        {
            group(Map)
            {
                ShowCaption = false;
                usercontrol(WebReportViewer; "Microsoft.Dynamics.Nav.Client.WebPageViewer")
                {
                    ApplicationArea = All;
                    trigger ControlAddInReady(callbackUrl: Text)
                    begin
                        CurrPage.WebReportViewer.Navigate(Url);
                    end;
                }
            }
        }
    }

Oltre allo usercontrol nel trigger “onaftergetrecord” andremo a richiamare la funzione creata prima:

trigger OnAfterGetRecord()
    var
        MapsCu: Codeunit "Maps Cu";
    begin
        Clear(MapsCu);
        Url := MapsCu.GetMapUrl(Rec);
    end;

A questo punto non resta che pubblicare il tutto ed ecco il risultato:

Con questi passaggi è possibile integrare la funzionalità di utilizzo della geolocalizzazione all’interno di una propria app senza dover scrivere del codice di gestione a riguardo e allo stesso tempo potrebbe fungere da base per ulteriori sviluppi più complessi tramite l’utilizzo delle API forniti dai vari gestori di servizi di geolocalizzazione, la flessibilità del setup infatti permette di utilizzare oltre a Bing, anche Google Maps, Openstreet Maps e non ultimo HereWeGo.

 

Semplifica i processi, prendi decisioni più informate e accelera la crescita con Dynamics 365 Business Central, una soluzione di gestione aziendale completa progettata per le piccole e medie imprese.

 

Dynamics 365 Developer