Deliver invoice from Blinksale with H2O

Scenario

A friend of mine told me the story below, I have make some tweaks on his company name and industry but he operation flow and the issue that he want to resolve remains.

I received purchase request from my business partner, then I roast my beans and have it delivered. Then, I will issue invoice to complete the ordering.


It is now performed in a half manual, half automated manner. Invoices is created in a web application called Blinksale, when the due day has come, I will either print out the the invoice and fax it, or have Blinksale to send it via email.


For now, the workload is OK but I need to reconfirm with the business partner if they have received the invoice. Sometimes, the invoice might be sent to their SPAM folder and I don't know if it is safe to send the invoice this way.

Blinksale is a nice tool, it's easy to enter the data of the business partner and keep track of the invoices. My friend will be pleased if some sort of automation, together with a means to make sure his invoice is sent without a hitch (and safely!).

After studying Blinksale for a while, I noticed that they offered API to access the data. So I am wondering if H2O can help to do the transmission, so that my friend can rely on Blinksale to do the data input while using H2O to do the transmission. This allow each of the tools to focus on what they can do best.

How does it looks like?

The "architecture" will look like this.
image
A java program will invoke Blinksale through the provided RESTFul API. And this program will call the WebService interface provided by H2O, in sending the invoice through a partnership defined for the message transmission.

The "Bridge"

Let's call the "bridge" as "H2O-Blinksale". It contains 2 java classes and has 4 objectives that want to be achieved.
  1. Determine which of the invoice is ready to be sent in Blinksale
  2. Retrieve the invoice from blinksale
  3. Invoke H2O through the web service interface and have the invoice delivered through ebMS (or AS2 as you desire)
  4. Update the tag of the invoice from open to close if an acknowledgement is received.

Get Invoice

Blinksale offers a number of way to search for invoice. They have offered a nice documentation on how to construct the RESTful HTTP request. Notice that you will need to define the proper content type, as well as having your username/password BASE 64 encoded.

def conn = new URL(url).openConnection()
def authorizationString = "Basic " + (username + ":" + password).getBytes().encodeBase64().toString()

conn.addRequestProperty("Accept","application/vnd.blinksale+xml")
conn.setRequestProperty("Content-Type","application/vnd.blinksale+xml")
conn.setRequestProperty ("Authorization", authorizationString)

You can get a list of invoices by "tag", by "date" or "status". Since we tagged all the invoice that have yet to process with a tag of "open", thus "" will send a query to Blinksale for all the invoices possessing this tag.

def invListConn = getURLConnection(username,password,url+"?tags=open")

Below is the content of the returned list,

    <?xml version="1.0" encoding="UTF-8"?>
    <invoices xmlns="http://www.blinksale.com/api">
      <invoice status="open" uri="http://example.blinksale.com/invoices/1" total="37.56" total_due="37.56">
        <client name="Acme">http://example.blinksale.com/clients/2</client>
        <number>100001</number>
        <date>2006-09-19</date>
        <terms due_date="2006-10-04">15</terms>
        <currency>USD</currency>
        <tags>brian, consulting</tags>
      </invoice>
      (...)
    </invoices>

With the list, individual invoice can be retrieved by invoking their corresponding URL in the form of data stream. In the returned data, we are in particular interest to two elements - "tags" and "number". "Tags" contains all the attribute that has been assigned to this invoice. You will notice that when we have finished processing this invoice, we will change the attribute of this invoice to something else, as an indication of completion. The value of the element "number" is the invoice ID that has been assigned to this invoice.

    <?xml version="1.0" encoding="UTF-8"?>
    <invoice xmlns="http://www.blinksale.com/api" uri="http://example.blinksale.com/invoices/1" status="pastdue" subtotal="19.00" total="19.00" paid="2.00" total_due="17.00" surplus="0.00" updated_at="2006-09-20T17:27:48Z" created_at="2006-06-27T22:43:13Z">
      <number>100001</number>
      <tags>open, service</tags>
      ...
    </invoice>


Send Invoice

Assuming the recipient already has H2O in place and a partnership has been created on both side. What has to be done next is to invoke the web service API on H2O, ask H2O to deliver the invoice via the defined partnership.

The code is very similar to loopback test, with the except on how the payload is being attached to the SOAP message. In loopback test, we use the FileDataHandler while in this example, we use the DataHandler instead. For details on the implementation, please refer to our previous article.

Upon receiving the message ID returned from H2O, we will update tag this invoice to a state of "close", so that the same invoice will not be retrieved for duplicated process.

    def updInvConn = getURLConnection(username,password,it.toString())
    updInvConn.setRequestMethod("PUT")
    updInvConn.doOutput = true

    invTags = invTags.toString().replaceAll('open', 'close')
    invTags = invTags.replace(" ", ",")
    def updateInv = """<?xml version="1.0" encoding="UTF-8"?> <invoice xmlns="http://www.blinksale.com/api"> """
    updateInv = updateInv + invTags + """</tags></invoice>"""

    Writer writer = new OutputStreamWriter(updInvConn.outputStream)
    writer.write(updateInv)
    writer.flush()
    writer.close()
    updInvConn.connect()


Deliverable

You can download the java program written in groovy from this location. The settings of the Blinksale account and the partnership value to be used in H2O are all defined in the file "conf/config.xml". The simplest way to try out is to sign up your Blinksale account, replace the value in the config file and run "ant run". Remember to tag your invoice with "open" though.

Summary

A recap on what we have archive, we retrieve a list of invoice from Blinksale, enforce data encryption on the content and request the recipient to return an acknowledgement when they have received the invoice to ensure proper delivery. The delivery is taken care by H2O by using ebXML and the invoice data is taken care by Blinksale.

You can further enhance the program but enforcing digital signing upon delivering the invoice. What's more, you may keep the relationship of the invoice id with the message id and determine the status of delivery.

In the next section, we will looking at this same scenario from the opposite angle. How can one use H2O to handle the received invoice.



Discuss this in our forum

Posted by Ronnie Kwok on 05/02 at 04:49 PM