Search Shipping Item in Netsuite API - php

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());

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 .

How to get BACS account details in Woocommerce using API?

I already done with https://acp.sample.ph/wc/v3/order created in PHP but the response of the API doesn't show the bank/account details for Bank account transfer (BACS). I am using the package automattic/woocommerce for fetching the API. This API I fetch is from WordPress woocommerce. Here's my sample code below.
$woocommerce = new Client(
'https://acp.sample.ph',
$credential['key'],
$credential['secrete'],
[
'wp_api' => true,
'version' => 'wc/v3',
'query_string_auth' => true
]
);
$data = array(
"order_id"=>"717",
"payment_method"=>"bacs"
);
$accounts = $woocommerce->post('process_payment', $data);
echo '<pre>';
print_r($accounts);
echo '</pre>';
You might need to create own endpoint or alter the Order API response
Can you try this ---
function prefix_wc_rest_prepare_order_object( $response, $object, $request ) {
// Get the value
$bacs_info = get_option( 'woocommerce_bacs_accounts');
$response->data['bacs_info'] = $bacs_info;
return $response;
}
add_filter( 'woocommerce_rest_prepare_shop_order_object', 'prefix_wc_rest_prepare_order_object', 10, 3 );

How to initialize a POST and a PUT method from inside a Wordpress custom endpoint

I am creating a custom endpoint in wordpress, which should do the following:
1. Create the path (done)
2. call a function, which:
2.1. Gets all the products from WooCommerce and stores them in an array (done)
2.2. Compares the products on WooCommerce with products from an external database and if there is any difference in data, get updated (PUT) by the data from the external DB
2.3. If some products exist on the external DB but do not exist on WooCommerce, create them on WooCommerce (POST)
I have managed to get all the data from WooCommerce via wc_get_products ($args) but I cannot find how to write the PUT and the POST method to update or create products.
If I use Automatic/WooCommerce to push or put products from a standalone file (not from the custom endpoint) works, but if I keep the Automatic/WooCommerce on the custom endpoint it tells me the following:
Failed to connect to localhost port 8000: Connection refused in /var/www/html/wp-content/plugins/wl-api/vendor/automattic/woocommerce/src/WooCommerce/HttpClient/HttpClient.php on line 417
which makes total sense because from the custom endpoint I am already connected to WooCommerce and the Automatic/WooCommerce would attempt to connect again. So are there any methods like wc_get_products but for PUT and PUSH?
//CUSTOM ENDPOINT PHP FILE
add_action('rest_api_init', 'customEndpoint');
function customEndpoint() {
register_rest_route('endpoint', '/transfer', array(
'methods' => 'GET',
'callback' => 'get_data',
));
}
function get_data() {
include "updateOrCreate.php";
}
//updateOrCreate.php
require 'vendor/autoload.php';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require 'vendor/guzzlehttp/guzzle/src/Client.php';
use Automattic\WooCommerce;
//-----------Connect to the External DB----------
$baseUrl=...;
$externalClient = new GuzzleHttp\Client();
$res = $externalClient->request('GET', $baseUrl, [
"query" => ['fields' => $fields, 'aktiv' => true],
'auth' => ['...', '...']
]);
$articles = json_decode($res->getBody());
//-----------Connect to WooCommerce DB
$wooKey= "...";
$wooSecret= "...";
$wooCommerceBaseUrl = "http://localhost:8000";
$wooCommerceClient = new WooCommerce\Client($wooCommerceBaseUrl,
$wooKey, $wooSecret,
[
'wp_api' => true,
'version' => 'wc/v3',
]
);
//GET all products from WooCommerce
$args = array(
'status' => 'publish',
'limit' => -1,
);
$wooExistingProducts = wc_get_products($args);
$productsForWoo= [];
//check if there are no products on woocommerce:
if(empty($wooExistingProducts)){
foreach ($articles as &$article){
//Create the necessary template to initialize the connections between external products and woocommerce product template
$wooTemplate = [
...
];
array_push($productsForWoo, $wooTemplate);
//CREATE BATCHES OF 10
if(sizeof($productsForWoo) == 10){
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
$productsForWoo = [];
}
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
}
// if there are existing products on woocommerce
else{
//Loop through all existing products on the external DB
foreach ($articles as &$article){
$did_match = false;
$wooTemplate = [
...
];
//loop through all products on WooCommerce
foreach ($wooExistingProducts as &$product){
//if the product id from the external db matches the id from an existing product on woocommerce
if(...){
//update that product
$wooCommerceClient->put('products/'.urlencode($product->id), $wooTemplate);
$did_match = true;
break;
}
}
//otherwise, if the product from the external db is not found on the woocommerce database, create it
if(!$did_match){
array_push($productsForWoo, $wooTemplate);
if(sizeof($productsForWoo) == 10){
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
$productsForWoo = [];
}
}
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
}
I will deeply appreciate any input related to my issue. Thank you!
To get POST and PUT, you'll need to implement the methods (verbs).
You can use:
$verb = $_SERVER['REQUEST_METHOD'];
echo $verb;
... to test what HTTP request method (PUT vs GET) you're using.
Here's a SO article regarding PHP methods which I have bookmarked and often use when troubleshooting this. The code provided there is pretty clean and a great place to start.

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

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!

Magento: Store, Store view, Website in transaction

I have small problem about store, store view and website creation. I create the store on the customer register (one customer has one website, one store view and one store), all is ok, but when there is an error in saving for example store view, other elements in the DB.
The code:
// Root Category
$category = new Mage_Catalog_Model_Category();
$category->setStoreId(0);
$category->save();
// Website
$website = new Mage_Core_Model_Website();
$website->setData(array(
'code' => $codes,
'sort_order' => 10
))->save();
// Create store group (store view)
$storeGroup = new Mage_Core_Model_Store_Group();
$storeGroup->setData(array(
'website_id' => $website->getId(),
'root_category_id' => $category->getId()
))->save();
// Create store
$store = new Mage_Core_Model_Store();
$store->setData(array(
'code' => $codes,
'website_id' => $website->getId(),
'group_id' => $storeGroup->getId(),
));
$store->save();
I need to edit the code so this things will create in transaction and rollback if there is an error. I don't know how to do this, because I need an id after each object save.
ok, solved myself
try {
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
$write->beginTransaction();
$category = Mage::getModel('catalog/category')
->setStoreId(0)
->setName($code)
->setParentId(Mage_Catalog_Model_Category::TREE_ROOT_ID)
->setPath(Mage_Catalog_Model_Category::TREE_ROOT_ID)
->setDisplayMode(Mage_Catalog_Model_Category::DM_PRODUCT)
->setIsActive(TRUE)
->setId(NULL)
->save();
$website = Mage::getModel('core/website')
->setCode($code)
->setName($code)
->setSortOrder(10)
->setId(NULL)
->save();
$storegr = Mage::getModel('core/store_group')
->setWebsiteId($website->getId())
->setName($code)
->setRootCategoryId($category->getId())
->setId(NULL)
->save();
$store = Mage::getModel('core/store')
->setCode('1'.$code)
->setWebsiteId($website->getId())
->setGroupId($storegr->getId())
->setName($code)
->setSortOrder(10)
->setIsActive(TRUE)
->setId(NULL)
->save();
$write->commit();
} catch (Exception $e) {
$write->rollback();
}

Categories