3 weeks ago - last edited 3 weeks ago
Hi Experts,
I am new to groovy and learning basics. But got little complex requirement which I tried but couldn't get the desired requirement. So asking your help to achieve my requirement. Please help me to achieve below requirment.
I need to read xml message and from that take value of /User/User/CustomField_BookingHours which is currently -2 and sort all /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingDate, oldest date should the top one then take value of first /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount and add both like 0.5 + (-2) then the balance is -1.5 and then take 2nd /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount which is 0.5 and add reslted balance which is -1.5, so the result is 0.5 + (-1.5) now new balance is -1.0 and then take 2nd /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount whoch is 3.0 and add reslted balance which is -1.0, so the result is 3.0 + (-1.0) now new balance is 2.0 which is greater than or eauql to 0, add the new node after 3rd TimeAccountDetail node, after which balanc value becomes >= 0, with field /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount value of /User/User/CustomField_BookingHours.
Excepting adding this new node, remaining payload should be as-is. Only add new node with /User/User/CustomField_BookingHours where ever it becomes >= 0 after adding to each /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount.
Sample payload
<User>
<User>
<CustomField_BookingHours>-2</CustomField_BookingHours>
<bookingDate>2023-11-11T00:00:00.000</bookingDate>
<TimeAccount>
<timeAccountDetails>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-01-14T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-04-02T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>3.0</bookingAmount>
<bookingDate>2023-02-27T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>1.0</bookingAmount>
<bookingDate>2024-04-03T00:00:00.000</bookingDate>
</TimeAccountDetail>
</timeAccountDetails>
</TimeAccount>
</User>
</User>
The output should be
<User>
<User>
<CustomField_BookingHours>-2</CustomField_BookingHours>
<bookingDate>2023-11-11T00:00:00.000</bookingDate>
<TimeAccount>
<timeAccountDetails>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-01-14T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-04-02T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>3.0</bookingAmount>
<bookingDate>2023-02-27T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>-2</bookingAmount>
<bookingDate>2023-11-11T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>1.0</bookingAmount>
<bookingDate>2024-04-03T00:00:00.000</bookingDate>
</TimeAccountDetail>
</timeAccountDetails>
</TimeAccount>
</User>
</User>
Hi,
Got it, script was slightly modified to handle the dataType as in "Double" integer and here is the updated script. Give it a try now.
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
//getting the input body
def body = message.getBody(java.lang.String) as String;
//prasing the input XML body
def xml = new XmlParser().parseText(body)
//running each User node
xml.User.each{
recs ->
timeAccount = recs.TimeAccount.timeAccountDetails.TimeAccountDetail
//sort the timeaccount records based on the order of old to new date
timeAccount.sort {
a, b ->
Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSS", a.bookingDate.text()) <=> Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSS", b.bookingDate.text())
}
boolean customAddHour_Flag = false
//get CustomField_BookingHours
def rootHour = recs.CustomField_BookingHours.text().toDouble()
//replace the Timeaccountdetail segment with the updated logic
recs.TimeAccount.timeAccountDetails.replaceNode{
timeAccountDetails{
timeAccount.each{
timeRecs ->
//copy the /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail
TimeAccountDetail{
bookingAmount(timeRecs.bookingAmount.text())
bookingDate(timeRecs.bookingDate.text())
}
//get timeAccount - BookingAmount
def bAmount = timeRecs.bookingAmount.text().toDouble()
//add the hours
rootHour = rootHour + bAmount
//when hour is greater than or eauql to 0, add the new node after the TimeAccountDetail node
if(rootHour >= 0 && !customAddHour_Flag){
customAddHour_Flag = true
TimeAccountDetail{
bookingAmount(recs.CustomField_BookingHours.text())
bookingDate(recs.bookingDate.text())
}
}
}
}
}
}
//setting the output body
message.setBody(groovy.xml.XmlUtil.serialize(xml))
return message;
}
GroovyIDE link for reference:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @naveen4796 ,
Thank for the quick groovy. Current groovy logic considering adding node where ever the CustomField_BookingHours becomes zero with single TimeAccountDetail/bookingAmount. My requirement is to minus(actually plus we need to use as we are getting - sign in the for the value)) the CustomField_BookingHours from each TimeAccountDetail/bookingAmount and with the balance hours, I need to minus from next TimeAccountDetail/bookingAmount and with the balance, I need to minus next TimeAccountDetail/bookingAmount. LIke this loop, where ever the value becomes >= 0, after that we need to add the node.
<User>
<User>
<CustomField_BookingHours>-0.75</CustomField_BookingHours>
<bookingDate>2023-11-11T00:00:00.000</bookingDate>
<TimeAccount>
<timeAccountDetails>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-01-14T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-04-02T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>3.0</bookingAmount>
<bookingDate>2023-02-27T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>1.0</bookingAmount>
<bookingDate>2024-04-03T00:00:00.000</bookingDate>
</TimeAccountDetail>
</timeAccountDetails>
</TimeAccount>
</User>
</User>
in SAP CPI, I need to read xml message and from that take value of /User/User/CustomField_BookingHours which is currently -0.75 and then take value of first /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount and add both like 0.5 + (-0.75) then the balance is -0.25 and then take 2nd /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount whoch is 0.5 and add reslted balance which is -0.25, so the result is 0.5 + (-0.25) now new balance is 0.25 which is greater than or eauql to 0, add the new node after 2rd TimeAccountDetail node, after which balanc value becomes >= 0, with field /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail/bookingAmount value of /User/User/CustomField_BookingHours. So the output should be like below
<User>
<User>
<CustomField_BookingHours>-0.75</CustomField_BookingHours>
<bookingDate>2023-11-11T00:00:00.000</bookingDate>
<TimeAccount>
<timeAccountDetails>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-01-14T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>0.5</bookingAmount>
<bookingDate>2022-04-02T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>-0.75</bookingAmount>
<bookingDate>2023-11-11T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>3.0</bookingAmount>
<bookingDate>2023-02-27T00:00:00.000</bookingDate>
</TimeAccountDetail>
<TimeAccountDetail>
<bookingAmount>1.0</bookingAmount>
<bookingDate>2024-04-03T00:00:00.000</bookingDate>
</TimeAccountDetail>
</timeAccountDetails>
</TimeAccount>
</User>
</User>
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
The following groovy should fulfill your requirement, kindly give it a try.
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
//getting the input body
def body = message.getBody(java.lang.String) as String;
//prasing the input XML body
def xml = new XmlParser().parseText(body)
//running each User node
xml.User.each{
recs ->
timeAccount = recs.TimeAccount.timeAccountDetails.TimeAccountDetail
//sort the timeaccount records based on the order of old to new date
timeAccount.sort {
a, b ->
Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSS", a.bookingDate.text()) <=> Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSS", b.bookingDate.text())
}
//replace the Timeaccountdetail segment with the updated logic
recs.TimeAccount.timeAccountDetails.replaceNode{
timeAccountDetails{
timeAccount.each{
timeRecs ->
//copy the /User/User/TimeAccount/timeAccountDetails/TimeAccountDetail
TimeAccountDetail{
bookingAmount(timeRecs.bookingAmount.text())
bookingDate(timeRecs.bookingDate.text())
}
//get CustomField_BookingHours
def rootHour = recs.CustomField_BookingHours.text().toFloat()
//get timeAccount - BookingAmount
def bAmount = timeRecs.bookingAmount.text().toFloat()
//add the hours
def hourAdd = rootHour + bAmount
//when hour is greater than or eauql to 0, add the new node after the TimeAccountDetail node
if(hourAdd >= 0){
TimeAccountDetail{
bookingAmount(recs.CustomField_BookingHours.text())
bookingDate(recs.bookingDate.text())
}
}
}
}
}
}
//setting the output body
message.setBody(groovy.xml.XmlUtil.serialize(xml))
return message;
}
Adding GroovyIDE Online simulator link for your reference:
GroovyIDE Link - execute code
Regards,
Naveen
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
74 | |
10 | |
8 | |
7 | |
6 | |
5 | |
5 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.