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.