LedgerSync provides ledger-specific resources and operations for you to easily interface with a ledger. Complexity arises for a few reasons, such as the following:
- Ledgers have different resources. Some ledgers may not even implement the same resources as another ledger.
- Resources for a given ledger have different attributes from their counterparts in other ledgers.
- Operations may not be supported in all ledgers (e.g. deletion is not available for some resources in QuickBooks Online)
Because of this complexity, LedgerSync tries to remain “unopinionated” about ledgers. The goal is to have resources, attributes, and operations that match as closely to the API as possible. The issue here is that it requires a developer to have ledger-specific knowledge for every interaction with LedgerSync or to define new resource, operation, and validation layers entirely.
To solve this problem, some engineers at Modern Treasury have created what we call a
ResourceConverter. This object takes in a
destination. It also defines the mapping from source to destination. This makes it easy to take any object and map it to a ledger-specific resource. Having a converter per resource per ledger enables you to create an interface with LedgerSync. After this layer is created, future developers are not required to have ledger-specific knowledge to make updates.
Let’s see how this works.
Let’s assume that we have a
Customer model object that we use internally that looks like the following:
class Customer attr_accessor :name attr_accessor :email attr_accessor :id end
We want to sync the data on this object (specifically
id) to QuickBooks Online and NetSuite. We will also assume that we have already handled authentication and have a valid client for each(
netsuite_client, respectively). Both ledgers implement their own
Customer object, but the attributes for these objects vary. For example, here are the relevant snippets of these resources:
module LedgerSync module Ledgers module QuickBooksOnline class Customer < QuickBooksOnline::Resource attribute :DisplayName, type: LedgerSync::Type::String references_one :PrimaryEmailAddr, to: PrimaryEmailAddr end end end end module LedgerSync module Ledgers module QuickBooksOnline class PrimaryEmailAddr < QuickBooksOnline::Resource attribute :Address, type: LedgerSync::Type::String end end end end
module LedgerSync module Ledgers module NetSuite class Customer < NetSuite::Resource attribute :email, type: LedgerSync::Type::String attribute :companyName, type: LedgerSync::Type::String attribute :firstName, type: LedgerSync::Type::String attribute :lastName, type: LedgerSync::Type::String end end end end
We will ignore for the purposes of this guide that NetSuite requires a `subsidiary` for their `Customer` resource.