Améliorations pour la réception et l'annulation dans la transaction MIGO de SAP ABAP

Dans le cadre de la gestion des mouvements de marchandises via la trensaction MIGO, des points d'extension spécifiques permettent d'ajouter une logique métier personnalisée pour les opérations de réception et d'annulation. Ce document décrit les différentes méthodes d'amélioration disponibles et fournit des exemples de code adaptés.

Amélioration de l'interface MIGO

Pour intercepter les traitements au niveau de l'interface, on utilise le point d'extension MB_GOODSMOVEMENT (BADI). La mise en œuvre implique la création d'une implémentation BADI via SE18, puis la surcharge des méthodes pertinentes.


" Exemple pour le traitement des réceptions (mouvements 101, 123)
DATA: ls_document TYPE mkpf,
      ls_posting  TYPE mseg,
      lt_custom   TYPE TABLE OF zsd_custom_table,
      lv_ref_id   TYPE zrfcid,
      lv_counter  TYPE i VALUE 0.

LOOP AT i_documents INTO ls_document.
  LOOP AT i_postings INTO ls_posting
       WHERE mblnr = ls_document-mblnr
         AND mjahr = ls_document-mjahr.

    " Ignorer les lignes sans numéro d'achat ou avec type de mouvement non ciblé
    IF ls_posting-ebeln IS INITIAL OR
       ( ls_posting-bwart <> '101' AND ls_posting-bwart <> '123' ).
      CONTINUE.
    ENDIF.

    " Recherche du processus de commande
    SELECT SINGLE * INTO @DATA(ls_process)
      FROM zsd_order_process
      WHERE order_number = @ls_posting-ebeln
        AND process_type = 'PO'
        AND version      = '0010'.
    IF sy-subrc <> 0. CONTINUE. ENDIF.

    " Récupération de l'identifiant de référence
    SELECT SINGLE * INTO @DATA(ls_ref_config)
      FROM zsd_reference_config
      WHERE reference_id = @ls_process-reference_id
        AND version      = '0010'.
    IF sy-subrc <> 0. CONTINUE. ENDIF.

    lv_ref_id = ls_ref_config-reference_id.
    lv_counter = lv_counter + 1.

    " Construction des données personnalisées
    APPEND VALUE #(
      purchase_order   = ls_posting-ebeln
      item_number      = ls_posting-ebelp
      posting_date     = ls_document-budat
      document_date    = ls_document-bldat
      quantity         = ls_posting-menge
      batch            = ls_posting-charg
      material_doc     = ls_posting-mblnr
      material_doc_year = ls_posting-mjahr
      line_item        = ls_posting-zeile
      reference_doc    = ls_document-xblnr
      reference_id     = lv_ref_id
      sequence_number  = lv_counter * 10
    ) TO lt_custom.
  ENDLOOP.
ENDLOOP.

IF lt_custom IS NOT INITIAL.
  CALL FUNCTION 'Z_UPDATE_CUSTOM_TABLES'
    EXPORTING
      iv_reference   = lv_ref_id
    TABLES
      it_custom_data = lt_custom.
ENDIF.

Amélioration via BADI de troisième génération

Cette méthode intercepte les appels provenant de BAPI (et non de l'itnerface graphique). L'implémentation se fait via SE19.


" Traitement spécifique pour les transactions MIGO
IF sy-tcode = 'MIGO'.
  DATA: ls_header    TYPE mkpf,
        lt_items     TYPE TABLE OF mseg,
        lt_log_data  TYPE TABLE OF zsd_receipt_log,
        lv_process   TYPE zrfcid.

  " ... (Logique similaire mais adaptée pour le contexte BAPI)
  " Collecte des données et appel d'un module fonctionnel dédié
  CALL FUNCTION 'Z_PROCESS_RECEIPT_LOG'
    EXPORTING
      iv_process_id = lv_process
    TABLES
      it_log_entries = lt_log_data.
ENDIF.

" Logique pour les annulations (mouvements 102, 122)
" ... (Code adapté pour capturer les annulations et mettre à jour les références)

Validation des postes

Des vérifications supplémentaires peuvent être ajoutées au niveau des lignes de poste. L'exemple suivant empêche certains types de mouvement d'être associés à des ordres internes ou centres de coûts non valides.


" Validation des mouvements Z15/Z16 (sortie pour R&D)
IF cs_posting-bwart = 'Z15' OR cs_posting-bwart = 'Z16'.
  " Vérifier que l'ordre interne est de type R&D
  SELECT SINGLE order_type INTO @DATA(lv_ord_type)
    FROM coas WHERE order_number = @cs_posting-aufnr.
  IF lv_ord_type <> '1'.
    " Générer une erreur : Veuillez sélectionner un ordre interne R&D
    RETURN.
  ENDIF.

  " Vérifier que le centre de coûts est de type R&D
  SELECT SINGLE cost_center_type INTO @DATA(lv_cc_type)
    FROM csks WHERE cost_center = @cs_posting-kostl.
  IF lv_cc_type <> 'E'.
    " Générer une erreur : Veuillez sélectionner un centre de coûts lié à la R&D
    RETURN.
  ENDIF.
ENDIF.

Logique de modification des lignes

La méthode LINE_MODIFY permet de modfiier dynamiquement les données des lignes de poste. Les améliorations courantes incluent le calcul automatique des numéros de lot et la gestion des quantités pour les ordres de fabrication.


" Génération automatique du numéro de lot basé sur la date
DATA(lv_date_segment) = sy-datum+2(6).
DATA(lv_lot_pattern)  = lv_date_segment && '%'.

IF cs_posting-bwart = '101' OR cs_posting-bwart = 'Z10'.
  SELECT MAX( batch ) INTO @DATA(lv_last_batch)
    FROM mseg
    WHERE material = @cs_posting-matnr
      AND batch LIKE @lv_lot_pattern.

  IF lv_last_batch+0(6) = lv_date_segment.
    cs_posting-charg = lv_last_batch + 1.
  ELSE.
    cs_posting-charg = lv_date_segment && '0001'.
  ENDIF.
ENDIF.

" Calcul des quantités pour les ordres de fabrication planifiés
IF cs_posting-bwart = '261'.
  " Récupération des données de l'ordre de fabrication
  SELECT SINGLE required_qty, delivered_qty
    INTO @DATA(ls_order_data)
    FROM afpo INNER JOIN aufk ON afpo~order_number = aufk~order_number
    WHERE aufk~order_number = @cs_posting-aufnr
      AND aufk~deletion_flag = ''.

  " Calcul de la quantité à livrer proportionnellement
  DATA(lv_total_demand) = ls_order_data-required_qty.
  DATA(lv_remaining)    = ls_order_data-required_qty - ls_order_data-delivered_qty.

  IF lv_total_demand > 0 AND lv_remaining > 0.
    DATA(lv_proportional_qty) = ( lv_target_qty / lv_total_demand ) * cs_posting-menge.
    cs_posting-menge = lv_proportional_qty.
  ENDIF.
ENDIF.

Validation de l'en-tête

La validation de l'en-tête permet de contrôler les données globales avant le traitement. Cela inclut généralement la cohérence entre les quantités de l'en-tête et les capacités de l'ordre sous-jacent.


" Vérification que la quantité totale ne dépasse pas la capacité de l'ordre
IF header_data-order_number IS NOT INITIAL AND header_data-movement_type = '261'.
  SELECT SINGLE SUM( required_qty ), SUM( delivered_qty )
    INTO @DATA(ls_totals)
    FROM afpo
    WHERE order_number = @header_data-order_number.

  IF ls_totals-required_qty > 0.
    DATA(lv_remaining_capacity) = ls_totals-required_qty - ls_totals-delivered_qty.
    IF header_data-total_qty > lv_remaining_capacity.
      " Générer une erreur : La quantité dépasse la capacité restante de l'ordre
      et_return_messages = VALUE #( ( type = 'E' id = 'MM' number = '899'
        message = 'La quantité dépasse la capacité restante de l\'ordre' ) ).
    ENDIF.
  ENDIF.
ENDIF.

Étiquettes: SAP ABAP MIGO BADI Extension

Publié le 3 juin à 20h15