Skip to Content

Change / round header gross weight in customs document

Hi all,

I would like to change / round the gross weight (Field /SAPSLL/WEIGRO) in the customs document after it is created or while being transported to GTS I am aware of the BAdIs / Exits /SAPSLL/IFEX_SD0C_R3 in ECC and /SAPSLL/CUHD_PROP in GTS.

However I got the following problem with the two BAdIs. In ECC using /SAPSLL/IFEX_SD0C_R3 I would have e.g. 2 Items in the header table. If I round them now, I would have a bigger rounding error than just rounding the summend gross weight. So I'm trying to avoid that.

On the GTS side, when using /SAPSLL/CUHD_PROP it doesn't give me any possibility to get hands on the /SAPSLL/WEIGRO field on the header. I could only change the item /SAPSLL/WEIGRO which would not suffice because the header gross weight would contain the packing material weigths as well.

Any clues on how to get hands on the gross weight in header of customs document in gts?

Cheers

Jens

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Best Answer
    Sep 14, 2011 at 07:41 PM

    Hi Jens,

    As far as I remember, the system automatically re-calculates the header weight from the items when you execute an output message. In that case, perhaps you don't need to worry about making your own calculation in the header?

    In case I'm wrong, please test carefully!

    Best regards,

    Dave

    Add comment
    10|10000 characters needed characters exceeded

  • Sep 14, 2011 at 11:00 PM

    Thanks Dave,

    ok, I did assume that the system calculates the header gross weight as a sum of all item weights.

    But in fact it calculates the header gross weight as the sum of the item gross weights including the packing material.

    Is there maybe any other solution?

    Maybe I'm just running nuts on maths here but assume you'll have 2 items one with 23,44 kg and one with 22,64 kg. This would add to 46,08 kg hence rounded to 46,1 kg.

    However if i'll round every item I'll have itll be 23,4 + 22,6 = 46,0 kg.

    Cheers

    Add comment
    10|10000 characters needed characters exceeded

    • Hi Jens,

      I see what you mean. You could re-calculate the header weight in the BAdI /SAPSLL/CUS_ECC, Method MODIFY_IDOC_VIEW. But for some countries (DE, CH) there is some subsequent calculation code, so again you would need to test carefully.

      But taking your example, the rounded weight at the header seems more-or-less correct. In that case, perhaps you should adjust the items to avoid under-stating the total weight. To do that, you would need to write a function to first round the item weights, then sum up the rounded weights and compare with the rounded total. If you find a difference, then sort the items by weight (to minimize the percentage error). If the difference is positive, then subtract 0.1 from each item in turn until you have used up the difference. If negative, then add 0.1 in the same way. FYI, GTS uses exactly that strategy in the duty calculation code.

      In your example then, you would end up with 23.5 + 22.6 = 46.1. Would that be a better solution? It depends on which is more important - to get the most accurate item weights, or the most accurate header weight.

      Best regards,

      Dave

  • Sep 16, 2011 at 08:53 PM

    Hi there,

    thanks for the insights to GTS way of handling things. After a little chat with a sap represantive who stated that he would urge us to implement any rounding operation on ECC side and let GTS handle their calculations and validation itself I implemented the "round" method in the previously mentioned BAdI "".

    Somehow the html gets distroyed by the code, however, just paste in your BAdI.

    Thanks again, Dave, for pushing me to the right direction, really appreciate this.

    Maybe this will come in handy for somebody. If there is any standard function doing compensatied summation, let me know.

    Cheers

    Jens





    METHOD round.

    =====================================================================

    • Eingebetabelle wird gerundet.

    • Abhängig vom Eingabeparameter wird summenerhaltend gerundet.

    • Abhängig vom Eingabeparameter wird auf-, ab- oder kaufm. gerundet.

    *----


    *

    TYPES:

    BEGIN OF lts_round,

    index TYPE sytabix,

    value LIKE LINE OF ct_value,

    END OF lts_round,

    ltt_round TYPE STANDARD TABLE OF lts_round.

    DATA: l_total LIKE LINE OF ct_value,

    l_total_rounded_values LIKE LINE OF ct_value,

    l_total_rounded LIKE LINE OF ct_value,

    l_total_error LIKE LINE OF ct_value,

    l_step LIKE LINE OF ct_value,

    lt_rounded TYPE ltt_round,

    l_rounded LIKE LINE OF lt_rounded,

    lt_rounded_compensated TYPE ltt_round,

    lt_value_rounded LIKE ct_value,

    l_value_rounded LIKE LINE OF ct_value.

    FIELD-SYMBOLS:

    LIKE LINE OF lt_rounded_compensated.

    =====================================================================

    • Eingabetabelle verarbeiten

    *----


    *

    LOOP AT ct_value ASSIGNING .

    • Summe über ungerundete Einzelwerte

    l_total = l_total + .

    • Runden

    CALL FUNCTION 'ROUND'

    EXPORTING

    decimals = 1

    input = 0.

    • Syst Protokollieren

    mo_log->add(

    i_protlvl = zcl_log=>mc_protlvl_important

    i_syst = abap_true ).

    zcx_general_exception=>raise_system_exception( ).

    ENDIF.

    • Wenn wir summenerhaltend runden, füllen wir eine temporäre Tabelle

    • ansonsten füllen wir die Changing Tabelle, da wir hier dann schon

    • fertig sind.

    IF i_compensated = abap_true.

    l_rounded-index = sy-tabix.

    l_rounded-value = l_value_rounded.

    APPEND l_rounded TO lt_rounded.

    • Summe über gerundete Einzelwerte

    l_total_rounded_values = l_total_rounded_values + l_value_rounded.

    ELSE.

    = l_value_rounded.

    ENDIF.

    ENDLOOP.

    *----


    *

    =====================================================================

    • Wenn wir summenerhaltendes Runden haben, machen wir weiter, ansonsten

    • liefern wir die gerundeten Einzelwerte in der Tabelle jetzt zurück.

    *----


    *

    IF i_compensated <> abap_true.

    RETURN.

    ENDIF.

    *----


    *

    =====================================================================

    • Summe runden und möglichen Fehler zur Summe der gerundeten Einzelwerte

    • ermitteln

    *----


    *

    CALL FUNCTION 'ROUND'

    EXPORTING

    decimals = 1

    input = l_total

    sign = i_round_sign

    IMPORTING

    output = l_total_rounded

    EXCEPTIONS

    input_invalid = 1

    overflow = 2

    type_invalid = 3

    OTHERS = 4.

    IF sy-subrc <> 0.

    • Syst Protokollieren

    mo_log->add(

    i_protlvl = zcl_log=>mc_protlvl_important

    i_syst = abap_true ).

    zcx_general_exception=>raise_system_exception( ).

    ENDIF.

    • Fehler ermitteln

    l_total_error = l_total_rounded - l_total_rounded_values.

    *----


    *

    *=====================================================================

    • Wir machen uns nur die Mühe, wenn wir einen Fehler haben

    *----


    *

    IF l_total_error = 0.

    RETURN.

    ENDIF.

    *----


    *

    =====================================================================

    • Schrittweite abhängig von Dezimalstellen einstellen. Wenn wir einen

    • positiven Fehler haben, ist der Schritt negativ und vice versa.

    *----


    *

    l_step = SIGN( l_total_error ) * ( 1 / ( 10 ** i_decimals ) ).

    *----


    *

    =====================================================================

    • Zu rundende Werte absteigend sortieren, damit der prozentuelle

    • Fehler möglichst klein bleibt.

    *----


    *

    lt_rounded_compensated = lt_rounded.

    SORT lt_rounded_compensated DESCENDING

    BY value.

    *----


    *

    =====================================================================

    • Solange wir noch einen Fehler haben, schrittweise (Schrittweite s.o)

    • den Positionen die Schrittweite zuschlagen (negativer Gesamtfehler)

    • oder abziehen (positiver Gesamtfehler)

    *----


    *

    LOOP AT lt_rounded_compensated ASSIGNING .

    • Abbrechen, wenn wir den Fehler kompensiert haben

    IF ABS( l_total_error ) <= 0.

    EXIT.

    ENDIF.

    • Fehler kompensieren Addition (kann negativ sein) der Schrittweite

    -value

    + l_step.

    • Betrag des Gesamtfehlers verringern

    l_total_error = l_total_error - l_step.

    ENDLOOP.

    *----


    *

    =====================================================================

    • Gerundete Werte wieder in ursprüngliche Sortierung bringen

    *----


    *

    SORT lt_rounded_compensated

    BY index.

    *----


    *

    =====================================================================

    • Ausgabetabelle füllen

    *----


    *

    LOOP AT lt_rounded_compensated ASSIGNING -value.

    APPEND l_value_rounded TO lt_value_rounded.

    ENDLOOP.

    *----


    *

    =====================================================================

    • Exportparameter füllen

    *----


    *

    ct_value = lt_value_rounded.

    *----


    *

    ENDMETHOD.</code></pre>

    Edited by: Jens Schwendemann on Sep 16, 2011 10:53 PM

    Add comment
    10|10000 characters needed characters exceeded