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,389 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Order Pricing
|
3
|
-
excerpt: This document provides information to help you develop the skills of explaining and extending order pricing.
|
4
|
-
---
|
5
|
-
|
6
|
-
Order Pricing
|
7
|
-
======================================================================
|
8
|
-
|
9
|
-
To facilitate [orders](orders.html)—transactions between shoppers and retailers, often including [shipping](shipping.html)—Workarea must reliably compute the prices for these transactions.
|
10
|
-
These computations include the price of each order item, potentially adjusted for customizations, overrides, and discounts;
|
11
|
-
and the overall price of the order, including shipping and tax, also potentially adjusted.
|
12
|
-
|
13
|
-
Fortunately, Workarea computes this information automatically and does not require any developer intervention.
|
14
|
-
However, as a developer, you must be prepared to _explain_ the pricing of a specific order or all orders to a retailer.
|
15
|
-
For example, a retailer may ask you why the total price of a particular order was unexpectedly low.
|
16
|
-
Or, you may need to explain why Workarea is computing tax subtotals differently than the retailer's accounting department.
|
17
|
-
Furthermore, you may need to _extend_ the pricing logic for a retailer, perhaps to charge a fee for gift wrapping, or to replace Workarea's tax calculations with those from an integrated service.
|
18
|
-
|
19
|
-
This document provides information to help you develop the skills of __explaining__ and __extending__ order pricing.
|
20
|
-
After reviewing an __example__ order and some shared __context__, you will learn the primary concepts to help you develop these skills.
|
21
|
-
Specifically, to explain _why_ an order is priced as it is, you should work backward from __pricing totals__, which are computed from __price adjustments__ by __pricing totals objects__.
|
22
|
-
To explain _how_ price adjustments are created, you should examine __pricing calculators__.
|
23
|
-
And to _change_ how price adjustments are created, you should implement your own pricing calculators which honor the __pricing calculator contract__, and re-configure the __pricing calculators collection__ to contain your custom calculators.
|
24
|
-
|
25
|
-
We'll explore each of these topics in turn, but first let's make things more concrete with an example.
|
26
|
-
|
27
|
-
|
28
|
-
Example Order
|
29
|
-
----------------------------------------------------------------------
|
30
|
-
|
31
|
-
Throughout this document, we'll use a specific order as a running example.
|
32
|
-
The following diagrams represent Storefront views of this order:
|
33
|
-
|
34
|
-
![Order pricing cart example](../images/order-pricing-cart-example.png)
|
35
|
-
|
36
|
-
![Order pricing placed order example](../images/order-pricing-placed-order-example.png)
|
37
|
-
|
38
|
-
The first diagram represents the order as a cart, while the second represents the same order after a shipping address is provided.
|
39
|
-
Both views of the order include computed pricing information.
|
40
|
-
The top two rows of each diagram represent _item-level_ prices, while the table following the line items represents _order-level_ prices.
|
41
|
-
_All_ of this pricing information is computed repeatedly until the order is placed.
|
42
|
-
|
43
|
-
|
44
|
-
Order Pricing in Context
|
45
|
-
----------------------------------------------------------------------
|
46
|
-
|
47
|
-
The pricing information for each order must be re-computed continually because Workarea's commerce model is cyclical.
|
48
|
-
Shoppers shop and admins manage, changing the states of various domain models.
|
49
|
-
The current states of these models must be reflected in the prices shown to shoppers and authorized on their payments.
|
50
|
-
|
51
|
-
The following diagram (adapted from [Commerce Model](commerce-model.html)) represents this cycle:
|
52
|
-
|
53
|
-
![Order pricing within the commerce model](../images/commerce-model-order-pricing.png)
|
54
|
-
|
55
|
-
Shoppers _create and manage carts_ by adding, removing, and updating order items and promo codes.
|
56
|
-
Shoppers additionally set the shipping address and shipping service within checkout, allowing them to _place the orders_.
|
57
|
-
Simultaneously, admins (and/or automated systems integrated with Workarea) _manage the catalog_ and _merchandise the store_ by manipulating SKU prices, sales, discounts (on items, orders, and shippings), shipping services, and tax rates.
|
58
|
-
|
59
|
-
To account for these ongoing changes, Workarea re-prices each cart before showing it to the shopper, including each checkout screen.
|
60
|
-
Each time a cart is priced, the results are a "snapshot" of the pricing for the transaction at that moment in time.
|
61
|
-
At the conclusion of checkout, when the order is placed, the pricing information is computed one last time and persisted as a permanent record (on the order, items, and shippings).
|
62
|
-
|
63
|
-
Familiarity with this lifecycle is indispensable when developing the skills of explaining and extending order pricing.
|
64
|
-
Let's move on to those specific skills.
|
65
|
-
|
66
|
-
|
67
|
-
Skill: Explaining Order Pricing
|
68
|
-
----------------------------------------------------------------------
|
69
|
-
|
70
|
-
From a system architecture perspective, `Pricing.perform` is the API call responsible for pricing orders.
|
71
|
-
Additionally, when setting the shipping address and shipping service in checkout, a call to `Shipping#set_shipping_service` precedes `Pricing.perform` to initiate pricing.
|
72
|
-
|
73
|
-
However, when a retailer questions the pricing of an order, you can likely trace their inquiry to a specific total or subtotal.
|
74
|
-
They may think the _total price_ of a particular order seems too low or the _tax subtotal_ seems to be off by a cent or two for most orders.
|
75
|
-
Therefore, to explain _why_ an order is priced as it is, you should work backward from __pricing totals__, which are computed from __price adjustments__ by __pricing totals objects__.
|
76
|
-
|
77
|
-
|
78
|
-
### Pricing Totals
|
79
|
-
|
80
|
-
_Pricing totals_ are computed money values stored within fields on each order, its items, and its associated shippings.
|
81
|
-
These fields represent the total price and various subtotals of the order transaction.
|
82
|
-
|
83
|
-
Many of these values are displayed to the shopper directly.
|
84
|
-
Examples are highlighted in the following diagram, which also indicates the underlying API calls to query the values.
|
85
|
-
|
86
|
-
![Totals within order pricing example](../images/order-pricing-example-totals.png)
|
87
|
-
|
88
|
-
There are additional totals fields, which are not shown in the above diagram.
|
89
|
-
For example, the total of each shipping is shown only when an order has multiple shippings.
|
90
|
-
Also, the total _value_ of an order or item is displayed in some Admin screens and used for calculations, such as discounts.
|
91
|
-
|
92
|
-
The following code example queries for _all_ pricing totals for our example order:
|
93
|
-
|
94
|
-
```ruby
|
95
|
-
order_id = '123321'
|
96
|
-
|
97
|
-
order = Workarea::Order.find(order_id)
|
98
|
-
items = order.items
|
99
|
-
shippings = Workarea::Shipping.by_order(order.id).to_a
|
100
|
-
|
101
|
-
puts order.subtotal_price
|
102
|
-
# 250.00
|
103
|
-
puts order.shipping_total
|
104
|
-
# 10.00
|
105
|
-
puts order.tax_total
|
106
|
-
# 2.00
|
107
|
-
puts order.total_price
|
108
|
-
# 202.00
|
109
|
-
puts order.total_value
|
110
|
-
# 190.00
|
111
|
-
|
112
|
-
puts items.first.total_price
|
113
|
-
# 100.00
|
114
|
-
puts items.first.total_value
|
115
|
-
# 76.00
|
116
|
-
puts items.last.total_price
|
117
|
-
# 150.00
|
118
|
-
puts items.last.total_value
|
119
|
-
# 114.00
|
120
|
-
|
121
|
-
puts shippings.first.shipping_total
|
122
|
-
# 10.00
|
123
|
-
puts shippings.first.tax_total
|
124
|
-
# 2.00
|
125
|
-
```
|
126
|
-
|
127
|
-
Querying the pricing totals for an order transaction is an important first step toward explaining the pricing for the order.
|
128
|
-
From a pricing total, you can work backward to specific __price adjustments__, which we explore next.
|
129
|
-
|
130
|
-
|
131
|
-
### Price Adjustments
|
132
|
-
|
133
|
-
_Price adjustments_ are documents embedded within order items and shippings that represent the "raw" pricing data for the order.
|
134
|
-
This data is used to calculate the order totals.
|
135
|
-
It may be helpful to think of the order totals as a credit card receipt which shows only a summary of what was charged to your card, while the price adjustments are collectively the "itemized" receipt with more granular details.
|
136
|
-
|
137
|
-
While most price adjustments are used internally—to compute totals—some are shown directly to shoppers.
|
138
|
-
The following diagram highlights and annotates the values in our placed order example that are read directly from price adjustments.
|
139
|
-
|
140
|
-
![Adjustments within order pricing example](../images/order-pricing-example-adjustments.png)
|
141
|
-
|
142
|
-
To explain the pricing for an order, look up the relevant adjustments.
|
143
|
-
Remember that these are documents embedded within the order's items and shippings.
|
144
|
-
The following code example queries for _all_ price adjustments for our example order:
|
145
|
-
|
146
|
-
```ruby
|
147
|
-
item_price_adjustments = items.map(&:price_adjustments).reduce(&:+)
|
148
|
-
shipping_price_adjustments = shippings.map(&:price_adjustments).reduce(&:+)
|
149
|
-
all_price_adjustments = item_price_adjustments + shipping_price_adjustments
|
150
|
-
|
151
|
-
all_price_adjustments.count
|
152
|
-
# => 10
|
153
|
-
all_price_adjustments.first.class
|
154
|
-
# => Workarea::PriceAdjustment
|
155
|
-
```
|
156
|
-
|
157
|
-
To understand how adjustments become totals, first examine a single price adjustment.
|
158
|
-
Most notably, it has a money `:amount`, either postive or negative, and a `:price`, which you should think of as a price _type_.
|
159
|
-
The price type is always one of `'item'`, `'order'`, `'shipping'`, or `'tax'`, and these are sometimes additionally referred to as "levels" (e.g. item-level vs order-level).
|
160
|
-
The adjustment document also has several metadata fields describing the price, including `:description`.
|
161
|
-
|
162
|
-
Now consider the adjustments in aggregate again.
|
163
|
-
The following diagram creates a visual "stack" of the adjustments for our example order, each with its amount, price type, and description.
|
164
|
-
|
165
|
-
![Price adjustments diagram](../images/price-adjustments-diagram.png)
|
166
|
-
|
167
|
-
To calculate `Order#total_price`, Workarea simply sums _all_ the amounts:
|
168
|
-
|
169
|
-
![Order total price diagram](../images/order-total-price-diagram.png)
|
170
|
-
|
171
|
-
All other order totals (i.e. subtotals) are calculated by summing a _subset_ of the same price adjustments.
|
172
|
-
The logic for each totals field is based on the adjustment price types and the objects on which they are stored.
|
173
|
-
|
174
|
-
For example, `Order#subtotal_price` is calculated by summing only the _item-level_ adjustments.
|
175
|
-
|
176
|
-
![Order subtotal price diagram](../images/order-subtotal-price-diagram.png)
|
177
|
-
|
178
|
-
Similarly, the shipping and tax totals are calculated by summing only the _shipping_ and _tax_ adjustments, respectively:
|
179
|
-
|
180
|
-
![Order shipping total diagram](../images/order-shipping-total-diagram.png)
|
181
|
-
|
182
|
-
![Order tax total diagram](../images/order-tax-total-diagram.png)
|
183
|
-
|
184
|
-
The total price for each _item_ is the sum of the item-level adjustments stored within that particular item.
|
185
|
-
The following diagram represents the total for the second item:
|
186
|
-
|
187
|
-
![Order item total price diagram](../images/order-item-total-price-diagram.png)
|
188
|
-
|
189
|
-
As a final example, the _total value_ of an order is the sum of its item- and order-level adjustments, or explained differently: the value of the _merchandise_, which includes most discounts, but excludes shipping and tax. (Expect a retailer or another developer to ask you about this; it's a common question).
|
190
|
-
|
191
|
-
![Order total value diagram](../images/order-total-value-diagram.png)
|
192
|
-
|
193
|
-
( If you're wondering why items embed both item- and order-level adjustments, or why some adjustments are embedded within shippings instead of items, we'll cover that with __pricing calulators__. )
|
194
|
-
|
195
|
-
The lesson here is each total can be deconstructed into a subset of the order transaction's price adjustments.
|
196
|
-
Recall the recipe for this: work backward from pricing totals, which are computed from price adjustments by __pricing totals objects__.
|
197
|
-
We'll therefore look at pricing totals objects next.
|
198
|
-
|
199
|
-
|
200
|
-
### Pricing Totals Objects
|
201
|
-
|
202
|
-
_Pricing totals objects_ are the objects responsible for calculating and writing the pricing totals to the order, items, and shippings each time an order is priced.
|
203
|
-
They encapsulate the logic for creating each pricing total from the "stack" of price adjustments for a given order and shippings.
|
204
|
-
Therefore, to deconstruct a total into price adjustments, you must look up the logic for that total within a pricing totals object, and reverse it.
|
205
|
-
|
206
|
-
The specific API calls that calculate and write the pricing totals are `OrderTotals#total` and `ShippingTotals#total`.
|
207
|
-
To find the implementations of these methods within your application or plugin, run the following command from your project's root:
|
208
|
-
|
209
|
-
```bash
|
210
|
-
find $(bundle show workarea-core) -path '*/app/*/pricing/*_totals.rb'
|
211
|
-
```
|
212
|
-
|
213
|
-
This command lists the pathnames of the classes where these methods are defined within your project.
|
214
|
-
Open the classes in your editor and locate the code assigning a value to the totals field you are trying to deconstruct.
|
215
|
-
From there, you can see which price adjustments factor into that total.
|
216
|
-
You may want to literally or metaphorically create a diagram like those above that show which of the adjustments contribute to a particular total.
|
217
|
-
|
218
|
-
(
|
219
|
-
Pricing totals objects use a special-purpose collection class, `PriceAdjustmentSet`, to subset and sum adjustments, thus creating totals.
|
220
|
-
These collections are effectively arrays with a few additional methods that encapsulate the logic for subsetting and summing based on the price type of the adjustments.
|
221
|
-
If you find these collections unintuitive, review the class definition and Mongoid extension that provides their behavior.
|
222
|
-
)
|
223
|
-
|
224
|
-
```bash
|
225
|
-
find $(bundle show workarea-core) -path '*/app/*/price_adjustment_*.rb'
|
226
|
-
```
|
227
|
-
|
228
|
-
After you've identified specific price adjustments, look at them more closely.
|
229
|
-
In addition to amount, price (type), and description, each adjustment has the additional fields `:calculator` and `:data`:
|
230
|
-
|
231
|
-
```ruby
|
232
|
-
sample_price_adjustment = all_price_adjustments.sample
|
233
|
-
|
234
|
-
sample_price_adjustment.calculator
|
235
|
-
# => "Workarea::Pricing::Calculators::ItemCalculator"
|
236
|
-
|
237
|
-
sample_price_adjustment.data
|
238
|
-
# => {"on_sale"=>true, "original_price"=>125.0, "tax_code"=>"simple"}
|
239
|
-
```
|
240
|
-
|
241
|
-
The `:calculator` field indentifies the class of object that created the adjustment when the order was last priced.
|
242
|
-
That calculator determined the amount and price of the adjustment, and wrote the adjustment's description and additional metadata, which it stored in the adjustment's `:data` field.
|
243
|
-
These details may provide enough information to answer the retailer's question about the order's pricing.
|
244
|
-
When these details are _not_ enough, you'll have to dig deeper to explore _how_ the price adjustment was created.
|
245
|
-
|
246
|
-
As the name of the `:calculator` field implies, price adjustments are created by __pricing calculators__.
|
247
|
-
|
248
|
-
|
249
|
-
### Pricing Calculators
|
250
|
-
|
251
|
-
_Pricing calculators_ are objects that _adjust_ the pricing of an order transaction by creating price adjustments on the items and shippings during the pricing of the order.
|
252
|
-
More specifically, each calculator inherits from `Pricing::Calculator` and implements `Pricing::Calculator#adjust`.
|
253
|
-
This method encapsulates the logic for creating the price adjustments the calculator is responsible for.
|
254
|
-
|
255
|
-
During the pricing of an order, each calculator is given the opportunity to adjust the order pricing by writing adjustments to the items and shippings.
|
256
|
-
This process is managed by `Pricing.perform`, which begins by clearing all price adjustments from the order's items and shippings.
|
257
|
-
(There is one type of adjustment that isn't cleared, for historical reasons, which is the adjustment that shippings write to themselves, outside of `Pricing.perform`.
|
258
|
-
These adjustments represent the price of the shipping service for each shipping.)
|
259
|
-
`Pricing.perform` then calls `#adjust` on each pricing calculator, providing it the opportunity to create price adjustments on the items and shippings.
|
260
|
-
This process builds the price adjustment stack that you've seen many times above.
|
261
|
-
|
262
|
-
The following diagram illustrates this process for our example order.
|
263
|
-
The order has two items and one shipping.
|
264
|
-
The example shown represents the final pricing of the order, during the "place order" action.
|
265
|
-
The pricing process begins with a single price adjustment on the shipping.
|
266
|
-
Each calculator then has the opportunity to adjust the pricing; some do nothing while other create adjustments (which are highlighted).
|
267
|
-
The end result is the familiar stack of price adjustments used to calculate the pricing totals.
|
268
|
-
|
269
|
-
![Pricing calculators diagram](../images/pricing-calculators-diagram.png)
|
270
|
-
|
271
|
-
It's important to understand this overall process because each calculator has access to the adjustments created by the calculators that precede it.
|
272
|
-
Knowledge of the process therefore helps you understand each calculator's implementation of `#apply`, which are not explained in this document.
|
273
|
-
Some of these implementations are quite complex and defer to other subsystems, such as discounts and taxes.
|
274
|
-
Until each of these implementations can be sufficiently documented, you'll need to explore them on your own.
|
275
|
-
|
276
|
-
The following command prints the pathnames of all pricing calculators available to your application:
|
277
|
-
|
278
|
-
```bash
|
279
|
-
find $(pwd) $(bundle show --paths | grep workarea) \
|
280
|
-
-path '*/app/*/pricing/calculators/*.rb'
|
281
|
-
```
|
282
|
-
|
283
|
-
Plugins and applications can also provide their own pricing calculators, which is the basis of __extending order pricing__.
|
284
|
-
|
285
|
-
|
286
|
-
Skill: Extending Order Pricing
|
287
|
-
----------------------------------------------------------------------
|
288
|
-
|
289
|
-
Sometimes, the business requirements of a retailer require you to do more than _explain_ order pricing; you must _extend_ it.
|
290
|
-
A retailer may add a new feature that affects pricing, such as offering gift wrapping for a fee; or they may want to replace an existing feature, such as using an integrated service to calculate taxes rather than Workarea's default logic.
|
291
|
-
|
292
|
-
Fortunately, for requirements such as these, Workarea provides a clear path for extension.
|
293
|
-
To extend pricing, you must change how price adjustments are created.
|
294
|
-
To do this, you should implement your own pricing calculators which honor the __pricing calculator contract__, and re-configure the __pricing calculators collection__ to include your custom calculators.
|
295
|
-
|
296
|
-
(
|
297
|
-
It's worth mentioning that you should first look for a [plugin](https://plugins.workarea.com) that does what you need.
|
298
|
-
I borrowed this document's use cases from existing plugins.
|
299
|
-
)
|
300
|
-
|
301
|
-
|
302
|
-
### Pricing Calculator Contract
|
303
|
-
|
304
|
-
To create your own pricing calculator, define a class which satisfies the _pricing calculator contract_.
|
305
|
-
Fundamentally, this is a class which includes `Pricing::Calculator` and implements `Pricing::Calculator#apply`.
|
306
|
-
|
307
|
-
(
|
308
|
-
I'll continue to explain this process conceptually, but for a more detailed, procedural explanation of creating your own pricing calculators, see [Add or Replace a Pricing Calculator](add-or-replace-a-pricing-calculator.html).
|
309
|
-
)
|
310
|
-
|
311
|
-
`Pricing::Calculator#apply` has access to several objects and collections via the methods `#order`, `#shippings`, `#pricing`, and `#discounts`; and it must satisfy two responsibilities: determine which objects should receive the price adjustments, and create the price adjustments on those objects.
|
312
|
-
|
313
|
-
To determine the objects, start with this simple rule: create _item_ and _order_ adjustments on _items_, and create _shipping_ and _tax_ adjustments on _shippings_.
|
314
|
-
This rule follows the logic of the Core calculators, which write shipping and tax adjustments to shippings because those adjustments require a shipping address to compute.
|
315
|
-
However, your calculator may need to look for _specific_ items and shippings.
|
316
|
-
For example, the customizations calculator creates adjustments for only those items that include customizations.
|
317
|
-
Adjustments to the entire order, say _$50 off your entire order_, must be distributed across the items, since the order has no price adjustments of its own.
|
318
|
-
Also, the retailer likely wants the cost distributed in the case of a customer returning a single item.
|
319
|
-
|
320
|
-
To create the adjustments, use `Order::Item#adjust_pricing` or `Shipping#adjust_pricing`, and provide the following `PriceAdjustment` attributes:
|
321
|
-
|
322
|
-
| Attribute | Description |
|
323
|
-
| -------------- | ----------- |
|
324
|
-
| `:amount` | The money amount which may be displayed and will contribute to pricing totals |
|
325
|
-
| `:price` | The type of adjustment, either `'item'`, `'order'`, `'shipping'`, or `'tax'`, which determines to which totals the amount contributes and where it's displayed |
|
326
|
-
| `:description` | A brief description of the adjustment, which may display directly to shoppers |
|
327
|
-
| `:calculator` | The class of your calculator, as a string |
|
328
|
-
| `:data` | A hash of additional data for audit and/or implementation purposes; see base calculators for examples |
|
329
|
-
|
330
|
-
After creating a calculator that meets these requirements, you must manipulate the __pricing calculators collection__ to include your calculator.
|
331
|
-
|
332
|
-
|
333
|
-
### Pricing Calculators Collection
|
334
|
-
|
335
|
-
The _pricing calculators collection_ is a configurable value—a [SwappableList](swappable-list-data-structure.html)—which holds the ordered list of pricing calculators which can adjust the pricing of orders during each `Pricing.perform`.
|
336
|
-
|
337
|
-
In other words, the list of which pricing calculators run, in which order, is configurable.
|
338
|
-
The following code example queries the current configuration of an application:
|
339
|
-
|
340
|
-
```ruby
|
341
|
-
Workarea.config.pricing_calculators.class
|
342
|
-
# => Workarea::SwappableList
|
343
|
-
|
344
|
-
puts Workarea.config.pricing_calculators
|
345
|
-
# Workarea::Pricing::Calculators::ItemCalculator
|
346
|
-
# Workarea::Pricing::Calculators::CustomizationsCalculator
|
347
|
-
# Workarea::Pricing::Calculators::OverridesCalculator
|
348
|
-
# Workarea::Pricing::Calculators::DiscountCalculator
|
349
|
-
# Workarea::Pricing::Calculators::TaxCalculator
|
350
|
-
```
|
351
|
-
|
352
|
-
You must modify this list to include your custom pricing calculator.
|
353
|
-
Use the methods of [SwappableList](swappable-list-data-structure.html) to insert your calculator before or after an existing calculator, or to replace an existing calculator.
|
354
|
-
You should _replace_ a calculator when you want to _change_ how its price adjustments are created, like using a tax service integration to create tax adjustments, rather than Workarea's tax subsystem.
|
355
|
-
In contrast, _insert_ your calculator to add an _additional_ upcharge for a feature, such as gift wrapping.
|
356
|
-
|
357
|
-
When inserting a new calculator, its position in the list is important.
|
358
|
-
The default calculator order obeys the following logic:
|
359
|
-
|
360
|
-
1. Start with a subtotal for each item
|
361
|
-
2. Add the cost of any customizations (e.g. engraving)
|
362
|
-
3. Reduce the item or order cost according to order-specific overrides (e.g. a customer service credit)
|
363
|
-
4. Apply discounts
|
364
|
-
5. Calculate tax
|
365
|
-
|
366
|
-
You should not change the sequence of the default calculators, since they depend on this order.
|
367
|
-
For example, an item subtotal must be present before an override can reduce its price, and all other prices must be determined before tax can be calculated.
|
368
|
-
When inserting a new calculator, determine where it fits into this logic.
|
369
|
-
In most cases, a new calculator is added to create an additional upcharge, and should therefore be inserted after the customizations calculator (which performs a similar function).
|
370
|
-
However, review the logic above, and determine where your calculator fits.
|
371
|
-
|
372
|
-
|
373
|
-
Summary
|
374
|
-
----------------------------------------------------------------------
|
375
|
-
|
376
|
-
Workarea handles the complication of computing order prices, but you should develop the skills of explaining and extending order pricing.
|
377
|
-
Both skills depend on a knowledge of Workarea's cycle of commerce, which requires all orders to be continually re-priced until they are placed.
|
378
|
-
|
379
|
-
To explain a cart or placed order's pricing, start from one or more pricing totals, which are money fields on the order, items, and shippings.
|
380
|
-
Deconstruct those fields back into price adjustments, documents embedded in items and shippings that represent the raw pricing data for that order.
|
381
|
-
To do so, look at the implementations of the pricing totals objects, specifically the `#total` method, which encapsulates the logic to go from adjustments to totals.
|
382
|
-
Examine the fields of the price adjustments, and attempt to explain the order's pricing from that data.
|
383
|
-
If insufficient, use the meta data on the price adjustments to identify which pricing calculators created them.
|
384
|
-
Study the implementation of `#apply` for each calculator to see in more detail how each price was created.
|
385
|
-
|
386
|
-
To extend the pricing logic, define your own pricing calculators, each of which must implement an `#apply` method that creates price adjustments on zero or more of the items and shippings that make up an order.
|
387
|
-
Ensure that each price adjustment has an amount, price, and metadata such as description and calculator.
|
388
|
-
Include each of your pricing calculators in the configurable pricing calculators collection, either as a new calculator or as a replacement for an existing calculator.
|
389
|
-
Always preserve the order of the default calculators, while placing new calculators in a logical postion within the collection.
|
@@ -1,210 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Orders & Items
|
3
|
-
excerpt: Orders are transactions between consumers and the retailer. Consumers create orders in the Storefront, as carts, to which they add items (and optionally promo codes). Consumers complete checkouts, thereby placing their orders. The placed orders, which
|
4
|
-
---
|
5
|
-
|
6
|
-
# Orders & Items
|
7
|
-
|
8
|
-
[Orders](orders.html) are transactions between consumers and the retailer. Consumers create orders in the Storefront, as carts, to which they add items (and optionally promo codes). Consumers complete checkouts, thereby placing their orders. The placed orders, which act as permanent records of the transactions, are accessible to the retailer through the Admin.
|
9
|
-
|
10
|
-
The `Order` class (which is also a module/namespace) is the primary model representing these transactions. Each order [document](application-document.html) represents an order through its entire life cycle, from cart through order management. An order model therefore fulfills the roles of purchase order, invoice, and detailed receipt for a transaction.
|
11
|
-
|
12
|
-
The `Order` model and its embedded items identify the consumer and the items that make up the transaction and their prices. More specifically, a placed order is composed of the following data:
|
13
|
-
|
14
|
-
- The identity of the consumer and their environment
|
15
|
-
- One or more items, each composed of:
|
16
|
-
- A SKU, quantity, and additional details to identify and price the item
|
17
|
-
- One or more price adjustments representing granular pricing details
|
18
|
-
- The calculated item-level price totals
|
19
|
-
- Zero or more promo codes, which may affect item and order pricing
|
20
|
-
- The calculated order-level price totals
|
21
|
-
|
22
|
-
## Consumer & Environment
|
23
|
-
|
24
|
-
Each order stores information identifying the consumer, who is either a guest, a user, an admin guest browsing, or an admin impersonating a user.
|
25
|
-
|
26
|
-
At a minimum, a placed order has an email:
|
27
|
-
|
28
|
-
```
|
29
|
-
order = Workarea::Order.sample
|
30
|
-
# => #<Workarea::Order _id: 39F628D36D, ... >
|
31
|
-
|
32
|
-
order.email
|
33
|
-
# => "bobbyclams@workarea.com"
|
34
|
-
```
|
35
|
-
|
36
|
-
An order may have additional contextual information, such as the consumer’s IP address and an order _source_, such as `'storefront'`, `'admin'`, or `'api'`:
|
37
|
-
|
38
|
-
```
|
39
|
-
order.ip_address
|
40
|
-
# => "127.0.0.1"
|
41
|
-
|
42
|
-
order.source
|
43
|
-
# => "storefront"
|
44
|
-
```
|
45
|
-
|
46
|
-
Orders placed by users, admins impersonating users, and admins guest browsing will additionally store the IDs of both users as the `user_id` and `checkout_by_id`. These values are foreign keys that relate the order to `User` models. Similarly, orders placed through a web browser store the `user_activity_id`, which relates the order to a `UserActivity` model<sup><a href="#notes" id="note-1-context">[1]</a></sup>.
|
47
|
-
|
48
|
-
```
|
49
|
-
order.user_id
|
50
|
-
# => "5ab2b5b3eefbfe12dbb4b44b"
|
51
|
-
|
52
|
-
order.user_activity_id
|
53
|
-
# => "5ab2b5b3eefbfe12dbb4b44b"
|
54
|
-
|
55
|
-
order.checkout_by_id
|
56
|
-
# => "5ab2b5b3eefbfe12dbb4b44b"
|
57
|
-
```
|
58
|
-
|
59
|
-
Additional details about the consumer, such as name and shipping and billing addresses, are stored on other models and are not a concern of the `Order` model.
|
60
|
-
|
61
|
-
## Items
|
62
|
-
|
63
|
-
Each order contains _items_, an embedded collection of type `Order::Item`.
|
64
|
-
|
65
|
-
```
|
66
|
-
order.items.count
|
67
|
-
# => 2
|
68
|
-
|
69
|
-
order.items.first.class
|
70
|
-
# => Workarea::Order::Item
|
71
|
-
```
|
72
|
-
|
73
|
-
Each item document contains the data the retailer needs to fulfill the item (SKU, quantity, and customizations), additional data to calculate the price(s) of the item (SKU details), and records of the actual prices calculated (price adjustments and item totals).
|
74
|
-
|
75
|
-
### SKU, Quantity & Details
|
76
|
-
|
77
|
-
Each item represents a good or service from the retailer’s catalog, identified by its _SKU_. Typically, the SKU and quantity provide the minimum data required to fulfill the item. However, some items allow customization by the consumer (for example engraving or monogramming), in which case additional data is collected to perform the customization during fulfillment.
|
78
|
-
|
79
|
-
```
|
80
|
-
item = order.items.first
|
81
|
-
# => #<Workarea::Order::Item _id: 5ab2b5eceefbfe12dbb4b451, ... >
|
82
|
-
|
83
|
-
item.sku
|
84
|
-
# => "524376751-4"
|
85
|
-
|
86
|
-
item.quantity
|
87
|
-
# => 1
|
88
|
-
|
89
|
-
item.customizations
|
90
|
-
# => {}
|
91
|
-
```
|
92
|
-
|
93
|
-
In most cases, additional details are saved on the item to ensure the item is priced accurately. The pricing subsystem uses a series of calculators to determine the total price of each item and the order overall. These calculators often depend on the additional item details to calculate pricing as expected. These details include the product ID and attributes (the entire product model, serialized), the categories in which the product appears, and whether the item is discountable.
|
94
|
-
|
95
|
-
```
|
96
|
-
item.product_id
|
97
|
-
# => "66BC7BEA53"
|
98
|
-
|
99
|
-
pp item.product_attributes.keys
|
100
|
-
# ["_id",
|
101
|
-
# "tags",
|
102
|
-
# "active",
|
103
|
-
# "subscribed_user_ids",
|
104
|
-
# "details",
|
105
|
-
# "filters",
|
106
|
-
# "template",
|
107
|
-
# "purchasable",
|
108
|
-
# "name",
|
109
|
-
# "digital",
|
110
|
-
# "description",
|
111
|
-
# "slug",
|
112
|
-
# "updated_at",
|
113
|
-
# "created_at",
|
114
|
-
# "variants"]
|
115
|
-
|
116
|
-
pp item.category_ids
|
117
|
-
# ["5ab2b04beefbfe1185011c9d",
|
118
|
-
# "5ab2b04beefbfe1185011c9f",
|
119
|
-
# "5ab2b04beefbfe1185011c9b"]
|
120
|
-
|
121
|
-
item.discountable
|
122
|
-
# => true
|
123
|
-
```
|
124
|
-
|
125
|
-
The forthcoming guide, “Managing Carts”, will describe API calls for fetching these details and storing them on the order item.
|
126
|
-
|
127
|
-
### Price Adjustments
|
128
|
-
|
129
|
-
Each time an order is priced, the granular pricing details are stored on the item as _price adjustments_, an embedded collection of type `Workarea::PriceAdjustment`. These embedded documents provide the necessary details to determine the total price of an item (in the case of a cart) and a record of how that price was determined (in the case of a placed order).
|
130
|
-
|
131
|
-
```
|
132
|
-
item.price_adjustments.count
|
133
|
-
# => 2
|
134
|
-
|
135
|
-
price_adjustment = item.price_adjustments.last
|
136
|
-
# => #<Workarea::PriceAdjustment _id: 5ab2b0a2eefbfe11850123f2, ... >
|
137
|
-
|
138
|
-
price_adjustment.amount.to_f
|
139
|
-
# => -8.32
|
140
|
-
|
141
|
-
price_adjustment.description
|
142
|
-
# => "10% Off Order"
|
143
|
-
```
|
144
|
-
|
145
|
-
Item pricing is volatile; prices fluctuate and vary based on quantity, sales, discounts, and other factors. The unit price of an item and the adjustments that may apply due to active discounts and other factors are likely to change from order to order, and may even change within the lifespan of a single cart. Therefore, each order is continually re-priced until it is placed.
|
146
|
-
|
147
|
-
While the details of order pricing and price adjustments are outside the scope of this guide, one detail is notable here: order items and [shippings](shipping.html) are the only models that embed price adjustments. All _order_ and _item_ adjustments are stored on an order’s _items_, while all _shipping_ and _tax_ adjustments are stored on the _shippings_ related to the order.
|
148
|
-
|
149
|
-
### Item Totals
|
150
|
-
|
151
|
-
Additionally, each time an order is priced, the total price and value<sup><a href="#notes" id="note-2-context">[2]</a></sup> of each item are written onto the item as fields. These values provide a snapshot of the “agreed upon” price of the item, as calculated by the pricing module. The consumer can metaphorically “negotiate” this price by shopping at a different time (during a sale or promotion) or applying promo codes to the order.
|
152
|
-
|
153
|
-
In the case of a cart, these values may change before the order is placed. The values are displayed to the consumer when viewing the cart and throughout checkout. In the case of a placed order, these represent the price at which the item sold, which may differ for another consumer purchasing the same item or the same consumer when placing a different order.
|
154
|
-
|
155
|
-
```
|
156
|
-
item.total_price.to_f
|
157
|
-
# => 83.24
|
158
|
-
|
159
|
-
item.total_value.to_f
|
160
|
-
# => 74.92
|
161
|
-
```
|
162
|
-
|
163
|
-
## Promo Codes
|
164
|
-
|
165
|
-
Returning to the order, in addition to items, consumers can add promo codes, which may qualify the order or its items for discounts, resulting in more favorable pricing for the consumer. Unlike items, which are embedded documents, promo codes are simply strings stored in an array on the order.
|
166
|
-
|
167
|
-
```
|
168
|
-
order.promo_codes
|
169
|
-
# => ["10PERCENTOFF"]
|
170
|
-
```
|
171
|
-
|
172
|
-
The order model provides API calls to add promo codes, which ensure the collection contains only unique, uppercase string values. The forthcoming “Managing Carts” guide will cover this topic.
|
173
|
-
|
174
|
-
## Order Totals
|
175
|
-
|
176
|
-
Similarly to item totals, when the pricing module prices an order, it writes the order-level totals to the order as fields. For a cart, these values represent the last calculated “asking price” of the order, and for a placed order they represent the final transaction prices. The Storefront displays these values in the cart and checkout for the consumer, and the Admin displays these values to the retailer in the order administration screens and reports.
|
177
|
-
|
178
|
-
```
|
179
|
-
order.subtotal_price.to_f
|
180
|
-
=> 153.23
|
181
|
-
|
182
|
-
order.shipping_total.to_f
|
183
|
-
=> 7.0
|
184
|
-
|
185
|
-
order.tax_total.to_f
|
186
|
-
=> 10.14
|
187
|
-
|
188
|
-
order.total_price.to_f
|
189
|
-
=> 155.05
|
190
|
-
|
191
|
-
order.total_value.to_f
|
192
|
-
=> 137.91
|
193
|
-
```
|
194
|
-
|
195
|
-
While the full details of pricing are outside the scope of this guide, note that subtotal price is derived from the price adjustments stored on the _items_, while the shipping and tax totals are derived from the price adjustments stored on the related _shippings_.
|
196
|
-
|
197
|
-
## Summary
|
198
|
-
|
199
|
-
- Orders build and record consumer/retailer transactions, which contain the consumer’s identity, the items being transacted, and the “current” pricing as calculated by the pricing subsystem
|
200
|
-
- Each item on an order contains the SKU and quantity, along with other details to accurately price the item
|
201
|
-
- Consumers can add promo codes to the order, which may also affect pricing
|
202
|
-
- Pricing is recorded on each item as granular price adjustments and calculated item-level totals, and on the order as calculated order-level totals
|
203
|
-
|
204
|
-
## Notes
|
205
|
-
|
206
|
-
[1] User activity is an aspect of the Workarea recommendations subsystem that will be covered in more detail in future documentation.
|
207
|
-
|
208
|
-
[2] Upcoming pricing documentation will describe the concept of price vs value.
|
209
|
-
|
210
|
-
|
@@ -1,66 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Orders
|
3
|
-
excerpt: 'Workarea applications facilitate orders: transactions between consumers and retailers. Due to their complexity, orders are enabled by and recorded across many models within the Workarea platform. More specifically, various models within the Order, Shi'
|
4
|
-
---
|
5
|
-
|
6
|
-
# Orders
|
7
|
-
|
8
|
-
Workarea applications facilitate <dfn>orders</dfn>: transactions between consumers and retailers. Due to their complexity, orders are enabled by and recorded across many models within the Workarea platform. More specifically, various models within the `Order`, `Shipping`, `Payment`, `Pricing`, `Inventory`, and `Fulfillment` modules enable and record these transactions.
|
9
|
-
|
10
|
-
However, at the core of each of these transaction is an `Order` model. The order model uniquely identifies the transaction, and using its `id`, you can join the various models, providing a complete record of the transaction.
|
11
|
-
|
12
|
-
## Seeding Order Data
|
13
|
-
|
14
|
-
Workarea provides [seeds](seeds.html) for orders, which are defined in `Workarea::OrdersSeeds`. This seeds script creates a variety of placed orders, as well as the user, shipping, and payment data needed to place those orders.
|
15
|
-
|
16
|
-
Each order is placed through <dfn>checkout</dfn>, a process that joins an order with the other models necessary to represent a complete consumer/retailer transaction.
|
17
|
-
|
18
|
-
Finally, the script _fulfills_ each order, which involves capturing the associated payment and marking the items shipped.
|
19
|
-
|
20
|
-
## Joining Order Data
|
21
|
-
|
22
|
-
Using the first seeded order as its subject, the following example demonstrates how you can join an order model with the corresponding shippings, payment, inventory transactions, and fulfillment. In practice, this sort of in-application join is typically performed in a [view model](view-models.html).
|
23
|
-
|
24
|
-
```
|
25
|
-
order = Workarea::Order.first
|
26
|
-
|
27
|
-
shippings = Workarea::Shipping.where(order_id: order.id).to_a
|
28
|
-
# => [#<Workarea::Shipping _id: 5a95ab0707dd423bb63a92d0, ...>]
|
29
|
-
|
30
|
-
payment = Workarea::Payment.find(order.id)
|
31
|
-
# => #<Workarea::Payment _id: 048E031F8B, ...>
|
32
|
-
|
33
|
-
inventory_transactions =
|
34
|
-
Workarea::Inventory::Transaction.where(order_id: order.id).to_a
|
35
|
-
# => [#<Workarea::Inventory::Transaction _id: 5a95ab0a07dd423bb63a931, ...>]
|
36
|
-
|
37
|
-
fulfillment = Workarea::Fulfillment.find(order.id)
|
38
|
-
# => #<Workarea::Fulfillment _id: 048E031F8B, ...>
|
39
|
-
```
|
40
|
-
|
41
|
-
## The Order Module
|
42
|
-
|
43
|
-
As you can see in the example above, the `id` of the Order model is what relates the various models. Central to order modeling is the `Order` module and its primary models: `Order` and `Order::Item`.
|
44
|
-
|
45
|
-
The following order module topics are pertinent to Workarea application and plugin developers:
|
46
|
-
|
47
|
-
- [The _order_ and _order item_ abstractions](orders-and-items.html)
|
48
|
-
- What they represent
|
49
|
-
- How they are structured
|
50
|
-
- Order statuses and states
|
51
|
-
- Managing carts
|
52
|
-
- Indexing and searching for orders
|
53
|
-
- Managing placed orders
|
54
|
-
- Exporting orders
|
55
|
-
- Canceling orders
|
56
|
-
- Copying orders
|
57
|
-
- Order reporting and insights
|
58
|
-
- Extending orders
|
59
|
-
|
60
|
-
## Summary
|
61
|
-
|
62
|
-
- Orders are transactions between consumers and retailers, which are represented by various models within the Workarea platform
|
63
|
-
- The model central to a consumer/retailer transaction is `Order`; its `id` joins the other models
|
64
|
-
- The platform provides seeds to bootstrap an environment with placed orders
|
65
|
-
- Forthcoming guides will explain the order and item abstractions and the various uses of orders within the platform
|
66
|
-
|