ORDER condition not working in cakephp 3 TREE behavior - cakephp-3.0

I am using cakephp-3 tree behavior for Categories table. Here 'sequence_no' field are using to sorting sub-category list for a category. I am searching with a category_id to get all of his child category in ASCENDING order by 'sequence_no'. But order not working here. My code snippet and output here.
$categoris = $this->Categories->find('children', ['for' => $id])
->find('threaded')
->contain('ParentCategories')
->order(['Categories.sequence_no' => 'ASC'])
->toArray();
- OUTPUT SAMPLE:
{
"status": "OK",
"result": {
"data": [
{
"id": 15,
"store_id": 0,
"uuid": null,
"name": "cat-3",
"parent_id": 3,
"lft": 16,
"rght": 17,
"sequence_no": 2,
"url": "cat-3",
"layout_id": 0,
"status": 1,
"total": 0,
"created": "2018-06-12T07:36:15+00:00",
"modified": "2018-06-12T08:15:12+00:00",
"parent_category": {
"id": 3,
"store_id": 2,
"uuid": null,
"name": "Pants",
"parent_id": null,
"lft": 15,
"rght": 20,
"sequence_no": null,
"url": "pants",
"layout_id": 0,
"status": 1,
"total": 0,
"created": "2018-06-06T10:23:50+00:00",
"modified": "2018-06-06T10:23:50+00:00"
},
"children": []
},
{
"id": 16,
"store_id": 0,
"uuid": null,
"name": "cat-4",
"parent_id": 3,
"lft": 18,
"rght": 19,
"sequence_no": 1,
"url": "cat-4",
"layout_id": 0,
"status": 1,
"total": 0,
"created": "2018-06-12T07:36:34+00:00",
"modified": "2018-06-12T08:15:12+00:00",
"parent_category": {
"id": 3,
"store_id": 2,
"uuid": null,
"name": "Pants",
"parent_id": null,
"lft": 15,
"rght": 20,
"sequence_no": null,
"url": "pants",
"layout_id": 0,
"status": 1,
"total": 0,
"created": "2018-06-06T10:23:50+00:00",
"modified": "2018-06-06T10:23:50+00:00"
},
"children": []
}
]
}
}

Since findChildred finder add a ORDER lft asc clause to your query your order conditions will be appended to that
If you want to force your order you can do
->order(['Categories.sequence_no' => 'ASC'], true)
the second parameter in the order() method tells cake to overwrite the ORDER BY set before
see the manual, about the end of this paragraph

Related

Order list sorting according to the annual income only when both cgpa were same

I got a collection but I want to sort that collection. If the two application's cgpa is equal then sort the list collection according to the annual_salary where lower will up at list. Default the collection sort with the cgpa. below is my server response.
Thanks in advance
"applications": [
{
"id": 1,
"name": "Dr. W Khan",
"annual_salary": 5000,
"created_at": "2022-11-07T19:16:01.000000Z",
"updated_at": "2022-11-07T19:16:01.000000Z",
"education": [
{
"id": 1,
"application_id": 1,
"name": "HSC",
"cgpa": 400,
"created_at": "2022-11-07T19:16:01.000000Z",
"updated_at": "2022-11-07T19:16:01.000000Z"
}
]
},
{
"id": 2,
"name": "Dr. M Khan",
"annual_salary": 7000,
"created_at": "2022-11-07T19:16:14.000000Z",
"updated_at": "2022-11-07T19:16:14.000000Z",
"education": [
{
"id": 2,
"application_id": 2,
"name": "HSC",
"cgpa": 350,
"created_at": "2022-11-07T19:16:14.000000Z",
"updated_at": "2022-11-07T19:16:14.000000Z"
}
]
},
{
"id": 3,
"name": "Dr.",
"annual_salary": 5000,
"created_at": "2022-11-07T19:16:28.000000Z",
"updated_at": "2022-11-07T19:16:28.000000Z",
"education": [
{
"id": 3,
"application_id": 3,
"name": "HSC",
"cgpa": 350,
"created_at": "2022-11-07T19:16:28.000000Z",
"updated_at": "2022-11-07T19:16:28.000000Z"
}
]
}
]
This is the query for me.
$application = Application::with(
[
'education' => function ($query) {
$query->orderBy('cgpa', 'desc');
},
]
)
->orderBy('annual_salary', 'asc')
->get();
But ordering the list followed by a second orderBy.

Python 3 - Extracting value from key in nested dictionary

Hoping for some pointers here as I'm striking out with my attempts. Am working with python 3.8.5.
I'm querying a Car Park booking system that returns a json list of availability. The result has lots of nested dictionaries and I'm struggling to extract just the values i want.
This is what I've been doing:
import requests
import json
enquiry = requests.post(url.....) #queries api, this works fine
results = enquiry.text #extracts response data
dictionary = json.loads(results) #convert response to python dict
If there is one slot available, I get this output (apologies for length). If there are multiple slots available, i get the same output repeated:
{
"data": {
"services": [{
"id": null,
"name": null,
"services": [{
"id": null,
"name": "Car Park",
"met": true,
"filterCount": 1,
"primary": true,
"options": [{
"id": "9",
"images": [],
"available": true,
"calendarId": "AAAA",
"templateId": "BBBB",
"capacity": 0,
"name": "Car Park Slot 3",
"sessionId": "CCCC",
"functions": null,
"startDate": "2020-08-18T13:30:00Z", <--this is what I want to extract
"endDate": "2020-08-18T14:30:00Z",
"geo": {
"lat": 0.0,
"lng": 0.0
},
"selected": false,
"linkedServices": [],
"tiers": null
}]
}],
"currentBookingId": null,
"startDate": {
"ms": 1597757400000,
"year": 2020,
"month": 8,
"day": 18,
"dayOfWeek": 2,
"time": {
"seconds": 0,
"minutes": 30,
"hours": 14,
"days": 0
}
},
"endDate": {
"ms": 1597761000000,
"year": 2020,
"month": 8,
"day": 18,
"dayOfWeek": 2,
"time": {
"seconds": 0,
"minutes": 30,
"hours": 15,
"days": 0
}
},
"sessionId": "2222222",
"chargeType": 1,
"hasPrimaryBookable": false,
"hasBookable": false,
"hasDiscounts": false,
"hasMultipleTiers": false,
"isPreferred": false,
"primaryServiceAvailable": true,
"primaryServiceId": null,
"primaryServiceType": "undefined",
"unavailableAttendees": []
}],
"bookingLimit": null
},
"success": true,
"suppress": false,
"version": "2.3.293",
"message": null,
"result": null,
"errors": null,
"code": null,
"flags": 0,
"redirect": null
}
I want to extract:
"startDate": "2020-08-18T13:30:00Z"
from each key, value pair in any of the returned slots. However, I cant work it out.
Extracting the whole of this nested dictionary would also contain the same data, but would then involve more work to tidy it up after.
"startDate": {
"ms": 1597757400000,
"year": 2020,
"month": 8,
"day": 18,
"dayOfWeek": 2,
"time": {
"seconds": 0,
"minutes": 30,
"hours": 14,
"days": 0
}
I've tried loads of dictionary.get and dictionary.items variations, but cant seem to get anywhere.
I tried something like
key = ('startDate')
availability = dictionary.get(key)
print(availability)
this just returns 'none', so think im way off
Any pointers?
Thanks in advance!
Thanks for the full data. It makes testing easier :)
I had to replace null -> None, true -> True, false -> False
slot = {
"data": {
"services": [{
"id": None,
"name": None,
"services": [{
"id": None,
"name": "Car Park",
"met": True,
"filterCount": 1,
"primary": True,
"options": [{
"id": "9",
"images": [],
"available": True,
"calendarId": "AAAA",
"templateId": "BBBB",
"capacity": 0,
"name": "Car Park Slot 3",
"sessionId": "CCCC",
"functions": None,
"startDate": "2020-08-18T13:30:00Z", # <--this is what I want to extract
................
print("Start Date:", slot['data']['services'][0]['services'][0]['options'][0]['startDate'])
Output
Start Date: 2020-08-18T13:30:00Z

jmeter Json filter data based on condition

I am working on jmeter and trying to get values from a Json response.
I have below Json:
`{
"linked": {},
"learning_items": [
{
"id": "3452",
"enrollable_id": "3452",
"enrollable_type": "Enrollment",
"learnable_id": "6",
"learnable_type": "CourseTemplate",
"title": "all kinda ",
"description": "",
"state": "created",
"completed_at": null,
"created_at": "2017-04-10T16:26:36.850-06:00",
"archived_at": null,
"permanently_failed": false,
"data": {
"end_at": "2017-04-16T23:59:59.000-06:00",
"expires_at": null,
"renew_by": null,
"required": true,
"score": 0,
"time_remaining": 5,
"current_position": 0,
"furthest_progress": 0,
"quiz_positions": [
2,
3,
4,
5
],
"direct_enrollment": true,
"max_quiz_attempts": null,
"attempts_count": 0,
"inactive": null,
"program": null,
"programs": [],
"in_completed_program": false,
"external_id": null,
"estimated_time": 5,
"passing_threshold": 80,
"has_certificate": false,
"course_type": "bridge",
"slide_count": 5,
"attachments_count": 1,
"attachments_count_author": 2,
"third_party_course_id": null,
"open_book": true,
"continuing_education_credits": null,
"features": [
"has_quizzes"
]
},
"tags": []
},
{
"id": "3451",
"enrollable_id": "3451",
"enrollable_type": "Enrollment",
"learnable_id": "7",
"learnable_type": "CourseTemplate",
"title": "All types",
"description": "",
"state": "active",
"completed_at": null,
"created_at": "2017-04-10T16:26:36.605-06:00",
"archived_at": null,
"permanently_failed": false,
"data": {
"end_at": "2017-04-17T23:59:59.000-06:00",
"expires_at": null,
"renew_by": null,
"required": true,
"score": 0,
"time_remaining": 7,
"current_position": 1,
"furthest_progress": 0.1429,
"quiz_positions": [
2,
3,
4,
5,
6,
7
],
"direct_enrollment": true,
"max_quiz_attempts": null,
"attempts_count": 1,
"inactive": null,
"program": null,
"programs": [],
"in_completed_program": false,
"external_id": null,
"estimated_time": 7,
"passing_threshold": 80,
"has_certificate": false,
"course_type": "bridge",
"slide_count": 7,
"attachments_count": 0,
"attachments_count_author": 1,
"third_party_course_id": null,
"open_book": false,
"continuing_education_credits": null,
"features": [
"has_quizzes"
]
},
"tags": []
},
{
"id": "6301",
"enrollable_id": "1",
"enrollable_type": "ProgramEnrollment",
"learnable_id": "1",
"learnable_type": "Program",
"title": "IamaProgram",
"description": null,
"state": "active",
"completed_at": null,
"created_at": "2018-08-27T13:01:07.383-06:00",
"archived_at": null,
"permanently_failed": false,
"data": {
"required": true,
"current_course": {
"id": 19,
"title": "abcde",
"state": "created",
"end_at": "2018-09-03T23:59:59.999-06:00",
"expires_at": null,
"renew_by": null,
"required": true,
"score": 0,
"estimated_time": 2,
"time_remaining": 2,
"passing_threshold": 80,
"has_certificate": null,
"course_type": "bridge",
"slide_count": 2,
"attachments_count": 0,
"current_position": 0,
"furthest_progress": 0,
"learnable_type": "CourseTemplate"
},
"end_at": null,
"expires_at": null,
"furthest_progress": 0,
"inactive": null,
"item_count": 2,
"item_counts": [
{
"item_type": "CourseTemplate",
"count": 2
}
],
"program_index": 1,
"has_certificate": false,
"pending_approval_item_count": 0,
"pending_approval_items": [],
"features": [
"has_quizzes"
]
},
"tags": []
},
{
"id": "6300",
"enrollable_id": "1",
"enrollable_type": "TaskEnrollment",
"learnable_id": "1",
"learnable_type": "Task",
"title": "IamaCheckpoint",
"description": "",
"state": "created",
"completed_at": null,
"created_at": "2018-08-27T12:59:42.541-06:00",
"archived_at": null,
"permanently_failed": false,
"data": {
"requires_approval": false,
"requires_evidence": false,
"direct_enrollment": true,
"required": true,
"program": null,
"programs": [],
"in_completed_program": false,
"end_at": "2018-09-03T23:59:59.999-06:00",
"inactive": null,
"attachments_count": 0,
"attachments_count_author": 0,
"has_certificate": false
},
"tags": []
},
{
"id": "3450",
"enrollable_id": "3450",
"enrollable_type": "Enrollment",
"learnable_id": "4",
"learnable_type": "CourseTemplate",
"title": "Science 101",
"description": null,
"state": "complete",
"completed_at": "2018-08-27T12:37:13.365-06:00",
"created_at": "2017-04-10T16:26:36.368-06:00",
"archived_at": null,
"permanently_failed": false,
"data": {
"end_at": "2017-04-17T23:59:59.000-06:00",
"expires_at": null,
"renew_by": null,
"required": true,
"score": 100,
"time_remaining": 0,
"current_position": 0,
"furthest_progress": 1,
"quiz_positions": [],
"direct_enrollment": true,
"max_quiz_attempts": null,
"attempts_count": 1,
"inactive": null,
"program": null,
"programs": [],
"in_completed_program": false,
"external_id": null,
"estimated_time": 4,
"passing_threshold": 80,
"has_certificate": false,
"course_type": "bridge",
"slide_count": 4,
"attachments_count": 0,
"attachments_count_author": 0,
"third_party_course_id": null,
"open_book": null,
"continuing_education_credits": null,
"features": []
},
"tags": []
}
],
"meta": {}
}`
I just want to get all the courses (learnable_id) which are
State = Created
learnable_type = CourseTemplate
Once I get all the learnable_id which met above condition then I can return random number from that array.
How do I get this?
Thanks in advance.
You can use JSON path to extract json key values by applying required filters
Add a JSON extractor as a child of your request where you are getting above respone.
use the following configuration in JSON extractor
Json path Expression : $..[?(#.learnable_type=='CourseTemplate' && #.state == 'created')].learnable_id
match no : 0 (This will return a random matach from the possible matches in JMeter
as shown below
Debug Sampler Result :
More info :
Extracting variables
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import net.minidev.json.parser.JSONParser;
import org.apache.commons.lang.StringUtils;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
//Get Store total count
int totalLearningItems = StringUtils.countMatches(new String(data), "enrollable_id");
log.info("Total Number of Learning Items are: " + totalLearningItems);
Random rand = new Random();
if (totalLearningItems > 0) {
//Check for Fulfilment type is "Pickup"
String jsonString = new String(data);
JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE);
JSONObject learning_items = (JSONObject) parser.parse(data);
JSONArray learningArray = (JSONArray) learning_items.get("learning_items");
String learningItemId;
courseList = new ArrayList();
programList = new ArrayList();
taskList = new ArrayList();
for (int i=0; i<learningArray.size(); i++) {
if(learningArray.get(i).getAsString("state").equals("created") || learningArray.get(i).getAsString("state").equals("active")) {
if(learningArray.get(i).getAsString("learnable_type").equals("CourseTemplate")){
courseList.add(learningArray.get(i).getAsString("learnable_id"));
} else if (learningArray.get(i).getAsString("learnable_type").equals("Program")) {
programList.add(learningArray.get(i).getAsString("learnable_id"));
} else if (learningArray.get(i).getAsString("learnable_type").equals("Task")) {
taskList.add(learningArray.get(i).getAsString("learnable_id"));
}
}
}
if(courseList.size() > 0) {
vars.put("courseID", courseList.get(new Random().nextInt(courseList.size())));
} else if (programList.size() > 0) {
vars.put("programID", programList.get(new Random().nextInt(programList.size())));
} else if(taskList.size() > 0) {
vars.put("taskID", taskList.get(new Random().nextInt(taskList.size())));
}
}

lumen order by with two level relation

this is a task manager web app
i have 3 tables rows, tasks and inputs
the inputs table has order column to choice which column to be shown first
row has many tasks
input has many tasks
so every task has an input and a row
i want to sort the tasks by row_id and then by input.order
first try
App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'])
->orderBy('rows.id', 'ASC', 'order', 'ASC')
->get();
it ignores the order
result
[
{
"id": 1,
"user_id": 1,
"created_at": "2018-06-07 18:40:23",
"updated_at": "2018-06-07 18:40:23",
"tasks": [
{
"id": 1,
"row_id": 1,
"input_id": 1,
"option_id": 1,
"value": null,
"input": {
"id": 1,
"name": "assigned to",
"type": 1,
"value": "mario",
"required": 1,
"order": 2,
"user_id": 1,
"created_at": "2018-06-07 18:40:16",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 2,
"row_id": 1,
"input_id": 2,
"option_id": null,
"value": "test new option",
"input": {
"id": 2,
"name": "test new option",
"type": 0,
"value": "test new option",
"required": 0,
"order": 3,
"user_id": 1,
"created_at": "2018-06-07 18:40:44",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 3,
"row_id": 1,
"input_id": 3,
"option_id": null,
"value": "2018-07-01",
"input": {
"id": 3,
"name": "deadline",
"type": 3,
"value": "2018-07-01",
"required": 0,
"order": 4,
"user_id": 1,
"created_at": "2018-06-08 10:07:37",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 4,
"row_id": 1,
"input_id": 4,
"option_id": null,
"value": "",
"input": {
"id": 4,
"name": "priority",
"type": 6,
"value": "",
"required": 0,
"order": 1,
"user_id": 1,
"created_at": "2018-06-08 10:08:19",
"updated_at": "2018-06-08 10:08:19"
}
}
]
}
]
second try
App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'])
->orderBy('rows.id', 'ASC')
->orderBy('order', 'ASC')
->get();
but it generated an error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'order' in 'order clause' (SQL: select * from `rows` order by `rows`.`id` asc, `order` asc)
third try
App\Row::with([
'user',
'tasks',
'tasks.option',
'tasks.input' =>
function($query) {
$query->orderBy('order', 'ASC');
}
])
->orderBy('rows.id', 'ASC')
->get();
it ignores the order result same as first
forth try
return App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'])
->join('tasks', 'rows.id', '=', 'tasks.row_id')
->join('inputs', 'inputs.id', '=', 'tasks.input_id')
->orderBy('rows.id', 'ASC')
->orderBy( 'inputs.order', 'ASC')
->get();
it generate row for every column and not row as it suppose to
result
[
{
"id": 4,
"user_id": 1,
"created_at": "2018-06-08 10:08:19",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 4,
"option_id": null,
"value": "",
"name": "priority",
"type": 6,
"required": 0,
"order": 1,
"tasks": []
},
{
"id": 1,
"user_id": 1,
"created_at": "2018-06-07 18:40:16",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 1,
"option_id": 1,
"value": "mario",
"name": "assigned to",
"type": 1,
"required": 1,
"order": 2,
"tasks": [
{
"id": 1,
"row_id": 1,
"input_id": 1,
"option_id": 1,
"value": null,
"input": {
"id": 1,
"name": "assigned to",
"type": 1,
"value": "mario",
"required": 1,
"order": 2,
"user_id": 1,
"created_at": "2018-06-07 18:40:16",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 2,
"row_id": 1,
"input_id": 2,
"option_id": null,
"value": "test new option",
"input": {
"id": 2,
"name": "test new option",
"type": 0,
"value": "test new option",
"required": 0,
"order": 3,
"user_id": 1,
"created_at": "2018-06-07 18:40:44",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 3,
"row_id": 1,
"input_id": 3,
"option_id": null,
"value": "2018-07-01",
"input": {
"id": 3,
"name": "deadline",
"type": 3,
"value": "2018-07-01",
"required": 0,
"order": 4,
"user_id": 1,
"created_at": "2018-06-08 10:07:37",
"updated_at": "2018-06-08 10:08:19"
}
},
{
"id": 4,
"row_id": 1,
"input_id": 4,
"option_id": null,
"value": "",
"input": {
"id": 4,
"name": "priority",
"type": 6,
"value": "",
"required": 0,
"order": 1,
"user_id": 1,
"created_at": "2018-06-08 10:08:19",
"updated_at": "2018-06-08 10:08:19"
}
}
]
},
{
"id": 2,
"user_id": 1,
"created_at": "2018-06-07 18:40:44",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 2,
"option_id": null,
"value": "test new option",
"name": "test new option",
"type": 0,
"required": 0,
"order": 3,
"tasks": []
},
{
"id": 3,
"user_id": 1,
"created_at": "2018-06-08 10:07:37",
"updated_at": "2018-06-08 10:08:19",
"row_id": 1,
"input_id": 3,
"option_id": null,
"value": "2018-07-01",
"name": "deadline",
"type": 3,
"required": 0,
"order": 4,
"tasks": []
}
]
this file is here
the full code is here
Because it searches columns in table rows not in input.
App\Row::with(['user', 'tasks', 'tasks.option', 'tasks.input'=> function ($q){
$q->orderBy('order', 'ASC'); // order from "rows" table
}])
->orderBy('id', 'ASC') // id from "rows" table
->get();

reformating cakephp find threaded

My goal is to use a tree object to store invoices. The issue I'm running into is that it always puts a "Invoice" model wrapper around each subsequent child. I tried just getting the results and using the Set class to clean up the redundant "Invoice", "children" but I couldn't figure out how to get it to work. I'm using this in an API so basically what I want to be able to do is move up and down the array without having to constantly do invoice.children.invoice.children
In my controller I have:
$results = $this->Invoice->find('threaded', array(
'order' => array('lft ASC') // or array('id ASC')
));
$this->set(array(
'results' => $results,
'_serialize' => 'results'
));
What I'm getting is:
{
"success": true,
"data": [
{
"id": 1,
"parent_id": null,
"lft": 1,
"rght": 30,
"name": "Invoices",
"children": [
{
"Invoice": {
"id": 2,
"parent_id": 1,
"lft": 2,
"rght": 15,
"text": "invoice 001"
},
"children": [
{
"Invoice": {
"id": 3,
"parent_id": 2,
"lft": 3,
"rght": 8,
"text": "invoice_item"
},
"children": [
{
"Invoice": {
"id": 4,
"parent_id": 3,
"lft": 4,
"rght": 5,
"text": "invoice_sub_item"
},
"children": []
},
{
"Invoice": {
"id": 5,
"parent_id": 3,
"lft": 6,
"rght": 7,
"text": "subitem#2"
},
"children": []
}
]
}
]
}
]
}
]
}
Ideally I'd like to have
invoices.invoice.text = "invoice 001"
and
invoices.invoice.invoice_item[0].text = "invoice_item"
Obviously I'll need to add/take away from the array and resubmit with changes. Is this possible or am I just making things harder on myself?