mercoledì 26 ottobre 2016

Modifica al report standard Stampa libro magazzino

Come certamente SAPpiamo è possibile personalizzare il sistema fino ad arrivare a modificare il codice sorgente in programmi o funzioni standard.

Normalmente sono sempre contrario ad arrivare a questo punto ma, se sussistono alcune condizioni:

  • modifica delimitata in un punto preciso del programma e non "invasiva"
  • molto ben documentata
  • che porta benefici significativi alla funzionalità
  • che, se disattivata, non comporta particolari problemi

è accettabile, secondo me, procedere attraverso questa strada.

In ogni caso è bene limitarle il più possibile, per dare qualche numero: nella installazione attuale, dopo 4 anni di utilizzo, si è resa necessaria UNA modifica allo standard; nell'azienda dove lavoravo prima, dopo circa 12 anni di SAP, le modifiche si potevano contare sulle dita di una mano.

Veniamo al caso concreto:

La stampa del registro di magazzino viene normalmente effettuata diversi mesi dopo la chiusura dell'anno contabile, quindi a distanza di molti mesi dalla data dei movimenti. Nella lista vengono riportati anche i movimenti verso clienti e fornitori, ma la ragione sociale riportata è quella dell'anagrafica alla data di elaborazione stampa. In diversi casi il cliente o fornitore ha cambiato nel frattempo la ragione sociale (magari passa da SRL a SPA o altre modifiche) e dall'amministrazione chiedevano che, nel registro, venga riportata la ragione sociale che aveva il cliente/fornitore alla data del movimento.

Ho provato a vedere nel sistema se era possibile attivare una funzionalità del genere, ho cercato exit, Enhancement, etc. ma non sono arrivato a una soluzione.

Dall'amministrazione l'unico metodo trovato era il seguente: prima di stampare il registro, se nel periodo da stampare erano a conoscenza che erano state modificate denominazioni, procedevano a modificare la ragione sociale riportando la vecchia, si lanciava la stampa del registro, poi si rimetteva a posto l'anagrafica. Questo era piuttosto noioso, erano possibili errori di inserimento e "sporcava" la storia delle modifiche tracciata in SAP.

Ho quindi deciso di esplorare la strada alla modifica dello standard e, verificato che poteva rispondere ai requisiti riportati sopra, ho deciso di procedere in tal senso.

Per fare una cosa "pulita" ho creato una funzione che, dato il codice di un cliente/fornitore e una data, restituisca la ragione sociale alla data indicata cercando nello storico modifiche.

Nota: anche questo però non era sufficiente poichè, talvolta, le modifiche alla ragione sociale vengono inserite a sistema con un certo ritardo (tempi di comunicazione o altri impedimenti), per cui non sempre è corretto prendere la data di inserimento della modifica. Per gestire questi casi isolati (poi rivelatosi UN solo caso!) ho creato una tabella Z dove registrarli tramite SM30.


Funzione Z_NAME1_OLD

Importazione

Esportazione

Codice

FUNCTION z_name1_old.
*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*"  IMPORTING
*"     REFERENCE(TIPO) TYPE  CHAR01
*"     REFERENCE(CODICE) TYPE  CDHDR-OBJECTID
*"     REFERENCE(DATA) TYPE  DATS
*"  EXPORTING
*"     REFERENCE(NAME1_OLD) TYPE  CHAR40
*"     REFERENCE(UDATE) TYPE  CDHDR-UDATE
*"----------------------------------------------------------------------
* Autore     : Fabio Giacobbe - 19/05/2016                             |
* Descrizione: Ricerca ragione sociale alla data.                      |
*----------------------------------------------------------------------+
* Modifiche  :            by                                           |
* Note       :                                                         |
*----------------------------------------------------------------------+
* parametri
*   ingresso:
*      TIPO  : Tipo C=cliente - F=Fornitore
*      CODICE: codice del cliente o fornitore
*      DATA  : data alla quale si vuole cercare la vecchia rag.sociale
*   uscita:
*      NAME1_OLD: valore NAME1 alla data
*      UDATE    : data successiva modifica
*----------------------------------------------------------------------+
* Descrizione funzionamento:
*
*   Cerca nell'archivio delle modifiche la prima modifica al campo
*   NAME1 successiva alla data inserita: il valore precedente
*   indica che ragione sociale era attiva alla data di input e lo
*   restituisce come valore.
*----------------------------------------------------------------------+

  DATA: wa_cdhdr      LIKE cdhdr,
        wa_cdpos      LIKE cdpos,
        wa_codice(10),
        wa_zrsstorica LIKE zrsstorica,
        wa_objectclas LIKE cdhdr-objectclas,
        wa_tabname    LIKE cdpos-tabname.

* verifico nella tabella storico ragione sociale
  wa_codice = codice.
  SELECT SINGLE * FROM zrsstorica INTO wa_zrsstorica
                 WHERE   tipo   = tipo
                   AND codice   = wa_codice
                   AND data_ini <= data
                   AND data_fin => data.
  IF sy-subrc = 0.
    name1_old = wa_zrsstorica-name1.
    udate     = wa_zrsstorica-data_fin.
    EXIT.
  ENDIF.

  CASE tipo.
    WHEN 'F'.
      wa_objectclas = 'KRED'.
      wa_tabname    = 'LFA1'.
    WHEN 'C'.
      wa_objectclas = 'DEBI'.
      wa_tabname    = 'KNA1'.
    WHEN OTHERS.
      EXIT.
  ENDCASE.

* cerco tutte le modifiche all'anagrafica materiale successive alla
* data inserita.
  SELECT * FROM cdhdr INTO wa_cdhdr
                     WHERE objectclas = wa_objectclas
                       AND objectid   = codice
                       AND udate      => data
                     ORDER BY udate utime.    "in ordine data-ora

* verifico se si tratta di una modifica alla ragione sociale
    SELECT SINGLE * FROM cdpos INTO wa_cdpos
                              WHERE objectclas = wa_cdhdr-objectclas
                                AND objectid   = wa_cdhdr-objectid
                                AND changenr   = wa_cdhdr-changenr
                                AND tabname    = wa_tabname
                                AND fname      = 'NAME1'
                                AND chngind    = 'U'.
    IF sy-subrc = 0.

      name1_old = wa_cdpos-value_old.
      udate     = wa_cdhdr-udate.

      EXIT.

    ENDIF.
  ENDSELECT.

ENDFUNCTION.

Nota: può essere anche tolta la parte relativa alla tabella ZRSSTORICA se si vuole evitare di dover creare e gestire la tabella, in questo caso vale la data di inserimento modifica ragione sociale.

Adesso che è disponibile la funzione procediamo con la modifica del programma originale RFBELJ10_NACC.

Quando si tenta di entrare, con l'editor SE38, in modifica il sistema chiede la chiave di accesso: infatti ad ogni modifica di un oggetto standard (può essere un programma, una funzione, una tabella, etc) ci si deve collegare al portale SAP e sbloccare l'oggetto in questione.


ci sono 2 punti precisi dove viene letta l'anagrafica rispettivamente di clienti e fornitori:

Clienti

        IF t-koart = 'D'.
          CALL FUNCTION 'READ_KNA1'
            EXPORTING
              xkunnr         = t-konto
            IMPORTING
              xkna1          = kna1
            EXCEPTIONS              "<<INSERT:68132
              not_found      = 1 "<<INSERT:68132
              key_incomplete = 2 "<<INSERT:68132
              not_authorized = 3."<<INSERT:68132
          CASE sy-subrc.               "<<INSERT:68132
             .... (non riporto il codice CASE-ENDCASE che ho lasciato invariato)
          ENDCASE.
*{   INSERT         
* F.G. 23/05/2016: modificato Standard per leggere ragione sociale alla
*                  data di inizio report.
          Data: wa_name1_old(40),
                wa_codice like CDHDR-OBJECTID.
          CLEAR: wa_name1_old, wa_codice.
          wa_codice = t-konto.
          CALL FUNCTION 'Z_NAME1_OLD'
            EXPORTING
              tipo            = 'C'
              codice          = wa_codice
              DATA            = budat_low
            IMPORTING
              NAME1_OLD       = wa_name1_old
                    .
          IF NOT wa_name1_old IS INITIAL.
            kna1-name1 = wa_name1_old.
            kna1-sortl = wa_name1_old.
          ENDIF.
*}   INSERT


Fornitori

        IF t-koart = 'K'.
          CALL FUNCTION 'READ_LFA1'
            EXPORTING
              xlifnr         = t-konto
            IMPORTING
              xlfa1          = lfa1
            EXCEPTIONS
              not_found      = 1
              key_incomplete = 2
              not_authorized = 3.

          CASE sy-subrc.
             .... (non riporto il codice CASE-ENDCASE che ho lasciato invariato)
          ENDCASE.
*{   INSERT         
* F.G. 23/05/2016: modificato Standard per leggere ragione sociale alla
*                  data di inizio report.
          CLEAR: wa_name1_old, wa_codice.
          wa_codice = t-konto.
          CALL FUNCTION 'Z_NAME1_OLD'
            EXPORTING
              tipo            = 'F'
              codice          = wa_codice
              DATA            = budat_low
            IMPORTING
              NAME1_OLD       = wa_name1_old
                    .
          IF NOT wa_name1_old IS INITIAL.
            lfa1-name1 = wa_name1_old.
            lfa1-sortl = wa_name1_old.
          ENDIF.
*}   INSERT

Adesso la stampa registro riporta la ragione sociale che il cliente/fornitore aveva alla data di inizio periodo del report.

Nessun commento:

Posta un commento