Forums >> Programming >> Proof of Concept (POC)

Jump to:




bvstone

Creating Mobile Applications using RPG, the IBM i, and Canvas

Posted:

Creating Mobile Applications using RPG, the IBM i, and Canvas

The subject of creating applications for mobile devices comes up quite often.  There are normally many solutions provided, some theoretical, others proven with actual use.  So I thought I would share my experience with creating mobile applications on the IBM i.

In working with a customer we needed a way to dispatch technicians to locations to perform installations, fixes or even training.  Paper tickets were being used before.  These tickets were used to log the time spent, any materials used, as well as obtain a signature from the customer to show the work that was done.

We needed a way to make this work on mobile digital devices such as iPhones, iPads, Android devices and Blackberries.

My first thought was create a web application.  Since they can be cross platform that would solve that issue.  Then we ran into an issue where during the work, not only did we need to capture signatures, but also be able to take pictures of things we could attach to the work ticket.  That made it more complicated than a web application could handle.  Yes, it's possible, but is it worth the fight?

Then I started looking into "apps that create apps".  One was from a company named Canvas (www.gocanvas.com).  After 15 minutes of playing with it, I knew I was onto something good.

What you can do with Canvas is create apps for your company.  You get a WYSIWYG interface to build the forms used by the apps and control the flow of the app.  In this case we needed one that would work as a dispatch for technicians.  Each technician installs the Canvas app and creates an account at Canvas.  Then, when we want to alert a specific technician of work to do, we use a Web Service (or RESTful) request to send information about the job to the technician (or technicians).

In the following posts I will describe the steps used.  More will be added to this as time goes on, but hopefully it will provide enough information to help you with your project.




Latest Posts:

Update for Google WorkSpace Accounts (2024): Google Dropping Support for Update for Google WorkSpace Accounts (2024): Google Dropping Support for "Less Secure Apps" May 30th, 2022. What Does This Mean for Your IBM i Email?
Posted by January 19, 2024
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Sales By State Report in QuickBooks Online Sales By State Report in QuickBooks Online
Posted by January 13, 2024
QuickBooks >> QuickBooks Online
How to Whitelist GreenTools for G Suite (G4G) For Your Organization How to Whitelist GreenTools for G Suite (G4G) For Your Organization
Posted by November 5, 2023
BVSTools >> BVSTools Software Discussion >> GreenTools for G Suite (Google Apps) (G4G) Specific Discussion
QuickBooks Online Releases QuickBooks Online Releases "New Invoices!"... and It's Terrible!
Posted by October 8, 2023
QuickBooks >> QuickBooks Online
Admin/4i - What is it? Admin/4i - What is it?
Posted by September 30, 2023
Vendor Corner >> MSD Information Technology
BVSTools Releases Send Job Log to BVSTools (SNDLOG2BVS) Command BVSTools Releases Send Job Log to BVSTools (SNDLOG2BVS) Command
Posted by August 28, 2023
BVSTools >> BVSTools Announcements
MAILTOOL Now Allows Email Redirection for Development and Testing MAILTOOL Now Allows Email Redirection for Development and Testing
Posted by May 27, 2023
BVSTools >> BVSTools Announcements >> eMail Tool (MAILTOOL) Specific Announcements
GreenTools for Microsoft Apps (G4MS) Now Supports Footers When Sending Email GreenTools for Microsoft Apps (G4MS) Now Supports Footers When Sending Email
Posted by March 29, 2023
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
QuickBooks Online - Subtotals and Discounts Frustration QuickBooks Online - Subtotals and Discounts Frustration
Posted by March 16, 2023
QuickBooks >> QuickBooks Online
Making the Switch From QuickBooks Desktop to QuickBooks Online - No Picnic Making the Switch From QuickBooks Desktop to QuickBooks Online - No Picnic
Posted by March 16, 2023
QuickBooks >> QuickBooks Online
BVSTools Software Verified on V7R5 and Power10 BVSTools Software Verified on V7R5 and Power10
Posted by December 9, 2022
BVSTools >> BVSTools Announcements
Microsoft Office 365 Servers and Random Errors Issue Microsoft Office 365 Servers and Random Errors Issue
Posted by November 14, 2022
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Sending/Resending Emails Using a MIME File with MAILTOOL Sending/Resending Emails Using a MIME File with MAILTOOL
Posted by November 8, 2022
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Sending an HTML Email on Your IBM i Using MAILTOOL Sending an HTML Email on Your IBM i Using MAILTOOL
Posted by November 1, 2022
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Transferring License Keys from One System to Another Transferring License Keys from One System to Another
Posted by October 31, 2022
BVSTools >> BVSTools Software Discussion
bvstone

Creating the App using Canvas

Posted:

Creating the App using Canvas

When you first log on to your Canvas account, you are given a few templates to work with.  Because our form was quite simple, we chose to start from scratch.

Selecting the MyApps link will list any apps you have created and that are provided by default.  You have the option to edit apps, or create a new one.

You'll notice in the app list there is a version associated with each one.  This idea of versioning is quite useful in case you mess up during an edit and need to revert to an older version.

When we enter the editor we are given a WYSIWYG interface that allows you to create "screens", add items to each screen, as well as work with the flow of each app (ie, which order the screens will appear).

Each item on each screen can be text, numeric, date, or even calculated.  Each field can also be set to a default value in the app itself as well as have it's value set when you initiate the creation of an app to be sent to a user.  

In this example we will send a dispatch to a technician.  The dispatch will include the address of the customer and also allow them to use their mobile device's GPS system to get them there.  Obviously the address will be different for each dispatch and that value can be set when the dispatch is created, which we will see more of later.

As you can see, the tools provided by Canvas make things very easy to create and update. 


Last edited 10/02/2014 at 13:11:05



bvstone

Initiating an Event

Posted:

Initiating an Event

In our example we are working with a dispatch system to send technicians to locations to perform specific tasks.  

Our online system already allowed the creation of work tickets and allowed us to assign technicians to that specific ticket.  

To incorporate the use of Canvas and the apps, we simply added an option to our work ticket screen to create a dispatch and alert the technician of a job that was ready for them.

In the screen capture above we see that we have a work ticket.  To the left are employees that are assigned to the ticket.  To the right are employees that are available to be assigned to the ticked.

In the list of assigned employees we have a Canvas logo that when clicked, will initiate the creation of a dispatch for that specific employee.

In this next screen shot we see the results after clicking the Canvas logo next to the user of "Brad Stone".  This screen alerts us that in the background there is a process of creating and sending the dispatch to the user.  This is done, in this case, using the GETURI application to make a POST to the Canvas servers.

The POST consists of XML that not only defines which app we want to send (in this case, a Dispatch), but it also defines the values for any data that we want to prefill in the app when the user opens it.  An example of the POST and XML created (using the eRPG SDK, which could also be done with CGIDEV2 or other tools) is as follows:

POST /apiv2/dispatch_items?username=xxxxxxxx&password=xxxxxxxx HTTP/1.0
Accept: text/html
Host: www.gocanvas.com
Content-type: application/x-www-form-urlencoded
Content-length: 907

<?xml version="1.0" encoding="utf-8"?> 
<List> 
	<DI FormName="Dispatch" Description="this is a work ticket (41)" User="bvstone@bvstools.com"> 
		<DIEntry Label="ticket_id" Value="41"/> 
		<DIEntry Label="order_date" Value="04/17/2014"/> 
		<DIEntry Label="customer_email" Value="cindysmith@cindy.com"/> 
		<DIEntry Label="customer_business" Value=""/> 
		<DIEntry Label="customer_contact" Value="Cindy Smith"/> 
		<DIEntry Label="customer_add1" Value="111 Main Street"/> 
		<DIEntry Label="customer_add2" Value=""/> 
		<DIEntry Label="customer_city" Value="Fairhope"/> 
		<DIEntry Label="customer_state" Value="AL"/> 
		<DIEntry Label="customer_zip" Value="60004"/> 
		<DIEntry Label="customer_phone" Value="18478705236"/> 
		<DIEntry Label="default_labor_rate" Value="99.99"/> 
		<DIEntry Label="has_parts" Value="true"/> 
		<DIEntry Label="has_labor" Value="true"/> 
	</DI> 
</List>

The POST is made to a specific URL and also sends the user id and password of an account holder in Canvas. 

The XML contains information such as the name of the form to send (in this case, our Dispatch form), which user to send it to, and any default values.

Once the POST is complete the Canvas application returns XML with any errors, messages, or information.


Last edited 10/02/2014 at 13:23:42



bvstone

Receiving the Dispatch on the Mobile Device

Posted:

Receiving the Dispatch on the Mobile Device

Once the dispatch is sent to a user they will receive a notification on their device that a new item is available.

Then can click on the notification or the Canvas app itself to see the new dispatches that are ready for them to act on.

We see here by the icon next to the work ticket that this one is new and needs to be completed.

When the user clicks on the ticket, it is opened with the default values that were sent in the XML POST in the previous step.

The user will then go through each screen and fill out the information.  This particular design allows them to enter multiple details lines for parts used as well as time spent on each job.

Finally, when they are done they present the device to the end customer to get a signature saying that the work has been completed.

The customers signature is then captured.

When everything is done, the information is submitted back to Canvas and made available for our application to retrieve any data, including images and signatures.

As of this writing there really isn't a way to trigger our server to tell us that a dispatch has been completed, but according the support at Canvas it is something they are looking into.

 


Last edited 10/02/2014 at 14:27:52



bvstone

Retrieving the App Data back to your IBM i

Posted:

Retrieving the App Data back to your IBM i

Once a dispatch is done, we need some way to retrieve the information that was stored in the app for the specific dispatch.

The information is available for download manually from the Canvas page under the "Submissions" menu as shown here:

As stated, at this time there really is no way to trigger the download of the data when the dispatch is submitted from the mobil device, so instead we have a manual refresh process we use.  

The manual submission triggers another POST using GETURI to the Canvas site to find any new submissions that are made.  

A sample of the code used is as follows:

     H DFTACTGRP(*NO) BNDDIR('ERPGSDK')
      ****************************************************************
      * Prototypes                                                   *
      ****************************************************************
     D SUBMISSION      PR
     D                              128
     D                             1024
     D SUBMISSION      PI
     D   inKey                      128
     D   outErrorMsg               1024
      ****************************************************************
      /COPY GETURI/QCOPYSRC,GETURICOPY
      /COPY QCOPYSRC,P.APPSTAT
      /COPY qcopysrc,p.pdocxml
      /COPY qcopysrc,p.libl
      ****************************************************************
      * Work Variables
     D xmlFile         s            500a   varying
     D ignoreMe        s              1a
     D GetError        s               n
     D rc              S             10i 0
      ****************************************************************
      /free
       outErrorMsg = ' ';
       #appstat_setStatus(inKey:'Retrieving Submissions...');
       xmlFile = '/tmp/canvassubmissions.xml';
       #pushLib('GETURI');
       EXSR $LoadParms;
       EXSR $GETURI;
       #popLib('GETURI');

       if (not GetError);
         #appstat_setStatus(inKey:'Processing Submissions...');
         rc = #pdocxml_setKey(inKey);
         rc = #pdocxml_setID('submission');
         rc = #pdocxml_clearErrors();
         rc = #pdocxml_loadRefs();
         xml-sax %handler(#pdocxml_xmlHandler:ignoreMe)
              %XML(xmlFile: 'doc=file');
       else;
         outErrorMsg = GetUri_Msg;
       endif;

       *inlr = *on;

       //***************************************************************
       //* Load GETURI Parameters
       //***************************************************************
       BegSr $LoadParms;

         CLEAR GetUri_In;
         GI_URI = 'https://www.gocanvas.com/apiv2/submissions.xml?' +
                  'username=xxxxxxxx&password=xxxxxxxxx&' +
                  'form_name=Dispatch';
         GI_ReqMeth = 'POST';
         GI_SSL   = '*YES';
         GI_Port   = 443;
         GI_CCSID  = 1208;
         GI_CodPag  = 1208;
         GI_OutType   = '*STMF';
         GI_Stmf = xmlFile;
         GI_SprHead = '*YES';
         GI_Debug = '*YES';

       EndSr;
       //***************************************************************
       //* Call GETURI
       //***************************************************************
       BegSr $GETURI;

      /end-free
     C                   CALL      'GETURIRG'                           99
     C                   PARM                    GetUri_In
     C                   PARM                    GetUri_Out
     C                   PARM                    GetUri_Head
     C                   PARM                    GetUri_Data
     C                   PARM                    GetUri_MsgCd
     C                   PARM                    GetUri_Msg
      /free

         GetError = (%scan('200 OK':GetUri_Head) <= 0) or (*IN99);

       EndSr;

      /end-free

The POST looks like the following:

POST /apiv2/submissions.xml?username=xxxxxx&password=xxxxxxx&form_name=Dispatch HTTP/1.0
Accept: text/html
Host: www.gocanvas.com
Content-type: application/x-www-form-urlencoded
Content-length: 0

What this request is doing is saying "retrieve all the data for any submissions with the form name of Dispatch.

The data returned is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<CanvasResult>
 <TotalPages>1</TotalPages><CurrentPage>1</CurrentPage><Submissions><Submission Id="8092165">
  <Form Id="700427">
    <Name>Dispatch</Name>
    <Status>published</Status>
    <Version>14</Version>
  </Form>
  <Date>2014.10.02 18:33:50</Date>
  <DeviceDate>2014.10.02 18:31:12</DeviceDate>
  <UserName>bvstone@bvstools.com</UserName>
  <FirstName>Bradley</FirstName>
  <LastName>Stone</LastName>
  <ResponseID>63fff60953a2c4cf-1412269994795</ResponseID>
  <Sections>
    <Section>
    <Name>Customer Information</Name>
    <Screens>
      <Screen>
      <Name>Customer Information</Name>
            <Responses>
              <Response>
        <Label>ticket_id</Label>
        <Value>41</Value>
        <Type>Integer</Type>
        </Response>
        <Response>
        <Label>order_date</Label>
        <Value>04/17/2014</Value>
        <Type>Date</Type>
        </Response>
        <Response>
        <Label>customer_email</Label>
        <Value>cindysmith@cindy.com</Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>customer_business</Label>
        <Value></Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>customer_contact</Label>
        <Value>Cindy Smith</Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>customer_add1</Label>
        <Value>111 Main Street</Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>customer_add2</Label>
        <Value></Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>customer_state</Label>
        <Value>AL</Value>
        <Type>Value List</Type>
        </Response>
        <Response>
        <Label>customer_city</Label>
        <Value>Fairhope</Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>customer_zip</Label>
        <Value>60004</Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>customer_phone</Label>
        <Value>18478705236</Value>
        <Type>Text Box</Type>
        </Response>
            </Responses>
      </Screen>
    </Screens>
    </Section>
    <Section>
    <Name>Description of Work Performed</Name>
    <Screens>
      <Screen>
      <Name>Description of Work Performed</Name>
            <Responses>
              <Response>
        <Label>work_location</Label>
        <Value></Value>
        <Type>Text Box</Type>
        </Response>
        <Response>
        <Label>work_description</Label>
        <Value>install new VOIP phones</Value>
        <Type>Multi-Line Text</Type>
        </Response>
        <Response>
        <Label>work_gps</Label>
        <Value></Value>
        <Type>GPS</Type>
        </Response>
        <Response>
        <Label>default_labor_rate</Label>
        <Value>99.99</Value>
        <Type>Decimal</Type>
        </Response>
        <Response>
        <Label>has_parts</Label>
        <Value>True</Value>
        <Type>Checkbox</Type>
        </Response>
        <Response>
        <Label>has_labor</Label>
        <Value>True</Value>
        <Type>Checkbox</Type>
        </Response>
            </Responses>
      </Screen>
    </Screens>
    </Section>
    <Section>
    <Name>Parts List</Name>
    <Screens>
      <Screen>
      <Name>Parts List</Name>
        <ResponseGroups>
        <ResponseGroup>
          <Response>
          <Label>part_qty</Label>
          <Value>5</Value>
          <Type>Integer</Type>
          </Response>
          <Section>
          <Name>Parts List (Detail)</Name>
          <Screens>
            <Screen>
            <Name>Parts List</Name>
                  <Responses>
                    <Response>
              <Label>part_number</Label>
              <Value>phones</Value>
              <Type>Text Box</Type>
              </Response>
              <Response>
              <Label>part_desc</Label>
              <Value>voip phones</Value>
              <Type>Text Box</Type>
              </Response>
              <Response>
              <Label>part_each</Label>
              <Value></Value>
              <Type>Decimal</Type>
              </Response>
              <Response>
              <Label>part_total</Label>
              <Value>0.00</Value>
              <Type>Calculation</Type>
              </Response>
                  </Responses>
            </Screen>
          </Screens>
          </Section>
        </ResponseGroup>
        <ResponseGroup>
          <Response>
          <Label>part_qty</Label>
          <Value>20</Value>
          <Type>Integer</Type>
          </Response>
          <Section>
          <Name>Parts List (Detail)</Name>
          <Screens>
            <Screen>
            <Name>Parts List</Name>
                  <Responses>
                    <Response>
              <Label>part_number</Label>
              <Value>cable</Value>
              <Type>Text Box</Type>
              </Response>
              <Response>
              <Label>part_desc</Label>
              <Value></Value>
              <Type>Text Box</Type>
              </Response>
              <Response>
              <Label>part_each</Label>
              <Value></Value>
              <Type>Decimal</Type>
              </Response>
              <Response>
              <Label>part_total</Label>
              <Value>0.00</Value>
              <Type>Calculation</Type>
              </Response>
                  </Responses>
            </Screen>
          </Screens>
          </Section>
        </ResponseGroup>
        </ResponseGroups>
      </Screen>
    </Screens>
    </Section>
    <Section>
    <Name>Labor</Name>
    <Screens>
      <Screen>
      <Name>Labor</Name>
        <ResponseGroups>
        </ResponseGroups>
      </Screen>
    </Screens>
    </Section>
    <Section>
    <Name>Contract Totals</Name>
    <Screens>
      <Screen>
      <Name>Contract Totals</Name>
            <Responses>
              <Response>
        <Label>complete_date</Label>
        <Value>10/02/2014</Value>
        <Type>Date</Type>
        </Response>
        <Response>
        <Label>subtotal_parts</Label>
        <Value>0.00</Value>
        <Type>Summary</Type>
        </Response>
        <Response>
        <Label>subtotal_labor</Label>
        <Value>0.00</Value>
        <Type>Summary</Type>
        </Response>
        <Response>
        <Label>subtotal</Label>
        <Value>0.00</Value>
        <Type>Calculation</Type>
        </Response>
        <Response>
        <Label>tax_rate</Label>
        <Value>7</Value>
        <Type>Decimal</Type>
        </Response>
        <Response>
        <Label>total_tax</Label>
        <Value>0.00</Value>
        <Type>Calculation</Type>
        </Response>
        <Response>
        <Label>total_amount</Label>
        <Value>0.00</Value>
        <Type>Calculation</Type>
        </Response>
            </Responses>
      </Screen>
    </Screens>
    </Section>
    <Section>
    <Name>Signature</Name>
    <Screens>
      <Screen>
      <Name>Signature</Name>
            <Responses>
              <Response>
        <Label>Customer Signature</Label>
        <Value>502357631</Value>
        <Type>Signature</Type>
        </Response>
            </Responses>
      </Screen>
    </Screens>
    </Section>
  </Sections>
</Submission></Submissions> </CanvasResult>

As shown, the data returned will allow us to get the value of anything entered by the user's mobile device.  For any images (including signatures) a URL is provided to be able to either reference or download.

The data is retrieved as XML and parsed using the built in SAX parser.  Once compete, we see the new submission in the list and can view it's details (the last one in the list that is highlighted yellow).

 

 


Last edited 10/02/2014 at 14:11:49




Reply




© Copyright 1983-2020 BVSTools
GreenBoard(v3) Powered by the eRPG SDK, MAILTOOL Plus!, GreenTools for Google Apps, jQuery, jQuery UI, BlockUI, CKEditor and running on the IBM i (AKA AS/400, iSeries, System i).