flex_commerce_api 0.6.57
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.env.example +6 -0
- data/.gitignore +14 -0
- data/.rspec +4 -0
- data/.rubocop.yml +1065 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +56 -0
- data/Rakefile +1 -0
- data/app/models/address.rb +41 -0
- data/app/models/asset_file.rb +26 -0
- data/app/models/asset_folder.rb +14 -0
- data/app/models/bundle.rb +20 -0
- data/app/models/bundle_group.rb +15 -0
- data/app/models/cart.rb +136 -0
- data/app/models/category.rb +70 -0
- data/app/models/category_tree.rb +11 -0
- data/app/models/component.rb +8 -0
- data/app/models/container_coupon.rb +12 -0
- data/app/models/country.rb +11 -0
- data/app/models/coupon.rb +18 -0
- data/app/models/customer_account.rb +96 -0
- data/app/models/customer_account_authentication.rb +5 -0
- data/app/models/customer_segment.rb +6 -0
- data/app/models/customer_segment_member.rb +6 -0
- data/app/models/data_attribute.rb +6 -0
- data/app/models/data_store_record.rb +9 -0
- data/app/models/data_store_type.rb +9 -0
- data/app/models/discount_summary.rb +12 -0
- data/app/models/email.rb +5 -0
- data/app/models/ewis_opt_in.rb +8 -0
- data/app/models/external_url.rb +6 -0
- data/app/models/free_shipping_promotion.rb +12 -0
- data/app/models/import.rb +6 -0
- data/app/models/import_entry.rb +6 -0
- data/app/models/line_item.rb +34 -0
- data/app/models/line_item_discount.rb +7 -0
- data/app/models/markdown_price.rb +11 -0
- data/app/models/menu.rb +36 -0
- data/app/models/menu_item.rb +7 -0
- data/app/models/menu_item_item.rb +5 -0
- data/app/models/note.rb +18 -0
- data/app/models/order.rb +38 -0
- data/app/models/password_recovery.rb +20 -0
- data/app/models/payment_address_verification.rb +13 -0
- data/app/models/payment_process.rb +13 -0
- data/app/models/payment_provider.rb +15 -0
- data/app/models/payment_transaction.rb +13 -0
- data/app/models/product.rb +99 -0
- data/app/models/product_asset_file.rb +12 -0
- data/app/models/promotion.rb +19 -0
- data/app/models/promotion_qualifying_product_exclusion.rb +8 -0
- data/app/models/redirect.rb +14 -0
- data/app/models/refund.rb +14 -0
- data/app/models/remote_address.rb +22 -0
- data/app/models/remote_line_item.rb +11 -0
- data/app/models/remote_order.rb +15 -0
- data/app/models/remote_shipping_method.rb +12 -0
- data/app/models/report.rb +18 -0
- data/app/models/report_invocation.rb +18 -0
- data/app/models/retail_store.rb +18 -0
- data/app/models/role.rb +6 -0
- data/app/models/search_suggestion.rb +17 -0
- data/app/models/section.rb +9 -0
- data/app/models/session.rb +8 -0
- data/app/models/shipping_method.rb +26 -0
- data/app/models/slug.rb +19 -0
- data/app/models/static_page.rb +60 -0
- data/app/models/static_page_folder.rb +8 -0
- data/app/models/stock_level.rb +21 -0
- data/app/models/tax_code.rb +6 -0
- data/app/models/taxonomy.rb +5 -0
- data/app/models/template.rb +9 -0
- data/app/models/template_component.rb +11 -0
- data/app/models/template_definition.rb +12 -0
- data/app/models/template_section.rb +12 -0
- data/app/models/user.rb +8 -0
- data/app/models/user_profile.rb +6 -0
- data/app/models/v2/create_order.rb +10 -0
- data/app/models/v2/deallocate_order.rb +10 -0
- data/app/models/v2/line_item.rb +9 -0
- data/app/models/v2/order.rb +9 -0
- data/app/models/v2/unallocate_order.rb +10 -0
- data/app/models/variant.rb +18 -0
- data/app/models/webhook.rb +17 -0
- data/app/services/param_to_shql.rb +72 -0
- data/app/services/surrogate_keys.rb +44 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config/locales/payments.en.yml +3 -0
- data/flex-commerce-api.gemspec +41 -0
- data/lib/flex_commerce.rb +95 -0
- data/lib/flex_commerce_api.rb +21 -0
- data/lib/flex_commerce_api/api_base.rb +11 -0
- data/lib/flex_commerce_api/base_resource.rb +250 -0
- data/lib/flex_commerce_api/config.rb +55 -0
- data/lib/flex_commerce_api/error/access_denied.rb +6 -0
- data/lib/flex_commerce_api/error/bad_request.rb +10 -0
- data/lib/flex_commerce_api/error/base.rb +12 -0
- data/lib/flex_commerce_api/error/client_error.rb +7 -0
- data/lib/flex_commerce_api/error/connection_error.rb +6 -0
- data/lib/flex_commerce_api/error/internal_server.rb +37 -0
- data/lib/flex_commerce_api/error/not_found.rb +13 -0
- data/lib/flex_commerce_api/error/record_invalid.rb +16 -0
- data/lib/flex_commerce_api/error/unexpected_status.rb +7 -0
- data/lib/flex_commerce_api/errors.rb +13 -0
- data/lib/flex_commerce_api/json_api_client_extension/builder.rb +28 -0
- data/lib/flex_commerce_api/json_api_client_extension/capture_surrogate_keys_middleware.rb +16 -0
- data/lib/flex_commerce_api/json_api_client_extension/flexible_connection.rb +59 -0
- data/lib/flex_commerce_api/json_api_client_extension/has_many_association_proxy.rb +60 -0
- data/lib/flex_commerce_api/json_api_client_extension/included_data.rb +27 -0
- data/lib/flex_commerce_api/json_api_client_extension/json_format_middleware.rb +20 -0
- data/lib/flex_commerce_api/json_api_client_extension/logging_middleware.rb +24 -0
- data/lib/flex_commerce_api/json_api_client_extension/paginator.rb +26 -0
- data/lib/flex_commerce_api/json_api_client_extension/parse_json.rb +23 -0
- data/lib/flex_commerce_api/json_api_client_extension/parsers/parser.rb +16 -0
- data/lib/flex_commerce_api/json_api_client_extension/previewed_request_middleware.rb +17 -0
- data/lib/flex_commerce_api/json_api_client_extension/remote_builder.rb +29 -0
- data/lib/flex_commerce_api/json_api_client_extension/requestor.rb +42 -0
- data/lib/flex_commerce_api/json_api_client_extension/save_request_body_middleware.rb +20 -0
- data/lib/flex_commerce_api/json_api_client_extension/status_middleware.rb +40 -0
- data/lib/flex_commerce_api/v2/api_base.rb +13 -0
- data/lib/flex_commerce_api/version.rb +3 -0
- data/lib/json_erb.rb +9 -0
- data/lib/json_struct.rb +73 -0
- data/lib/patches.rb +4 -0
- data/lib/patches/json_api_client/resource.rb +50 -0
- data/lib/paypal_express.rb +3 -0
- data/lib/paypal_express/additional_info.rb +45 -0
- data/lib/paypal_express/api.rb +86 -0
- data/lib/paypal_express/auth.rb +83 -0
- data/lib/paypal_express/cart_shipping_method.rb +38 -0
- data/lib/paypal_express/exception/access_denied.rb +10 -0
- data/lib/paypal_express/exception/connection_error.rb +10 -0
- data/lib/paypal_express/exception/not_authorized.rb +10 -0
- data/lib/paypal_express/exception/transaction.rb +15 -0
- data/lib/paypal_express/generate_summary.rb +118 -0
- data/lib/paypal_express/process/paypal_params.rb +123 -0
- data/lib/paypal_express/process/response_parser.rb +146 -0
- data/lib/paypal_express/setup.rb +94 -0
- data/lib/paypal_express/shipping_methods_for_cart.rb +46 -0
- data/lib/retry.rb +20 -0
- data/schemas/jsonapi/schema.json +370 -0
- data/schemas/shift/v1/documents/collection/address.json +45 -0
- data/schemas/shift/v1/documents/collection/asset_file.json +43 -0
- data/schemas/shift/v1/documents/collection/asset_folder.json +43 -0
- data/schemas/shift/v1/documents/collection/customer_account.json +50 -0
- data/schemas/shift/v1/documents/collection/markdown_price.json +43 -0
- data/schemas/shift/v1/documents/collection/product.json +43 -0
- data/schemas/shift/v1/documents/collection/variant.json +43 -0
- data/schemas/shift/v1/documents/member/address.json +39 -0
- data/schemas/shift/v1/documents/member/asset_file.json +37 -0
- data/schemas/shift/v1/documents/member/asset_folder.json +39 -0
- data/schemas/shift/v1/documents/member/customer_account.json +44 -0
- data/schemas/shift/v1/documents/member/markdown_price.json +37 -0
- data/schemas/shift/v1/documents/member/product.json +39 -0
- data/schemas/shift/v1/documents/member/variant.json +46 -0
- data/schemas/shift/v1/resources/address.json +130 -0
- data/schemas/shift/v1/resources/asset_file.json +146 -0
- data/schemas/shift/v1/resources/asset_folder.json +188 -0
- data/schemas/shift/v1/resources/customer_account.json +339 -0
- data/schemas/shift/v1/resources/markdown_price.json +52 -0
- data/schemas/shift/v1/resources/product.json +230 -0
- data/schemas/shift/v1/resources/variant.json +298 -0
- data/tasks/json_schema.thor +275 -0
- data/todo.md +8 -0
- 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,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
|