workarea-flow_io 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.eslintignore +2 -0
- data/.eslintrc.json +37 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +90 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +2 -0
- data/.ruby-version +1 -0
- data/.stylelintrc.json +12 -0
- data/CHANGELOG.md +200 -0
- data/Gemfile +19 -0
- data/LICENSE +52 -0
- data/README.md +200 -0
- data/Rakefile +59 -0
- data/app/assets/javascripts/workarea/storefront/flow_io/adapters/flow_io_adapter.js +61 -0
- data/app/assets/javascripts/workarea/storefront/flow_io/configuration.js.erb +10 -0
- data/app/assets/javascripts/workarea/storefront/flow_io/flow.js +91 -0
- data/app/assets/stylesheets/flow_io/storefront/country_picker.scss +189 -0
- data/app/controllers/workarea/admin/application_controller.decorator +5 -0
- data/app/controllers/workarea/admin/catalog_categories_controller.decorator +9 -0
- data/app/controllers/workarea/admin/flow_imports_controller.rb +9 -0
- data/app/controllers/workarea/admin/orders_controller.decorator +6 -0
- data/app/controllers/workarea/admin/pricing_skus_controller.decorator +7 -0
- data/app/controllers/workarea/admin/search_settings_controller.decorator +27 -0
- data/app/controllers/workarea/storefront/application_controller.decorator +80 -0
- data/app/controllers/workarea/storefront/checkouts_controller.decorator +38 -0
- data/app/controllers/workarea/storefront/flow_io_webhook_controller.rb +49 -0
- data/app/controllers/workarea/storefront/recent_views_controller.decorator +15 -0
- data/app/controllers/workarea/storefront/searches_controller.decorator +11 -0
- data/app/helpers/workarea/admin/flow_helper.rb +13 -0
- data/app/helpers/workarea/storefront/flow_analytics_helper.rb +23 -0
- data/app/helpers/workarea/storefront/flow_content_helper.rb +21 -0
- data/app/middleware/workarea/flow_io/session_middleware.rb +68 -0
- data/app/models/workarea/address.decorator +12 -0
- data/app/models/workarea/catalog/category.decorator +8 -0
- data/app/models/workarea/checkout.decorator +26 -0
- data/app/models/workarea/flow_io/experience_geo.rb +18 -0
- data/app/models/workarea/flow_io/experience_summary.rb +15 -0
- data/app/models/workarea/flow_io/import.rb +31 -0
- data/app/models/workarea/flow_io/imported_item.rb +124 -0
- data/app/models/workarea/flow_io/local_item.rb +28 -0
- data/app/models/workarea/flow_io/localized_price.rb +30 -0
- data/app/models/workarea/flow_io/price.rb +12 -0
- data/app/models/workarea/flow_io/price_with_base.rb +7 -0
- data/app/models/workarea/flow_io/webhook/shared_secret.rb +12 -0
- data/app/models/workarea/flow_price_adjustment_set.rb +80 -0
- data/app/models/workarea/fulfillment.decorator +63 -0
- data/app/models/workarea/order.decorator +39 -0
- data/app/models/workarea/order/item.decorator +43 -0
- data/app/models/workarea/payment.decorator +11 -0
- data/app/models/workarea/payment/authorize/flow_payment.rb +48 -0
- data/app/models/workarea/payment/capture/flow_payment.rb +35 -0
- data/app/models/workarea/payment/flow_payment_data.rb +25 -0
- data/app/models/workarea/payment/flow_payment_operation.rb +20 -0
- data/app/models/workarea/payment/purchase/flow_payment.rb +44 -0
- data/app/models/workarea/payment/refund/flow_payment.rb +42 -0
- data/app/models/workarea/payment/store_flow_credit_card.rb +34 -0
- data/app/models/workarea/payment/tender.decorator +8 -0
- data/app/models/workarea/payment/tender/flow_payment.rb +15 -0
- data/app/models/workarea/payment/transaction.decorator +12 -0
- data/app/models/workarea/pricing/calculators/flow_localization_calculator.rb +30 -0
- data/app/models/workarea/pricing/calculators/item_calculator.decorator +39 -0
- data/app/models/workarea/pricing/collection.decorator +113 -0
- data/app/models/workarea/pricing/order_totals.decorator +53 -0
- data/app/models/workarea/pricing/price.decorator +17 -0
- data/app/models/workarea/pricing/price_distributor.decorator +51 -0
- data/app/models/workarea/pricing/request.decorator +17 -0
- data/app/models/workarea/pricing/shipping_totals.decorator +24 -0
- data/app/models/workarea/pricing/sku.decorator +46 -0
- data/app/models/workarea/search/settings.decorator +8 -0
- data/app/models/workarea/search/storefront/product.decorator +25 -0
- data/app/models/workarea/shipping.decorator +28 -0
- data/app/queries/workarea/order_metrics.decorator +23 -0
- data/app/queries/workarea/search/product_search.decorator +14 -0
- data/app/queries/workarea/search/storefront_search/response.decorator +40 -0
- data/app/services/workarea/flow_io/checkout.rb +242 -0
- data/app/services/workarea/flow_io/checkout_token_form.rb +36 -0
- data/app/services/workarea/flow_io/countries.rb +14 -0
- data/app/services/workarea/flow_io/detailed_shipping_notification_form.rb +84 -0
- data/app/services/workarea/flow_io/experiences.rb +24 -0
- data/app/services/workarea/flow_io/fulfillment_cancellation_form.rb +40 -0
- data/app/services/workarea/flow_io/item.rb +122 -0
- data/app/services/workarea/flow_io/item_importer.rb +108 -0
- data/app/services/workarea/flow_io/line_item_form.rb +72 -0
- data/app/services/workarea/flow_io/order_put_form.rb +62 -0
- data/app/services/workarea/flow_io/price_applier.rb +81 -0
- data/app/services/workarea/flow_io/price_applier/item_applier.rb +157 -0
- data/app/services/workarea/flow_io/routing_contraints.rb +10 -0
- data/app/services/workarea/flow_io/session.rb +90 -0
- data/app/services/workarea/flow_io/webhook.rb +28 -0
- data/app/services/workarea/flow_io/webhook/experience_deleted_v2.rb +9 -0
- data/app/services/workarea/flow_io/webhook/experience_upserted_v2.rb +9 -0
- data/app/services/workarea/flow_io/webhook/order_upserted_v2.rb +36 -0
- data/app/services/workarea/flow_io/webhook_request_signature.rb +19 -0
- data/app/view_models/workarea/admin/flow_imports_view_model.rb +36 -0
- data/app/view_models/workarea/storefront/cart_view_model.decorator +27 -0
- data/app/view_models/workarea/storefront/content_blocks/category_summary_view_model.decorator +11 -0
- data/app/view_models/workarea/storefront/content_blocks/product_insights_view_model.decorator +11 -0
- data/app/view_models/workarea/storefront/content_blocks/product_list_view_model.decorator +13 -0
- data/app/view_models/workarea/storefront/order_item_view_model.decorator +35 -0
- data/app/view_models/workarea/storefront/order_view_model.decorator +51 -0
- data/app/view_models/workarea/storefront/product_templates/option_set_view_model.decorator +20 -0
- data/app/view_models/workarea/storefront/product_templates/package_view_model.decorator +14 -0
- data/app/view_models/workarea/storefront/product_view_model.decorator +15 -0
- data/app/view_models/workarea/storefront/product_view_model/cache_key.decorator +7 -0
- data/app/view_models/workarea/storefront/recommendations_view_model.decorator +20 -0
- data/app/view_models/workarea/storefront/user_activity_view_model.decorator +18 -0
- data/app/views/workarea/admin/catalog_categories/edit.html.haml +85 -0
- data/app/views/workarea/admin/facets/_price_inputs.html.haml +50 -0
- data/app/views/workarea/admin/flow_imports/index.html.haml +44 -0
- data/app/views/workarea/admin/orders/_flow.html.haml +22 -0
- data/app/views/workarea/admin/orders/_flow_aux_navigation.html.haml +2 -0
- data/app/views/workarea/admin/orders/flow.html.haml +109 -0
- data/app/views/workarea/admin/orders/tenders/_flow_payment.html.haml +3 -0
- data/app/views/workarea/admin/pricing_skus/_cards.html.haml +83 -0
- data/app/views/workarea/admin/pricing_skus/flow.html.haml +60 -0
- data/app/views/workarea/admin/search_settings/show.html.haml +55 -0
- data/app/views/workarea/admin/shared/_flow_imports_link.html.haml +1 -0
- data/app/views/workarea/storefront/_flow_io_country_picker.html.haml +2 -0
- data/app/views/workarea/storefront/_flow_io_country_picker_javascript.html.haml +1 -0
- data/app/views/workarea/storefront/order_mailer/tenders/_flow_payment.html.haml +2 -0
- data/app/views/workarea/storefront/order_mailer/tenders/_flow_payment.text.erb +1 -0
- data/app/views/workarea/storefront/orders/tenders/_flow_payment.html.haml +3 -0
- data/app/views/workarea/storefront/products/_pricing.html.haml +41 -0
- data/app/workers/workarea/flow_io/delete_items.rb +30 -0
- data/app/workers/workarea/flow_io/fetch_import.rb +34 -0
- data/app/workers/workarea/flow_io/fulfillment_cancellation.rb +14 -0
- data/app/workers/workarea/flow_io/item_exporter.rb +47 -0
- data/app/workers/workarea/flow_io/process_import.rb +28 -0
- data/app/workers/workarea/flow_io/shipping_notifications.rb +13 -0
- data/bin/rails +25 -0
- data/config/initializers/appends.rb +39 -0
- data/config/initializers/freedom_patches.rb +23 -0
- data/config/initializers/middleware.rb +11 -0
- data/config/initializers/payment_proxy.rb +5 -0
- data/config/initializers/rack_attack.rb +15 -0
- data/config/initializers/scheduled_jobs.rb +9 -0
- data/config/initializers/workarea.rb +101 -0
- data/config/initializers/workarea_i18n.rb +11 -0
- data/config/locales/en.yml +72 -0
- data/config/routes.rb +21 -0
- data/lib/active_merchant/billing/bogus_flow_gateway.rb +16 -0
- data/lib/active_merchant/billing/flow_gateway.rb +48 -0
- data/lib/tasks/flow_io.rake +117 -0
- data/lib/workarea/flow_io.rb +73 -0
- data/lib/workarea/flow_io/bogus_client.rb +57 -0
- data/lib/workarea/flow_io/bogus_client/checkout_tokens.rb +25 -0
- data/lib/workarea/flow_io/bogus_client/experiences.rb +152 -0
- data/lib/workarea/flow_io/bogus_client/fulfillments.rb +9 -0
- data/lib/workarea/flow_io/bogus_client/items.rb +11 -0
- data/lib/workarea/flow_io/bogus_client/orders.rb +499 -0
- data/lib/workarea/flow_io/bogus_client/organizations.rb +42 -0
- data/lib/workarea/flow_io/bogus_client/proxy_client.rb +29 -0
- data/lib/workarea/flow_io/bogus_client/sessions.rb +115 -0
- data/lib/workarea/flow_io/bogus_client/shipping_notifications.rb +10 -0
- data/lib/workarea/flow_io/bogus_client/webhook_settings.rb +11 -0
- data/lib/workarea/flow_io/bogus_client/webhooks.rb +11 -0
- data/lib/workarea/flow_io/controller_log_subscriber.rb +21 -0
- data/lib/workarea/flow_io/engine.rb +8 -0
- data/lib/workarea/flow_io/http_handler.rb +27 -0
- data/lib/workarea/flow_io/version.rb +5 -0
- data/lib/workarea/freedom_patches/flow_io.rb +53 -0
- data/package.json +9 -0
- data/script/admin_ci +9 -0
- data/script/ci +11 -0
- data/script/core_ci +9 -0
- data/script/plugins_ci +9 -0
- data/script/storefront_ci +9 -0
- data/test/dummy/.ruby-version +1 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +28 -0
- data/test/dummy/bin/update +28 -0
- data/test/dummy/bin/yarn +11 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +32 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +52 -0
- data/test/dummy/config/environments/production.rb +88 -0
- data/test/dummy/config/environments/test.rb +45 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +14 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/content_security_policy.rb +25 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +34 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/package.json +5 -0
- data/test/factories/workarea/flow_io.rb +136 -0
- data/test/factories/workarea/flow_io/euro_order_upserted_payload.rb +581 -0
- data/test/fixtures/files/example.csv +14 -0
- data/test/integration/workarea/admin/flow_imports_integration_test.rb +20 -0
- data/test/integration/workarea/admin/flow_order_integration_test.rb +37 -0
- data/test/integration/workarea/admin/search_settings_integration_test.decorator +44 -0
- data/test/integration/workarea/flow_locale_integration_test.rb +34 -0
- data/test/integration/workarea/storefront/copying_guest_order_integration_test.decorator +113 -0
- data/test/integration/workarea/storefront/flow_io_order_redirect_test.rb +55 -0
- data/test/integration/workarea/storefront/flow_io_session_integration_test.rb +122 -0
- data/test/integration/workarea/storefront/flow_io_webhooks/order_integration_test.rb +750 -0
- data/test/integration/workarea/storefront/flow_webhook_rack_attack_integration_test.rb +54 -0
- data/test/integration/workarea/storefront/search_integration_test.decorator +51 -0
- data/test/javascripts/flow_spec.js +39 -0
- data/test/javascripts/spec_helper.js +3 -0
- data/test/models/workarea/address_test.decorator +20 -0
- data/test/models/workarea/checkout_test.decorator +20 -0
- data/test/models/workarea/flow_io/imported_item_test.rb +50 -0
- data/test/models/workarea/fulfillment_test.decorator +12 -0
- data/test/models/workarea/oms_fulfillment_test.decorator +14 -0
- data/test/models/workarea/order/item_test.decorator +46 -0
- data/test/models/workarea/order_test.decorator +16 -0
- data/test/models/workarea/payment/flow_payment_integration_test.rb +163 -0
- data/test/models/workarea/price_adjustment_set_flow_test.rb +8 -0
- data/test/models/workarea/pricing/calculators/flow_localization_calculator_test.rb +152 -0
- data/test/models/workarea/pricing/calculators/item_calculator_test.decorator +59 -0
- data/test/models/workarea/pricing/collection_test.decorator +140 -0
- data/test/models/workarea/pricing/order_totals_test.rb +247 -0
- data/test/models/workarea/pricing/price_distributor_test.decorator +21 -0
- data/test/models/workarea/pricing/sku_test.decorator +113 -0
- data/test/models/workarea/shipping_test.decorator +70 -0
- data/test/queries/workarea/flow_order_metrics_test.rb +104 -0
- data/test/services/workarea/commit_shipments_test.decorator +14 -0
- data/test/services/workarea/flow_io/checkout_test.rb +43 -0
- data/test/services/workarea/flow_io/detailed_shipping_notification_form_test.rb +145 -0
- data/test/services/workarea/flow_io/experiences_test.rb +14 -0
- data/test/services/workarea/flow_io/fulfillment_cancellation_form_test.rb +46 -0
- data/test/services/workarea/flow_io/item_importer_test.rb +357 -0
- data/test/services/workarea/flow_io/item_test.rb +72 -0
- data/test/services/workarea/flow_io/line_item_form_test.rb +34 -0
- data/test/services/workarea/flow_io/order_put_form_test.rb +48 -0
- data/test/services/workarea/flow_io/price_applier_test.rb +916 -0
- data/test/support/flow_fixtures.rb +1362 -0
- data/test/support/webhook_integration_test.rb +43 -0
- data/test/support/workarea/flow_bogus_client_support.rb +18 -0
- data/test/support/workarea/flow_io_vcr_config.rb +22 -0
- data/test/system/workarea/admin/search_fulfillment_system_test.decorator +25 -0
- data/test/system/workarea/storefront/analytics_system_test.decorator +28 -0
- data/test/system/workarea/storefront/flow_cart_recommendations_system_test.rb +70 -0
- data/test/system/workarea/storefront/users_flow_orders_system_test.rb +25 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +27 -0
- data/test/vcr_cassettes/payment/flow/auth_capture.yml +188 -0
- data/test/vcr_cassettes/payment/flow/auth_capture_refund.yml +249 -0
- data/test/vcr_cassettes/payment/flow/auth_void.yml +188 -0
- data/test/vcr_cassettes/payment/flow/purchase_refund.yml +249 -0
- data/test/vcr_cassettes/payment/flow/store_auth.yml +127 -0
- data/test/vcr_cassettes/payment/flow/store_purchase.yml +188 -0
- data/test/view_models/workarea/storefront/cart_view_model_test.decorator +19 -0
- data/test/view_models/workarea/storefront/order_item_view_model_test.decorator +24 -0
- data/test/view_models/workarea/storefront/order_view_model_test.decorator +41 -0
- data/test/view_models/workarea/storefront/package_view_model_test.decorator +11 -0
- data/test/workers/workarea/flow_io/delete_items_test.rb +37 -0
- data/test/workers/workarea/flow_io/fetch_import_test.rb +41 -0
- data/test/workers/workarea/flow_io/item_exporter_test.rb +47 -0
- data/test/workers/workarea/flow_io/process_import_test.rb +25 -0
- data/workarea-flow_io.gemspec +20 -0
- metadata +375 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class CheckoutTokenForm
|
4
|
+
def self.from(order:, session_id:)
|
5
|
+
new(order: order, session_id: session_id).to_flow_model
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :order, :session_id
|
9
|
+
|
10
|
+
def initialize(order:, session_id:)
|
11
|
+
@order = order
|
12
|
+
@session_id = session_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_flow_model
|
16
|
+
::Io::Flow::V0::Models::CheckoutTokenReferenceForm.new(attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes
|
20
|
+
{
|
21
|
+
order_number: order.id,
|
22
|
+
session_id: session_id,
|
23
|
+
urls: {
|
24
|
+
continue_shopping: continue_shopping_url
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def continue_shopping_url
|
32
|
+
"https://#{Workarea.config.host}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class Countries
|
4
|
+
def self.all
|
5
|
+
# @return [Io::Flow::V0::Models::Country]
|
6
|
+
Rails.cache.fetch('flow-countries', expires_in: Workarea.config.cache_expirations.flow_io_country_cache) do
|
7
|
+
FlowIo.client
|
8
|
+
.organizations
|
9
|
+
.get_countries_by_organization(Workarea::FlowIo.organization_id)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class DetailedShippingNotificationForm
|
4
|
+
attr_reader :id, :fulfillment
|
5
|
+
|
6
|
+
def self.from(id:, tracking_number:)
|
7
|
+
order = Workarea::Order.find id
|
8
|
+
shipping = Workarea::Shipping.find_by_order id
|
9
|
+
fulfillment = Workarea::Fulfillment.find id
|
10
|
+
|
11
|
+
new(order: order, shipping: shipping, fulfillment: fulfillment, tracking_number: tracking_number).to_flow_model
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :order, :shipping, :fulfillment, :tracking_number
|
15
|
+
|
16
|
+
def initialize(order:, shipping:, fulfillment:, tracking_number:)
|
17
|
+
@order = order
|
18
|
+
@shipping = shipping
|
19
|
+
@fulfillment = fulfillment
|
20
|
+
@tracking_number = tracking_number
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return ::Io::Flow::V0::Models::DetailedShippingNotificationForm
|
24
|
+
def to_flow_model
|
25
|
+
::Io::Flow::V0::Models::DetailedShippingNotificationForm.new(
|
26
|
+
attributes: { number: order.id },
|
27
|
+
carrier_tracking_number: tracking_number,
|
28
|
+
destination: {
|
29
|
+
contact: {
|
30
|
+
name: {
|
31
|
+
first: shipping_address.first_name,
|
32
|
+
last: shipping_address.last_name
|
33
|
+
},
|
34
|
+
phone: shipping_address.phone_number
|
35
|
+
},
|
36
|
+
location: {
|
37
|
+
streets: [shipping_address.street, shipping_address.street_2].compact,
|
38
|
+
city: shipping_address.city,
|
39
|
+
province: shipping_address.region,
|
40
|
+
postal: shipping_address.postal_code,
|
41
|
+
country: shipping_address.country.alpha3
|
42
|
+
}
|
43
|
+
},
|
44
|
+
order_number: order.id,
|
45
|
+
package: package,
|
46
|
+
service: shipping.shipping_service.service_code
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def shipping_address
|
53
|
+
shipping&.address
|
54
|
+
end
|
55
|
+
|
56
|
+
def workarea_package
|
57
|
+
@workarea_package ||= Storefront::PackageViewModel.wrap(
|
58
|
+
fulfillment.find_package(tracking_number),
|
59
|
+
order: order
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
def discounts
|
64
|
+
@discounts ||= Pricing::Discount
|
65
|
+
.where(:_id.in => order.discount_ids)
|
66
|
+
.to_a
|
67
|
+
end
|
68
|
+
|
69
|
+
# TODO - IMPROVEMENT if using workarea-oms send package information
|
70
|
+
#
|
71
|
+
def package
|
72
|
+
{
|
73
|
+
dimensions: {},
|
74
|
+
items: workarea_package.items.map do |fulfillment_item_view_model|
|
75
|
+
FlowIo::LineItemForm.from(
|
76
|
+
order_item: fulfillment_item_view_model,
|
77
|
+
discounts: discounts
|
78
|
+
)
|
79
|
+
end
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class Experiences
|
4
|
+
def self.all
|
5
|
+
# @return [::Io::Flow::V0::Models::Experience]
|
6
|
+
Rails.cache.fetch("flow-expereinces-#{FlowIo.organization_id}", expires_in: 1.hour) do
|
7
|
+
FlowIo.client.experiences.get(FlowIo.organization_id).select do |experience|
|
8
|
+
experience.status.value == "active"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.refresh_cache
|
14
|
+
Rails.cache.delete("flow-expereinces-#{FlowIo.organization_id}")
|
15
|
+
Experiences.all
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String]
|
19
|
+
def self.all_currencies
|
20
|
+
Experiences.all.map(&:currency).uniq
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class FulfillmentCancellationForm
|
4
|
+
def self.from(id:, quantities:)
|
5
|
+
order = Workarea::Order.find id
|
6
|
+
|
7
|
+
new(order: order, quantities: quantities).to_flow_model
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :order, :quantities
|
11
|
+
|
12
|
+
def initialize(order:, quantities:)
|
13
|
+
@order = order
|
14
|
+
@quantities = quantities
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return ::Io::Flow::V0::Models::FulfillmentCancellationForm
|
18
|
+
def to_flow_model
|
19
|
+
::Io::Flow::V0::Models::FulfillmentCancellationForm.new(
|
20
|
+
reason: "consumer_requested",
|
21
|
+
lines: lines
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def lines
|
28
|
+
@lines ||= quantities.map do |order_item_id, quantity|
|
29
|
+
order_item = order.items.detect { |item| item.id.to_s == order_item_id.to_s }
|
30
|
+
next unless order_item.present?
|
31
|
+
|
32
|
+
{
|
33
|
+
item_number: order_item.sku,
|
34
|
+
quantity: quantity.to_i
|
35
|
+
}
|
36
|
+
end.compact
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class Item
|
4
|
+
include ActionView::Helpers::AssetUrlHelper
|
5
|
+
include Core::Engine.routes.url_helpers
|
6
|
+
include Workarea::ApplicationHelper
|
7
|
+
|
8
|
+
attr_reader :product, :sku
|
9
|
+
delegate :name, :description, to: :product
|
10
|
+
|
11
|
+
def initialize(product, sku)
|
12
|
+
@product = product
|
13
|
+
@sku = sku
|
14
|
+
end
|
15
|
+
|
16
|
+
def form
|
17
|
+
::Io::Flow::V0::Models::ItemForm.new(self.to_h)
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_h
|
21
|
+
{
|
22
|
+
number: sku,
|
23
|
+
locale: FlowIo.config.original_locale,
|
24
|
+
name: name,
|
25
|
+
currency: pricing_sku.sell_price.currency.iso_code,
|
26
|
+
price: price,
|
27
|
+
categories: categories,
|
28
|
+
attributes: attributes,
|
29
|
+
dimensions: dimensions,
|
30
|
+
images: images
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def variant
|
37
|
+
@variant ||= product.variants.find_by(sku: sku)
|
38
|
+
end
|
39
|
+
|
40
|
+
def shipping_sku
|
41
|
+
@shipping_sku ||= Shipping::Sku.find(sku) rescue nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def pricing_sku
|
45
|
+
@pricing_sku ||= Pricing::Sku.find(sku) rescue Pricing::Sku.new(id: sku)
|
46
|
+
end
|
47
|
+
|
48
|
+
def price
|
49
|
+
pricing_sku.sell_price.dollars.to_f
|
50
|
+
end
|
51
|
+
|
52
|
+
def categories
|
53
|
+
@categories ||= Categorization.new(product).to_models.map(&:name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def attributes
|
57
|
+
variant_attributes.merge(
|
58
|
+
"product_id" => product.id,
|
59
|
+
"msrp" => pricing_sku.msrp&.dollars&.to_f,
|
60
|
+
"regular_price" => sku_price.regular.dollars.to_f,
|
61
|
+
"sale_price" => sku_price.sale&.dollars&.to_f,
|
62
|
+
"fulfillment_method" => product.digital ? "digital" : "physical"
|
63
|
+
).compact.map { |k, v| [k, v.to_s] }.to_h
|
64
|
+
end
|
65
|
+
|
66
|
+
def dimensions
|
67
|
+
return unless shipping_sku.present?
|
68
|
+
|
69
|
+
spatial_dimensions =
|
70
|
+
if shipping_sku.dimensions.present?
|
71
|
+
{
|
72
|
+
depth: { value: shipping_sku.height, units: shipping_sku.length_units },
|
73
|
+
length: { value: shipping_sku.length, units: shipping_sku.length_units },
|
74
|
+
width: { value: shipping_sku.width, units: shipping_sku.length_units },
|
75
|
+
}
|
76
|
+
else
|
77
|
+
{}
|
78
|
+
end
|
79
|
+
|
80
|
+
weight =
|
81
|
+
if shipping_sku.weight.present?
|
82
|
+
{ weight: { value: shipping_sku.weight, units: shipping_sku.weight_units } }
|
83
|
+
else
|
84
|
+
{}
|
85
|
+
end
|
86
|
+
|
87
|
+
{ packing: spatial_dimensions.merge(weight) }
|
88
|
+
end
|
89
|
+
|
90
|
+
def variant_specific_images
|
91
|
+
@variant_specific_images ||=
|
92
|
+
begin
|
93
|
+
sku_options = variant.details.values.flat_map { |options| options.map(&:optionize) }
|
94
|
+
|
95
|
+
product.images.select do |image|
|
96
|
+
sku_options.include?(image.option.optionize)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def images
|
102
|
+
@images ||= (variant_specific_images || [product.images.first]).flat_map do |image|
|
103
|
+
FlowIo.image_sizes.map do |processor, tags|
|
104
|
+
{ url: product_image_url(image, processor), tags: tags }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def sku_price
|
110
|
+
@sku_price ||= pricing_sku.find_price(quantity: 1)
|
111
|
+
end
|
112
|
+
|
113
|
+
def variant_attributes
|
114
|
+
variant.details.map { |k, v| [k, v.join(', ')] }.to_h
|
115
|
+
end
|
116
|
+
|
117
|
+
def mounted_core
|
118
|
+
self
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class ItemImporter
|
4
|
+
def self.perform!(item)
|
5
|
+
new(item).perform!
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :item
|
9
|
+
|
10
|
+
def initialize(item)
|
11
|
+
@item = item
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform!
|
15
|
+
if local_item.present?
|
16
|
+
local_item.update_attributes local_item_attributes
|
17
|
+
else
|
18
|
+
pricing_sku.flow_io_local_items.create!(local_item_attributes)
|
19
|
+
end
|
20
|
+
Sidekiq::Callbacks.disable(Workarea::FlowIo::ItemExporter) do
|
21
|
+
pricing_sku.save
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
delegate :local, to: :item
|
27
|
+
delegate :experience, to: :local
|
28
|
+
|
29
|
+
def sku
|
30
|
+
item.number
|
31
|
+
end
|
32
|
+
|
33
|
+
def pricing_sku
|
34
|
+
@pricing_sku ||= Pricing::Sku.find sku
|
35
|
+
end
|
36
|
+
|
37
|
+
def local_item
|
38
|
+
@local_item ||= pricing_sku
|
39
|
+
.flow_io_local_items
|
40
|
+
.detect { |li| li.experience.key == experience.key }
|
41
|
+
end
|
42
|
+
|
43
|
+
def pricing_attributes
|
44
|
+
@pricing_attributes || local.price_attributes.symbolize_keys
|
45
|
+
end
|
46
|
+
|
47
|
+
def msrp_attributes
|
48
|
+
@msrp_attributes ||= pricing_attributes[:msrp]
|
49
|
+
end
|
50
|
+
|
51
|
+
def msrp
|
52
|
+
return {} unless msrp_attributes.present?
|
53
|
+
|
54
|
+
{
|
55
|
+
msrp: {
|
56
|
+
price: msrp_attributes.to_m,
|
57
|
+
label: msrp_attributes.label,
|
58
|
+
base_currency: { price: msrp_attributes.base.to_m, label: msrp_attributes.base.label }
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def local_item_attributes
|
64
|
+
{
|
65
|
+
experience: {
|
66
|
+
id: experience.id,
|
67
|
+
key: experience.key,
|
68
|
+
name: experience.name,
|
69
|
+
country: Country.find_country_by_alpha3(experience.country),
|
70
|
+
currency: experience.currency,
|
71
|
+
language: experience.language
|
72
|
+
},
|
73
|
+
prices: prices
|
74
|
+
}.merge(msrp)
|
75
|
+
end
|
76
|
+
|
77
|
+
def prices
|
78
|
+
regular = pricing_attributes[:regular_price]
|
79
|
+
sale = pricing_attributes[:sale_price]
|
80
|
+
|
81
|
+
price = {
|
82
|
+
min_quantity: 1,
|
83
|
+
regular: {
|
84
|
+
price: regular.to_m,
|
85
|
+
label: regular.label,
|
86
|
+
base_currency: {
|
87
|
+
price: regular.base.to_m,
|
88
|
+
label: regular.base.label
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
if sale.present?
|
94
|
+
price[:sale] = {
|
95
|
+
price: sale.to_m,
|
96
|
+
label: sale.label,
|
97
|
+
base_currency: {
|
98
|
+
price: sale.base.to_m,
|
99
|
+
label: sale.base.label
|
100
|
+
}
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
[price]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Workarea
|
2
|
+
module FlowIo
|
3
|
+
class LineItemForm
|
4
|
+
def self.from(order_item:, discounts:)
|
5
|
+
new(order_item: order_item, discounts: discounts).to_flow_model
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :order_item, :discounts
|
9
|
+
|
10
|
+
def initialize(order_item:, discounts:)
|
11
|
+
@order_item = order_item
|
12
|
+
@discounts = discounts
|
13
|
+
end
|
14
|
+
|
15
|
+
def price
|
16
|
+
::Io::Flow::V0::Models::Money.new(
|
17
|
+
amount: base_item_price.cents,
|
18
|
+
currency: base_item_price.currency.to_s
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_h
|
23
|
+
{
|
24
|
+
number: order_item.sku,
|
25
|
+
quantity: order_item.quantity,
|
26
|
+
price: price,
|
27
|
+
discounts: discounts_form
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_flow_model
|
32
|
+
::Io::Flow::V0::Models::LineItemForm.new(to_h)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Discount price adjustments for the order_item
|
38
|
+
#
|
39
|
+
# @return [Array<Workarea::PriceAdjustment>]
|
40
|
+
#
|
41
|
+
def discount_price_adjustments
|
42
|
+
order_item.price_adjustments.discounts
|
43
|
+
end
|
44
|
+
|
45
|
+
def base_item_price
|
46
|
+
order_item
|
47
|
+
.flow_price_adjustments
|
48
|
+
.adjusting('item')
|
49
|
+
.reject(&:discount?)
|
50
|
+
.sum
|
51
|
+
end
|
52
|
+
|
53
|
+
def discounts_form
|
54
|
+
::Io::Flow::V0::Models::DiscountsForm.new(
|
55
|
+
discounts: discount_price_adjustments.map do |discount_price_adjustment|
|
56
|
+
{
|
57
|
+
offer: {
|
58
|
+
money: {
|
59
|
+
amount: discount_price_adjustment.amount.abs.to_f,
|
60
|
+
currency: discount_price_adjustment.amount.currency.iso_code
|
61
|
+
},
|
62
|
+
discriminator: ::Io::Flow::V0::Models::DiscountOffer::Types::DISCOUNT_OFFER_FIXED
|
63
|
+
},
|
64
|
+
target: "item",
|
65
|
+
label: discount_price_adjustment.description
|
66
|
+
}
|
67
|
+
end
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|