Portefeuille du client

Comment suivre ce chapitre

Entrées : userId, portfolioId et un token CLIENT issus des étapes précédentes.

Étapes et résultat attendu : Listez les portefeuilles et sélectionnez-en un. Récupérez ensuite son snapshot et les données associées. Téléchargez le document choisi en utilisant sa référence et son identifiant de portefeuille dans les métadonnées.

Alternatives et actions ultérieures : Les valeurs, comptes de liquidités et documents peuvent devenir disponibles de manière asynchrone. Une liste vide ou des données indisponibles sont possibles tant que le traitement du portefeuille n’est pas terminé.

Code source des DTO : BankAccountTypeOutputModel, BookingCodeOutputModel, CashAccountMovementOutputModel, CashAccountOutputModel, PortfolioOutputModel, PortfolioValuesContainerOutputModel, UserBankDocumentInfoOutputModel

Les variables affectées dans un bloc précédent sont réutilisées dans les suivants. Les saisies du client proviennent de votre interface. Conservez les identifiants et les valeurs de référence dans le contexte du client ; ne recréez pas ce contexte à chaque étape.

Les exemples utilisent des classes utilitaires communes. Consultez Classes utilitaires communes : code source C# et Java complet avant de copier un exemple.
Prérequis : userId, le portfolioId sélectionné et un token CLIENT ou un token administratif autorisé à lire ces ressources.
À conserver pour la suite : Snapshots du portefeuille, valeurs de performance, mouvements de compte et documents bancaires téléchargeables.
Ce chapitre explique comment récupérer les données du portefeuille d’un client.

Liste des portefeuilles

Entrées : userId et token CLIENT.
Action : Lisez la liste actuelle des portefeuilles avec Snapshot.
À conserver / résultat attendu : Conservez le portfolioId sélectionné par le client.
Pour cet appel, définissez dans l’en-tête Authorization un token ayant le rôle CLIENT ou ADMIN.

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
// Assuming this is our client ID
// Use the userId returned by registration.
var clientPortfolios = await httpClient.GetFromJsonAsync<IList<PortfolioOutputModel>>($"api/v1/user-portfolios/user-id/{userId}?portfolio-view-as=Snapshot");

								
// Assuming this is our client ID
// Use the userId returned by registration.

HttpRequest portfolioRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("user-portfolios/user-id/" + userId + "?portfolio-view-as=Snapshot"))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + accessToken)
    .header("Content-Type", "application/json")
    .build();

var response = httpClient.send(portfolioRequest, BodyHandlers.ofString());
Api.requireSuccess(response);

Type listType = new TypeToken<ArrayList<PortfolioOutputModel>>(){}.getType();
List<PortfolioOutputModel> portfolioObjs = new Gson().fromJson(response.body(), listType);

Portefeuille par identifiant

Entrées : Le portfolioId sélectionné.
Action : Récupérez le snapshot actuel du portefeuille.
À conserver / résultat attendu : Utilisez l’état retourné et HasPendingOrder pour présenter les actions disponibles.
Récupérez le snapshot sélectionné, avec ses propriétés actuelles et les valeurs disponibles. Ces exemples demandent explicitement Snapshot. Sans portfolio-view-as, l’API utilise Forecast par défaut.

// Assuming this is the portfolio ID
// portfolioId is selected from the returned client portfolio list.
var clientPortfolio = await httpClient.GetFromJsonAsync<PortfolioOutputModel>($"api/v1/user-portfolios/portfolio-id/{portfolioId}?portfolio-view-as=Snapshot");

								
// Assuming this is the portfolio ID
// portfolioId is selected from the returned client portfolio list.

HttpRequest portfolioRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("user-portfolios/portfolio-id/" + portfolioId + "?portfolio-view-as=Snapshot"))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + accessToken)
    .header("Content-Type", "application/json")
    .build();

response = httpClient.send(portfolioRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
PortfolioOutputModel portfolioObj = new Gson().fromJson(response.body(), PortfolioOutputModel.class);

Ces informations permettent de créer une première vue du portefeuille :
Exemple de détails du portefeuille

Valeurs du portefeuille

Entrées : portfolioId et la période souhaitée.
Action : Récupérez le conteneur des performances et des valeurs.
À conserver / résultat attendu : Lisez sa collection Values. Les données peuvent ne pas encore être disponibles pour la période demandée.
L’historique des performances, les valeurs de marché, le total des actifs, les gains et pertes ainsi que les liquidités sont accessibles par le point de terminaison des performances. La réponse est un PortfolioValuesContainerOutputModel dont la collection Values contient des valeurs datées. Les paramètres facultatifs startingDate et endingDate utilisent yyyyMMdd ; les dates de la réponse suivent le schéma JSON. HTTP 404 peut indiquer que les performances ne sont pas encore disponibles pour ce portefeuille.
Performances Exemple de graphique des performances
Valeurs de marché Exemple de graphique de valeur de marché

// Assuming this is the portfolio ID we want to display
// portfolioId is selected from the returned client portfolio list.
var portfolioValues = await httpClient.GetFromJsonAsync<PortfolioValuesContainerOutputModel>($"api/v1/user-portfolios/portfolio-id/{portfolioId}/performances");

								
// Assuming this is the portfolio ID we want to display
// Use the same selected portfolioId.

HttpRequest portfolioPerformanceRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("user-portfolios/portfolio-id/" + portfolioId + "/performances"))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + accessToken)
    .header("Content-Type", "application/json")
    .build();

response = httpClient.send(portfolioPerformanceRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
PortfolioValuesContainerOutputModel portfolioPerformanceObj = new Gson().fromJson(response.body(), PortfolioValuesContainerOutputModel.class);

Liquidités du portefeuille

Entrées : portfolioId.
Action : Trouvez le compte de liquidités associé et récupérez son solde et ses mouvements.
À conserver / résultat attendu : Conservez l’identifiant du compte concerné et affichez le solde avec sa date.
Récupérez les comptes de liquidités du portefeuille sélectionné. Utilisez l’IBAN et le solde de l’entrée CASH-ACCOUNT concernée. L’absence d’un compte peut dépendre du cycle de vie du portefeuille ou de la configuration. Cet IBAN est celui sur lequel le client effectue, par exemple, son versement annuel au pilier 3a. Les soldes correspondent à la date comptable fournie par le service et peuvent refléter un paiement ou une transaction avec retard, pendant le traitement des données de la banque dépositaire. Les exemples suivants identifient le compte de liquidités :

// Get bank account types: Cash account/Custody account
var bankAccountTypes = await httpClient.GetFromJsonAsync<List<BankAccountTypeOutputModel>>($"api/v1/cash-account-types");
var cashAccountType = bankAccountTypes.First(x => x.Code == "CASH-ACCOUNT");
// Get portfolio's bank accounts
var bankAccounts = await httpClient.GetFromJsonAsync<List<CashAccountOutputModel>>($"api/v1/user-cash-accounts/portfolio-id/{portfolioId}");
var cashAccount = bankAccounts.First(x => x.AccountTypeId == cashAccountType.Id);

								
// Portfolio cash amount

HttpRequest bankAccountTypesRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("cash-account-types"))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + Settings.GUEST_TOKEN)
    .header("Content-Type", "application/json")
    .build();

// Get bank account types: Cash account/Custody account
response = httpClient.send(bankAccountTypesRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
Type listBankAccountTypes = new TypeToken<ArrayList<BankAccountTypeOutputModel>>(){}.getType();
List<BankAccountTypeOutputModel> bankAccountTypes = new Gson().fromJson(response.body(), listBankAccountTypes);
var bankAccountType = bankAccountTypes.stream().filter(x -> "CASH-ACCOUNT".equals(x.Code)).findFirst().orElseThrow(() -> new IllegalStateException("Required reference data is unavailable"));

// Get portfolio's bank accounts
HttpRequest portfolioBankAccountRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("user-cash-accounts/portfolio-id/" + portfolioId))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + accessToken)
    .header("Content-Type", "application/json")
    .build();

response = httpClient.send(portfolioBankAccountRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
Type cashAccountType = new TypeToken<ArrayList<CashAccountOutputModel>>(){}.getType();
List<CashAccountOutputModel> cashAccountObjs = new Gson().fromJson(response.body(), cashAccountType);
CashAccountOutputModel cashAccountObj = cashAccountObjs.stream().filter(x -> x.AccountTypeId == bankAccountType.Id).findFirst().orElseThrow(() -> new IllegalStateException("Required reference data is unavailable"));

CashAccountOutputModel contient Iban, Balance et BalanceDate. Le compte possède aussi son propre identifiant ; utilisez cette Id pour demander ses mouvements.
Vous pouvez également consulter les mouvements du compte. Les achats et ventes comptabilisés du portefeuille peuvent y apparaître. L’exemple suivant montre comment les récupérer :
									
var bankAccountMovements = await httpClient.GetFromJsonAsync<List<CashAccountMovementOutputModel>>($"api/v1/user-cash-accounts/cash-account-id/{cashAccount.Id}/movements");

									
HttpRequest cashAccountMovementsRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("user-cash-accounts/cash-account-id/" + cashAccountObj.Id + "/movements"))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + accessToken)
    .header("Content-Type", "application/json")
    .build();

response = httpClient.send(cashAccountMovementsRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
Type cashAccountMovementType = new TypeToken<ArrayList<CashAccountMovementOutputModel>>(){}.getType();
List<CashAccountMovementOutputModel> cashAccountMovementObjs = new Gson().fromJson(response.body(), cashAccountMovementType);

CashAccountMovementOutputModel possède une propriété BookingCodeId. Vous pouvez l’utiliser pour obtenir la description du type de mouvement :
									
foreach (var bankAccountMovement in bankAccountMovements)
{
    var bookingCode = await httpClient.GetFromJsonAsync<BookingCodeOutputModel>($"api/v1/booking-codes/id/{bankAccountMovement.BookingCodeId}");
    var bookingCodeValue = bookingCode.Code;
    var bookingCodeDescription = bookingCode.Description;
// Continue with the data returned by the API.
}

	
									
HttpRequest bookingCodeRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("booking-codes"))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + accessToken)
    .header("Content-Type", "application/json")
    .build();

response = httpClient.send(bookingCodeRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
Type bookingCodeTypes = new TypeToken<ArrayList<BookingCodeOutputModel>>(){}.getType();
List<BookingCodeOutputModel> bookingCodeTypeObjs = new Gson().fromJson(response.body(), bookingCodeTypes);

cashAccountMovementObjs.forEach(bankAccountMovement -> {
    BookingCodeOutputModel bookingCodeTypeObj = bookingCodeTypeObjs.stream().filter(x -> x.Id == bankAccountMovement.BookingCodeId).findFirst().orElseThrow(() -> new IllegalStateException("Required reference data is unavailable"));

    var bookingCode = bookingCodeTypeObj.Code;
    var bookingCodeDescription = bookingCodeTypeObj.Description;
    // Continue with the data returned by the API.
});

Exemple de mouvements du compte

Documents bancaires du portefeuille

Entrées : userId, puis l’identifiant du document sélectionné dans les métadonnées.
Action : Listez les documents et téléchargez le PDF sélectionné en données binaires.
À conserver / résultat attendu : Utilisez UserPortfolioId et Reference des métadonnées, sans supposer que tous les documents appartiennent au portefeuille actuellement sélectionné.
Les documents PDF émis ou fournis par la banque peuvent être téléchargés par le client.

// User bank documents
var url = $"api/v1/user-bank-documents/user-id/{userId}/list?starting-from=20000101";
var bankDocumentsForAllPortfolios = await httpClient.GetFromJsonAsync<IList<UserBankDocumentInfoOutputModel>>(url);

								
// User bank documents
HttpRequest userDocumentsMetadataRequest = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("user-bank-documents/user-id/" + userId + "/list?starting-from=20000101"))
    .header("Accept-Language", "de-DE")
    .header("Authorization", "Bearer " + accessToken)
    .header("Content-Type", "application/json")
    .build();

response = httpClient.send(userDocumentsMetadataRequest, BodyHandlers.ofString());
Api.requireSuccess(response);
Type userBankDocumentInfoType = new TypeToken<ArrayList<UserBankDocumentInfoOutputModel>>(){}.getType();
List<UserBankDocumentInfoOutputModel> userDocumentsMetadataObjs = new Gson().fromJson(response.body(), userBankDocumentInfoType);

Sélectionnez un document dans les métadonnées et utilisez l’identifiant du portefeuille et la référence correspondants. UserPortfolioId identifie le portefeuille du document. Choisissez selectedDocumentId dans la liste et utilisez sa Reference pour télécharger le PDF.

// selectedDocumentId identifies an item chosen from the returned metadata.
var selectedDocument = bankDocumentsForAllPortfolios.Single(x => x.Id == selectedDocumentId);
var documentPortfolioId = selectedDocument.UserPortfolioId;
var reference = selectedDocument.Reference;
var url = $"api/v1/user-bank-documents/user-id/{userId}/portfolio-id/{documentPortfolioId}/download-bank-document/reference/{Uri.EscapeDataString(reference)}";
var byteArray = await httpClient.GetByteArrayAsync(url);
// Save or display the PDF after the HTTP request succeeds.

								
// selectedDocumentId identifies an item chosen from the returned metadata.
var selectedDocument = userDocumentsMetadataObjs.stream()
    .filter(x -> x.Id == selectedDocumentId).findFirst()
    .orElseThrow(() -> new IllegalArgumentException("Select a listed document"));
var documentPortfolioId = selectedDocument.UserPortfolioId;
var reference = selectedDocument.Reference;
var encodedReference = java.net.URLEncoder.encode(reference, StandardCharsets.UTF_8).replace("+", "%20");
HttpRequest request = HttpRequest.newBuilder()
    .timeout(Duration.ofMinutes(1))
    .uri(Settings.wmsUri("user-bank-documents/user-id/" + userId
        + "/portfolio-id/" + documentPortfolioId + "/download-bank-document/reference/" + encodedReference))
    .header("Authorization", "Bearer " + accessToken).GET().build();
var response = httpClient.send(request, BodyHandlers.ofByteArray());
Api.requireSuccess(response);
byte[] pdfBytes = response.body();
// Save or display pdfBytes as a PDF.

Exemple de document bancaire :
Exemple de contrat PDF