From 0f65e0a2dd3f79802e4b3ed0bd899ed7a057eeb7 Mon Sep 17 00:00:00 2001 From: Danny Berger Date: Mon, 13 Jan 2014 08:18:46 -0700 Subject: [PATCH] post barcoding-inventory-with-qr-codes --- ...01-13-barcoding-inventory-with-qr-codes.md | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 blog/_posts/2014-01-13-barcoding-inventory-with-qr-codes.md diff --git a/blog/_posts/2014-01-13-barcoding-inventory-with-qr-codes.md b/blog/_posts/2014-01-13-barcoding-inventory-with-qr-codes.md new file mode 100644 index 0000000..74c646c --- /dev/null +++ b/blog/_posts/2014-01-13-barcoding-inventory-with-qr-codes.md @@ -0,0 +1,179 @@ +--- +title: "Barcoding Inventory with QR Codes" +layout: post +tags: barcode qr-code retail product label scan +description: A web-centric, user-friendly approach for using barcodes in a retail shop. +--- + +Most decently-sized stores will have barcodes on their products. For the store, it makes the checkout process extremely +easy and accurate. For the consumer, barcodes might be useful with a phone app to scan them. I needed to make the +inventory scannable at the [shop][1], and I really wanted to do it in a more meaningful way than 1D barcodes could +support. + + +### Barcodes: 1D vs 2D + +There are two different kinds of barcodes: 1 dimensional and 2 dimensional. The 1D allows for a purely linear scan of +simple, [UPC][2]-like barcodes. While 1D barcodes are extremely commonplace on many products, I dislike them because +they can't provide any context. + +For example, if I were shopping in [Target][3] and scanned a UPC barcode with a regular phone app, it might take me to +the [Amazon][4] listing first - not necessarily great for Target's business, but it also becomes a completely separate +brand channel distracting my thoughts. Another example is when UPCs aren't registered on a product - different retail +stores will make up their own internal barcode which isn't helpful at all if I try to scan it. + +On the otherhand, 2D barcodes require complex parsing but they can hold much more data. [QR codes][5] are one extremely +common form of 2D barcodes and they typically encode URLs. With my goal of providing more context, URLs provide just +that - not only with a domain name, but an arbitrary path. If somebody scanned an item at our shop, they'd at least get +redirected through the shop's website. + +One disadvantage that QR codes have compared to 1D barcodes is their size and resolution requirements. All 1D barcodes +could theoretically be 1 pixel high, but QR codes must be square. To help ensure a reasonable QR codes, most people +will use a URL shortener service - shorter URLs mean simpler QR designs, simpler designs mean the QR code can be read +more easily and doesn't need to be large. + +Another disadvantage to QR codes is that 2D handheld scanners are significantly more expensive than 1D. Fortunately, +many previously-used 2D scanners can be found on [eBay][6] for very reasonable prices. Unfortunately, I found that +some of the used ones would quickly turn unreliable after a period of time. + + +### Mapping URLs to retail "things" + +While inventory was the primary target of barcoding, I really wanted to barcode most things involved with retail +workflows (like order receipts). With that in mind I figured I needed to store three properties: + + * `insignia` - the unique, short identifier (e.g. `EyV3chYax`) + * `target_ref` - the type of "thing" (e.g. `inventory` or `order`) + * `target_id` - the ID of the "thing" (e.g. `010035EA-9F6D-41A2-97C4-EEB5A3F3034A`) + +I created a manager which supports three basic operations (internally it uses a map of the different types of +"things"): + + * `getInsignia($target)` - which returns the short identifier/insignia + * `getTarget($insignia)` - which returns the application object + * `getResponse($insignia)` - which returns an appropriate HTTP response + +I created a couple of HTTP endpoints which utilize the manager: + + * `/io/{insignia}` - which returns the result of `getResponse` (typically a redirect) + * `/io/{insignia}.png` - which returns the QR code image + +Then, whenever I want to print a QR code on a document, I just have to do: + + + Your Receipt for Order #{% raw %}{{ transaction.id }}{% endraw %} + +Further, the QR code can be used with a redirecting short domain for even simpler codes: + + > ![QR Code](http://www.theloopyewe.com/io/EyV3chYax.png?s=2 "http://tle.io/EyV3chYax") + > [`http://tle.io/EyV3chYax`](http://www.theloopyewe.com/io/EyV3chYax) + + +### Adding More Context + +One of the reasons I wanted to use QR codes was context. Aside from scans now landing on the shop's website, they can +be even more context-aware through security roles. For example, if a customer scans the QR code above, they'll end up +on the product page for the shop as you would expect; but if an admin scans it they'll end up on the main inventory +page to see current quantities and recent transactions. + +Or, a better example is with order receipts. If somebody scans their order receipt, they'll be required to login and +then will be taken to their order details page, assuming the order was on their account. If an admin scans the receipt +(perhaps while packing it) they'll be taken to the administrative, detailed view of the order. + +The idea of context doesn't only apply to where a user might end up, it also applies to how they get there. For +example, sometimes there will be more than one bolt of a single fabric pattern, and, since each bolt is a different +"thing" in the system, they each have a different QR code. If a customer scans either of the bolts, they would get +taken to the exact same public product page. However, when an admin scans a bolt they'll get taken to the detailed +view showing which orders were cut on that specific bolt and how much yardage the bolt still has. + + + +### Integrated Context + +At this point, the barcodes were extremely accessible for one-off scans, but I also wanted to integrate the barcodes +into specific points of the system. For the computers we're using USB 2D barcode scanners which are capable of acting +like a keyboard device (the computer sees it "typing" whatever it scans, followed by an Enter). The most useful +integration point was the POS for handling in-store shoppers. + +For the POS, I created a new UI component which auto-focused itself. Once something gets scanned, it sends the scanned +data to the server so it can figure out what should happen. For QR code scans, it performs the insignia lookup to find +the actual inventory item. Then, for simple inventory items it can just add the scanned item to the order. For fabric +on the bolt, it comes back with a dialog about how much to cut. For complex items, it shows a dialog for further +specifications. Or there might just be a discrepancy and it needs to come back and show a message. Once the item is +added it provides visual feedback, the scan field is re-focused and the cycle continues. It works something like the +following in a browser... + +
+
+ + Click to Scan + +
+ + +
+ + +### Conclusion + +I feel like the shop is able to better grow both technically and logistically by having used QR codes as opposed to a +classic barcode system. A few techy customers have tried the QR codes, but it's not really something we've been +promoting. Once the website has a proper mobile-friendly version we'll have a better opportunity and reason to try and +impress customers with the QR codes. In the meantime, the QR codes have been an immense time-saver for both staff and +shoppers checking out at the shop. + + + [1]: http://www.theloopyewe.com/ + [2]: http://en.wikipedia.org/wiki/Universal_Product_Code + [3]: http://www.target.com/ + [4]: http://www.amazon.com/ + [5]: http://en.wikipedia.org/wiki/QR_code + [6]: http://www.ebay.com/