Want to dynamically place decimal point in given 18 digit string(representing amount) - mule

I have two variables i.e. amount(18 char) and precision(2 digits). I want to put the decimal point in amount based on precision value.
Lets say amount= 100000000000000000 and precision=2, then using dwl I want to convert amount as 1000000000000000.00
Please note I don't want to use global function due to performance issue.
I tried it using amount/100. this gave me exponential 1.0E15.
dwl-
{
amount :100000000000000000 as :string /100
}
Expected output is { amount : 1000000000000000.00 }

Please refer to the following documentation on MuleSoft:
https://support.mulesoft.com/s/article/How-to-format-numbers-in-DataWeave
https://blogs.mulesoft.com/dev/training-talks/how-to-format-numbers-in-dataweave/
%dw 1.0
%output application/json
---
{
amount :100000000000000000 as :string {format: "#.00"}
}
yields:
{"amount": "100000000000000000.00"}

I used below implementation and now this gives me exactly what I want. I just need to divide the number by 10(or 100 or 1000 etc based on precision value) before formatting output.
%dw 1.0
%output application/json
---
{
"amt" : "100123456789123456789" /"1000" as :string {format: "#"}
}
output received:
{ "amt": 100123456789123456.789
}

Related

Reverse ordering in Mule4 using Date field

I wanted to do reverse ordering using Date field from highest to lowest (DSC). This question is similar to the below link Reverse ordering in Mule4. Thought small tweaks would make the fix. Tried various ways.Not working. When I try to format date it says the key cant be formatted to date or it complains about -. Any thoughts? Thanks
%dw 2.0
output application/json
var test = { "2022-10-19":[{"kio":"spotage"}] ,
"2022-10-17": [{"kio":"spotage"}] ,
"2022-10-18": [{"kio":"spotage"}]
}
---
test orderBy -($$ as String as Date {format: "yyyy-MM-dd"}
)
Expected Response:
{
"2022-10-19": [
{
"kio": "spotage"
}
],
"2022-10-18": [
{
"kio": "spotage"
}
],
"2022-10-17": [
{
"kio": "spotage"
}
]
}
The orderBy() function seems to be expecting a number to be able to do reverse sorting. A Date can not be converted directly to a number in DataWeave. However the date format 'yyyyMMdd' can be converted to a number that can directly sorted.
Example:
%dw 2.0
output application/json
var test = {
"2022-10-18":[{"kio":"spotage"}],
"2022-10-17": [{"kio":"spotage"}],
"2022-10-19": [{"kio":"spotage"}]
}
---
test orderBy -($$ as String as Date {format: "yyyy-MM-dd"} as String {format: "yyyyMMdd"} as Number)
I modified the input to show that the script actually orders the output.

date operations in mule esb using data weave

I have requirement like where need to find difference in between two dates using dataweave, Both input and output is XML format.
both the date formats are yyyy.mm.dd and output date format must be like mm.dd.yy or mm.dd.yyyy.
Please assist me, thanks
You can format dates like this (example):
yourInputDate as :localdatetime {format: "yyyy-MM-dd'T'HH:mm:ss"})
you can add and subtract dates, another example how i use this in a project with variables:
%var stamp = (now as :localdatetime {format: "yyyy-MM-dd'T'HH:mm:ss"})
%var dayDiff = ("P" ++ (stamp.dayOfWeek - 1) ++ "D") as :period
%var firstDateWeek = (stamp - dayDiff) as :localdatetime {format: "yyyy-MM-dd"}
docs here: https://docs.mulesoft.com/mule-user-guide/v/3.8/dataweave-types#datetime
In Dataweave, you can convert a string to date format and then just subtract them
Input
<dates>
<startDate>2007.05.01</startDate>
<endDate>2017.02.15</endDate>
</dates>
Transform
%dw 1.0
%var startDate = payload.dates.startDate as :date {format: "yyyy.MM.dd"}
%var endDate = payload.dates.endDate as :date {format: "yyyy.MM.dd"}
%output application/json
---
{
difference: startDate - endDate
}
Output
{
"difference": "P9Y9M14D"
}
9 years, 9 months, 14 days
You can create a global function with Java/Groovy and use DateTime object to find the difference and return from that function. Now you can use that function inside your dataweave.
Subtracting two Dates in dataweave. Format the date according to your requirement
%dw 1.0
%output application/json
---
{
a: |23:59:56-03:00| - |22:59:56-00:00|,
b: |2003-10-01| - |2002-09-23|
}
{
"a": "PT-4H",
"b": "P-1Y-8D"
}

Mule dataweave: convert decimal to an integer

I want to convert a decimal (78.22) to an integer (78) using Dataweave.
<root>
<MoneyAmountRequired>78.22</MoneyAmountRequired>
</root>
I try as below and it doesn't work if I add default 0
moneyAmountRequired: payload.root.MoneyAmountRequired as :number{format: "0"} default 0
Can some one please point out why it doesn't work when default 0 is present.
Thank you!
Use floor function of dataweave.
{
root: {
MoneyAmountRequired: floor payload.root.MoneyAmountRequired
}
}
You can try the following :-
moneyAmountRequired: payload.root.MoneyAmountRequired as :string {format: "0"}as :number default 0
Here you need to convert it first in String as :string then in number as :number
This is the only way it seems to work !!
ref:- Mule Dataweave format :number
Try myvalue: removeDecimal(28.23)
This works for me.
moneyAmountRequired: payload.root.MoneyAmountRequired as :number {format: "##,##"} as :string {format: "##"} as :number
Hope this helps.
Check this:
%dw 1.0
%output application/java
%var regex = /(.\d+?)0+\b/
data replace regex with ""
After the number is formatted, it is indeed a string, but you are defaulting it to a number 0 instead of defaulting it to a string "0". But that would be enough if 'as :number' did not failed when the variable is null, which is in the first place the reason you need the default. Therefore, default it before converting it to a number as follows:
moneyAmountRequired: (payload.root.MoneyAmountRequired default "0") as :number{format: "0"}
Hope this will answer your question about the default 0 not working.
((payload.root.MoneyAmountRequired as :string) splitBy '.')[0] as :number
If you prefer to use a function, then:
%function truncateDecimals(d) ((d as :string) splitBy '.')[0] as :number when d != null otherwise d
---
{value: truncateDecimals(payload.root.MoneyAmountRequired)}
Use this for
%dw 1.0
%output application/json
{
value : moneyAmountRequired: floor payload.root.MoneyAmountRequired as :number default 0
}

Mule Dataweave format :number

I'm having an issue trying to parse a string to double this would be a sample code, it's returning an integer instead of type :double any ideas?
{
"data": "22" as :number { format: "##.##" }
}
This, and only this, works for me;
%dw 1.0
%output application/json
---
{
data: "22" as :number as :string {format: ".00"} as :number
}
format only seems to add zeros when converting from a number to a string.
If "22" would have already been a number you wouldn't need the first :number conversion;
data: 22 as :string {format: ".00"} as :number
The latter number conversion makes it output as a float. Otherwise you would get a string, formatted according to the hosts locale.
And beware. When using%output text/json instead, the above code will in some cases produces 22.0 instead of 22.00.
I think thats more for formatting strings. Try this for decimal points:
{
"data": "22" as :number {format: ".00"}
}
I'm using:
%output application/json
%type currency = :string { format: "###,##0.00"}
%function toLocalCurrency (currency) currency replace "." with "#" replace "," with "." replace "#" with ","
---
{
usCurrencyWithOneDecimal: 900000.1 as :currency,
brCurrency: toLocalCurrency(900000.1 as :currency),
usCurrencyWithTwoDecimal: 900000.12 as :currency,
usCurrencyWithThreeDecimal: 900000.124 as :currency,
usCurrencyWithThreeDecimalRounding: 900000.125 as :currency,
usCurrencyZero: 0 as :currency
}
The output is:
{
"usCurrencyWithOneDecimal": "900,000.10",
"brCurrency": "900.000,10",
"usCurrencyWithTwoDecimal": "900,000.12",
"usCurrencyWithThreeDecimal": "900,000.12",
"usCurrencyWithThreeDecimalRounding": "900,000.12",
"usCurrencyZero": "0.00"
}

DateWeaver date field conversion not working - Mule

In DataWeaver documentation 10.8. Changing the Format of a Date https://developer.mulesoft.com/docs/dataweave#_date_time_operations
Below is the transform
%dw 1.0
%output application/json
%type mydate = :string { format: "YYYY/MM/dd" }
---
{
formatedDate1: |2003-10-01T23:57:59| as :mydate,
formatedDate2: |2015-07-06T08:53:15| as :mydate
}
In the dataweaver preview it is looking fine as expected response ( Changed the date format).
I'm taking response in file component, But it is not converting the date in the format mentioned( Also kept logger right after the dataWeaver, not an expected response).
Response getting as below
{
"formatedDate1": "2003-10-01T23:57:59",
"formatedDate2": "2015-07-06T08:53:15"
}
I have other query, here we are hardCoding the date inside the weaver. If suppose we are taking the date field from Input parameter does we need to wrap the field inside ||. Example as below, will it work
%dw 1.0
%output application/json
%type mydate = :string { format: "YYYY/MM/dd" }
---
{
formatedDate1: |payload.dateField1| as :mydate,
formatedDate2: payload.dateField1 as :mydate
}
The above seems not to work for me. Please let me know the correct usage.
Thanks in advance
Try this:
%dw 1.0
%output application/json
%type mydate = :date { format: "yyyy/M/d" }
---
{
formatedDate1: |2003-10-01T23:57:59| as :mydate,
formatedDate2: |2015-07-06T08:53:15| as :mydate
}
Output:
{
"formatedDate1": "2003-10-01",
"formatedDate2": "2015-07-06"
}
The difference is the datatype from :string to :date::
%type mydate = **:date** { format: "yyyy/M/d" }
It seems the result doesn't change to /. This is probably a bug.
%dw 1.0
%output application/json
%type mydate = :string { format: "YYYY/M/d" }
---
{
formatedDate1: |2003-10-01T23:57:59| as :mydate,
formatedDate2: |2015-07-06T08:53:15| as :mydate
}
Try this