xero api failing to add tracking on purchase order - xero-api

When I add tracking to invoices or credit notes via the api it works fine. but when i try to add it on purchase order it fails and I cannot seem to get a clear error message out of it.
I am using accounting api https://xeroapi.github.io/xero-php-oauth2/docs/v2/accounting/index.html#api-Accounting-updatePurchaseOrder
Error I get is message: "[400] Client error: POST https://api.xero.com/api.xro/2.0/PurchaseOrders/42797164-58c9-483c-9af8-96165c31a26f` resulted in a 400 Bad Request response:\n{\r\n "ErrorNumber": 10,\r\n "Type": "ValidationException",\r\n "Message": "A validation exception occurred",\r\n "Elements" (truncated...)\n"
`
Code I am using to try set it after I have created the purchase order.
[$trackingCategoryId, $trackingOptionId] = $this->getTrackingCategoryByNameFromXero($projectName, 'Project');
$purchaseOrder = null;
$xeroTenantId = $this->xero_account->tenantId;
try {
$purchaseOrders = $this->accountingApi->getPurchaseOrder($xeroTenantId, $purchaseOrderId);
foreach ($purchaseOrders as $model) {
if ($model->getPurchaseOrderId() == $purchaseOrderId) {
$purchaseOrder = $model;
break;
}
}
} catch (Exception $e) {
echo 'Exception when calling AccountingApi->getPurchaseOrder: ', $e->getMessage(), PHP_EOL;
}
if ($purchaseOrder instanceof PurchaseOrder) {
$lineItems = $purchaseOrder->getLineItems();
foreach ($lineItems as $lineItem) {
$tc = new LineItemTracking();
$tc->setTrackingCategoryId($trackingCategoryId);
$tc->setTrackingOptionId($trackingOptionId);
$lineItem->setTracking([$tc]);
$lineItems[] = $lineItem;
}
$purchaseOrder->setLineItems($lineItems);
$purchaseOrders = new PurchaseOrders();
$arr_purchase_orders[] = $purchaseOrder;
$purchaseOrders->setPurchaseOrders($arr_purchase_orders);
$summarizeErrors = true;
try {
$x = $this->accountingApi->updatePurchaseOrder(
$this->xero_account->tenantId,
$purchaseOrderId,
$purchaseOrders
);
} catch (\ApiException $e) {
print_r($e->getMessage());die;
}
}

Related

Facebook api returns : (#120) Invalid album id when trying to post to a group

When I try to post a photo in a group through the API I get an error, the post happens, but without the photo.
I've seen people say it's a bug on Facebook and it happens when there's a question mark (?).
However in my post there is no question mark, does anyone know what it could be?
The error i get is: (#120) Invalid album id
Example:
I am using Facebook SDK for PHP like this, and i have a custom method, like this.
public function postPhoto(string $message, string $img_path, string $page, string $id='me')
{
$photoData = [
'message' => $message,
'source' => $this->fb->fileToUpload($img_path),
];
$this->pageAccessToken = $this->getTokenForPage($page);
try {
$response = $this->fb->post("/$id/photos", $photoData, $this->pageAccessToken);
$graphNode = $response->getGraphNode();
$this->post_id = $graphNode['id'];
} catch (FacebookResponseException $e) {
$this->error = $e->getMessage();
return false;
} catch (FacebookSDKException $e) {
$this->error = $e->getMessage();
return false;
}
}

Display backend error message after Create call

In my controller I have the following code - The problem is when it is error, I want to display exact error that is being passed from backend. But in my error handling function I never get any data. What is wrong here?
Controller.js
var token = null;
$.ajax({
url: sServiceURl,
type: "GET",
async: true,
beforeSend: function(xhr) {
sap.ui.core.BusyIndicator.show(0);
xhr.setRequestHeader("X-CSRF-Token", "Fetch");
},
complete: function(xhr) {
token = xhr.getResponseHeader("X-CSRF-Token");
oContext.OdataModel.create("/materialsSet", oContext.Data, null, oContext.submitSuccess.bind(oContext), oContext.submitError.bind(oContext));
}
});
submitSuccess: function(data, response, oContext) {
// works fine
},
submitError: function(oError) {
// I never get anything in oError, so the below code is useless.
try {
if (oError.responseText) {
obj = JSON.parse(oError.responseText);
message = obj.error.message.value;
} else if (oError.response.body) {
var errorModel = new sap.ui.model.xml.XMLModel();
errorModel.setXML(oError.response.body);
//Read message node
if (errorModel.getProperty("/0/message") !== "") {
message = errorModel.getProperty("/0/message");
} else {
message = message1;
}
} else {
message = message1;
}
} catch (error) {
message = message1;
}
sap.m.MessageToast.show(message);
},
Hope this will help you, first of all check backend response. I have use the below code for error handling.
submitError: function(responseBody) {
try {
var body = JSON.parse(responseBody);
var errorDetails = body.error.innererror.errordetails;
if (errorDetails) {
if (errorDetails.length > 0) {
for (i = 0; i < errorDetails.length; i++) {
console.log(errorDetails[i].message);
}
} else
console.log(body.error.message.value);
} else
console.log(body.error.message.value);
} catch (err) {
try {
//the error is in xml format. Technical error by framework
switch (typeof responseBody) {
case "string": // XML or simple text
if (responseBody.indexOf("<?xml") > -1) {
var oXML = jQuery.parseXML(responseBody);
var oXMLMsg = oXML.querySelector("message");
if (oXMLMsg)
console.log(oXMLMsg.textContent);
} else
console.log(responseBody);
break;
case "object": // Exception
console.log(responseBody.toString());
break;
}
} catch (err) {
console.log("common error message");
}
}
}

Interactive button doesn't work properly when using pub/sub

I'm writing a Hangouts Chat bot in C# that uses pub/sub so I can host the bot on our side of a firewall. Everything seems to work well except interactive buttons within cards. If I create a button with a specific action method name, the bot does receive the CARD_CLICKED message with the appropriate action method name. However, it doesn't seem like the card in the Hangouts Chat app knows a response was sent because the bot ends up getting the CARD_CLICKED message three times before the Hangouts Chat app finally says "Unable to contact Bot. Try again later". I've been using the Google.Apis.HangoutsChat.v1 and Google.Cloud.PubSub.V1 packages from NuGet for the bot.
This is speculation, but it seems like the issue might be that interactive buttons don't work properly through pub/sub. Any help would be appreciated.
Here is a snippet of the code I have:
SubscriptionName subscriptionName = new SubscriptionName(PROJECT_ID, SUBSCRIPTION_ID);
SubscriberServiceApiClient client = SubscriberServiceApiClient.Create();
GoogleCredential credential = GoogleCredential.FromFile(CREDENTIALS_PATH_ENV_PROPERTY).CreateScoped(HANGOUTS_CHAT_API_SCOPE);
HangoutsChatService chatService = new HangoutsChatService(new BaseClientService.Initializer
{
ApplicationName = "My Bot",
HttpClientInitializer = credential
});
while (true)
{
PullResponse response = client.Pull(subscriptionName, false, 3, CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.FromTimeout(TimeSpan.FromSeconds(90)))));
if ((response.ReceivedMessages == null) || (response.ReceivedMessages.Count == 0))
Console.WriteLine("Pulled no messages.");
else
{
foreach (ReceivedMessage message in response.ReceivedMessages)
{
try
{
byte[] jsonBytes = message.Message.Data.ToByteArray();
JObject json = JObject.Parse(Encoding.UTF8.GetString(jsonBytes));
string messageType = (string)json["type"];
switch (messageType)
{
case "MESSAGE":
{
// Get text
string messageText = (string)json["message"]["text"];
Console.WriteLine($"[{messageType}] {messageText}");
// Send response
string spaceName = (string)json["space"]["name"];
SpacesResource.MessagesResource.CreateRequest request = chatService.Spaces.Messages.Create(new Message
{
Cards = new[]
{
new Card
{
Header = new CardHeader
{
Title = "Message Received!"
},
Sections = new[]
{
new Section
{
Widgets = new[]
{
new WidgetMarkup
{
Buttons = new[]
{
new Button
{
TextButton = new TextButton
{
Text = "Click Me!",
OnClick = new OnClick
{
Action = new FormAction
{
ActionMethodName = "ClickedAction"
}
}
}
}
}
}
}
}
}
}
},
Thread = new Thread
{
Name = (string)json["message"]["thread"]["name"]
}
}, spaceName);
Message responseMsg = request.Execute();
break;
}
case "CARD_CLICKED":
{
string actionMethodName = (string)json["action"]["actionMethodName"];
Console.WriteLine($"[{messageType}] {actionMethodName} at {((DateTime)json["message"]["createTime"]).ToString()}");
// Send response
string spaceName = (string)json["space"]["name"];
SpacesResource.MessagesResource.CreateRequest request = chatService.Spaces.Messages.Create(new Message
{
ActionResponse = new ActionResponse
{
Type = "UPDATE_MESSAGE"
},
Text = $"You clicked on '{actionMethodName}'.",
Thread = new Thread
{
Name = (string)json["message"]["thread"]["name"]
}
}, spaceName);
Message responseMsg = request.Execute();
break;
}
default:
{
Console.WriteLine($"[{messageType}]");
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error parsing message: {ex}");
}
}
// Acknowledge the message so we don't see it again.
string[] ackIds = new string[response.ReceivedMessages.Count];
for (int i = 0; i < response.ReceivedMessages.Count; ++i)
ackIds[i] = response.ReceivedMessages[i].AckId;
client.Acknowledge(subscriptionName, ackIds);
}
}
Using buttons with Hangouts Chat API requires a custom answer including:
{
'thread': {
'name': thread_id
},
'actionResponse': {
'type': 'UPDATE_MESSAGE'
}
}
I'd recommend using Hangouts Chat API with a bot URL.

Adding a specific price in the cart

I would like to add a specific price for certain products in the cart. Currently I achieved that in one shop, but not in the other. I was able to add a specific price to a certain product (attribute) in the cart. I have this code that does the adding part:
foreach ($prices as $product) {
$specific_price = new SpecificPrice;
$specific_price->id_product = $product['id_product'];
$specific_price->id_product_attribute = $product['id_product_attribute'];
$specific_price->id_cart = (int)$params['cart']->id;
$specific_price->id_shop = $this->context->shop->id;
$specific_price->id_shop_group = $this->context->shop->id_shop_group;
$specific_price->id_country = $this->context->country->id;
$specific_price->id_currency = $this->context->currency->id;
$specific_price->id_group = $this->context->customer->id_default_group;
$specific_price->id_customer = $this->context->customer->id ? $this->context->customer->id : NULL;
$specific_price->from_quantity = 0;
$m2 = $product['m2'] < 0 ? 1 : round($product['m2']);
$specific_price->price = Tools::ps_round($product['price'] * $m2 / $product['quantity'], 6);
$specific_price->reduction_type = 'amount';
$specific_price->reduction_tax = 1;
$specific_price->reduction = 0;
$specific_price->from = date('Y-m-d H:i:s');
$specific_price->to = '0000-00-00 00:00:00';
try {
$specific_price->add(true);
} catch (Exception $e) {
Logger::addLog(sprintf('[%s] %s, line %d', $this->name, $e->getMessage(), __LINE__));
echo $e->getMessage();
if ($e->getCode() == 0) {
try {
$specific_price->update(true);
} catch (Exception $e) {
Logger::addLog(sprintf('[%s] %s, line %d', $this->name, $e->getMessage(), __LINE__ ));
echo $e->getMessage();
}
}
}
}
In id_shop 1 it works, but in the other shop id_shop 2 it doesn't. I'm cracking my head for hours on this. I've been clean cache everywhere possible, restart XAMPP, check http.conf for clues.
I have disabled id_customer as being required. Because I want to price to be saved for visitors/guests too.

Gmail API get list "An error occurred: { "error": "invalid_grant", "error_description": "Bad Request" } " in PHP

I am trying to get mail list using php library. It was working before , but now it show the following error :
An error occurred: { "error": "invalid_grant", "error_description":
"Bad Request" }
array(0) { }
Code:
function getList($lastsynctime='') {
// Get the API client and construct the service object.
$client = $this->getClient();
$service = new Google_Service_Gmail($client);
// $newTime = strtotime('-15 minutes');
if ($lastsynctime =='') {
$newTime = strtotime('-60 day');
$after = strtotime(date('Y-m-d H:i:s', $newTime));
}else{
$after = strtotime($lastsynctime);
}
// Print the labels in the user's account.
$userId = 'me';
$pageToken = NULL;
$messages = array();
$opt_param = array();
do {
try {
if ($pageToken) {
$opt_param['pageToken'] = $pageToken;
}
$opt_param['q'] = "from:example#gmail.com after:$after";
$messagesResponse = $service->users_messages->listUsersMessages($userId, $opt_param);
echo "<pre>";var_dump($messagesResponse);
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
} while ($pageToken);
return $messagesResponse;
}
Well! As your code was working before and you haven't change anything. Then i think the problem is not in you code.
You can check your Connected apps and sites settings under your gmail My Account menu to make sure your app is there.
If the app is there but yet not working then you need to delete the app and regenerate your client secret key. Because your client secret may get expired.
I got this error in different API (Google Search Console).
Try visiting https://myaccount.google.com/security#connectedapps from your Gmail account.
See if Drive Testing Key shows up under Apps with account access. If it doesn't, then as #Mahbubul Islam mentioned, you'll need to create the credentials again.