Postcode api and internet issues

Just a quick question; with the postcode api script is there a way of telling it to bypass the check if the internet is not working?

We are on mobile broadband ao it does have its moments -

Currently if it fails to get the postcode data it freezes Sambapos and we have to restart.

It’s probably something I can add to the script but don’t know what sort of function I need to be looking for.

Thanks

Robbie

You may notice a momentary freeze, like 1 second or less, but then it should continue.

Have you modified the script?

When the internet connection is stable, there is a slight lag for a second while it runs the script and inserts the values into the fields as expected; the issue is when there is not an internet connection (or if its unstable and cannot connect to google) it freezes and samba waits for the script to respond (which it doesn’t - at least until we reset the internet router).

May go backwards slightly and use a local database of postcodes, until we can get a permanent internet connection sorted.

I have many customers who for whatever reason do not have always on internet connection or no internet connection at their shop in the UK and nobody has ever reported this issue to me. They also use customers with postcode and the postcode API setup is on their system. I am sure I would have heard about this multiple times had there been an issue here.

As I was curious to what you were reporting, I just tested it myself and, as expected, it works fine without internet - there is at most a 1 second delay then it just goes back to not returning any results.

See below video I took just now - I disconnected the internet by removing the ethernet cable, this system does not have wifi.

So my questions I would ask is:

  • Are you using the latest version of SambaPOS (v5.3.0)?
  • Have you modified the postcode API setup in any way?
  • Are you using any software or service that might interfere with how windows determines it has no internet access? (e.g. VPN software, internet security software that uses a proxy server, etc.)?
  • What version of Windows are you using? I tested this on Windows 10 IoT, however would expect the same on any edition of Windows 10 (Home, Pro, etc.).
2 Likes

Hi Mark,

latest version of Samba yep, but have edited the script to pull distance data and travel time - so this is likely the issue. Am in process of trying the script in its unedited form to confirm.

Attached my edited script just for you to have a gander :upside_down_face:

function Read(postcode)
{
   var YOUR_API_KEY = 'MY KEY HERE';
   var country = 'GB';
   var urlfmt = 'https://maps.googleapis.com/maps/api/geocode/json?key='+ YOUR_API_KEY + '&components=postal_code:' + postcode;

   if(country != undefined) 
     urlfmt += '|country:'+country;
   var content = web.Download(urlfmt);
   var obj = JSON.parse(content);
   var lat = obj.results[0].geometry.location.lat;
   var lng = obj.results[0].geometry.location.lng;

   var addrurl = 'https://maps.googleapis.com/maps/api/geocode/json?key=' + YOUR_API_KEY + '&latlng=' + lat + ',' + lng + '&sensor=false';

   var addr = web.Download(addrurl);
   var addrObject = JSON.parse(addr);

   var data = GetAddressComponents(addrObject.results,postcode);
   if(data == null) return postcode;

   var street = ReadComponent('route',data);
   if(street == '-')
     street = ReadComponent('locality',data);
   if(street == '-')
     street = ReadComponent('administrative_area_level_4',data);
   var town = ReadComponent('postal_town',data);
   var distance = gdistance(postcode);

   return postcode + ',' + street + ',' + town + ',' + distance;
}

function GetAddressComponents(results,postcode)
{
    for(i=0;i < results.length;i++)
    {
       for(j=0; j< results[i].address_components.length;j++)
       {
         var component = results[i].address_components[j];
         if(component.long_name.replace(' ','') == postcode.replace(' ',''))
           return results[i].address_components;
       }
    }
    return null;
}

function ReadComponent(name,components)
{
   for(i=0;i<components.length;i++)
   {
      var component = components[i];
      
      for(j=0;j<component.types.length;j++)
      {
         if(component.types[j] == name)
           return component.long_name;
      } 
   }
   
   return '-';
}

function gdistance(postcode)

{

var YOUR_API_KEY = 'MY API KEY';

var u = 'https://maps.googleapis.com/maps/api/distancematrix/json?key='+ YOUR_API_KEY +'&origins=NP201FU.&destinations=' + postcode + '.&mode=driving&language=en-GB&sensor=false&units=metric';

var alldata = web.Download(u);

var json = JSON.parse(alldata);

var distance = json.rows[0].elements[0].distance.value/1000;

var time = json.rows[0].elements[0].duration.text;

return distance + ',' + time;

}

I can see now that there’s no scipting for a null return on the distance bit I’ve added

maybe something like

if(alldata == null) return 'no data';

or something like that… am at work so guessing haha

Would have expected the parse to throw an error on null as not valid json but wouldnt heart and good practice to control all outcomes.

if(qryKHRexists == true && qryCNYexists == true && qryEURexists == true)
{
	dlg.ShowMessage("Fetching USD rates...")
	var nL = "<linebreak/>";
	var apikey = "#################";
	var base = "USD";
	var symbol1 = "KHR";
	var symbol2 = "CNY";
	var symbol3 = "EUR";
	
	// CALL TO FIXER API LATEST END POINT
	
	var u = "http://data.fixer.io/api/latest?access_key="+apikey+"&base="+base+"&symbols="+symbol1+","+symbol2+","+symbol3+"";
	var getrates = web.Download(u);
	
	// IF DOWNLOAD SUCCESSFUL CREATE JSON OBJECT
		if(getrates)
        {
   
            var allrates = JSON.parse(getrates);
            var currentdate = allrates.date;
            var rate1 = allrates.rates.KHR;
            var rate2 = allrates.rates.CNY;
            var rate3 = allrates.rates.EUR;
            	

            	if(allrates.success)
            	{	
            		dlg.ShowMessage("Success!\rUSD rates updated.")
            		var KHRupdate = "UPDATE [ProgramSettingValues] SET [VALUE] ="+rate1+" WHERE [Name] = 'KHR'";
            		sql.ExecSql(KHRupdate);
            		
            		var CNYupdate = "UPDATE [ProgramSettingValues] SET [VALUE] ="+rate2+" WHERE [Name] = 'CNY'";
            		sql.ExecSql(CNYupdate);
            		
            		var EURupdate = "UPDATE [ProgramSettingValues] SET [VALUE] ="+rate3+" WHERE [Name] = 'EUR'";
            		sql.ExecSql(EURupdate);
            		
            		var valueKHR = sql.Query("SELECT [VALUE] FROM dbo.[ProgramSettingValues] WHERE [NAME] = 'KHR'").First;
					var valueCNY = sql.Query("SELECT [VALUE] FROM dbo.[ProgramSettingValues] WHERE [NAME] = 'CNY'").First;
					var valueEUR = sql.Query("SELECT [VALUE] FROM dbo.[ProgramSettingValues] WHERE [NAME] = 'EUR'").First;
            		
                	return tag.Size(25,'<color White> '+base+' 1 = '+symbol1+' '+valueKHR+' </color>')
                	+ nL + tag.Size(25,'<color White> '+base+' 1 = '+symbol2+' '+valueCNY+' </color>')
                	+ nL + tag.Size(25,'<color White> '+base+' 1 = '+symbol3+' '+valueEUR+' </color>');
        		}
        }

Something like this