retrodoc-abap-ia/documentation/documentation_zpayments.prog.md

9.2 KiB

The user wants me to document the ABAP report ZPAYMENTS in markdown format with specific sections. Let me analyze the code carefully.

Documentation technique : ZPAYMENTS

Rapport : ZPAYMENTS | Créé le : 01.01.2016 | Auteur : Hifzulla.A (I065658) Objectif : Automatiser le paiement des fournisseurs (Vendor Payments) en appliquant des règles métier sur les postes ouverts comptables.


Algorithmie

Le programme implémente un moteur de paiement automatique des fournisseurs en plusieurs phases :

  1. Chargement des règles de paiement : lecture de la table custom ZPAYMENTRULES qui définit la liste des fournisseurs éligibles et leurs paramètres (notamment dayslate).

  2. Extraction des postes ouverts : sélection dans BSIK (postes fournisseurs ouverts) des documents de type RE (facture) et KR (avoir crédit) pour tous les fournisseurs présents dans les règles.

  3. Calcul de la date et du montant de paiement : pour chaque poste ouvert, le programme détermine la date de paiement et le montant à payer selon deux logiques :

    • Sans escompte (zbd1p vide ou nul) : date = date de base + délai net + jours de retard autorisés.
    • Avec escompte : selon le nombre de niveaux d'escompte (zbd2t, zbd3t), le programme compare la date du jour à la date d'escompte :
      • Si on est exactement à la date d'escompte : paiement avec déduction du taux d'escompte.
      • Sinon : paiement au net.
    • Si dayslate est renseigné : paiement forcé au net avec ajout des jours de retard sur la date nette.
  4. Filtrage des documents annulés : élimination des paires de documents H (original) / S (contrepassation) pour ne pas payer des factures déjà annulées.

  5. Posting des paiements : appel de la fonction ZFI_OUT_PAYMENT_POST_CLEAR pour chaque paiement à effectuer, avec détermination dynamique de la banque (HBKID/HKTID) selon la société (BUKRS).

  6. Journalisation : chaque tentative de paiement (succès ou échec) est tracée dans la table ZPAYMENTSLOG.

  7. Envoi d'un email de synthèse : un mail HTML récapitulatif est envoyé en fin d'exécution via SO_NEW_DOCUMENT_SEND_API1.


Objets

Tables de base de données

Objet Type Rôle
ZPAYMENTRULES Table custom Z Référentiel des fournisseurs éligibles au paiement automatique, avec paramètres (dayslate, etc.)
BSIK Table SAP standard Postes comptables fournisseurs ouverts (source des factures à payer)
ZPAYMENTSLOG Table custom Z Journal des paiements exécutés (succès / erreurs)
T052 Table SAP standard Table des conditions de paiement (déclarée mais non exploitée directement dans le code visible)

Structures et types locaux

Objet Rôle
ty_lifnr Type simple pour stocker un numéro de fournisseur
ty_paymentdata Type local de données de paiement (remplacé dans la pratique par zpayments_data_s)
zpayments_data_s Structure custom principale transportant les données de paiement enrichies (new_dateofpayment, new_wrbtr, etc.)

Tables internes principales

Variable Rôle
lt_zpaymentrules / ls_zpaymentrules Règles de paiement chargées depuis ZPAYMENTRULES
iv_lt_bsik / iv_ls_bsik Postes ouverts bruts issus de BSIK
lt_payment_data / ls_payment_data Postes filtrés et enrichis avec les dates/montants de paiement calculés
lt_payment_reversals / ls_payment_reversals Postes de contrepassation isolés pour nettoyage
lt_payment_data_temp / ls_payment_data_temp Copie de travail pour la boucle de posting
lt_paymentslog / ls_paymentslog Journal des résultats de paiement

Variables de pilotage

Variable Rôle
for_date Paramètre de sélection : date de traitement (défaut = date du jour)
bukrs Paramètre de sélection : société (défaut = 1710)
no_data Flag indiquant l'absence de données à traiter
lv_hbkid / lv_hktid Identifiants de la banque utilisée pour le paiement, déterminés par société

Fonction externe

Fonction Rôle
ZFI_OUT_PAYMENT_POST_CLEAR Fonction custom Z qui comptabilise et solde le paiement fournisseur
SO_NEW_DOCUMENT_SEND_API1 Fonction SAP standard d'envoi d'email via SAPoffice/SMTP

Dépendances

Dépendances fonctionnelles critiques

ZPAYMENTS
│
├── ZPAYMENTRULES          (table de configuration : fournisseurs éligibles)
├── BSIK                   (postes ouverts fournisseurs, source de données)
├── ZPAYMENTSLOG           (table de log, mise à jour via MODIFY)
├── ZPAYMENTS_DATA_S       (structure de données intermédiaire)
│
├── ZFI_OUT_PAYMENT_POST_CLEAR   (module fonction de posting/clearing)
│     └── Dépend de la config bancaire (HBKID/HKTID par société)
│
└── SO_NEW_DOCUMENT_SEND_API1    (envoi email SAPoffice)

Dépendances par société (mapping banque)

BUKRS HBKID HKTID
1710 USBK1 USAC1
AUC1 AUCBK AUCAC
DEC1 DECBK DECAC
USC1 USCBK USCAC

Toute nouvelle société nécessite un ajout dans le code source.

Dépendances de configuration

  • La table ZPAYMENTRULES doit être alimentée pour que le programme fonctionne.
  • Le fournisseur USSU_V8000 est exclu en dur du traitement.
  • La fonction ZFI_OUT_PAYMENT_POST_CLEAR doit exister et être fonctionnelle.
  • Le groupe de fonctions ZFGPAYMENTRULES gère la vue de maintenance de ZPAYMENTRULES.

Flux de traitement

[DÉBUT]
    │
    ├─► Affichage heure de démarrage (sy-uzeit)
    │
    ├─► SELECT * FROM ZPAYMENTRULES → lt_zpaymentrules
    │       └─► Exclusion forcée du fournisseur USSU_V8000
    │
    ├─► [SI lt_zpaymentrules vide] → Message + RETURN
    │
    ├─► SELECT FROM BSIK (blart = RE ou KR)
    │       └─► Pour tous les fournisseurs de lt_zpaymentrules
    │       └─► Filtre : zfbdt <= sy-datum (postes dont la date de base est passée)
    │
    ├─► [SI BSIK vide] → Message "No records"
    │
    ├─► LOOP sur iv_lt_bsik
    │       ├─► Cas SANS escompte (zbd1p = 0)
    │       │       └─► new_dateofpayment = zfbdt + zbd1t + dayslate
    │       │       └─► new_wrbtr = wrbtr (montant plein)
    │       │
    │       └─► Cas AVEC escompte
    │               ├─► dayslate = 0 : respect strict des termes de paiement
    │               │       ├─► 1 niveau d'escompte : si date = lv_discount_date1 → paiement escompté
    │               │       │                          sinon → paiement net
    │               │       └─► 2 niveaux d'escompte : comparaison date1 puis date2
    │               │                                   sinon → paiement net
    │               └─► dayslate > 0 : paiement net + décalage dayslate
    │
    ├─► DELETE lt_payment_data WHERE new_dateofpayment > for_date
    │
    ├─► Nettoyage des contrepassations (shkzg H/S)
    │       └─► Suppression des paires original/contrepassation de lt_payment_data
    │
    ├─► [SI lt_payment_data vide] → no_data = 'X'
    │
    ├─► LOOP sur lt_payment_data_temp (= postes à payer)
    │       ├─► Détermination HBKID/HKTID selon BUKRS
    │       ├─► CALL FUNCTION ZFI_OUT_PAYMENT_POST_CLEAR
    │       ├─► [SI ex_belnr renseigné] → log Succès
    │       └─► [SINON]                 → log Erreur
    │
    ├─► MODIFY ZPAYMENTSLOG FROM TABLE lt_paymentslog
    │
    ├─► PERFORM send_mail
    │       ├─► Construction du corps HTML (résumé statistiques + détails)
    │       ├─► Listing des erreurs puis des succès
    │       └─► CALL FUNCTION SO_NEW_DOCUMENT_SEND_API1
    │
    └─► Affichage heure de fin
[FIN]

Points d'attention

Risques techniques

# Risque Description
1 Exclusion fournisseur en dur DELETE lt_zpaymentrules WHERE lifnr EQ 'USSU_V8000' est codé en dur. Toute évolution de cette liste nécessite une modification du programme.
2 Mapping banque en dur L'association BUKRS -> HBKID/HKTID est dans un IF/ELSEIF statique. L'ajout d'une nouvelle société impose une modification de code.
3 Compte GL en dur im_hkont = '0011001000' est passé en dur à la fonction de clearing. Aucune paramétrage externe n'est prévu.
4 Variable bukrs shadowing Le filtre DELETE iv_lt_bsik WHERE bukrs NE bukrs compare le champ bukrs de la table interne avec lui-même (même nom que le paramètre de sélection). Cette condition ne filtre jamais rien et est probablement un bug.
5 Données locales déclarées dans une boucle DATA: lv_discount_date1, lv_discount_date2, lv_net_date, lv_discount_levels sont déclarés à l'intérieur d'un LOOP. En ABAP classique, cela est toléré syntaxiquement mais contraire aux bonnes pratiques et peut induire des comportements inattendus si la variable n'est pas correctement réinitialisée.
6 **Absence de gestion d'erreur sur Z