venerdì 28 settembre 2018

Previsioni di consumo: settimanali o mensili?

Quando si devono fornire delle previsioni di consumo dei materiali si vorrebbe, nel breve periodo, dare una stima più dettagliata, più avanti invece è preferibile mostrare un dato più aggregato.

Per esempio con fornitori che lavorano in modalità Kanban, nel nostro caso legato a dei Piani di Consegna,  si vuole fornire anche una previsione di consumo dei materiali.

La richiesta era di dare una previsione settimanale per il primo mese, poi un dato aggregato per mese nei periodi successivi.


Qui però c'è un problema di aggregazione: adesso siamo nella settimana 39 dell'anno 2018, se prendiamo 4 settimane la situazione è questa:


Si arriva al 21 ottobre, ma come ci si comporta con gli impegni del periodo 22-31 ottobre?

Si mostrano comunque come impegni di ottobre? In questo caso si darebbe una visione alterata mostrando un mese che sembra consumare poco materiale.

Una soluzione potrebbe essere svincolarsi dai mesi e, per il periodo in avanti, dare un dato aggregato per i 30 giorni successivi. Si ottiene una cosa di questo tipo:


Che è corretta e "pulita" dal punto di vista degli impegni, ma poco pratica e "leggibile": nella nostra testa si è sempre orientati a pensare per mesi ed inoltre, in questo modo, si andrebbe anche ad aggregare fine dicembre 2018 con parte di gennaio 2019! Davvero poco significativo.

La soluzione che ho trovato io è la seguente: mostrare gli impegni per un numero minimo di settimane, nel mio caso ho impostato 4, poi mostrare gli impegni per settimana fino a raggiungere la fine del mese in corso, nel periodo successivo mostrare gli impegni per mese completo. In pratica si ha una visione settimanale con un numero di settimane che può variare da un minimo di 4 ad un massimo di circa 8 settimane (non ho fatto bene i conti di come può cadere).

In questo modo però si apre un altro problema: come trattare le settimane che iniziano in un mese e terminano nel mese successivo? per esempio la settimana 44 che inizia il 29 ottobre e termina il 4 novembre:


Se si mettono tutti gli impegni nella settimana 44 l'indicazione del mese di novembre ne risulterebbe falsata.

Io ho fatto in questo modo: ho riportato gli impegni dal 29 al 31 ottobre nella casella della settimana 44, fornendo però indicazione che si tratta di una settimana con un numero di giorni ridotto. Anche questo non è bello, ma mi sembra il "male minore".

Questo un esempio di come viene la stampa di un Piano di consegna:


per materiale (posizione del piano) viene prima riportata la situazione Kanban con:
  • Quantità Kanban.
  • Numero totale Kanban.
  • N. Kanban Pieni in azienda.
  • N. Kanban vuoti in azienda.
  • N. Kanban vuoti dal fornitore.
poi le previsioni con un minimo di 4 settimane, in questo esempio ne vengono riportate 6 settimane, dalla 39 alla 44, con l'indicazione che gli impegni nella settimana 44 fanno riferimento a soli 3 giorni.

Questo il dettaglio della intestazione:


Per fare in modo di mostrare la linea di separazione tra settimane e mesi nella intestazione, che non è fissa ma è mobile in base al periodo di elaborazione, ho costruito nello smartforms dei template con unica cella di larghezza via via più grande e che presentano il bordo solo nel lato sinistro:


con una condizione di visualizzazione che dipende dal numero di settimane da mostrare, passato nella chiamata al modulo.

Questa la section dove mi costruisco una tabella (con le date di inizio e fine per ogni casella di output) e dove mi costruisco la label da stampare nella intestazione.

Variabili globali:

* Tabella di appoggio per date
TYPES: BEGIN OF rec_tab2,
          dt_ini LIKE sy-datum,
          dt_fin LIKE sy-datum,
          tipo(1),
          mm(2),
          week(2),
          aaaaxx(06),
          label(20),
      END OF rec_tab2.

DATA tab_date TYPE rec_tab2 OCCURS 10 WITH HEADER LINE.

DATA: numero_week(2) TYPE n.

Codice FORM:

*&---------------------------------------------------------------------*
*&      Form  CALCOLA-DATE
*&---------------------------------------------------------------------*
FORM calcola-date .

  DATA: wa_data   LIKE sy-datum,
        wa_dt_fm  LIKE sy-datum,
        wa_dt_ini LIKE sy-datum,
        wa_dt_fin LIKE sy-datum,
        wa_week   LIKE scal-week,
        wa_week_min(2) TYPE n,
        wa_gg_sett(1) TYPE n,
        wa_gg_setts(3),
        wa_conta TYPE i,
        wa_gg2fm TYPE i,
        wa_tipo(1),
        wa_mm_att(2).

  wa_data = sy-datum.
  wa_tipo = 'W'.
* imposto numero minimo di settimane da esporre  
  wa_week_min = 4.

  CLEAR: tab_date, wa_conta, numero_week.
  REFRESH tab_date.

  DO 12 TIMES.

    ADD 1 TO wa_conta.

    CLEAR tab_date.
    tab_date-tipo = wa_tipo.

    IF wa_tipo = 'W'.

      add 1 to numero_week.

* Trovo data inizio e fine settimana.
      CALL FUNCTION 'GET_WEEK_INFO_BASED_ON_DATE'
        EXPORTING
          date   = wa_data
        IMPORTING
          week   = wa_week
          monday = wa_dt_ini
          sunday = wa_dt_fin.

* trovo il mese ad inizio settimana
      wa_mm_att = wa_dt_ini+4(2).

      CLEAR wa_gg_setts.

* se il contatore è => wa_week_min
      IF wa_conta => wa_week_min.

* trovo la data di fine mese
        CALL FUNCTION 'RP_LAST_DAY_OF_MONTHS'
          EXPORTING
            day_in            = wa_dt_ini
          IMPORTING
            last_day_of_month = wa_dt_fm.
* se cambia il mese
        IF wa_mm_att <> wa_dt_fin+4(2).

* imposto ultimo giorno settimana con data fine mese
          wa_dt_fin = wa_dt_fm.

* trovo il numero di giorni della settimana
          wa_gg_sett = wa_dt_fin - wa_dt_ini + 1.
          CONCATENATE '(' wa_gg_sett ')'
                 INTO wa_gg_setts.
          wa_tipo   = 'M'.
        ELSE.
* verifico se la domenica è l'ultimo giorno del mese.
          IF wa_dt_fin = wa_dt_fm.
            wa_tipo   = 'M'.
          ENDIF.
        ENDIF.
      ENDIF.

* per la prima colonna lascio vuota la data iniziale in modo da
* considerare anche tutti gli impegni arretrati.
      IF wa_conta > 1.
        tab_date-dt_ini = wa_dt_ini.
      ENDIF.

      tab_date-dt_fin = wa_dt_fin.
      tab_date-week   = wa_week+4(2).
      tab_date-aaaaxx = wa_week.
      CONCATENATE 'W-' tab_date-week wa_gg_setts
             INTO tab_date-label.

      APPEND tab_date.

    ELSE.

* trovo ultimo giorno del mese in corso
      CALL FUNCTION 'RP_LAST_DAY_OF_MONTHS'
        EXPORTING
          day_in            = wa_data
        IMPORTING
          last_day_of_month = wa_dt_fin.

      tab_date-dt_ini = wa_data.

* se è l'ultima casella allora si mette tutto l'oltre.
      IF wa_conta = 12.
        tab_date-dt_fin = '99991231'.
        tab_date-label = 'Oltre'.
      ELSE.
        tab_date-dt_fin = wa_dt_fin.
        CONCATENATE wa_data+0(4) '-' wa_data+4(2)

               INTO tab_date-label.
      ENDIF.

      tab_date-tipo = wa_tipo.
      tab_date-mm   = wa_data+4(2).
      tab_date-aaaaxx = wa_data+0(6).

      APPEND tab_date.

    ENDIF.

    wa_data = wa_dt_fin + 1.

  ENDDO.

ENDFORM.                    " CALCOLA-DATE

Da notare che nel 2018 il 31 dicembre è di lunedì e viene considerato il primo giorno della settimana 1 del 2019:


Questa l'intestazione che ne risulta:


Nessun commento:

Posta un commento