-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First draft of file structure, port classes from Compete.
- Loading branch information
Showing
10 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
--color | ||
--format documentation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
source "https://rubygems.org" | ||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
module Rubill | ||
class << self | ||
attr_accessor :configuration | ||
end | ||
|
||
def self.configure | ||
self.configuration ||= Configuration.new | ||
yield(configuration) | ||
end | ||
|
||
class Configuration | ||
attr_accessor :user_name | ||
attr_accessor :password | ||
attr_accessor :dev_key | ||
attr_accessor :org_id | ||
|
||
def to_hash | ||
{ | ||
"user_name" => user_name, | ||
"password" => password, | ||
"dev_key" => dev_key, | ||
"org_id" => org_id, | ||
} | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
module Rubill | ||
class Base | ||
attr_accessor :remote_record | ||
|
||
delegate :[], to: :remote_record | ||
|
||
class NotFound < StandardError; end | ||
|
||
def initialize(remote) | ||
self.remote_record = remote | ||
end | ||
|
||
def self.active | ||
# There is also a way to list only active via the API but it's opaque | ||
# and unlikely to be much faster than doing it in Ruby | ||
all_remote.select do |record| | ||
record[:isActive] == "1" | ||
end | ||
end | ||
|
||
def id | ||
remote_record[:id] | ||
end | ||
|
||
def update | ||
self.class.update(remote_record) | ||
end | ||
|
||
def delete | ||
self.class.delete(remote_record[:id]) | ||
end | ||
|
||
def self.find(id) | ||
new(session.read(remote_class_name, id)) | ||
end | ||
|
||
def self.create(data) | ||
new(session.create(remote_class_name, data.merge({entity: remote_class_name}))) | ||
end | ||
|
||
def self.update(data) | ||
session.update(remote_class_name, data) | ||
end | ||
|
||
def self.delete(id) | ||
session.delete(remote_class_name, id) | ||
end | ||
|
||
def self.all | ||
session.list(remote_class_name) | ||
end | ||
|
||
def self.session | ||
Session.instance | ||
end | ||
|
||
private | ||
|
||
def self.remote_class_name | ||
raise NotImplementedError | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module Rubill | ||
class Bill < Base | ||
def self.send_payment(opts) | ||
session.send_payment(opts) | ||
end | ||
|
||
def self.void_sent_payment(id) | ||
session.void_sent_payment(id) | ||
end | ||
|
||
def self.remote_class_name | ||
"Bill" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
module Rubill | ||
class Customer < Base | ||
def self.find_by_name(name) | ||
record = active_remote.detect do |d| | ||
d[:name] == name | ||
end | ||
|
||
raise NotFound unless record | ||
new(record) | ||
end | ||
|
||
def self.receive_payment(opts) | ||
session.receive_payment(opts) | ||
end | ||
|
||
def self.void_received_payment(id) | ||
session.void_received_payment(id) | ||
end | ||
|
||
def create_credit(amount, description="") | ||
data = { | ||
customerId: remote_record.id, | ||
amount: amount.to_f, | ||
description: description, | ||
paymentType: "5", | ||
paymentDate: Date.today, | ||
} | ||
|
||
self.class.receive_payment(data) | ||
end | ||
|
||
def self.remote_class_name | ||
"Customer" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module Rubill | ||
class Invoice < Base | ||
def amount_paid | ||
amount - amount_due | ||
end | ||
|
||
def amount | ||
# to_s then to_d because it returns a float | ||
remote_record[:amount].to_s.to_d | ||
end | ||
|
||
def amount_due | ||
# to_s then to_d because it returns a float | ||
remote_record[:amountDue].to_s.to_d | ||
end | ||
|
||
def self.invoice_line_item(amount, description, item_id) | ||
{ | ||
entity: "InvoiceLineItem", | ||
quantity: 1, | ||
itemId: item_id, | ||
# must to_f amount otherwise decimal will be converted to string in JSON | ||
price: amount.to_f, | ||
description: description, | ||
} | ||
end | ||
|
||
def self.remote_class_name | ||
"Invoice" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
module Rubill | ||
class Session | ||
include HTTParty | ||
include Singleton | ||
|
||
base_uri "https://api.bill.com/api/v2" | ||
|
||
CREDENTIALS = Rubill.configuration.to_hash | ||
|
||
delegate :_post, to: self | ||
|
||
attr_accessor :session_id | ||
|
||
def initialize | ||
login | ||
end | ||
|
||
def read(entity, id) | ||
_post("/Crud/Read/#{entity}.json", options(id: id)) | ||
end | ||
|
||
def create(entity, object={}) | ||
_post("/Crud/Create/#{entity}.json", options(obj: object)) | ||
end | ||
|
||
def update(entity, object={}) | ||
_post("/Crud/Update/#{entity}.json", options(obj: object)) | ||
end | ||
|
||
def delete(entity, id) | ||
_post("/Crud/Delete/#{entity}.json", options(id: id)) | ||
end | ||
|
||
def receive_payment(opts={}) | ||
_post("/RecordARPayment.json", options(opts)) | ||
end | ||
|
||
def send_payment(opts={}) | ||
_post("/RecordAPPayment.json", options(opts)) | ||
end | ||
|
||
def void_sent_payment(id) | ||
_post("/VoidAPPayment.json", options(sentPayId: id)) | ||
end | ||
|
||
def void_received_payment(id) | ||
_post("/VoidARPayment.json", options(id: id)) | ||
end | ||
|
||
def list(entity) | ||
# Note: this method returns ALL of desired entity, including inactive | ||
result = [] | ||
start = 0 | ||
step = 999 | ||
loop do | ||
chunk = _post("/List/#{entity}.json", options(start: start, max: step)).presence | ||
|
||
if chunk | ||
result += chunk | ||
start += step | ||
else | ||
break | ||
end | ||
end | ||
|
||
result | ||
end | ||
|
||
def login | ||
self.session_id = self.class.login | ||
end | ||
|
||
def self.login | ||
login_options = { | ||
headers: default_headers, | ||
query: { | ||
password: CREDENTIALS["password"], | ||
userName: CREDENTIALS["user_name"], | ||
devKey: CREDENTIALS["dev_key"], | ||
orgId: CREDENTIALS["org_id"], | ||
} | ||
} | ||
login = _post("/Login.json", login_options) | ||
login[:sessionId] | ||
end | ||
|
||
def options(data={}) | ||
{ | ||
headers: self.class.default_headers, | ||
query: { | ||
sessionId: session_id, | ||
devKey: CREDENTIALS["dev_key"], | ||
data: data.to_json, | ||
}, | ||
} | ||
end | ||
|
||
def self.default_headers | ||
{"Content-Type" => "application/x-www-form-urlencoded"} | ||
end | ||
|
||
def self._post(url, options) | ||
result = JSON.parse(post(url, options).body).with_indifferent_access | ||
raise result[:response_data][:error_message] unless result[:response_status] == 0 | ||
result[:response_data] | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Gem::Specification.new do |s| | ||
s.name = 'rubill' | ||
s.version = '0.0.1' | ||
s.date = '2014-09-31' | ||
s.summary = "Interface with Bill.com" | ||
s.description = "A Ruby interface to Bill.com's API" | ||
s.authors = ["Andrew Taber"] | ||
s.email = '[email protected] ' | ||
s.files = ["lib/rubill.rb"] | ||
s.homepage = 'http://rubygems.org/gems/rubill' | ||
s.license = 'MIT' | ||
|
||
s.add_dependency "httparty" | ||
|
||
s.add_development_dependency "rspec" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
require "bundler/setup" | ||
Bundler.setup | ||
|
||
require "rubill" | ||
|
||
RSpec.configure do |c| | ||
end | ||
|