Etsy Order Manager

Using Angular and Node

Posted on March 11, 2016 in webdev

See it on Github

The Problem

My wife, Terra, has an Etsy shop that sells planner stickers. She has had it for a few months now, and more and more orders are coming in. It's exciting, but it is also a lot of work to keep track of and ship multiple orders a day.

Etsy looks nice and has some good seller tools, but as I watched Terra's process all the way from getting a sale to shipping the order, I saw some things that could be improved.

  1. She keeps track of which orders she has printed in a text file on her computer. As she completes each one, she checks them off.

  2. She doesn't know ahead of time how many of each sticker sheet she needs to print. For example, let's say she gets 5 orders. Etsy will show them like this:

Customer #1: Sticker Sheet A
Customer #2: Sticker Sheet B
Customer #3: Sticker Sheet A, B, C
Customer #4: Sticker Sheet B, A
Customer #5: Sticker Sheet A, D, C

She could go down the list, printing each sheet as goes, but she can actually fit more than one sticker sheet on a page. So she tries to save paper and time by printing all "Sticker Sheet A's" at the same time and all "Sticker Sheet B's" at the same time. This requires her to scroll up and down quite a bit and keep a mental note of too many things.

I asked her to describe the ideal "Etsy Order Manager" and she helped me come up with this wireframe...

Wireframe

With a layout like this she can always see her progress, and she can see how many of each sticker sheet type remain for her to print.

Using the Etsy API

The Etsy API let me do everything I needed with just one request!

This let me find all of the receipts with an "open" status, which is exactly what Terra looks at to see which orders she needs to ship next. The results of this call included everything I needed except for the name of the buyer and information about the product they orders.

Luckily, this endpoint lets you append "associations" to your request. Here are the associations available for all "receipt" endpoints:

The receipts' transactions contain the buyer name and information about the products they ordered. So, all I had to do to get all this information was add this to my API call: ?includes=Transactions

Then, I just opened up a route on my express server which requested this info from the Etsy API:

app.get('/getReceipts', function(req, res) {

    var getReceipts = new Promise(function(resolve, reject){

    client.auth(process.env.CONSUMER_KEY, process.env.CONSUMER_SECRET).get('/shops/'+process.env.SHOP_NAME+'/receipts/open', {limit: 100, includes: 'Transactions'}, function(err, status, body, headers) {

        if (err) {
            console.log(err);
        }
        if (body) {
            resolve(body.results);
        }
	    
        })
    });

    getReceipts.then( function(receipts){
	res.send(receipts);
        // keep this promise resolution in case I need to add another API call later
    });

});

Then, I could call that server route from my angular controller to put the data into the view:

$scope.getReceipts = function(chosen_date){

        return $http.get('/getReceipts')
            .success(function(data) {
                    storeData(data, chosen_date);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
}

Conclusion

I left quite a bit out in this post. I learned a LOT about angular and node, especially about asynchronous calls. At one point, I believed I had to make a separate call for every single receipt. I found out the hard way that "for" loops don't work the same way in node as they do in other languages, but I've learned to love the asynchronous nature of node. Modules like "async" make API data collection very fast and simple. And angular was the perfect tool for keeping all the checkboxes in sync.

After a few days of work in between classes, here is the final result:

See it on Github


comments powered by Disqus