on 09-14-2011 5:06 PM
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
User | Count |
---|---|
15 | |
4 | |
2 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.