UKG Dimensions Number of employees in request (624) exceeds allowed limit (500) - dimensions

This error occurs when you are requesting aggregated data using the URL:
POST - {{DIMENSIONSHOST}}/v1/commons/data/multi_read
The Postman body that I used was:
{
"select": [
{"key": "EMP_COMMON_FULL_NAME"}
],
"from": {
"view": "EMP",
"employeeSet": {
"hyperfind": {
"id": -9
},
"dateRange": {
"startDate": "2022-01-01",
"endDate": "2022-04-30"
}
}
},
"index": 0,
"count": 500
}
Notice that I requested "count": 500. Even though I requested only 500 records, I got the error message that there were more than 500 records.

This identifies a bug in UKG Dimensions. I have developed a work around:
Retrieve the hyperfind by itself using /v1/commons/hyperfind/execute
Use a Postman Test (a post-response program) to split the IDs into batches of 500.
Save the batches to an environment variable
Use the environment variable for the aggregated data request.
You can retrieve the hyperfind by itself using:
POST - {{DIMENSIONSHOST}}/v1/commons/hyperfind/execute
The body of the request is:
{
"dateRange": {
"startDate": "2022-05-01",
"endDate": "2022-06-30"
},
"hyperfind": {
"id": -9
},
"includeTerminatedInRangeForLocations": true
}
The test script is:
var jsonData = JSON.parse(responseBody); //the data from the response body
var allIDs = []; //an array of all the IDs, no record count limit
var max500IDs = []; //arrays of maximum number of IDs
//
//retrieve all the IDs and put them into an array called allIDs
//
for(var i = 0; i < jsonData.result.refs.length; i++) {
allIDs.push(jsonData.result.refs[i].id );
}
var batchCount = 1; //number of batches - default 1
var IDsInBatch = 500; //maximum number of records in batch
//
//calculate the number of batches that you will need
//
if(allIDs.length > IDsInBatch) {
batchCount = Math.ceil((allIDs.length - 1) / IDsInBatch);
}
//
//loop through the number of batches
//
var eeCountInOtherBatches = 0;
for(var k = 0; k < batchCount; k++) {
//
//loop through all the IDs and transfer them to a max 500 batch
//
var batch = []
for(var j = 0; j < IDsInBatch; j++) {
personID = allIDs[eeCountInOtherBatches + j];
if(personID) {
batch.push(personID);
}
}
max500IDs[k] = batch;
eeCountInOtherBatches = eeCountInOtherBatches + IDsInBatch;
}
//
//transfer the batches to environment variable(s)
//
for(var x = 0; x < max500IDs.length; x++) {
postman.setEnvironmentVariable("max500IDs_" + x, max500IDs[x]);
}
The environment variables will be:
max500IDs_0
max500IDs_1
etc.
The employee request would be something like:
POST - {{DIMENSIONSHOST}}/v1/commons/data/multi_read
The body would be:
{
"select": [
{"key": "EMP_COMMON_FULL_NAME"}
],
"from": {
"view": "EMP",
"employeeSet": {
"employees": {
"ids": [{{max500IDs_0}}]
},
"dateRange": {
"startDate": "2022-01-01",
"endDate": "2022-04-30"
}
}
},
"index": 0,
"count": 500
}

Related

Mongo db query | Join | Create query on two collection

Select leadId count on two collection in Mongo DB
Collection 1 : leads
{
leadId:"abc123",
status:"OPENED",
stage:"start",
crossSell:
{
cc:
{
consent:true,
shown:[{first:true}]
}
}
}
Collection 2 : pdata
{
activeLeadId:"abc123",
status:"OPENED",
details:
[
{
rating:10
},
{
rating:9
}
]
}
Question : Find leadId count from leads collection join with pdata collection based on below conditions
leads.leadId = pdata.activeleadId and
leads.status = "OPENED" and
leads.crossSell.cc.consent = true and
leads.crossSell.cc.shown[0].first = true and
pdata.details.rating >= 5
You can try a aggregation query,
$match your conditions for leads collection
$lookup with pdata collection, pass leadId to match with pdata
match required conditions for pdata
$limit to return single document, because we don't need that data in response
$match condition to check is pdata is not empty
$count to get total number of records
db.leads.aggregate([
{
$match: {
status: "OPENED",
"crossSell.cc.consent": true,
"crossSell.cc.shown.first": true
}
},
{
"$lookup": {
"from": "pdata",
"let": { "leadId": "$leadId" },
"pipeline": [
{
$match: {
$expr: { $eq: ["$$leadId", "$activeLeadId"] },
"details.rating": { $gte: 5 }
}
},
{ $limit: 1 }
],
"as": "pdata"
}
},
{ $match: { pdata: { $ne: [] } } },
{ $count: "count" }
])
Playground

Karate - filter a specific json key from response based on another static array

I have the following JSON response (reference name: "list") and
[
{
"key": "101",
"val": {
"portCall": {
"id": 12664978
},
"status": "in-port"
}
},
{
"key": "102",
"val": {
"portCall": {
"id": 12415798
},
"status": "in-port"
}
},
{
"key": "103",
"val": {
"status": "on-voyage",
"voyage": {
"id": "7kynv-7lq85"
}
}
},
{
"key": "104",
"val": {
"status": "on-voyage",
"voyage": {
"id": "7kynv-2385"
}
}
}
]
also, I have an array list of few key values, evImos = [101,102,104]
In that, I have to identify the first key in the "list" response that has status as "on-voyage". So, the result should be "104".
I have tried the following and I need some help to make it work. Any help would be appreciated.
* def function getFirst = function(evImos) { for (let num of evImos) { let results = list.filter(d => d["key"] === num && d["val"]["status"] === "on-voyage"); if(results.length === 1) { karate.log(num); return num; } } }
* list.forEach(getFirst(evImos))
I'll just give you one hint. This one line will convert the whole thing in to a form that is much easier for you to validate:
* def temp = {}
* list.forEach(x => temp[x.key] = x.val.status)
Which gives you:
{
"101": "in-port",
"102": "in-port",
"103": "on-voyage",
"104": "on-voyage"
}
Now you can do:
* def isOnVoyage = function(key){ return temp[key] == 'on-voyage' }
Also read this: https://stackoverflow.com/a/59162760/143475
Thanks, to #Peter.
Based on his hint, I just tweaked it a little bit to match my requirement and it worked for me.
Here is the working copy for anyone to refer in the future.
* def temp = {}
* list.forEach(x => temp[x.key] = x.val.status)
* def isOnVoyage = function(keys){ for (let key of keys) { if(temp[key] == 'on-voyage'){ karate.log(key); karate.set('num', key); break; }}}
* isOnVoyage(evImos)

Need to retrieve the json key value as null if key not present at the node

{
"a": {
"b": 1,
"c": 0
},
"values": [
{
"d": "WERTY",
"e": "details",
"f": [
{
"addressId": "vvvv",
"address": "ffff"
}
]
},
{
"d": "ZXCVB",
"e": "details"
},
{
"d": "ASDFG",
"e": "details",
"f": [
{
"addressId": "vvvv",
"address": "xxxx"
}
]
}
]
}
After getting the response from restassured, I am trying to fetch the values of a particular key with JsonPath.
I am using:
responseBody.jsonPath().getList("values.f.address)
This is returning me a list - ["ffff","xxxx"]
I want to get - ["ffff",null,"xxxx"]
Is it possible to achieve this with Karate?
JsonPath = values[0].f[0].address
If you are using validatableResonse then you can use:
String res_str = Response.extract().jsonPath().getString("values[0].f[0].address");
The response should be of ValidatableResponse type.
It won't return you null for that absent item, because field address is actually not present in the response body.
You can do it checking whether the f key is available in each object of values array;
If it is available -> add the value of address in each object in f array, to a String list
If it is not available -> add null to the same String list.
I create a org.json.JSONObject from io.restassured.response.Response.
Response response = given()
.when()
.get(url)
.then()
.extract()
.response();
List<String> addressList = new ArrayList<>();
JSONObject responseObject = new org.json.JSONObject(response.body().asString());
JSONArray jsonArray = responseObject.getJSONArray("values");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
if (jsonObject.keySet().contains("f")) {
JSONArray fObjectArray = jsonObject.getJSONArray("f");
for (int j = 0; j < fObjectArray.length(); j++) {
addressList.add(fObjectArray.getJSONObject(j).get("address").toString());
}
} else {
addressList.add(null);
}
}
System.out.println(addressList.toString());
This will print the following result;
[ffff, null, xxxx]

Getting the maximum value from an array in a JSON response in Karate

I have the following Json as a response from a API call
{
"location": {
"name": "London",
"region": "City of London, Greater London",
"country": "United Kingdom",
"lat": 51.52,
"lon": -0.11,
"tz_id": "Europe/London",
"localtime_epoch": 1583594426,
"localtime": "2020-03-07 15:20"
},
"forecast": {
"forecastday": [
{
"date": "2020-03-03",
"day": {
"maxtemp_c": 9,
"mintemp_c": 4
}
},
{
"date": "2020-03-04",
"day": {
"maxtemp_c": 8,
"mintemp_c": 4.1
}
},
{
"date": "2020-03-05",
"day": {
"maxtemp_c": 7,
"mintemp_c": 5.6
}
}
]
}
}
I want to find out which date had the highest temperature amongst the 3 days.
The way I am currently doing feels inefficient as I am checking for the temperature element within my js function and it is as follows
* def hottest =
"""
function(array) {
var greatest;
var indexOfGreatest;
for (var i = 0; i < array.length; i++) {
if (!greatest || array[i].day.maxtemp_c > greatest) {
greatest = array[i].day.maxtemp_c;
indexOfGreatest = i;
}
}
return indexOfGreatest;
}
"""
* def index = call hottest response.forecast.forecastday
* def hottestdate = response.forecast.forecastday[index].date
* print hottestdate
With this I am getting the correct result but can someone kindly suggest a better way of doing this?
Best practice in Karate is to NOT use JS for loops at all. It results in cleaner, more readable code:
* def fun = function(x){ return { max: x.day.maxtemp_c, date: x.date } }
* def list = karate.map(response.forecast.forecastday, fun)
* def max = 0
* def index = 0
* def finder =
"""
function(x, i) {
var max = karate.get('max');
if (x.max > max) {
karate.set('max', x.max);
karate.set('index', i);
}
}
"""
* karate.forEach(list, finder)
* print 'found at index', index
* print 'item:', list[index]
Note how easy it is to re-shape a given JSON, the result of list here would be:
[
{
"max": 9,
"date": "2020-03-03"
},
{
"max": 8,
"date": "2020-03-04"
},
{
"max": 7,
"date": "2020-03-05"
}
]

How to use nested loops for fetching the data from a rest api in flutter?

I have a order screen where the placed orders and the items that are placed for each order is displayed. I have used a for loop to fetch the orders from the api but in the order json response it also has items parameter inside which there are multiple items. I am not able to figure out how to place another loop in the code to fetch the items list. So please help me with it...
Thank you..
my json response
[
{
"id": 1453,
"total": "407.00",
"line_items": [
{
"id": 34,
"name": "Aloo Chaat Salad",
"product_id": 931,
"quantity": 1,
"total": "90.00",
},
{
"id": 35,
"name": "Aloo Jeera",
"product_id": 1020,
"quantity": 1,
"total": "140.00",
},
{
"id": 36,
"name": "Banana Shake",
"product_id": 963,
"quantity": 1,
"tax_class": "",
"total": "140.00",
}
],
}
]
myModel.dart
class OrderListModel {
final int id;
final String total;
Map line_items = {};
OrderListModel(this.id, this.total, this.line_items);
}
my code for fetching the data
List<OrderListModel> myAllDatas = [];
Future getDatas() async {
String basicAuth = 'Basic ' +
base64.encode(
utf8.encode('${GlobalVar.consumerKey}:${GlobalVar.secretKey}'));
var response = await http
.get("${GlobalVar.url}wp-json/wc/v2/orders?customer=6", headers: {
'Authorization': basicAuth,
'Accept': 'application/json',
});
if (response.statusCode == 200) {
String responseBody = response.body;
var jsonBody = json.decode(responseBody);
for (var data in jsonBody) // loop for fetching the orders
{
myAllDatas.add(new OrderListModel(data['id'], data['total'],
data['line_items'])); // how to place a loop so that i can fetch the items
inside the line_items parameter too?
}
setState(() {});
} else {
print(response.statusCode);
print(response.body);
}
}
when I fetch the items of line_items i just want to fetch their names and seperate them by commas in a row.
Use for loop like this -
for (var data in body) {
List items = data["line_items"];
for (int i = 0; i < items.length; i++) {
int id = items[i]["id"];
String name = items[i]["name"];
}
}