Indice articolo

L’apertura di smeup verso piattaforme esterne porta costantemente a sviluppare nuovi connettori che permettano al suo gestionale di creare nuove fonti dati. Per smeup, infatti, il dato è astratto e quindi non legato necessariamente ad una specifica piattaforma.

In questo articolo, mostreremo come sia possibile, da smeup, eseguire delle operazioni sui dati del gestionale SAP.

Il progetto di integrazione con SAP è durato 5 mesi. Durante questo periodo è stata fatta un’analisi sulle strade percorribili per il raggiungimento dell’obiettivo, oltre ad essere stata sviluppata una soluzione dimostrativa che ha permesso di mettere in evidenza le principali caratteristiche dell’integrazione. Come vedremo in seguito, il suo punto di forza è la versatilità che permette, tramite una breve fase di configurazione, di leggere, scrivere, aggiornare ed eliminare le informazioni.

Il concetto principale è che si deve fornire a smeup una configurazione che sia in grado di convertire le informazioni provenienti da SAP in un formato utilizzabile dal nostro ERP. Si deve quindi creare in smeup un oggetto V5 per ogni corrispondente entità di SAP (Contatti, Articoli, etc…), all’interno del quale saranno definiti sia l’URL da cui prendere i dati, sia la mappatura degli stessi.

Partiamo dal risultato

A scopo di esempio, utilizzeremo lo showcase delle integrazioni inserendo nello spotlight il comando: UPP WS_116.

Selezioniamo la voce “SAP BTP” sotto la sezione “Oggetti remoti V5“.

screenshot dimostrativo del posizionamento dell'upp di integrazione con sap

Cliccando sulla tab “Lista” è possibile vedere l’elenco dei contatti di SAP. Ovviamente è solo una delle entità disponibili, ma è sufficiente per rendere l’idea.

dimostrazione tramite liste dell'avvenuta integrazione con sap

Vediamo i corrispondenti dati sul gestionale SAP

h3ls04-nw22000684-sap-list.png

Come lo abbiamo fatto?

Per comprendere a pieno questa implementazione, seguiamo passo dopo passo il flusso delle informazioni.

Schema che rappresenta il processo di integrazione con sap

Se guardiamo in debug della matrice, vediamo che la fun che viene eseguita è la seguente:

F(EXB;WS_116_01;MATLIS) 1(OG;;V50000015) INPUT(K47FS()) SS(CONAP(B£) Context() CGr(WUP) ID({webup}))

Come possiamo vedere, la FUN restituisce il seguente XML:

<?xml version="1.0" encoding="UTF-8"?><UiSmeup Testo="V50000015 Integrazione SAP - Contatti - "> <Service Titolo1="" Titolo2="Integrazione SAP - Contatti" Funzione="F(EXB;WS_116_01;MATLIS) 1(OG;;V50000015) 2(;;) INPUT(K47FS())" Servizio="WS_116_01" TSep="." DSep="," IdFun="1027165439169" NumSes="922594"/>
  <Griglia>
    <Colonna Cod="XXTIPO" Txt="Tipo" Lun="12" IO="H" Ogg="OG" Tooltip="Yes"/>
    <Colonna Cod="XXCODI" Txt="Codice K47" Lun="15" IO="H" Ogg="[XXTIPO]" Tooltip="Yes"/>
    <Colonna Cod="I/CID" Txt="Codice" Lun="100" IO="O" Ogg="V50000015" Tooltip="Yes"/>
    <Colonna Cod="I/BID" Txt="Descrizione" Lun="100" IO="O" Tooltip="No"/>
    <Colonna Cod="I/TIT" Txt="Title" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/FNA" Txt="FirstName" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/MNA" Txt="MiddleName" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/LNA" Txt="LastName" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/NNA" Txt="Nickname" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/INI" Txt="Initials" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/SEX" Txt="Sex" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/PNR" Txt="PhoneNumber" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/FNR" Txt="FaxNumber" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/EAS" Txt="EmailAddress" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/LAN" Txt="Language" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/DOB" Txt="DateOfBirth" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/CTY" Txt="City" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/PCD" Txt="PostalCode" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/STR" Txt="Street" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/BDG" Txt="Building" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/COY" Txt="Country" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/ADT" Txt="AddressType" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/LOE" Txt="Longitude" Lun="999" IO="O" Tooltip="No"/>
    <Colonna Cod="I/LAE" Txt="Latitude" Lun="999" IO="O" Tooltip="No"/>
  </Griglia>
  <Righe>
    <Riga Fld="V50000015|p3p3HYY|12617c2d-458e-1ed8-b4a3-ebd61c4e064d|0100000000||Karl||Müller|||M|0622734567|0622734004|angelo15.reply@sap.com|E||Walldorf|69190|Robert-Koch-Straße|1|DE|02|8.6425969|49.3037108|"/>
    <Riga Fld="V50000015|5dA05Ql|5fafc1be-c34d-1edd-93c3-f2aef3f02cfa|0100000000||Karl||Müller|||M|0622734567|0622734004|angelo1.reply@sap.com|E||Walldorf|69190|Robert-Koch-Straße|1|DE|02|||"/>
    <Riga Fld="V50000015|e6Dtves|5fafc1be-c34d-1edd-93c3-fa2529ce2d03|0100000000||Karl||Müller|||M|0622734567|0622734004|angelo1.reply@sap.com|E||Walldorf|69190|Robert-Koch-Straße|1|DE|02|||"/>
    <Riga Fld="V50000015|T07AKUD|5fafc1be-c34d-1edd-93c4-02be7772ad0b|0100000000||Utente25|Test|Smeup|||M|0622734567|0622734004|angelo15.reply@sap.com|E||Walldorf|69190|Robert-Koch-Straße|1|DE|02|||"/>
    <Riga Fld="V50000015|KtySvK_|5fafc1be-c34d-1edd-93c5-2fb074b0ee07|0100000000||Utente50|Test|Smeup|||M|0622734567|0622734004|angelo1.reply@sap.com|E||Walldorf|69190|Robert-Koch-Straße|1|DE|02|||"/>
    <Riga Fld="V50000015|rGZi4Sg|cb352625-a446-1eed-9290-465b9f7c6065|0100000000||Angelo||Marchese|||M|0622734567|0622734004|angelo.reply@sap.com|E||Walldorf|69190|Robert-Koch-Straße|1|DE|02|||"/>
    <Riga Fld="V50000015|0q3OXOQ|cb352625-a446-1eed-9290-6e9926d56092|0100000000||Angelo|Test|Marchese|||M|0622734567|0622734004|angelo.reply@sap.com|E||Walldorf|69190|Robert-Koch-Straße|1|DE|02|||"/>
    <Riga Fld="V50000015|dHGXwhp|12617c2d-458e-1ed8-b4a3-ebd61c4e464d|0100000001||Dagmar||Schulze|||F|3088530|3088004|customer-dagmar.schulze@beckerberlin.de|E||Berlin|13467|Schulzendorfer Straße|101|DE|02|13.2936670|52.6101990|"/>
    <Riga Fld="V50000015|LPeE7nd|12617c2d-458e-1ed8-b4a3-ebd61c4e664d|0100000001||Ursula|Mariana|Wexler|||F|3088529|3088004|ursula.wexler@beckerberlin.de|E||Berlin|13467|Zabel-Krüger-Damm|127|DE|02|13.3441820|52.6137660|"/>
    <Riga Fld="V50000015|PGrkXOM|12617c2d-458e-1ed8-b4a3-ebd61c4e864d|0100000002||Maria||Brown|||F|3023352668|3023352004|customer-maria.brown@delbont.com|E||Wilmington, Delaware|19899|223 Kirkwood Park|1|US|02|75.5398090-|39.7454530|"/>
  </Righe>
</UiSmeup>

Notiamo che i dati appartenenti a SAP hanno degli attributi con degli OAV tipici di smeup, anche se SAP non possiede questa struttura. In effetti, questi attributi non vengono restituiti da SAP ma vengono elaborati e convertiti nel XML di cui sopra dopo una serie di elaborazioni.

Chiamata al servizio

In questo articolo abbiamo preso come esempio una griglia che utilizza il servizio WS_116_01. Per fruire dei dati di SAP, però, può essere utilizzato qualunque servizio che utilizzi la K47.

La FUN richiama il servizio, il quale esegue le seguenti operazioni:

  • Richiama la /COPY K47.
  • La K47 richiama /COPY K11 per recuperare i dati da SAP.
  • La K47 riceve i dati e crea degli oggetti V5, mappandoli con degli OAV.
  • Il servizio riceve gli oggetti V5, genera l’XML e lo restituisce alla griglia come richiesto dalla fun.

Per fare tutto ciò, al servizio viene passato il nome dello script SCP_K47/V5_0000015 in cui sono contenute le informazioni necessarie. Segue la definizione dello script:

//Parametri di Cache se non esplicitati prendono di default
XXCAH ValLis="3600" Dis=" "
//Lista A38
::SEZ.LIS SubA38="SAP.S02.B02" VarA38="URL(&KU.WS_116%SUR)"

// informazioni da estrapolare
::OAV Cod="I/CID" Txt="Codice" Ogg="V50000015" Len="100" JsonPath="value(*)\ContactGUID" Shrink="1" Cdd="C"
::OAV Cod="I/BID" Txt="Descrizione" Len="100" JsonPath="value(*)\BusinessPartnerID" Cdd="D"
::OAV Cod="I/TIT" Txt="Title" Len="999" JsonPath="value(*)\Title"
::OAV Cod="I/FNA" Txt="FirstName" Len="999" JsonPath="value(*)\FirstName"
::OAV Cod="I/MNA" Txt="MiddleName" Len="999" JsonPath="value(*)\MiddleName"
::OAV Cod="I/LNA" Txt="LastName" Len="999" JsonPath="value(*)\LastName"
::OAV Cod="I/NNA" Txt="Nickname" Len="999" JsonPath="value(*)\Nickname"
::OAV Cod="I/INI" Txt="Initials" Len="999" JsonPath="value(*)\Initials"
::OAV Cod="I/SEX" Txt="Sex" Len="999" JsonPath="value(*)\Sex"
::OAV Cod="I/PNR" Txt="PhoneNumber" Len="999" JsonPath="value(*)\PhoneNumber"
::OAV Cod="I/FNR" Txt="FaxNumber" Len="999" JsonPath="value(*)\FaxNumber"
::OAV Cod="I/EAS" Txt="EmailAddress" Len="999" JsonPath="value(*)\EmailAddress"
::OAV Cod="I/LAN" Txt="Language" Len="999" JsonPath="value(*)\Language"
::OAV Cod="I/DOB" Txt="DateOfBirth" Len="999" JsonPath="value(*)\DateOfBirth"
::OAV Cod="I/CTY" Txt="City" Len="999" JsonPath="value(*)\Address\City"
::OAV Cod="I/PCD" Txt="PostalCode" Len="999" JsonPath="value(*)\Address\PostalCode"
::OAV Cod="I/STR" Txt="Street" Len="999" JsonPath="value(*)\Address\Street"
::OAV Cod="I/BDG" Txt="Building" Len="999" JsonPath="value(*)\Address\Building"
::OAV Cod="I/COY" Txt="Country" Len="999" JsonPath="value(*)\Address\Country"
::OAV Cod="I/ADT" Txt="AddressType" Len="999" JsonPath="value(*)\Address\AddressType"
::OAV Cod="I/LOE" Txt="Longitude" Len="999" JsonPath="value(*)\Address\GeoLocation\Longitude" Cnv="*NUMTOTEXT" CnvVar="DECSEP(.) DECNUM(7)"
::OAV Cod="I/LAE" Txt="Latitude" Len="999" JsonPath="value(*)\Address\GeoLocation\Latitude" Cnv="*NUMTOTEXT" CnvVar="DECSEP(.) DECNUM(7)"

Utilizzo della K47 e K11

Il servizio richiama la /COPY K47 che gestisce l’intero processo di lettura e mappatura dei dati da SAP. Per poterlo fare, la K47 richiama la /COPY K11 che deve essere stata configurata nel LOA38.

Come possiamo vedere nella seguente riga, estratta dallo script SCP_K47/V5_0000015, è stato definito il nome della variabile da cui la K11 deve prendere l’indirizzo URL a cui fare la chiamata HTTP per recuperare i dati.

::SEZ.LIS SubA38="SAP.S02.B02" VarA38="URL(&KU.WS_116%SUR)"

La variabile è composta da 2 parti:

  • WS_116: la UPP di riferimento
  • SUR: nome della variabile
h3ls04-nw22000684-upp_ws_116_var_sur.png

Quindi, nel nostro caso, il link di SAP da cui leggere i dati è il seguente:

http://172.16.2.118:8000/sap/opu/odata4/iwbep/v4_sample/default/iwbep/v4_gw_sample_basic/0001/ContactList?$top=10

N.B.: il cliente che dovrà configurare questa implementazione, troverà il template delle variabili nella libreria SMEDEV/SCP_UPP/WS_116_VAR.

La K11 esegue quindi una chiamata HTTP e riceve i dati in formato JSON.

Mappatura dei dati

Dopo aver ricevuto i dati dalla K11, la K47 esegue la mappatura delle informazioni restituite da SAP. Qui sotto vediamo l’altra parte del codice, estratta dallo script SCP_K47/V5_0000015, che contiene “Il contratto” di mappatura del JSON con un oggetto V5 con il nome “Contatti SAP”.

// informazioni da estrapolare
::OAV Cod="I/CID" Txt="Codice" Ogg="V50000015" Len="100" JsonPath="value(*)\ContactGUID" Shrink="1" Cdd="C"
::OAV Cod="I/BID" Txt="Descrizione" Len="100" JsonPath="value(*)\BusinessPartnerID" Cdd="D"
::OAV Cod="I/TIT" Txt="Title" Len="999" JsonPath="value(*)\Title"
::OAV Cod="I/FNA" Txt="FirstName" Len="999" JsonPath="value(*)\FirstName"
::OAV Cod="I/MNA" Txt="MiddleName" Len="999" JsonPath="value(*)\MiddleName"
::OAV Cod="I/LNA" Txt="LastName" Len="999" JsonPath="value(*)\LastName"
::OAV Cod="I/NNA" Txt="Nickname" Len="999" JsonPath="value(*)\Nickname"
::OAV Cod="I/INI" Txt="Initials" Len="999" JsonPath="value(*)\Initials"
::OAV Cod="I/SEX" Txt="Sex" Len="999" JsonPath="value(*)\Sex"
::OAV Cod="I/PNR" Txt="PhoneNumber" Len="999" JsonPath="value(*)\PhoneNumber"
::OAV Cod="I/FNR" Txt="FaxNumber" Len="999" JsonPath="value(*)\FaxNumber"
::OAV Cod="I/EAS" Txt="EmailAddress" Len="999" JsonPath="value(*)\EmailAddress"
::OAV Cod="I/LAN" Txt="Language" Len="999" JsonPath="value(*)\Language"
::OAV Cod="I/DOB" Txt="DateOfBirth" Len="999" JsonPath="value(*)\DateOfBirth"
::OAV Cod="I/CTY" Txt="City" Len="999" JsonPath="value(*)\Address\City"
::OAV Cod="I/PCD" Txt="PostalCode" Len="999" JsonPath="value(*)\Address\PostalCode"
::OAV Cod="I/STR" Txt="Street" Len="999" JsonPath="value(*)\Address\Street"
::OAV Cod="I/BDG" Txt="Building" Len="999" JsonPath="value(*)\Address\Building"
::OAV Cod="I/COY" Txt="Country" Len="999" JsonPath="value(*)\Address\Country"
::OAV Cod="I/ADT" Txt="AddressType" Len="999" JsonPath="value(*)\Address\AddressType"
::OAV Cod="I/LOE" Txt="Longitude" Len="999" JsonPath="value(*)\Address\GeoLocation\Longitude" Cnv="*NUMTOTEXT" CnvVar="DECSEP(.) DECNUM(7)"
::OAV Cod="I/LAE" Txt="Latitude" Len="999" JsonPath="value(*)\Address\GeoLocation\Latitude" Cnv="*NUMTOTEXT" CnvVar="DECSEP(.) DECNUM(7)"

Segue una descrizione dei campi:

  • “Cod”: corrisponde all’OAV da assegnare a tale campo.
  • “Txt”: corrisponde alla descrizione descrizione del campo.
  • “JsonPath”: corrisponde al nome del campo sul file JSON proveniente da SAP.

È importante notare che all’interno del JsonPath c’è una particolare sintassi che indica la path della struttura JSON. Il carattere * indica che è all’interno di un array.

Restituzione dei dati

La K47 restituisce gli oggetti V5 al servizio WS_116_01 il quale li utilizza per generare un XML da restituire al componente, in questo caso una griglia.