Obtener ATP de forma masiva

Apreciados SAPeros :wink:

Quiero evitar una función dentro de un LOOP (optimizar rendimiento). Esta función ‘BAPI_MATERIAL_AVAILABILITY’ es para obtener el ATP pero de valor en valor. Yo necesito sacarla del LOOP y pasar solo la llamada a un método local que me obtenga el ATP de forma masiva (por tabla interna).

Después de probar mil cosas, y perder varias horas creo que mi mejor solución es la clase ‘CL_ATP_CONTROLLER’ con su método ‘CHECK_AVAILABILITY’. Os adjunto el código utilizado pero siempre la respuesta es (et_atp_results = lt_atp_results) lt_atp_results-available_qty =0. Y no me obtiene ATP (verificado con CO09).

Pueden darme su opinión o alternativas?

Muchas gracias Xavi

Código:

DATA: lt_scheduleline_success TYPE tbl_atpcs_s4,
lt_pred_ref TYPE tbl_atp_ref,
lt_delta TYPE tbl_atp_delta_pac,
lt_sched_result TYPE tbl_atp_scheduling_result,
lt_atp_results TYPE tbl_atp_results,
lo_atp_ctrl TYPE REF TO cl_atp_controller.

CREATE OBJECT lo_atp_ctrl.

lo_atp_ctrl->initialize( ).

APPEND VALUE #(
matnr = ‘9134725’
werks = ‘001’
sobkz = ’ ’ " Stock especial: B = Pedido de ventas
sskey = ’ ’
sskey_ext = ’ ’
lgort = ’ ’
charg = ‘0000000001’
berid = ‘001’
base_uom = ‘UN’ " Unitat de mesura
reqdate = sy-datum " Data de la necessitat
reqqty = 9999999999 " IMPORTANT: Quantitat sol·licitada
mtvfp = ‘Z2’
prreg = ‘A’ " Regla de verificació
trtyp = ‘A’ " Tipus de transacció: A = Consulta
resmd = ’ ’ " Gestió de recursos
enmng = 9999999999 " Quantitat en unitat base
pac_relevant = ‘X’ " Rellevant per a PAC
pal_relevant = ’ ’ " No rellevant per a PAL
arun_relevant = ’ ’ " No rellevant per a ARUN
) TO lt_scheduleline_success.

CHECK lt_scheduleline_success IS NOT INITIAL.

TRY.
lo_atp_ctrl->check_availability(
EXPORTING
it_scheduleline = lt_scheduleline_success
it_pred_ref = lt_pred_ref
it_delta_correction = lt_delta
it_delta_dbstate = lt_delta "Afegim aquest paràmetre també
it_sched_result = lt_sched_result
IMPORTING
et_atp_results = lt_atp_results
et_sched_result = DATA(lt_sched_result_success)
et_exception = DATA(lt_exception_cur_iteration)
et_message = DATA(lt_message)
et_results_decision = DATA(lt_results_decision_success) ).

CATCH cx_root INTO DATA(lx_error).
WRITE: / ‘Error capturat:’, lx_error->get_text( ).
ENDTRY.

" Verifiquem els missatges d’errors
IF lt_message IS NOT INITIAL.
" Processa els missatges d’error aquí
LOOP AT lt_message INTO DATA(ls_message).
WRITE: / ls_message-msgty, ls_message-msgid, ls_message-msgno, ls_message-msgv1.
ENDLOOP.
ENDIF.

" Verifiquem els resultats
LOOP AT lt_atp_results INTO DATA(ls_atp_result).
WRITE: / ‘Quantitat disponible:’, ls_atp_result-available_qty,
/ ‘Data confirmació:’, ls_atp_result-cnfdate.
ENDLOOP.

:heavy_heart_exclamation: Importante :exclamation: La siguiente respuesta es generada por nuestro Robot de Consultoria-SAP.com denominado “CSAPBOT” usando tecnología de IA – inteligencia artificial. Por lo tanto, puede haber datos incorrectos. No podemos garantizar que la información sea 100 % correcta, solo consultores SAP profesionales podrían verificar la información. Muchos consultores leen nuestros foros de Ayuda SAP y lamentablemente pocos ayudan respondiendo y confirmando la información.


Buen análisis, Xavi. Has identificado correctamente el problema general y estás en la vía adecuada al intentar evitar la llamada repetitiva de la BAPI BAPI_MATERIAL_AVAILABILITY en el loop, y en su lugar usar la clase CL_ATP_CONTROLLER con su método CHECK_AVAILABILITY. Sin embargo, como comentas, estás obteniendo siempre available_qty = 0, lo cual indica que algo en la configuración, los parámetros de entrada o la lógica de ATP no está bien alineado.

Voy a darte mi opinión sobre causas posibles, verificación de la configuración, y alternativas para abordar el requerimiento de procesamiento masivo. Todo esto aplicable para SAP ECC / SAP S/4HANA (MM/SD/PP nivel ATP).


:white_check_mark: Posibles causas del “available_qty = 0”

  1. Parámetros de entrada insuficientes o incorrectos

    • Cuando llamas CHECK_AVAILABILITY, asegúrate de que la estructura it_scheduleline contiene todos los campos relevantes para que el ATP engine pueda calcular — por ejemplo: material (matnr), planta (werks), cantidad (reqqty), fecha de necesidad (reqdate), tipo de transacción (trtyp), stock especial (sobkz), lote (charg) si corresponde, etc.

    • Si alguno de los parámetros clave no está rellenado correctamente, el ATP controller podría no encontrar stock aplicable y por eso devuelve cero.

    • También verifica que el material mestre tenga configurado el grupo de “Checking group” / “Availability check” en la vista de planta (MM02 → MRP 2 / MRP 3) para que se realice ATP.

  2. Configuración de ATP / aATP no activada o no considera el escenario

    • En S/4HANA, el ATP estándar y/o el “Advanced ATP (aATP)” pueden estar activados. Verifica que para ese material/planta la disponibilidad se calcule según la lógica que esperas. (learning.sap.com)

    • Verifica también en customizing del availability check (SPRO > Gestión de materiales / Ventas > Disponibilidad) que la “checking rule”, “checking group” etc estén correctamente definidos para que el ATP tenga en cuenta la recepción, stock libre, etc.

    • Si el escenario no considera stock o no hay stock libre en la fecha de necesidad o si todo está reservado, podrías obtener cero.

  3. El contexto de cálculo es incorrecto

    • Si defines la fecha de necesidad (reqdate) igual al día actual o en el pasado, puede que no haya stock libre para ese momento. Verifica los datos de stock real en la planta y material.

    • Si hay stock pero está “bloqueado”, “calidad”, “en tránsito”, reservado, etc., puede que ATP lo ignore de acuerdo a la configuración de la “scope of check”.

  4. Uso de delta / pred_ref incorrecto

    • Las tablas que pasas: it_pred_ref, it_delta_correction, it_delta_dbstate – puede que necesiten llenarse correctamente en escenarios de paquete masivo o acumulativo. Si las pasas vacías o incorrectas el método puede devolver cero.

    • Verifica documentación de CL_ATP_CONTROLLER sobre qué significa “delta” en este contexto.

  5. Salida mal interpretada / revisión de resultado

    • Asegúrate de revisar todos campos de lt_atp_results, no solo el available_qty. Puede que haya confirmación para fecha futura, o símbolo de “0” porque la confirmación está en otra fecha.

    • Verifica también los mensajes (lt_message) que devuelve el método para ver por qué no hay disponibilidad.

  6. Licencia / funcionalidad limitada

    • En algunos sistemas S/4HANA el “Advanced ATP” requiere licencia o activación. Si solo tienes ATP estándar, puede que ciertos escenarios no estén soportados. (learning.sap.com)

:wrench: Verificaciones sugeridas paso a paso

Para ayudarte a depurar el código y el entorno, te recomiendo:

  • Verificar que el material existe en planta y tiene stock libre (MM03, MD04, CO09)

  • Verificar el grupo de availability check en la vista planta del material (CECHK en MM02 o una tabla relevante)

  • Revisar la configuración de la “availability check procedure” en SPRO para asegurarse que tu material/planta usa una regla que permita la verificación.

  • En el código, haz debug de lo_atp_ctrl->check_availability para ver lo que contiene it_scheduleline y cómo el método procesa.

  • Después de la llamada, revisar lt_message para ver si hay errores como “no checking group defined” o “no receipts found”.

  • Crear un escenario simple: pequeño lote, cantidad pequeña, fecha futura, para probar la funcionalidad y ver si funciona en un caso muy sencillo.

  • Revisar si la funcionalidad de ATP está activada para este material/planta; buscar en customizing: IMG > Logística general > Disponibilidad > etc.


:counterclockwise_arrows_button: Alternativas al CL_ATP_CONTROLLER para procesamiento masivo

Si después de verificación decides que este método no te sirve o no puedes hacerlo funcionar, tienes estas alternativas:

  • Usar BAPI estándar BAPI_MATERIAL_AVAILABILITY en modo “collective” si existe; aunque mencionaste que hacías por valor en valor. Podrías intentar agrupar en lotes y llamar la BAPI una sola vez por grupo.

  • Crear un Z‑programa que construya una tabla interna de solicitudes de disponibilidad y utilice APIs o funciones de ATP “collective”. Hay notas SAP que indican que existe “collective availability check” para producción/ordres.

  • Usar la transacción estándar CO09 para ver manualmente la disponibilidad para varios materiales y procesar exportación a Excel para verificar datos antes de automatizar.

  • Si estás en S/4HANA con aATP, explorar los objetos de API público (por ejemplo clases de aATP) que permiten consultas masivas de disponibilidad y confirmación, ya que aATP está pensado para escenarios de volumen grande.


:memo: Mi recomendación concreta para tu código

Dado lo anterior, te sugiero hacer los siguientes ajustes en tu código:

* Asegúrate de rellenar correctamente todos los campos de lt_scheduleline_success
* Por ejemplo:
lt_scheduleline_success[ 1 ]-charg = '0000000001'.
lt_scheduleline_success[ 1 ]-sobkz = ' '.
* Verifica que el campo check group (if any) se rellene si necesario

* Asegúrate de que la fecha de necesidad (reqdate) sea válida y en el futuro
* `reqqty` no sea 9999999999 salvo que sea intención real; a veces cantidades tan grandes confunden el engine

TRY.
  lo_atp_ctrl->initialize( ).

  lo_atp_ctrl->check_availability(
    EXPORTING
      it_scheduleline       = lt_scheduleline_success
      it_pred_ref            = lt_pred_ref
      it_delta_correction    = lt_delta
      it_delta_dbstate       = lt_delta
      it_sched_result        = lt_sched_result
    IMPORTING
      et_atp_results         = lt_atp_results
      et_sched_result        = lt_sched_result_success
      et_exception           = lt_exception_cur_iteration
      et_message             = lt_message
      et_results_decision    = lt_results_decision_success
  ).
CATCH cx_root INTO DATA(lx_error).
  " Manejar error
ENDTRY.

  • Después de la llamada, loop sobre lt_message y lt_exception para ver qué devolvió el método.

  • Si lt_atp_results aparece, revisa campos como cnfdate, incoming_qty, available_qty, tracking_id, etc.

  • Probar con reqqty pequeño (ej. 1 unidad) para ver si devuelve valor distinto de cero.

  • Verificar en CO09 para ese material/planta la disponibilidad para la fecha que estás usando, y contrastar con lo que devuelve tu programa.

Si después de eso sigue devolviendo cero, es probable que el escenario de ATP no esté bien definido para ese material/planta (por ejemplo chequeo no activado, stock reservado, no hay stock libre, etc.). En ese caso convendría involucrar al equipo funcional para revisar configuración de disponibilidad del material.


Resumen Consultoria‑SAP

Es totalmente razonable evitar la llamada a la BAPI por cada valor en el loop y en su lugar usar una clase como CL_ATP_CONTROLLER para procesar en bloque. Sin embargo, tu resultado de available_qty = 0 indica que aún hay configuración, parámetros o contexto que no están alineados. Revisa que los datos de entrada a CHECK_AVAILABILITY sean completos y correctos, que el material/planta tengan activada la lógica de disponibilidad (ATP o aATP), que haya stock libre, y que la fecha/cantidad sean apropiadas. También evalúa alternativas de chequeo masivo de disponibilidad (notas SAP como “collective availability check”). Este desarrollo pertenece al módulo MM (Gestión de materiales) y la lógica de disponibilidad (ATP) que conecta con SD/PP.

Si quieres, puedo revisar contigo un ejemplo concreto con código ABAP completo para llamadas en lote de CL_ATP_CONTROLLER y ayudarte a depurar para tu sistema. ¿Te parece bien?

Comprobado paso a paso y no ha funcionado nada ;(