cancel
Showing results for 
Search instead for 
Did you mean: 

UDF Help Needed: Format Number based on Condition

former_member184789
Active Contributor
0 Kudos

Hi,

I have the following requirement. I have one field whose value denotes currency type such as USD etc. The second field contains the currency amount. For currency types JPN,RSY & TPD (3 in total) I want the second field containing currency amount to be rounded off to the higher integer say if field 1 is JPN,RSY or TPD,then round it off to higher integer i.e if currency amount is 456.43 round it off to 457. For other currency types which are not equal to JPN,RSY or TPD, I want the currency amount to be rounded off to two decimal places such as 4587.564 to 4587.56 etc. I cannot use the standard mapping functions for some reason. Both the input fields are type String. In target structure,we have a RFC,in which the currency type is string and currency amount is decimal. In source structure, I have a 0:unbounded structure containing these fields currency type & currency amount. As the source record gets replicated multiple times and only some of these records contain these three currency types(JPN,RSY & TPD), will I need a single value UDF or one for all values of context/queue? Please suggest & help.

Accepted Solutions (0)

Answers (1)

Answers (1)

former_member189387
Active Contributor
0 Kudos

Hi ,

You can go for single value UDF with simple string to Float/int conversion java code .

For each occurrence structure this  UDF will be executed .

Sample code

int number = Integer.parseInt(LineNum);

// if Line number is 0 then return 1000

if  ( number == 0 )

     {

         return   Integer.toString(1000);

      }

// if Line number other than 0 then add one then  return multiples of 1000

else

     {

                                                                 return Integer.toString(( (number+1) * 1000) );

    }

Else try with java mapping .

former_member184789
Active Contributor
0 Kudos

I couldn't get it.Please note that it is possible that the currency may not contain a decimal place at all even for these currencies. Apart from this we may also have a 0 value. In such cases only 0 will be passed.

former_member189387
Active Contributor
0 Kudos

          float n= Float.parseFloat("4587.564");

      

       For other currency types which are not equal to JPN,RSY or TPD,

    f = (float) (Math.round(n*100.0f)/100.0f);

    * Output  4587.56

     If  is JPN,RSY or TPD,then round it off to higher integer

       

        int i = (int) f; // i has value 456

Hope this clarifies .

former_member184789
Active Contributor
0 Kudos

Now I am using this code:

if (var1.equals("JPN") || var1.equals("RSY") || var1.equals("TPD"))

{

BigDecimal bd  = new BigDecimal(var2).setScale(0, BigDecimal.ROUND_HALF_UP);

return bd.toString();

}

else {

BigDecimal bd  = new BigDecimal(var2).setScale(2, BigDecimal.ROUND_HALF_UP);

return bd.toString(); }

This code works exactly as desired for other currency types and rounds off to two decimal places. For the three currency types in which decimal places are not allowed,it removes the decimal places but doesn't round it off to higher integer. Say if currency type is JPN,RSY or TPD and currency amount is 345.24, it will pass 345, while my requirement is that if there is any decimal for these currency types, it should round it to higher integer.And if there is no decimal for these currency types, it should be passed as it is. Please help me out.

former_member189387
Active Contributor
0 Kudos

HI ,

while my requirement is that if there is any decimal for these currency types, it should round it to higher integer

if the value is more than half way towards ,   Then Java Rounds to the nearest integer. So, if the value is more than half way towards the higher integer, the value is rounded up to the next integer.

Hence as per your code it will return 345 only .

But , if you use the following code it might solve your issue

        double f1=345.24;

        float f2= (float)Math.ceil(f1);

        int tst=(int)f2;

        System.out.println(tst);

result : 346

Try this ...

anupam_ghosh2
Active Contributor
0 Kudos

Hi Adarsh,

                       Try this UDF. This seems to work as per your requirements.

public String formatNumber(String var1,String var2,Container container)

{

  String s="";

  try

  {

  

   if((var1.equals("JPN") || var1.equals("RSY") || var1.equals("TPD")))

   {

          java.math.BigDecimal bd  = new java.math.BigDecimal(var2).setScale(0, java.math.BigDecimal.ROUND_CEILING);

          s=bd.toString();

   }

   else

   {

    java.math.BigDecimal bd  = new java.math.BigDecimal(var2).setScale(2, java.math.BigDecimal.ROUND_HALF_UP);

    s=bd.toString();

   }

  }

  catch(Exception e)

  {

   e.printStackTrace();

  }

  return s;

}

Output and input samples

currency=JPN,input=4587.01,output=4588

currency=RSY,input=4587.456,output=4588

currency=TPD,input=4587.00,output=4587

currency=USD,input=4587.7895,output=4587.79

currency=USD,input=4587.345,output=4587.35

currency=USD,input=4587.01,output=4587.01

Regards

Anupam

Former Member
0 Kudos

Hi Anupam,

The above UDF is for single value, I want to use it for all values of queue. Can it be possible.

Waiting for your support and quick response.

Thanks in advance.

Best Regards,

Sagarika Mishra

Former Member
0 Kudos

You need to change context for Val1 and Val2 accordingly, just check by display queue feature in mapping.

- - - Divyesh vasani

anupam_ghosh2
Active Contributor
0 Kudos

Hi Sagarika,

                      Yes its possible. There will be minor changes in the above UDF. Change the type of UDF to type context. var1 and var2 will be inputs to the UDF as array of strings. Use a remove context and set it to root of source xml for var1 and var2 before giving input to the UDF.

public void formatNumber(String var1[],String var2[],ResultList result,Container container) 

  String s=""; 

  try 

  { 

   int i;

   for(i=0;i<var1.length;++i)

   { 

             if((var1[i].equals("JPN") || var1[i].equals("RSY") || var1[i].equals("TPD"))) 

             { 

                    java.math.BigDecimal bd  = new java.math.BigDecimal(var2[i]).setScale(0, java.math.BigDecimal.ROUND_CEILING); 

                    s=bd.toString(); 

             } 

             else 

             { 

                        java.math.BigDecimal bd  = new java.math.BigDecimal(var2[i]).setScale(2, java.math.BigDecimal.ROUND_HALF_UP); 

                        s=bd.toString(); 

             }  

             result.addValue(s); 

  } 

  catch(Exception e) 

  { 

   e.printStackTrace(); 

  } 

Regards

Anupam