workarea 3.4.16 → 3.4.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +81 -0
- metadata +10 -579
- data/docs/Gemfile +0 -8
- data/docs/Gemfile.lock +0 -130
- data/docs/bin/middleman +0 -29
- data/docs/config.rb +0 -87
- data/docs/config.ru +0 -7
- data/docs/data/articles.yml +0 -157
- data/docs/package.json +0 -15
- data/docs/source/404.html.erb +0 -13
- data/docs/source/articles/access-routes-in-javascript.html.md +0 -33
- data/docs/source/articles/add-a-content-area.html.md +0 -169
- data/docs/source/articles/add-a-content-block-type.html.md +0 -334
- data/docs/source/articles/add-a-report.html.md +0 -202
- data/docs/source/articles/add-css-through-the-admin-ui.html.md +0 -30
- data/docs/source/articles/add-javascript-through-a-manifest.html.md +0 -367
- data/docs/source/articles/add-javascript-through-a-view.html.md +0 -80
- data/docs/source/articles/add-javascript-through-the-admin-ui.html.md +0 -30
- data/docs/source/articles/add-metrics.html.md +0 -58
- data/docs/source/articles/add-or-replace-a-pricing-calculator.html.md +0 -150
- data/docs/source/articles/add-remove-or-change-a-mongoid-validation.html.md +0 -147
- data/docs/source/articles/add-remove-or-change-a-product-template.html.md +0 -142
- data/docs/source/articles/add-remove-sort-and-group-storefront-search-filters.html.md +0 -483
- data/docs/source/articles/add-stylesheets-through-a-manifest.html.md +0 -276
- data/docs/source/articles/add-system-content.html.md +0 -138
- data/docs/source/articles/analytics-overview.html.md +0 -51
- data/docs/source/articles/analyze-storefront-search-results.html.md +0 -261
- data/docs/source/articles/api-overview.html.md +0 -35
- data/docs/source/articles/appending.html.md +0 -506
- data/docs/source/articles/application-document.html.md +0 -88
- data/docs/source/articles/automated-javascript-testing.html.md +0 -162
- data/docs/source/articles/b2b-overview.html.md +0 -64
- data/docs/source/articles/browser-and-device-support.html.md +0 -47
- data/docs/source/articles/change-product-placeholder-image.html.md +0 -39
- data/docs/source/articles/change-storefront-search-results.html.md +0 -283
- data/docs/source/articles/change-the-storefront-product-pricing-ui.html.md +0 -348
- data/docs/source/articles/change-the-storefront-search-filters-ui.html.md +0 -103
- data/docs/source/articles/checkout.html.md +0 -479
- data/docs/source/articles/commerce-model.html.md +0 -164
- data/docs/source/articles/configuration-for-hosting.html.md +0 -106
- data/docs/source/articles/configuration.html.md +0 -406
- data/docs/source/articles/configure-a-payment-gateway.html.md +0 -58
- data/docs/source/articles/configure-asset-storage.html.md +0 -29
- data/docs/source/articles/configure-asset-types.html.md +0 -18
- data/docs/source/articles/configure-contact-form-subjects-list.html.md +0 -24
- data/docs/source/articles/configure-imageoptim.html.md +0 -23
- data/docs/source/articles/configure-locales.html.md +0 -45
- data/docs/source/articles/configure-logins-and-authentication.html.md +0 -42
- data/docs/source/articles/configure-low-inventory-threshold.html.md +0 -26
- data/docs/source/articles/configure-product-image-sizes-and-processing.html.md +0 -28
- data/docs/source/articles/content.html.md +0 -554
- data/docs/source/articles/contentable.html.md +0 -41
- data/docs/source/articles/contribute-code.html.md +0 -69
- data/docs/source/articles/contribute-documentation.html.md +0 -60
- data/docs/source/articles/create-a-custom-discount.html.md +0 -234
- data/docs/source/articles/create-a-new-app.html.md +0 -131
- data/docs/source/articles/create-a-plugin.html.md +0 -19
- data/docs/source/articles/create-a-style-guide.html.md +0 -71
- data/docs/source/articles/create-a-theme.html.md +0 -134
- data/docs/source/articles/css-architectural-overview.html.md +0 -89
- data/docs/source/articles/customize-a-helper.html.md +0 -91
- data/docs/source/articles/decoration.html.md +0 -415
- data/docs/source/articles/define-and-configure-inventory-policies.html.md +0 -107
- data/docs/source/articles/documentation-style-guide.html.md +0 -48
- data/docs/source/articles/documentation.html.md +0 -54
- data/docs/source/articles/domain-modeling.html.md +0 -82
- data/docs/source/articles/error-pages.html.md.erb +0 -95
- data/docs/source/articles/extension-overview.html.md +0 -152
- data/docs/source/articles/favicon-support.html.md +0 -112
- data/docs/source/articles/feature-spec-helper-stylesheet.html.md +0 -25
- data/docs/source/articles/featurejs-and-feature-spec-helper.html.md +0 -20
- data/docs/source/articles/help-and-support.html.md +0 -34
- data/docs/source/articles/html-fragment-caching.html.md +0 -46
- data/docs/source/articles/http-caching.html.md +0 -43
- data/docs/source/articles/i18n.html.md +0 -35
- data/docs/source/articles/images-flow.html.md +0 -10
- data/docs/source/articles/index-storefront-search-documents.html.md +0 -104
- data/docs/source/articles/infrastructure.html.md +0 -46
- data/docs/source/articles/installing.html.md +0 -61
- data/docs/source/articles/integrate-a-payment-gateway.html.md +0 -124
- data/docs/source/articles/integrate-a-web-analytics-provider.html.md +0 -35
- data/docs/source/articles/integrate-an-inventory-management-system.html.md +0 -88
- data/docs/source/articles/integrating-with-other-software.html.md +0 -59
- data/docs/source/articles/inventory.html.md +0 -352
- data/docs/source/articles/javascript-coding-standards.html.md +0 -30
- data/docs/source/articles/javascript-modules.html.md +0 -174
- data/docs/source/articles/javascript-overview.html.md +0 -62
- data/docs/source/articles/javascript-reference-documentation.html.md +0 -51
- data/docs/source/articles/javascript-templates.html.md +0 -52
- data/docs/source/articles/low-level-caching.html.md +0 -25
- data/docs/source/articles/maintain-a-plugin.html.md +0 -12
- data/docs/source/articles/maintenance-policy.html.md +0 -79
- data/docs/source/articles/navigable.html.md +0 -51
- data/docs/source/articles/navigating-the-code.html.md +0 -149
- data/docs/source/articles/navigation.html.md +0 -386
- data/docs/source/articles/order-life-cycle.html.md +0 -546
- data/docs/source/articles/order-pricing.html.md +0 -389
- data/docs/source/articles/orders-and-items.html.md +0 -210
- data/docs/source/articles/orders.html.md +0 -66
- data/docs/source/articles/overriding.html.md +0 -155
- data/docs/source/articles/overview.html.md +0 -43
- data/docs/source/articles/plugins-overview.html.md +0 -12
- data/docs/source/articles/prerequisites-and-dependencies.html.md +0 -202
- data/docs/source/articles/products.html.md.erb +0 -1270
- data/docs/source/articles/progressive-web-application-support.html.md +0 -148
- data/docs/source/articles/rails-asset-manifests.html.md +0 -33
- data/docs/source/articles/rails-asset-view-helpers.html.md +0 -25
- data/docs/source/articles/reading-data.html.md +0 -10
- data/docs/source/articles/releasable.html.md +0 -37
- data/docs/source/articles/report-a-bug.html.md +0 -75
- data/docs/source/articles/ruby-coding-standards.html.md +0 -10
- data/docs/source/articles/run-sidekiq-in-a-local-environment.html.md +0 -40
- data/docs/source/articles/searching.html.md +0 -1005
- data/docs/source/articles/security-policy.html.md +0 -42
- data/docs/source/articles/seeds.html.md +0 -345
- data/docs/source/articles/shipping.html.md +0 -756
- data/docs/source/articles/sort-and-exclude-product-options.html.md +0 -47
- data/docs/source/articles/storefront-search-features.html.md +0 -568
- data/docs/source/articles/storefront-searches.html.md +0 -126
- data/docs/source/articles/style-guides.html.md +0 -21
- data/docs/source/articles/stylesheet-coding-standards.html.md +0 -24
- data/docs/source/articles/stylesheets-overview.html.md +0 -67
- data/docs/source/articles/swappable-list-data-structure.html.md +0 -81
- data/docs/source/articles/system-emails.html.md +0 -102
- data/docs/source/articles/taggable.html.md +0 -8
- data/docs/source/articles/test-a-credit-card-transaction.html.md +0 -16
- data/docs/source/articles/test-if-a-plugin-is-installed.html.md +0 -34
- data/docs/source/articles/testing.html.md +0 -914
- data/docs/source/articles/themes-overview.html.md +0 -155
- data/docs/source/articles/translate-administrable-content.html.md +0 -14
- data/docs/source/articles/translate-javascript-content.html.md +0 -16
- data/docs/source/articles/translate-or-customize-message-content.html.md +0 -29
- data/docs/source/articles/translate-or-customize-static-content.html.md +0 -30
- data/docs/source/articles/use-an-existing-workarea-app.html.md +0 -108
- data/docs/source/articles/view-models.html.md +0 -509
- data/docs/source/articles/views.html.md +0 -14
- data/docs/source/articles/workers.html.md +0 -613
- data/docs/source/articles/writing-data.html.md +0 -10
- data/docs/source/cli.html.md +0 -163
- data/docs/source/favicon.ico +0 -0
- data/docs/source/images/3-variants-1-option.png +0 -0
- data/docs/source/images/3-variants-3-options.png +0 -0
- data/docs/source/images/3-years-primary-image.png +0 -0
- data/docs/source/images/404-storefront-error-page.png +0 -0
- data/docs/source/images/404-system-content-admin.png +0 -0
- data/docs/source/images/404.jpg +0 -0
- data/docs/source/images/5-years-primary-image.png +0 -0
- data/docs/source/images/activity-dashboard.png +0 -0
- data/docs/source/images/activity-for-object.png +0 -0
- data/docs/source/images/activity-ui.png +0 -0
- data/docs/source/images/adding-captioned-image-block-custom-icon.png +0 -0
- data/docs/source/images/adding-captioned-image-block-default-icon.png +0 -0
- data/docs/source/images/admin-alerts-ui.png +0 -0
- data/docs/source/images/admin-category-range-filters.png +0 -0
- data/docs/source/images/admin-for-3-column-hero.png +0 -0
- data/docs/source/images/admin-help-index.png +0 -0
- data/docs/source/images/admin-help-ui.png +0 -0
- data/docs/source/images/admin-javascript.png +0 -0
- data/docs/source/images/admin-notification-for-deactivated-discount.png +0 -0
- data/docs/source/images/admin-notifications-ui.png +0 -0
- data/docs/source/images/admin-product-show-page.png +0 -0
- data/docs/source/images/admin-products-index-page.png +0 -0
- data/docs/source/images/admin-range-filters.png +0 -0
- data/docs/source/images/admin-style-guides-navigation.png +0 -0
- data/docs/source/images/after-re-seeding.png +0 -0
- data/docs/source/images/after-seeding-localhost-3000.png +0 -0
- data/docs/source/images/after-seeding.png +0 -0
- data/docs/source/images/arrow.svg +0 -1
- data/docs/source/images/arrow_white.svg +0 -1
- data/docs/source/images/aws-resource-map.png +0 -0
- data/docs/source/images/backordered-until-output-on-inventory-sku-card.png +0 -0
- data/docs/source/images/before-seeding-localhost-3000.png +0 -0
- data/docs/source/images/before-seeding.png +0 -0
- data/docs/source/images/browsing-workarea-versions-on-the-web.png +0 -0
- data/docs/source/images/bulk-asset-upload-on-assets-index-page.png +0 -0
- data/docs/source/images/bulk-asset-upload-while-editing-content.png +0 -0
- data/docs/source/images/bundle-show-workarea-core.png +0 -0
- data/docs/source/images/bundle-show-workarea.png +0 -0
- data/docs/source/images/calendar-for-backordered-until-field.png +0 -0
- data/docs/source/images/captioned-image-block-in-storefront.png +0 -0
- data/docs/source/images/captioned-image-content-block-storefront-component-style-guide.png +0 -0
- data/docs/source/images/cart-system-content-in-admin.png +0 -0
- data/docs/source/images/cart-system-content-in-storefront.png +0 -0
- data/docs/source/images/checkout-addresses-guest.png +0 -0
- data/docs/source/images/checkout-addresses-user.png +0 -0
- data/docs/source/images/checkout-confirmation.png +0 -0
- data/docs/source/images/checkout-flow-0.png +0 -0
- data/docs/source/images/checkout-flow-1.png +0 -0
- data/docs/source/images/checkout-flow-2.png +0 -0
- data/docs/source/images/checkout-flow-3.png +0 -0
- data/docs/source/images/checkout-flow-4.png +0 -0
- data/docs/source/images/checkout-payment-guest.png +0 -0
- data/docs/source/images/checkout-payment-user.png +0 -0
- data/docs/source/images/checkout-shipping.png +0 -0
- data/docs/source/images/color-picker-component-admin-style-guide.png +0 -0
- data/docs/source/images/color-picker-component-on-content-editing-screen.png +0 -0
- data/docs/source/images/commerce-model-carts-orders.png +0 -0
- data/docs/source/images/commerce-model-order-pricing.png +0 -0
- data/docs/source/images/commerce-model.png +0 -0
- data/docs/source/images/configuring-an-index-pattern-in-kibana.png +0 -0
- data/docs/source/images/content-block-presets.png +0 -0
- data/docs/source/images/content-search-customization.png +0 -0
- data/docs/source/images/country-with-region-data-in-address-form.png +0 -0
- data/docs/source/images/country-without-region-data-in-address-form.png +0 -0
- data/docs/source/images/create-content-block-preset-ui.png +0 -0
- data/docs/source/images/credit-card-icons.png +0 -0
- data/docs/source/images/css-added-through-admin.png +0 -0
- data/docs/source/images/css-admin-ui.png +0 -0
- data/docs/source/images/current-configuration-shown-in-admin-settings.png +0 -0
- data/docs/source/images/customer-impersonation-in-admin.png +0 -0
- data/docs/source/images/customer-impersonation-in-store-front.png +0 -0
- data/docs/source/images/date-filter-same-day.png +0 -0
- data/docs/source/images/developer-toolbar-in-store-front.png +0 -0
- data/docs/source/images/discounts-sorted-by-most-redeemed.png +0 -0
- data/docs/source/images/edit-help-article.png +0 -0
- data/docs/source/images/editing-content-for-search-customization.png +0 -0
- data/docs/source/images/editing-dynamic-captioned-image-block.png +0 -0
- data/docs/source/images/editing-product-fields-in-the-admin.png +0 -0
- data/docs/source/images/editing-search-system-content.png +0 -0
- data/docs/source/images/editing-static-captioned-image-block-custom-icon.png +0 -0
- data/docs/source/images/editing-static-captioned-image-block-default-icon.png +0 -0
- data/docs/source/images/external.svg +0 -1
- data/docs/source/images/favicon_16.png +0 -0
- data/docs/source/images/favicon_180.png +0 -0
- data/docs/source/images/favicon_32.png +0 -0
- data/docs/source/images/filters-all.png +0 -0
- data/docs/source/images/filters-control.png +0 -0
- data/docs/source/images/filters-custom.png +0 -0
- data/docs/source/images/filters-groups.png +0 -0
- data/docs/source/images/filters-material.png +0 -0
- data/docs/source/images/filters-omitted.png +0 -0
- data/docs/source/images/filters-pinned.png +0 -0
- data/docs/source/images/filters-range.png +0 -0
- data/docs/source/images/filters-sorted.png +0 -0
- data/docs/source/images/filters-wrapping-to-second-line-in-admin.png +0 -0
- data/docs/source/images/generic-product-template-images-no-options-selected.png +0 -0
- data/docs/source/images/generic-product-template-images-options-selected.png +0 -0
- data/docs/source/images/generic-template.png +0 -0
- data/docs/source/images/hosting.svg +0 -1
- data/docs/source/images/image-group-content-block-in-storefront.png +0 -0
- data/docs/source/images/images.svg +0 -1
- data/docs/source/images/import-export-screenshot.png +0 -0
- data/docs/source/images/invalid-display.png +0 -0
- data/docs/source/images/itcss.png +0 -0
- data/docs/source/images/kibana-dev-tools-console.png +0 -0
- data/docs/source/images/layout-content-admin-with-2-areas.png +0 -0
- data/docs/source/images/layout-content-admin-with-3-areas.png +0 -0
- data/docs/source/images/link-to-search-system-content.png +0 -0
- data/docs/source/images/logo.svg +0 -1
- data/docs/source/images/menu.svg +0 -2
- data/docs/source/images/mongo-replica-set.svg +0 -1
- data/docs/source/images/multi-column-hero-blocks.png +0 -0
- data/docs/source/images/option-selects-product-template-images-options-selected.png +0 -0
- data/docs/source/images/option-selects-template.png +0 -0
- data/docs/source/images/option-thumbnails-template.png +0 -0
- data/docs/source/images/order-item-total-price-diagram.png +0 -0
- data/docs/source/images/order-pricing-cart-example.png +0 -0
- data/docs/source/images/order-pricing-example-adjustments.png +0 -0
- data/docs/source/images/order-pricing-example-totals.png +0 -0
- data/docs/source/images/order-pricing-placed-order-example.png +0 -0
- data/docs/source/images/order-shipping-total-diagram.png +0 -0
- data/docs/source/images/order-show-with-multiple-tenders.png +0 -0
- data/docs/source/images/order-subtotal-price-diagram.png +0 -0
- data/docs/source/images/order-tax-total-diagram.png +0 -0
- data/docs/source/images/order-total-price-diagram.png +0 -0
- data/docs/source/images/order-total-value-diagram.png +0 -0
- data/docs/source/images/orders-dashboard-links.png +0 -0
- data/docs/source/images/oval.svg +0 -1
- data/docs/source/images/payment-icon-storefront-style-guide.png +0 -0
- data/docs/source/images/people-dashboard-links.png +0 -0
- data/docs/source/images/price-adjustments-diagram.png +0 -0
- data/docs/source/images/price-display-no-options.png +0 -0
- data/docs/source/images/price-display-options-selected.png +0 -0
- data/docs/source/images/pricing-calculators-diagram.png +0 -0
- data/docs/source/images/product-list-content-block-admin.png +0 -0
- data/docs/source/images/product-list-content-block-in-store-front.png +0 -0
- data/docs/source/images/promo-products-excluded-autocomplete-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-featured-category-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-recommendations-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-search-category-results-after.png +0 -0
- data/docs/source/images/promo-products-excluded-search-results-after.png +0 -0
- data/docs/source/images/promo-products-included-autocomplete-results-before.png +0 -0
- data/docs/source/images/promo-products-included-featured-category-results-before.png +0 -0
- data/docs/source/images/promo-products-included-recommendations-results-before.png +0 -0
- data/docs/source/images/promo-products-included-search-category-results-before.png +0 -0
- data/docs/source/images/promo-products-included-search-results-before.png +0 -0
- data/docs/source/images/rails-version-constraint.png +0 -0
- data/docs/source/images/re-enable-discount.png +0 -0
- data/docs/source/images/reading-data.svg +0 -1
- data/docs/source/images/readme-hero.png +0 -0
- data/docs/source/images/redesigned-customized-sort-for-search-results.png +0 -0
- data/docs/source/images/reviews-summary-above-share-buttons.png +0 -0
- data/docs/source/images/reviews-summary-below-product-name.png +0 -0
- data/docs/source/images/reviews-summary-below-share-buttons.png +0 -0
- data/docs/source/images/reviews-summary-removed.png +0 -0
- data/docs/source/images/rsa-fingerprint-for-stash.png +0 -0
- data/docs/source/images/ruby-version-constraint.png +0 -0
- data/docs/source/images/script-tag-added-through-admin.png +0 -0
- data/docs/source/images/search-analysis-admin-alternate-rendering.png +0 -0
- data/docs/source/images/search-analysis-admin.png +0 -0
- data/docs/source/images/search-quality-report.png +0 -0
- data/docs/source/images/search.svg +0 -1
- data/docs/source/images/searching-for-cart-system-content-in-admin.png +0 -0
- data/docs/source/images/searching-for-layout-system-content-in-admin.png +0 -0
- data/docs/source/images/seeded-admin.png +0 -0
- data/docs/source/images/seeds-from-plugins.png +0 -0
- data/docs/source/images/seo-metadata-automation-ui.png +0 -0
- data/docs/source/images/show-password-button.png +0 -0
- data/docs/source/images/storefront-autocomplete.png +0 -0
- data/docs/source/images/storefront-category-summary-content-block.png +0 -0
- data/docs/source/images/storefront-category.png +0 -0
- data/docs/source/images/storefront-product-after-overriding.png +0 -0
- data/docs/source/images/storefront-product-before-overriding.png +0 -0
- data/docs/source/images/storefront-product-browse-page.png +0 -0
- data/docs/source/images/storefront-product-recommendations.png +0 -0
- data/docs/source/images/storefront-product-show-page.png +0 -0
- data/docs/source/images/storefront-requests-and-search-requests.png +0 -0
- data/docs/source/images/storefront-search-request-handling.png +0 -0
- data/docs/source/images/storefront-search-response-creation.png +0 -0
- data/docs/source/images/storefront-search.png +0 -0
- data/docs/source/images/storefront-style-guides-navigation.png +0 -0
- data/docs/source/images/styles.css +0 -3
- data/docs/source/images/tax-categories-ui.png +0 -0
- data/docs/source/images/tax-rates-ui.png +0 -0
- data/docs/source/images/unpurchasable-product.png +0 -0
- data/docs/source/images/url-redirects-filtering.png +0 -0
- data/docs/source/images/utility-nav-area-in-admin.png +0 -0
- data/docs/source/images/utility-nav-area-in-storefront.png +0 -0
- data/docs/source/images/validation-message-in-storefront.png +0 -0
- data/docs/source/images/view-model-interface.png +0 -0
- data/docs/source/images/viewing-workarea-version-in-source.png +0 -0
- data/docs/source/images/workarea.svg +0 -1
- data/docs/source/images/worst-performing-searches-on-results-customization-page.png +0 -0
- data/docs/source/images/writing-data.svg +0 -1
- data/docs/source/index.html.erb +0 -166
- data/docs/source/javascripts/jquery.js +0 -2
- data/docs/source/javascripts/lunr.js +0 -7
- data/docs/source/javascripts/site.js +0 -299
- data/docs/source/javascripts/vendor/highlight.pack.js +0 -2
- data/docs/source/layouts/article.erb +0 -106
- data/docs/source/layouts/bare.erb +0 -46
- data/docs/source/layouts/layout.erb +0 -43
- data/docs/source/release-notes/workarea-3-0-0.html.md +0 -146
- data/docs/source/release-notes/workarea-3-0-1.html.md +0 -161
- data/docs/source/release-notes/workarea-3-0-10.html.md +0 -39
- data/docs/source/release-notes/workarea-3-0-11.html.md +0 -277
- data/docs/source/release-notes/workarea-3-0-12.html.md +0 -14
- data/docs/source/release-notes/workarea-3-0-13.html.md +0 -153
- data/docs/source/release-notes/workarea-3-0-14.html.md +0 -93
- data/docs/source/release-notes/workarea-3-0-15.html.md +0 -107
- data/docs/source/release-notes/workarea-3-0-16.html.md +0 -36
- data/docs/source/release-notes/workarea-3-0-17.html.md +0 -141
- data/docs/source/release-notes/workarea-3-0-18.html.md +0 -123
- data/docs/source/release-notes/workarea-3-0-19.html.md +0 -160
- data/docs/source/release-notes/workarea-3-0-2.html.md +0 -222
- data/docs/source/release-notes/workarea-3-0-20.html.md +0 -95
- data/docs/source/release-notes/workarea-3-0-21.html.md +0 -168
- data/docs/source/release-notes/workarea-3-0-22.html.md +0 -268
- data/docs/source/release-notes/workarea-3-0-23.html.md +0 -173
- data/docs/source/release-notes/workarea-3-0-24.html.md +0 -19
- data/docs/source/release-notes/workarea-3-0-25.html.md +0 -26
- data/docs/source/release-notes/workarea-3-0-26.html.md +0 -199
- data/docs/source/release-notes/workarea-3-0-27.html.md +0 -113
- data/docs/source/release-notes/workarea-3-0-28.html.md +0 -39
- data/docs/source/release-notes/workarea-3-0-29.html.md +0 -73
- data/docs/source/release-notes/workarea-3-0-3.html.md +0 -35
- data/docs/source/release-notes/workarea-3-0-30.html.md +0 -186
- data/docs/source/release-notes/workarea-3-0-31.html.md +0 -125
- data/docs/source/release-notes/workarea-3-0-32.html.md +0 -73
- data/docs/source/release-notes/workarea-3-0-33.html.md +0 -137
- data/docs/source/release-notes/workarea-3-0-34.html.md +0 -203
- data/docs/source/release-notes/workarea-3-0-35.html.md +0 -205
- data/docs/source/release-notes/workarea-3-0-36.html.md +0 -105
- data/docs/source/release-notes/workarea-3-0-37.html.md +0 -144
- data/docs/source/release-notes/workarea-3-0-38.html.md +0 -73
- data/docs/source/release-notes/workarea-3-0-39.html.md +0 -77
- data/docs/source/release-notes/workarea-3-0-4.html.md +0 -14
- data/docs/source/release-notes/workarea-3-0-40.html.md +0 -130
- data/docs/source/release-notes/workarea-3-0-41.html.md +0 -70
- data/docs/source/release-notes/workarea-3-0-42.html.md +0 -52
- data/docs/source/release-notes/workarea-3-0-43.html.md +0 -72
- data/docs/source/release-notes/workarea-3-0-44.html.md +0 -93
- data/docs/source/release-notes/workarea-3-0-45.html.md +0 -61
- data/docs/source/release-notes/workarea-3-0-46.html.md +0 -171
- data/docs/source/release-notes/workarea-3-0-47.html.md +0 -130
- data/docs/source/release-notes/workarea-3-0-48.html.md +0 -160
- data/docs/source/release-notes/workarea-3-0-49.html.md +0 -28
- data/docs/source/release-notes/workarea-3-0-5.html.md +0 -225
- data/docs/source/release-notes/workarea-3-0-50.html.md +0 -74
- data/docs/source/release-notes/workarea-3-0-51.html.md +0 -61
- data/docs/source/release-notes/workarea-3-0-52.html.md +0 -76
- data/docs/source/release-notes/workarea-3-0-53.html.md +0 -126
- data/docs/source/release-notes/workarea-3-0-54.html.md +0 -112
- data/docs/source/release-notes/workarea-3-0-55.html.md +0 -105
- data/docs/source/release-notes/workarea-3-0-56.html.md +0 -56
- data/docs/source/release-notes/workarea-3-0-57.html.md +0 -82
- data/docs/source/release-notes/workarea-3-0-58.html.md +0 -153
- data/docs/source/release-notes/workarea-3-0-59.html.md +0 -78
- data/docs/source/release-notes/workarea-3-0-6.html.md +0 -165
- data/docs/source/release-notes/workarea-3-0-60.html.md +0 -43
- data/docs/source/release-notes/workarea-3-0-61.html.md +0 -46
- data/docs/source/release-notes/workarea-3-0-62.html.md +0 -23
- data/docs/source/release-notes/workarea-3-0-63.html.md +0 -25
- data/docs/source/release-notes/workarea-3-0-64.html.md +0 -25
- data/docs/source/release-notes/workarea-3-0-65.html.md +0 -37
- data/docs/source/release-notes/workarea-3-0-7.html.md +0 -207
- data/docs/source/release-notes/workarea-3-0-8.html.md +0 -337
- data/docs/source/release-notes/workarea-3-0-9.html.md +0 -196
- data/docs/source/release-notes/workarea-3-1-0.html.md +0 -414
- data/docs/source/release-notes/workarea-3-1-1.html.md +0 -139
- data/docs/source/release-notes/workarea-3-1-10.html.md +0 -19
- data/docs/source/release-notes/workarea-3-1-11.html.md +0 -27
- data/docs/source/release-notes/workarea-3-1-12.html.md +0 -216
- data/docs/source/release-notes/workarea-3-1-13.html.md +0 -113
- data/docs/source/release-notes/workarea-3-1-14.html.md +0 -39
- data/docs/source/release-notes/workarea-3-1-15.html.md +0 -107
- data/docs/source/release-notes/workarea-3-1-16.html.md +0 -188
- data/docs/source/release-notes/workarea-3-1-17.html.md +0 -141
- data/docs/source/release-notes/workarea-3-1-18.html.md +0 -73
- data/docs/source/release-notes/workarea-3-1-19.html.md +0 -137
- data/docs/source/release-notes/workarea-3-1-2.html.md +0 -55
- data/docs/source/release-notes/workarea-3-1-20.html.md +0 -203
- data/docs/source/release-notes/workarea-3-1-21.html.md +0 -205
- data/docs/source/release-notes/workarea-3-1-22.html.md +0 -121
- data/docs/source/release-notes/workarea-3-1-23.html.md +0 -144
- data/docs/source/release-notes/workarea-3-1-24.html.md +0 -94
- data/docs/source/release-notes/workarea-3-1-25.html.md +0 -77
- data/docs/source/release-notes/workarea-3-1-26.html.md +0 -130
- data/docs/source/release-notes/workarea-3-1-27.html.md +0 -70
- data/docs/source/release-notes/workarea-3-1-28.html.md +0 -52
- data/docs/source/release-notes/workarea-3-1-29.html.md +0 -44
- data/docs/source/release-notes/workarea-3-1-3.html.md +0 -185
- data/docs/source/release-notes/workarea-3-1-30.html.md +0 -72
- data/docs/source/release-notes/workarea-3-1-31.html.md +0 -93
- data/docs/source/release-notes/workarea-3-1-32.html.md +0 -61
- data/docs/source/release-notes/workarea-3-1-33.html.md +0 -171
- data/docs/source/release-notes/workarea-3-1-34.html.md +0 -130
- data/docs/source/release-notes/workarea-3-1-35.html.md +0 -179
- data/docs/source/release-notes/workarea-3-1-36.html.md +0 -28
- data/docs/source/release-notes/workarea-3-1-37.html.md +0 -74
- data/docs/source/release-notes/workarea-3-1-38.html.md +0 -61
- data/docs/source/release-notes/workarea-3-1-39.html.md +0 -96
- data/docs/source/release-notes/workarea-3-1-4.html.md +0 -148
- data/docs/source/release-notes/workarea-3-1-40.html.md +0 -126
- data/docs/source/release-notes/workarea-3-1-41.html.md +0 -128
- data/docs/source/release-notes/workarea-3-1-42.html.md +0 -105
- data/docs/source/release-notes/workarea-3-1-43.html.md +0 -37
- data/docs/source/release-notes/workarea-3-1-44.html.md +0 -82
- data/docs/source/release-notes/workarea-3-1-45.html.md +0 -153
- data/docs/source/release-notes/workarea-3-1-46.html.md +0 -91
- data/docs/source/release-notes/workarea-3-1-47.html.md +0 -65
- data/docs/source/release-notes/workarea-3-1-48.html.md +0 -46
- data/docs/source/release-notes/workarea-3-1-49.html.md +0 -23
- data/docs/source/release-notes/workarea-3-1-5.html.md +0 -169
- data/docs/source/release-notes/workarea-3-1-50.html.md +0 -42
- data/docs/source/release-notes/workarea-3-1-51.html.md +0 -25
- data/docs/source/release-notes/workarea-3-1-52.html.md +0 -57
- data/docs/source/release-notes/workarea-3-1-6.html.md +0 -117
- data/docs/source/release-notes/workarea-3-1-7.html.md +0 -176
- data/docs/source/release-notes/workarea-3-1-8.html.md +0 -283
- data/docs/source/release-notes/workarea-3-1-9.html.md +0 -212
- data/docs/source/release-notes/workarea-3-2-0.html.md +0 -1705
- data/docs/source/release-notes/workarea-3-2-1.html.md +0 -216
- data/docs/source/release-notes/workarea-3-2-10.html.md +0 -237
- data/docs/source/release-notes/workarea-3-2-11.html.md +0 -121
- data/docs/source/release-notes/workarea-3-2-12.html.md +0 -145
- data/docs/source/release-notes/workarea-3-2-13.html.md +0 -138
- data/docs/source/release-notes/workarea-3-2-14.html.md +0 -77
- data/docs/source/release-notes/workarea-3-2-15.html.md +0 -130
- data/docs/source/release-notes/workarea-3-2-16.html.md +0 -111
- data/docs/source/release-notes/workarea-3-2-17.html.md +0 -52
- data/docs/source/release-notes/workarea-3-2-18.html.md +0 -44
- data/docs/source/release-notes/workarea-3-2-19.html.md +0 -72
- data/docs/source/release-notes/workarea-3-2-2.html.md +0 -145
- data/docs/source/release-notes/workarea-3-2-20.html.md +0 -93
- data/docs/source/release-notes/workarea-3-2-21.html.md +0 -61
- data/docs/source/release-notes/workarea-3-2-22.html.md +0 -154
- data/docs/source/release-notes/workarea-3-2-23.html.md +0 -130
- data/docs/source/release-notes/workarea-3-2-24.html.md +0 -200
- data/docs/source/release-notes/workarea-3-2-25.html.md +0 -28
- data/docs/source/release-notes/workarea-3-2-26.html.md +0 -94
- data/docs/source/release-notes/workarea-3-2-27.html.md +0 -61
- data/docs/source/release-notes/workarea-3-2-28.html.md +0 -96
- data/docs/source/release-notes/workarea-3-2-29.html.md +0 -126
- data/docs/source/release-notes/workarea-3-2-30.html.md +0 -112
- data/docs/source/release-notes/workarea-3-2-31.html.md +0 -105
- data/docs/source/release-notes/workarea-3-2-32.html.md +0 -56
- data/docs/source/release-notes/workarea-3-2-33.html.md +0 -82
- data/docs/source/release-notes/workarea-3-2-34.html.md +0 -153
- data/docs/source/release-notes/workarea-3-2-35.html.md +0 -91
- data/docs/source/release-notes/workarea-3-2-36.html.md +0 -118
- data/docs/source/release-notes/workarea-3-2-37.html.md +0 -46
- data/docs/source/release-notes/workarea-3-2-38.html.md +0 -23
- data/docs/source/release-notes/workarea-3-2-39.html.md +0 -42
- data/docs/source/release-notes/workarea-3-2-4.html.md +0 -109
- data/docs/source/release-notes/workarea-3-2-40.html.md +0 -25
- data/docs/source/release-notes/workarea-3-2-41.html.md +0 -90
- data/docs/source/release-notes/workarea-3-2-5.html.md +0 -186
- data/docs/source/release-notes/workarea-3-2-6.html.md +0 -173
- data/docs/source/release-notes/workarea-3-2-7.html.md +0 -89
- data/docs/source/release-notes/workarea-3-2-8.html.md +0 -137
- data/docs/source/release-notes/workarea-3-2-9.html.md +0 -219
- data/docs/source/release-notes/workarea-3-3-0.html.md +0 -1272
- data/docs/source/release-notes/workarea-3-3-1.html.md +0 -324
- data/docs/source/release-notes/workarea-3-3-10.html.md +0 -69
- data/docs/source/release-notes/workarea-3-3-11.html.md +0 -72
- data/docs/source/release-notes/workarea-3-3-12.html.md +0 -136
- data/docs/source/release-notes/workarea-3-3-13.html.md +0 -61
- data/docs/source/release-notes/workarea-3-3-14.html.md +0 -196
- data/docs/source/release-notes/workarea-3-3-15.html.md +0 -167
- data/docs/source/release-notes/workarea-3-3-16.html.md +0 -234
- data/docs/source/release-notes/workarea-3-3-17.html.md +0 -82
- data/docs/source/release-notes/workarea-3-3-18.html.md +0 -165
- data/docs/source/release-notes/workarea-3-3-19.html.md +0 -106
- data/docs/source/release-notes/workarea-3-3-2.html.md +0 -72
- data/docs/source/release-notes/workarea-3-3-20.html.md +0 -116
- data/docs/source/release-notes/workarea-3-3-21.html.md +0 -228
- data/docs/source/release-notes/workarea-3-3-22.html.md +0 -125
- data/docs/source/release-notes/workarea-3-3-23.html.md +0 -154
- data/docs/source/release-notes/workarea-3-3-24.html.md +0 -70
- data/docs/source/release-notes/workarea-3-3-25.html.md +0 -114
- data/docs/source/release-notes/workarea-3-3-26.html.md +0 -260
- data/docs/source/release-notes/workarea-3-3-27.html.md +0 -138
- data/docs/source/release-notes/workarea-3-3-28.html.md +0 -147
- data/docs/source/release-notes/workarea-3-3-29.html.md +0 -63
- data/docs/source/release-notes/workarea-3-3-3.html.md +0 -153
- data/docs/source/release-notes/workarea-3-3-30.html.md +0 -102
- data/docs/source/release-notes/workarea-3-3-31.html.md +0 -57
- data/docs/source/release-notes/workarea-3-3-32.html.md +0 -44
- data/docs/source/release-notes/workarea-3-3-33.html.md +0 -114
- data/docs/source/release-notes/workarea-3-3-34.html.md +0 -29
- data/docs/source/release-notes/workarea-3-3-4.html.md +0 -332
- data/docs/source/release-notes/workarea-3-3-5.html.md +0 -242
- data/docs/source/release-notes/workarea-3-3-6.html.md +0 -100
- data/docs/source/release-notes/workarea-3-3-7.html.md +0 -148
- data/docs/source/release-notes/workarea-3-3-8.html.md +0 -163
- data/docs/source/release-notes/workarea-3-3-9.html.md +0 -93
- data/docs/source/release-notes/workarea-3-4-0.html.md +0 -580
- data/docs/source/release-notes/workarea-3-4-1.html.md +0 -150
- data/docs/source/release-notes/workarea-3-4-10.html.md +0 -72
- data/docs/source/release-notes/workarea-3-4-11.html.md +0 -60
- data/docs/source/release-notes/workarea-3-4-12.html.md +0 -155
- data/docs/source/release-notes/workarea-3-4-15.html.md +0 -100
- data/docs/source/release-notes/workarea-3-4-16.html.md +0 -88
- data/docs/source/release-notes/workarea-3-4-2.html.md +0 -188
- data/docs/source/release-notes/workarea-3-4-3.html.md +0 -136
- data/docs/source/release-notes/workarea-3-4-4.html.md +0 -114
- data/docs/source/release-notes/workarea-3-4-5.html.md +0 -275
- data/docs/source/release-notes/workarea-3-4-6.html.md +0 -169
- data/docs/source/release-notes/workarea-3-4-7.html.md +0 -162
- data/docs/source/release-notes/workarea-3-4-8.html.md +0 -95
- data/docs/source/release-notes/workarea-3-4-9.html.md +0 -135
- data/docs/source/release-notes.html.md +0 -261
- data/docs/source/search.html.erb +0 -34
- data/docs/source/shared/_header.erb +0 -61
- data/docs/source/shared/_svgs.erb +0 -17
- data/docs/source/style_guide/index.html.erb +0 -382
- data/docs/source/stylesheets/_base.scss +0 -125
- data/docs/source/stylesheets/_components.scss +0 -669
- data/docs/source/stylesheets/_helpers.scss +0 -10
- data/docs/source/stylesheets/_opinions.scss +0 -42
- data/docs/source/stylesheets/_settings.scss +0 -56
- data/docs/source/stylesheets/_typography.scss +0 -119
- data/docs/source/stylesheets/site.css.scss +0 -14
- data/docs/source/stylesheets/vendor/_avalanche.scss +0 -328
- data/docs/source/stylesheets/vendor/_normalize.scss +0 -341
- data/docs/source/stylesheets/vendor/highlight/_tomorrow_night_blue.scss +0 -75
- data/docs/source/upgrade-guides/workarea-3-4-0.html.md +0 -152
- data/docs/source/upgrade-guides.html.md +0 -18
- data/docs/workarea_renderer.rb +0 -8
- data/docs/yarn.lock +0 -2522
@@ -1,756 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Shipping
|
3
|
-
excerpt: A shipping (Workarea::Shipping) is an application document that represents shipping and pricing information for an order or a subset of an order.
|
4
|
-
---
|
5
|
-
|
6
|
-
# Shipping
|
7
|
-
|
8
|
-
## Shipping
|
9
|
-
|
10
|
-
A <dfn>shipping</dfn> (`Workarea::Shipping`) is an [application document](application-document.html) that represents shipping and pricing information for an order or a subset of an order.
|
11
|
-
|
12
|
-
### Order
|
13
|
-
|
14
|
-
A shipping is associated with an order. An order may be associated with many shippings, but without customization, the Workarea checkout models and UI assume one shipping per order. The `order_id` field on a shipping identifies its associated order.
|
15
|
-
|
16
|
-
```
|
17
|
-
# returns the first shipping for the given order id
|
18
|
-
Workarea::Shipping.find_by_order(order_id)
|
19
|
-
|
20
|
-
# returns all shippings with the given order id
|
21
|
-
Workarea::Shipping.where(order_id: order_id).to_a
|
22
|
-
```
|
23
|
-
|
24
|
-
### Address
|
25
|
-
|
26
|
-
A shipping embeds one shipping address. `Shipping#set_address` builds and saves the embedded address from the given attributes.
|
27
|
-
|
28
|
-
```
|
29
|
-
shipping.set_address(
|
30
|
-
first_name: 'Bob',
|
31
|
-
last_name: 'Clams',
|
32
|
-
street: '22 S 3rd St',
|
33
|
-
city: 'Philadelphia',
|
34
|
-
region: 'PA',
|
35
|
-
postal_code: '19106',
|
36
|
-
country: 'US'
|
37
|
-
)
|
38
|
-
# => true
|
39
|
-
|
40
|
-
shipping.address.class
|
41
|
-
# => Workarea::Shipping::Address
|
42
|
-
|
43
|
-
shipping.address.first_name
|
44
|
-
# => "Bob"
|
45
|
-
```
|
46
|
-
|
47
|
-
### Service Selection
|
48
|
-
|
49
|
-
A shipping embeds one service selection. `Shipping#apply_shipping_service` builds the embedded service selection without persisting it. `Shipping#set_shipping_service` builds and saves the embedded service selection, using `apply_shipping_service` within its implementation.
|
50
|
-
|
51
|
-
`Shipping#apply_shipping_service` resets the price adjustments and shipping total on the shipping and then sets a _shipping_ price adjustment on the shipping. This price adjustment represents the base price of the service selection. See pricing example, below.
|
52
|
-
|
53
|
-
### Pricing
|
54
|
-
|
55
|
-
A shipping embeds many price adjustments. While order items embed all _item_ and _order_ price adjustments, shippings embed all _shipping_ and _tax_ price adjustments. The price adjustments on a shipping may represent the following:
|
56
|
-
|
57
|
-
- The base price of the service selection embedded within the shipping
|
58
|
-
- Each discount on the service selection embedded within the shipping
|
59
|
-
- The tax price of the service selection embedded within the shipping
|
60
|
-
- The tax price of each order item associated with the shipping
|
61
|
-
|
62
|
-
`Shipping#base_price` returns the `amount` of the _shipping_ price adjustment on the shipping, if any. `Shipping#shipping_total` and `Shipping#tax_total` are `Money` values that default to zero when a shipping is initialized and are updated when the shipping is priced by the Workarea pricing model. See pricing example, below.
|
63
|
-
|
64
|
-
### Pricing Example
|
65
|
-
|
66
|
-
```
|
67
|
-
# create tax category
|
68
|
-
Workarea::Tax::Category.destroy_all
|
69
|
-
sales_tax_category = Workarea::Tax::Category.create!(
|
70
|
-
name: 'Sales Tax',
|
71
|
-
code: '001'
|
72
|
-
)
|
73
|
-
|
74
|
-
# create tax rate
|
75
|
-
sales_tax_category.rates.create!(
|
76
|
-
country: 'US',
|
77
|
-
region: 'PA',
|
78
|
-
percentage: 0.05
|
79
|
-
)
|
80
|
-
|
81
|
-
# create pricing sku
|
82
|
-
Workarea::Pricing::Sku.destroy_all
|
83
|
-
Workarea::Pricing::Sku.create!(
|
84
|
-
_id: 'small-shirt',
|
85
|
-
prices: [{ regular: 10 }],
|
86
|
-
tax_code: '001'
|
87
|
-
)
|
88
|
-
|
89
|
-
# create shipping service
|
90
|
-
Workarea::Shipping::Service.destroy_all
|
91
|
-
shipping_service = Workarea::Shipping::Service.create!(
|
92
|
-
name: 'Standard', rates: [{ price: 6 }], tax_code: '001'
|
93
|
-
)
|
94
|
-
|
95
|
-
# create shipping discount
|
96
|
-
Workarea::Pricing::Discount::Shipping.destroy_all
|
97
|
-
Workarea::Pricing::Discount::Shipping.create!(
|
98
|
-
name: "$5 #{shipping_service.name} Shipping",
|
99
|
-
shipping_service: shipping_service.name,
|
100
|
-
amount: 5
|
101
|
-
)
|
102
|
-
|
103
|
-
# create order with item
|
104
|
-
Workarea::Order.destroy_all
|
105
|
-
order = Workarea::Order.create!(
|
106
|
-
items: [{ product_id: 'shirt', sku: 'small-shirt', quantity: '1' }]
|
107
|
-
)
|
108
|
-
|
109
|
-
# create shipping
|
110
|
-
Workarea::Shipping.destroy_all
|
111
|
-
shipping = Workarea::Shipping.create!(order_id: order.id)
|
112
|
-
|
113
|
-
# set shipping address
|
114
|
-
shipping.set_address(
|
115
|
-
first_name: 'Bob',
|
116
|
-
last_name: 'Clams',
|
117
|
-
street: '22 S 3rd St',
|
118
|
-
city: 'Philadelphia',
|
119
|
-
region: 'PA',
|
120
|
-
postal_code: '19106',
|
121
|
-
country: 'US'
|
122
|
-
)
|
123
|
-
|
124
|
-
# set shipping service selection
|
125
|
-
Workarea::Pricing.perform(order)
|
126
|
-
shipping_option = shipping_service.to_option(order.subtotal_price)
|
127
|
-
shipping.set_shipping_service(shipping_option.to_h)
|
128
|
-
|
129
|
-
# price the order and shipping
|
130
|
-
Workarea::Pricing.perform(order, shipping)
|
131
|
-
|
132
|
-
shipping.price_adjustments.map(&:price)
|
133
|
-
# => ["shipping", "shipping", "tax", "tax"]
|
134
|
-
|
135
|
-
shipping.price_adjustments.map(&:description)
|
136
|
-
# => ["Standard", "$5 Standard Shipping", "Tax", "Tax"]
|
137
|
-
|
138
|
-
shipping.price_adjustments.map(&:calculator)
|
139
|
-
# => ["Workarea::Shipping", "Workarea::Pricing::Discount::Shipping", "Workarea::Pricing::TaxApplier", "Workarea::Pricing::TaxApplier"]
|
140
|
-
|
141
|
-
shipping.price_adjustments.map { |a| a.amount.to_s }
|
142
|
-
# => ["6.00", "-1.00", "0.50", "0.25"]
|
143
|
-
|
144
|
-
shipping.base_price.to_s
|
145
|
-
# => "6.00"
|
146
|
-
|
147
|
-
shipping.shipping_total.to_s
|
148
|
-
# => "5.00"
|
149
|
-
|
150
|
-
shipping.tax_total.to_s
|
151
|
-
# => "0.75"
|
152
|
-
```
|
153
|
-
|
154
|
-
### Options
|
155
|
-
|
156
|
-
`Shipping#find_method_options` returns shipping options that qualify for the shipping and the given packages. Each shipping option is created from a rate estimate provided by the configured carrier. Price adjustments are not set on these options, so the price of each reflects the base price only.
|
157
|
-
|
158
|
-
```
|
159
|
-
# clear all shipping services
|
160
|
-
Workarea::Shipping::Service.destroy_all
|
161
|
-
|
162
|
-
# create 2 location agnostic shipping services
|
163
|
-
Workarea::Shipping::Service.create!(
|
164
|
-
name: 'Standard',
|
165
|
-
rates: [{ price: 5 }]
|
166
|
-
)
|
167
|
-
Workarea::Shipping::Service.create!(
|
168
|
-
name: 'Priority',
|
169
|
-
rates: [{ price: 10 }]
|
170
|
-
)
|
171
|
-
|
172
|
-
# create 2 location specific shipping services
|
173
|
-
Workarea::Shipping::Service.create!(
|
174
|
-
name: 'PA Standard',
|
175
|
-
rates: [{ price: 5 }],
|
176
|
-
country: 'US',
|
177
|
-
regions: ['PA']
|
178
|
-
)
|
179
|
-
Workarea::Shipping::Service.create!(
|
180
|
-
name: 'PA Priority',
|
181
|
-
rates: [{ price: 10 }],
|
182
|
-
country: 'US',
|
183
|
-
regions: ['PA']
|
184
|
-
)
|
185
|
-
|
186
|
-
# create order and shipping
|
187
|
-
order = Workarea::Order.create!
|
188
|
-
shipping = Workarea::Shipping.create!(
|
189
|
-
order_id: order.id,
|
190
|
-
address: {
|
191
|
-
first_name: 'Bob',
|
192
|
-
last_name: 'Clams',
|
193
|
-
street: '22 S 3rd St',
|
194
|
-
city: 'Philadelphia',
|
195
|
-
region: 'PA',
|
196
|
-
postal_code: '19106',
|
197
|
-
country: 'US'
|
198
|
-
}
|
199
|
-
)
|
200
|
-
|
201
|
-
# init packages
|
202
|
-
packages = Workarea::Packaging.new(order, shipping).packages
|
203
|
-
|
204
|
-
# list names of ALL shipping services
|
205
|
-
Workarea::Shipping::Service.all.to_a.map(&:name)
|
206
|
-
# => ["Standard", "Priority", "PA Standard", "PA Priority"]
|
207
|
-
|
208
|
-
# list names of QUALIFYING shipping options (each corresponding to a service)
|
209
|
-
shipping.find_method_options(packages).map(&:name)
|
210
|
-
# => ["PA Standard", "PA Priority"]
|
211
|
-
```
|
212
|
-
|
213
|
-
## Address
|
214
|
-
|
215
|
-
A <dfn>shipping address</dfn> (`Workarea::Shipping::Address`) is an embedded [application document](application-document.html) that represents the address to which its parent shipping is to be shipped.
|
216
|
-
|
217
|
-
### Fields
|
218
|
-
|
219
|
-
A shipping address has the following fields (required fields indicated).
|
220
|
-
|
221
|
-
- `first_name` (required)
|
222
|
-
- `last_name` (required)
|
223
|
-
- `company`
|
224
|
-
- `street` (required)
|
225
|
-
- `street_2`
|
226
|
-
- `city` (required)
|
227
|
-
- `region` (required if country has regions)
|
228
|
-
- `postal_code` (required if country has postal codes)
|
229
|
-
- `country` (required)
|
230
|
-
- `phone_number`
|
231
|
-
- `phone_extension`
|
232
|
-
|
233
|
-
A shipping address also applies the following validations and transformations.
|
234
|
-
|
235
|
-
- All fields have a max length of 500 characters
|
236
|
-
- `street` and `street_2` cannot be a PO Box, as defined by the pattern in `Workarea.config.po_box_regex`
|
237
|
-
- The `phone_number` setter strips non-digits
|
238
|
-
|
239
|
-
### ActiveShipping
|
240
|
-
|
241
|
-
`Shipping::Address#to_active_shipping` initializes and returns an ActiveShipping location representing the address.
|
242
|
-
|
243
|
-
```
|
244
|
-
shipping = Workarea::Shipping.create!(
|
245
|
-
address: {
|
246
|
-
first_name: 'Bob',
|
247
|
-
last_name: 'Clams',
|
248
|
-
street: '22 S 3rd St',
|
249
|
-
city: 'Philadelphia',
|
250
|
-
region: 'PA',
|
251
|
-
postal_code: '19106',
|
252
|
-
country: 'US'
|
253
|
-
}
|
254
|
-
)
|
255
|
-
|
256
|
-
# address attributes
|
257
|
-
shipping.address.as_document
|
258
|
-
# => {
|
259
|
-
# "_id" => BSON::ObjectId('58d42851eefbfefd52cc4b6b'),
|
260
|
-
# "_type" => "Workarea::Shipping::Address",
|
261
|
-
# "first_name" => "Bob",
|
262
|
-
# "last_name" => "Clams",
|
263
|
-
# "street" => "22 S 3rd St",
|
264
|
-
# "city" => "Philadelphia",
|
265
|
-
# "region" => "PA",
|
266
|
-
# "postal_code" => "19106",
|
267
|
-
# "country" => "US"
|
268
|
-
# }
|
269
|
-
|
270
|
-
# location attributes
|
271
|
-
shipping.address.to_active_shipping.to_hash
|
272
|
-
# => {
|
273
|
-
# :country => "US",
|
274
|
-
# :postal_code => "19106",
|
275
|
-
# :province => "PA",
|
276
|
-
# :city => "Philadelphia",
|
277
|
-
# :name => nil,
|
278
|
-
# :address1 => nil,
|
279
|
-
# :address2 => nil,
|
280
|
-
# :address3 => nil,
|
281
|
-
# :phone => nil,
|
282
|
-
# :fax => nil,
|
283
|
-
# :address_type => nil,
|
284
|
-
# :company_name => nil
|
285
|
-
# }
|
286
|
-
```
|
287
|
-
|
288
|
-
## Service Selection
|
289
|
-
|
290
|
-
A <dfn>shipping service selection</dfn> (`Workarea::Shipping::ServiceSelection`) is an embedded [application document](application-document.html) that represents the shipping service for its parent shipping.
|
291
|
-
|
292
|
-
A service selection's `name`, `carrier`, and `service_code` should identify a shipping service within the retailer's fulfillment system. The `tax_code` field identifies the applicable tax category within the Workarea system.
|
293
|
-
|
294
|
-
## Shipping Option
|
295
|
-
|
296
|
-
A <dfn>shipping option</dfn> (`Workarea::ShippingOption`) is an object representing a _qualifying_ shipping service for an order or shipping (if multiple shippings). While a rate estimate represents a shipping service from the carrier's perspective, a shipping option represents a shipping service from the perspective of the Workarea system, including `tax_code` and `price_adjustments`.
|
297
|
-
|
298
|
-
```
|
299
|
-
shipping_option.name
|
300
|
-
# => "Media Mail"
|
301
|
-
|
302
|
-
shipping_option.carrier
|
303
|
-
# => "USPS"
|
304
|
-
|
305
|
-
shipping_option.service_code
|
306
|
-
# => "Media Mail Parcel"
|
307
|
-
|
308
|
-
shipping_option.tax_code
|
309
|
-
# => "001"
|
310
|
-
```
|
311
|
-
|
312
|
-
### Pricing
|
313
|
-
|
314
|
-
Within checkout, shipping options are presented with an adjusted price (the absolute sum of all _shipping_ price adjustments). After a customer selects a shipping option, the selected shipping option is used to persist a service selection on the shipping. The service selection includes the `tax_code`, which is used to calculate a `tax` price adjustment on the shipping.
|
315
|
-
|
316
|
-
A shipping option may be initialized with a price (stored in `@price`) and may have price adjustments (stored in `@price_adjustments`). The methods `price` and `base_price` return the adjusted and non-adjusted price, respectively. When `@price_adjustments` is empty, both methods return the same value.
|
317
|
-
|
318
|
-
```
|
319
|
-
shipping_option.price_adjustments.map{ |a| a.amount.to_s }
|
320
|
-
# => ["-1.00"]
|
321
|
-
|
322
|
-
shipping_option.base_price.to_s
|
323
|
-
# => "6.00"
|
324
|
-
|
325
|
-
shipping_option.price.to_s
|
326
|
-
# => "5.00"
|
327
|
-
```
|
328
|
-
|
329
|
-
### Initializing
|
330
|
-
|
331
|
-
A shipping option can be initialized from an rate estimate or a shipping service. Additionally, `Shipping#find_method_options` and `Checkout::ShippingOptions#available` return collections of shipping options.
|
332
|
-
|
333
|
-
#### From Rate Estimate
|
334
|
-
|
335
|
-
When initializing from a rate estimate, `price` is typecast to `Money`. Additionally, `Shipping::Service.find_tax_code` finds the value for `tax_code` using the `carrier` and `service_name`. When an application is configured to use a shipping carrier other than `ActiveShipping::Workarea`, shipping service models are likely not used for rate estimates. However, they will still be used to look up tax codes. Any application concerned with shipping service tax codes must therefore persist shipping services.
|
336
|
-
|
337
|
-
```
|
338
|
-
# rate estimate attributes
|
339
|
-
JSON.parse(rate_estimate.to_json)
|
340
|
-
=> {
|
341
|
-
# "origin" => {} # truncated
|
342
|
-
# "destination" => {} # truncated
|
343
|
-
# "carrier" => "USPS",
|
344
|
-
# "service_name" => "Media Mail",
|
345
|
-
# "service_code" => "Media Mail Parcel",
|
346
|
-
# "description" => nil,
|
347
|
-
# "estimate_reference" => nil,
|
348
|
-
# "pickup_time" => nil,
|
349
|
-
# "expires_at" => nil,
|
350
|
-
# "package_rates" => [],
|
351
|
-
# "total_price" => 600,
|
352
|
-
# "negotiated_rate" => nil,
|
353
|
-
# "compare_price" => nil,
|
354
|
-
# "phone_required" => false,
|
355
|
-
# "currency" => "USD",
|
356
|
-
# "delivery_range" => [],
|
357
|
-
# "shipping_date" => nil,
|
358
|
-
# "delivery_date" => nil,
|
359
|
-
# "insurance_price" => nil,
|
360
|
-
# "delivery_category" => nil,
|
361
|
-
# "shipment_options" => [],
|
362
|
-
# "charge_items" => []
|
363
|
-
# }
|
364
|
-
|
365
|
-
# shipping option attributes
|
366
|
-
Workarea::ShippingOption.from_rate_estimate(rate_estimate).to_h
|
367
|
-
# => {
|
368
|
-
# :carrier => "USPS",
|
369
|
-
# :name => "Media Mail",
|
370
|
-
# :service_code => "Media Mail Parcel",
|
371
|
-
# :price => #<Money fractional:600 currency:USD>,
|
372
|
-
# :base_price => #<Money fractional:600 currency:USD>,
|
373
|
-
# :tax_code => "001"
|
374
|
-
# }
|
375
|
-
```
|
376
|
-
|
377
|
-
#### From Shipping Service
|
378
|
-
|
379
|
-
`ShippingService#to_option(subtotal)` initializes a shipping option from a shipping service, using the provided subtotal to look up the qualifying rate. The shipping service `name` is flattened to a string (from localization hash) and `price` is added.
|
380
|
-
|
381
|
-
```
|
382
|
-
# shipping service attributes
|
383
|
-
JSON.parse(shipping_service.to_json)
|
384
|
-
# => {
|
385
|
-
# "_id" => "58d43b5aeefbfefd52cc4bc0",
|
386
|
-
# "carrier" => "USPS",
|
387
|
-
# "country" => nil,
|
388
|
-
# "created_at" => "2017-03-23T21:17:14.731Z",
|
389
|
-
# "name" => "Media Mail",
|
390
|
-
# "rates" => [{
|
391
|
-
# "_id" => "58d43b5aeefbfefd52cc4bc1",
|
392
|
-
# "created_at" => nil,
|
393
|
-
# "price" => {"cents" => 500.0, "currency_iso" => "USD"},
|
394
|
-
# "tier_max" => nil,
|
395
|
-
# "tier_min" => nil,
|
396
|
-
# "updated_at" => nil
|
397
|
-
# }],
|
398
|
-
# "regions" => nil,
|
399
|
-
# "service_code" => "Media Mail Parcel",
|
400
|
-
# "subtotal_max" => nil,
|
401
|
-
# "subtotal_min" => nil,
|
402
|
-
# "tax_code" => "001",
|
403
|
-
# "updated_at" => "2017-03-23T21:17:14.731Z"
|
404
|
-
# }
|
405
|
-
|
406
|
-
# shipping option attributes
|
407
|
-
shipping_service.to_option(25).to_h
|
408
|
-
# => {
|
409
|
-
# :carrier => "USPS",
|
410
|
-
# :name => "Media Mail",
|
411
|
-
# :service_code => "Media Mail Parcel",
|
412
|
-
# :price => #<Money fractional:500 currency:USD>,
|
413
|
-
# :base_price => #<Money fractional:500 currency:USD>,
|
414
|
-
# :tax_code => "001"
|
415
|
-
# }
|
416
|
-
```
|
417
|
-
|
418
|
-
#### From Shipping & Packages
|
419
|
-
|
420
|
-
`Shipping#find_method_options` requests rate estimates from the configured shipping carrier and maps each to a shipping option, returning a collection of shipping options (see options, above). This method uses `ShippingOption.from_rate_estimate` within its implementation (see from rate estimate, above).
|
421
|
-
|
422
|
-
#### From Order & Shipping
|
423
|
-
|
424
|
-
The Workarea checkout service uses `Workarea::Checkout::ShippingOptions#available` to return the collection of shipping options that qualify for the checkout, using information from the checkout's order and shipping. Since this API has access to an order and a shipping, the shipping options it returns have price adjustments representing any discounts on the shipping service selection. **This is the only API that returns shipping options with price adjustments.**
|
425
|
-
|
426
|
-
```
|
427
|
-
# create 2 shipping services
|
428
|
-
Workarea::Shipping::Service.destroy_all
|
429
|
-
standard_shipping_service = Workarea::Shipping::Service.create!(
|
430
|
-
name: 'Standard',
|
431
|
-
rates: [{ price: 6 }]
|
432
|
-
)
|
433
|
-
free_shipping_service = Workarea::Shipping::Service.create!(
|
434
|
-
name: 'FREE',
|
435
|
-
rates: [{ price: 0 }],
|
436
|
-
subtotal_min: 50
|
437
|
-
)
|
438
|
-
|
439
|
-
# create shipping discount
|
440
|
-
Workarea::Pricing::Discount::Shipping.destroy_all
|
441
|
-
Workarea::Pricing::Discount::Shipping.create!(
|
442
|
-
name: "$5 #{shipping_service.name} Shipping",
|
443
|
-
shipping_service: shipping_service.name,
|
444
|
-
amount: 5
|
445
|
-
)
|
446
|
-
|
447
|
-
# create pricing sku
|
448
|
-
Workarea::Pricing::Sku.destroy_all
|
449
|
-
Workarea::Pricing::Sku.create!(
|
450
|
-
_id: 'small-shirt',
|
451
|
-
prices: [{ regular: 10 }]
|
452
|
-
)
|
453
|
-
|
454
|
-
# create order with item
|
455
|
-
Workarea::Order.destroy_all
|
456
|
-
order = Workarea::Order.create!(
|
457
|
-
items: [{ product_id: 'shirt', sku: 'small-shirt', quantity: '1' }]
|
458
|
-
)
|
459
|
-
|
460
|
-
# create shipping with address
|
461
|
-
Workarea::Shipping.destroy_all
|
462
|
-
shipping = Workarea::Shipping.create!(
|
463
|
-
order_id: order.id,
|
464
|
-
address: {
|
465
|
-
first_name: 'Bob',
|
466
|
-
last_name: 'Clams',
|
467
|
-
street: '22 S 3rd St',
|
468
|
-
city: 'Philadelphia',
|
469
|
-
region: 'PA',
|
470
|
-
postal_code: '19106',
|
471
|
-
country: 'US'
|
472
|
-
}
|
473
|
-
)
|
474
|
-
|
475
|
-
# price the order and shipping
|
476
|
-
Workarea::Pricing.perform(order, shipping)
|
477
|
-
|
478
|
-
shipping_options = Workarea::Checkout::ShippingOptions.new(order, shipping).available
|
479
|
-
|
480
|
-
# ALL shipping services
|
481
|
-
Workarea::Shipping::Service.count
|
482
|
-
# => 2
|
483
|
-
|
484
|
-
# QUALIFYING shipping options
|
485
|
-
shipping_options.count
|
486
|
-
# => 1
|
487
|
-
|
488
|
-
shipping_option = shipping_options.first
|
489
|
-
|
490
|
-
shipping_option.name
|
491
|
-
# => "Standard"
|
492
|
-
|
493
|
-
# price, including discount(s)
|
494
|
-
shipping_option.price.to_s
|
495
|
-
# => "5.00"
|
496
|
-
|
497
|
-
# find corresponding shipping service
|
498
|
-
shipping_service = Workarea::Shipping::Service.find_by(name: shipping_option.name)
|
499
|
-
|
500
|
-
# base price of shipping service (excludes discounts)
|
501
|
-
shipping_service.find_rate(order.subtotal_price).price.to_s
|
502
|
-
# => "6.00"
|
503
|
-
```
|
504
|
-
|
505
|
-
### Serializing
|
506
|
-
|
507
|
-
`ShippingOption#to_h` serializes a shipping option into attributes appropriate for the initialization of a shipping service selection. This method is used to persist a shipping option as a shipping service selection via `Shipping#apply_shipping_service`.
|
508
|
-
|
509
|
-
```
|
510
|
-
shipping_option.to_h
|
511
|
-
# => {
|
512
|
-
# :carrier => "USPS",
|
513
|
-
# :name => "Media Mail",
|
514
|
-
# :service_code => "Media Mail Parcel",
|
515
|
-
# :price => #<Money fractional:600 currency:USD>,
|
516
|
-
# :base_price => #<Money fractional:600 currency:USD>,
|
517
|
-
# :tax_code => "001"
|
518
|
-
# }
|
519
|
-
```
|
520
|
-
|
521
|
-
## ActiveShipping
|
522
|
-
|
523
|
-
Workarea uses [ActiveShipping (v1.8)](http://www.rubydoc.info/gems/active_shipping/1.8.6), a Ruby API that abstracts the web services of various shipping carriers.
|
524
|
-
|
525
|
-
### Carrier
|
526
|
-
|
527
|
-
A Workarea application is configured with an ActiveShipping carrier (`ActiveShipping::Carrier`, [docs](http://www.rubydoc.info/gems/active_shipping/1.8.6/ActiveShipping/Carrier)) from which it will request shipping rates using `ActiveShipping::Carrier#find_rates` ([docs](http://www.rubydoc.info/gems/active_shipping/1.8.6/ActiveShipping/Carrier#find_rates-instance_method)). `find_rates` has the following signature.
|
528
|
-
|
529
|
-
```
|
530
|
-
ActiveShipping::Carrier#find_rates(origin, destination, packages, options = {}) â ActiveShipping::RateResponse
|
531
|
-
```
|
532
|
-
|
533
|
-
A rate request therefore requires `origin` and `destination`, which are locations, and a collection of packages. For most carriers, the rate request happens over HTTP. The request returns a response, which, if successful, includes a collection of rate estimates.
|
534
|
-
|
535
|
-
### Workarea Shipping Carrier
|
536
|
-
|
537
|
-
`Workarea.config.gateways.shipping` holds an instance of the currently configured carrier. The default shipping carrier is `ActiveShipping::Workarea`, which implements `find_rates` as follows.
|
538
|
-
|
539
|
-
```
|
540
|
-
Workarea::Shipping::RateLookup.new(origin, destination, packages, options).response
|
541
|
-
```
|
542
|
-
|
543
|
-
This implementation does not require an HTTP request, and the response from `Shipping::RateLookup#response` is always successful. The returned collection of rate estimates is initialized from the set of qualifying shipping services persisted in MongoDB. To determine qualifying shipping services, services are queried by country and region (using the address on the shipping) and by price (using the order subtotal). The services within the intersection of these queries are used to initialize the collection of rate estimates for the response.
|
544
|
-
|
545
|
-
### Location
|
546
|
-
|
547
|
-
An ActiveShipping location (`ActiveShipping::Location`, [docs](http://www.rubydoc.info/gems/active_shipping/1.8.6/ActiveShipping/Location)) represents either the origin or destination location to use during fulfillment of an order.
|
548
|
-
|
549
|
-
The destination location is created from the shipping address, while the origin is created from the attributes held in `Workarea.config.shipping_origin`.
|
550
|
-
|
551
|
-
```
|
552
|
-
Workarea.config.shipping_origin
|
553
|
-
# => {:country=>"US", :state=>"PA", :city=>"Philadelphia", :zip=>"19106"}
|
554
|
-
```
|
555
|
-
|
556
|
-
### Package
|
557
|
-
|
558
|
-
An ActiveShipping package (`ActiveShipping::Package`, [docs](http://www.rubydoc.info/gems/active_shipping/1.8.6/ActiveShipping/Package)) represents a physical package to be delivered as part of order fulfillment. See packaging, below.
|
559
|
-
|
560
|
-
### Response
|
561
|
-
|
562
|
-
An ActiveShipping response (`ActiveShipping::Response`, [docs](http://www.rubydoc.info/gems/active_shipping/1.8.6/ActiveShipping/Response)) represents the response from a carrier for rate estimates. With the exception of the Workarea shipping carrier, the request and response typically occurs over HTTP. The response will indicate success or failure and provide rate estimates.
|
563
|
-
|
564
|
-
### Rate Estimate
|
565
|
-
|
566
|
-
An ActiveShipping rate estimate (`ActiveShipping::RateEstimate`, [docs](http://www.rubydoc.info/gems/active_shipping/1.8.6/ActiveShipping/RateEstimate)) represents a qualified shipping service for the customer to select. During checkout, rate estimates are used to initialize shipping options, which unlike rate estimates, can present adjusted pricing.
|
567
|
-
|
568
|
-
## Sku
|
569
|
-
|
570
|
-
A <dfn>shipping sku</dfn> (`Workarea::Shipping::Sku`) is an [application document](application-document.html) that represents the shipping attributes for a catalog variant (`Workarea::Catalog::Variant`). The `_id` of a shipping sku matches the `sku` of the variant with which it is associated.
|
571
|
-
|
572
|
-
```
|
573
|
-
variant.sku == shipping_sku.id.to_s
|
574
|
-
# => true
|
575
|
-
```
|
576
|
-
|
577
|
-
Without customization, a shipping sku has `weight` and `dimensions` fields. By default, weight is measured in ounces and dimensions are measured in inches. An application can use metric units by changing the ActiveShipping options held in `Workarea.config.shipping_options`.
|
578
|
-
|
579
|
-
```
|
580
|
-
Workarea.config.shipping_options
|
581
|
-
# => { :units => :imperial }
|
582
|
-
```
|
583
|
-
|
584
|
-
The Workarea packaging service finds the shipping sku for each order item within an order to construct one or many packages for the order (or its associated shipping, if multiple shippings).
|
585
|
-
|
586
|
-
## Packaging
|
587
|
-
|
588
|
-
The Workarea <dfn>packaging service</dfn> (Workarea::Packaging) initializes a collection of packages for a given order and shipping. Packages are needed to request rate estimates from an ActiveShipping carrier.
|
589
|
-
|
590
|
-
### Default Implementation
|
591
|
-
|
592
|
-
Without customization, the Workarea checkout service assumes one shipping per order. By default, the packaging service therefore ignores the provided shipping and always returns a collection with a single package representing the entire order.
|
593
|
-
|
594
|
-
The weight and dimensions of the package are derived from the combined weight and dimensions of all items to be included in the package, as stored on the shipping sku that corresponds to each order item. If a shipping sku is not persisted for an item in the order, a new shipping sku (with default values) is used to represent that item in the package.
|
595
|
-
|
596
|
-
If the dimensions of any item in the package are unknown, the value held in `Workarea.config.shipping_dimensions` is used as the dimensions of the package. For this reason, this value should represent the average or standard box size used to fulfill orders.
|
597
|
-
|
598
|
-
```
|
599
|
-
Workarea.config.shipping_dimensions
|
600
|
-
# => [1, 1, 1]
|
601
|
-
```
|
602
|
-
|
603
|
-
The following example demonstrates the process of initializing packages from an order and shipping.
|
604
|
-
|
605
|
-
```
|
606
|
-
Workarea::Catalog::Product.destroy_all
|
607
|
-
product = Workarea::Catalog::Product.create!(
|
608
|
-
name: 'shirt',
|
609
|
-
variants: [{ sku: 'large-shirt' }]
|
610
|
-
)
|
611
|
-
sku = product.variants.first.sku
|
612
|
-
Workarea::Shipping::Sku.destroy_all
|
613
|
-
Workarea::Shipping::Sku.create!(
|
614
|
-
_id: sku,
|
615
|
-
weight: 5.0,
|
616
|
-
dimensions: [11, 9, 2]
|
617
|
-
)
|
618
|
-
Workarea::Order.destroy_all
|
619
|
-
order = Workarea::Order.create!(
|
620
|
-
items: [{
|
621
|
-
product_id: product.id,
|
622
|
-
sku: sku,
|
623
|
-
quantity: '1'
|
624
|
-
}]
|
625
|
-
)
|
626
|
-
Workarea::Shipping.destroy_all
|
627
|
-
shipping = Workarea::Shipping.create!(order_id: order.id)
|
628
|
-
package = Workarea::Packaging.new(order, shipping).packages.first
|
629
|
-
|
630
|
-
package.ounces
|
631
|
-
# => 5.0
|
632
|
-
|
633
|
-
package.inches
|
634
|
-
# => [2, 9, 11]
|
635
|
-
```
|
636
|
-
|
637
|
-
### Extension
|
638
|
-
|
639
|
-
Although it receives a collection of packages, the default shipping carrier ignores them when constructing its list of qualifying rate estimates. However, this is unlikely to be true for other carriers.
|
640
|
-
|
641
|
-
The default packaging logic may be too naive for some applications, but the complexities required to handle all possibilities is beyond the scope of the Workarea platform. Applications using a shipping carrier that relies on packaging may need to decorate the packaging service to implement the logic preferred by the retailer.
|
642
|
-
|
643
|
-
## Service
|
644
|
-
|
645
|
-
A <dfn>shipping service</dfn> (`Workarea::Shipping::Service`) is an [application document](application-document.html) that represents a shipping service by which an order can be fulfilled. A shipping service may represent a specific shipping product, such as _FedEx Ground_, or may represent a more abstract shipping service, such as _Standard Shipping_ or _Free Shipping_.
|
646
|
-
|
647
|
-
The Workarea shipping carrier uses the persisted shipping services to construct a collection of rate estimates, which are then used to initialize shipping options to present to the customer during checkout.
|
648
|
-
|
649
|
-
### Fields
|
650
|
-
|
651
|
-
A shipping service must have a `name`, and may also have values for `carrier`, `service_code`, and `tax_code`.
|
652
|
-
|
653
|
-
```
|
654
|
-
shipping_service.name
|
655
|
-
# => "Media Mail"
|
656
|
-
|
657
|
-
shipping_service.carrier
|
658
|
-
# => "USPS"
|
659
|
-
|
660
|
-
shipping_service.service_code
|
661
|
-
# => "Media Mail Parcel"
|
662
|
-
|
663
|
-
shipping_service.tax_code
|
664
|
-
# => "001"
|
665
|
-
```
|
666
|
-
|
667
|
-
### Rates
|
668
|
-
|
669
|
-
A service embeds many rates representing the base prices of the service. `Shipping::Service#find_rate` finds the lowest qualifying rate for the given amount (typically the order subtotal).
|
670
|
-
|
671
|
-
```
|
672
|
-
standard_shipping_service = Workarea::Shipping::Service.create!(
|
673
|
-
name: 'Standard',
|
674
|
-
rates: [
|
675
|
-
{ price: 5, tier_max: 49.99 },
|
676
|
-
{ price: 10, tier_max: 99.99 },
|
677
|
-
{ price: 15, tier_min: 100 }
|
678
|
-
]
|
679
|
-
)
|
680
|
-
|
681
|
-
standard_shipping_service.find_rate((49.99).to_m).price.to_s
|
682
|
-
# => "5.00"
|
683
|
-
|
684
|
-
standard_shipping_service.find_rate((50.00).to_m).price.to_s
|
685
|
-
# => "10.00"
|
686
|
-
|
687
|
-
standard_shipping_service.find_rate((99.99).to_m).price.to_s
|
688
|
-
# => "10.00"
|
689
|
-
|
690
|
-
standard_shipping_service.find_rate((100.00).to_m).price.to_s
|
691
|
-
# => "15.00"
|
692
|
-
|
693
|
-
standard_shipping_service.find_rate((500.00).to_m).price.to_s
|
694
|
-
# => "15.00"
|
695
|
-
```
|
696
|
-
|
697
|
-
### Querying
|
698
|
-
|
699
|
-
`Shipping::Service.for_location` queries services by country and region, while `Shipping::Service.by_price` queries services by price.
|
700
|
-
|
701
|
-
### By Country & Region
|
702
|
-
|
703
|
-
```
|
704
|
-
Workarea::Shipping::Service.destroy_all
|
705
|
-
Workarea::Shipping::Service.create!(name: 'Standard', rates: [{ price: 5 }])
|
706
|
-
Workarea::Shipping::Service.create!(name: 'Priority', rates: [{ price: 10 }])
|
707
|
-
Workarea::Shipping::Service.create!(name: 'Express', rates: [{ price: 20 }])
|
708
|
-
|
709
|
-
Workarea::Shipping::Service.for_location('US', 'PA').map(&:name)
|
710
|
-
# => ["Standard", "Priority", "Express"]
|
711
|
-
|
712
|
-
standard_shipping_service = Workarea::Shipping::Service.find_by(name: 'Standard')
|
713
|
-
standard_shipping_service.update_attributes!(country: 'US', regions: ['PA'])
|
714
|
-
|
715
|
-
Workarea::Shipping::Service.for_location('US', 'PA').map(&:name)
|
716
|
-
# => ["Standard"]
|
717
|
-
```
|
718
|
-
|
719
|
-
### Services by Price
|
720
|
-
|
721
|
-
```
|
722
|
-
Workarea::Shipping::Service.destroy_all
|
723
|
-
Workarea::Shipping::Service.create!(name: 'Standard', rates: [{ price: 10 }])
|
724
|
-
Workarea::Shipping::Service.create!(name: 'FREE', rates: [{ price: 0 }], subtotal_min: 50)
|
725
|
-
|
726
|
-
Workarea::Shipping::Service.by_price((49.99).to_m).map(&:name)
|
727
|
-
# => ["Standard"]
|
728
|
-
|
729
|
-
Workarea::Shipping::Service.by_price((50.00).to_m).map(&:name)
|
730
|
-
# => ["Standard", "FREE"]
|
731
|
-
|
732
|
-
standard_shipping_service = Workarea::Shipping::Service.find_by(name: 'Standard')
|
733
|
-
standard_shipping_service.update_attributes!(subtotal_max: 49.99)
|
734
|
-
Workarea::Shipping::Service.by_price((49.99).to_m).map(&:name)
|
735
|
-
# => ["Standard"]
|
736
|
-
|
737
|
-
Workarea::Shipping::Service.by_price((50.00).to_m).map(&:name)
|
738
|
-
# => ["FREE"]
|
739
|
-
```
|
740
|
-
|
741
|
-
### Rate
|
742
|
-
|
743
|
-
A <dfn>shipping rate</dfn> (Workarea::Shipping::Rate) is an embedded [application document](application-document.html) that represents a price for its parent shipping service as well as any data that may be used to qualify the rate.
|
744
|
-
|
745
|
-
By default, a rate is qualified by comparing its `tier_min` and `tier_max` to a given amount.
|
746
|
-
|
747
|
-
A rate has a required `price` field that represents a base price for the parent service.
|
748
|
-
|
749
|
-
```
|
750
|
-
shipping_service.rates.first.price.to_s
|
751
|
-
# => "5.00"
|
752
|
-
|
753
|
-
shipping_service.rates.first.tier_max.to_s
|
754
|
-
# => "49.99"
|
755
|
-
```
|
756
|
-
|