bill_forward 1.2014.296

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/.gitignore +27 -0
  2. data/.idea/.name +1 -0
  3. data/.idea/compiler.xml +23 -0
  4. data/.idea/copyright/profiles_settings.xml +3 -0
  5. data/.idea/encodings.xml +5 -0
  6. data/.idea/inspectionProfiles/Project_Default.xml +11 -0
  7. data/.idea/inspectionProfiles/profiles_settings.xml +7 -0
  8. data/.idea/misc.xml +23 -0
  9. data/.idea/modules.xml +9 -0
  10. data/.idea/scopes/scope_settings.xml +5 -0
  11. data/.idea/vcs.xml +7 -0
  12. data/.rspec +2 -0
  13. data/Gemfile +9 -0
  14. data/LICENSE.md +22 -0
  15. data/README.md +227 -0
  16. data/Rakefile +73 -0
  17. data/bill_forward.gemspec +29 -0
  18. data/bill_forward.iml +28 -0
  19. data/lib/bill_forward.rb +18 -0
  20. data/lib/bill_forward/billing_entity.rb +263 -0
  21. data/lib/bill_forward/client.rb +355 -0
  22. data/lib/bill_forward/custom_hash.rb +14 -0
  23. data/lib/bill_forward/deny_method.rb +4 -0
  24. data/lib/bill_forward/entities/account.rb +19 -0
  25. data/lib/bill_forward/entities/address.rb +25 -0
  26. data/lib/bill_forward/entities/amendments/amendment.rb +11 -0
  27. data/lib/bill_forward/entities/amendments/invoice_recalculation_amendment.rb +10 -0
  28. data/lib/bill_forward/entities/api_configuration.rb +11 -0
  29. data/lib/bill_forward/entities/authorize_net_token.rb +9 -0
  30. data/lib/bill_forward/entities/credit_note.rb +13 -0
  31. data/lib/bill_forward/entities/invoice.rb +25 -0
  32. data/lib/bill_forward/entities/invoice_parts/invoice_line.rb +37 -0
  33. data/lib/bill_forward/entities/invoice_parts/invoice_payment.rb +29 -0
  34. data/lib/bill_forward/entities/invoice_parts/tax_line.rb +23 -0
  35. data/lib/bill_forward/entities/invoice_parts/taxation_link.rb +5 -0
  36. data/lib/bill_forward/entities/organisation.rb +37 -0
  37. data/lib/bill_forward/entities/payment_method.rb +5 -0
  38. data/lib/bill_forward/entities/payment_method_subscription_link.rb +5 -0
  39. data/lib/bill_forward/entities/pricing_component.rb +21 -0
  40. data/lib/bill_forward/entities/pricing_component_tier.rb +5 -0
  41. data/lib/bill_forward/entities/pricing_component_value.rb +5 -0
  42. data/lib/bill_forward/entities/pricing_component_value_change.rb +5 -0
  43. data/lib/bill_forward/entities/product.rb +5 -0
  44. data/lib/bill_forward/entities/product_rate_plan.rb +19 -0
  45. data/lib/bill_forward/entities/profile.rb +15 -0
  46. data/lib/bill_forward/entities/role.rb +4 -0
  47. data/lib/bill_forward/entities/subscription.rb +53 -0
  48. data/lib/bill_forward/entities/unit_of_measure.rb +5 -0
  49. data/lib/bill_forward/insertable_entity.rb +32 -0
  50. data/lib/bill_forward/mutable_entity.rb +47 -0
  51. data/lib/bill_forward/resource_path.rb +11 -0
  52. data/lib/bill_forward/type_check.rb +21 -0
  53. data/lib/bill_forward/version.rb +4 -0
  54. data/spec/component/account_spec.rb +200 -0
  55. data/spec/component/billing_entity_spec.rb +153 -0
  56. data/spec/component/invoice_spec.rb +155 -0
  57. data/spec/component/subscription_spec.rb +357 -0
  58. data/spec/functional/account_spec.rb +25 -0
  59. data/spec/functional/bad_citizen/account_spec.rb +103 -0
  60. data/spec/functional/bad_citizen/credit_note_spec.rb +41 -0
  61. data/spec/functional/bad_citizen/payment_method_spec.rb +34 -0
  62. data/spec/functional/bad_citizen/product_rate_plan_spec.rb +105 -0
  63. data/spec/functional/bad_citizen/product_spec.rb +22 -0
  64. data/spec/functional/bad_citizen/situational/authorize_net_token_spec.rb +27 -0
  65. data/spec/functional/bad_citizen/situational/invoice_recalculation_amendment_spec.rb +27 -0
  66. data/spec/functional/bad_citizen/situational/invoice_spec.rb +22 -0
  67. data/spec/functional/bad_citizen/situational/malordered_entity_spec.rb +43 -0
  68. data/spec/functional/bad_citizen/situational/organisation_spec.rb +39 -0
  69. data/spec/functional/bad_citizen/situational/payment_method_spec.rb +47 -0
  70. data/spec/functional/bad_citizen/situational/subscription_chargeable_spec.rb +255 -0
  71. data/spec/functional/bad_citizen/subscription_spec.rb +179 -0
  72. data/spec/functional/bad_citizen/subscription_with_credit_spec.rb +240 -0
  73. data/spec/functional/bad_citizen/unit_of_measure_spec.rb +20 -0
  74. data/spec/functional/billing_entity_spec.rb +22 -0
  75. data/spec/functional/client_spec.rb +24 -0
  76. data/spec/functional/organisation_spec.rb +28 -0
  77. data/spec/setup_test_constants.rb +73 -0
  78. data/spec/spec_helper.rb +11 -0
  79. data/spec/syntax/account_spec.rb +24 -0
  80. data/spec/syntax/address_spec.rb +19 -0
  81. data/spec/syntax/api_configuration_spec.rb +13 -0
  82. data/spec/syntax/billing_entity_spec.rb +93 -0
  83. data/spec/syntax/client_spec.rb +8 -0
  84. metadata +287 -0
@@ -0,0 +1,14 @@
1
+ module BillForward
2
+ # Note: does not use indifferent access! Only entities themselves have indifferent access!
3
+ class OrderedHashWithDotAccess < ActiveSupport::OrderedHash
4
+ def method_missing(method_id, *arguments, &block)
5
+ # no call to super; our criteria is all keys.
6
+ #setter
7
+ if /^(\w+)=$/ =~ method_id.to_s
8
+ return self[$1] = arguments.first
9
+ end
10
+ #getter
11
+ self[method_id.to_s]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ module BillForward
2
+ class DenyMethod < StandardError
3
+ end
4
+ end
@@ -0,0 +1,19 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # Role[] .roles
5
+ # PaymentMethod[] .paymentMethods
6
+ # Profile .profile
7
+ class Account < MutableEntity
8
+ @resource_path = BillForward::ResourcePath.new("accounts", "account")
9
+
10
+ protected
11
+ def unserialize_all(hash)
12
+ super
13
+ unserialize_entity('profile', Profile, hash)
14
+
15
+ unserialize_array_of_entities('roles', Role, hash)
16
+ unserialize_array_of_entities('paymentMethods', PaymentMethod, hash)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module BillForward
2
+ class Address < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new('addresses', 'address')
4
+
5
+ class << self
6
+ def get_by_id(id, query_params = {}, customClient = nil)
7
+ raise DenyMethod.new 'Get by ID support is denied for this entity; '+
8
+ 'at the time of writing, no API endpoint exists to support it.'+
9
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
10
+ end
11
+
12
+ def get_all(query_params = {}, customClient = nil)
13
+ raise DenyMethod.new 'Get All support is denied for this entity; '+
14
+ 'at the time of writing, no API endpoint exists to support it.'+
15
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
16
+ end
17
+ end
18
+
19
+ def save()
20
+ raise DenyMethod.new 'Save support is denied for this entity; '+
21
+ 'at the time of writing, the provided API endpoint is not functioning.'+
22
+ 'The entity can be saved through cascade only (i.e. save a related entity).'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module BillForward
2
+ class Amendment < InsertableEntity
3
+ @resource_path = BillForward::ResourcePath.new("amendments", "amendment")
4
+
5
+ def initialize(*args)
6
+ raise AbstractInstantiateError.new('This abstract class cannot be instantiated!') if self.class == Amendment
7
+ super
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module BillForward
2
+ class InvoiceRecalculationAmendment < Amendment
3
+ @resource_path = BillForward::ResourcePath.new("amendments", "amendment")
4
+
5
+ def initialize(*args)
6
+ super
7
+ set_state_param('@type', 'InvoiceRecalculationAmendment')
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module BillForward
2
+ class APIConfiguration < MutableEntity
3
+ class << self
4
+ def create(entity = nil)
5
+ raise DenyMethod.new 'Create support is denied for this entity; '+
6
+ 'at the time of writing, no API endpoint exists to support it. '+
7
+ 'The entity can be created through cascade only (i.e. instantiated within another entity).'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module BillForward
2
+ class AuthorizeNetToken < MutableEntity
3
+ # WARNING: resource paths for AuthorizeNetTokens do not follow the usual pattern;
4
+ # instead of posting to 'root' of a URL root reserved for AuthorizeNetTokens,
5
+ # this routing is a bit less standard; for example we can't GET from the same
6
+ # place we POST to.
7
+ @resource_path = BillForward::ResourcePath.new('vaulted-gateways/authorize-net', 'authorizeNetToken')
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module BillForward
2
+ class CreditNote < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new('credit-notes', 'creditNote')
4
+
5
+ class << self
6
+ def get_all(query_params = {}, customClient = nil)
7
+ raise DenyMethod.new 'Get All support is denied for this entity; '+
8
+ 'at the time of writing, no API endpoint exists to support it.'+
9
+ 'The entity can be GETted by ID only.'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # InvoiceLine[] .invoiceLines
5
+ # TaxLine[] .taxLines
6
+ # InvoicePayment[] .invoicePayments
7
+ class Invoice < MutableEntity
8
+ @resource_path = BillForward::ResourcePath.new('invoices', 'invoice')
9
+
10
+ class << self
11
+ def create(entity = nil)
12
+ raise DenyMethod.new 'Create support is denied for this entity; '+
13
+ 'Invoices are generated instead by the BillForward Engines.'
14
+ end
15
+ end
16
+
17
+ protected
18
+ def unserialize_all(hash)
19
+ super
20
+ unserialize_array_of_entities('invoiceLines', InvoiceLine, hash)
21
+ unserialize_array_of_entities('taxLines', TaxLine, hash)
22
+ unserialize_array_of_entities('invoicePayments', InvoicePayment, hash)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # UnitOfMeasure .unitOfMeasure
5
+ class InvoiceLine < MutableEntity
6
+ class << self
7
+ def create(entity = nil)
8
+ raise DenyMethod.new 'Create support is denied for this entity; '+
9
+ 'at the time of writing, no API endpoint exists to support it. '+
10
+ 'The entity can be created through cascade only (i.e. instantiated within another entity).'
11
+ end
12
+
13
+ def get_by_id(id, query_params = {}, customClient = nil)
14
+ raise DenyMethod.new 'Get by ID support is denied for this entity; '+
15
+ 'at the time of writing, no API endpoint exists to support it.'+
16
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
17
+ end
18
+
19
+ def get_all(query_params = {}, customClient = nil)
20
+ raise DenyMethod.new 'Get All support is denied for this entity; '+
21
+ 'at the time of writing, no API endpoint exists to support it.'+
22
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
23
+ end
24
+ end
25
+
26
+ def save()
27
+ raise DenyMethod.new 'Save support is denied for this entity; '+
28
+ 'at the time of writing, the provided API endpoint is not functioning.'+
29
+ 'The entity can be saved through cascade only (i.e. save a related entity).'
30
+ end
31
+ protected
32
+ def unserialize_all(hash)
33
+ super
34
+ unserialize_entity('unitOfMeasure', UnitOfMeasure, hash)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ module BillForward
2
+ class InvoicePayment < MutableEntity
3
+ class << self
4
+ def create(entity = nil)
5
+ raise DenyMethod.new 'Create support is denied for this entity; '+
6
+ 'at the time of writing, no API endpoint exists to support it. '+
7
+ 'The entity can be created through cascade only (i.e. instantiated within another entity).'
8
+ end
9
+
10
+ def get_by_id(id, query_params = {}, customClient = nil)
11
+ raise DenyMethod.new 'Get by ID support is denied for this entity; '+
12
+ 'at the time of writing, no API endpoint exists to support it.'+
13
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
14
+ end
15
+
16
+ def get_all(query_params = {}, customClient = nil)
17
+ raise DenyMethod.new 'Get All support is denied for this entity; '+
18
+ 'at the time of writing, no API endpoint exists to support it.'+
19
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
20
+ end
21
+ end
22
+
23
+ def save()
24
+ raise DenyMethod.new 'Save support is denied for this entity; '+
25
+ 'at the time of writing, the provided API endpoint is not functioning.'+
26
+ 'The entity can be saved through cascade only (i.e. save a related entity).'
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ module BillForward
2
+ class TaxLine < InsertableEntity
3
+ class << self
4
+ def create(entity = nil)
5
+ raise DenyMethod.new 'Create support is denied for this entity; '+
6
+ 'at the time of writing, no API endpoint exists to support it. '+
7
+ 'The entity can be created through cascade only (i.e. instantiated within another entity).'
8
+ end
9
+
10
+ def get_by_id(id, query_params = {}, customClient = nil)
11
+ raise DenyMethod.new 'Get by ID support is denied for this entity; '+
12
+ 'at the time of writing, no API endpoint exists to support it.'+
13
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
14
+ end
15
+
16
+ def get_all(query_params = {}, customClient = nil)
17
+ raise DenyMethod.new 'Get All support is denied for this entity; '+
18
+ 'at the time of writing, no API endpoint exists to support it.'+
19
+ 'The entity can be GETted through cascade only (i.e. GET a related entity).'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ module BillForward
2
+ class TaxationLink < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new("taxation-links", "TaxationLink")
4
+ end
5
+ end
@@ -0,0 +1,37 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # APIConfiguration[] .apiConfigurations
5
+ class Organisation < MutableEntity
6
+ @resource_path = BillForward::ResourcePath.new("organizations", "organization")
7
+
8
+ class << self
9
+ def get_mine(options = {}, customClient = nil)
10
+ client = customClient
11
+ client = singleton_client if client.nil?
12
+
13
+ route = resource_path.path
14
+ endpoint = 'mine'
15
+ url_full = "#{route}/#{endpoint}"
16
+
17
+ response = client.get(url_full)
18
+ results = response["results"]
19
+
20
+ # maybe use build_entity_array here for consistency
21
+ entity_array = Array.new
22
+ # maybe it's an empty array, but that's okay too.
23
+ results.each do |value|
24
+ entity = self.new(value, client)
25
+ entity_array.push(entity)
26
+ end
27
+ entity_array
28
+ end
29
+ end
30
+
31
+ protected
32
+ def unserialize_all(hash)
33
+ super
34
+ unserialize_array_of_entities('apiConfigurations', APIConfiguration, hash)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ module BillForward
2
+ class PaymentMethod < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new("payment-methods", "paymentMethod")
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module BillForward
2
+ class PaymentMethodSubscriptionLink < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new("payment-method-subcription-links", "PaymentMethodSubscriptionLink")
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # PricingComponentTier[] .tiers
5
+ class PricingComponent < MutableEntity
6
+ @resource_path = BillForward::ResourcePath.new("pricing-components", "PricingComponent")
7
+
8
+ def self.get_all(options=nil, customClient=nil)
9
+ raise ArgumentError.new('Get All support is denied for this entity;
10
+ at the time of writing, no working API endpoint exists to support it.
11
+ The entity can be GETted through cascade (i.e. GET a related entity), or by ID only.'
12
+ )
13
+ end
14
+
15
+ protected
16
+ def unserialize_all(hash)
17
+ super
18
+ unserialize_array_of_entities('tiers', PricingComponentTier, hash)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module BillForward
2
+ class PricingComponentTier < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new("pricing-component-tiers", "pricingComponentTier")
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module BillForward
2
+ class PricingComponentValue < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new("pricing-component-values", "PricingComponentValue")
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module BillForward
2
+ class PricingComponentValueChange < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new("pricing-component-value-changes", "PricingComponentValueChange")
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module BillForward
2
+ class Product < MutableEntity
3
+ @resource_path = BillForward::ResourcePath.new("products", "product")
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # Product .product
5
+ # TaxationLink[] .taxation
6
+ # PricingComponent[] .pricingComponents
7
+ class ProductRatePlan < MutableEntity
8
+ @resource_path = BillForward::ResourcePath.new("product-rate-plans", "productRatePlan")
9
+
10
+ protected
11
+ def unserialize_all(hash)
12
+ super
13
+ unserialize_entity('product', Product, hash)
14
+
15
+ unserialize_array_of_entities('taxation', TaxationLink, hash)
16
+ unserialize_array_of_entities('pricingComponents', PricingComponent, hash)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # Address[] .addresses
5
+ class Profile < MutableEntity
6
+ @resource_path = BillForward::ResourcePath.new("profiles", "profile")
7
+
8
+ protected
9
+ def unserialize_all(hash)
10
+ super
11
+
12
+ unserialize_array_of_entities('addresses', Address, hash)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module BillForward
2
+ class Role < InsertableEntity
3
+ end
4
+ end
@@ -0,0 +1,53 @@
1
+ module BillForward
2
+ # This entity exposes the following child entities via method_missing:
3
+ #
4
+ # PricingComponentValue[] .pricingComponentValues
5
+ # PricingComponentValueChange[] .pricingComponentValueChanges
6
+ class Subscription < MutableEntity
7
+ @resource_path = BillForward::ResourcePath.new("subscriptions", "subscription")
8
+
9
+ class << self
10
+ def get_by_account_id(id, query_params = {}, customClient = nil)
11
+ client = customClient
12
+ client = singleton_client if client.nil?
13
+
14
+ raise ArgumentError.new("id cannot be nil") if id.nil?
15
+ TypeCheck.verifyObj(Hash, query_params, 'query_params')
16
+
17
+ route = resource_path.path
18
+ endpoint = 'account'
19
+ url_full = "#{route}/#{endpoint}/#{id}"
20
+
21
+ response = client.get(url_full, query_params)
22
+ results = response["results"]
23
+
24
+ # maybe use build_entity_array here for consistency
25
+ entity_array = Array.new
26
+ # maybe it's an empty array, but that's okay too.
27
+ results.each do |value|
28
+ entity = self.new(value, client)
29
+ entity_array.push(entity)
30
+ end
31
+ entity_array
32
+ end
33
+ end
34
+
35
+ def activate
36
+ set_state_param('state', 'AwaitingPayment')
37
+ response = save
38
+ response
39
+ end
40
+
41
+ protected
42
+ def unserialize_all(hash)
43
+ super
44
+ # always has these:
45
+ unserialize_array_of_entities('pricingComponentValues', PricingComponentValue, hash)
46
+ unserialize_array_of_entities('pricingComponentValueChanges', PricingComponentValueChange, hash)
47
+
48
+
49
+ # think about the other entities later..
50
+ # unserialize_array_of_entities('paymentMethodSubscriptionLinks', PaymentMethodSubscriptionLink, hash)
51
+ end
52
+ end
53
+ end