SAP Analytics Cloud Embedded : Integrer l analytique dans les apps Fiori

Catégorie
Integration
Publié
Auteur
Johannes

SAP Analytics Cloud (SAC) Embedded vous permet d’integrer des tableaux de bord interactifs et des visualisations directement dans les applications Fiori. Au lieu de basculer entre differents outils, les utilisateurs voient le contenu analytique dans le contexte de leur travail quotidien.

Qu’est-ce que SAP Analytics Cloud Embedded ?

SAC Embedded designe l’integration des Stories SAP Analytics Cloud dans les applications SAP. Les tableaux de bord, graphiques et KPIs sont directement integres dans l’interface Fiori :

AspectSAC AutonomeSAC Embedded
AccesPortail separeDans l’app Fiori
ContexteIndependantLie a l’objet metier
NavigationAutonomePartie du workflow
FiltreManuelAutomatique depuis l’app
LicenceLicence SACInclus dans BTP

Cas d’utilisation

  • Object Page Analytics : Indicateurs pour l’objet metier actuel
  • Overview Page : Tuiles KPI avec drill-down
  • Custom Sections : Zones analytiques dans les apps Fiori
  • Tableaux de bord de gestion : Integres dans les applications transactionnelles

Architecture et composants

L’integration repose sur plusieurs composants :

┌─────────────────────────────────────────────────────┐
│ App Fiori │
│ ┌───────────────────────────────────────────────┐ │
│ │ SAC Story (iframe) │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ Charts, Tables, KPIs │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────┘
│ Contexte de filtre
┌──────────────────────▼──────────────────────────────┐
│ SAP Analytics Cloud │
│ ┌───────────────────────────────────────────────┐ │
│ │ Story / Model / Connection │ │
│ └───────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────┘
│ Live Data Connection
┌──────────────────────▼──────────────────────────────┐
│ Systeme ABAP Cloud │
│ ┌───────────────────────────────────────────────┐ │
│ │ Vues CDS Analytiques │ │
│ │ (Cube, Dimensions, Queries) │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘

Vues CDS analytiques pour SAC

La base de l’integration SAC sont les vues CDS analytiques. Celles-ci doivent etre specifiquement annotees pour l’acces par SAC.

Vue Dimension

Les dimensions sont des caracteristiques de regroupement comme client, produit ou temps :

@Analytics.dataCategory: #DIMENSION
@ObjectModel.representativeKey: 'CustomerId"
@EndUserText.label: 'Dimension Clients"
define view entity ZI_CustomerDimension
as select from zcustomer
association [0..1] to I_Country as _Country
on $projection.CountryCode = _Country.Country
{
@ObjectModel.text.element: ['CustomerName']
key customer_id as CustomerId,
customer_name as CustomerName,
customer_group as CustomerGroup,
@ObjectModel.foreignKey.association: '_Country"
country_code as CountryCode,
city as City,
region as Region,
_Country
}

Vue Cube pour SAC

Le Cube contient les mesures et lie les dimensions :

@Analytics.dataCategory: #CUBE
@Analytics.internalName: #LOCAL
@ObjectModel.supportedCapabilities: [#ANALYTICAL_QUERY, #SQL_DATA_SOURCE]
@EndUserText.label: 'Sales Cube pour SAC"
define view entity ZI_SalesCubeSAC
as select from zsales_data as Sales
association [0..1] to ZI_CustomerDimension as _Customer
on $projection.CustomerId = _Customer.CustomerId
association [0..1] to ZI_ProductDimension as _Product
on $projection.ProductId = _Product.ProductId
association [0..1] to I_CalendarMonth as _CalendarMonth
on $projection.CalendarMonth = _CalendarMonth.CalendarMonth
{
-- Dimensions
@Analytics.dimension: true
@ObjectModel.foreignKey.association: '_Customer"
Sales.customer_id as CustomerId,
@Analytics.dimension: true
@ObjectModel.foreignKey.association: '_Product"
Sales.product_id as ProductId,
@Analytics.dimension: true
@Semantics.calendar.yearMonth: true
@ObjectModel.foreignKey.association: '_CalendarMonth"
Sales.calendar_month as CalendarMonth,
@Analytics.dimension: true
Sales.sales_org as SalesOrganization,
@Analytics.dimension: true
Sales.distribution_ch as DistributionChannel,
-- Mesures
@Aggregation.default: #SUM
@Semantics.amount.currencyCode: 'Currency"
@EndUserText.label: 'Chiffre d affaires"
Sales.revenue as Revenue,
@Aggregation.default: #SUM
@Semantics.quantity.unitOfMeasure: 'Unit"
@EndUserText.label: 'Quantite"
Sales.quantity as Quantity,
@Aggregation.default: #SUM
@EndUserText.label: 'Nombre de commandes"
cast(1 as abap.int4) as OrderCount,
@Semantics.currencyCode: true
Sales.currency as Currency,
@Semantics.unitOfMeasure: true
Sales.unit as Unit,
-- Associations
_Customer,
_Product,
_CalendarMonth
}

Vue Query pour SAC

La Query definit l’evaluation analytique :

@Analytics.query: true
@VDM.viewType: #CONSUMPTION
@EndUserText.label: 'Sales Analytics Query"
-- Important pour l'acces SAC
@ObjectModel.usageType: {
serviceQuality: #D,
sizeCategory: #XXL,
dataClass: #MIXED
}
define view entity ZC_SalesAnalyticsSAC
as projection on ZI_SalesCubeSAC
{
-- Caracteristiques libres (selectionnables dans SAC)
@AnalyticsDetails.query.display: #KEY_TEXT
@AnalyticsDetails.query.axis: #FREE
CustomerId,
@AnalyticsDetails.query.axis: #FREE
ProductId,
@AnalyticsDetails.query.axis: #ROWS
CalendarMonth,
@AnalyticsDetails.query.axis: #FREE
SalesOrganization,
@AnalyticsDetails.query.axis: #FREE
DistributionChannel,
-- Indicateurs
@AnalyticsDetails.query.axis: #COLUMNS
Revenue,
@AnalyticsDetails.query.axis: #COLUMNS
Quantity,
@AnalyticsDetails.query.axis: #COLUMNS
OrderCount,
Currency,
Unit,
-- Indicateur calcule : Valeur moyenne de commande
@EndUserText.label: 'Valeur moy. commande"
@AnalyticsDetails.query.axis: #COLUMNS
division(Revenue, OrderCount, 2) as AverageOrderValue,
_Customer,
_Product,
_CalendarMonth
}

Configurer la Live Data Connection

La Live Data Connection connecte SAC directement au systeme ABAP Cloud.

Etape 1 : Creer le Communication Arrangement

Dans le systeme ABAP Cloud, un Communication Arrangement pour l’acces SAC est necessaire :

Communication Scenario: SAP_COM_0065 (InA - Information Access)
Communication System: SAC_SYSTEM
Communication User: SAC_TECHNICAL_USER

Etape 2 : Creer la connexion dans SAC

Dans SAP Analytics Cloud sous Connections -> Add Connection :

ParametreValeur
Connection TypeSAP S/4HANA
Hostabap-system.cloud.sap
Port443
AuthenticationOAuth 2.0 SAML Bearer
Token URL/sap/bc/sec/oauth2/token

Etape 3 : Creer le modele

Le modele SAC est base sur la CDS Query :

Model Type: Live Data
Connection: ABAP_CLOUD_SYSTEM
Data Source: ZC_SALESANALYTICSSAC

Activation du service InA

Le service InA (Information Access) doit etre active dans le systeme :

-- La vue CDS doit etre compatible InA
@Analytics.query: true
@ObjectModel.supportedCapabilities: [#ANALYTICAL_QUERY]
-- Cette annotation est importante pour Live Data
@Analytics.internalName: #LOCAL

Integrer une Story dans une app Fiori

L’integration s’effectue via le widget SAC ou un controleur personnalise.

Option 1 : Widget SAC dans Object Page

Pour les apps Fiori Elements, une Custom Section avec widget SAC est utilisee :

Adaptation manifest.json :

{
"sap.ui5": {
"routing": {
"targets": {
"ObjectPage": {
"options": {
"settings": {
"content": {
"body": {
"sections": {
"analyticsSection": {
"template": "sap.fe.templates.ObjectPage.AnalyticsSection",
"title": "Analyse des ventes",
"storyId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
}
}
}
}
}
}
}
}
}
}

Option 2 : Freestyle UI5 avec sac-embed

Pour les apps Freestyle, la bibliotheque sac-embed est utilisee :

sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/sac/df/embed/SACEmbedding"
], function (Controller, SACEmbedding) {
"use strict";
return Controller.extend("com.example.app.controller.Analytics", {
onInit: function () {
this._initSACEmbed();
},
_initSACEmbed: function () {
var oContainer = this.byId("sacContainer");
var oEmbedding = new SACEmbedding({
url: "https://your-sac-tenant.sapanalytics.cloud",
storyId: "STORY_ID",
pageId: "PAGE_ID",
tenantId: "TENANT_ID"
});
oEmbedding.embed(oContainer.getDomRef());
}
});
});

Option 3 : Integration par iFrame

La variante la plus simple utilise un iFrame :

<mvc:View xmlns:mvc="sap.ui.core.mvc"
xmlns:html="http://www.w3.org/1999/xhtml">
<html:iframe
id="sacFrame"
src="{path: 'StoryUrl'}"
width="100%"
height="600px"
frameborder="0"/>
</mvc:View>

Contexte de filtre entre app et SAC

Le contexte de filtre synchronise les selections entre l’app Fiori et la Story SAC.

Parametres URL pour les filtres

Les filtres sont passes a la Story via des parametres URL :

_buildSACUrl: function (sStoryId, oFilters) {
var sBaseUrl = "https://tenant.sapanalytics.cloud/sap/fpa/ui/app.html";
var sParams = "#/story/" + sStoryId;
// Filtre comme parametre URL
if (oFilters.CustomerId) {
sParams += "?filter=CustomerId eq '" + oFilters.CustomerId + "'";
}
if (oFilters.CalendarMonth) {
sParams += "&filter=CalendarMonth eq '" + oFilters.CalendarMonth + "'";
}
return sBaseUrl + sParams;
}

API postMessage pour les filtres dynamiques

Pour la communication bidirectionnelle, l’API postMessage est utilisee :

// Envoyer le filtre a la Story SAC
_applyFilterToSAC: function (oFilter) {
var oIframe = this.byId("sacFrame").getDomRef();
var oMessage = {
type: "setFilter",
dimension: oFilter.dimension,
values: oFilter.values,
operator: "IN"
};
oIframe.contentWindow.postMessage(oMessage, "https://tenant.sapanalytics.cloud");
},
// Recevoir les evenements de filtre de SAC
_initFilterListener: function () {
var that = this;
window.addEventListener("message", function (event) {
if (event.origin !== "https://tenant.sapanalytics.cloud") {
return;
}
if (event.data.type === "filterChanged") {
that._onSACFilterChanged(event.data.filter);
}
});
}

Passage de contexte dans Object Page

Dans les Object Pages, le contexte de l’objet actuel est automatiquement filtre :

_embedSACWithContext: function () {
var oBindingContext = this.getView().getBindingContext();
var sCustomerId = oBindingContext.getProperty("CustomerId");
// Charger la Story avec filtre pour le client actuel
var sStoryUrl = this._buildSACUrl("STORY_ID", {
CustomerId: sCustomerId
});
this.byId("sacFrame").setSrc(sStoryUrl);
}

Modele de filtre pour la synchronisation

// Modele de filtre pour la synchronisation bidirectionnelle
var oFilterModel = new JSONModel({
CustomerId: "",
SalesOrganization: "",
CalendarMonth: "",
syncEnabled: true
});
this.getView().setModel(oFilterModel, "filter");
// Lors d'un changement dans l'app Fiori
oFilterModel.attachPropertyChange(function (oEvent) {
if (oFilterModel.getProperty("/syncEnabled")) {
this._applyFilterToSAC({
dimension: oEvent.getParameter("path").substring(1),
values: [oEvent.getParameter("value")]
});
}
}.bind(this));

Bonnes pratiques pour les performances

Optimisation des vues CDS

-- Annotation d'agregation pour une consolidation efficace
@Aggregation.default: #SUM
Revenue,
-- Exposer uniquement les dimensions necessaires
@Analytics.dimension: true
@AnalyticsDetails.query.axis: #ROWS -- Preselectionne en lignes
CalendarMonth,
-- Associations de texte pour un acces rapide
@ObjectModel.text.association: '_CustomerText"
CustomerId,

Reduire le volume de donnees

MesureDescription
AgregationUtiliser des vues pre-agregees
FiltreCharger uniquement les donnees pertinentes
PaginationLimiter les grands volumes de donnees
CacheActiver la mise en cache SAC

Live Data vs. Import

AspectLive DataImport
ActualiteTemps reelSnapshot
PerformanceDepend du backendRapide (cache)
Volume de donneesLimiteIllimite
Recommande pourAnalyse operationnelleGrands volumes de donnees

Configuration du pool de connexions

# Parametres de connexion SAC
max_connections: 10
connection_timeout: 30000
query_timeout: 300000

Strategie de mise en cache

-- Dans la vue CDS pour SAC
@ObjectModel.usageType: {
serviceQuality: #D, -- Optimise pour les requetes directes
sizeCategory: #L, -- Volume de donnees attendu
dataClass: #TRANSACTIONAL
}

Autorisations et securite

CDS Access Control

@MappingRole: true
define role ZR_SalesAnalytics {
grant select on ZC_SalesAnalyticsSAC
where SalesOrganization = aspect pfcg_auth (
V_VBAK_AAT, VKORG, ACTVT = '03"
);
}

Autorisations Team et Folder SAC

  • Public Folder : Stories pour tous les utilisateurs
  • Team Folder : Stories pour certaines equipes
  • Private Folder : Stories personnelles

Configuration SSO

Pour une authentification transparente entre Fiori et SAC :

Identity Provider: SAP Identity Authentication
Trust Configuration: Cross-Domain SSO enabled
Principal Propagation: Active

Depannage

Problemes frequents

ProblemeCauseSolution
Pas de donnees dans SACService InA non actifVerifier le Communication Scenario
Performance lenteGrand volume sans filtreDefinir des filtres obligatoires
Filtre ne fonctionne pasMauvais nom de champSynchroniser les noms techniques
Erreur de connexionCertificat expireMettre a jour le Trust Store

Outils de diagnostic

-- Tester la vue CDS
SELECT * FROM zc_salesanalyticssac WHERE CalendarMonth = '202401';
-- Verifier le service InA
/sap/bw/ina/GetServerInfo

Resume

SAP Analytics Cloud Embedded apporte l’analytique directement dans le contexte de travail des utilisateurs. Les etapes cles :

  1. Creer des vues CDS analytiques avec les annotations correctes
  2. Configurer la Live Data Connection entre ABAP Cloud et SAC
  3. Creer une Story dans SAC avec le modele CDS
  4. Integrer la Story dans l’app Fiori (Widget, Library ou iFrame)
  5. Synchroniser le contexte de filtre pour une experience utilisateur fluide

La combinaison de donnees en temps reel et de visualisations interactives fait de SAC Embedded un outil puissant pour les decisions basees sur les donnees.

Sujets connexes