flex_commerce_api 0.6.57

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +6 -0
  3. data/.gitignore +14 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +1065 -0
  6. data/.ruby-gemset +1 -0
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +3 -0
  9. data/Gemfile +4 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +56 -0
  12. data/Rakefile +1 -0
  13. data/app/models/address.rb +41 -0
  14. data/app/models/asset_file.rb +26 -0
  15. data/app/models/asset_folder.rb +14 -0
  16. data/app/models/bundle.rb +20 -0
  17. data/app/models/bundle_group.rb +15 -0
  18. data/app/models/cart.rb +136 -0
  19. data/app/models/category.rb +70 -0
  20. data/app/models/category_tree.rb +11 -0
  21. data/app/models/component.rb +8 -0
  22. data/app/models/container_coupon.rb +12 -0
  23. data/app/models/country.rb +11 -0
  24. data/app/models/coupon.rb +18 -0
  25. data/app/models/customer_account.rb +96 -0
  26. data/app/models/customer_account_authentication.rb +5 -0
  27. data/app/models/customer_segment.rb +6 -0
  28. data/app/models/customer_segment_member.rb +6 -0
  29. data/app/models/data_attribute.rb +6 -0
  30. data/app/models/data_store_record.rb +9 -0
  31. data/app/models/data_store_type.rb +9 -0
  32. data/app/models/discount_summary.rb +12 -0
  33. data/app/models/email.rb +5 -0
  34. data/app/models/ewis_opt_in.rb +8 -0
  35. data/app/models/external_url.rb +6 -0
  36. data/app/models/free_shipping_promotion.rb +12 -0
  37. data/app/models/import.rb +6 -0
  38. data/app/models/import_entry.rb +6 -0
  39. data/app/models/line_item.rb +34 -0
  40. data/app/models/line_item_discount.rb +7 -0
  41. data/app/models/markdown_price.rb +11 -0
  42. data/app/models/menu.rb +36 -0
  43. data/app/models/menu_item.rb +7 -0
  44. data/app/models/menu_item_item.rb +5 -0
  45. data/app/models/note.rb +18 -0
  46. data/app/models/order.rb +38 -0
  47. data/app/models/password_recovery.rb +20 -0
  48. data/app/models/payment_address_verification.rb +13 -0
  49. data/app/models/payment_process.rb +13 -0
  50. data/app/models/payment_provider.rb +15 -0
  51. data/app/models/payment_transaction.rb +13 -0
  52. data/app/models/product.rb +99 -0
  53. data/app/models/product_asset_file.rb +12 -0
  54. data/app/models/promotion.rb +19 -0
  55. data/app/models/promotion_qualifying_product_exclusion.rb +8 -0
  56. data/app/models/redirect.rb +14 -0
  57. data/app/models/refund.rb +14 -0
  58. data/app/models/remote_address.rb +22 -0
  59. data/app/models/remote_line_item.rb +11 -0
  60. data/app/models/remote_order.rb +15 -0
  61. data/app/models/remote_shipping_method.rb +12 -0
  62. data/app/models/report.rb +18 -0
  63. data/app/models/report_invocation.rb +18 -0
  64. data/app/models/retail_store.rb +18 -0
  65. data/app/models/role.rb +6 -0
  66. data/app/models/search_suggestion.rb +17 -0
  67. data/app/models/section.rb +9 -0
  68. data/app/models/session.rb +8 -0
  69. data/app/models/shipping_method.rb +26 -0
  70. data/app/models/slug.rb +19 -0
  71. data/app/models/static_page.rb +60 -0
  72. data/app/models/static_page_folder.rb +8 -0
  73. data/app/models/stock_level.rb +21 -0
  74. data/app/models/tax_code.rb +6 -0
  75. data/app/models/taxonomy.rb +5 -0
  76. data/app/models/template.rb +9 -0
  77. data/app/models/template_component.rb +11 -0
  78. data/app/models/template_definition.rb +12 -0
  79. data/app/models/template_section.rb +12 -0
  80. data/app/models/user.rb +8 -0
  81. data/app/models/user_profile.rb +6 -0
  82. data/app/models/v2/create_order.rb +10 -0
  83. data/app/models/v2/deallocate_order.rb +10 -0
  84. data/app/models/v2/line_item.rb +9 -0
  85. data/app/models/v2/order.rb +9 -0
  86. data/app/models/v2/unallocate_order.rb +10 -0
  87. data/app/models/variant.rb +18 -0
  88. data/app/models/webhook.rb +17 -0
  89. data/app/services/param_to_shql.rb +72 -0
  90. data/app/services/surrogate_keys.rb +44 -0
  91. data/bin/console +14 -0
  92. data/bin/setup +7 -0
  93. data/config/locales/payments.en.yml +3 -0
  94. data/flex-commerce-api.gemspec +41 -0
  95. data/lib/flex_commerce.rb +95 -0
  96. data/lib/flex_commerce_api.rb +21 -0
  97. data/lib/flex_commerce_api/api_base.rb +11 -0
  98. data/lib/flex_commerce_api/base_resource.rb +250 -0
  99. data/lib/flex_commerce_api/config.rb +55 -0
  100. data/lib/flex_commerce_api/error/access_denied.rb +6 -0
  101. data/lib/flex_commerce_api/error/bad_request.rb +10 -0
  102. data/lib/flex_commerce_api/error/base.rb +12 -0
  103. data/lib/flex_commerce_api/error/client_error.rb +7 -0
  104. data/lib/flex_commerce_api/error/connection_error.rb +6 -0
  105. data/lib/flex_commerce_api/error/internal_server.rb +37 -0
  106. data/lib/flex_commerce_api/error/not_found.rb +13 -0
  107. data/lib/flex_commerce_api/error/record_invalid.rb +16 -0
  108. data/lib/flex_commerce_api/error/unexpected_status.rb +7 -0
  109. data/lib/flex_commerce_api/errors.rb +13 -0
  110. data/lib/flex_commerce_api/json_api_client_extension/builder.rb +28 -0
  111. data/lib/flex_commerce_api/json_api_client_extension/capture_surrogate_keys_middleware.rb +16 -0
  112. data/lib/flex_commerce_api/json_api_client_extension/flexible_connection.rb +59 -0
  113. data/lib/flex_commerce_api/json_api_client_extension/has_many_association_proxy.rb +60 -0
  114. data/lib/flex_commerce_api/json_api_client_extension/included_data.rb +27 -0
  115. data/lib/flex_commerce_api/json_api_client_extension/json_format_middleware.rb +20 -0
  116. data/lib/flex_commerce_api/json_api_client_extension/logging_middleware.rb +24 -0
  117. data/lib/flex_commerce_api/json_api_client_extension/paginator.rb +26 -0
  118. data/lib/flex_commerce_api/json_api_client_extension/parse_json.rb +23 -0
  119. data/lib/flex_commerce_api/json_api_client_extension/parsers/parser.rb +16 -0
  120. data/lib/flex_commerce_api/json_api_client_extension/previewed_request_middleware.rb +17 -0
  121. data/lib/flex_commerce_api/json_api_client_extension/remote_builder.rb +29 -0
  122. data/lib/flex_commerce_api/json_api_client_extension/requestor.rb +42 -0
  123. data/lib/flex_commerce_api/json_api_client_extension/save_request_body_middleware.rb +20 -0
  124. data/lib/flex_commerce_api/json_api_client_extension/status_middleware.rb +40 -0
  125. data/lib/flex_commerce_api/v2/api_base.rb +13 -0
  126. data/lib/flex_commerce_api/version.rb +3 -0
  127. data/lib/json_erb.rb +9 -0
  128. data/lib/json_struct.rb +73 -0
  129. data/lib/patches.rb +4 -0
  130. data/lib/patches/json_api_client/resource.rb +50 -0
  131. data/lib/paypal_express.rb +3 -0
  132. data/lib/paypal_express/additional_info.rb +45 -0
  133. data/lib/paypal_express/api.rb +86 -0
  134. data/lib/paypal_express/auth.rb +83 -0
  135. data/lib/paypal_express/cart_shipping_method.rb +38 -0
  136. data/lib/paypal_express/exception/access_denied.rb +10 -0
  137. data/lib/paypal_express/exception/connection_error.rb +10 -0
  138. data/lib/paypal_express/exception/not_authorized.rb +10 -0
  139. data/lib/paypal_express/exception/transaction.rb +15 -0
  140. data/lib/paypal_express/generate_summary.rb +118 -0
  141. data/lib/paypal_express/process/paypal_params.rb +123 -0
  142. data/lib/paypal_express/process/response_parser.rb +146 -0
  143. data/lib/paypal_express/setup.rb +94 -0
  144. data/lib/paypal_express/shipping_methods_for_cart.rb +46 -0
  145. data/lib/retry.rb +20 -0
  146. data/schemas/jsonapi/schema.json +370 -0
  147. data/schemas/shift/v1/documents/collection/address.json +45 -0
  148. data/schemas/shift/v1/documents/collection/asset_file.json +43 -0
  149. data/schemas/shift/v1/documents/collection/asset_folder.json +43 -0
  150. data/schemas/shift/v1/documents/collection/customer_account.json +50 -0
  151. data/schemas/shift/v1/documents/collection/markdown_price.json +43 -0
  152. data/schemas/shift/v1/documents/collection/product.json +43 -0
  153. data/schemas/shift/v1/documents/collection/variant.json +43 -0
  154. data/schemas/shift/v1/documents/member/address.json +39 -0
  155. data/schemas/shift/v1/documents/member/asset_file.json +37 -0
  156. data/schemas/shift/v1/documents/member/asset_folder.json +39 -0
  157. data/schemas/shift/v1/documents/member/customer_account.json +44 -0
  158. data/schemas/shift/v1/documents/member/markdown_price.json +37 -0
  159. data/schemas/shift/v1/documents/member/product.json +39 -0
  160. data/schemas/shift/v1/documents/member/variant.json +46 -0
  161. data/schemas/shift/v1/resources/address.json +130 -0
  162. data/schemas/shift/v1/resources/asset_file.json +146 -0
  163. data/schemas/shift/v1/resources/asset_folder.json +188 -0
  164. data/schemas/shift/v1/resources/customer_account.json +339 -0
  165. data/schemas/shift/v1/resources/markdown_price.json +52 -0
  166. data/schemas/shift/v1/resources/product.json +230 -0
  167. data/schemas/shift/v1/resources/variant.json +298 -0
  168. data/tasks/json_schema.thor +275 -0
  169. data/todo.md +8 -0
  170. metadata +470 -0
@@ -0,0 +1,95 @@
1
+ module FlexCommerce
2
+ def self.gem_root
3
+ File.expand_path("../", __dir__)
4
+ end
5
+
6
+ # V2 Models
7
+ module V2
8
+ autoload :CreateOrder, File.join(FlexCommerce.gem_root, "app", "models", "v2", "create_order")
9
+ autoload :DeallocateOrder, File.join(FlexCommerce.gem_root, "app", "models", "v2", "deallocate_order")
10
+ autoload :LineItem, File.join(FlexCommerce.gem_root, "app", "models", "v2", "line_item")
11
+ autoload :Order, File.join(FlexCommerce.gem_root, "app", "models", "v2", "order")
12
+ autoload :UnallocateOrder, File.join(FlexCommerce.gem_root, "app", "models", "v2", "unallocate_order")
13
+ end
14
+
15
+ # V1 Models
16
+ autoload :Address, File.join(gem_root, "app", "models", "address")
17
+ autoload :AssetFile, File.join(gem_root, "app", "models", "asset_file")
18
+ autoload :AssetFolder, File.join(gem_root, "app", "models", "asset_folder")
19
+ autoload :Bundle, File.join(gem_root, "app", "models", "bundle")
20
+ autoload :BundleGroup, File.join(gem_root, "app", "models", "bundle_group")
21
+ autoload :Cart, File.join(gem_root, "app", "models", "cart")
22
+ autoload :Category, File.join(gem_root, "app", "models", "category")
23
+ autoload :CategoryTree, File.join(gem_root, "app", "models", "category_tree")
24
+ autoload :Component, File.join(gem_root, "app", "models", "component")
25
+ autoload :ContainerCoupon, File.join(gem_root, "app", "models", "container_coupon")
26
+ autoload :Country, File.join(gem_root, "app", "models", "country")
27
+ autoload :Coupon, File.join(gem_root, "app", "models", "coupon")
28
+ autoload :CustomerAccount, File.join(gem_root, "app", "models", "customer_account")
29
+ autoload :CustomerAccountAuthentication, File.join(gem_root, "app", "models", "customer_account_authentication")
30
+ autoload :CustomerSegment, File.join(gem_root, "app", "models", "customer_segment")
31
+ autoload :CustomerSegmentMember, File.join(gem_root, "app", "models", "customer_segment_member")
32
+ autoload :DataAttribute, File.join(gem_root, "app", "models", "data_attribute")
33
+ autoload :DataStoreRecord, File.join(gem_root, "app", "models", "data_store_record")
34
+ autoload :DataStoreType, File.join(gem_root, "app", "models", "data_store_type")
35
+ autoload :DiscountSummary, File.join(gem_root, "app", "models", "discount_summary")
36
+ autoload :Email, File.join(gem_root, "app", "models", "email")
37
+ autoload :EwisOptIn, File.join(gem_root, "app", "models", "ewis_opt_in")
38
+ autoload :ExternalUrl, File.join(gem_root, "app", "models", "external_url")
39
+ autoload :FreeShippingPromotion, File.join(gem_root, "app", "models", "free_shipping_promotion")
40
+ autoload :Import, File.join(gem_root, "app", "models", "import")
41
+ autoload :ImportEntry, File.join(gem_root, "app", "models", "import_entry")
42
+ autoload :LineItem, File.join(gem_root, "app", "models", "line_item")
43
+ autoload :LineItemDiscount, File.join(gem_root, "app", "models", "line_item_discount")
44
+ autoload :MarkdownPrice, File.join(gem_root, "app", "models", "markdown_price")
45
+ autoload :Menu, File.join(gem_root, "app", "models", "menu")
46
+ autoload :MenuItem, File.join(gem_root, "app", "models", "menu_item")
47
+ autoload :MenuItemItem, File.join(gem_root, "app", "models", "menu_item_item")
48
+ autoload :Note, File.join(gem_root, "app", "models", "note")
49
+ autoload :Order, File.join(gem_root, "app", "models", "order")
50
+ autoload :PasswordRecovery, File.join(gem_root, "app", "models", "password_recovery")
51
+ autoload :PaymentAdditionalInfo, File.join(gem_root, "app", "models", "payment_additional_info")
52
+ autoload :PaymentAddressVerification, File.join(gem_root, "app", "models", "payment_address_verification")
53
+ autoload :PaymentProcess, File.join(gem_root, "app", "models", "payment_process")
54
+ autoload :PaymentProvider, File.join(gem_root, "app", "models", "payment_provider")
55
+ autoload :PaymentProviderSetup, File.join(gem_root, "app", "models", "payment_provider_setup")
56
+ autoload :PaymentTransaction, File.join(gem_root, "app", "models", "payment_transaction")
57
+ autoload :Product, File.join(gem_root, "app", "models", "product")
58
+ autoload :ProductAssetFile, File.join(gem_root, "app", "models", "product_asset_file")
59
+ autoload :Promotion, File.join(gem_root, "app", "models", "promotion")
60
+ autoload :PromotionQualifyingProductExclusion, File.join(gem_root, "app", "models", "promotion_qualifying_product_exclusion")
61
+ autoload :Redirect, File.join(gem_root, "app", "models", "redirect")
62
+ autoload :Refund, File.join(gem_root, "app", "models", "refund")
63
+ autoload :RemoteAddress, File.join(gem_root, "app", "models", "remote_address")
64
+ autoload :RemoteLineItem, File.join(gem_root, "app", "models", "remote_line_item")
65
+ autoload :RemoteOrder, File.join(gem_root, "app", "models", "remote_order")
66
+ autoload :RemoteShippingMethod, File.join(gem_root, "app", "models", "remote_shipping_method")
67
+ autoload :Role, File.join(gem_root, "app", "models", "role")
68
+ autoload :Report, File.join(gem_root, "app", "models", "report")
69
+ autoload :ReportInvocation, File.join(gem_root, "app", "models", "report_invocation")
70
+ autoload :RetailStore, File.join(gem_root, "app", "models", "retail_store")
71
+ autoload :SearchSuggestion, File.join(gem_root, "app", "models", "search_suggestion")
72
+ autoload :Section, File.join(gem_root, "app", "models", "section")
73
+ autoload :Session, File.join(gem_root, "app", "models", "session")
74
+ autoload :ShippingMethod, File.join(gem_root, "app", "models", "shipping_method")
75
+ autoload :Slug, File.join(gem_root, "app", "models", "slug")
76
+ autoload :StaticPage, File.join(gem_root, "app", "models", "static_page")
77
+ autoload :StaticPageFolder, File.join(gem_root, "app", "models", "static_page_folder")
78
+ autoload :StockLevel, File.join(gem_root, "app", "models", "stock_level")
79
+ autoload :TaxCode, File.join(gem_root, "app", "models", "tax_code")
80
+ autoload :Taxonomy, File.join(gem_root, "app", "models", "taxonomy")
81
+ autoload :Template, File.join(gem_root, "app", "models", "template")
82
+ autoload :TemplateComponent, File.join(gem_root, "app", "models", "template_component")
83
+ autoload :TemplateDefinition, File.join(gem_root, "app", "models", "template_definition")
84
+ autoload :TemplateSection, File.join(gem_root, "app", "models", "template_section")
85
+ autoload :User, File.join(gem_root, "app", "models", "user")
86
+ autoload :UserProfile, File.join(gem_root, "app", "models", "user_profile")
87
+ autoload :Variant, File.join(gem_root, "app", "models", "variant")
88
+ autoload :Webhook, File.join(gem_root, "app", "models", "webhook")
89
+
90
+ # Services
91
+ autoload :ParamToShql, File.join(gem_root, "app", "services", "param_to_shql")
92
+ autoload :SurrogateKeys, File.join(gem_root, "app", "services", "surrogate_keys")
93
+ autoload :PaypalExpress, File.join(gem_root, "lib", "paypal_express")
94
+ autoload :Retry, File.join(gem_root, "lib", "retry")
95
+ end
@@ -0,0 +1,21 @@
1
+ require "patches"
2
+ require "paypal_express"
3
+ require "flex_commerce_api/config"
4
+ require "flex_commerce"
5
+ require "flex_commerce_api/errors"
6
+ require "flex_commerce_api/json_api_client_extension/parse_json"
7
+
8
+ module FlexCommerceApi
9
+ def self.config
10
+ FlexCommerceApi::Config.instance.tap do |config|
11
+ yield config if block_given?
12
+ config.reconfigure_all! if block_given?
13
+ end
14
+ end
15
+ def self.gem_root
16
+ File.expand_path("../", __dir__)
17
+ end
18
+ def self.logger
19
+ FlexCommerceApi::Config.instance.logger
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ require "flex_commerce_api/base_resource"
2
+
3
+ module FlexCommerceApi
4
+ class ApiBase < BaseResource
5
+ def self.endpoint_version
6
+ "v1"
7
+ end
8
+
9
+ reconfigure
10
+ end
11
+ end
@@ -0,0 +1,250 @@
1
+ require "json_api_client"
2
+ require "faraday/request/basic_authentication"
3
+ require "uri"
4
+ require "active_support/core_ext/hash/indifferent_access"
5
+ require "flex_commerce_api/json_api_client_extension/paginator"
6
+ require "flex_commerce_api/json_api_client_extension/requestor"
7
+ require "flex_commerce_api/json_api_client_extension/save_request_body_middleware"
8
+ require "flex_commerce_api/json_api_client_extension/logging_middleware"
9
+ require "flex_commerce_api/json_api_client_extension/status_middleware"
10
+ require "flex_commerce_api/json_api_client_extension/json_format_middleware"
11
+ require "flex_commerce_api/json_api_client_extension/previewed_request_middleware"
12
+ require "flex_commerce_api/json_api_client_extension/capture_surrogate_keys_middleware"
13
+ require "flex_commerce_api/json_api_client_extension/has_many_association_proxy"
14
+ require "flex_commerce_api/json_api_client_extension/builder"
15
+ require "flex_commerce_api/json_api_client_extension/flexible_connection"
16
+ require "flex_commerce_api/json_api_client_extension/parsers/parser"
17
+ require "flex_commerce_api/json_api_client_extension/remote_builder"
18
+
19
+ module FlexCommerceApi
20
+ #
21
+ # Base class for all flex commerce models
22
+ #
23
+ class BaseResource < JsonApiClient::Resource
24
+ PRIVATE_ATTRIBUTES = %w(id type relationships links meta)
25
+ RELATED_META_RESOURCES = %w(related-categories related-static_pages related-resources related-files related-products)
26
+
27
+ # set the api base url in an abstract base class
28
+ self.paginator = JsonApiClientExtension::Paginator
29
+ self.requestor_class = JsonApiClientExtension::Requestor
30
+ self.connection_class = ::FlexCommerceApi::JsonApiClientExtension::FlexibleConnection
31
+ self.parser = ::FlexCommerceApi::JsonApiClientExtension::Parsers::Parser
32
+
33
+ class << self
34
+ def create!(*args)
35
+ create(*args).tap do |resource|
36
+ raise(::FlexCommerceApi::Error::RecordInvalid.new(resource)) unless resource.errors.empty?
37
+ end
38
+ end
39
+
40
+ # @method all
41
+ # Returns all resources
42
+ # @return [FlexCommerceApi::ApiBase[]] An array of resources or an empty array
43
+
44
+ # @method paginate
45
+ # Paginates the list of resources by a preset page size
46
+ # @param [Hash] options The options to paginate with
47
+ # @param options [Numeric|String] :page The page to fetch
48
+
49
+ # @method find_all
50
+ # Finds many resources, always returning an array, even if 1 result
51
+ alias_method :find_all, :find
52
+
53
+ # @method find
54
+ # @param [String] spec The spec of what to find
55
+ #
56
+ # Finds a resource
57
+ # @return [FlexCommerceApi::ApiBase] resource The resource found
58
+ # @raise [FlexCommerceApi::Error::NotFound] If not found
59
+ def find(*args)
60
+ # This is required as currently the underlying gem returns an array
61
+ # even if 1 record is found. This is inconsistent with active record
62
+ result = super
63
+ result.length <= 1 ? result.first : result
64
+ end
65
+
66
+ # The username to use for authentication.
67
+ # @return [String] The username
68
+ def username
69
+ username = FlexCommerceApi.config.flex_account
70
+ username = URI.parse(site).path.split("/").reject(&:empty?).first if username.nil? || username.empty?
71
+ username
72
+ end
73
+
74
+ # The password to use for authentication. This is the same as
75
+ # the access key token from the flex platform.
76
+ # @return [String] The password
77
+ def password
78
+ FlexCommerceApi.config.flex_api_key
79
+ end
80
+
81
+ def path(params = nil, record = nil)
82
+ super(params)
83
+ end
84
+
85
+ def capture_surrogate_keys
86
+ Thread.current[:shift_surrogate_keys] = []
87
+ yield
88
+ Thread.current[:shift_surrogate_keys].uniq!
89
+ results = Thread.current[:shift_surrogate_keys].join(' ')
90
+ Thread.current[:shift_surrogate_keys] = nil
91
+ results
92
+ end
93
+
94
+ def reconfigure_all options = {}
95
+ self.subclasses.each do |sub|
96
+ sub.reconfigure_api_base options
97
+ end
98
+ end
99
+
100
+ def reconfigure_api_base options = {}
101
+ self.subclasses.each do |sub|
102
+ sub.reconfigure options
103
+ end
104
+ reconfigure options
105
+ end
106
+
107
+ def reconfigure options = {}
108
+ self.site = append_version(FlexCommerceApi.config.api_base_url)
109
+ base_options = {
110
+ adapter: FlexCommerceApi.config.adapter || :net_http,
111
+ http_cache: FlexCommerceApi.config.http_cache,
112
+ timeout: FlexCommerceApi.config.timeout,
113
+ open_timeout: FlexCommerceApi.config.open_timeout
114
+ }
115
+ self.connection_options.delete(:include_previewed)
116
+ self.connection_options = connection_options.merge(base_options).merge(options)
117
+ reload_connection_if_required
118
+ end
119
+
120
+ def reload_connection_if_required
121
+ _build_connection(true) if connection_object
122
+ end
123
+
124
+ # Allows ApiBase to be used as the class and the real class is then calculated from the type
125
+ def load(params)
126
+ return super unless self == FlexCommerceApi::ApiBase
127
+ klass = JsonApiClient::Utils.compute_type(FlexCommerce, params["type"].singularize.classify)
128
+ klass.load(params)
129
+ end
130
+
131
+ def append_version(base_url)
132
+ "#{base_url}/#{endpoint_version}"
133
+ end
134
+
135
+ def endpoint_version
136
+ raise NotImplementedError
137
+ end
138
+ end
139
+
140
+ def freeze
141
+ attributes.freeze
142
+ associations.freeze
143
+ links.freeze
144
+ relationships.freeze
145
+ self
146
+ end
147
+
148
+ # Ensures all attributes are with indifferent access
149
+ def initialize(attrs = {})
150
+ super attrs.with_indifferent_access
151
+ end
152
+
153
+ def save!
154
+ return if save
155
+ raise_record_invalid
156
+ end
157
+
158
+ def public_attributes
159
+ attributes.reject { |k, v| PRIVATE_ATTRIBUTES.include?(k.to_s) }
160
+ end
161
+
162
+ def meta_attribute(key)
163
+ begin
164
+ return self.send(key) if RELATED_META_RESOURCES.include?(attributes[:meta_attributes][key][:data_type])
165
+ attributes[:meta_attributes][key][:value]
166
+ rescue NoMethodError
167
+ nil
168
+ end
169
+ end
170
+
171
+ def method_missing(method, *args)
172
+ if relationships and relationships.has_attribute?(method)
173
+ super
174
+ else
175
+ has_attribute?(method) || method.to_s=~(/=$/) || method.to_s=~/!$/ ? super : nil
176
+ end
177
+ end
178
+
179
+ def as_json_api(*args)
180
+ convert_relationship_attributes! super(*args)
181
+ end
182
+
183
+ private
184
+
185
+ def convert_relationship_attributes!(h)
186
+ valid_relationships = relationship_attributes
187
+ (h["attributes"].keys & valid_relationships).each do |attr|
188
+ h["attributes"][attr] = convert_relationship_attribute(h["attributes"][attr])
189
+ end
190
+ h
191
+ end
192
+
193
+ def relationship_attributes
194
+ @relationship_attributes ||= self.class.associations.map { |a| a.is_a?(JsonApiClient::Associations::HasMany::Association) ? "#{a.attr_name}_resources" : "#{a.attr_name}_resource" }
195
+ end
196
+
197
+ def convert_relationship_attribute(data)
198
+ case data
199
+ when Array
200
+ data.map do |d|
201
+ convert_relationship_attribute(d)
202
+ end
203
+ when FlexCommerceApi::ApiBase
204
+ data.as_json_api
205
+ else
206
+ data
207
+ end
208
+ end
209
+
210
+ def raise_record_invalid
211
+ raise(::FlexCommerceApi::Error::RecordInvalid.new(self))
212
+ end
213
+
214
+ # This is temporary code - eventually this will be in the lower level gem
215
+ def has_many_association_proxy(assoc_name, real_instance, options = {})
216
+ JsonApiClientExtension::HasManyAssociationProxy.new(real_instance, self, assoc_name, options)
217
+ end
218
+
219
+ # Gets a relationship using its related link - but returns a builder allowing for it to be
220
+ # paginated, searched and more.
221
+ def get_related(relationship)
222
+ relationship_definitions = relationships[relationship]
223
+ association = association_for(relationship)
224
+ raise "#{relationship} is not defined in #{self.class.name}" unless association
225
+ if relationship_definitions["links"] && url = relationship_definitions["links"]["related"]
226
+ url = URI.parse(url)
227
+ site = url.clone.tap { |u|
228
+ u.path = ""
229
+ u.query = nil
230
+ u.fragment = nil
231
+ }.to_s
232
+ path = url.clone.tap { |u|
233
+ u.scheme = nil
234
+ u.host = nil
235
+ u.port = nil
236
+ u.userinfo = nil
237
+ }.to_s
238
+ connection = if site.empty?
239
+ self.class.connection
240
+ else
241
+ FlexCommerceApi::JsonApiClientExtension::FlexibleConnection.new(self.class.connection_options.merge(site: site, add_json_api_extension: false, authenticate: false))
242
+ end
243
+ FlexCommerceApi::JsonApiClientExtension::RemoteBuilder.new(association.association_class, path: path, connection: connection)
244
+ end
245
+
246
+ end
247
+
248
+
249
+ end
250
+ end
@@ -0,0 +1,55 @@
1
+ require "singleton"
2
+ module FlexCommerceApi
3
+ #
4
+ # Global configuration object
5
+ #
6
+ # This is not accessed directly but using code similar to this example :-
7
+ #
8
+ # FlexCommerceApi.config do |config|
9
+ # config.flex_root_url=ENV["FLEX_ROOT_URL"]
10
+ # config.flex_account=ENV["FLEX_ACCOUNT"]
11
+ # config.flex_api_key=ENV["FLEX_API_KEY"]
12
+ # config.logger = Rails.logger
13
+ # config.order_test_mode = ENV.key?("ORDER_TEST_MODE")
14
+ # end
15
+ #
16
+ # The above code would typically be found in a rails initializer as an example.
17
+ class Config
18
+ include Singleton
19
+ # @!attribute flex_root_url
20
+ # The root url for the flex server. Must NOT include the account name at the end
21
+ # For example https://api.flexcommerce.com
22
+ # @!attribute flex_account
23
+ # The account to be used on the flex server.
24
+ # For example myaccount
25
+ # @!attribute flex_api_key
26
+ # The API key to access the flex server with. This comes from the 'Access Keys'
27
+ # section of the admin panel
28
+ # @!attribute order_test_mode
29
+ # The order test mode.This config determines if orders are processed as test or real orders
30
+ attr_accessor :flex_root_url, :flex_api_key, :flex_account, :logger, :adapter, :order_test_mode, :http_cache, :open_timeout, :timeout, :paypal_login, :paypal_password, :paypal_signature, :order_test_mode, :paypal_connection_errors_no_of_retries
31
+ attr_reader :api_version
32
+
33
+ def initialize
34
+ self.order_test_mode = false
35
+ self.http_cache = {}
36
+ self.open_timeout = ENV.fetch('SHIFT_OPEN_TIMEOUT', 2).to_i
37
+ self.timeout = ENV.fetch('SHIFT_TIMEOUT', 15).to_i
38
+ end
39
+
40
+ # The api base URL
41
+ # @return [String] The base URL for the flex system. Calculated from the
42
+ # flex_root_url and _api_verision
43
+ def api_base_url
44
+ "#{flex_root_url}/#{flex_account}"
45
+ end
46
+
47
+ # Informs all models that the configuration may have changed
48
+ # but only if ApiBase is defined - else nothing has loaded yet
49
+ # so they wont need reconfiguring
50
+ def reconfigure_all!
51
+ FlexCommerceApi::BaseResource.reconfigure_all if FlexCommerceApi.const_defined? "ApiBase"
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,6 @@
1
+ module FlexCommerceApi
2
+ module Error
3
+ class AccessDenied < ClientError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module FlexCommerceApi
2
+ module Error
3
+ class BadRequest < ClientError
4
+ def message
5
+ msg = response_env[:body]["errors"].map {|e| "#{e['title']} - #{e['detail']}"}.join(" , ")
6
+ "Bad Request #{msg}"
7
+ end
8
+ end
9
+ end
10
+ end