rconomic 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/.travis.yml +11 -0
  2. data/Gemfile +8 -0
  3. data/Gemfile.lock +54 -0
  4. data/LICENSE +19 -0
  5. data/README.md +74 -0
  6. data/Rakefile +7 -0
  7. data/lib/economic/current_invoice.rb +78 -0
  8. data/lib/economic/current_invoice_line.rb +47 -0
  9. data/lib/economic/debtor.rb +51 -0
  10. data/lib/economic/economic.wsdl +56858 -0
  11. data/lib/economic/entity.rb +167 -0
  12. data/lib/economic/proxies/current_invoice_line_proxy.rb +28 -0
  13. data/lib/economic/proxies/current_invoice_proxy.rb +38 -0
  14. data/lib/economic/proxies/debtor_proxy.rb +40 -0
  15. data/lib/economic/proxies/entity_proxy.rb +61 -0
  16. data/lib/economic/session.rb +59 -0
  17. data/lib/rconomic/version.rb +3 -0
  18. data/lib/rconomic.rb +26 -0
  19. data/rconomic.gemspec +26 -0
  20. data/spec/economic/current_invoice_line_spec.rb +10 -0
  21. data/spec/economic/current_invoice_spec.rb +59 -0
  22. data/spec/economic/debtor_spec.rb +43 -0
  23. data/spec/economic/entity_spec.rb +179 -0
  24. data/spec/economic/proxies/current_invoice_line_proxy_spec.rb +77 -0
  25. data/spec/economic/proxies/current_invoice_proxy_spec.rb +64 -0
  26. data/spec/economic/proxies/debtor_proxy_spec.rb +74 -0
  27. data/spec/economic/session_spec.rb +64 -0
  28. data/spec/fixtures/connect/success.xml +8 -0
  29. data/spec/fixtures/current_invoice_create_from_data/success.xml +10 -0
  30. data/spec/fixtures/current_invoice_get_data/success.xml +73 -0
  31. data/spec/fixtures/current_invoice_line_get_data/success.xml +39 -0
  32. data/spec/fixtures/debtor_find_by_ci_number/many.xml +15 -0
  33. data/spec/fixtures/debtor_get_data/success.xml +54 -0
  34. data/spec/fixtures/debtor_get_next_available_number/success.xml +8 -0
  35. data/spec/fixtures/spec_entity_create_from_data/success.xml +10 -0
  36. data/spec/fixtures/spec_entity_get_data/success.xml +11 -0
  37. data/spec/fixtures/spec_entity_update_from_data/success.xml +10 -0
  38. data/spec/fixtures/wsdl.xml +56596 -0
  39. data/spec/spec_helper.rb +97 -0
  40. metadata +135 -0
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ # Specify which ruby versions you wish to run your tests on, each version will be used
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - ree
6
+ - rbx
7
+
8
+ # Specify the recipients for email notification
9
+ notifications:
10
+ recipients:
11
+ - jakob@mentalized.net
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rake'
7
+ gem 'savon_spec', '0.1.6'
8
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rconomic (0.1.0)
5
+ activesupport (~> 3.0)
6
+ savon (= 0.9.5)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ activesupport (3.0.9)
12
+ akami (1.0.0)
13
+ gyoku (>= 0.4.0)
14
+ builder (3.0.0)
15
+ diff-lcs (1.1.2)
16
+ gyoku (0.4.4)
17
+ builder (>= 2.1.2)
18
+ httpi (0.9.5)
19
+ rack
20
+ mocha (0.9.12)
21
+ nokogiri (1.5.0)
22
+ nori (1.0.2)
23
+ rack (1.3.0)
24
+ rake (0.9.2)
25
+ rspec (2.6.0)
26
+ rspec-core (~> 2.6.0)
27
+ rspec-expectations (~> 2.6.0)
28
+ rspec-mocks (~> 2.6.0)
29
+ rspec-core (2.6.4)
30
+ rspec-expectations (2.6.0)
31
+ diff-lcs (~> 1.1.2)
32
+ rspec-mocks (2.6.0)
33
+ savon (0.9.5)
34
+ akami (~> 1.0)
35
+ builder (>= 2.1.2)
36
+ gyoku (>= 0.4.0)
37
+ httpi (~> 0.9)
38
+ nokogiri (>= 1.4.0)
39
+ nori (~> 1.0)
40
+ wasabi (~> 1.0)
41
+ savon_spec (0.1.6)
42
+ mocha (>= 0.9.8)
43
+ rspec (>= 2.0.0)
44
+ savon (>= 0.8.0)
45
+ wasabi (1.0.0)
46
+ nokogiri (>= 1.4.0)
47
+
48
+ PLATFORMS
49
+ ruby
50
+
51
+ DEPENDENCIES
52
+ rake
53
+ rconomic!
54
+ savon_spec (= 0.1.6)
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Lokalebasen.dk A/S
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ r-conomic
2
+ =========
3
+
4
+ Ruby wrapper for the [e-conomic](http://www.e-conomic.co.uk) SOAP API, that aims at making working with the API bearable.
5
+
6
+ E-conomic is a web-based accounting system. For their marketing speak, see [http://www.e-conomic.co.uk/about/](). More details about their API at [http://www.e-conomic.co.uk/integration/integration-partner/]().
7
+
8
+
9
+ Usage example
10
+ -------------
11
+
12
+ economic = Economic::Session.new(123456, 'API', 'passw0rd')
13
+ economic.connect
14
+
15
+ # Find a debtor:
16
+ debtor = economic.debtors.find(101)
17
+
18
+ # Creating a debtor:
19
+ debtor = economic.debtors.build
20
+
21
+ debtor.number = economic.debtors.next_available_number
22
+ debtor.debtor_group_handle = { :number => 1 }
23
+ debtor.name = 'Bob'
24
+ debtor.vat_zone = 'HomeCountry' # HomeCountry, EU, Abroad
25
+ debtor.currency_handle = { :code => 'DKK' }
26
+ debtor.price_group_handle = { :number => 1 }
27
+ debtor.is_accessible = true
28
+ debtor.ci_number = '12345678'
29
+ debtor.term_of_payment_handle = { :id => 1 }
30
+ debtor.layout_handle = { :id => 16 }
31
+ debtor.save
32
+
33
+ # Create invoice for debtor:
34
+ invoice = economic.current_invoices.build
35
+ invoice.date = Time.now
36
+ invoice.due_date = Time.now + 15
37
+ invoice.exchange_rate = 100
38
+ invoice.is_vat_included = false
39
+
40
+ invoice_line = Economic::CurrentInvoiceLine.new
41
+ invoice_line.description = 'Line on invoice'
42
+ invoice_line.unit_handle = { :number => 1 }
43
+ invoice_line.product_handle = { :number => 101 }
44
+ invoice_line.quantity = 12
45
+ invoice_line.unit_net_price = 19.95
46
+ invoice.lines << invoice_line
47
+
48
+ invoice.save
49
+
50
+
51
+ How to enable e-conomic API access
52
+ ----------------------------------
53
+
54
+ You need to enable API access in e-conomic before you can, well, use the API. Otherwise you'll be getting access denied errors when connecting.
55
+
56
+ Just follow the instructions on [e-copedia](http://wiki.e-conomic.co.uk/add-on-modules/) to enable the API Add-on module.
57
+
58
+
59
+ It doesn't do everything
60
+ ------------------------
61
+
62
+ Not even remotely... For now, limited to a small subset of all the [available operations](https://www.e-conomic.com/secure/api1/EconomicWebService.asmx):
63
+
64
+ | Create | Read | Update
65
+ -------------------+--------+------+-------
66
+ Debtor | X | X | X
67
+ CurrentInvoice | X | X | X
68
+ CurrentInvoiceLine | X | X | X
69
+
70
+
71
+ Credits
72
+ -------
73
+
74
+ Sponsored by [Lokalebasen.dk](http://lokalebasen.dk)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,78 @@
1
+ require 'economic/entity'
2
+
3
+ module Economic
4
+
5
+ # Current invoices are invoices that are not yet booked. They are therefore not read-only.
6
+ #
7
+ # http://www.e-conomic.com/apidocs/Documentation/T_Economic_Api_ICurrentInvoice.html
8
+ class CurrentInvoice < Entity
9
+ has_properties :id, :debtor_handle, :debtor_name, :debtor_address, :debtor_postal_code, :debtor_city, :debtor_country, :date, :term_of_payment_handle, :due_date, :currency_handle, :exchange_rate, :is_vat_included, :layout_handle, :delivery_date, :net_amount, :vat_amount, :gross_amount, :margin, :margin_as_percent
10
+
11
+ def initialize(properties = {})
12
+ super
13
+ end
14
+
15
+ # Returns the current invoice lines of CurrentInvoice
16
+ def lines
17
+ @lines ||= CurrentInvoiceLineProxy.new(self)
18
+ end
19
+
20
+ def initialize_defaults
21
+ self.id = 0
22
+ self.date = Time.now
23
+ self.term_of_payment_handle = nil
24
+ self.due_date = nil
25
+ self.currency_handle = nil
26
+ self.exchange_rate = 100 # Why am _I_ inputting this?
27
+ self.is_vat_included = nil
28
+ self.layout_handle = nil
29
+ self.delivery_date = nil
30
+ self.net_amount = 0
31
+ self.vat_amount = 0
32
+ self.gross_amount = 0
33
+ self.margin = 0
34
+ self.margin_as_percent = 0 # Why do I have to input both Margin and MarginAsPercent? Shouldn't powerful Windows machines running ASP.NET be able to compute this?
35
+ end
36
+
37
+ # Returns OrderedHash with the properties of CurrentInvoice in the correct order, camelcased and ready
38
+ # to be sent via SOAP
39
+ def build_soap_data
40
+ data = ActiveSupport::OrderedHash.new
41
+
42
+ data['Id'] = id
43
+ data['DebtorHandle'] = { 'Number' => debtor_handle[:number] } unless debtor_handle.blank?
44
+ data['DebtorName'] = debtor_name
45
+ data['DebtorAddress'] = debtor_address unless debtor_address.blank?
46
+ data['DebtorPostalCode'] = debtor_postal_code unless debtor_postal_code.blank?
47
+ data['DebtorCity'] = debtor_city unless debtor_city.blank?
48
+ data['DebtorCountry'] = debtor_country unless debtor_country.blank?
49
+ data['Date'] = date.iso8601 unless date.blank?
50
+ data['TermOfPaymentHandle'] = { 'Id' => term_of_payment_handle[:id] } unless term_of_payment_handle.blank?
51
+ data['DueDate'] = due_date.iso8601 unless due_date.blank?
52
+ data['CurrencyHandle'] = { 'Code' => currency_handle[:code] } unless currency_handle.blank?
53
+ data['ExchangeRate'] = exchange_rate
54
+ data['IsVatIncluded'] = is_vat_included
55
+ data['LayoutHandle'] = { 'Id' => layout_handle[:id] } unless layout_handle.blank?
56
+ data['DeliveryDate'] = delivery_date ? delivery_date.iso8601 : nil
57
+ data['NetAmount'] = net_amount
58
+ data['VatAmount'] = vat_amount
59
+ data['GrossAmount'] = gross_amount
60
+ data['Margin'] = margin
61
+ data['MarginAsPercent'] = margin_as_percent
62
+
63
+ return data
64
+ end
65
+
66
+ def save
67
+ result = super
68
+ id = result[:id]
69
+
70
+ self.lines.each do |invoice_line|
71
+ invoice_line.session = session
72
+ invoice_line.invoice_handle = { :id => id }
73
+ invoice_line.save
74
+ end
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,47 @@
1
+ require 'economic/entity'
2
+ require 'economic/current_invoice'
3
+
4
+ module Economic
5
+
6
+ class CurrentInvoiceLine < Entity
7
+ has_properties :invoice_handle, :description, :delivery_date, :unit_handle, :product_handle, :quantity, :unit_net_price, :discount_as_percent, :unit_cost_price, :total_net_amount, :total_margin, :margin_as_percent
8
+
9
+ def initialize_defaults
10
+ self.invoice_handle = nil
11
+ self.description = nil
12
+ self.delivery_date = nil
13
+ self.unit_handle = nil
14
+ self.product_handle = nil
15
+ self.quantity = nil
16
+ self.unit_net_price = nil
17
+ self.discount_as_percent = 0
18
+ self.unit_cost_price = 0
19
+ self.total_net_amount = nil
20
+ self.total_margin = 0
21
+ self.margin_as_percent = 0
22
+ end
23
+
24
+ # Returns OrderedHash with the properties of CurrentInvoice in the correct order, camelcased and ready
25
+ # to be sent via SOAP
26
+ def build_soap_data
27
+ data = ActiveSupport::OrderedHash.new
28
+
29
+ data['Number'] = 0 # Doesn't seem to be used
30
+ data['InvoiceHandle'] = { 'Id' => invoice_handle[:id] } unless invoice_handle.blank?
31
+ data['Description'] = description unless description.blank?
32
+ data['DeliveryDate'] = delivery_date
33
+ data['UnitHandle'] = { 'Number' => unit_handle[:number] } unless unit_handle.blank?
34
+ data['ProductHandle'] = { 'Number' => product_handle[:number] } unless product_handle.blank?
35
+ data['Quantity'] = quantity unless quantity.blank?
36
+ data['UnitNetPrice'] = unit_net_price unless unit_net_price.blank?
37
+ data['DiscountAsPercent'] = discount_as_percent unless discount_as_percent.blank?
38
+ data['UnitCostPrice'] = unit_cost_price unless unit_cost_price.blank?
39
+ data['TotalNetAmount'] = total_net_amount
40
+ data['TotalMargin'] = total_margin unless total_margin.blank?
41
+ data['MarginAsPercent'] = margin_as_percent unless margin_as_percent.blank?
42
+
43
+ return data
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,51 @@
1
+ require 'economic/entity'
2
+
3
+ module Economic
4
+
5
+ class Debtor < Entity
6
+ has_properties :handle, :number, :debtor_group_handle, :name, :vat_zone, :currency_handle, :price_group_handle, :is_accessible, :ean, :public_entry_number, :email, :telephone_and_fax_number, :website, :address, :postal_code, :city, :country, :credit_maximum, :vat_number, :county, :ci_number, :term_of_payment_handle, :layout_handle, :attention_handle, :your_reference_handle, :our_reference_handle, :balance
7
+
8
+ # Provides access to the current invoices - ie invoices that haven't yet been booked
9
+ def current_invoices
10
+ @current_invoices ||= CurrentInvoiceProxy.new(self)
11
+ end
12
+
13
+ protected
14
+
15
+ def build_soap_data
16
+ data = ActiveSupport::OrderedHash.new
17
+
18
+ data['Handle'] = { 'Number' => number }
19
+ data['Number'] = number
20
+ data['DebtorGroupHandle'] = { 'Number' => debtor_group_handle[:number] } unless debtor_group_handle.blank?
21
+ data['Name'] = name
22
+ data['VatZone'] = vat_zone
23
+ data['CurrencyHandle'] = { 'Code' => currency_handle[:code] } unless currency_handle.blank?
24
+ data['PriceGroupHandle'] = { 'Number' => price_group_handle[:number] } unless price_group_handle.blank?
25
+ data['IsAccessible'] = is_accessible
26
+ data['Ean'] = ean unless ean.blank?
27
+ data['PublicEntryNumber'] = public_entry_number unless public_entry_number.blank?
28
+ data['Email'] = email unless email.blank?
29
+ data['TelephoneAndFaxNumber'] = telephone_and_fax_number unless telephone_and_fax_number.blank?
30
+ data['Website'] = website unless website.blank?
31
+ data['Address'] = address unless address.blank?
32
+ data['PostalCode'] = postal_code unless postal_code.blank?
33
+ data['City'] = city unless city.blank?
34
+ data['Country'] = country unless country.blank?
35
+ data['CreditMaximum'] = credit_maximum unless credit_maximum.blank?
36
+ data['VatNumber'] = vat_number unless vat_number.blank?
37
+ data['County'] = county unless county.blank?
38
+ data['CINumber'] = ci_number unless ci_number.blank?
39
+ data['TermOfPaymentHandle'] = { 'Id' => term_of_payment_handle[:id] } unless term_of_payment_handle.blank?
40
+ data['LayoutHandle'] = { 'Id' => layout_handle[:id] } unless layout_handle.blank?
41
+ data['AttentionHandle'] = attention_handle unless attention_handle.blank?
42
+ data['YourReferenceHandle'] = your_reference_handle unless your_reference_handle.blank?
43
+ data['OurReferenceHandle'] = our_reference_handle unless our_reference_handle.blank?
44
+ data['Balance'] = balance unless balance.blank?
45
+
46
+ return data
47
+ end
48
+
49
+ end
50
+
51
+ end