huginn_xero_agent 0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f8fa7c298f35b0481e97e5444162566836ee87b6
4
+ data.tar.gz: e0906c462cc539d1a8433864578547f21f3a5804
5
+ SHA512:
6
+ metadata.gz: 882691fc0a528cc67425e87d6ba14b1be81b2828b995f8112435233c41020f8b6027ec3d1a9baa502d7e216a892d09e4fe3037895c1e0efdc12adab63559ea7d
7
+ data.tar.gz: 1e983e090c697b4ebfd4934493c4aa970d4437aa1fba77536b04075593bc8ea15f8801f1dbeaed72fae41d09064e6fa83fd6fc8c2a90ad9117ca3204e0444a3d
data/LICENSE.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2017 Andrew Cantino
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,4 @@
1
+ require 'huginn_agent'
2
+
3
+ #HuginnAgent.load 'huginn_xero_agent/concerns/my_agent_concern'
4
+ HuginnAgent.register 'huginn_xero_agent/xero_agent'
@@ -0,0 +1,90 @@
1
+ require 'xero_gateway'
2
+
3
+ module Agents
4
+ class XeroAgent < Agent
5
+ cannot_be_scheduled!
6
+
7
+ gem_dependency_check { defined?(XeroGateway) }
8
+
9
+ description <<-MD
10
+ Create Invoices in Xero based on incoming Events.
11
+
12
+ See [this Agent's GitHub page](https://github.com/cantino/huginn_xero_agent) for instructions on setting up this Agent to access your Xero data.
13
+
14
+ All options support [Liquid templating](https://github.com/huginn/huginn/wiki/Formatting-Events-using-Liquid).
15
+
16
+ Options
17
+
18
+ * `expected_receive_period_in_days` - How often you expect data to be received by this Agent from other Agents.
19
+ * `due_in_days` - The number of days from now when the invoice is due.
20
+ * The options `contact_name`, `contact_phone_number`, `contact_email`, `contact_address_line_1`, `contact_address_line_2`, `contact_address_city`, `contact_address_region`, `contact_address_country`, and `contact_address_post_code` allow setting details for a new contact.
21
+ * You can set an `item_path` if you'd like to create multiple invoices, one per record at that [JSONPath](http://goessner.net/articles/JsonPath/).
22
+ * The options `item_description`, `item_account_code`, and `item_amount` allow configuring of invoice details and can contain [Liquid templating](https://github.com/huginn/huginn/wiki/Formatting-Events-using-Liquid), allowing you to make them dynamic based on Event input.
23
+ MD
24
+
25
+ def default_options
26
+ {
27
+ due_in_days: 14,
28
+ contact_name: '{{name}}',
29
+ contact_phone_number: '{{phone}}',
30
+ contact_email: '{{email}}',
31
+ item_path: 'items',
32
+ item_description: 'Widget',
33
+ item_account_code: '123',
34
+ item_amount: 20,
35
+ expected_receive_period_in_days: 10
36
+ }
37
+ end
38
+
39
+ def working?
40
+ last_receive_at && last_receive_at > options['expected_receive_period_in_days'].to_i.days.ago && !recent_error_logs?
41
+ end
42
+
43
+ def validate_options
44
+ errors.add(:base, "due_in_days must be a number") if options['due_in_days'].present? && options['due_in_days'].to_s !~ /\A\d+\z/
45
+ errors.add(:base, "item_description and item_amount are required") unless options['item_description'].present? && options['item_amount'].present?
46
+ errors.add(:base, "expected_receive_period_in_days is required") unless options['expected_receive_period_in_days'].present?
47
+ end
48
+
49
+ def gateway
50
+ @gateway ||= XeroGateway::PrivateApp.new(ENV['XERO_CONSUMER_KEY'], ENV['XERO_CONSUMER_SECRET'], ENV['XERO_PRIVATE_KEY_PATH'])
51
+ end
52
+
53
+ def receive(incoming_events)
54
+ incoming_events.each do |event|
55
+ invoice = create_invoice(event)
56
+ create_event payload: { id: invoice.invoice_id }
57
+ end
58
+ end
59
+
60
+ def create_invoice(event)
61
+ interpolate_with(event.payload) do
62
+ invoice = gateway.build_invoice({
63
+ invoice_type: "ACCREC",
64
+ due_date: (interpolated['due_in_days'].presence || 14).to_i.days.from_now
65
+ })
66
+ invoice.contact.name = interpolated['contact_name'].presence
67
+ invoice.contact.phone.number = interpolated['contact_phone_number'].presence
68
+ invoice.contact.email = interpolated['contact_email'].presence
69
+ invoice.contact.address.line_1 = interpolated['contact_address_line_1'].presence
70
+ invoice.contact.address.line_2 = interpolated['contact_address_line_2'].presence
71
+ invoice.contact.address.city = interpolated['contact_address_city'].presence
72
+ invoice.contact.address.region = interpolated['contact_address_region'].presence
73
+ invoice.contact.address.country = interpolated['contact_address_country'].presence
74
+ invoice.contact.address.post_code = interpolated['contact_address_post_code'].presence
75
+
76
+ [Utils.value_at(event.payload, interpolated['item_path']) || {}].flatten.each do |item|
77
+ line_item = XeroGateway::LineItem.new(
78
+ :description => interpolated(item)['item_description'],
79
+ :account_code => interpolated(item)['item_account_code'].presence,
80
+ :unit_amount => interpolated(item)['item_amount']
81
+ )
82
+ invoice.line_items << line_item
83
+ end
84
+
85
+ invoice.create
86
+ invoice
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,46 @@
1
+ require 'rails_helper'
2
+ require 'huginn_agent/spec_helper'
3
+
4
+ describe Agents::XeroAgent do
5
+ before(:each) do
6
+ @valid_options = Agents::XeroAgent.new.default_options
7
+ @checker = Agents::XeroAgent.new(:name => "XeroAgent", :options => @valid_options)
8
+ @checker.user = users(:bob)
9
+ @checker.save!
10
+ end
11
+
12
+ describe "validation" do
13
+ before do
14
+ expect(@checker).to be_valid
15
+ end
16
+
17
+ it "should validate integer nature of due_in_days" do
18
+ @checker.options[:due_in_days] = "a"
19
+ expect(@checker).not_to be_valid
20
+
21
+ @checker.options[:due_in_days] = "1.1"
22
+ expect(@checker).not_to be_valid
23
+
24
+ @checker.options[:due_in_days] = "1"
25
+ expect(@checker).to be_valid
26
+
27
+ @checker.options[:due_in_days] = 1
28
+ expect(@checker).to be_valid
29
+ end
30
+
31
+ it "should validate presence of expected_receive_period_in_days" do
32
+ @checker.options[:expected_receive_period_in_days] = nil
33
+ expect(@checker).not_to be_valid
34
+ end
35
+
36
+ it "should validate presence of item_description" do
37
+ @checker.options[:item_description] = nil
38
+ expect(@checker).not_to be_valid
39
+ end
40
+
41
+ it "should validate presence of item_amount" do
42
+ @checker.options[:item_amount] = nil
43
+ expect(@checker).not_to be_valid
44
+ end
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: huginn_xero_agent
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Cantino
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: huginn_agent
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: xero_gateway
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - cantino@users.noreply.github.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - LICENSE.txt
77
+ - lib/huginn_xero_agent.rb
78
+ - lib/huginn_xero_agent/xero_agent.rb
79
+ - spec/xero_agent_spec.rb
80
+ homepage: https://github.com/cantino/huginn_xero_agent
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.6.13
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Huginn Agent for interfacing with Xero
104
+ test_files:
105
+ - spec/xero_agent_spec.rb