Sunday, September 3, 2017

Sparkpost and Alpha Five - Fantastic

Date: September 3rd 2017.

Sparkpost and Alpha Five... 

Part One:
Okay, now that you have done lots of work in Alpha Five and you have many clients under your belt, you are thinking - "Hey how about mass email marketing.. sounds like its about time."
Yes it's about time.
I am assuming you have done text messaging via Twilio earlier and now ready for email stuff.

The first thing you need to do is to sign up with an email service provider.  There are few out there, but this is about Sparkpost.
So I am going to deal with that only.
Go to www.sparkpost.com and check it out. You can try for free or get started for free. I did get started for free.  They give you about 25000 emails per day, for me that is lots of emails. Once you get the hang of it then you can upgrade anytime you want. So, I would say sign up for free account. Nothing fancy, no money. Just free as in free.

Once you get signed up then you can send an email via their sandbox account but that is only good for 5 emails, pittance, because you need more than that to complete all testing.  So what can you do.
Well, as far as sparkpost is concerned from address a sending domain. So go to your dashboard and create a new shiny domain.  They need to verify you hold that account before you can send email via that address. When you create the domain it says unverified. In order to verify you will need do either of these two steps.  You can verify with SMTP relay, meaning they will send an email to postmaster or abuse @ your domain.com. So you should have one of those set in your website.  I had postmaster@....com and the email came to it and verified to start sending.  Or you can copy paste the DNS setting which according to them is better, but I did not lose anything by the email method. So do the way you like, but at the end your domain ( that is the from address ) needs to be verified.
Once verified, that account will say verified, ready for sending. Now you are halfway thru with sparkpost.

Next you need to generate an api key. 
Go to your dashboard and scroll down, it will indicate the progress. You have created sending domain and verified.  Next click on the manage api keys and generate a new api key. Now here is the important part. Once you close that window you cannot get that key back. so copy and paste it in at least two places with some kind of name that you can recognize and recall the api key..

Now you are almost there in sparkpost.
There are several ways to send emails with sparkpost and they give you example codes.
The example codes include cURL, NodeJs and C# among other languages. You can also send via SMTP_Relay, meaning using standard smtp open, send and close methods. I am going to talk about SMTP_Relay since it is the easiest of all. There is nothing fancy no need to work hard and just few lines of code you can send one or many emails as you want. But eventually I will try to master javascript way of doing things, but that is for down the road.

Next, we need to work on alpha to complete the rest of the stuff so we can send one or many emails we need.
That is for next week...
Stay tuned.

Sunday, July 10, 2016

Alphasoftware and AngularJS - part 4

Alphasoftware and AngularJS - part 4.


Date: July 10th 2016.

Good morning everyone.
Last week we built main menu successfully, today we will redirect to the contents of at least one page to show you the fundamentals how it is done.
If you remember hello gandhi post where I sent a http call to the alpha server which provided a message "hello gandhi" and angular js posted that message on the html page, we will be using the same method to get the data from alpha server.  The alpha server will query a mysql backend database and execute the query and fashion the output as json object.  And angular js will get the output to display, we will modify with bootstrap to look beautiful

So here is the xbasic code that runs in  alpha server to fetch the items from inventory table.

<%a5
Response.headers.set("Access-Control-Allow-Origin", "*")
dim cn as sql::Connection
dim result as l = .f.
dim args as sql::Arguments
dim rs as sql::ResultSet
dim msg as c
dim sqlSelect as c
result = cn.Open("::Name::alpha_blog")
if result then
sqlSelect = "SELECT id, brand, description, unit_price FROM inventory ORDER BY brand"
result = cn.Execute(sqlSelect)
if result then
rs = cn.ResultSet
msg = rs.ToJSONObjectSyntax()
msg = "{\"items\":["+strtran(msg,crlf(),",")+"]}"
msg = strtran(msg,"'","\"")
else
msg = "\"items\":([\"msg\" : \"unable to get records\"])"
end if
cn.Close()
else
msg = "\"items\":([\"msg\" : \"unable to get connection\"])"
end if
?msg
%>

As you can see the alpha a5w page contains nothing but xbasic code and puts out the data as json formatted data.  (I am using version 11 and in that version I do need to convert the json to format properly with double quotes).

So when a call to this a5w page happens alpha serves up the data to the call.
And now back in the angularJs to harvest the data and show it on the page.

If you remember in the app.js we had a route 
.when('/items', {
        templateUrl: 'partials/items.html',
        controller: 'itemsCtrl'
        })
that redirects to the items page and uses the itemsCtrl controller as content director.
Now we will build that controller.

'use strict';
var SERVER = "http://xx.xx.xx.xx:port/";

alphaBlog.controller('itemsCtrl', function($scope, $http) {
    $http.get(SERVER + "alpha_blog/itemsCallback.a5w")
            .success(function(response) {$scope.items = response.items;});
                             });

As you can see the response.items is now assigned to $scope.items.
If you just leave it alone you will see page full of items, not pleasing.  So now we are going to use angularJs directive ng-repeat to go thru each item an display nicely, something for n next n loop in alpha.
So replace the items.html to 
<div>
<h1>Items</h1>
    <table>
    <thead>
        <td>Brand</td>
        <td>Description</td>
        </thead>
    <tr ng-repeat = "x in items">
        <td>{{x.brand}}</td>
        <td>{{x.description}}</td>
        </tr>
    </table>
    
</div>
Here we are using ngRepeat directive ( note when we state, we state ng-repeat in the html, since the directive will be interpreted by angularJs for proper camelCase since css can also be included in the HTML markup).  The ngRepeat cycles thru the items and displays the content in a tabular form.  You can use table to <li> </li> construct to display.

Okay if you notice that i am pulling only few fields from the inventory table and yet again I am only displaying fewer fields, right.  Unlike alpha I am not calling large amount of data once and keep playing with that data, I make repeated calls to the server and display as needed.  This makes loading time shorter and make the user experience better. Should you decide to use local storage to feed the data it will be even faster and not dependent on the internet connection.

So for so good, now we will apply bootstrap css to make it look better with alternate coloring and panels. And we will be adding a back button to get back to the home - main menu panel. We will also add search feature to search the list to show only the item we need to see.
So here is the next version of the items html with css and back button:

<div>
 <div class="container-fluid"> 
            <a href="#/" class="btn btn-info btn-md">
            Back to Home
            </a>
    
<div class="panel panel-default">
        <div class="panel-heading">
           <h3 class="panel-title">Item List</h3>
        </div> 
</div>
            
    Search: <input id="searchID" type="text" ng-model="itemName">
        <table class="table table-striped table-condensed">
        <thead>
        <td>Name</td>
        <td>Description</td>
        </thead>
    
    <tr ng-repeat="x in items | filter:itemName">
        <td><a href="#/items/{{x.id}}">{{x.brand}}</a></td>
        <td>{{x.description}}</td>
    </tr>
     </table>
       
            </div>   
</div>

If you notice that I have added a link to id field, that will display the detailed information for that item corresponding to that id number.
Now we will build item detail html.  As you expect this will need a controller, itemsDetailCtrl which will call the server with the id number of the item and fetch the data and we will again use bootstrap css to make that look nicer.
So here is the detail page:

<div ng-controller="itemsDetailCtrl">
    <div class="container-fluid"> 
    <a href="#/items" class="btn btn-info btn-md">
     Back to item
    </a>
        <h2>Item Detail</h2>
   <div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title">Item Detail For: {{item_detail[0].brand}}</h3>
  </div>
       
  <div class="panel-body">
    Item ID: {{item_detail[0].id}}
  </div>
      <div class="panel-body" style="background-color:#F0F0F0 ">
    Brand: {{item_detail[0].brand}}
  </div>
      <div class="panel-body">
    Description: {{item_detail[0].description}}
  </div>
      <div class="panel-body" style="background-color:#F0F0F0 ">
    Size: {{item_detail[0].size}}
  </div>
      <div class="panel-body">
    Price: {{item_detail[0].unit_price | currency}}
  </div>
      <div class="panel-body" style="background-color:#F0F0F0 ">
    Notes: {{item_detail[0].notes}}
  </div>
</div> 
    </div>
    
And to control the detail page here is the itemsDetailCtrl:
(add this right below the itemsCtrl, so it looks like this)

'use strict';
var SERVER = "http://xx.xx.xx.xx:port/";

alphaBlog.controller('itemsCtrl', function($scope, $http) {
    $http.get(SERVER + "alpha_blog/itemsCallback.a5w")
            .success(function(response) {$scope.items = response.items;});
                             });

alphaBlog.controller('itemsDetailCtrl', function($scope, $routeParams, $http) {
        $scope.item_id = $routeParams.item_id;
        $http.get(SERVER + "alpha_blog/item_DetailCallback.a5w",{params:{item:$scope.item_id}})
            .success(function(response) {$scope.item_detail = response.item;});
       });
and the server will process this http call and respond with the item in question as a json object, and here is the a5w page that does the trick:

<%a5
Response.headers.set("Access-Control-Allow-Origin", "*")
dim cn as sql::connection
dim result as l=.f.
dim args as sql::arguments
dim rs as sql::resultset
dim sqlSelect as c
dim msg as c
dim flag as l=.f.
dim item_id as n
dim item as c
'item=2008
item_id = convert_type(item,"N")
result = cn.Open("::Name::alpha_blog")
if result then
sqlSelect = "SELECT id, brand, description, size, unit_price, notes FROM inventory WHERE id = :newID"
args.Set("newID", item_id)
result = cn.Execute(sqlSelect,args)
if result then
rs = cn.ResultSet
msg = rs.ToJSONObjectSyntax()
msg = "{\"item\":["+strtran(msg,crlf(),",")+"]}"
msg = strtran(msg,"'","\"")
end if
cn.close()
else
msg = "{\"item\":\"unable to open connection to the database\""
end if
?msg
%>

So when the items page is listing all the items and when you click on the brand name, the link takes the item.id and passes as a parameter to the http call and returns the response object.
The detail page the uses the bootstrap to fashion it in a nice way and angularJs display the data as array object with elements that we need.

All the controllers are listed in the same page and that page is called blogController.js and the index.html lists the link to the source file for the script tags so the controllers are called in when the index.html is loaded.
So now so far we have seen how to model the scope object and use http to fetch data and implement search and show detail, isn't that cool todo with alpha and angularJs.

So we will see how this evolves:

Please post any comments, so that I can improve the presentation written or the video.
Thank you.



Sunday, June 26, 2016

Alphasoftware and AngularJS - part 3.

Alphasoftware and AngularJS - part 3.

Date: June 26th 2016

Good Morning everyone.

Last week we did the home page that displays the main menu that will direct our user to various pages.  Normally, you should have a login page as the first page and when person is granted access then the main menu will show up. We will do that later, I did not implement that into my app since i will be the one to use.

Now we are going to take advantage of the angular routing to direct the user to different pages then we will fill in the content of the pages.

Go to the blogApp.js file open it.

When you look at the content 

it will be

'use strict';

var alphaBlog = angular.module('alphaBlog',[
    'ngRoute'
]);

alphaBlog.config(function($routeProvider){
    $routeProvider
    .when('/', {
        templateUrl: 'partials/home.html'
    });
    
});

change that to:

'use strict';

var alphaBlog = angular.module('alphaBlog',[
    'ngRoute'
]);

alphaBlog.config(function($routeProvider){
    $routeProvider
 
    .when('/items', {
        templateUrl: 'partials/items.html'
    })
    .when('/', {
        templateUrl: 'partials/home.html'
    });
 
});

save the file, note that between the routes there is no semicolon.
So now when you click on the items button the items page will pop up.
So let's go and create a new page.
Create a new file under partials, call that items.html and fill that with the following.

<div>
<h1>Items </h1>
</div>

and save it  and refresh the index.html on the browser and when you click on the items button the items page will pop up.  if all goes well then we can do that to all pages, we will fill in the content later on on each page along with the controller that will display the contents dynamically.
So now, let's see how we are doing:

https://www.youtube.com/watch?v=nAUR9KVLNZw

take a look at this video.
The finished routing should look like this:
'use strict';

var alphaBlog = angular.module('alphaBlog',[
    'ngRoute'
]);

alphaBlog.config(function($routeProvider){
    $routeProvider
    .when('/map', {
        templateUrl: 'partials/our_location.html'
    })
    .when('/weekly_wine_tasting', {
        templateUrl: 'partials/weekly_wine_tasting.html'
    })
    .when('/wine_recommendation_show', {
        templateUrl: 'partials/recommendation_list.html'
    })
    .when('/new_purchase_order', {
        templateUrl: 'partials/new_purchase_order.html'
    })
    .when('/vendors', {
        templateUrl: 'partials/vendors.html'
    })
    .when('/signin', {
        templateUrl: 'partials/signin.html'
    })
    .when('/appointments', {
        templateUrl: 'partials/appointments.html'
    })
    .when('/delivery', {
        templateUrl: 'partials/delivery.html'
    })
    .when('/items', {
        templateUrl: 'partials/items.html'
    })
    .when('/', {
        templateUrl: 'partials/home.html'
    });
 
});


Next week we will start filling in the contents of the page.

Please post any comments and let me know how to improve this blog.
Have a wonderful day.


Sunday, June 19, 2016

Alphasoftware and AngularJS

Part 2, 
June 19th 2016.

Happy Fathers Day everyone!

Today we will be discussing how to set up device deployable product.
Since my aim is to create primarily iPhone, iPad apps I will be working on Mac, but the steps are the same in windows based computer.
So, let's get going.

First we need to setup required frameworks for our project.
Go to NodeJs.org and download node.js to your computer and install. Once installed npm, the node package manager is also available for you to use.
You can verify the installation with
node -v  and npm -v commands you should see the version for each.
If okay so far, we are set to go.
Now we are going to install the packages with npm. Follow the commands one by one and you will install the required packages.

sudo npm install -g corodova, supply the password when prompted.
that will download and install cordova ( -g option installs globally)

Now we will create the program, I will call my program BLOG.
Enter the command
cordova create blog com.niniswinecellar blog
your company identifier is com prefixed, so if your id is alpha.com the instead f com.niniswinecellar use com.alpha.
You will see Cordova creates the folder and necessary files.
Now cd to blog with cd blog command.
You can inspect the contents with ls command and see the files are there.
Next, we will add iOS platform with this command
cordova platforms add iOS.
We will be adding more packages at this point with another package manager - Bower.
Let's add Bower with npm.  
npm install -g bower ( if there are errors you will need to run sudo nom install -g bower)
Once installed we will use bower to install other components.
We are still in the blog directory and install the following
bower install angular
bower install angular-route
bower install bootstrap
bower install ngCordova.

I like using Brackets editor since it comes with preview web server and the path is easily managed.
When you looked at the directory of blog you will see a folder - www, if you examine that folder will have all the deployable files and an index.html. We will be working in that folder.
Start the Brackets and load the folder blog into it.
And select the index.html file and start the preview server.
You will see phone gap log in flashing screen.
If that happens all good.

Here is the video:

https://www.youtube.com/watch?v=fFScQpnIY-U

This is how I have added the packages to the project, a step I did not show in the last video:
https://www.youtube.com/watch?v=QwOMlGddy1U

Saturday, June 11, 2016

Alphasoftware and AngularJS

Date: June 11th 2016:

Okay, now I will be discussing how to integrate AngularJs with Alphasoftware. 
I use version 11 of Alpha Five and all these are done with that version.  I develop using Mac since I am primarily interested in deploying in iPhone & iPads.  But this can be deployed in Android devices too as long as you have necessary SDK installed in your computer.  When this session is complete I will rewrite the same in iconic angular framework which is even finer than the AngularJS.

Okay, what is AngularJS anyway? It is full javascript framework that extends the HTML markup tags and is maintained by none other than GOOGLE and many volunteers contributing source code for the project.  It is an open-source code project.  It is a part of the commonly known MEAN stack. M(ongoDB)E(xpress)A(ngularJS)N(odeJS) .

This blog is NOT intended to teach AngularJS. There are, however, large number of books, videos and tutorials available and in no way I can do better job than those.  If anyone interested in learning about AngularJs or iconic frameworks then they should refer to those available out there.  My aim in this blog is how to integrate AngularJs with Alphasoftware, primarily for phone and tablets use, because we will be taking advantage of the device functions. I want you to know in the desktop it appears and works just as it does in the device but without the device oriented functions like camera, barcode scanner etc.,

The final application will have a main menu page and on push of the selection it will load the appropriate page and data can be viewed, edited, deleted and created, all at your disposal  Finished product will also feature other frameworks like bootstrap css, nodeJS & npm, bower package manager, google maps and last but not the least, Xcode to push this into iPhone for functioning properly.

So we will start with the general introductory page:
Hello World example
1> from standard html page
2> from alpha five web server with a5w page
3> from angularJS simple display page
4> from angularJs displaying from local alpha five web server
5> from angularJS calling a remote alpha five web server 
the later methods use angular supplied HTTP service,  which renders a response from remote server as json objects. The json object then is converted and injected into the html page.  JSON is standard transport for AngularJS.

You can see all of these in this following video. Next week we will start building our menu page and partials to show different aspects of the data.

Please copy and paste this link:
http://www.youtube.com/watch?v=3JlfvoeP6Ic


Hope you like this, let me know.
You comments are most appreciated.

Friday, June 10, 2016

July 10th 2016

Sorry everybody, I have been away and busy with lots of things and did not post any new post lately.
Now I am back.
I will be posting few articles how to integrate Alpha software with AngularJS and Iconic framework.
Also I noticed during cleanup all my old screencasts were removed, if I can recreate them I will, if not please contact me I can create a new one to provide you.
Starting this Sunday I hope to post once a week to show what can be done.
Thanks
See you soon.

Tuesday, August 26, 2014

Master Detail grid for a purchase order

August 26th 2014

Today I am going to show how I implemented master grid with a child detail grid for the purposes of a purchase order.  Normally I like to do this in a dialog but this time I chose to implement via a grid since this gave me an opportunity to add a single line each time a record is saved in the detail section.  I am sure I can do this in a dialog.  But this is working so I did not pursue that line.

Before I build the purchase order header, let me tell you how the detail view is done. Then it will be easy to incorporate it into the header grid and you are done with it.  The detail grid is a simple updatable grid with a property to add a single new record rather than the customary 3 records that alpha gives.  The item name field is designed as a look up to fill all the rest and in the onChange event I have triggered to save the grid via action javascript.  My grid is also designed to total the amount for the total cases and the cost, you can easily accomplish that. This is rather straight forward.  The main work comes in the next grid.

The header grid is based on the single record template.  The reason I chose this instead of others is that when you finish it almost looks like a dialog, not anything nearly like a grid.  I have also hidden the detail section and the buttons to direct the user my way.

To show the buttons show and hide property is used for the first two buttons based on the idea whether the grid is dirty or not.  And for the next three buttons it is based on the idea record id being grater than 1.

Printing report and sending email are again straight forward.  One is done with action javascript, the other via an xbasic routine.

To show the detail section on demand a div with an id is created below the detail section of the grid in the freeform area and the onClick event of the button opens the child grid filtered by the purchase order id at that location.

When all done the parent grid and child detail grid work flawlessly and has been a good addition to my work schedule.

The same method may be applied to receiving document and especially sales. I have to finish the sales before I post it.
In the meantime here are some videos to show how this is done

purchase order detail:
http://screencast.com/t/zwe2K2H6yC
purchase order header part 1
http://screencast.com/t/3ON0pzC30H1
purchase order header part 2
http://screencast.com/t/aeLcMqqa
real life functioning purchase order at my store
http://screencast.com/t/h7N63XZqKjM