189 lines
9.2 KiB
Markdown
189 lines
9.2 KiB
Markdown
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 |