L’Output Management dans ABAP Cloud diffère fondamentalement de l’On-Premise. Le Spool classique avec des transactions comme SP01, SP02 et SPAD n’est pas disponible sur SAP BTP. Au lieu de cela, ABAP Cloud utilise des concepts modernes et Cloud-natives pour le traitement des sorties.
Concepts de base
Dans ABAP Cloud, il existe plusieurs façons de sortir des documents :
| Concept | Description | Cas d’utilisation |
|---|---|---|
| SAP Cloud Print Manager | Service d’impression Cloud | Impression directe sur imprimantes réseau |
| Génération PDF | Créer des documents en PDF | Téléchargement, envoi par e-mail |
| Output Control | Gestion centralisée des sorties | Sortie basée sur formulaires |
| Envoi par e-mail | Envoyer des documents par e-mail | Factures, notifications |
Vue d’ensemble de l’architecture
┌─────────────────────────────────────────────────────────────────────────────┐│ Output Management dans ABAP Cloud ││ ││ ┌────────────────────────────────────────────────────────────────────────┐ ││ │ RAP Business Object / Application │ ││ │ ││ │ ┌─────────────────────┐ │ ││ │ │ Output Request │ │ ││ │ │ (Ordre impres.) │ │ ││ │ └──────────┬──────────┘ │ ││ └─────────────┼────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────────────────────┐ ││ │ Options de sortie │ ││ │ │ ││ │ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │ ││ │ │ Cloud Print │ │ Téléchargement │ │ Envoi par e-mail │ │ ││ │ │ Manager │ │ PDF │ │ │ │ ││ │ │ - Print Queue │ │ - RAP Action │ │ - cl_bcs_mail │ │ ││ │ │ - Imprimante │ │ - Attachment │ │ - Attachment │ │ ││ │ └───────────────────┘ └───────────────────┘ └───────────────────┘ │ ││ └─────────────────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────────────────────────────────────────────────────────────┐ ││ │ Destinations de sortie │ ││ │ - Imprimante réseau via Cloud Print │ ││ │ - Téléchargement navigateur │ ││ │ - Boîte e-mail │ ││ │ - Gestion documentaire (DMS) │ ││ └─────────────────────────────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────────────────────────────┘SAP Cloud Print Manager
Le SAP Cloud Print Manager est le remplaçant Cloud-native du système Spool classique. Il permet l’impression sur des imprimantes physiques depuis le Cloud.
Composants
| Composant | Description |
|---|---|
| Cloud Print Manager | Service SAP BTP pour gestion des ordres d’impression |
| Print Queue | File d’attente pour ordres d’impression |
| Print Agent | Composant On-Premise qui connecte les imprimantes |
| Printer | Imprimante de sortie configurée |
Architecture avec Print Agent
┌───────────────────────────────────────────────────────────────────────────┐│ Architecture Cloud Print ││ ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ SAP BTP │ ││ │ │ ││ │ ┌───────────────────┐ ┌───────────────────┐ │ ││ │ │ ABAP Cloud │ ────► │ Cloud Print │ │ ││ │ │ Application │ HTTP │ Manager Service │ │ ││ │ └───────────────────┘ └─────────┬─────────┘ │ ││ │ │ │ ││ └──────────────────────────────────────────┼───────────────────────────┘ ││ │ ││ │ Cloud Connector ││ │ ou accès direct ││ ▼ ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ On-Premise / Réseau entreprise │ ││ │ │ ││ │ ┌───────────────────┐ ┌───────────────────┐ │ ││ │ │ Print Agent │ ────► │ Imprimante │ │ ││ │ │ (SAP Software) │ Print │ réseau │ │ ││ │ └───────────────────┘ └───────────────────┘ │ ││ │ │ ││ └─────────────────────────────────────────────────────────────────────┘ │└───────────────────────────────────────────────────────────────────────────┘Configurer Print Queue
La configuration se fait dans l’environnement SAP BTP Cloud Foundry :
- Activer le service Cloud Print Manager dans le Subaccount BTP
- Créer une Service Instance
- Générer une Service Key pour l’authentification
- Installer et configurer le Print Agent On-Premise
Exemple de code : Créer un ordre d’impression
" Ordre d'impression via Cloud Print ManagerCLASS zcl_print_manager DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_print_request, queue_name TYPE string, document_name TYPE string, content TYPE xstring, content_type TYPE string, " application/pdf, text/plain copies TYPE i, duplex TYPE abap_bool, color TYPE abap_bool, END OF ty_print_request.
TYPES: BEGIN OF ty_print_response, job_id TYPE string, status TYPE string, message TYPE string, queue_name TYPE string, END OF ty_print_response.
METHODS: constructor IMPORTING iv_comm_scenario TYPE string.
METHODS: submit_print_job IMPORTING is_request TYPE ty_print_request RETURNING VALUE(rs_response) TYPE ty_print_response RAISING cx_http_dest_provider_error cx_web_http_client_error.
METHODS: get_print_queues RETURNING VALUE(rt_queues) TYPE string_table RAISING cx_http_dest_provider_error cx_web_http_client_error.
METHODS: get_job_status IMPORTING iv_job_id TYPE string RETURNING VALUE(rv_status) TYPE string RAISING cx_http_dest_provider_error cx_web_http_client_error.
PRIVATE SECTION. DATA: mv_comm_scenario TYPE string.
METHODS: get_http_client RETURNING VALUE(ro_client) TYPE REF TO if_web_http_client RAISING cx_http_dest_provider_error cx_web_http_client_error.
ENDCLASS.
CLASS zcl_print_manager IMPLEMENTATION.
METHOD constructor. mv_comm_scenario = iv_comm_scenario. ENDMETHOD.
METHOD submit_print_job. " Créer HTTP Client DATA(lo_client) = get_http_client( ).
TRY. DATA(lo_request) = lo_client->get_http_request( ).
" Chemin pour Print Job API lo_request->set_uri_path( '/v1/print-jobs' ). lo_request->set_header_field( i_name = 'Content-Type" i_value = 'application/json" ).
" Request Body DATA(lv_content_base64) = cl_http_utility=>encode_base64( is_request-content ).
DATA(lv_request_body) = |\{| && |"queueName": "{ is_request-queue_name }",| && |"documentName": "{ is_request-document_name }",| && |"contentType": "{ is_request-content_type }",| && |"content": "{ lv_content_base64 }",| && |"numberOfCopies": { is_request-copies },| && |"duplex": { COND #( WHEN is_request-duplex = abap_true THEN 'true' ELSE 'false' ) },| && |"color": { COND #( WHEN is_request-color = abap_true THEN 'true' ELSE 'false' ) }| && |\}|.
lo_request->set_text( lv_request_body ).
" Appeler l'API DATA(lo_response) = lo_client->execute( if_web_http_client=>post ).
DATA(lv_status) = lo_response->get_status( ).
IF lv_status-code = 201 OR lv_status-code = 200. " Parser la réponse DATA(lv_response_json) = lo_response->get_text( ).
" Extraire le Job ID (simplifié) rs_response-status = 'SUBMITTED'. rs_response-queue_name = is_request-queue_name. " Parser le Job ID depuis JSON... ELSE. rs_response-status = 'ERROR'. rs_response-message = lo_response->get_text( ). ENDIF.
CATCH cx_web_http_client_error INTO DATA(lx_http). rs_response-status = 'ERROR'. rs_response-message = lx_http->get_text( ). ENDTRY.
lo_client->close( ). ENDMETHOD.
METHOD get_print_queues. DATA(lo_client) = get_http_client( ).
TRY. DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_uri_path( '/v1/queues' ).
DATA(lo_response) = lo_client->execute( if_web_http_client=>get ).
IF lo_response->get_status( )-code = 200. " Parser les queues depuis JSON DATA(lv_json) = lo_response->get_text( ). " JSON-Parsing avec /ui2/cl_json... ENDIF.
CLEANUP. lo_client->close( ). ENDTRY. ENDMETHOD.
METHOD get_job_status. DATA(lo_client) = get_http_client( ).
TRY. DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_uri_path( |/v1/print-jobs/{ iv_job_id }| ).
DATA(lo_response) = lo_client->execute( if_web_http_client=>get ).
IF lo_response->get_status( )-code = 200. " Parser le statut depuis JSON rv_status = 'COMPLETED'. " simplifié ELSE. rv_status = 'UNKNOWN'. ENDIF.
CLEANUP. lo_client->close( ). ENDTRY. ENDMETHOD.
METHOD get_http_client. " Destination depuis Communication Arrangement DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement( comm_scenario = mv_comm_scenario service_id = 'PRINT_SERVICE" ).
ro_client = cl_web_http_client_manager=>create_by_http_destination( lo_destination ). ENDMETHOD.
ENDCLASS.Output Control - Gestion centralisée des sorties
Pour les scénarios complexes avec différents canaux de sortie, SAP propose Output Control (également connu sous le nom de PPF - Post Processing Framework).
Concept
Output Control permet :
- Sortie automatique de documents basée sur des règles
- Différents canaux de sortie (impression, e-mail, EDI)
- Contrôle du timing (immédiat, planifié, manuel)
- Logique de retry en cas d’erreur
Types de sortie
| Type de sortie | Description | Exemple |
|---|---|---|
| Impression physique | Bon de livraison | |
| Envoi par e-mail | Confirmation de commande | |
| EDI | Échange de données électroniques | Commande au fournisseur |
| Archive | Archivage | Facture vers DMS |
Exemple de code : Créer une demande de sortie
" Créer une Output Request pour un documentCLASS zcl_output_control DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_output_request, document_id TYPE string, document_type TYPE string, output_type TYPE string, " PRINT, EMAIL, ARCHIVE output_channel TYPE string, recipient TYPE string, priority TYPE i, scheduled_time TYPE timestampl, END OF ty_output_request.
METHODS: create_output_request IMPORTING is_request TYPE ty_output_request RETURNING VALUE(rv_request_id) TYPE string.
METHODS: process_output_request IMPORTING iv_request_id TYPE string RAISING zcx_output_error.
METHODS: get_output_status IMPORTING iv_request_id TYPE string RETURNING VALUE(rv_status) TYPE string.
ENDCLASS.
CLASS zcl_output_control IMPLEMENTATION.
METHOD create_output_request. " Sauvegarder l'Output Request dans une table DATA ls_request TYPE zoutput_request.
ls_request-request_uuid = cl_system_uuid=>create_uuid_x16_static( ). ls_request-document_id = is_request-document_id. ls_request-document_type = is_request-document_type. ls_request-output_type = is_request-output_type. ls_request-output_channel = is_request-output_channel. ls_request-recipient = is_request-recipient. ls_request-priority = is_request-priority. ls_request-scheduled_time = is_request-scheduled_time. ls_request-status = 'PENDING'. ls_request-created_at = cl_abap_tstmp=>utclong_current( ).
INSERT zoutput_request FROM @ls_request.
rv_request_id = cl_system_uuid=>convert_uuid_x16_static( uuid = ls_request-request_uuid ). ENDMETHOD.
METHOD process_output_request. " Charger la request SELECT SINGLE * FROM zoutput_request WHERE request_uuid = @( cl_system_uuid=>convert_uuid_c36_static( iv_request_id ) ) INTO @DATA(ls_request).
IF sy-subrc <> 0. RAISE EXCEPTION TYPE zcx_output_error EXPORTING textid = zcx_output_error=>request_not_found. ENDIF.
" Statut sur Processing UPDATE zoutput_request SET status = 'PROCESSING" WHERE request_uuid = @ls_request-request_uuid.
TRY. " Traiter selon le type de sortie CASE ls_request-output_type. WHEN 'PRINT'. process_print_output( ls_request ). WHEN 'EMAIL'. process_email_output( ls_request ). WHEN 'ARCHIVE'. process_archive_output( ls_request ). WHEN OTHERS. RAISE EXCEPTION TYPE zcx_output_error EXPORTING textid = zcx_output_error=>unknown_output_type. ENDCASE.
" Succès UPDATE zoutput_request SET status = 'COMPLETED', processed_at = @( cl_abap_tstmp=>utclong_current( ) ) WHERE request_uuid = @ls_request-request_uuid.
CATCH zcx_output_error INTO DATA(lx_error). " Enregistrer l'erreur UPDATE zoutput_request SET status = 'ERROR', error_message = @( lx_error->get_text( ) ) WHERE request_uuid = @ls_request-request_uuid.
RAISE EXCEPTION lx_error. ENDTRY. ENDMETHOD.
METHOD get_output_status. SELECT SINGLE status FROM zoutput_request WHERE request_uuid = @( cl_system_uuid=>convert_uuid_c36_static( iv_request_id ) ) INTO @rv_status. ENDMETHOD.
ENDCLASS.Envoi par e-mail comme canal de sortie
L’envoi par e-mail est une alternative courante à l’impression dans ABAP Cloud.
Exemple de code : Envoyer un document par e-mail
" Envoyer un document par e-mailCLASS zcl_email_document_sender DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_email_request, recipient TYPE string, subject TYPE string, body_text TYPE string, attachment TYPE xstring, attachment_name TYPE string, attachment_type TYPE string, END OF ty_email_request.
METHODS: send_document IMPORTING is_request TYPE ty_email_request RAISING cx_bcs_exception.
ENDCLASS.
CLASS zcl_email_document_sender IMPLEMENTATION.
METHOD send_document. " Envoyer un e-mail avec pièce jointe DATA(lo_mail) = cl_bcs_mail_message=>create_instance( ).
" Définir le destinataire lo_mail->add_recipient( is_request-recipient ).
" Définir le sujet lo_mail->set_subject( is_request-subject ).
" Définir le corps lo_mail->set_main( cl_bcs_mail_textpart=>create_instance( iv_content = is_request-body_text iv_content_type = 'text/plain" ) ).
" Ajouter une pièce jointe IF is_request-attachment IS NOT INITIAL. lo_mail->add_attachment( cl_bcs_mail_binarypart=>create_instance( iv_content = is_request-attachment iv_content_type = is_request-attachment_type iv_filename = is_request-attachment_name ) ). ENDIF.
" Envoyer l'e-mail lo_mail->send( ). ENDMETHOD.
ENDCLASS.Intégration avec RAP
" RAP Action pour envoi de documentMETHOD sendDocument FOR MODIFY IMPORTING keys FOR ACTION Document~sendDocument RESULT result.
" Charger les documents READ ENTITIES OF zi_document IN LOCAL MODE ENTITY Document ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_documents).
LOOP AT lt_documents INTO DATA(ls_document). TRY. " Générer le PDF DATA(lo_pdf_gen) = NEW zcl_pdf_generator( ). DATA(lv_pdf) = lo_pdf_gen->generate_document_pdf( ls_document ).
" Envoyer par e-mail DATA(lo_email_sender) = NEW zcl_email_document_sender( ). lo_email_sender->send_document( VALUE #( recipient = ls_document-contact_email subject = |Votre document : { ls_document-document_number }| body_text = |Mesdames, Messieurs,\n\n| && |Veuillez trouver ci-joint votre document.\n\n| && |Cordialement| attachment = lv_pdf attachment_name = |Document_{ ls_document-document_number }.pdf| attachment_type = 'application/pdf" ) ).
" Message de succès APPEND VALUE #( %tky = ls_document-%tky %param = ls_document ) TO result.
CATCH cx_bcs_exception INTO DATA(lx_mail). APPEND VALUE #( %tky = ls_document-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = lx_mail->get_text( ) ) ) TO reported-document. ENDTRY. ENDLOOP.ENDMETHOD.Alternatives au Spool classique
Comparaison On-Premise vs. Cloud
| Aspect | On-Premise (Spool) | ABAP Cloud |
|---|---|---|
| Ordres d’impression | SP01, Ordres Spool | Cloud Print Manager, Print Queues |
| Configuration imprimante | SPAD | BTP Cockpit, Print Agent |
| Formulaires | SmartForms, Adobe Forms | SAP Forms Service, services externes |
| Gestion sortie | NACE, Output Types | Output Control, RAP Actions |
| Archivage | ArchiveLink | SAP Document Management |
| Monitoring | SP02, SMX | Apps Fiori, Logging |
Alternative 1 : Téléchargement PDF au lieu d’impression
L’alternative la plus simple à l’impression est le téléchargement PDF :
" Téléchargement PDF via RAP Actionaction downloadDocument parameter ZA_DownloadParams result [1] ZA_DownloadResult;L’utilisateur peut ensuite imprimer le PDF localement.
Alternative 2 : Impression basée navigateur
" Générer HTML avec Print-CSSCLASS zcl_browser_print DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS: generate_printable_html IMPORTING is_data TYPE any RETURNING VALUE(rv_html) TYPE string.
ENDCLASS.
CLASS zcl_browser_print IMPLEMENTATION.
METHOD generate_printable_html. " HTML avec CSS optimisé pour impression rv_html = |<!DOCTYPE html>| && |<html>| && |<head>| && |<style>| && |@media screen \{| && | .print-button \{ display: block; margin: 20px; padding: 10px; \}| && |\}| && |@media print \{| && | .print-button \{ display: none; \}| && | body \{ margin: 0; padding: 15mm; font-family: Arial; \}| && | @page \{ size: A4; margin: 15mm; \}| && | table \{ width: 100%; border-collapse: collapse; \}| && | th, td \{ border: 1px solid #000; padding: 5px; \}| && |\}| && |</style>| && |</head>| && |<body>| && |<button class="print-button" onclick="window.print()">| && | Imprimer le document| && |</button>| && |<!-- Contenu du document ici -->| && |</body>| && |</html>|. ENDMETHOD.
ENDCLASS.Alternative 3 : Services d’impression tiers
Pour des besoins spécifiques, des services d’impression externes peuvent être utilisés :
" Intégration avec service d'impression externeCLASS zcl_external_print_service DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS: submit_to_print_service IMPORTING iv_document TYPE xstring iv_printer_id TYPE string RETURNING VALUE(rv_job_id) TYPE string RAISING cx_web_http_client_error.
ENDCLASS.Configuration d’imprimante
Configurer Print Agent
Le Print Agent est un composant On-Premise qui établit la connexion entre Cloud Print Manager et les imprimantes locales :
- Téléchargement : Télécharger Print Agent depuis SAP Software Center
- Installation : Installer sur un serveur dans le réseau d’entreprise
- Configuration : Établir la connexion au service BTP
- Enregistrer imprimantes : Enregistrer les imprimantes locales sur l’Agent
Propriétés d’imprimante
" Obtenir les informations d'imprimanteTYPES: BEGIN OF ty_printer_info, printer_id TYPE string, printer_name TYPE string, queue_name TYPE string, location TYPE string, capabilities TYPE string_table, " duplex, color, staple status TYPE string, " online, offline, error END OF ty_printer_info.Sélection d’imprimante dans l’application
" Sélection d'imprimante pour l'utilisateurMETHOD get_available_printers. DATA(lo_print_mgr) = NEW zcl_print_manager( 'Z_PRINT_COMM' ).
" Obtenir les queues DATA(lt_queues) = lo_print_mgr->get_print_queues( ).
" Afficher dans l'UI (par ex. comme Value Help) rt_printers = lt_queues.ENDMETHOD.Monitoring et gestion des erreurs
Surveiller les ordres d’impression
" Classe de monitoring pour ordres d'impressionCLASS zcl_print_monitor DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_job_info, job_id TYPE string, document_name TYPE string, queue_name TYPE string, status TYPE string, submitted_at TYPE timestampl, completed_at TYPE timestampl, error_message TYPE string, END OF ty_job_info.
METHODS: get_pending_jobs RETURNING VALUE(rt_jobs) TYPE STANDARD TABLE OF ty_job_info WITH KEY job_id.
METHODS: get_failed_jobs RETURNING VALUE(rt_jobs) TYPE STANDARD TABLE OF ty_job_info WITH KEY job_id.
METHODS: retry_failed_job IMPORTING iv_job_id TYPE string RAISING zcx_output_error.
ENDCLASS.Logging avec Application Log
" Enregistrer les actions de sortieCLASS zcl_output_logger DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS: log_output_request IMPORTING iv_request_id TYPE string iv_action TYPE string iv_status TYPE string iv_message TYPE string OPTIONAL.
ENDCLASS.
CLASS zcl_output_logger IMPLEMENTATION.
METHOD log_output_request. TRY. DATA(lo_log) = cl_bali_log=>create_with_header( header = cl_bali_header_setter=>create( object = 'ZOUTPUT" subobject = 'PRINT" ) ).
DATA(lv_severity) = COND #( WHEN iv_status = 'ERROR" THEN if_bali_constants=>c_severity_error WHEN iv_status = 'WARNING" THEN if_bali_constants=>c_severity_warning ELSE if_bali_constants=>c_severity_status ).
lo_log->add_item( item = cl_bali_message_setter=>create( severity = lv_severity id = 'ZOUTPUT" number = '001" variable_1 = CONV #( iv_request_id ) variable_2 = CONV #( iv_action ) variable_3 = CONV #( iv_message ) ) ).
cl_bali_log_db=>get_instance( )->save_log( log = lo_log ).
CATCH cx_bali_runtime. " Ignorer les erreurs de logging ENDTRY. ENDMETHOD.
ENDCLASS.Best Practices
Recommandations pour Output Management
| Aspect | Recommandation |
|---|---|
| Documents simples | Téléchargement PDF avec impression navigateur |
| Impression régulière | Cloud Print Manager avec Print Agent |
| Sortie de masse | Traitement asynchrone avec Background Jobs |
| Traçabilité | Application Logging pour toutes les sorties |
| Gestion erreurs | Logique de retry et notifications |
Checklist pour implémentation de sortie
- Définir le canal de sortie : Impression, e-mail, téléchargement ?
- Définir le format de document : PDF, HTML, autre ?
- Configurer imprimantes/destinations : Print Agent, serveur e-mail
- Implémenter la gestion d’erreurs : Retries, notifications
- Mettre en place le monitoring : Logging, suivi de statut
- Vérifier les autorisations : Qui peut sortir quoi ?
Sujets complémentaires
- Génération PDF dans ABAP Cloud - Créer des documents en PDF
- HTTP Client - Communication avec services externes
- Background Jobs - Traitement de sortie asynchrone
- Application Logging - Enregistrer les sorties
Résumé
Output Management dans ABAP Cloud nécessite de nouvelles approches :
- Cloud Print Manager remplace le Spool classique et permet l’impression Cloud-vers-On-Premise
- Print Agent connecte le Cloud aux imprimantes réseau locales
- Téléchargement PDF est l’alternative la plus simple à l’impression directe
- Envoi par e-mail convient pour la livraison automatisée de documents
- Output Control gère des scénarios de sortie complexes avec différents canaux
- Monitoring et logging sont essentiels pour les systèmes productifs
Le choix de la bonne méthode de sortie dépend de vos besoins : pour des scénarios simples, le téléchargement PDF suffit, pour des exigences d’entreprise, Cloud Print Manager est la solution robuste.