Importing product prices into VtigerCRM via web services - web-services

I'm using vtwsclib – vtiger CRM Web Services Client Library version 1.4
and everything is working fine beside the import of prices.
The code:
$module = 'Products';
$record = $clientCrm->doCreate
(
$module,
Array
(
'productname' => $sItemName,
'cf_753' => $sSku,
'discontinued' => 1,
'description' => $sDescription,
'unit_price' => $sPrice,
)
);
Now I tried to set $sPrice everything like:
$sPrice = '5';
$sPrice = "5";
$sPrice = 5;
$sPrice = 5.0;
$sPrice = (float) '5';
$sPrice = floatval ('5');
At every single import my price is 500 - not 5.
So my question: How do I need to format my price that it stays 5 after the import into Vtiger (6.4)?

Figured it out.
In the settings of the user by default it seems like the entry:
Decimal Separator and Digit Grouping Separator have both been set to ..
I changed the Digit Grouping one to , and now it's working.

Related

softlayer API : Get OS version list?

Now I'm developing a project about softlayer api. I wan't to get the os list by softlayer api. Just like the portal site. Is there certain method to get correct os list ? regards~
Is there a specific language example you are looking for? If you use the SoftLayer CLI you can do this with the following command
slcli vs create-options # For Virtual Guests
slcli server create-options # For Bare Metal Servers
Unfortunately, it's not possible to retrieve the same result than Control Portal making a single call, but it's possible using a programming language.
To see programming languages supported by SoftLayer:
SoftLayer Development Network
Take a look the following python script:
"""
List OSs for VSI similar than Portal
See below references for more details.
Important manual pages:
http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getItemPrices
http://sldn.softlayer.com/article/object-filters
http://sldn.softlayer.com/article/object-Masks
#License: http://sldn.softlayer.com/article/License
#Author: SoftLayer Technologies, Inc. <sldn#softlayer.com>
"""
import SoftLayer
import datetime
import time
# Your SoftLayer's username and api Key
USERNAME = 'set me'
API_KEY = 'set me'
# Package id
packageId = 46
# Datacenter
datacenter = 'wdc04'
# Computing INstance
core = '1 x 2.0 GHz Core'
# Creating service
client = SoftLayer.Client(username=USERNAME, api_key=API_KEY)
packageService = client['SoftLayer_Product_Package']
# Declaring filters and mask to get additional information for items
filterDatacenter = {"itemPrices": {"pricingLocationGroup": {"locations": {"name": {"operation": datacenter}}}}}
objectMaskDatacenter = 'mask[pricingLocationGroup[locations]]'
objectMask = 'mask[pricingLocationGroup[locations],categories,item[id, description, capacity,softwareDescription[manufacturer],availabilityAttributeCount, availabilityAttributes[attributeType]]]'
filterInstance = {
'itemPrices': {
'categories': {
'categoryCode': {
'operation': 'os'
}
}
}
}
# Define a variable to get capacity
coreCapacity = 0
# To get item id information
itemId = 0
flag = False
# Define the manufacturers from which you like to get information
manufacturers = ["CentOS", "CloudLinux", "CoreOS", "Debian", "Microsoft", "Redhat", "Ubuntu"]
# Declare time to avoid list OS expired
now = time.strftime("%m/%d/%Y")
nowTime = time.mktime(datetime.datetime.strptime(now, "%m/%d/%Y").timetuple())
try:
conflicts = packageService.getItemConflicts(id=packageId)
itemPrices = packageService.getItemPrices(id=packageId, filter=filterDatacenter, mask=objectMask)
if len(itemPrices) == 0:
filterDatacenter = {"itemPrices":{"locationGroupId":{"operation":"is null"}}}
itemPrices = packageService.getItemPrices(id=packageId, filter=filterDatacenter, mask=objectMask)
for itemPrice in itemPrices:
if itemPrice['item']['description'] == core:
itemId = itemPrice['item']['id']
coreCapacity = itemPrice['item']['capacity']
result = packageService.getItemPrices(id=packageId, mask=objectMask, filter=filterInstance)
filtered_os = []
for item in result:
for attribute in item['item']['availabilityAttributes']:
expireTime = time.mktime(datetime.datetime.strptime(attribute['value'], "%m/%d/%Y").timetuple())
if ((attribute['attributeType']['keyName'] == 'UNAVAILABLE_AFTER_DATE_NEW_ORDERS') and (expireTime >= nowTime)):
filtered_os.append(item)
if item['item']['availabilityAttributeCount'] == 0:
filtered_os.append(item)
for manufacturer in manufacturers:
print(manufacturer)
for itemOs in filtered_os:
for conflict in conflicts:
if (((itemOs['item']['id'] == conflict['itemId']) and (itemId == conflict['resourceTableId'])) or ((itemId == conflict['itemId']) and (itemOs['item']['id'] == conflict['resourceTableId']))):
flag = False
break
else:
flag = True
if flag:
if itemOs['item']['softwareDescription']['manufacturer'] == manufacturer:
if 'capacityRestrictionMinimum' in itemOs:
if((itemOs['capacityRestrictionMinimum'] <= coreCapacity) and (coreCapacity <= itemOs['capacityRestrictionMaximum'])):
print("%s Price Id: %s Item Id: %s" % (itemOs['item']['description'], itemOs['id'], itemOs['item']['id']))
else:
print("%s Price Id: %s Item Id: %s" % (itemOs['item']['description'], itemOs['id'], itemOs['item']['id']))
print("---------------------------------------------------")
except SoftLayer.SoftLayerAPIError as e:
print('Unable to get Item Prices faultCode=%s, faultString=%s'
% (e.faultCode, e.faultString))
I added core variable, because the OSs have restriction for capacity of cores. Also I added datecenter to get the specific core item price for a specifc datacenter, perhaps it's something innecesary, but you can edit this script according your requirements.
The same idea could be applied for others programming languges.
I hope it helps, please let me know any doubt, comments or if you need further assistance.
Updated
I improved the script, I added the ability to check conflicts between items, in order to get the same result for each kind of Computing Instance

How can a Spotfire data table be sent to a web service as csv and then replace the data table with the service response?

I need to send my Spotfire data table to a web service as csv and then replace the data table with the service response. I assume that this can be done with IronPython behind a button. Any ideas how?
I have addressed the similar problem but I was using different approach than the proposed IronPython script behind a button.
In my case I created a standalone C#/ASP.NET web application and I have embedded the Spotfire Web Player into the application.
I used the Spotfire JavaScript API to pick up the data marked by user within the Spotfire Web embedded part and then send it via JavaScript call to webservice on the application. The webservice did some processing and sent the data to other destination.
So my scenario was a bitt different but for yours you would also consider using the approach to embedd Spotfire Web into some app that you have full control over rather than using the IronPython script.
This code answers the second part of your requirement but I think it also can be good starting point for the first one.
Add JSON or XML Data from a Web Service
XML example
import clr
clr.AddReference('System.Data')
import System
from System import DateTime
from System.Data import DataSet, DataTable, XmlReadMode
from System.IO import StringReader, StreamReader, StreamWriter, MemoryStream, SeekOrigin
from System.Net import HttpWebRequest
from Spotfire.Dxp.Data import DataType, DataTableSaveSettings
from Spotfire.Dxp.Data.Import import TextFileDataSource, TextDataReaderSettings
# get stock quotes data in XML format from Yahoo Finance API
tickerSymbol = Document.Properties["TickerSymbol"]
startDate = DateTime.Today.AddMonths(-3).ToString("yyyy-MM-dd")
endDate = DateTime.Today.ToString("yyyy-MM-dd")
uri = "http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.historicaldata where symbol = %22" + tickerSymbol + "%22 and startDate = %22" + startDate + "%22 and endDate = %22" + endDate + "%22&format=xml&diagnostics=true&env=store://datatables.org/alltableswithkeys"
webRequest = HttpWebRequest.Create(uri)
response = webRequest.GetResponse()
streamReader = StreamReader(response.GetResponseStream())
xmlData = streamReader.ReadToEnd()
stringReader = StringReader(xmlData)
# read desired data fields from XML into a DataSet
dataSet = DataSet()
dataTable = DataTable("quote")
dataTable.Columns.Add("Date", System.String)
dataTable.Columns.Add("Close", System.String)
dataSet.Tables.Add(dataTable)
dataSet.ReadXml(stringReader, XmlReadMode.IgnoreSchema)
# build a string representing the data in tab-delimited text format
textData = "Symbol\tDate\tClose\r\n"
for row in dataTable.Rows:
textData += tickerSymbol + "\t" + "\t".join(row.ItemArray) + "\r\n"
# make a stream from the string
stream = MemoryStream()
writer = StreamWriter(stream)
writer.Write(textData)
writer.Flush()
stream.Seek(0, SeekOrigin.Begin)
# set up the text data reader
readerSettings = TextDataReaderSettings()
readerSettings.Separator = "\t"
readerSettings.AddColumnNameRow(0)
readerSettings.SetDataType(0, DataType.String)
readerSettings.SetDataType(1, DataType.Date)
readerSettings.SetDataType(2, DataType.Currency)
# create a data source to read in the stream
textDataSource = TextFileDataSource(stream, readerSettings)
# add the data into a Data Table in Spotfire
if Document.Data.Tables.Contains("Stock Data"):
Document.Data.Tables["Stock Data"].ReplaceData(textDataSource)
else:
newTable = Document.Data.Tables.Add("Stock Data", textDataSource)
tableSettings = DataTableSaveSettings (newTable, False, False)
Document.Data.SaveSettings.DataTableSettings.Add(tableSettings)
JSON example
import clr
clr.AddReference('System.Data')
clr.AddReference('System.Web.Extensions')
import System
from System import DateTime
from System.Data import DataSet, DataTable
from System.IO import StreamReader, StreamWriter, MemoryStream, SeekOrigin
from System.Net import HttpWebRequest
from System.Web.Script.Serialization import JavaScriptSerializer
from Spotfire.Dxp.Data import DataType, DataTableSaveSettings
from Spotfire.Dxp.Data.Import import TextFileDataSource, TextDataReaderSettings
# get stock quotes data in JSON format from Yahoo Finance API
tickerSymbol = Document.Properties["TickerSymbol"]
startDate = DateTime.Today.AddMonths(-3).ToString("yyyy-MM-dd")
endDate = DateTime.Today.ToString("yyyy-MM-dd")
uri = "http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.historicaldata where symbol = %22" + tickerSymbol + "%22 and startDate = %22" + startDate + "%22 and endDate = %22" + endDate + "%22&format=json&diagnostics=true&env=store://datatables.org/alltableswithkeys"
webRequest = HttpWebRequest.Create(uri)
response = webRequest.GetResponse()
streamReader = StreamReader(response.GetResponseStream())
jsonData = streamReader.ReadToEnd()
js = JavaScriptSerializer()
dataDict = js.Deserialize(jsonData,object)
# build a string representing the data in tab-delimited text format
textData = "Symbol\tDate\tClose\r\n"
for quote in dataDict["query"]["results"]["quote"]:
textData += tickerSymbol + "\t" + quote["Date"] + "\t" + quote["Close"] + "\r\n"
# make a stream from the string
stream = MemoryStream()
writer = StreamWriter(stream)
writer.Write(textData)
writer.Flush()
stream.Seek(0, SeekOrigin.Begin)
# set up the text data reader
readerSettings = TextDataReaderSettings()
readerSettings.Separator = "\t"
readerSettings.AddColumnNameRow(0)
readerSettings.SetDataType(0, DataType.String)
readerSettings.SetDataType(1, DataType.Date)
readerSettings.SetDataType(2, DataType.Currency)
# create a data source to read in the stream
textDataSource = TextFileDataSource(stream, readerSettings)
# add the data into a Data Table in Spotfire
if Document.Data.Tables.Contains("Stock Data"):
Document.Data.Tables["Stock Data"].ReplaceData(textDataSource)
else:
newTable = Document.Data.Tables.Add("Stock Data", textDataSource)
tableSettings = DataTableSaveSettings (newTable, False, False)
Document.Data.SaveSettings.DataTableSettings.Add(tableSettings)
Source:
http://spotfired.blogspot.com/search?q=web+service
http://spotfire.tibco.com/tips/2014/03/03/streaming-xml-and-json-data-from-the-web-directly-into-spotfire-clients-using-script-controls/

Getting current cart ID in prestashop

I am busy with a site built on Code Igniter that needs integration with Prestashop. In the site, when creating a user account, I save a "shop_id" to the database, which is then retrieved as a session variable when logging in.
I am using the Prestashop API to retrieve the customer successfully (using above "shop_id")
$xml = $this->PSWebService->get(
array('resource' => 'customers', 'id' => (int)$this->user['shop_id'])
);
This successfully returns the user in question, but there is no Cart IDs in this result.
Logging in to the back-end of my shop, I see that there are multiple carts associated with the logged in user.
My question is: How to I retrieve the LATEST cart ID using the API?
$userId = (int) $this->user['shop_id'];
$opt['resource'] = 'carts';
$xml = $this->PSWebService->get($opt);
$carts = $xml->carts->children();
foreach ($carts as $cart) {
$cartIds[] = $cart['id'];
}
for ($i = count($cartIds) - 1; $i > -1; $i--) {
$opt['id'] = $cartIds[$i];
$xml = $this->PSWebService->get($opt);
//since cart ids are descending the first found will be the latest
if ($xml->cart->id_customer == $userId) {
$latestCartId = $cartIds[$i];
break;
}
}
Kind of late, but I struggled a bit with this same problem and found a way to do it just from query, based on yenshirak's tip (since cart ids are descending the first found will be the latest).
I query the API directly using postman like this:
get all carts:
GET webserver/api/carts
get cart for customer:
GET webserver/api/carts?filter[id_customer]=1
get the most recent:
GET webserver/api/carts?filter[id_customer]=1&sort=[id_DESC]&limit=1
for a pretty print, you can also add params:
display=full&output_format=JSON
You can do this in php, I have not tested if the syntax is correct, but based on documentation it looks something like this:
$opt = array(
'resource' => 'carts',
'filter[id_customer]' => '[1]',
'sort' => '[id_DESC]',
'limit' => '1'
);
$xml = $webService->get($opt);

Zend Framework : How to handle "No route matched the request" error?

In Bootstrap.php I have some custom routes using Zend_Controller_Router_Route_Regex.
Everything works fine except when user type in address bar a wrong link.
Ex :
http://mysite/en/1-some-article.html => This is a valid link that matches a ROUTE in Bootstrap.
But when user make a typo mistake like:
http://mysite/en/1-some-article.**html'** or http://mysite/en/1-some-article.**hhtml** , they are not match any ROUTE in Bootstrap, then Zend Framework throws an exception like : No route matched the request
Is there anyway to handle it, like redirecting to a custom page for "No matched routes"?
Any help will be appreciated. Thanks for advance!
Configuration (from comment below)
[production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
phpSettings.date.timezone = "Europe/London"
;includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = ""
;resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules = ""
autoloaderNamespaces.Fxml = "Mycms_"
autoloaderNamespaces.Fxml = "Fxml_"
To make use of the ErrorController, you need to set the front controller throwExceptions attribute to false. Put this in your [production] configuration section
resources.frontController.params.throwExceptions = 0
See http://framework.zend.com/manual/1.12/en/zend.controller.exceptions.html and http://framework.zend.com/manual/1.12/en/zend.controller.plugins.html#zend.controller.plugins.standard.errorhandler.fourohfour.
I mentioned this in the comments above but you seem to have missed it (you have displayExceptions set to false but not throwExceptions).

Problem with session managment

I have PHP application that contain three small applications. Each application have own users and they are unique for all system. I have problem with session management. When one user is logged in server.com/app1 and write server.com/app2 second application log in automaticaly with this user. But this user hasn't any rights on this application. In login page I do this:
$status = $user->status;
if($status != 4) {
$auth_key = session_encrypt($userdata, $passdata);
$SQL = "UPDATE customer SET auth_key = '$auth_key'
WHERE username = '$userdata' ";
$auth_query = mysql_db_query($db, $SQL);
setcookie("auth_key", $auth_key, time() + 60 * 60 * 24 * 7, "/app1", "server.com", false, true);
// Assign variables to session
session_regenerate_id(true);
$session_id = $user->id;
$session_username = $userdata;
$_SESSION['cid'] = $session_id;
$_SESSION['username'] = $session_username;
$_SESSION['status'] = $status;
$_SESSION['user_lastactive'] = time();
header("Location: index.php");
exit;
}
But this doesn't work. Can someone help me how to repair my sessions. Thanks :)
If I'm reading your question correctly, your problem is that your three apps are independent but are hosted on the same server/use the same php instance. This results in their using the same php session, and the latter gets filled up with inappropriate garbage.
You've several potential solutions:
The first and easiest is to prefix your sessions in the way or another, i.e. use $_SESSION['app1']['param'] or $_SESSION['app1_param'] rather than $_SESSION['param'].
Another, if you've php installed as cgi rather than as an Apache module, is to configure each individual apps' php.ini in such a way that they're no longer sharing their session_id (i.e. configure the session cookie name and/or path) nor storing the session data in the same location (which is somewhere in /tmp if I recall correctly).
If you would like your sessions to be handled independently by each app then it might be easier to just set the unique sessionid for each app in the cookie.
setcookie("auth_key", $auth_key, time() + 60 * 60 * 24 * 7, "/app1", "server.com", false, true);
setcookie("auth_key", $auth_key, time() + 60 * 60 * 24 * 7, "/app2", "server.com", false, true);
setcookie("auth_key", $auth_key, time() + 60 * 60 * 24 * 7, "/app3", "server.com", false, true);