Showing posts with label Lotus Notes. Show all posts
Showing posts with label Lotus Notes. Show all posts

Tuesday, February 16, 2010

Add A Google Map To XPages

A snapshot of the Lotus XPage embedded Google Map

The goal of this XPage practice is to add a web search function for a traditional Lotus CRM database with a embedded Google Map view. A Google map with address markers will be displayed under based upon the customers search result .

This is the original view of the Notes database which I used for the data source, the database need to be fully indexed for search function to perform correctly -
 

This XPage named "search4" was created under the same database and the layout of this XPage includes three Panels - first is for the search bar, second is for the View control and the third is for the Google Map canvas.

First Panel has two components, one is the "Edie Box" for the search string, we need to bind it to the "View Scope" and name it "searchString".

The second component is the search Button which need to add a "Simple Action" under its onClick event, then choose "Open Page" as the function, the name of the Page should be "computed" -
"search4.xsp?search=" + viewScope.searchString


The View (data grid) for the search result is named "viewPanel1" (default), I selected the data source from Domino view "location"
add following content at "search" field which should be a server side JavaScript(compute dynamically) -
context.getUrlParameter("search");
The third Panel is the easiest one which you just need to give it a name for Google Map API can access it, we named it "map" (actually, it become "view:_id1:map" on web page).

Make "dojoParseOnLoad" on XPage property as "true" since we need to use dojoAddOnLoad to load our JavaScript codes after page loaded.

There is a JavaScript library (geo4.js) needed inside this database script library. The purpose of this library is to dynamically load the Google Javascript header after page load , and to execute the Google API for populating the address markers on the map. I use the the Google Maps API geocoding service via the GClientGeocoder object to decode the address and create marker. To make my life easier, I did some hacks to avoid the javascript variable conversion which I still have problem dealing with, I had to manually find out the name of the table and div on the web page I need and hard-code them on the geo4.js (red section).

Following is the JavaScript codes - geo4.js stored at script library.
var map;

function loadScript() {
  var script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "http://maps.google.com/maps?file=api&v=2.x&key=your_google_api_key&async=2&callback=loadMap";
  document.body.appendChild(script);
}
 
function loadMap() {
  map = new GMap2(document.getElementById("view:_id1:map"));
  map.setCenter(new GLatLng(38.4419, -102.1419), 4);
  map.setUIToDefault();
  mapMe();
  }
 
function mapMe() {
var tb=document.getElementById("view:_id1:viewPanel1");
var tr=tb.getElementsByTagName("tr");

for (i=1; i<tr.length; i++)
var td=tr[i].getElementsByTagName("td");

var sp=td[4].getElementsByTagName("span");
if (sp[0] != undefined)
showAddress(sp[0].firstChild.data, map);

  }
}
 
  function showAddress(address, m) {
      var geocoder = new GClientGeocoder();
      geocoder.getLatLng(
        address,
        function(point) {
          if (!point) {
           // alert(address + " not found");
          } else {
           
            var marker = new GMarker(point);
            m.addOverlay(marker);
                var html = address;
              GEvent.addListener(marker, "click", function() {
             marker.openInfoWindowHtml(html);
              })   
            //marker.openInfoWindowHtml(address);
          }
        }
      );
    }
   
  function showAddressInfo(address, m) {
      var geocoder = new GClientGeocoder();
      geocoder.getLatLng(
        address,
        function(point) {
          if (!point) {
           // alert(address + " not found");
          } else {
           
            var marker = new GMarker(point);
            m.addOverlay(marker);
                var html = address;
              GEvent.addListener(marker, "click", function() {
             marker.openInfoWindowHtml(html);
              })   
            marker.openInfoWindowHtml(address);
          }
        }
      )
    }
   
    dojo.addOnLoad(loadScript);

You can download the design template of this Notes database by clicking here

Wednesday, December 16, 2009

Warehouse Automation (I) - Create A Low-cost Smart Bar-Code Scanning Solution



Purpose -
To implement a low-cost smart bar-code scanning solution for the warehouse inventory control, automatic data upload process through MS ActiveSync synchronization.

H/W (PDA with built-in Barcode scanner) - 
  • Motorola(Symbol) PPT8800 or MC series, you can find PPT8800 under $200 at eBay, however, I used MC70 for this practice
  • Networked PC with Windows XP, connect the PDA thru USB port
  • Server hosting the database which keep all S/N information, I used a Linux server with MySQL for this practice. You can connect to any database depneds on your environment, even to those non-database applications like Quickbooks, Peachtree, Navision, SAP B1, Lotus Notes ... etc. As long as you set up the connector correctly (normally ODBC)
S/W - 
  • TracerPlus Pro - barcode scan S/W ($215, trial version available)
  • Tracer Desktop - layout editor (free)
  • MS ActiveSync 4.5 - connect PDA and PC for synchronization (download from MS)
  • GoodSync - since ActiveSync only sync data under My document folder we use GoodSync to sync scan data which is under program folder



    Example file - download
    This is a TracerPlus Desktop project file, it includes two scan forms, one for outgoing invoices S/N scanning, he other for receiving S/N scanning. Some checking mechanism have been added to avoid double scan or wrong formats.
    Fields of Outgoing Invoice S/N Form :
    INVNO: Invoice#
    PN: P/N
    SN: S/N
    DATE: scanned date
    SCANNER: scanned by

    Fields of Receiving Orders S/N Form :
    REFNO: PO#
    PN: P/N
    SN: S/N
    DATE: received date
    SCANNER: scanned by

    Implement Data Synchronization and Database Connector -
    set up the GoodSync to upload the scan data to file server everytime when the scanner is attached to the PC, this is a one-way sync








    ODBC setting: the export files from TracerPlus we have predefined as CSV, therefore, we use the "MS Text Driver" for our ODBC System DSN, 


    Once the ODBC ready, we need to decide how to connect to the target database to add the new S/N information. We should have a front-end process to filter the scan data make sure they are before we update the database.

    I implemented three scheduled tasks by different tools which just wan to show you the basic concept to automate your inventory management -
    • update MySQL S/N table by Using PHP and Cron jobs
    • use Invoice# as key to update Quickbooks invoices and add the S/N information into Memo field by using QODBC, ASP and Windows scheduled tasks
    • use Invoice# as key to update Lotus Notes S/N control database by using Lotus LEI (Lotus Enterprise Integrator)
    On the following article, I will publish more details about how to implement these three data pumping tasks.

    Thursday, September 24, 2009

    Set Up Lotus Domino 8.02 Partitioned Servers on Amazon EC2 - Part I


    a snapshot of 4 Domino servers running on 1 Amazon EC2 instance

    The purpose of this practice is to find a reliable(over 99.9% up time) and cheap back-up/disaster recovery plan for Lotus Domino systems.

    You must have an Amazon account to start your own EC2 and S3 account. Go to Amazon web site, click at "For Developers" at left hand bottom, then click at "Amazon Web Services". Once you get into the Amazon Web Services page, sign up for a free AWS account. Then click at "AWS Management Console" to start your EC2 own journey. Couple hours' digging will only cost you less than $2 (a Windows 2003 instance cost $0.125/hr), so do not afraid to try anything new!

    IBM does offer some AMIs on Amazon EC2. However, there is no Lotus Domino pre-installed AMI, therefore, we have to build it from the ground. I will use Windows 2003 server for this practice, I did try the Cent OS 5.3 which was also working fine.

    We would like to build four partitioned servers on a single instance, since one instance can only attache one IP, therefor, we will need Port Mapping to share this IP.

    What we need -
    Basic Microsoft Windows Server 2003 (AMI Id: ami-de4daab7)
    100GB EBS Volume for datastore
    1 Elastic IP(optional)
    Domino Server 8.02



    We pick the Small Instance (m1.small) which has
    1.7 GB memory
    1 EC2 Compute Unit (1 virtual core with 1 EC2 Compute Unit)
    160 GB instance storage (150 GB plus 10 GB root partition)
    32-bit platform

    If you plan to save the image for future use (your own AMI)then don't bother to use the 150GB D drive at all, since the data on D drive won't be saved when creating new image from this instance. Therefore, we need a datastore(a new Volume) created from EBS, I set the size at 100GB according to my case, try not to use the size much bigger than you need because you need to pay for the storage too!

    Security Setting -
    Before creating your first instance you need to create a new Security Group (mine named W2K3) add some more ports to fit our instance needs


    port POP3, IMAP, SMTP, HTTP, HTTPS ports open or not depend on your applications
    Port 1352 is the Domino default port
    port 1353 - 1356 used by partitioned servers which need port mapping
    port 8585 for Domino server remote setup
    port 5800/5900 for VNC server
    port 3389 for Windows Remote Desktop

    You can launch instance now!


    Set Up Lotus Domino 8.02 Partitioned Servers on Amazon EC2 - Part II
    Set Up Lotus Domino 8.02 Partitioned Servers on Amazon EC2 - Part III