(function() {
  var selectOption = function(selector, value) {
    var options = $('option', selector);
    options.filter(function() {
      return ($(this).text() == value);
    }).prop('selected', true);
  };

  var highlight = function(selector) {
    $(selector).effect('highlight', 1500);
  };

  var setVAT = function(value) {
    var selector = '#purchase_sales_tax_rate';
    selectOption(selector, value);
    highlight(selector);
  };

  var setEcStatus = function(value) {
    var ecStatusOptions = {
      'Non-EC': '#bank_account_entry_ec_status_',
      'EC Goods': '#bank_account_entry_ec_status_2',
      'EC Services': '#bank_account_entry_ec_status_1'
    };

    var ecStatusSelector = ecStatusOptions[value];
    $(ecStatusSelector).prop('checked', true);
    highlight('#ec_status_options');
  };

  var setCategory = function(value) {
    var selector = $('#spending_category');
    selectOption(selector, value);
    highlight(selector);
  };

  var setDescription = function(value) {
    var selector = '#description';
    var descriptionField = $(selector);
    descriptionField.val(value);
    highlight(selector);
  };

  var promptForAnAttachment = function() {
    var selector = '#attachment_form h2';
    $(selector).text('Now upload an attachment!');
    $(selector).css('color', '#f00');
    highlight(selector);
  }

  var tryToExplainTransaction = function() {
    var unexplainedTransactionText = $('.transaction.unexplained').text();

    if (unexplainedTransactionText) {
      var rulesURL = 'https://rawgit.com/freerange/free_agent_transaction_explainer/master/rules.json';
      $.getJSON(rulesURL, function(rules) {
        $(rules).each(function(index, rule) {
          var textToMatch = rule['textToMatch'];
          var description = rule['description'];
          var vat = rule['vat'];
          var category = rule['category'];
          var shouldHaveAttachment = rule['shouldHaveAttachment'];
          var ecStatus = rule['ecStatus'];

          console.log('Testing: ' + textToMatch);
          if (unexplainedTransactionText.match(textToMatch)) {
            console.log('Found: ' + description);

            setVAT(vat);
            setEcStatus(ecStatus);
            setCategory(category);
            setDescription(description);
            if (shouldHaveAttachment) {
              promptForAnAttachment();
            };

            return false; // We don't need to continue having found a match
          };
        });
      });
    } else {
      console.log('Ignoring previously explained transactions');
    };
  }

  tryToExplainTransaction();
})();

@@ -1702,293 +1702,8 @@
 ) %7B%0A
-          var textToMatch = rule%5B'textToMatch'%5D;%0A          var description = rule%5B'description'%5D;%0A          var vat = rule%5B'vat'%5D;%0A          var category = rule%5B'category'%5D;%0A          var shouldHaveAttachment = rule%5B'shouldHaveAttachment'%5D;%0A          var ecStatus = rule%5B'ecStatus'%5D;%0A%0A
     
@@ -1734,16 +1734,21 @@
 ng: ' + 
+rule.
 textToMa
@@ -1800,16 +1800,21 @@
 t.match(
+rule.
 textToMa
@@ -1857,16 +1857,21 @@
 nd: ' + 
+rule.
 descript
@@ -1896,16 +1896,21 @@
  setVAT(
+rule.
 vat);%0A  
@@ -1931,16 +1931,21 @@
 cStatus(
+rule.
 ecStatus
@@ -1971,16 +1971,21 @@
 ategory(
+rule.
 category
@@ -2014,16 +2014,21 @@
 ription(
+rule.
 descript
@@ -2049,16 +2049,21 @@
     if (
+rule.
 shouldHa

Simplify by using object properties instead of dictionary lookup.