Laravel get attribute value based on range from json - mysql

The following is coded in the Laravel framework:
QUERY
$shipping = DB::table('shipping')->where('country',$delivery->country)->first();
$data= json_decode(json_encode($shipping),true);
RESULT
array (
'id' => 3,
'carrier' => 'EN',
'country' => 'AU',
'rates_json' => '{"rates": [{"international": [{"zone4": [{"to_kg": "2", "total": "1", "from_kg": "1"}, {"to_kg": "4", "total": "2", "from_kg": "3"}]}]}]}',
)
In the MySQL database, I stored "rates_json" in a "JSON" datatype column. The attribute "from_kg" and "to_kg" is a range.
I intend to retrieve the total if a value is between the range. For instance, if value 1.5 is between 1 and 2 then the total is 1.
Your help is appreciated.
Thank You.

Since your question is not clear,
I can only give you a hint, what you can do.
foreach (json_decode($data['rates_json'])->rates as $rates) {
foreach ($rates->international as $international) {
foreach ($international->zone4 as $zone) {
if ($zone->from_kg <= $zone->total && $zone->total <= $zone->to_kg)
{
// do whatever you want here.
dump($zone->total);
}
}
}
}
Let me know for any adjustments.

Related

How to group orders by different cities using Laravel, MySql, JSON

Trying to build a report result of orders related information of a laravel project. But struggling to find out a solution on a specific data structure.
My Request :
// Date Ranges
$fromDate = $this->request->fromDate;
$toDate = $this->request->toDate;
So the result should be within a date range.
My orders table :
order_id order_addresses grand_total
------------------------------------------
1 JSON DATA 3,000.00
2 JSON DATA 2,000.00
3 JSON DATA 1,500.00
So My JSON DATA looks like this :
{
"delivery_address":{
"House":"Offline House",
"Street":"Offline Road",
"Area":"Offline Area",
"PostCode":"1230",
"City":"City1",
"Country":"Country1",
"ContactPerson":"Offline User",
"ContactNumber":"01XXXXXXXX"
}
}
I just want the response as :
{
"orders": 3, // How many orders are there in that particular city
"totals": "5,500.00", // Total how much the cost of orders in that city
"groupby": "City1",
},
{
"orders": 5,
"totals": "7,500.00",
"groupby": "City2",
},
...,
...
I am seeking a solution using query builder in laravel with MySQL.
This is an existing project so I can't really change the structure how it was built. So, any suggestions on how I can extract the cities from JSON DATA having relation with the orders identity along with the totals and all.
I just need the order_ids I think city wise then I can structure my result anyway I like to achieve end result.
If anything confusion here, please let me know so that I can make it clear.
Thanks in Advance !
I would suggest grouping fetched data using Laravel Collection functions.
Order Model
class Order extends Model {
// This will cast data to native types.
// so order_address json string to array
protected $casts = [
'order_addresses' => 'array',
];
}
Controller function
// Fetch orders from the database as you usually do
// without considering about grouping.
// with your conditions.
// I will simply use all() for example.
$orders = Order::all();
// First group by city
// Then map to get the result you want.
$groupedOrders = $orders->groupBy(function($order) {
// since we added it to the casts array in the model
// laravel will automatically cast json string to an array.
// So now order_address is an array.
return $order->order_addresses['City'];
})
->map(function($groupedOrders, $groupName) {
return [
'orders' => $groupedOrders->count(),
'totals' => $groupedOrders->sum('grand_total'),
'groupby' => $groupName,
];
});

Jira API | Error: "Operation value must be a string" - trying to set value nested two levels deep

Trying to create a new jira ticket of specific requestType, but it is nested two levels deep. Tried few possible alterations, but no luck. Here's the code I have,
require 'jira-ruby' # https://github.com/sumoheavy/jira-ruby
options = {
:username => jira_username,
:password => jira_password,
:site => 'https://jiraurl/rest/api/2/',
:context_path => '',
:auth_type => :basic,
:read_timeout => 120
}
client = JIRA::Client.new(options)
issue = client.Issue.build
fields_options = {
"fields" =>
{
"summary" => "Test ticket creation",
"description" => "Ticket created from Ruby",
"project" => {"key" => "AwesomeProject"},
"issuetype" => {"name" => "Task"},
"priority" => {"name" => "P1"},
"customfield_23070" =>
{
"requestType" => {
"name" => "Awesome Request Type"
}
}
}
}
issue.save(fields_options)
"errors"=>{"customfield_23070"=>"Operation value must be a string"}
Also tried passing a JSON object to customfield_23070,
"customfield_23070": { "requestType": { "name": "Awesome Request Type" } }
still no luck, get the same error message.
If it helps, this is how customfield_23070 looks like in our Jira,
Does anyone know how to set requestType in this case, please? Any help is greatly appreciated!!
It seems that for custom fields with specific data types (string/number), you must pass the value as:
"customfield_1111": 1
or:
"customfield_1111": "string"
instead of:
"customfield_1111":{ "value": 1 }
or:
"customfield_1111":{ "value": "string" }
I'm not sure but you can try this possible examples:
eg.1:
"customfield_23070"=>{"name"=>"requestType","value"=>"Awesome Request Type"}
eg.2:
"customfield_23070"=>{"requestType"=>"Awesome Request Type"}
eg.3:
"customfield_23070"=>{"value"=>"Awesome Request Type"}
eg.4
"customfield_23070"=>{"name"=>"Awesome Request Type"}
for ref there are 2 methods depending upon the fields you are interacting with
have a look here '
updating-an-issue-via-the-jira-rest-apis-6848604
' for the applicable fields for update via verb operations, the other fields you can use examples as per above,
you can use both methods within the same call
{
"update": {"description": [{"set": "Description by API Update - lets do this thing"}]},
"fields": {"customfield_23310": "TESTING0909"}
}
Ok, I think I found how to do it.
You need to provide a string, and that string is the GUID of the RequestType.
In order to get that GUID. You need to run the following in a scriptrunner console:
import com.atlassian.jira.component.ComponentAccessor
def issue = ComponentAccessor.issueManager.getIssueByCurrentKey("ISSUE-400546") //Issue with the desired Request Type
def cf = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Tipo de solicitud del cliente") //Change it to the name of your request type field
issue.getCustomFieldValue(cf)
Source: https://community.atlassian.com/t5/Jira-Software-questions/how-to-set-request-type-value-in-while-create-jira-issue/qaq-p/1106696

Update Query in laravel 5.4

How can I update multiple rows
I'm getting below array
[
"3",
"4",
"5"
]
My Controller
$answers= $request->get('option'); //answers array
foreach ($answers as $answer)
{
Answer::where('question_id', 1)->update(
['customer_id' => 1,
'answer' => $answer]);
}
You can use update() method:
Answer::where('question_id', 2)->update(['customer_id' => 1, 'answer' => 2]);
The update method expects an array of column and value pairs representing the columns that should be updated
Don't forget to add customer_id, answer to the $fillable array:
protected $fillable = ['customer_id', 'answer'];
If you are using query builder then use bellow query
DB::table('answers')
->where('question_id', 2)
->update(array('customer_id' => 1, 'answer' => 2]);
and if you are using Eloquent ORM then use bellow query
App\Answers::where('question_id', 2)->update(['customer_id' => 1,'answer'=>2]);
You can update with simple following query.
DB::table('answers')->where('id',2)->update(['customer_id' => 1, 'answer' => 2]);
It's better to use Eloquent Model like,
Answer::where('id',2)->update(['customer_id' => 1, 'answer' => 2]);
If you have not added these column in $fillable property of model then, you can update with after find like,
$answer = Answer::find(2);
$answer->customer_id = 1;
$answer->answer = 2;
$answer->save();
Hope you understand.

feathersjs/sequelize -> results of a 'find' are not equal to defined 'select'

Situation
In a project I have this code to select data from a table. Please note, it is working, I only don't get the result I expect.
serviceSurveyQuestions.find({
query: {
survey_id: this.survey_id,
user_id: this.$store.state.auth.user.id, //TODO move this to the hook!!
//todo make satus also not equal new
$or: [
{ status_id: process.env.mfp.statusSurveyQuestionStarted },
{ status_id: process.env.mfp.statusSurveyQuestionPlanned }
],
$sort: {
survey_question_question: 1
},
$limit: 150,
$select: [
'survey_question_question',
'survey_question_at',
'survey_question_answer',
'survey_question_details',
'survey_question_source_id',
'survey_question_source_answer_id',
'survey_question_source_user_id',
'survey_question_step',
'survey_question_dep_step',
'id'
]
}
}).then(page => {
this.listSurveyQuestions = page;
});
When I see what would be in one item of listSurveyQuestion I will see this:
{
"survey_question_question": "PEN 10 Scope vaststellen",
"survey_question_at": "2017-06-23T06:46:10.038Z",
"survey_question_answer": "",
"survey_question_details": "tester done",
"survey_question_source_id": 83499707,
"survey_question_source_answer_id": 74864,
"survey_question_source_user_id": 83488216,
"survey_question_step": 10,
"survey_question_dep_step": null,
"id": 4651,
"source_user": {
"user_id": 1005
},
"status": {
"status": "Planned"
},
"language": {
"language": "Dutch"
,
"source": {
"source": "MexonInControl - Pob - Dev (local)"
},
"survey_question": [{
"answer_type_id": 1014,
"answer_en": null,
"answer_nl": null,
"answer_explanation_en": null,
"answer_explanation_nl": null,
"survey_question_next_id": 4652
} ]
}
I know the result is comming from the configuration in my get and find hook of the service being called.
Expected Result
What I expect to happen is that the data returned is only the columns defined in the $SELECT. If I leave this as is, it will work but I'm getting to much data from the database which can be seen later as a security breach. Not with this example, but with other tables it will.
** Question **
So what do I need to change to have this functioning as expected. You could adapt the return of the service, but then I can't use the same service in other situations for the columns aren't available. Or can you pass an option to the service which will result in if (parameter = view 1) then return view 1 and so on.
** Solving **
Remark 1:
So I just see the 'cause' is a bit different. The configured hooks returns more columns from the question table which are not shown. So my guess here is that if you don't configure the includes in the find query, it will pass all includes. I need to check that and if this is the case, see if there is a option to not select the 'includes' as well.
Assuming that the hook you are referring to is setting hook.params.sequelize similar to this answer you will have to check if you included properties are also set in the $select query with something like this:
// GET /my-service?include=1
function (hook) {
const include = [];
const select = hook.params.query.$select;
// Go through all properties that are added via includes
['includeProp1', 'includeProp2'].forEach(propertyName => {
// If no $select or the include property is part of the $select
if(!select || select.indexOf(propertyName) !== -1) {
include.push({ model: ModelForIncludeProp1 });
}
});
hook.params.sequelize = { include };
return Promise.resolve(hook);
}

Is there anything like batch update in Rails?

In Java we have batch execution like the java code below:
Statement statement = null;
statement = connection.createStatement();
statement.addBatch("update people set firstname='John' where id=123");
statement.addBatch("update people set firstname='Eric' where id=456");
statement.addBatch("update people set firstname='May' where id=789");
int[] recordsAffected = statement.executeBatch();
how to do the same in rails ActiveRecord?
You can give this a try. Seems like what you're after.
# Updating multiple records:
people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
Person.update(people.keys, people.values)
Quoted: https://cbabhusal.wordpress.com/2015/01/03/updating-multiple-records-at-the-same-time-rails-activerecord/
To fit the post requirements, it translates to:
people = {
123 => { "firstname" => "John" },
456 => { "firstname" => "Eric" },
789 => { "firstname" => "May" }
}
Person.update(people.keys, people.values)
Please note that translating the above into SQL still yields multiple queries
Thanks to Rails 6, you can now perform bulk update using upsert_all method for exemple.
More details available there: https://www.bigbinary.com/blog/bulk-insert-support-in-rails-6
Be aware that unique_by option is not supported when the database is MySQL but it works great for Postgresql.