Skip to content

Commit

Permalink
Avalara error handling (#1968)
Browse files Browse the repository at this point in the history
* Taxcloud doesn't really support getTaxCodes yet

* Ok, calm down

* Taxcloud doesn't really provide taxCodes yet

* Log Tax code errors to Logs collection rather than throwing a Meteor.Error

* Add missing import

* Use name from namespaced provides rather than name

* Pulling tax codes from TaxCloud

* Configure saving taxcloud taxes to db and displaying them
  • Loading branch information
zenweasel authored and kieckhafer committed Mar 13, 2017
1 parent a5c6008 commit 1f882b1
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 51 deletions.
1 change: 1 addition & 0 deletions imports/plugins/core/logging/server/index.js
@@ -1 +1,2 @@
import "./publications";
import "./methods";
39 changes: 39 additions & 0 deletions imports/plugins/core/logging/server/methods.js
@@ -0,0 +1,39 @@
import { Meteor } from "meteor/meteor";
import { Logs } from "/lib/collections";
import { Reaction } from "/server/api";

export function writeToLog(logType, logLevel, logData, source = "client") {
check(logType, String);
check(logLevel, String);
check(logData, Object);

const logEntry = {
logType: logType,
shopId: Reaction.getShopId(),
data: logData,
level: logLevel,
source: source
};
Logs.insert(logEntry);
}

function logError(logType, logData) {
check(logType, String);
check(logData, Object);
if (Roles.userIsInRole(this.userId, ["admin", "owner"])) {
writeToLog(logType, "error", logData);
}
}

function logWarning(logType, logData) {
check(logType, String);
check(logData, Object);
if (Roles.userIsInRole(this.userId, ["admin", "owner"])) {
writeToLog(logType, "warn", logData);
}
}

Meteor.methods({
"logging/logError": logError,
"logging/logWarning": logWarning
});
@@ -1,3 +1,4 @@
import _ from "lodash";
import { Meteor } from "meteor/meteor";
import { ReactiveDict } from "meteor/reactive-dict";
import { Session } from "meteor/session";
Expand Down Expand Up @@ -158,23 +159,27 @@ Template.variantForm.helpers({
"shopId": shopId,
"registry.provides": "taxCodes",
"$where": function () {
const providerName = this.name.split("-")[1];
const providerName = _.filter(this.registry, (o) => o.provides === "taxCodes")[0].name.split("/")[2];
return this.settings[providerName].enabled;
}
});

const taxCodeProvider = _.filter(provider.registry, (o) => o.provides === "taxCodes")[0].name.split("/")[2];
if (provider) {
if (Meteor.subscribe("TaxCodes").ready() && TaxCodes.find({}).count() === 0) {
Meteor.call(provider.settings.taxCodes.getTaxCodeMethod, (error, result) => {
if (error) {
throw new Meteor.Error(`Error calling method ${provider.settings.taxCodes.getTaxCodeMethod}`, error);
if (typeof error === "object") {
Meteor.call("logging/logError", taxCodeProvider, error);
} else {
Meteor.call("logging/logError", taxCodeProvider, { error });
}
} else if (result && Array.isArray(result)) {
result.forEach(function (code) {
Meteor.call("taxes/insertTaxCodes", shopId, code, provider.name, (err) => {
if (err) {
throw new Meteor.Error("Error populating TaxCodes collection", err);
}
return;
});
});
}
Expand All @@ -201,7 +206,7 @@ Template.variantForm.helpers({
return instance.state.get("taxCodes");
},
displayCode: function () {
if (this.taxCode && this.taxCode !== "00000") {
if (this.taxCode && this.taxCode !== "0000") {
return this.taxCode;
}
return i18next.t("productVariant.selectTaxCode");
Expand Down
Expand Up @@ -20,11 +20,13 @@ taxCodes.populateTaxCodes = function (shopId, code, providerName) {
TaxCodes.insert({
id: code.id,
shopId: shopId,
taxCode: code.taxCode,
taxCode: code.taxCode || code.id,
taxCodeProvider: providerName,
ssuta: code.isSSTCertified,
label: code.description,
parent: code.parentTaxCode
title: code.title || "",
label: code.description || code.label,
parent: code.parentTaxCode || code.parent,
children: code.children || []
});
} catch (err) {
throw new Meteor.Error("Error populating TaxCodes collection", err);
Expand Down
Expand Up @@ -51,7 +51,7 @@ function checkConfiguration(packageData = taxCalc.getPackageData()) {
for (const field of requiredFields) {
if (!settings[field]) {
const msg = `The Avalara package cannot function unless ${field} is configured`;
Logger.fatal(msg);
Logger.warn(msg);
Avalogger.error({ error: msg });
isValid = false;
}
Expand Down
2 changes: 1 addition & 1 deletion imports/plugins/included/taxes-taxcloud/server/index.js
Expand Up @@ -4,5 +4,5 @@ import "./i18n";
// TODO decide if we want to use tax codes
// these imports was start a job to import TaxCloud taxCodes

// import "./methods";
import "./methods";
// import "./jobs";
@@ -0,0 +1 @@
import "./methods";
55 changes: 14 additions & 41 deletions imports/plugins/included/taxes-taxcloud/server/methods/methods.js
@@ -1,58 +1,31 @@
import { Meteor } from "meteor/meteor";
import { Match, check } from "meteor/check";
import { HTTP } from "meteor/http";
import { EJSON } from "meteor/ejson";
import { Logger } from "/server/api";
import Reaction from "../../core/taxes/server/api";


Meteor.methods({
/**
* taxes/fetchTIC
* Tax Code fixture data.
* We're using https://taxcloud.net
* just to get an intial import data set
* this service doesn't require taxcloud id
* but other services need authorization
* use TAXCODE_SRC to override source url
* @param {String} url alternate url to fetch TaxCodes from
* @return {undefined}
* @returns {Array} An array of Tax code objects
*/
"taxcloud/getTaxCodes": function (url) {
check(url, Match.Optional(String));
// check(url, Match.Optional(SimpleSchema.RegEx.Url));

// pretty info
if (url) {
Logger.debug("Fetching TaxCodes from source: ", url);
}
// allow for custom taxCodes from alternate sources
const TAXCODE_SRC = url || "https://taxcloud.net/tic/?format=json";
"taxcloud/getTaxCodes": function () {
const taxCodeArray = [];
const TAXCODE_SRC = "https://taxcloud.net/tic/?format=json";
const taxCodes = HTTP.get(TAXCODE_SRC);

if (taxCodes.data && Reaction.Import.taxCode) {
for (json of taxCodes.data.tic_list) {
// transform children and flatten
// first level of tax children
// TODO: is there a need to go further
if (json.tic.children) {
const children = json.tic.children;
delete json.tic.children; // remove child levels for now
// process chilren
for (json of children) {
delete json.tic.children; // remove child levels for now
const taxCode = EJSON.stringify([json.tic]);
Reaction.Import.process(taxCode, ["id", "label"], Reaction.Import.taxCode);
}
if (taxCodes) {
taxCodes.data.tic_list.forEach(function (code) {
if (code.tic.children) {
code.tic.children.forEach(function (child) {
taxCodeArray.push(child.tic);
});
}
// parent code process
const taxCode = EJSON.stringify([json.tic]);
Reaction.Import.process(taxCode, ["id", "label"], Reaction.Import.taxCode);
}
// commit tax records
Reaction.Import.flush();
} else {
throw new Meteor.error("unable to load taxcodes.");
taxCodeArray.push(code.tic);
});
return taxCodeArray;
}
throw new Meteor.Error("Error getting tax codes");
}
});
9 changes: 9 additions & 0 deletions lib/collections/schemas/logs.js
Expand Up @@ -13,6 +13,15 @@ export const Logs = new SimpleSchema({
defaultValue: "info",
allowedValues: ["trace", "debug", "info", "warn", "error", "fatal"]
},
source: {
type: String,
defaultValue: "server",
allowedValues: ["client", "server"],
},
handled: {
type: Boolean,
defaultValue: false
},
data: {
type: Object,
blackbox: true
Expand Down
2 changes: 1 addition & 1 deletion lib/collections/schemas/products.js
Expand Up @@ -268,7 +268,7 @@ export const ProductVariant = new SimpleSchema({
taxCode: {
label: "Tax Code",
type: String,
defaultValue: "00000",
defaultValue: "0000",
optional: true
},
taxDescription: {
Expand Down

0 comments on commit 1f882b1

Please sign in to comment.