How to update column in table if api results have been modified - php

My application: My application allows users to predict the scores of all upcoming soccer games for the next matchday. I get this data from an API and store the upcoming games in my database. These upcoming games have a status of Scheduled. Now I want to run a cronjob every few minutes that checks if the status of those matches have been changed to in_play or finished, if this is the case I want to update my status field in my database for the correct match to the status field from the api.
How can I check if the status has been changed and modify the correct match in my database? I have a match_id stored which can maybe be used for this?
My code:
updateStatus job
public function handle()
{
$this->updateStatus();
}
public function updateStatus() {
$this->getMatches();
// check if status has been changed from schedulded to 'in_play' or 'finished'
// update the match status of the right matches in my database
}
public function getMatches() {
$client = new Client();
$uri = 'http://api.football-data.org/v2/competitions/PL/matches/?matchday=12&season=2018&matches';
$header = ['headers' => ['X-Auth-Token' => 'My-token']];
$res = $client->get($uri, $header);
return json_decode($res->getBody()->getContents(), true);
}
getMatches job (this job gets the api data and stores it in the database)
public function handle()
{
$this->saveMatches();
}
public function saveMatches()
{
$matches = $this->getMatches();
collect($matches['matches'])
->each(function ($match, $key) {
$date = new DateTime($match['utcDate']);
Match::create([
'match_id' => $match['id'],
'homeTeam' => $match['homeTeam']['name'],
'awayTeam' => $match['awayTeam']['name'],
'status' => $match['status'],
'date' => $date->format('Y-m-d'),
'time' => $date->format('H:i'),
'matchday' => $match['matchday'],
'homeScore'=> $match['score']['fullTime']['homeTeam'],
'awayScore'=> $match['score']['fullTime']['awayTeam']
]);
});
}
public function getMatches()
{
$client = new Client();
$uri = 'http://api.football-data.org/v2/competitions/PL/matches/?matchday=12&season=2018&matches';
$header = ['headers' => ['X-Auth-Token' => 'My-token']];
$res = $client->get($uri, $header);
return json_decode($res->getBody()->getContents(), true);
}

What you probably want to do is utilize Laravel's updateOrCreate() method on your Match object. The uniquely identifying information appears to be the match id. If this doesn't ever change, then when you are looping through your each statement you can do this:
Match::updateOrCreate([
'id' => $match['id'],
],[
'homeTeam' => $match['homeTeam']['name'],
'awayTeam' => $match['awayTeam']['name'],
'status' => $match['status'],
'date' => $date->format('Y-m-d'),
'time' => $date->format('H:i'),
'matchday' => $match['matchday'],
'homeScore'=> $match['score']['fullTime']['homeTeam'],
'awayScore'=> $match['score']['fullTime']['awayTeam']
]);
What this does is look for an existing match with this same ID. If it already exists, it will simply update it with all of the information provided by the API, including the status of the match and the scores. If it doesn't yet exist, it will instead create it and store it in the database as a new match with all of the provided information. Hope this helps!

Related

Laravel only saves first item to database why?

public function download****()
{
// Downloads new externals (if updateable)
$site_id = 1;
$sinceLastId = $this->lastExternalSiteOrderId($site_id);
$api_version = config('services.*****.api_version');
$path = '/admin/api/' . $api_version . '/orders.json';
// GET request - Shopify.php (orders.json)
$result = $this->basicShopifyApi*****()->rest('GET', $path, ['since_id' => $sinceLastId]);
$orders = $result->body->orders;
if (!isset($orders)) {
return Response::json(['message' => 'No new ***** orders to download!'], 204);
} else {
foreach ($orders as $order) {
// Save to External Log
ExternalLog::create([
'data' => $order,
]);
// Gets updatable status
$updatable = $this->updateable($order->id);
// Saves new externals (create), if updateable
if ($updatable) {
$this->updateOrCreateExternals($order, $site_id);
}
}
}
}
// Updates a external role
public function updateOrCreateExternals($request, $site_id) {
// Saves external updates
$external = External::updateOrCreate(
[
'site_order_id' => ['order_id' => $request->id],
'site_id' => $site_id],
[
// 'order_id' => 0, // not required
'site_order_id' => $request->id,
'site_id' => $site_id, // Shopify is 1 (within ShopifyController this is correct)
'site_sub_id' => 0,
'site_account_id' => 0,
'data' => $request,
'site_order_status' => 0,
'order_created_at' => date("Y-m-d H:i:s", strtotime($request->created_at)),
'order_updated_at' => date("Y-m-d H:i:s", strtotime($request->updated_at)),
]);
echo "ShopifyExternalController#updateOrCreate function called!";
// Creates Customers, Orders, Carts, Payments for external, then set Site_Order_Status to 10
$shopifyOrderController = new shopifyOrderController();
$shopifyOrderController->updateOrCreateOrders($site_id);
}
This code works locally, but on dev (staging) server it only saves the first item?
Any ideas, why it won't work on the server?
It is shared hosting, cent os, PHP 7.2, not set up with Laravel Forge or vapor.
Any tips on writing YAML scripts to deploy a site correctly?
I have tried doing "composer dump-autoload" as I recently changed some of the controller names from lowercase to uppercase.
updateOrCreate
Updates only one model rather than many .

Insert a new record if not exist and update if exist, laravel 5.4

Is there any way to insert a new record if doesn't exist and update the record if exist? the following is the code i using.
public function store(Request $request)
{
$inputs = $request->all();
$this->validate($request,[
'course_code'=>'required'
]);
$batch = $request->batch;
$students = User::select('student_id')->where('batch', $batch)->get();
$course_codes = $inputs['course_code'];
$data=[];
foreach ($students as $student) {
foreach ($course_codes as $course_code) {
$data[]=[
'batch' => $batch,
'student_id' => $student->student_id,
'semester' => $inputs['semester'],
'course_code' => $course_code,
"created_at" => \Carbon\Carbon::now(), # \Datetime()
"updated_at" => \Carbon\Carbon::now() # \Datetime()
];
}
}
DB::table('assign_batches')->insert($data);
return redirect('/admin/assign/batch/create')->with('message', 'A batch has been assigned to courses successfully!');
}
Here is my output when I inserted same records again.
But I want one Student Id may have many Course Code but can not be duplicate. So I want to check if student has same course or courses then skip or update it and insert new records.
Please help me.
Thanks.
Check id if exist then update otherwise insert
if(isset($request->id)){
DB::table('assign_batches')->where("id", $request->id)->update($data);
}else {
DB::table('assign_batches')->insert($data);
}
Use firstOrCreate / firstOrNew
$students = User::firstOrNew(['student_id' => $request->student_id, 'course_code' => $request->course_code]);
$students->foo = $request->foo;
$students->save();
for example if you have a table for every each user to vote once or update his vote;
//give the record to use
$record = request('vote');
//checkif there is a record for user in model
$row = Uservoting::where('user_id',Auth->user()->id)->first;
//if true
if($row!==null){
//update
$row::update(['vote' => $record]);
//if there isn't in model
}else{
//create a new row and insert the value
$new_row = new Uservoting();
$new_row->user_id = Auth->user()->id ;
$new_row->vote = $record ;
$new_row->vote();`
}
hope this work:) {{--if you found any bug just tell me--}}

Search Shipping Item in Netsuite API

I have this existing code snippet that searches list of records specified by its RecordType (e.g. InventoryItem, SalesOrder).
$request = new GetRequest();
$request->baseRef = new RecordRef();
$request->baseRef->type = $type; //Record Type
$request->baseRef->internalId = $internalId; //Internal ID of record
$getResponse = $service->get($request);
if ( ! $getResponse->readResponse->status->isSuccess) {
return 'ERROR';
} else {
return $getResponse->readResponse->record;
}
However, it seems that there's no Shipping Item in the list in RecordType although I can pass an internal ID. My goal here was to get the shipping item details to be used in my computation for creating a sales order (needs to be displayed before submitting).
Will there be a different approach in getting the shipping item record? How?
Shipping Item record is not yet supported in Suitetalk. As an alternate solution you can create a RESTlet instead to get the Shipping Item.
I can now successfully retrieve Shipping items via RESTlets. I uploaded this first as new in the File Cabinet, then added it as a new script. NetSuite does not allow direct upload of script file when creating a new script.
// get_record.js
function get_record(datain)
{
var record = nlapiLoadRecord(datain.recordType, datain.id);
return record;
}
Then used guzzle http library to call the RESTlet.
$url = "https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl";
$client = new GuzzleHttp\Client();
$authorization = [
'NLAuth nlauth_account='.getenv('NETSUITE_ACCOUNT'),
'nlauth_email='.getenv('NETSUITE_EMAIL'),
'nlauth_signature='.getenv('NETSUITE_PASSWORD'),
'nlauth_role='.getenv('NETSUITE_ROLE')
];
$response = $client->request('GET', $url, [
'headers' => [
'Authorization' => implode(',', $authorization),
'Content-Type' => 'application/json'
],
'query' => [
'script' => '343', //script id
'deploy' => '1',
'recordType' => 'ShipItem',
'id' => '5905' // example of internal id of desired shipping item
]
]);
return json_decode($response->getBody());

Laravel - keeping a running tally of a column through a transformer

So I have a Contribution model. I have a controller that pulls in all the contributions and sends them to a transformer like so:
My Controller:
public function showContributions (Request $request, $memberId)
{
$perPage = $request->input('per_page', 15);
$contribution = parent::getRepo('Contribution');
$contributions = Cache::tags(['contributions'])->remember("contributions.$memberId.2", 60, function() use ($perPage, $memberId, $contribution){
return $contribution->where('vip_id', $memberId)->where('fund_id', 2)->paginate($perPage);
});
$transformedData = $this->fractal->paginatedCollection($contributions, new ContributionTransformer(), 'contributions');
return $this->sendResponse($transformedData['contributions'], $transformedData['meta']);
}
My transformer:
public function transform(Contribution $contribution)
{
setlocale(LC_MONETARY, 'en_US.UTF-8'); // Set so that money_format uses the dollar sign instead of USD. Consider moving to bootstrap
$report = $contribution->report;
$employer = $report->employer;
$employerHours = $contribution->employerHours;
$contributionLocal = $contribution->local->local_code ?? '';
$employerLocal = $employerHours->local->local_code ?? '';
$reciprocalLocal = $contributionLocal === $employerLocal ? '0000' : $employerLocal;
$response = [
'id' => $contribution->member_hours_id,
'report_number' => $contribution->report_number_id,
'employer_code' => $employer->employer_code,
'employer_name' => $employer->employer_name,
'worked_date' => $report->ending_worked_date,
'received_date' => $report->receipt_date,
'report_local' => $contributionLocal,
'reciprocal_local' => $reciprocalLocal,
'unit_type' => $contribution->unitType->code_description,
'units_worked' => $contribution->units_worked,
'credited_units' => $contribution->units_credited,
'rate' => $contribution->unit_multiplier,
'reciprocal_rate' => $employerHours->reciprocal_multiplier,
'calculated_amount' => money_format('%.2n', $contribution->calculated_amount),
'received_amount' => money_format('%.2n', $contribution->actual_amount),
'owed_amount' => money_format('%.2n', $contribution->owed_amount),
];
return $response;
}
One of the fields in the contributions table is sub_hours. What they want me to do is keep a running tally of said field. In each subsequent row return that tally as hours_to_date. So in first row sub_hours is 32 and in the second row it is 60. In the first row hours_to_date will be 32 but in the second row it will be 92 and the third row it will be 92 + sub_hours of row 3 etc. I can't seem to figure out how I should keep track of this running tally and allow the transformer access to it. Any help would be appreciated.
Can you create a property on the transformer class? I haven't used transformers but something like
class ContributionTransformer{
private $tally;
function __construct(){
$this->tally = 0;
}
public function transform(Contribution $contribution){
...
$this->tally += $contribution->sub_hours;
...
}

Saving data after read

I'm trying to save data after the same model read it. Here's my code:
public function partner($postid, $partner){
$this->Partner->id = $postid;
$this->Partner->id = $partner;
$this->Partner->ip = $_SERVER['REMOTE_ADDR'];
$result = $this->Partner->read();
if($result){
$time = $result['Partner']['time'];
pr($result);
}
$data = array('id' => $partner,
'post' => $postid,
'time' => time(),
'cash' => '0.001',
'ip' => $_SERVER['REMOTE_ADDR']);
$this->Partner->save($data);
}
It just updates the data, but doesn't save it as a new row
Before $this->Partner->save($data);, call $this->Parter->create();, that will set the Partner model to save a new row.
EDIT: Unless id is your model's primary key and you're setting it to a value that already exists in the database, in that case it will update regardless of whether you use $model->create() or not. (I think).

Categories