First question on here as an enthusiast trying to get this to work.
Using the open source project by jdorn PHP-Reports and following the stripe custom reporting tutorials.
The report never returns, what I am trying to achieve is custom Stripe payments reporting using the Stripe API to return all charges, to then display in a nice table 😀
Here is my paymentreport.php code
<?php
//My Payments Report
//This connects to the Stripe Payments api and shows a list of charges
//VARIABLE: { name: "count", display: "Number of Charges" }
// Set your secret key: remember to change this to your live secret key in production
\Stripe\Stripe::setApiKey('StripeTestCodeAPIKEY');
if($count > 100 || $count < 1) throw new Exception("Number of Charges must be between 1 and 100");
// Retrieve a list of 50 most recent charges
$charges = \Stripe\Charge::all(array(
'limit' => 50
));
// Loop through each charge
foreach ($charges->data as $charge) {
// Get the required charge information and assign to variables
$id = $charge->id;
$description = $charge->description;
$created = gmdate('Y-m-d H:i', $charge->created); // Format the time
$amount = $charge->amount/100; // Convert amount from cents to dollars
$currency = $charge->currency;
$rows = array();
foreach($charges as $charge) {
$rows[] = array(
'Charge Id'=>$charge->id,
'Amount'=>number_format($charge->amount/100,2),
'Date'=>date('Y-m-d',$charge->created)
);
}
echo json_encode($rows);
?>
There are a few problems here-- you accept a $count-variable that's never used. I think what you're trying to do is this:
$charges = \Stripe\Charge::all(array(
'limit' => $count
));
Additionally, you've got a loop at the bottom that's broken. You've got to remove the second foreach and move the $rows = array(); outside of the first loop.
Finally, the last call $rows[] = array(...) should probably also include the variables you captured above. Does that make sense?
Related
I have an array of admission and each student has multiple entry of payment.
Like Admission=[1,2,3,4,5,6] this is admission ids,
and Payment=[[1->1,5,6,2],[2->2,3],[3->4,7,8] this is admission id->payment_ids
foreach($admission as $a)
{
$payment=DB::table('payement')->where('admission_id',$a->admission_id)->get();
foreach($payment as $p)
{
// Here i wan if payment_date <= today_date
// 1. Add all payment
// 2. Else Go to the next admission id
}
}
It sounds like you're looking for something like this:
foreach($admission as $a)
{
$payment = DB::table('payment')->where('admission_id', $a->admission_id)->get();
$totalPayment = 0;
foreach($payment as $p)
{
if (\Carbon\Carbon::parse($p->payment_date)->lessThanOrEqualTo(\Carbon\Carbon::now())) {
$totalPayment += $p->amount;
}
}
}
Inside of the foreach loop on $payment the code above uses Carbon to compare the dates. It looks like you're using Laravel's Eloquent so you should have Carbon available in your application since it's a Laravel dependency. I use Carbon to compare the dates because it knows more about dates than I do.
Next, if it's true that payment_date is less than or equal to the current date then it will add it to the $totalPayment for that admission. Otherwise, it will move onto the next payment. This presumably makes using continue or break unnecessary unless I am misunderstanding something.
I'm not sure what you want to do with $totalPayment. Right now it will be calculated for each admission and then lost.
If you want to find the total payment across all admissions you should move $totalPayment = 0 to the line above foreach($admission as $a).
If you want to find the total payment for each admission you could set a totalPayment on each admission $a->total_payment = $totalPayment. I would then change $totalPayment = 0 to $a->total_payment = 0 and change $totalPayment += $p->amount to $a->totalPayment += $p->amount.
I'm currently trying to identify which purchase is costing our company more than 40. Each purchase is an array of data I get through an API, and the cost is pulled from a mysql database. I have been trying with a while and a for each loop but after multiple attempt I think using one loop will be the best for performance and accuracy.
$result is the MYSQL data, and $json_array contains the API data. I would like to join the 2 data sets within a loop so I can identify the purchase_id for any purchase that costing us more than 40.
Any help much appreciated!
I have already tried 2 different loops but it won't work. It needs to be in one loop instead of 2.
//Getting the MySQL Results
$result=mysqli_query($conn,$sql);
//Creating empty array
$overspend = array();
//Starting the loop
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
//If the cost if more than 40 continue
if($row["cost"] > 40){
array_push($overspend, $row['purchase_id'] );
if (in_array($json_array, $overspend)){
$count = array_count_values($json_array);
${'_'.$row['purchase_id'].'_l'} = $count[$row['purchase_id']];
${'_'.$row['purchase_id']} = $row['cost'];
if((${'_'.$row['purchase_id']}/${'_'.$row['purchase_id'].'_l'}) > 40){
echo ${'_'.$row['purchase_id']};
}
}
}
}
}
I am not getting any error messages, I am just not getting the result expected. The expected result should be the keyword id.
I am trying to query for all payments assigned to an invoice using the consolibyte quickbooks php toolkit. I was hoping I could pull these back using a query but so far the only way I can see to do it is by grabbing all payments and then looping through and checking what is within the LinkedTxn array and checking if it has a type of 'Invoice' and that the 'TxnId' value matches my stored invoice id. What I have so far is this which gets the payments but is obviously not an option going forward as there may be tens of thousands of payments in the system:
public function getAllPaymentsForInvoice(Invoice $invoice)
{
$query = "SELECT * FROM Payment";
$payments = $this->qbPaymentService->query($this->context, $this->realm, $query);
$lines = [];
foreach ($payments as $payment) {
$num_lines = $payment->countLine();
for ($i = 0; $i < $num_lines; $i++) {
$line = $payment->getLine($i);
$txnId = $this->parseResponse($line->getLinkedTxn()->getTxnId());// convert {-1} to 1
$txnType = $line->getLinkedTxn()->getTxnType();
if ($txnType == 'Invoice' && $txnId == $invoice->qb_ref) {
$lines[] = $line;
}
}
}
return $lines;
}
Can anyone push me in the direction of a better way?
There's no easy, one-liner way to do this using the QuickBooks Online API. This just isn't something that QuickBooks Online itself supports.
There are two separate approaches you could take to optimize what you're doing.
The payments applied should always be for the same customer as the invoices, so you can change your query to SELECT * FROM Payment WHERE CustomerRef = 'xyz' where xyz is the CustomerRef from the invoice. Then, use your existing code to check exactly which invoices payments are applied to.
Use the CDC functionality to keep a cached copy of all payments in your own database, and query your own database for the information instead (a normal SQL database is considerably more flexible and query-able than what QuickBooks Online offers).
The CDC functionality is specifically designed to allow you to keep an accurate, cached copy of the QuickBooks data in your own application, specifically to address situations like you're running into. You pass it a timestamp, and it gives you everything that has changed since that timestamp. By remembering the date/time you last ran the ->cdc(...) method, you can continually get lightweight updates to any objects that have changed since you last queried them.
<?php
$CDCService = new QuickBooks_IPP_Service_ChangeDataCapture();
// What types of objects do you want to get?
$objects = array(
'Payment',
'Invoice',
);
// The date they should have been updated after
$timestamp = QuickBooks_Utilities::datetime($datetime_you_last_called_cdc_method);
$cdc = $CDCService->cdc($Context, $realm,
$objects,
$timestamp);
// You would cache all the stuff you get back here
print_r($cdc);
Docs links:
https://github.com/consolibyte/quickbooks-php/blob/master/docs/partner_platform/example_app_ipp_v3/example_cdc.php
https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
The question is quite old, anyway, in case someone else is looking for answer:
$InvoiceService = new QuickBooks_IPP_Service_Invoice();
// $invoices = $InvoiceService->query($Context, $realm, "SELECT * FROM Invoice STARTPOSITION 1 MAXRESULTS 10");
// If, we have QB Invoice # i.e.DocNumber
$invoice_no = 1001;
$invoices = $InvoiceService->query($Context, $realm, "SELECT * FROM Invoice WHERE DocNumber = '$invoice_no' ");
foreach ($invoices as $Invoice)
{
$txnId = 0;
if (is_object($Invoice->getLinkedTxn()) && $Invoice->getLinkedTxn()->getTxnType() == 'Payment') {
$txnId = $Invoice->getLinkedTxn()->getTxnId();
}
print('Invoice # '.$Invoice->getDocNumber().' has a total of $'.$Invoice->getTotalAmt().' and Linked Payment ID: ' . $txnId . "\n");
}
I almost got it working perfectly, except for generating the labels.
I have this code to generate the rates, which works great:
//Wait for rates to be generated
$attempts = 0;
while (($shipment["object_status"] == "QUEUED" || $shipment["object_status"] == "WAITING") && $attempts < 10)
{
$shipment = Shippo_Shipment::retrieve($shipment["object_id"]);
$attempts +=1;
}
//Get all rates for shipment.
$rates = Shippo_Shipment::get_shipping_rates(array('id'=> $shipment["object_id"]));
$json = json_decode($rates, true);
foreach ($json["results"] as $key)
{
$amount = $key["amount"];
$servicelevel = $key["servicelevel_name"];
$objid = $key["object_id"];
}
As I go through each of the results, I assign them to variables for the different service levels and allow the user to select which shipping method they want to use. I pass the $objid to the next page to produce the label using the following code:
//Write the object_id to a variable
$var = $shiparray[1];
$transaction = Shippo_Transaction::create(array('rate'=>$var));
echo $transaction["object_status"] ."<br>";
// Wait for carrier to create shipping label
$attempts = 0;
while (($transaction["object_status"] == "QUEUED" || $transaction["object_status"] == "WAITING") && $attempts < 10)
{
$transaction = Shippo_Transaction::retrieve($transaction["object_id"]);
$attempts += 1;
}
echo $transaction["object_status"] ."<br>";
// Retrieve label url and tracking number or error message
if ($transaction["object_status"] == "SUCCESS")
{
echo($transaction["label_url"]);
echo("\n");
echo($transaction["tracking_number"]);
}
else
{
echo( $transaction["messages"] );
}
This just produces an error, though. Am I passing the wrong value to produce the label? Should I be using a value produced for the shipment rather then the rate?
this is Simon from Shippo. The link you've posted is actually the Rates response, not the Transaction (it's an array of many Rates, thus the length).
I've quickly checked your account and for your most recent transaction attempts, there's an error message "Rate can't be purchased because the Shippo account doesn't have valid billing settings.". This is because your Shippo user account doesn't have any credit card information, but you're trying to purchase labels in production.
You can enter a valid credit card here https://goshippo.com/user/billing/. The request should work fine as soon as your credit card has been saved!
Let me know if you have any further questions, always happy to help!
I'm trying to fetch 1000+ Twitter users from my database using this API call. However, Twitter lookup only allows 100 users per call, so how can I do it with 10 calls?
If I have 2232 users in my DB and I want to do a lookup on all users and get their details how to do it? Something which will count all the users being searched, break it into array of 100 elements, make the call for 100, and add the response back to database and then move onto the next 100.
I am using the tmhOAuth library for Twitter.
EDITED:
I was able to accomplish it using this code , but my next question is how can i bind those values back to my account ? because the screen_name is a entry and not the KEY of the array, so how can i do it ?
$accounts = $this->accounts->getAll();
$accounts_chunk = array_chunk($accounts,100);
foreach($accounts_chunk as $accounts){
$screen_names = "";
$last_key = end(array_keys($accounts));
foreach($accounts as $k => $account){
$screen_names .= $account->screen_name;
if($last_key == $k){
$screen_names .= "";
} else {
$screen_names .= ",";
}
}
$code = $this->twitter->request('GET', $this->twitter->url("1/users/lookup"),array('screen_name' => $screen_names));
echo "<pre>";print_r(json_decode($this->twitter->response));echo "</pre>";
}
But how to update values in DB using this .. i did a check but the sequence of the responses always changes so cannot use the current keys ..
You could loop through the max number of users and every hundredth time loop through hundred users and do your Twitter-magic there.
$iNumUsers = 2232; // or a mysql_num_rows-like result;
for($i = 0; $i < $iNumUsers; $i++) {
if($i % 100 == 0) {
for($j = $i; $j < 100; $j++) {
// your twitter-code here
}
}
}
Hi here are some simple steps to do this task
1: Get screen names from your db with limit of 100
2: impload with comma (join them with comma)
3: Send these 100 to users/lookup call and get data
4: (important) IF YOU RECEIVE AN ERROR OF "Rate limit exceeded" THEN USE PROXY
proxy will give you another chance to make next call of 100 users
5: decode json and send data to db
(important) if you use user's id instead of screen name then it will be easy to update db
Still have problem shout a comment here
The Twitter API says
You are strongly encouraged to use a POST for larger requests.
So try posting your 2,000 IDs to them.
With regards to the second part of your question
the sequence of the responses always changes so cannot use the current keys ..
Start with your array of user IDd - $ids
Get the response from Twitter as $tl
// Place the users into an array
$sortedUsers = array();
foreach ($tl as $user) {
$user_id = $user->id;
// $tl is *unsorted* - but $ids is *sorted*. So we place the users from $tl into a new array based on how they're sorted in $ids
$key = array_search($user_id, $ids);
$sortedUsers[$key] = $user;
}
// Sort the array by key so the most recent is at the top
ksort($sortedUsers);