diff --git a/.bumpversion.cfg b/.bumpversion.cfg index c636b522f..53c2c3e04 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2.19.6 +current_version = 2.20.5 parse = (?P\d+) \.(?P\d+) \.(?P\d+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f5723b8..6aa8653d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,169 @@ # Changelog +## [2.20.5](https://github.com/recurly/recurly-client-ruby/tree/2.20.5) (2025-12-17) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.20.4...2.20.5) + + +**Merged Pull Requests** + +- Add tax_service_opt_out attribute to GiftCard model and corresponding tests [#944](https://github.com/recurly/recurly-client-ruby/pull/944) ([d14z-tech](https://github.com/d14z-tech)) + + + +## [2.20.4](https://github.com/recurly/recurly-client-ruby/tree/2.20.4) (2025-12-10) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.20.3...2.20.4) + + +**Merged Pull Requests** + +- Accept vertex_transaction_type fur purchase, adjustments and invoice [#943](https://github.com/recurly/recurly-client-ruby/pull/943) ([sgilrodriguez](https://github.com/sgilrodriguez)) + + + +## [2.20.3](https://github.com/recurly/recurly-client-ruby/tree/2.20.3) (2024-11-13) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.20.2...2.20.3) + + +**Merged Pull Requests** + +- Add vertex_transaction_type to plans [#916](https://github.com/recurly/recurly-client-ruby/pull/916) ([faiberrec](https://github.com/faiberrec)) + + + +## [2.20.2](https://github.com/recurly/recurly-client-ruby/tree/2.20.2) (2024-08-28) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.20.1...2.20.2) + + +**Merged Pull Requests** + +- Get external sub by uuid [#911](https://github.com/recurly/recurly-client-ruby/pull/911) ([amandamfielding](https://github.com/amandamfielding)) + + + +## [2.20.1](https://github.com/recurly/recurly-client-ruby/tree/2.20.1) (2024-08-21) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.20.0...2.20.1) + + +**Merged Pull Requests** + +- Added support for refunding invoices and line items [#909](https://github.com/recurly/recurly-client-ruby/pull/909) ([andcoca](https://github.com/andcoca)) + + + +## [2.20.0](https://github.com/recurly/recurly-client-ruby/tree/2.20.0) (2024-07-03) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.14...2.20.0) + + +**Merged Pull Requests** + +- GET external_subscription by external_id [#907](https://github.com/recurly/recurly-client-ruby/pull/907) ([paulorbpinho-fullstacklabs](https://github.com/paulorbpinho-fullstacklabs)) +- add taxable address sources to business entity and adjustment [#906](https://github.com/recurly/recurly-client-ruby/pull/906) ([amandamfielding](https://github.com/amandamfielding)) + + + +## [2.19.14](https://github.com/recurly/recurly-client-ruby/tree/2.19.14) (2024-05-08) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.13...2.19.14) + + +**Merged Pull Requests** + +- Add subscription change proflex options [#898](https://github.com/recurly/recurly-client-ruby/pull/898) ([Patrick-Duvall](https://github.com/Patrick-Duvall)) + + + +## [2.19.13](https://github.com/recurly/recurly-client-ruby/tree/2.19.13) (2024-04-04) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.12...2.19.13) + + +**Merged Pull Requests** + +- Add net_terms_type to Invoices, Purchases, and Subscriptions [#897](https://github.com/recurly/recurly-client-ruby/pull/897) ([flaviomuller](https://github.com/flaviomuller)) + + + +## [2.19.12](https://github.com/recurly/recurly-client-ruby/tree/2.19.12) (2024-03-19) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.11...2.19.12) + + +**Merged Pull Requests** + +- Add card_network_preference field to v2 [#896](https://github.com/recurly/recurly-client-ruby/pull/896) ([gilv93](https://github.com/gilv93)) + + + +## [2.19.11](https://github.com/recurly/recurly-client-ruby/tree/2.19.11) (2024-03-13) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.10...2.19.11) + + +**Merged Pull Requests** + +- add revrec to purchases and adjustments [#891](https://github.com/recurly/recurly-client-ruby/pull/891) ([wsethbrown](https://github.com/wsethbrown)) +- add revrec to gift cards [#889](https://github.com/recurly/recurly-client-ruby/pull/889) ([wsethbrown](https://github.com/wsethbrown)) +- add revrec to addons and items [#885](https://github.com/recurly/recurly-client-ruby/pull/885) ([wsethbrown](https://github.com/wsethbrown)) +- Add revrec shipping methods [#883](https://github.com/recurly/recurly-client-ruby/pull/883) ([wsethbrown](https://github.com/wsethbrown)) +- add plan setup fee revrec [#881](https://github.com/recurly/recurly-client-ruby/pull/881) ([wsethbrown](https://github.com/wsethbrown)) +- add get business entity [#880](https://github.com/recurly/recurly-client-ruby/pull/880) ([wsethbrown](https://github.com/wsethbrown)) +- Add pobs [#879](https://github.com/recurly/recurly-client-ruby/pull/879) ([wsethbrown](https://github.com/wsethbrown)) +- Add RevRec features to ruby [#878](https://github.com/recurly/recurly-client-ruby/pull/878) ([faiberrec](https://github.com/faiberrec)) +- Adding support for General Ledger Accounts [#875](https://github.com/recurly/recurly-client-ruby/pull/875) ([faiberrec](https://github.com/faiberrec)) + + + +## [2.19.10](https://github.com/recurly/recurly-client-ruby/tree/2.19.10) (2023-12-06) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.9...2.19.10) + + +**Merged Pull Requests** + +- External payment phases [#868](https://github.com/recurly/recurly-client-ruby/pull/868) ([amandamfielding](https://github.com/amandamfielding)) + + + +## [2.19.9](https://github.com/recurly/recurly-client-ruby/tree/2.19.9) (2023-08-10) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.8...2.19.9) + + +**Merged Pull Requests** + +- [V2] Add action_result to Subscription and Transaction [#863](https://github.com/recurly/recurly-client-ruby/pull/863) ([fkosouski](https://github.com/fkosouski)) + + + +## [2.19.8](https://github.com/recurly/recurly-client-ruby/tree/2.19.8) (2023-07-27) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.7...2.19.8) + + +**Merged Pull Requests** + +- Fixed usage of Minitest [#862](https://github.com/recurly/recurly-client-ruby/pull/862) ([csampson](https://github.com/csampson)) +- [V2] Add starting_on and ending_on to subscription ramps [#858](https://github.com/recurly/recurly-client-ruby/pull/858) ([rlew421](https://github.com/rlew421)) + + + +## [2.19.7](https://github.com/recurly/recurly-client-ruby/tree/2.19.7) (2023-07-17) + +[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.6...2.19.7) + + +**Merged Pull Requests** + +- modify external subscription [#857](https://github.com/recurly/recurly-client-ruby/pull/857) ([amandamfielding](https://github.com/amandamfielding)) + + + ## [2.19.6](https://github.com/recurly/recurly-client-ruby/tree/2.19.6) (2023-06-13) [Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/2.19.5...2.19.6) @@ -989,7 +1153,7 @@ - Fix AddOn quantity accumulator [#278](https://github.com/recurly/recurly-client-ruby/pull/278) ([bhelx](https://github.com/bhelx)) - Add new dunning event notification [#277](https://github.com/recurly/recurly-client-ruby/pull/277) ([bhelx](https://github.com/bhelx)) - Fix failing dependency for ruby 1.9.3 [#276](https://github.com/recurly/recurly-client-ruby/pull/276) ([bhelx](https://github.com/bhelx)) -- Correct rails deprecation warning [#275](https://github.com/recurly/recurly-client-ruby/pull/275) ([jdeseno](https://github.com/jdeseno)) +- Correct rails deprecation warning [#275](https://github.com/recurly/recurly-client-ruby/pull/275) ([ghost](https://github.com/ghost)) - Fix redeem bang [#271](https://github.com/recurly/recurly-client-ruby/pull/271) ([sdhull](https://github.com/sdhull)) - Cleanup code around message interpolation [#268](https://github.com/recurly/recurly-client-ruby/pull/268) ([bhelx](https://github.com/bhelx)) - removes base from error messages [#267](https://github.com/recurly/recurly-client-ruby/pull/267) ([lmnleaf](https://github.com/lmnleaf)) @@ -1535,7 +1699,7 @@ - Fix AddOn quantity accumulator [#278](https://github.com/recurly/recurly-client-ruby/pull/278) ([bhelx](https://github.com/bhelx)) - Add new dunning event notification [#277](https://github.com/recurly/recurly-client-ruby/pull/277) ([bhelx](https://github.com/bhelx)) - Fix failing dependency for ruby 1.9.3 [#276](https://github.com/recurly/recurly-client-ruby/pull/276) ([bhelx](https://github.com/bhelx)) -- Correct rails deprecation warning [#275](https://github.com/recurly/recurly-client-ruby/pull/275) ([jdeseno](https://github.com/jdeseno)) +- Correct rails deprecation warning [#275](https://github.com/recurly/recurly-client-ruby/pull/275) ([ghost](https://github.com/ghost)) - Fix redeem bang [#271](https://github.com/recurly/recurly-client-ruby/pull/271) ([sdhull](https://github.com/sdhull)) - Cleanup code around message interpolation [#268](https://github.com/recurly/recurly-client-ruby/pull/268) ([bhelx](https://github.com/bhelx)) - removes base from error messages [#267](https://github.com/recurly/recurly-client-ruby/pull/267) ([lmnleaf](https://github.com/lmnleaf)) @@ -2153,7 +2317,7 @@ - Fix AddOn quantity accumulator [#278](https://github.com/recurly/recurly-client-ruby/pull/278) ([bhelx](https://github.com/bhelx)) - Add new dunning event notification [#277](https://github.com/recurly/recurly-client-ruby/pull/277) ([bhelx](https://github.com/bhelx)) - Fix failing dependency for ruby 1.9.3 [#276](https://github.com/recurly/recurly-client-ruby/pull/276) ([bhelx](https://github.com/bhelx)) -- Correct rails deprecation warning [#275](https://github.com/recurly/recurly-client-ruby/pull/275) ([jdeseno](https://github.com/jdeseno)) +- Correct rails deprecation warning [#275](https://github.com/recurly/recurly-client-ruby/pull/275) ([ghost](https://github.com/ghost)) - Fix redeem bang [#271](https://github.com/recurly/recurly-client-ruby/pull/271) ([sdhull](https://github.com/sdhull)) - Cleanup code around message interpolation [#268](https://github.com/recurly/recurly-client-ruby/pull/268) ([bhelx](https://github.com/bhelx)) - removes base from error messages [#267](https://github.com/recurly/recurly-client-ruby/pull/267) ([lmnleaf](https://github.com/lmnleaf)) diff --git a/README.md b/README.md index bfe292794..1cc2b0533 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Recurly is packaged as a Ruby gem. We recommend you install it with [Bundler](http://gembundler.com/) by adding the following line to your Gemfile: ``` ruby -gem 'recurly', '~> 2.19.6' +gem 'recurly', '~> 2.20.5' ``` Recurly will automatically use [Nokogiri](http://nokogiri.org/) (for a nice diff --git a/lib/recurly_v2.rb b/lib/recurly_v2.rb index 48933db07..1b5f18618 100644 --- a/lib/recurly_v2.rb +++ b/lib/recurly_v2.rb @@ -27,6 +27,7 @@ module RecurlyV2 require 'recurly_v2/external_invoice' require 'recurly_v2/external_product' require 'recurly_v2/external_product_reference' + require 'recurly_v2/external_payment_phase' require 'recurly_v2/external_subscription' require 'recurly_v2/helper' require 'recurly_v2/invoice' @@ -61,6 +62,8 @@ module RecurlyV2 require 'recurly_v2/currency_percentage_tier' require 'recurly_v2/sub_add_on_percentage_tier' require 'recurly_v2/custom_field_definition' + require 'recurly_v2/general_ledger_account' + require 'recurly_v2/performance_obligation' @subdomain = nil diff --git a/lib/recurly_v2/add_on.rb b/lib/recurly_v2/add_on.rb index ef0e7ddc2..43a084a75 100644 --- a/lib/recurly_v2/add_on.rb +++ b/lib/recurly_v2/add_on.rb @@ -31,7 +31,7 @@ class AddOn < Resource external_sku avalara_service_type avalara_transaction_type - ) + ) + RevRec::PRODUCT_ATTRIBUTES alias to_param add_on_code alias quantity default_quantity diff --git a/lib/recurly_v2/adjustment.rb b/lib/recurly_v2/adjustment.rb index 3fe1658a1..f2e58ffab 100644 --- a/lib/recurly_v2/adjustment.rb +++ b/lib/recurly_v2/adjustment.rb @@ -55,6 +55,8 @@ class Adjustment < Resource tax_type tax_region tax_rate + origin_tax_address_source + destination_tax_address_source tax_exempt tax_inclusive tax_code @@ -67,8 +69,9 @@ class Adjustment < Resource surcharge_in_cents avalara_transaction_type avalara_service_type + vertex_transaction_type refundable_total_in_cents - ] + ] + RevRec::ALL_ATTRIBUTES alias to_param uuid # @return ["charge", "credit", nil] The type of adjustment. diff --git a/lib/recurly_v2/billing_info.rb b/lib/recurly_v2/billing_info.rb index f4c5afab4..20dd18df7 100644 --- a/lib/recurly_v2/billing_info.rb +++ b/lib/recurly_v2/billing_info.rb @@ -50,6 +50,7 @@ class BillingInfo < Resource backup_payment_method cc_bin_country online_banking_payment_type + card_network_preference ) | CREDIT_CARD_ATTRIBUTES | BANK_ACCOUNT_ATTRIBUTES | AMAZON_ATTRIBUTES | PAYPAL_ATTRIBUTES | ROKU_ATTRIBUTES | SEPA_ATTRIBUTES | BACS_ATTRIBUTES | BECS_ATTRIBUTES | VENMO_ATTRIBUTES # Verify an account's stored billing info diff --git a/lib/recurly_v2/business_entity.rb b/lib/recurly_v2/business_entity.rb index 29c4746d0..5b0466817 100644 --- a/lib/recurly_v2/business_entity.rb +++ b/lib/recurly_v2/business_entity.rb @@ -1,9 +1,10 @@ module RecurlyV2 class BusinessEntity < Resource belongs_to :site + belongs_to :default_revenue_gl_account, class_name: 'GeneralLedgerAccount' + belongs_to :default_liability_gl_account, class_name: 'GeneralLedgerAccount' has_many :invoices - has_many :accounts define_attribute_methods %w( @@ -12,9 +13,13 @@ class BusinessEntity < Resource name invoice_display_address tax_address + origin_tax_address_source + destination_tax_address_source subscriber_location_countries default_vat_number default_registration_number + default_revenue_gl_account_id + default_liability_gl_account_id created_at updated_at ) diff --git a/lib/recurly_v2/external_invoice.rb b/lib/recurly_v2/external_invoice.rb index d82b5f219..460a42594 100644 --- a/lib/recurly_v2/external_invoice.rb +++ b/lib/recurly_v2/external_invoice.rb @@ -5,6 +5,7 @@ class ExternalInvoice < Resource belongs_to :site belongs_to :account belongs_to :external_subscription + belongs_to :external_payment_phase # @return [[ExternalCharge], nil] has_many :line_items, class_name: :ExternalCharge diff --git a/lib/recurly_v2/external_payment_phase.rb b/lib/recurly_v2/external_payment_phase.rb new file mode 100644 index 000000000..cadff01e6 --- /dev/null +++ b/lib/recurly_v2/external_payment_phase.rb @@ -0,0 +1,27 @@ +module RecurlyV2 + class ExternalPaymentPhase < Resource + + # @return [ExternalSubscription] + belongs_to :external_subscription + + define_attribute_methods %w( + id + started_at + ends_at + starting_billing_period_index + ending_billing_period_index + offer_type + offer_name + period_count + period_length + amount + currency + created_at + updated_at + ) + + # We do not expose POST or PUT via the v2 API + protected(*%w(save save!)) + private_class_method(*%w(create! create)) + end +end diff --git a/lib/recurly_v2/external_subscription.rb b/lib/recurly_v2/external_subscription.rb index a276ba6c6..e4fd2d6a4 100644 --- a/lib/recurly_v2/external_subscription.rb +++ b/lib/recurly_v2/external_subscription.rb @@ -10,8 +10,12 @@ class ExternalSubscription < Resource # @return [ExternalInvoice] has_many :external_invoices + # @return [ExternalPaymentPhase] + has_many :external_payment_phases + define_attribute_methods %w( account + uuid external_id external_product_reference quantity @@ -23,10 +27,36 @@ class ExternalSubscription < Resource auto_renew app_identifier state + trial_started_at + trial_ends_at + canceled_at + in_grace_period + imported + test ) # We do not expose PUT or POST in the v2 API. protected(*%w(save save!)) private_class_method(*%w(create! create)) + + def get_external_payment_phases + Pager.new(RecurlyV2::ExternalPaymentPhase, uri: "#{path}/external_payment_phases", parent: self) + rescue RecurlyV2::API::UnprocessableEntity => e + raise Invalid, e.message + end + + def get_external_payment_phase(external_payment_phase_uuid) + ExternalPaymentPhase.from_response API.get("#{path}/external_payment_phases/#{external_payment_phase_uuid}") + rescue RecurlyV2::API::UnprocessableEntity => e + raise Invalid, e.message + end + + def self.find_by_external_id(external_id) + self.find("external-id-#{external_id}") + end + + def self.find_by_uuid(uuid) + self.find("uuid-#{uuid}") + end end end diff --git a/lib/recurly_v2/general_ledger_account.rb b/lib/recurly_v2/general_ledger_account.rb new file mode 100644 index 000000000..317fa1e74 --- /dev/null +++ b/lib/recurly_v2/general_ledger_account.rb @@ -0,0 +1,16 @@ +module RecurlyV2 + class GeneralLedgerAccount < Resource + belongs_to :site + + define_attribute_methods %w( + id + code + description + account_type + ) + + def self.collection_path + "general_ledger_accounts" + end + end +end diff --git a/lib/recurly_v2/gift_card.rb b/lib/recurly_v2/gift_card.rb index d4789f9ee..3289ee586 100644 --- a/lib/recurly_v2/gift_card.rb +++ b/lib/recurly_v2/gift_card.rb @@ -36,7 +36,8 @@ class GiftCard < Resource gifter_account_code recipient_account_code invoice_number - ) + tax_service_opt_out + ) + RevRec::PRODUCT_ATTRIBUTES alias to_param id # Preview a GiftCard given some attributes diff --git a/lib/recurly_v2/invoice.rb b/lib/recurly_v2/invoice.rb index 81615e7c5..dba1b73b3 100644 --- a/lib/recurly_v2/invoice.rb +++ b/lib/recurly_v2/invoice.rb @@ -96,6 +96,7 @@ def invoice_number_with_prefix customer_notes address net_terms + net_terms_type collection_method tax_types refund_tax_date @@ -122,6 +123,7 @@ def invoice_number_with_prefix refundable_total_in_cents used_tax_service business_entity_id + vertex_transaction_type ) alias to_param invoice_number_with_prefix @@ -248,6 +250,25 @@ def refund_amount(amount_in_cents = nil, refund_method = 'credit_first', options ) end + # Refunds the invoice for a specific percentage. + # + # @return [Invoice, false] Invoice if successful, false if the invoice isn't + # refundable. + # @raise [Error] If the refund fails. + # @param percentage [Integer, nil] The percentage to refund from the invoice. + # @param refund_method ["credit_first", "transaction_first", "all_transaction", "all_credit"] The method used to refund. + # @param external_refund [true, false] Designates that the refund transactions created are manual. + # @param credit_customer_notes [String] Adds notes to refund credit invoice. + # @param payment_method [String] Creates the manual transactions with this payment method. Allowed if *external_refund* is true. + # @param description [String] Sets this value as the *transaction_note* on the manual transactions created. Allowed if *external_refund* is true. + # @param refunded_at [DateTime] Sets this value as the *collected_at* on the manual transactions created. Allowed if *external_refund* is true. + def refund_percentage(percentage = nil, refund_method = 'credit_first', options = {}) + return false unless link? :refund + self.class.from_response( + follow_link :refund, :body => refund_percentage_to_xml(percentage, refund_method, options) + ) + end + def xml_keys super - ['currency'] end @@ -284,6 +305,16 @@ def refund_amount_to_xml(amount_in_cents = nil, refund_method = nil, options = { builder.to_s end + def refund_percentage_to_xml(percentage = nil, refund_method = nil, options = {}) + builder = XML.new("") + builder.add_element 'refund_method', refund_method + builder.add_element 'percentage', percentage + options.each do |k, v| + builder.add_element k.to_s, v + end + builder.to_s + end + def refund_line_items_to_xml(line_items = nil, refund_method = nil, options = {}) builder = XML.new("") builder.add_element 'refund_method', refund_method @@ -295,8 +326,10 @@ def refund_line_items_to_xml(line_items = nil, refund_method = nil, options = {} line_items.each do |line_item| adj_node = node.add_element 'adjustment' adj_node.add_element 'uuid', line_item[:adjustment].uuid - adj_node.add_element 'quantity', line_item[:quantity] + adj_node.add_element 'quantity', line_item[:quantity] if line_item.key?(:quantity) adj_node.add_element('quantity_decimal', line_item[:quantity_decimal]) if line_item.key?(:quantity_decimal) + adj_node.add_element 'percentage', line_item[:percentage] if line_item.key?(:percentage) + adj_node.add_element 'amount_in_cents', line_item[:amount_in_cents] if line_item.key?(:amount_in_cents) adj_node.add_element 'prorate', line_item[:prorate] end builder.to_s diff --git a/lib/recurly_v2/item.rb b/lib/recurly_v2/item.rb index 7ab2b93f1..027cf668d 100644 --- a/lib/recurly_v2/item.rb +++ b/lib/recurly_v2/item.rb @@ -16,7 +16,7 @@ class Item < Resource created_at updated_at deleted_at - ) + ) + RevRec::PRODUCT_ATTRIBUTES def changed_attributes attrs = super diff --git a/lib/recurly_v2/performance_obligation.rb b/lib/recurly_v2/performance_obligation.rb new file mode 100644 index 000000000..6e3bf0b88 --- /dev/null +++ b/lib/recurly_v2/performance_obligation.rb @@ -0,0 +1,15 @@ +module RecurlyV2 + class PerformanceObligation < Resource + + define_attribute_methods %w( + id + name + created_at + updated_at + ) + + def self.collection_path + "performance_obligations" + end + end +end \ No newline at end of file diff --git a/lib/recurly_v2/plan.rb b/lib/recurly_v2/plan.rb index d63ca3c5b..a0e8ca997 100644 --- a/lib/recurly_v2/plan.rb +++ b/lib/recurly_v2/plan.rb @@ -1,6 +1,7 @@ module RecurlyV2 # RecurlyV2 Documentation: https://dev.recurly.com/docs/list-plans class Plan < Resource + # @return [Pager, []] has_many :add_ons @@ -13,6 +14,7 @@ class Plan < Resource # @return [[CustomField], []] has_many :custom_fields, class_name: :CustomField, readonly: false + # Define attribute methods define_attribute_methods %w( plan_code name @@ -41,6 +43,7 @@ class Plan < Resource setup_fee_revenue_schedule_type tax_exempt tax_code + vertex_transaction_type trial_requires_billing_info auto_renew allow_any_item_on_subscriptions @@ -50,7 +53,7 @@ class Plan < Resource custom_fields created_at updated_at - ) + ) + RevRec::PLAN_ATTRIBUTES alias to_param plan_code end end diff --git a/lib/recurly_v2/purchase.rb b/lib/recurly_v2/purchase.rb index ee5657383..6c2b5bc8c 100644 --- a/lib/recurly_v2/purchase.rb +++ b/lib/recurly_v2/purchase.rb @@ -136,6 +136,7 @@ class Purchase < Resource collection_method po_number net_terms + net_terms_type coupon_codes terms_and_conditions customer_notes @@ -143,6 +144,7 @@ class Purchase < Resource shipping_address_id gateway_code transaction_type + vertex_transaction_type billing_info_uuid ) diff --git a/lib/recurly_v2/resource.rb b/lib/recurly_v2/resource.rb index a63408092..7f3762bb1 100644 --- a/lib/recurly_v2/resource.rb +++ b/lib/recurly_v2/resource.rb @@ -1,5 +1,6 @@ require 'date' require 'erb' +require_relative './rev_rec' module RecurlyV2 # The base class for all RecurlyV2 resources (e.g. {Account}, {Subscription}, diff --git a/lib/recurly_v2/rev_rec.rb b/lib/recurly_v2/rev_rec.rb new file mode 100644 index 000000000..428abd9dc --- /dev/null +++ b/lib/recurly_v2/rev_rec.rb @@ -0,0 +1,18 @@ +module RecurlyV2 + module RevRec + POB_ATTRIBUTE = %i(performance_obligation_id).freeze + POB_NATIVE_ATTRIBUTE = %i(performance_obligation_identifier).freeze + + GLA_ID_ATTRIBUTES = %i(liability_gl_account_id revenue_gl_account_id).freeze + GLA_CODE_ATTRIBUTES = %i(liability_gl_account_code revenue_gl_account_code).freeze + + PRODUCT_NATIVE_ATTRS = (POB_NATIVE_ATTRIBUTE + GLA_ID_ATTRIBUTES).freeze + PRODUCT_ATTRIBUTES = (POB_ATTRIBUTE + GLA_ID_ATTRIBUTES).freeze + + LINE_ITEM_ATTRIBUTES = (POB_ATTRIBUTE + GLA_CODE_ATTRIBUTES).freeze + ALL_ATTRIBUTES = (PRODUCT_ATTRIBUTES + LINE_ITEM_ATTRIBUTES).uniq.freeze + + SETUP_FEE_ATTRIBUTES = PRODUCT_ATTRIBUTES.map { |key| :"setup_fee_#{key}" }.freeze + PLAN_ATTRIBUTES = [*PRODUCT_ATTRIBUTES, *SETUP_FEE_ATTRIBUTES].freeze + end +end \ No newline at end of file diff --git a/lib/recurly_v2/shipping_method.rb b/lib/recurly_v2/shipping_method.rb index 9bc88b6c4..ec0e1f493 100644 --- a/lib/recurly_v2/shipping_method.rb +++ b/lib/recurly_v2/shipping_method.rb @@ -7,7 +7,7 @@ class ShippingMethod < Resource tax_code created_at updated_at - ) + ) + RevRec::PRODUCT_ATTRIBUTES alias to_param code end end diff --git a/lib/recurly_v2/subscription.rb b/lib/recurly_v2/subscription.rb index b113edf74..1561c4959 100644 --- a/lib/recurly_v2/subscription.rb +++ b/lib/recurly_v2/subscription.rb @@ -70,6 +70,7 @@ class Subscription < Resource total_billing_cycles remaining_billing_cycles net_terms + net_terms_type collection_method po_number tax_in_cents @@ -107,6 +108,8 @@ class Subscription < Resource resume_at gateway_code transaction_type + action_result + proration_settings ) alias to_param uuid diff --git a/lib/recurly_v2/subscription_ramp_interval.rb b/lib/recurly_v2/subscription_ramp_interval.rb index b60cfde8c..e95a356d5 100644 --- a/lib/recurly_v2/subscription_ramp_interval.rb +++ b/lib/recurly_v2/subscription_ramp_interval.rb @@ -5,6 +5,8 @@ class SubscriptionRampInterval < Resource define_attribute_methods %w( starting_billing_cycle unit_amount_in_cents + starting_on + ending_on ) end end diff --git a/lib/recurly_v2/transaction.rb b/lib/recurly_v2/transaction.rb index 8bcb05b5c..54d3d02d0 100644 --- a/lib/recurly_v2/transaction.rb +++ b/lib/recurly_v2/transaction.rb @@ -72,6 +72,7 @@ class Transaction < Resource manually_entered avalara_transaction_type avalara_service_type + action_result ) alias to_param uuid alias fraud_info fraud diff --git a/lib/recurly_v2/version.rb b/lib/recurly_v2/version.rb index b8ba6d490..77a09f1f4 100644 --- a/lib/recurly_v2/version.rb +++ b/lib/recurly_v2/version.rb @@ -1,6 +1,6 @@ module RecurlyV2 module Version - VERSION = "2.19.6" + VERSION = "2.20.5" class << self def inspect diff --git a/lib/recurly_v2/xml/rexml.rb b/lib/recurly_v2/xml/rexml.rb index 741f47812..6881bc2b4 100644 --- a/lib/recurly_v2/xml/rexml.rb +++ b/lib/recurly_v2/xml/rexml.rb @@ -19,10 +19,10 @@ def each_element xpath = nil root.each_element(xpath) { |el| yield el } end - def each element = root, &block + def each element = root element.each_element do |el| - block.call el - each el, &block + yield el + each el, &Proc.new { |e| yield e } end end diff --git a/spec/fixtures/accounts/external_invoices/show-200.xml b/spec/fixtures/accounts/external_invoices/show-200.xml index cf6d54b6d..0cb17d3d8 100644 --- a/spec/fixtures/accounts/external_invoices/show-200.xml +++ b/spec/fixtures/accounts/external_invoices/show-200.xml @@ -6,6 +6,7 @@ Content-Type: application/xml; charset=utf-8 + abc123 paid USD diff --git a/spec/fixtures/accounts/external_subscriptions/show-200.xml b/spec/fixtures/accounts/external_subscriptions/show-200.xml index cbff0e795..74a6a2324 100644 --- a/spec/fixtures/accounts/external_subscriptions/show-200.xml +++ b/spec/fixtures/accounts/external_subscriptions/show-200.xml @@ -6,7 +6,9 @@ Content-Type: application/xml; charset=utf-8 + 1234abcd + 72bb9966bb5dc3767461ce4368a6b366 false @@ -15,6 +17,12 @@ Content-Type: application/xml; charset=utf-8 active + + + + false + false + false 2022-11-04T20:33:29Z 2022-11-04T20:33:29Z diff --git a/spec/fixtures/adjustments/create-201-with-revrec.xml b/spec/fixtures/adjustments/create-201-with-revrec.xml new file mode 100644 index 000000000..6787490f1 --- /dev/null +++ b/spec/fixtures/adjustments/create-201-with-revrec.xml @@ -0,0 +1,39 @@ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/adjustments/67360781108ceacd23dee747b7b1f5af + + + + + + + + 0 + 67360781108ceacd23dee747b7b1f5af + pending + + + + debit + 5000 + 1 + 0 + 0 + 5000 + USD + + 2023-01-18T23:34:52Z + + 2023-01-18T23:34:52Z + 2023-01-18T23:34:52Z + at_invoice + liability_gla + revenue_gla + 5 + + + field1 + priceless + + + \ No newline at end of file diff --git a/spec/fixtures/adjustments/create-201-with-taxable-address-sources.xml b/spec/fixtures/adjustments/create-201-with-taxable-address-sources.xml new file mode 100644 index 000000000..0d8935004 --- /dev/null +++ b/spec/fixtures/adjustments/create-201-with-taxable-address-sources.xml @@ -0,0 +1,31 @@ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/adjustments/67360781108ceacd23dee747b7b1f5af + + + + + + + + 0 + 67360781108ceacd23dee747b7b1f5af + pending + + + + debit + 5000 + 1 + 0 + 0 + 5000 + USD + + 2023-01-18T23:34:52Z + + 2023-01-18T23:34:52Z + 2023-01-18T23:34:52Z + origin + destination + \ No newline at end of file diff --git a/spec/fixtures/adjustments/show-200-taxed.xml b/spec/fixtures/adjustments/show-200-taxed.xml index c8008fc1a..f65184ad0 100644 --- a/spec/fixtures/adjustments/show-200-taxed.xml +++ b/spec/fixtures/adjustments/show-200-taxed.xml @@ -18,6 +18,8 @@ Content-Type: application/xml; charset=utf-8 0 1200 USD + origin + destination false basic diff --git a/spec/fixtures/adjustments/show-200-with-revrec.xml b/spec/fixtures/adjustments/show-200-with-revrec.xml new file mode 100644 index 000000000..ea692785b --- /dev/null +++ b/spec/fixtures/adjustments/show-200-with-revrec.xml @@ -0,0 +1,64 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + + + + + + + plastic_gloves + plastic_gloves + abcdef1234567890 + pending + + plan + $12 Annual Subscription + 1200 + 1 + 1.2 + 0 + 5000 + usst + CA + 0.0875 + 1200 + USD + basic + evenly + 100 + 3 + 600 + liability_gla + revenue_gla + 5 + + + california + state + 0.065 + 3000 + state + true + + + san francisco + county + 0.02 + 2000 + + + 0.5 + abcdefg1234567 + 2011-04-30T07:00:00Z + 2011-04-30T07:00:00Z + 2011-08-31T03:30:00Z + + + field1 + priceless + + + diff --git a/spec/fixtures/business_entities/index-200.xml b/spec/fixtures/business_entities/index-200.xml index e455f83a2..0a03c55ce 100644 --- a/spec/fixtures/business_entities/index-200.xml +++ b/spec/fixtures/business_entities/index-200.xml @@ -27,8 +27,12 @@ Link: US + origin + destination + 12345 + 56789 2023-03-01T16:26:40Z 2023-04-01T16:26:40Z @@ -54,8 +58,11 @@ Link: US + origin + destination - + abc123 + xyz789 2023-06-01T16:26:40Z 2023-07-01T16:26:40Z diff --git a/spec/fixtures/business_entities/show-200.xml b/spec/fixtures/business_entities/show-200.xml index d627ceae3..66d66db29 100644 --- a/spec/fixtures/business_entities/show-200.xml +++ b/spec/fixtures/business_entities/show-200.xml @@ -1,35 +1,35 @@ HTTP/1.1 200 OK Content-Type: application/xml; charset=utf-8 -Link: ; rel="start", ; rel="next" - - - - sbup2j0fx800 - default - Default Business Entity - - 123 Main Ave - - San Francisco - CA - 90210 - US - - - - 123 Main Ave - - San Francisco - CA - 90210 - US - - - - - 2023-03-01T16:26:40Z - 2023-04-01T16:26:40Z - - \ No newline at end of file + + sbup2j0fx800 + default + Default Business Entity + + 123 Main Ave + + San Francisco + CA + 90210 + US + + + + 123 Main Ave + + San Francisco + CA + 90210 + US + + + origin + destination + + + 12345 + 56789 + 2023-03-01T16:26:40Z + 2023-04-01T16:26:40Z + \ No newline at end of file diff --git a/spec/fixtures/external_payment_phases/show-200.xml b/spec/fixtures/external_payment_phases/show-200.xml new file mode 100644 index 000000000..1266218de --- /dev/null +++ b/spec/fixtures/external_payment_phases/show-200.xml @@ -0,0 +1,21 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + + sk0bmpw0wbby + 2023-03-14T19:55:07Z + 2023-04-14T19:55:07Z + + 4 + + + 1 + 2 MONTHS + 0.00 + USD + 2023-03-14T19:55:07Z + 2023-03-14T19:55:07Z + + diff --git a/spec/fixtures/external_subscriptions/external_invoices/show-200.xml b/spec/fixtures/external_subscriptions/external_invoices/show-200.xml index 08405378f..502fbd52e 100644 --- a/spec/fixtures/external_subscriptions/external_invoices/show-200.xml +++ b/spec/fixtures/external_subscriptions/external_invoices/show-200.xml @@ -7,6 +7,7 @@ Content-Type: application/xml; charset=utf-8 + abc123 paid USD diff --git a/spec/fixtures/external_subscriptions/external_payment_phases/index-200.xml b/spec/fixtures/external_subscriptions/external_payment_phases/index-200.xml new file mode 100644 index 000000000..416fa7c21 --- /dev/null +++ b/spec/fixtures/external_subscriptions/external_payment_phases/index-200.xml @@ -0,0 +1,21 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + + sk0bmpw0wbby + 2023-03-14T19:55:07Z + 2023-04-14T19:55:07Z + + 4 + + + 1 + 2 MONTHS + 0.00 + USD + 2023-03-14T19:55:07Z + 2023-04-14T19:55:07Z + + diff --git a/spec/fixtures/external_subscriptions/external_payment_phases/show-200.xml b/spec/fixtures/external_subscriptions/external_payment_phases/show-200.xml new file mode 100644 index 000000000..fc67d314d --- /dev/null +++ b/spec/fixtures/external_subscriptions/external_payment_phases/show-200.xml @@ -0,0 +1,19 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + sk0bmpw0wbby + 2023-03-14T19:55:07Z + 2023-04-14T19:55:07Z + + 4 + + + 1 + 2 MONTHS + 0.00 + USD + 2023-03-14T19:55:07Z + 2023-04-14T19:55:07Z + diff --git a/spec/fixtures/external_subscriptions/show-200.xml b/spec/fixtures/external_subscriptions/show-200.xml index e9f1629f7..11fc069d5 100644 --- a/spec/fixtures/external_subscriptions/show-200.xml +++ b/spec/fixtures/external_subscriptions/show-200.xml @@ -5,7 +5,9 @@ Content-Type: application/xml; charset=utf-8 + external-id + 72bb9966bb5dc3767461ce4368a6b366 sd1eheqcn5a2 1234 @@ -20,6 +22,12 @@ Content-Type: application/xml; charset=utf-8 expired 2023-01-13T17:28:02Z 2023-01-13T17:28:02Z + + + + false + false + false 2023-02-08T23:02:30Z 2023-02-08T23:02:30Z diff --git a/spec/fixtures/general_ledger_accounts/create-201.xml b/spec/fixtures/general_ledger_accounts/create-201.xml new file mode 100644 index 000000000..799effb08 --- /dev/null +++ b/spec/fixtures/general_ledger_accounts/create-201.xml @@ -0,0 +1,12 @@ +HTTP/1.1 201 Created + Content-Type: application/xml; charset=utf-8 + + + + u90r5deeaxix + code1 + revenue + string + 2024-01-16T14:34:16Z + 2024-01-16T14:34:16Z + \ No newline at end of file diff --git a/spec/fixtures/general_ledger_accounts/index-200-liability.xml b/spec/fixtures/general_ledger_accounts/index-200-liability.xml new file mode 100644 index 000000000..58b3f1b8c --- /dev/null +++ b/spec/fixtures/general_ledger_accounts/index-200-liability.xml @@ -0,0 +1,78 @@ +HTTP/1.1 200 OK + Content-Type: application/xml; charset=utf-8 + + + + + ty4utwr0mrgz + 90-557-279-6957 + liability + optimize rich content + 2023-11-22T16:36:34Z + 2023-11-22T16:36:34Z + + + twyyzw8vcm36 + 45-571-736-1179 + liability + incentivize sexy functionalities + 2023-11-16T19:45:05Z + 2023-11-16T19:45:05Z + + + twywtf01wkgb + 70-818-669-8644 + liability + generate transparent metrics + 2023-11-16T19:32:52Z + 2023-11-16T19:32:52Z + + + twywqfr48v9l + 7-271-680-5012 + liability + My main liability account + 2023-11-16T19:32:24Z + 2023-11-16T19:32:24Z + + + twyvjlhbnej2 + 1234 + liability + My main liability account + 2023-11-16T19:25:44Z + 2023-11-16T19:25:44Z + + + trkzlcm2pde8 + validategla + liability + HOWDY + 2023-10-20T15:22:49Z + 2023-10-20T15:22:49Z + + + trkzinjccchm + j + liability + HOWDY + 2023-10-20T15:22:24Z + 2023-10-20T15:22:24Z + + + tep8f2u4qq51 + get dat monayyy + liability + i can has money + 2023-08-16T15:45:40Z + 2023-08-16T15:45:40Z + + + tejv6lw4eovy + demo_liability + liability + i be descriptin' + 2023-08-15T21:42:35Z + 2023-09-13T15:38:04Z + + \ No newline at end of file diff --git a/spec/fixtures/general_ledger_accounts/index-200-revenue.xml b/spec/fixtures/general_ledger_accounts/index-200-revenue.xml new file mode 100644 index 000000000..5b5a91888 --- /dev/null +++ b/spec/fixtures/general_ledger_accounts/index-200-revenue.xml @@ -0,0 +1,38 @@ +HTTP/1.1 200 OK + Content-Type: application/xml; charset=utf-8 + + + + + u90r5deeaxix + string + revenue + string + 2024-01-16T14:34:16Z + 2024-01-16T14:34:16Z + + + trl0h3br1dl7 + 100 + revenue + HOWDY + 2023-10-20T15:27:46Z + 2023-10-20T15:27:46Z + + + trkz0atorlk3 + NEW code + revenue + NEW description + 2023-10-20T15:19:32Z + 2023-10-20T15:29:30Z + + + thproqnpcuwp + 303 + revenue + + 2023-08-31T20:46:04Z + 2023-08-31T20:46:04Z + + \ No newline at end of file diff --git a/spec/fixtures/general_ledger_accounts/index-200.xml b/spec/fixtures/general_ledger_accounts/index-200.xml new file mode 100644 index 000000000..c78664e2b --- /dev/null +++ b/spec/fixtures/general_ledger_accounts/index-200.xml @@ -0,0 +1,110 @@ +HTTP/1.1 200 OK + Content-Type: application/xml; charset=utf-8 + + + + + u90r5deeaxix + string + revenue + string + 2024-01-16T14:34:16Z + 2024-01-16T14:34:16Z + + + ty4utwr0mrgz + 90-557-279-6957 + liability + optimize rich content + 2023-11-22T16:36:34Z + 2023-11-22T16:36:34Z + + + twyyzw8vcm36 + 45-571-736-1179 + liability + incentivize sexy functionalities + 2023-11-16T19:45:05Z + 2023-11-16T19:45:05Z + + + twywtf01wkgb + 70-818-669-8644 + liability + generate transparent metrics + 2023-11-16T19:32:52Z + 2023-11-16T19:32:52Z + + + twywqfr48v9l + 7-271-680-5012 + liability + My main liability account + 2023-11-16T19:32:24Z + 2023-11-16T19:32:24Z + + + twyvjlhbnej2 + 1234 + liability + My main liability account + 2023-11-16T19:25:44Z + 2023-11-16T19:25:44Z + + + trl0h3br1dl7 + 100 + revenue + HOWDY + 2023-10-20T15:27:46Z + 2023-10-20T15:27:46Z + + + trkzlcm2pde8 + validategla + liability + HOWDY + 2023-10-20T15:22:49Z + 2023-10-20T15:22:49Z + + + trkzinjccchm + j + liability + HOWDY + 2023-10-20T15:22:24Z + 2023-10-20T15:22:24Z + + + trkz0atorlk3 + NEW code + revenue + NEW description + 2023-10-20T15:19:32Z + 2023-10-20T15:29:30Z + + + thproqnpcuwp + 303 + revenue + + 2023-08-31T20:46:04Z + 2023-08-31T20:46:04Z + + + tep8f2u4qq51 + get dat monayyy + liability + i can has money + 2023-08-16T15:45:40Z + 2023-08-16T15:45:40Z + + + tejv6lw4eovy + demo_liability + liability + i be descriptin' + 2023-08-15T21:42:35Z + 2023-09-13T15:38:04Z + + \ No newline at end of file diff --git a/spec/fixtures/general_ledger_accounts/show-200.xml b/spec/fixtures/general_ledger_accounts/show-200.xml new file mode 100644 index 000000000..a4010affe --- /dev/null +++ b/spec/fixtures/general_ledger_accounts/show-200.xml @@ -0,0 +1,12 @@ +HTTP/1.1 200 OK + Content-Type: application/xml; charset=utf-8 + + + + u90r5deeaxix + code1 + revenue + string + 2024-01-16T14:34:16Z + 2024-01-16T14:34:16Z + \ No newline at end of file diff --git a/spec/fixtures/gift_cards/show-200.xml b/spec/fixtures/gift_cards/show-200.xml index a1fc4fe75..05ee50baa 100644 --- a/spec/fixtures/gift_cards/show-200.xml +++ b/spec/fixtures/gift_cards/show-200.xml @@ -37,4 +37,7 @@ Content-Type: application/xml; charset=utf-8 2016-07-28T00:01:46Z + uf0jwj5zhclg + uf0jwincednb + 1 diff --git a/spec/fixtures/items/create-201.xml b/spec/fixtures/items/create-201.xml index 27671d40d..010ec19d4 100644 --- a/spec/fixtures/items/create-201.xml +++ b/spec/fixtures/items/create-201.xml @@ -9,6 +9,9 @@ Location: https://api.recurly.com/v2/items/plastic_gloves Sleek Plastic awesome-plastic-gloves 1569273944 + uf0jwj5zhclg + uf0jwincednb' + 1 never true diff --git a/spec/fixtures/items/show-200.xml b/spec/fixtures/items/show-200.xml index a2b0e965a..4372147fd 100644 --- a/spec/fixtures/items/show-200.xml +++ b/spec/fixtures/items/show-200.xml @@ -21,4 +21,7 @@ Content-Type: application/xml; charset=utf-8 2019-09-23T21:25:45Z 2019-09-23T21:25:45Z + uf0jwj5zhclg + uf0jwincednb + 1 diff --git a/spec/fixtures/performance_obligations/index-200.xml b/spec/fixtures/performance_obligations/index-200.xml new file mode 100644 index 000000000..258eb06a2 --- /dev/null +++ b/spec/fixtures/performance_obligations/index-200.xml @@ -0,0 +1,24 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + + 6 + Over Time (Daily) + 2023-08-11T18:57:57Z + 2023-08-11T18:57:57Z + + + 5 + Over Time (Partial Monthly) + 2023-08-11T18:57:57Z + 2023-08-11T18:57:57Z + + + 4 + Point in Time + 2023-08-11T18:57:57Z + 2023-08-11T18:57:57Z + + \ No newline at end of file diff --git a/spec/fixtures/performance_obligations/show-200.xml b/spec/fixtures/performance_obligations/show-200.xml new file mode 100644 index 000000000..73af9fa1c --- /dev/null +++ b/spec/fixtures/performance_obligations/show-200.xml @@ -0,0 +1,10 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + 6 + Over Time (Daily) + 2023-08-11T18:57:57Z + 2023-08-11T18:57:57Z + \ No newline at end of file diff --git a/spec/fixtures/plans/add_ons/index-200.xml b/spec/fixtures/plans/add_ons/index-200.xml index 07414ec63..a2f0697e2 100644 --- a/spec/fixtures/plans/add_ons/index-200.xml +++ b/spec/fixtures/plans/add_ons/index-200.xml @@ -10,6 +10,9 @@ Content-Type: application/xml; charset=utf-8 1 false evenly + udexyr9hjgkc + uelq7rzkydlu + 6 5 diff --git a/spec/fixtures/plans/add_ons/show-200.xml b/spec/fixtures/plans/add_ons/show-200.xml new file mode 100644 index 000000000..22516d67e --- /dev/null +++ b/spec/fixtures/plans/add_ons/show-200.xml @@ -0,0 +1,22 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + + marketing_email + Marketing Email + 1 + false + evenly + udexyr9hjgkc + uelq7rzkydlu + 6 + + 5 + + marketing-email + 600 + 3 + 2016-04-19T20:26:03Z + \ No newline at end of file diff --git a/spec/fixtures/plans/show-200.xml b/spec/fixtures/plans/show-200.xml index c98c3461f..71270622a 100644 --- a/spec/fixtures/plans/show-200.xml +++ b/spec/fixtures/plans/show-200.xml @@ -22,8 +22,15 @@ Content-Type: application/xml; charset=utf-8 + udf6kuqq5rwr + udf6kubl7urs + 6 + udf6ktwsed99 + udf6ktdh636s + 4 evenly evenly + lease false 2016-04-13T21:59:18Z diff --git a/spec/fixtures/purchases/invoice-201-with-revrec.xml b/spec/fixtures/purchases/invoice-201-with-revrec.xml new file mode 100644 index 000000000..72ac9369c --- /dev/null +++ b/spec/fixtures/purchases/invoice-201-with-revrec.xml @@ -0,0 +1,228 @@ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/invoices/3517 + + + + + +
+ 400 Alabama St + + San Francisco + CA + 94110 + US + +
+ + 43d762734303e29025a8b64ef7953606 + paid + + 5333 + + 0 + 1013 + USD + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + + 2018-03-27T17:52:42Z + Some notes for the customer. + + 1013 + 1013 + 0 + 2018-03-27T17:52:42Z + 0 + charge + purchase + + 1013 + + + 0 + automatic + + Our company terms and conditions. + + + + + + + 7 + 43d762733e47a12cf3dd7c47d9aed1c4 + invoiced + Setup fee: muWlYSa6U3 + + muwlysa6u3 + setup_fee + 7 + 1 + 0 + 0 + 7 + USD + + false + false + + 2018-03-27T17:52:42Z + + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + evenly + liability_gla + revenue_gla + 5 + + 400 Alabama St + + San Francisco + CA + 94110 + US + + + + + + + + + 6 + 43d76273412274c8c041354ce7a27ee5 + invoiced + muWlYSa6U3 + + muwlysa6u3 + plan + 6 + 1 + 0 + 0 + 6 + USD + + false + false + + 2018-03-27T17:52:42Z + 2019-04-27T17:52:42Z + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + evenly + + 400 Alabama St + + San Francisco + CA + 94110 + US + + + + + + + + 1000 + 43d76272fc2c59081d803145bbb017e4 + invoiced + + + 9d138ed5-7517-4984-b03d-a2116c0a714d + debit + 1000 + 1 + 0 + 0 + 1000 + USD + + false + false + + 2018-03-27T17:52:42Z + + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + at_invoice + + 400 Alabama St + + San Francisco + CA + 94110 + US + + + + + + + + + + 43d762736a8c3f29413c0544ba92a44c + purchase + 1013 + 0 + USD + success + credit_card + 6871449 + subscription + false + true + true + true + + test + api + + Successful test transaction + + + + + Street address and postal code match. + + + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z +
+ + 7747ed3b-1771-4a03-b32a-503e9d65d3ad + Benjamin + Benjamin + + + + Benjamin + Du Monde + 400 Alabama St + + San Francisco + CA + 94110 + US + + + Visa + 2019 + 12 + 411111 + 1111 + + +
+
+
+ +
+ + +
diff --git a/spec/fixtures/purchases/invoice-with-action-result-201.xml b/spec/fixtures/purchases/invoice-with-action-result-201.xml new file mode 100644 index 000000000..48e1596fd --- /dev/null +++ b/spec/fixtures/purchases/invoice-with-action-result-201.xml @@ -0,0 +1,226 @@ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/invoices/3517 + + + + + +
+ 400 Alabama St + + San Francisco + CA + 94110 + US + +
+ + 43d762734303e29025a8b64ef7953606 + paid + + 5333 + + 0 + 1013 + USD + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + + 2018-03-27T17:52:42Z + Some notes for the customer. + + 1013 + 1013 + 0 + 2018-03-27T17:52:42Z + 0 + charge + purchase + + 1013 + + + 0 + automatic + + Our company terms and conditions. + + + + + + + 7 + 43d762733e47a12cf3dd7c47d9aed1c4 + invoiced + Setup fee: muWlYSa6U3 + + muwlysa6u3 + setup_fee + 7 + 1 + 0 + 0 + 7 + USD + + false + false + + 2018-03-27T17:52:42Z + + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + evenly + + 400 Alabama St + + San Francisco + CA + 94110 + US + + + + + + + + + 6 + 43d76273412274c8c041354ce7a27ee5 + invoiced + muWlYSa6U3 + + muwlysa6u3 + plan + 6 + 1 + 0 + 0 + 6 + USD + + false + false + + 2018-03-27T17:52:42Z + 2019-04-27T17:52:42Z + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + evenly + + 400 Alabama St + + San Francisco + CA + 94110 + US + + + + + + + + 1000 + 43d76272fc2c59081d803145bbb017e4 + invoiced + + + 9d138ed5-7517-4984-b03d-a2116c0a714d + debit + 1000 + 1 + 0 + 0 + 1000 + USD + + false + false + + 2018-03-27T17:52:42Z + + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + at_invoice + + 400 Alabama St + + San Francisco + CA + 94110 + US + + + + + + + + + + 43d762736a8c3f29413c0544ba92a44c + purchase + 1013 + 0 + USD + success + credit_card + 6871449 + subscription + false + true + true + true + + test + api + + Successful test transaction + + + + + Street address and postal code match. + + + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z + 2018-03-27T17:52:42Z +
+ + 7747ed3b-1771-4a03-b32a-503e9d65d3ad + Benjamin + Benjamin + + + + Benjamin + Du Monde + 400 Alabama St + + San Francisco + CA + 94110 + US + + + Visa + 2019 + 12 + 411111 + 1111 + + +
+ example +
+
+
+ + + + diff --git a/spec/fixtures/purchases/invoice-with-eom-net-terms-201.xml b/spec/fixtures/purchases/invoice-with-eom-net-terms-201.xml new file mode 100644 index 000000000..e2f473b04 --- /dev/null +++ b/spec/fixtures/purchases/invoice-with-eom-net-terms-201.xml @@ -0,0 +1,161 @@ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/invoices/3517 + + + + + + +
+ + Chickpea + Batard + + 11060 US-31 + + Elk Rapids + MI + 49629 + US + +
+ + Verena Example + Verena + Example + 400 Alabama St. + + San Francisco + CA + 94110 + US + 555-555-5555 + + + 63f7cd6612ef3c7befe2aa4432bd9426 + paid + + 1240 + + 0 + 7000 + USD + 2022-08-10T18:26:38Z + 2022-08-10T18:26:38Z + + 2022-08-10T18:26:38Z + + + + 7000 + 7000 + 0 + 2022-08-10T18:26:38Z + 0 + charge + purchase + + 7000 + + 30 + eom + automatic + + + + + + + + + + + + 7000 + 63f7cd6605de0c75fbdf8745b28f77a8 + invoiced + Setup fee: Byzantium Draw + + ramp-plan + setup_fee + 7000 + 1 + 0 + 0 + 7000 + USD + + 2022-08-10T18:26:35Z + + 2022-08-10T18:26:38Z + 2022-08-10T18:26:38Z + evenly + + + + + + + + 63f7cd6639e20788c87c164842872b85 + purchase + 7000 + 0 + USD + success + credit_card + 5654000 + subscription + false + true + true + true + + test + api + + Successful test transaction + + + + Match + Street address and postal code match. + + + 2022-08-10T18:26:35Z + 2022-08-10T18:26:35Z + 2022-08-10T18:26:38Z + false +
+ + periwinkleamaranth4 + Ruby + Playground + + + + Chickpea + Batard + 11060 US-31 + + Elk Rapids + MI + 49629 + US + + + Visa + 2045 + 12 + 411111 + 1111 + + +
+
+
+
+ + + diff --git a/spec/fixtures/purchases/preview-201-with-eom-net-terms.xml b/spec/fixtures/purchases/preview-201-with-eom-net-terms.xml new file mode 100644 index 000000000..2b0d6f99f --- /dev/null +++ b/spec/fixtures/purchases/preview-201-with-eom-net-terms.xml @@ -0,0 +1,67 @@ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/invoices/3517 + + + + + +
+ 400 Alabama St + + San Francisco + CA + 94110 + US + +
+ 3cd86c538142718179ec4a4b4586efc4 + open + + + + + 1000 + 0 + 1000 + 1000 + USD + + + 2017-04-13T23:23:35Z + + + + + 30 + eom + automatic + + + + 3cd86c5379c19c7f92dca34d46846c46 + pending + + + c6b6ea2e-770d-4b1e-bdec-279d4be7e22f + debit + 1000 + 1 + 0 + 0 + 1000 + USD + false + false + + 2017-04-13T23:23:35Z + + + + at_invoice + + + + +
+
diff --git a/spec/fixtures/purchases/preview-201-with-revrec.xml b/spec/fixtures/purchases/preview-201-with-revrec.xml new file mode 100644 index 000000000..34f0fa3fd --- /dev/null +++ b/spec/fixtures/purchases/preview-201-with-revrec.xml @@ -0,0 +1,69 @@ +HTTP/1.1 201 Created +Content-Type: application/xml; charset=utf-8 +Location: https://api.recurly.com/v2/invoices/3517 + + + + + +
+ 400 Alabama St + + San Francisco + CA + 94110 + US + +
+ 3cd86c538142718179ec4a4b4586efc4 + open + + + + + 1000 + 0 + 1000 + 1000 + USD + + + 2017-04-13T23:23:35Z + + + + + 0 + automatic + + + + 3cd86c5379c19c7f92dca34d46846c46 + pending + + + c6b6ea2e-770d-4b1e-bdec-279d4be7e22f + debit + 1000 + 1 + 0 + 0 + 1000 + USD + false + false + + 2017-04-13T23:23:35Z + + + + at_invoice + liability_gla + revenue_gla + 5 + + + + +
+
diff --git a/spec/fixtures/shipping_methods/show-200.xml b/spec/fixtures/shipping_methods/show-200.xml index faac8499b..966956cbe 100644 --- a/spec/fixtures/shipping_methods/show-200.xml +++ b/spec/fixtures/shipping_methods/show-200.xml @@ -6,6 +6,9 @@ Content-Type: application/xml; charset=utf-8 fedex_ground FedEx Ground + twywqfr48v9l + thproqnpcuwp + 4 2019-05-07T16:36:22Z 2019-05-07T16:36:22Z diff --git a/spec/fixtures/subscriptions/preview-200-change-with-eom-net-terms.xml b/spec/fixtures/subscriptions/preview-200-change-with-eom-net-terms.xml new file mode 100644 index 000000000..04ff1d7fc --- /dev/null +++ b/spec/fixtures/subscriptions/preview-200-change-with-eom-net-terms.xml @@ -0,0 +1,73 @@ +HTTP/1.1 200 OK +Content-Type: application/xml; charset=utf-8 + + + + + + plan_code + A Man, a Plan, a Canal: Panama + + abcdef1234567890 + active + 1000 + USD + 5 + 2014-05-20T16:29:59Z + + + + + 2014-05-20T16:29:59Z + 2014-06-20T16:29:59Z + + + 5000 + + + + + + + abcdefg123 + open + + + + 60 + eom + + 5000 + 0 + 5000 + USD + + + + + + + abcdefg111 + pending + plan_code + + plan_code + plan + 5000 + 5 + 0 + 0 + 5000 + USD + false + false + 2014-05-20T18:14:08Z + 2014-06-20T16:29:59Z + + + + + + + + diff --git a/spec/fixtures/subscriptions/serialize-with-action-result.xml b/spec/fixtures/subscriptions/serialize-with-action-result.xml new file mode 100644 index 000000000..a27a38b3b --- /dev/null +++ b/spec/fixtures/subscriptions/serialize-with-action-result.xml @@ -0,0 +1 @@ +1manualEUR10gold1000example diff --git a/spec/fixtures/subscriptions/serialize-with-ramps-starting-on-ending-on.xml b/spec/fixtures/subscriptions/serialize-with-ramps-starting-on-ending-on.xml new file mode 100644 index 000000000..74ef62372 --- /dev/null +++ b/spec/fixtures/subscriptions/serialize-with-ramps-starting-on-ending-on.xml @@ -0,0 +1 @@ +114111-1111-1111-111120141234abcdverena@example.comVerenaExampleEURSome Customer Notestruegold2022-10-23 16:16:34.00000012022-09-23 16:16:34.000000100022022-10-23 16:16:34.00000020001234899ups_groundSome Terms and Conditions \ No newline at end of file diff --git a/spec/fixtures/subscriptions/show-200-with-eom-net-terms.xml b/spec/fixtures/subscriptions/show-200-with-eom-net-terms.xml new file mode 100644 index 000000000..6987fee3d --- /dev/null +++ b/spec/fixtures/subscriptions/show-200-with-eom-net-terms.xml @@ -0,0 +1 @@ +123456789012345678901234567890abbasicplanBasic Planactive130eommanual1000EUR10002011-05-27T07:00:00Z2011-06-27T07:00:00Z2010-07-27T07:00:00Z
diff --git a/spec/recurly_v2/add_on_spec.rb b/spec/recurly_v2/add_on_spec.rb index ccc034e25..53f43b7af 100644 --- a/spec/recurly_v2/add_on_spec.rb +++ b/spec/recurly_v2/add_on_spec.rb @@ -1,6 +1,40 @@ require 'spec_helper' describe AddOn do + let(:add_on) do + AddOn.new( + add_on_code: 'pink_sweaters', + name: 'Pink Sweaters', + revenue_schedule_type: 'evenly', + unit_amount_in_cents: 200, + add_on_type: 'usage', + optional: false, + usage_type: 'price', + liability_gl_account_id: 'uf0jwj5zhclg', + revenue_gl_account_id: 'uf0jwincednb', + performance_obligation_id: '1', + ) + end + + it 'must serialize' do + add_on.to_xml.must_equal <\ +pink_sweaters\ +usage\ +uf0jwj5zhclg\ +Pink Sweaters\ +false\ +1\ +uf0jwincednb\ +evenly\ +\ +200\ +\ +price\ + +XML + end + before do stub_api_request( :get, 'plans/gold', 'plans/show-200' @@ -26,6 +60,9 @@ stub_api_request( :get, 'plans/percentageplan/add_ons', 'plans/add_ons/index-200-tiered-percentage' ) + stub_api_request( + :get, 'plans/gold/add_ons/marketing_email', 'plans/add_ons/show-200' + ) end describe ".find" do @@ -85,5 +122,52 @@ add_on.percentage_tiers.first.tiers.count.must_equal 2 add_on.percentage_tiers.first.tiers.first.must_be_instance_of PercentageTier end + + it "returns RevRec attributes" do + plan = Plan.find 'gold' + add_ons = plan.add_ons + + add_on = add_ons.first + add_on.must_be_instance_of AddOn + add_on.liability_gl_account_id.must_equal "udexyr9hjgkc" + add_on.revenue_gl_account_id.must_equal "uelq7rzkydlu" + add_on.performance_obligation_id.must_equal "6" + end + end + + describe "create" do + it "must create a new add-on" do + stub_request(:post, "https://api.recurly.com/v2/plans/gold/add_ons"). + with(:body => "pink_sweatersusageuf0jwj5zhclgPink Sweatersfalse1uf0jwincednbevenly200price", + :headers => RecurlyV2::API.headers).to_return(:status => 200, :body => "", :headers => {}) + + plan = Plan.find 'gold' + add_on = plan.add_ons.create( + add_on_code: 'pink_sweaters', + name: 'Pink Sweaters', + revenue_schedule_type: 'evenly', + unit_amount_in_cents: 200, + add_on_type: 'usage', + optional: false, + usage_type: 'price', + liability_gl_account_id: 'uf0jwj5zhclg', + revenue_gl_account_id: 'uf0jwincednb', + performance_obligation_id: '1' + ) + add_on.must_be_instance_of AddOn + add_on.name.must_equal 'Pink Sweaters' + end + end + + describe "update" do + it "sends changed attributes to the server" do + plan = Plan.find 'gold' + add_on = plan.add_ons.find 'marketing_email' + stub_request(:put, "https://api.recurly.com/v2/plans/gold/add_ons/marketing_email"). + with(:body => "a8hkyaw9nmUpdated Emailsaksdfu48", + :headers => RecurlyV2::API.headers).to_return(:status => 200, :body => "", :headers => {}) + add_on.update_attributes({ name: 'Updated Emails', revenue_gl_account_id: 'aksdfu48', + liability_gl_account_id: 'a8hkyaw9nm', performance_obligation_id: '6'}) + end end end diff --git a/spec/recurly_v2/adjustment_spec.rb b/spec/recurly_v2/adjustment_spec.rb index 9fe79b840..31aca097d 100644 --- a/spec/recurly_v2/adjustment_spec.rb +++ b/spec/recurly_v2/adjustment_spec.rb @@ -63,6 +63,8 @@ adjustment = Adjustment.find 'abcdef1234567890' adjustment.tax_exempt?.must_equal false + adjustment.origin_tax_address_source.must_equal('origin') + adjustment.destination_tax_address_source.must_equal('destination') end it 'must parse the vertex details if available' do @@ -92,6 +94,17 @@ stub_api_request :get, 'adjustments/abcdef1234567890', 'adjustments/show-404' proc { Adjustment.find 'abcdef1234567890' }.must_raise Resource::NotFound end + + describe 'with RevRec' do + it 'must return the RevRec details' do + stub_api_request :get, 'adjustments/abcdef1234567890', 'adjustments/show-200-with-revrec' + + adjustment = Adjustment.find 'abcdef1234567890' + adjustment.liability_gl_account_code.must_equal 'liability_gla' + adjustment.revenue_gl_account_code.must_equal 'revenue_gla' + adjustment.performance_obligation_id.must_equal '5' + end + end end describe "#subscription" do @@ -131,6 +144,29 @@ end end + describe 'vertex_transaction_type attribute' do + it 'should accept vertex_transaction_type as an adjustment attribute' do + adjustment = Adjustment.new( + unit_amount_in_cents: 1000, + currency: 'USD', + quantity: 1, + vertex_transaction_type: 'rental' + ) + adjustment.vertex_transaction_type.must_equal 'rental' + end + + it 'should include vertex_transaction_type in XML output' do + adjustment = Adjustment.new( + unit_amount_in_cents: 1000, + currency: 'USD', + quantity: 1, + vertex_transaction_type: 'lease' + ) + xml = adjustment.to_xml + xml.must_include 'lease' + end + end + describe '#bill_for_account' do it 'calls the account endpoint to fetch bill_for_account' do stub_api_request :get, 'adjustments/abcdef1234567890', 'adjustments/show-200' @@ -144,11 +180,11 @@ describe '#POST /accounts/{account_code}/adjustments' do let(:adjustment_body) do { - unit_amount_in_cents: 5000, - currency: 'USD', - quantity: 1, - accounting_code: 'bandwidth', - tax_exempt: false, + unit_amount_in_cents: 5000, + currency: 'USD', + quantity: 1, + accounting_code: 'bandwidth', + tax_exempt: false, custom_fields: [ { name: 'field1', @@ -187,4 +223,100 @@ charge.custom_fields.must_equal [CustomField.new(name: 'field1', value: 'priceless')] end end + + describe 'with RevRec #POST /accounts/{account_code}/adjustments' do + let(:adjustment_body) do + { + unit_amount_in_cents: 5000, + currency: 'USD', + quantity: 1, + accounting_code: 'bandwidth', + tax_exempt: false, + liability_gl_account_id: 'ad8h3layw', + revenue_gl_account_id: 'ydu5owk', + performance_obligation_id: '5', + custom_fields: [ + { + name: 'field1', + value: 'priceless' + } + ] + } + end + let(:adjustment) { Adjustment.new(adjustment_body) } + + it 'must serialize' do + adjustment.to_xml.must_equal <\ +bandwidth\ +USD\ +\ +\ +field1\ +priceless\ +\ +\ +ad8h3layw\ +5\ +1\ +ydu5owk\ +false\ +5000\ + +XML + end + + it 'it creates an adjustment with RevRec details on the account specified' do + stub_api_request :get, 'accounts/abcdef1234567890', 'accounts/show-200' + stub_api_request :post, 'accounts/abcdef1234567890/adjustments', 'adjustments/create-201-with-revrec' + + account = Account.find('abcdef1234567890') + + charge = account.adjustments.create(adjustment_body) + charge.custom_fields.must_equal [CustomField.new(name: 'field1', value: 'priceless')] + charge.liability_gl_account_code.must_equal 'liability_gla' + charge.revenue_gl_account_code.must_equal 'revenue_gla' + charge.performance_obligation_id.must_equal '5' + end + end + + describe 'with taxable address sources #POST /accounts/{account_code}/adjustments' do + let(:adjustment_body) do + { + unit_amount_in_cents: 5000, + currency: 'USD', + quantity: 1, + accounting_code: 'bandwidth', + tax_exempt: false, + origin_tax_address_source: 'origin', + destination_tax_address_source: 'destination' + } + end + let(:adjustment) { Adjustment.new(adjustment_body) } + + it 'must serialize' do + adjustment.to_xml.must_equal <\ +bandwidth\ +USD\ +destination\ +origin\ +1\ +false\ +5000\ + +XML + end + + it 'it creates an adjustment with taxable address details on the account specified' do + stub_api_request :get, 'accounts/abcdef1234567890', 'accounts/show-200' + stub_api_request :post, 'accounts/abcdef1234567890/adjustments', 'adjustments/create-201-with-taxable-address-sources' + + account = Account.find('abcdef1234567890') + + charge = account.adjustments.create(adjustment_body) + charge.origin_tax_address_source.must_equal 'origin' + charge.destination_tax_address_source.must_equal 'destination' + end + end end diff --git a/spec/recurly_v2/billing_info_spec.rb b/spec/recurly_v2/billing_info_spec.rb index b43432dc0..2160046cb 100644 --- a/spec/recurly_v2/billing_info_spec.rb +++ b/spec/recurly_v2/billing_info_spec.rb @@ -11,6 +11,7 @@ :last_four => "1111", :city => "Los Angeles", :state => "CA", + :card_network_preference => "Cartes Bancaires", :gateway_attributes => { account_reference: "ABC123" }, ) } @@ -20,6 +21,7 @@ binfo.gateway_code = "gatewaycode123" binfo.to_xml.must_equal <\ +Cartes Bancaires\ Visa\ Los Angeles\ Larry\ diff --git a/spec/recurly_v2/business_entity_spec.rb b/spec/recurly_v2/business_entity_spec.rb index dbad7a62f..682cd067f 100644 --- a/spec/recurly_v2/business_entity_spec.rb +++ b/spec/recurly_v2/business_entity_spec.rb @@ -1,6 +1,18 @@ require 'spec_helper' describe BusinessEntity do + let(:revenue_gla) { + GeneralLedgerAccount.new( + account_type: 'revenue', + code: '12345', + ) + } + let(:liablity_gla) { + GeneralLedgerAccount.new( + account_type: 'liability', + code: '56789' + ) + } let(:business_entity) { BusinessEntity.new( id: 'sokvpa93ztmm', @@ -28,9 +40,13 @@ country: "Australia", zip: "2060" }), + origin_tax_address_source: 'origin', + destination_tax_address_source: 'desination', subscriber_location_countries: ['US', 'AU'], default_vat_number: '12345', default_registration_number: '12345', + default_revenue_gl_account: revenue_gla, + default_liability_gl_account: liablity_gla, created_at: '2023-05-23T19:02:40Z', updated_at: '2023-06-23T19:02:40Z' ) @@ -41,38 +57,38 @@ expect(business_entity.code).must_equal('samplecode') expect(business_entity.id).must_equal('sokvpa93ztmm') expect(business_entity.subscriber_location_countries).must_equal(['US', 'AU']) + expect(business_entity.default_revenue_gl_account_id).must_be_nil + expect(business_entity.default_liability_gl_account_id).must_be_nil expect(business_entity.created_at).must_equal('2023-05-23T19:02:40Z') expect(business_entity.updated_at).must_equal('2023-06-23T19:02:40Z') end end - describe ".index" do - before do - stub_api_request( - :get, "https://api.recurly.com/v2/business_entities", - "business_entities/index-200" - ) - end + describe ".find" do + let(:business_entity) { + stub_api_request(:get, "business_entities/sbup2j0fx800", "business_entities/show-200") + RecurlyV2::BusinessEntity.find 'sbup2j0fx800' + } it "returns a business entity" do business_entity.must_be_instance_of(BusinessEntity) - business_entity.id.must_equal('sokvpa93ztmm') - business_entity.code.must_equal('samplecode') + business_entity.id.must_equal('sbup2j0fx800') + business_entity.code.must_equal('default') + business_entity.default_liability_gl_account_id.must_equal('12345') + business_entity.default_revenue_gl_account_id.must_equal('56789') + business_entity.origin_tax_address_source.must_equal('origin') + business_entity.destination_tax_address_source.must_equal('destination') end end - describe ".find" do - before do - stub_api_request( - :get, "https://api.recurly.com/v2/business_entities/sokvpa93ztmm", - "business_entities/show-200" - ) - end + describe ".index" do + let(:business_entities) { + stub_api_request(:get, "business_entities", "business_entities/index-200") + RecurlyV2::BusinessEntity.all + } - it "returns a business entity" do - business_entity.must_be_instance_of(BusinessEntity) - business_entity.id.must_equal('sokvpa93ztmm') - business_entity.code.must_equal('samplecode') + it "returns all business entities" do + expect(business_entities.count).must_equal(2) end end end diff --git a/spec/recurly_v2/external_payment_phase_spec.rb b/spec/recurly_v2/external_payment_phase_spec.rb new file mode 100644 index 000000000..e279981ce --- /dev/null +++ b/spec/recurly_v2/external_payment_phase_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' + +describe ExternalPaymentPhase do + let(:external_payment_phase) { + ExternalPaymentPhase.new( + id: 'sd28t3zdm59p', + external_subscription: ExternalSubscription.new(id: '123abc'), + started_at: '2023-01-23T19:02:40Z', + ends_at: '2023-02-23T19:02:40Z', + starting_billing_period_index: 1, + ending_billing_period_index: 4, + period_count: 1, + period_length: '2 MONTHS', + amount: 0.00, + currency: 'USD', + created_at: '2023-01-23T19:02:40Z', + updated_at: '2023-02-23T19:02:40Z' + ) + } + let(:external_subscription) { + stub_api_request :get, 'external_subscriptions/sdam2lfeop3e', 'external_subscriptions/show-200' + ExternalSubscription.find('sdam2lfeop3e') + } + + describe "#associations" do + it "has correct associations" do + expect(external_payment_phase.external_subscription).must_be_instance_of ExternalSubscription + end + end + + describe "#methods" do + it "has correct attributes" do + expect(external_payment_phase.id).must_equal('sd28t3zdm59p') + expect(external_payment_phase.starting_billing_period_index).must_equal(1) + expect(external_payment_phase.created_at).must_equal('2023-01-23T19:02:40Z') + expect(external_payment_phase.updated_at).must_equal('2023-02-23T19:02:40Z') + end + end + + describe ".get_external_payment_phases" do + before do + stub_api_request( + :get, "https://api.recurly.com/v2/external_subscriptions/sdam2lfeop3e/external_payment_phases", + "external_subscriptions/external_payment_phases/index-200" + ) + end + + it "returns external_payment_phases" do + external_payment_phase = external_subscription.get_external_payment_phases[0] + + external_payment_phase.must_be_instance_of(ExternalPaymentPhase) + external_payment_phase.id.must_equal('sk0bmpw0wbby') + external_payment_phase.created_at.must_equal(DateTime.new(2023, 3, 14, 19, 55, 7)) + external_payment_phase.updated_at.must_equal(DateTime.new(2023, 4, 14, 19, 55, 7)) + end + end + + describe ".get_external_payment_phase" do + before do + stub_api_request( + :get, "https://api.recurly.com/v2/external_subscriptions/sdam2lfeop3e/external_payment_phases/sk0bmpw0wbby", + "external_subscriptions/external_payment_phases/show-200" + ) + end + + it "returns an external payment phase" do + external_payment_phase = external_subscription.get_external_payment_phase('sk0bmpw0wbby') + + external_payment_phase.must_be_instance_of(ExternalPaymentPhase) + external_payment_phase.id.must_equal('sk0bmpw0wbby') + external_payment_phase.created_at.must_equal(DateTime.new(2023, 3, 14, 19, 55, 7)) + external_payment_phase.updated_at.must_equal(DateTime.new(2023, 4, 14, 19, 55, 7)) + end + end +end diff --git a/spec/recurly_v2/external_subscription_spec.rb b/spec/recurly_v2/external_subscription_spec.rb index 0966676bb..7fc42a25f 100644 --- a/spec/recurly_v2/external_subscription_spec.rb +++ b/spec/recurly_v2/external_subscription_spec.rb @@ -11,6 +11,7 @@ created_at: "2019-08-24T14:15:22Z", updated_at: "2019-08-24T14:15:22Z" ), + uuid: "72bb9966bb5dc3767461ce4368a6b366", quantity: 1, activated_at: "2022-11-07 17:08:18", created_at: "2022-11-07 17:08:18", @@ -20,7 +21,13 @@ auto_renew: true, app_identifier: 'apple_play_store', external_id: 'abcd1234', - state: 'active' + state: 'active', + trial_started_at: "2022-11-07 17:08:18", + trial_ends_at: "2022-11-14 17:08:18", + canceled_at: "2022-11-15 17:08:18", + in_grace_period: false, + imported: false, + test: false ) } @@ -49,6 +56,7 @@ 2022-11-07 17:08:18\ apple_play_store\ true\ +2022-11-15 17:08:18\ 2022-11-07 17:08:18\ 2022-12-07 17:08:18\ abcd1234\ @@ -59,10 +67,16 @@ reference_code 1\ 2019-08-24T14:15:22Z\ \ +false\ +false\ 2022-11-07 17:08:18\ 1\ active\ +false\ +2022-11-14 17:08:18\ +2022-11-07 17:08:18\ 2022-11-07 17:08:18\ +72bb9966bb5dc3767461ce4368a6b366\
XML end diff --git a/spec/recurly_v2/general_ledger_account_spec.rb b/spec/recurly_v2/general_ledger_account_spec.rb new file mode 100644 index 000000000..9e6b14855 --- /dev/null +++ b/spec/recurly_v2/general_ledger_account_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' + +describe GeneralLedgerAccount do + let(:general_ledger_account) { + stub_api_request(:get, "general_ledger_accounts/u90r5deeaxix", "general_ledger_accounts/show-200") + RecurlyV2::GeneralLedgerAccount.find 'u90r5deeaxix' + } + + let(:general_ledger_accounts) { + stub_api_request(:get, "general_ledger_accounts", "general_ledger_accounts/index-200") + RecurlyV2::GeneralLedgerAccount.all + } + + describe "#find" do + it "returns a GeneralLedgerAccount" do + general_ledger_account.must_be_instance_of(GeneralLedgerAccount) + end + + it "has correct attributes" do + expect(general_ledger_account.id).must_equal('u90r5deeaxix') + expect(general_ledger_account.code).must_equal('code1') + expect(general_ledger_account.description).must_equal('string') + expect(general_ledger_account.account_type).must_equal('revenue') + end + end + + describe "#index" do + describe "when no params are passed" do + it "returns a list of general ledger accounts" do + expect(general_ledger_accounts.count).must_equal(13) + end + end + + describe "when account_type=revenue passed" do + let(:general_ledger_accounts) { + stub_api_request(:get, "general_ledger_accounts?account_type=revenue", "general_ledger_accounts/index-200-revenue") + RecurlyV2::GeneralLedgerAccount.all(account_type: 'revenue') + } + + it "returns a list of general ledger accounts" do + expect(general_ledger_accounts.count).must_equal(4) + end + end + + describe "when account_type=liability passed" do + let(:general_ledger_accounts) { + stub_api_request(:get, "general_ledger_accounts?account_type=liability", "general_ledger_accounts/index-200-liability") + RecurlyV2::GeneralLedgerAccount.all(account_type: 'liability') + } + + it "returns a list of general ledger accounts" do + expect(general_ledger_accounts.count).must_equal(9) + end + end + end + + describe "#save" do + let(:general_ledger_account) { GeneralLedgerAccount.new } + it "must return true when new and valid" do + stub_api_request :post, 'general_ledger_accounts', 'general_ledger_accounts/create-201' + general_ledger_account.save.must_equal true + general_ledger_account.code.must_equal 'code1' + end + end + + describe "#update" do + it "sends changed attributes to the server" do + stub_api_request :get, 'general_ledger_accounts/u90r5deeaxix', 'general_ledger_accounts/show-200' + stub_request(:put, "https://api.recurly.com/v2/general_ledger_accounts/u90r5deeaxix"). + with(:body => "new_string", + :headers => RecurlyV2::API.headers).to_return(:status => 200, :body => "", :headers => {}) + general_ledger_account.update_attributes({ description: 'new_string' }) + end + end +end diff --git a/spec/recurly_v2/gift_card_spec.rb b/spec/recurly_v2/gift_card_spec.rb index d60e3a8cc..775a97659 100644 --- a/spec/recurly_v2/gift_card_spec.rb +++ b/spec/recurly_v2/gift_card_spec.rb @@ -71,6 +71,12 @@ address.country.must_equal "US" address.phone.must_equal "337-555-5555" end + + it "should return RevRec settings" do + gift_card.revenue_gl_account_id.must_equal "uf0jwincednb" + gift_card.liability_gl_account_id.must_equal "uf0jwj5zhclg" + gift_card.performance_obligation_id.must_equal "1" + end end describe "#to_xml" do @@ -86,6 +92,7 @@ gift_card.to_xml.must_equal expected end end + describe "when creating the account with the gift card purchase" do let(:account_data) do { @@ -121,7 +128,10 @@ currency: 'USD', unit_amount_in_cents: 2000, gifter_account: account_data, - delivery: delivery_data + delivery: delivery_data, + liability_gl_account_id: "uf0jwj5zhclg", + revenue_gl_account_id: "uf0jwincednb", + performance_obligation_id: "1" ) } @@ -153,7 +163,10 @@ Sally Smith + uf0jwj5zhclg + 1 gift_card + uf0jwincednb 2000 XML @@ -187,5 +200,17 @@ actual_xml.must_equal expected_xml end end + + describe "with tax_service_opt_out" do + let(:gift_card) { + RecurlyV2::GiftCard.new( + tax_service_opt_out: true + ) + } + + it "should render a gift card payload with tax_service_opt_out" do + gift_card.to_xml.must_include "true" + end + end end end diff --git a/spec/recurly_v2/invoice_spec.rb b/spec/recurly_v2/invoice_spec.rb index b818a8897..9b165fa2e 100644 --- a/spec/recurly_v2/invoice_spec.rb +++ b/spec/recurly_v2/invoice_spec.rb @@ -141,6 +141,22 @@ end end + describe 'vertex_transaction_type attribute' do + it 'should accept vertex_transaction_type in Invoice.to_xml' do + xml = Invoice.to_xml(vertex_transaction_type: 'rental') + xml.must_include 'rental' + end + + it 'should include vertex_transaction_type in invoice creation params' do + stub_api_request :get, 'accounts/abcdef1234567890', 'accounts/show-200' + stub_api_request :post, 'accounts/abcdef1234567890/invoices', 'invoices/create-201' + + account = Account.find('abcdef1234567890') + invoice_collection = account.invoice!(vertex_transaction_type: 'lease') + invoice_collection.must_be_instance_of InvoiceCollection + end + end + describe "line item refund" do before do stub_api_request :get, 'invoices/refundable-invoice', 'invoices/show-200-refundable' @@ -162,6 +178,22 @@ adjustment.quantity_remaining.must_equal 1 end end + + it "creates a refund invoice for the line items refunded with amount in cents" do + line_items = @invoice.line_items.values.map do |adjustment| + { adjustment: adjustment, amount_in_cents: 100, prorate: false } + end + refund_invoice = @invoice.refund line_items + refund_invoice.must_be_instance_of Invoice + end + + it "creates a refund invoice for the line items refunded with percentage" do + line_items = @invoice.line_items.values.map do |adjustment| + { adjustment: adjustment, percentage: 77, prorate: false } + end + refund_invoice = @invoice.refund line_items + refund_invoice.must_be_instance_of Invoice + end end describe "#refund_to_xml" do @@ -178,6 +210,38 @@ 'credit_firstCredit NotestruecheckCheck no. 123456782018-12-01T00:00:00+00:0017500charge11false' ) end + + it "must serialize line_items with amount_in_cents" do + line_items = @invoice.line_items.values.map do |adjustment| + { adjustment: adjustment, amount_in_cents: 100, prorate: false } + end + options = { + credit_customer_notes: 'Credit Notes', + external_refund: true, + payment_method: 'check', + description: 'Check no. 12345678', + refunded_at: DateTime.new(2018, 12, 1, 0, 0, 0) + } + @invoice.send(:refund_line_items_to_xml, line_items, 'credit_first', options).must_equal( + 'credit_firstCredit NotestruecheckCheck no. 123456782018-12-01T00:00:00+00:00charge1100false' + ) + end + + it "must serialize line_items with percentage" do + line_items = @invoice.line_items.values.map do |adjustment| + { adjustment: adjustment, percentage: 77, prorate: false } + end + options = { + credit_customer_notes: 'Credit Notes', + external_refund: true, + payment_method: 'check', + description: 'Check no. 12345678', + refunded_at: DateTime.new(2018, 12, 1, 0, 0, 0) + } + @invoice.send(:refund_line_items_to_xml, line_items, 'credit_first', options).must_equal( + 'credit_firstCredit NotestruecheckCheck no. 123456782018-12-01T00:00:00+00:00charge177false' + ) + end end end @@ -189,8 +253,8 @@ @invoice = Invoice.find 'refundable-invoice' end - describe "#refund" do - it "creates a refund invoice for the line items refunded" do + describe "#refund_amount" do + it "creates a refund invoice for the line items refunded using amount" do refund_invoice = @invoice.refund_amount 1000 refund_invoice.must_be_instance_of Invoice refund_invoice.original_invoices.must_be_instance_of RecurlyV2::Resource::Pager @@ -198,7 +262,7 @@ end end - describe "#refund_to_xml" do + describe "#refund_amount_to_xml" do it "must serialize amount_in_cents" do options = { credit_customer_notes: 'Credit Notes', @@ -215,6 +279,39 @@ end end + describe "percentage refund" do + before do + stub_api_request :get, 'invoices/refundable-invoice', 'invoices/show-200-refundable' + stub_api_request :post, 'invoices/refundable-invoice/refund', 'invoices/refund_amount-201' + + @invoice = Invoice.find 'refundable-invoice' + end + + describe "#refund_percentage" do + it "creates a refund invoice for the line items refunded using percentage" do + refund_invoice = @invoice.refund_percentage 50 + refund_invoice.must_be_instance_of Invoice + refund_invoice.original_invoices.must_be_instance_of RecurlyV2::Resource::Pager + refund_invoice.amount_remaining_in_cents.must_equal 100 + end + end + + describe "#refund_percentage_to_xml" do + it "must serialize percentage" do + options = { + credit_customer_notes: 'Credit Notes', + external_refund: true, + payment_method: 'check', + description: 'Check no. 12345678', + refunded_at: DateTime.new(2018, 12, 1, 0, 0, 0) + } + @invoice.send(:refund_percentage_to_xml, 50, 'credit_first', options).must_equal( + 'credit_first50Credit NotestruecheckCheck no. 123456782018-12-01T00:00:00+00:00' + ) + end + end + end + describe "failed_refund" do before do stub_api_request :get, 'invoices/refundable-invoice', 'invoices/show-200-refundable' diff --git a/spec/recurly_v2/item_spec.rb b/spec/recurly_v2/item_spec.rb index 98940c472..4e23ecce4 100644 --- a/spec/recurly_v2/item_spec.rb +++ b/spec/recurly_v2/item_spec.rb @@ -10,7 +10,10 @@ accounting_code: '1234', revenue_schedule_type: 'evenly', avalara_transaction_type: 600, - avalara_service_type: 3 + avalara_service_type: 3, + liability_gl_account_id: 'uf0jwj5zhclg', + revenue_gl_account_id: 'uf0jwincednb', + performance_obligation_id: '1' ) end @@ -23,7 +26,10 @@ Some Pink Sweaters\ ABC-123\ pink_sweaters\ +uf0jwj5zhclg\ Pink Sweaters\ +1\ +uf0jwincednb\ evenly\ XML @@ -32,13 +38,42 @@ describe "methods" do let(:item) { Item.find 'plastic_gloves' } + describe "create" do + it "must create a new item" do + stub_api_request :post, 'items', 'items/create-201' + item = Item.create( + item_code: 'pink_sweaters', + name: 'Pink Sweaters', + description: 'Some Pink Sweaters', + external_sku: 'ABC-123', + accounting_code: '1234', + revenue_schedule_type: 'evenly', + avalara_transaction_type: 600, + avalara_service_type: 3, + liability_gl_account_id: 'uf0jwj5zhclg', + revenue_gl_account_id: 'uf0jwincednb', + performance_obligation_id: '1' + ) + item.must_be_instance_of Item + item.description.must_equal 'Sleek Plastic' + end + end + describe ".find" do - it "must return an item when available" do + before do stub_api_request :get, 'items/plastic_gloves', 'items/show-200' + end + it "must return an item when available" do item.must_be_instance_of Item item.description.must_equal 'Sleek Plastic' end + + it "must return RevRec details when available" do + item.liability_gl_account_id.must_equal('uf0jwj5zhclg') + item.revenue_gl_account_id.must_equal('uf0jwincednb') + item.performance_obligation_id.must_equal('1') + end end describe "#save" do @@ -57,9 +92,10 @@ it "sends changed attributes to the server" do stub_api_request :get, 'items/plastic_gloves', 'items/show-200' stub_request(:put, "https://api.recurly.com/v2/items/plastic_gloves"). - with(:body => "Sleek Plastic Gloves", + with(:body => "a8hkyaw9nmSleek Plastic Gloves6aksdfu48", :headers => RecurlyV2::API.headers).to_return(:status => 200, :body => "", :headers => {}) - item.update_attributes({ name: 'Sleek Plastic Gloves' }) + item.update_attributes({ name: 'Sleek Plastic Gloves', revenue_gl_account_id: 'aksdfu48', + liability_gl_account_id: 'a8hkyaw9nm', performance_obligation_id: '6'}) end end diff --git a/spec/recurly_v2/performance_obligation_spec.rb b/spec/recurly_v2/performance_obligation_spec.rb new file mode 100644 index 000000000..634255542 --- /dev/null +++ b/spec/recurly_v2/performance_obligation_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe PerformanceObligation do + let(:performance_obligation) { + stub_api_request(:get, "performance_obligations/6", "performance_obligations/show-200") + RecurlyV2::PerformanceObligation.find '6' + } + + let(:performance_obligations) { + stub_api_request(:get, "performance_obligations", "performance_obligations/index-200") + RecurlyV2::PerformanceObligation.all + } + + describe "#find" do + it "returns a PerformanceObligation" do + performance_obligation.must_be_instance_of(PerformanceObligation) + end + + it "has correct attributes" do + expect(performance_obligation.id).must_equal('6') + expect(performance_obligation.name).must_equal('Over Time (Daily)') + expect(performance_obligation.created_at).wont_be_nil + end + end + + describe "#index" do + describe "when no params are passed" do + it "returns a list of performance obligations" do + expect(performance_obligations.count).must_equal(3) + end + end + end +end \ No newline at end of file diff --git a/spec/recurly_v2/plan_spec.rb b/spec/recurly_v2/plan_spec.rb index f74396154..3cc797a5b 100644 --- a/spec/recurly_v2/plan_spec.rb +++ b/spec/recurly_v2/plan_spec.rb @@ -3,21 +3,21 @@ describe Plan do let(:plan) { Plan.new( - :plan_code => 'gold', - :name => 'The Gold Plan', - :unit_amount_in_cents => 79_00, - :description => 'The Gold Plan is for folks who love gold.', - :accounting_code => 'gold_plan_acc_code', - :setup_fee_accounting_code => 'setup_fee_ac', - :setup_fee_in_cents => 60_00, - :plan_interval_length => 1, - :plan_interval_unit => 'months', - :pricing_model => 'fixed', - :tax_exempt => false, - :revenue_schedule_type => 'evenly', - :avalara_transaction_type => 600, - :avalara_service_type => 3, - :custom_fields => [{ :name => 'color', value: 'Red' }] + :plan_code => 'gold', + :name => 'The Gold Plan', + :unit_amount_in_cents => 79_00, + :description => 'The Gold Plan is for folks who love gold.', + :accounting_code => 'gold_plan_acc_code', + :setup_fee_accounting_code => 'setup_fee_ac', + :setup_fee_in_cents => 60_00, + :plan_interval_length => 1, + :plan_interval_unit => 'months', + :pricing_model => 'fixed', + :tax_exempt => false, + :revenue_schedule_type => 'evenly', + :avalara_transaction_type => 600, + :avalara_service_type => 3, + :custom_fields => [{ :name => 'color', value: 'Red' }], ) } @@ -128,20 +128,76 @@ before do stub_api_request(:get, 'plans/gold', 'plans/show-200') end + let(:plan) { Plan.find 'gold' } it 'returns a plan when available' do - plan = Plan.find 'gold' - plan.must_be_instance_of Plan plan.plan_code.must_equal('gold') end - it 'returns plan with the custom fields' do - plan = Plan.find 'gold' + it 'returns plan with vertex transaction type' do + plan.vertex_transaction_type.must_equal('lease') + end + it 'returns plan with the custom fields' do plan.custom_fields[0].name.must_equal('color') plan.custom_fields[0].value.must_equal('Red') end + + it 'returns RevRec attributes' do + plan.setup_fee_performance_obligation_id.must_equal('4') + plan.performance_obligation_id.must_equal('6') + plan.setup_fee_liability_gl_account_id.must_equal('udf6ktwsed99') + plan.liability_gl_account_id.must_equal('udf6kuqq5rwr') + plan.setup_fee_revenue_gl_account_id.must_equal('udf6ktdh636s') + plan.revenue_gl_account_id.must_equal('udf6kubl7urs') + end + end + + describe 'RevRec attributes' do + let(:plan) { + Plan.new( + :plan_code => 'gold', + :name => 'The Gold Plan', + :unit_amount_in_cents => 79_00, + :description => 'The Gold Plan is for folks who love gold.', + :setup_fee_in_cents => 60_00, + :plan_interval_length => 1, + :plan_interval_unit => 'months', + :pricing_model => 'fixed', + :setup_fee_performance_obligation_id => '1', + :performance_obligation_id => '7uf', + :revenue_gl_account_id => '6t5', + :liability_gl_account_id => '8y7', + ) + } + + let(:expected_xml) do + <<~XML.gsub(' ', '').chomp + \ + The Gold Plan is for folks who love gold.\ + 8y7\ + The Gold Plan\ + 7uf\ + gold\ + 1\ + months\ + fixed\ + 6t5\ + \ + 6000\ + \ + 1\ + \ + 7900\ + \ + + XML + end + + it 'must serialize' do + plan.to_xml.must_equal expected_xml + end end describe '.save!' do @@ -159,4 +215,4 @@ plan.errors['setup_fee_in_cents'].must_equal ['is invalid'] end end -end +end \ No newline at end of file diff --git a/spec/recurly_v2/purchase_spec.rb b/spec/recurly_v2/purchase_spec.rb index 8a74fd5a5..c20226f43 100644 --- a/spec/recurly_v2/purchase_spec.rb +++ b/spec/recurly_v2/purchase_spec.rb @@ -2,23 +2,155 @@ describe Purchase do let(:plan_code) { 'plan_code' } + let(:adjustments) { [{ + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + custom_fields: [ + { + name: 'field1', + value: 'priceless' + } + ] + }]} + + describe 'vertex_transaction_type attribute' do + it 'should accept vertex_transaction_type as a purchase attribute' do + purchase = Purchase.new( + account: {account_code: 'account123'}, + vertex_transaction_type: 'rental', + adjustments: adjustments + ) + purchase.vertex_transaction_type.must_equal 'rental' + end + + it 'should include vertex_transaction_type in XML output' do + purchase = Purchase.new( + account: {account_code: 'account123'}, + vertex_transaction_type: 'lease', + adjustments: adjustments + ) + xml = purchase.to_xml + xml.must_include 'lease' + end + + it 'should accept adjustments with vertex_transaction_type within a purchase request' do + purchase = Purchase.new( + account: {account_code: 'account123'}, + adjustments: [ + { + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + vertex_transaction_type: 'lease' + } + ] + ) + purchase.adjustments.first.vertex_transaction_type.must_equal 'lease' + end + + it 'should include adjustment vertex_transaction_type in XML output' do + purchase = Purchase.new( + account: {account_code: 'account123'}, + adjustments: [ + { + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + vertex_transaction_type: 'rental' + } + ] + ) + xml = purchase.to_xml + xml.must_include 'rental' + end + + it 'should allow both purchase-level and adjustment-level vertex_transaction_type' do + purchase = Purchase.new( + account: {account_code: 'account123'}, + vertex_transaction_type: 'sale', + adjustments: [ + { + product_code: 'product_code_1', + unit_amount_in_cents: 1_000, + quantity: 1, + vertex_transaction_type: 'lease' + }, + { + product_code: 'product_code_2', + unit_amount_in_cents: 2_000, + quantity: 1, + vertex_transaction_type: 'rental' + } + ] + ) + purchase.vertex_transaction_type.must_equal 'sale' + purchase.adjustments[0].vertex_transaction_type.must_equal 'lease' + purchase.adjustments[1].vertex_transaction_type.must_equal 'rental' + end + + it 'should include both purchase and adjustment vertex_transaction_type in XML output' do + purchase = Purchase.new( + account: {account_code: 'account123'}, + vertex_transaction_type: 'sale', + adjustments: [ + { + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + vertex_transaction_type: 'lease' + } + ] + ) + xml = purchase.to_xml + # Purchase-level vertex_transaction_type + xml.must_match(/.*sale<\/vertex_transaction_type>.*<\/purchase>/m) + # Adjustment-level vertex_transaction_type + xml.must_match(/.*lease<\/vertex_transaction_type>.*<\/adjustment>/m) + end + end + let(:purchase) do Purchase.new( account: {account_code: 'account123'}, transaction_type: 'moto', - adjustments: [ + adjustments: adjustments, + subscriptions: [ { - product_code: 'product_code', - unit_amount_in_cents: 1_000, - quantity: 1, - custom_fields: [ - { - name: 'field1', - value: 'priceless' - } + plan_code: plan_code, + subscription_add_ons: [ + add_on_code: 'add_on_code', + unit_amount_in_cents: 200 ] } ], + shipping_address_id: 1234, + shipping_fees: [ + shipping_method_code: 'fedex_ground', + shipping_amount_in_cents: 999 + ], + shipping_address: { + nickname: "Work", + first_name: "Verena", + last_name: "Example", + company: "Recurly Inc.", + phone: "555-555-5555", + email: "verena@example.com", + address1: "400 Alabama St.", + city: "San Francisco", + state: "CA", + zip: "94110", + country: "US" + } + ) + end + let(:purchase_with_net_terms_type) do + Purchase.new( + account: {account_code: 'account123'}, + net_terms: 30, + net_terms_type: 'eom', + transaction_type: 'moto', + adjustments: adjustments, subscriptions: [ { plan_code: plan_code, @@ -58,6 +190,12 @@ shipping_address.must_be_instance_of ShippingAddress end + it 'should contain action result attribute on response' do + stub_api_request(:post, 'purchases', 'purchases/invoice-with-action-result-201') + collection = Purchase.invoice!(purchase) + expect(collection.charge_invoice.transactions.first.action_result).must_equal('example') + end + it 'the first ramp interval unit amount is reflected in these expected attributes' do stub_api_request(:post, 'purchases', 'purchases/invoice-with-ramp-pricing-201') collection = Purchase.invoice!(purchase) @@ -75,6 +213,16 @@ charge_invoice.transactions.first.amount_in_cents.must_equal 7000 end + it 'should return an invoice_collection with net_terms_type when valid' do + stub_api_request(:post, 'purchases', 'purchases/invoice-with-eom-net-terms-201') + collection = Purchase.invoice!(purchase_with_net_terms_type) + charge_invoice = collection.charge_invoice + + charge_invoice.total_in_cents.must_equal 7000 + charge_invoice.net_terms.must_equal 30 + charge_invoice.net_terms_type.must_equal 'eom' + end + it 'should raise an Invalid error when data is invalid' do stub_api_request(:post, 'purchases', 'purchases/invoice-422') # ensure error is raised @@ -95,6 +243,26 @@ purchase.adjustments.first.custom_fields.first.name.must_equal 'field1' purchase.adjustments.first.custom_fields.first.value.must_equal 'priceless' end + + describe 'with RevRec feature flag' do + let(:adjustments) { [{ + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + liability_gl_account_id: 'ad8h3layw', + revenue_gl_account_id: 'ydu5owk', + performance_obligation_id: '5', + }] + } + it 'should return RevRec details for an adjustment on a purchase that has RevRec details' do + stub_api_request(:post, 'purchases', 'purchases/invoice-201-with-revrec') + collection = Purchase.invoice!(purchase) + adjustment_list = collection.charge_invoice.line_items + adjustment_list.first.liability_gl_account_code.must_equal 'liability_gla' + adjustment_list.first.revenue_gl_account_code.must_equal 'revenue_gla' + adjustment_list.first.performance_obligation_id.must_equal '5' + end + end end describe 'Purchase.preview!' do @@ -104,6 +272,14 @@ preview_collection.charge_invoice.must_be_instance_of Invoice end + it 'should return a preview invoice with net_terms_type when valid' do + stub_api_request(:post, 'purchases/preview', 'purchases/preview-201-with-eom-net-terms') + preview_collection = Purchase.preview!(purchase_with_net_terms_type) + preview_collection.charge_invoice.must_be_instance_of Invoice + preview_collection.charge_invoice.net_terms.must_equal 30 + preview_collection.charge_invoice.net_terms_type.must_equal 'eom' + end + it 'the first ramp interval unit amount is reflected in these expected attributes' do stub_api_request(:post, 'purchases/preview', 'purchases/preview-with-ramp-pricing-201') collection = Purchase.preview!(purchase) @@ -126,6 +302,26 @@ # ensure error details are mapped back purchase.adjustments.first.errors['unit_amount_in_cents'].must_equal ['is not a number'] end + + describe 'with RevRec feature flag' do + let(:adjustments) { [{ + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + liability_gl_account_id: 'ad8h3layw', + revenue_gl_account_id: 'ydu5owk', + performance_obligation_id: '5', + }] + } + it 'should return RevRec details for an adjustment on a purchase that has RevRec details' do + stub_api_request(:post, 'purchases/preview', 'purchases/preview-201-with-revrec') + preview_collection = Purchase.preview!(purchase) + adjustment_list = preview_collection.charge_invoice.line_items + adjustment_list.first.liability_gl_account_code.must_equal 'liability_gla' + adjustment_list.first.revenue_gl_account_code.must_equal 'revenue_gla' + adjustment_list.first.performance_obligation_id.must_equal '5' + end + end end describe 'Purchase.authorize!' do @@ -160,6 +356,26 @@ # ensure error details are mapped back purchase.adjustments.first.errors['unit_amount_in_cents'].must_equal ['is not a number'] end + + describe 'with RevRec feature flag' do + let(:adjustments) { [{ + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + liability_gl_account_id: 'ad8h3layw', + revenue_gl_account_id: 'ydu5owk', + performance_obligation_id: '5', + }] + } + it 'should return RevRec details for an adjustment on a purchase that has RevRec details' do + stub_api_request(:post, 'purchases/authorize', 'purchases/preview-201-with-revrec') + authorized_collection = Purchase.authorize!(purchase) + adjustment_list = authorized_collection.charge_invoice.line_items + adjustment_list.first.liability_gl_account_code.must_equal 'liability_gla' + adjustment_list.first.revenue_gl_account_code.must_equal 'revenue_gla' + adjustment_list.first.performance_obligation_id.must_equal '5' + end + end end describe 'Purchase.pending!' do @@ -192,6 +408,26 @@ # ensure error details are mapped back purchase.adjustments.first.errors['unit_amount_in_cents'].must_equal ['is not a number'] end + + describe 'with RevRec feature flag' do + let(:adjustments) { [{ + product_code: 'product_code', + unit_amount_in_cents: 1_000, + quantity: 1, + liability_gl_account_id: 'ad8h3layw', + revenue_gl_account_id: 'ydu5owk', + performance_obligation_id: '5', + }] + } + it 'should return RevRec details for an adjustment on a purchase that has RevRec details' do + stub_api_request(:post, 'purchases/pending', 'purchases/preview-201-with-revrec') + pending_collection = Purchase.pending!(purchase) + adjustment_list = pending_collection.charge_invoice.line_items + adjustment_list.first.liability_gl_account_code.must_equal 'liability_gla' + adjustment_list.first.revenue_gl_account_code.must_equal 'revenue_gla' + adjustment_list.first.performance_obligation_id.must_equal '5' + end + end end describe "Purchase.capture!" do diff --git a/spec/recurly_v2/shipping_method_spec.rb b/spec/recurly_v2/shipping_method_spec.rb index 0e4094383..a805850a2 100644 --- a/spec/recurly_v2/shipping_method_spec.rb +++ b/spec/recurly_v2/shipping_method_spec.rb @@ -2,12 +2,21 @@ describe ShippingMethod do describe ".find" do - it "must return a shipping method when available" do + before do stub_api_request( :get, 'shipping_methods/fedex_ground', 'shipping_methods/show-200' - ) + ) + end + it "must return a shipping method when available" do shipping_method = ShippingMethod.find 'fedex_ground' shipping_method.must_be_instance_of ShippingMethod end + + it "returns RevRec values" do + shipping_method = ShippingMethod.find 'fedex_ground' + shipping_method.performance_obligation_id.must_equal('4') + shipping_method.revenue_gl_account_id.must_equal('thproqnpcuwp') + shipping_method.liability_gl_account_id.must_equal('twywqfr48v9l') + end end end \ No newline at end of file diff --git a/spec/recurly_v2/subscription_spec.rb b/spec/recurly_v2/subscription_spec.rb index 06dc8dcca..29a114f47 100644 --- a/spec/recurly_v2/subscription_spec.rb +++ b/spec/recurly_v2/subscription_spec.rb @@ -57,6 +57,13 @@ subscription.po_number.must_equal('1000') end + it "check deserialize for net_terms_type" do + subscription = Subscription.from_xml get_raw_xml("subscriptions/show-200-with-eom-net-terms.xml") + subscription.must_be_instance_of Subscription + subscription.net_terms.must_equal(30) + subscription.net_terms_type.must_equal('eom') + end + it 'can deserialize tax information' do stub_api_request :get, 'subscriptions/abc1234', 'subscriptions/show-200-taxed' subscription = Subscription.find 'abc1234' @@ -90,6 +97,46 @@ subscription = Subscription.new attributes subscription.to_xml.must_equal get_raw_xml('subscriptions/serialize-with-ramps.xml') end + + describe 'with starting_on and ending_on' do + before do + attributes.merge!( + ramp_intervals: [ + SubscriptionRampInterval.new( + starting_billing_cycle: 1, + unit_amount_in_cents: 1000, + starting_on: '2022-09-23 16:16:34.000000', + ending_on: '2022-10-23 16:16:34.000000' + ), + SubscriptionRampInterval.new( + starting_billing_cycle: 2, + unit_amount_in_cents: 2000, + starting_on: '2022-10-23 16:16:34.000000', + ending_on: nil + ) + ] + ) + end + + it 'contains the expected attributes' do + sub = Subscription.from_xml(get_raw_xml 'subscriptions/serialize-with-ramps-starting-on-ending-on.xml') + + expect(sub.ramp_intervals[0].starting_on).must_equal('2022-09-23 16:16:34.000000') + expect(sub.ramp_intervals[0].ending_on).must_equal('2022-10-23 16:16:34.000000') + expect(sub.ramp_intervals[0].starting_billing_cycle).must_equal('1') + expect(sub.ramp_intervals[0].unit_amount_in_cents).must_equal('1000') + + expect(sub.ramp_intervals[1].starting_on).must_equal('2022-10-23 16:16:34.000000') + expect(sub.ramp_intervals[1].ending_on).must_be_nil + expect(sub.ramp_intervals[1].starting_billing_cycle).must_equal('2') + expect(sub.ramp_intervals[1].unit_amount_in_cents).must_equal('2000') + end + end + end + + it 'contains action result attribute' do + subscription = Subscription.from_xml(get_raw_xml 'subscriptions/serialize-with-action-result.xml') + expect(subscription.action_result).must_equal('example') end end @@ -394,6 +441,21 @@ subscription.invoice_collection.must_be_instance_of InvoiceCollection subscription.invoice_collection.charge_invoice.must_be_instance_of Invoice end + + it 'previews subscription with net_terms_type' do + stub_api_request :get, 'subscriptions/abcdef1234567890', 'subscriptions/show-200-noinvoice' + stub_api_request :post, 'subscriptions/abcdef1234567890/preview', 'subscriptions/preview-200-change-with-eom-net-terms' + + subscription = Subscription.find 'abcdef1234567890' + subscription.net_terms = 60 + subscription.net_terms_type = 'eom' + subscription.preview + + subscription.invoice_collection.must_be_instance_of InvoiceCollection + subscription.invoice_collection.charge_invoice.must_be_instance_of Invoice + subscription.invoice_collection.charge_invoice.net_terms.must_equal 60 + subscription.invoice_collection.charge_invoice.net_terms_type.must_equal 'eom' + end end describe 'pausing and resuming' do