Skip to content

Product Offer

First-Pass Node Dossier

This page is an evidence-backed node dossier generated from the domain hierarchy and node questionnaire.

What It Is

ProductOffer is the main framework-owned pricing record for a product. It stores the sellable price inputs, targeting rules, and inventory-location context used to decide whether a shopper or order can buy a product at a given price.

Parent hierarchy:

  • Pricing & Promotions
  • Offer Resolution
  • Product Offer

Primary implementation paths:

  • packages/framework/src/Models/ProductOffer.php
  • packages/framework/src/Actions/ProductOffer
  • packages/framework/src/Http/Controllers/Api/Admin/ProductOffersController.php
  • packages/framework/src/Actions/Product/GetAvailableProductOffers.php
  • packages/storefront/src/Livewire/Storefront/Product/OfferBlock.php

What Users Can Do With It

Direct capabilities

Operators and integrations can:

  • create, update, list, and delete product offers through the admin API
  • export manufacturer-scoped offer data through Excel
  • synchronize offer data from ERP
  • inspect the currently available offers for a product in internal order-entry flows

Indirect capabilities

Other workflows consume product offers without exposing a packaged settings screen:

  • storefront product pricing resolves from available product offers
  • cart and order recalculation select the best eligible product offer
  • featured-offer calculation snapshots the best public or pro-deal offer by state and quantity
  • price history is logged when a product offer's current price changes

Where It Is Managed

ChannelRoleNotes
Admin APIDirectCRUD and list/filter operations live in ProductOffersController
Excel exportDirect read-onlyProduct offers can be exported by manufacturer
ERP bridgeDirectProduct offers sync from ERP DTOs
Admin order-entry dialogsDirect read-onlyOperators can inspect available offers while adding an item to an order
Storefront product pricingIndirectProduct and cart pricing resolve from available offers
Storefront offer APIDirect read-onlyDeprecated storefront API can still list offers for a product

Sources:

  • packages/framework/src/Http/Controllers/Api/Admin/ProductOffersController.php
  • packages/admin/src/Livewire/Admin/Tools/Excel/ExportDialog/ProductOffersExport.php
  • packages/framework/src/Actions/ErpBridge/ProductOffer/SyncModelsFromErp.php
  • packages/admin/src/Livewire/Admin/Order/Items/AddItemToOrder/ProductOffersDialog.php
  • packages/storefront/src/Livewire/Storefront/Product/OfferBlock.php
  • packages/framework/src/Http/Controllers/Api/Storefront/ProductsController.php

Channel-Level Field Coverage

Admin create and update actions

The inspected product-offer create and update actions validate and accept:

  • product_inventory_item_id
  • product_inventory_location_id
  • customer_id
  • regular_price
  • sale_price
  • msrp_price
  • date_on_sale_from
  • date_on_sale_to
  • min_quantity
  • shipping_addresses
  • billing_addresses
  • states
  • countries
  • shipping_postal_codes

Sources:

  • packages/framework/src/Actions/ProductOffer/CreateProductOffer.php
  • packages/framework/src/Actions/ProductOffer/UpdateProductOffer.php

Admin API list shaping

The admin index request supports:

  • sorts by regular_price, sale_price, current_price, product_id, markup, margin_percentage, and product SKU
  • includes for product, taxonomy context, vendor, shipping-zone count, and price-history count
  • filters for product, custom-price, price-zone, SKU, manufacturer, category, type, inventory items, stock, customer eligibility, and margin/cost health

Sources:

  • packages/framework/src/Actions/ProductOffer/Requests/Admin/IndexRequest.php

Model fields that exist but were not confirmed in a packaged direct-edit UI

Important model-level fields include:

  • price_type
  • except_zips
  • target_price
  • price_rule_id
  • price_zone_id
  • custom_price_id
  • customer_group_ids
  • weighted_cost
  • custom
  • on_hold
  • currency
  • special_cost
  • extra_attributes

Source:

  • packages/framework/src/Models/ProductOffer.php

Configuration And Data Model

Key model characteristics:

  • soft-deletable
  • ERP-syncable
  • geographical
  • price-history aware
  • availability-aware through targeting traits

Important field groups:

Field GroupPurpose
product linkageproduct_id, product_inventory_item_id, product_inventory_location_id, product_vendor_id
pricing inputsregular_price, sale_price, msrp_price, current_price, target_price, weighted_cost, cost
targetingcustomer, customer groups, countries, states, postal codes, shipping and billing addresses
commercial stateprice_type, min_quantity, custom, on_hold

Calculation behavior:

  • Calculate runs latitude/longitude, current price, cost, markup, and margin-percentage recalculation
  • current price falls back to regular price unless a better sale price exists
  • current-price changes log a PriceHistory entry

Sources:

  • packages/framework/src/Models/ProductOffer.php
  • packages/framework/src/Actions/ProductOffer/Calculate.php
  • packages/framework/src/Actions/ProductOffer/CalculateCurrentPrice.php
  • packages/framework/src/Actions/ProductOffer/CalculateCost.php
  • packages/framework/src/Actions/ProductOffer/CalculateMarkup.php
  • packages/framework/src/Actions/ProductOffer/CalculateMarginPercentage.php

Relationships

ProductOffer directly relates to:

  • product
  • productInventoryItem
  • productInventoryItems
  • productInventoryLocation
  • productVendor
  • customer
  • customers
  • customerGroups
  • shippingPostalCodes
  • states
  • countries
  • shippingAddresses
  • billingAddresses
  • shippingZones
  • orderItems
  • priceHistories

Source:

  • packages/framework/src/Models/ProductOffer.php

Rules And Downstream Effects

Important rules and effects:

  • offer availability is filtered by customer, inventory location, shipping postal code, shipping address, billing address, and minimum quantity
  • stock-aware offer resolution prefers in-stock offers, then falls back to backorder-capable offers
  • storefront and cart best-offer resolution sorts by current_price, and can further sort by closest inventory distance when inventory items are loaded
  • current-price changes create PriceHistory rows
  • offer creation recalculates the offer itself, but featured-offer recalculation is dispatched later from offer updates, deletes, restores, force deletes, and offer-inventory pivot changes because the initial create event fires before inventory items are attached

Sources:

  • packages/framework/src/Actions/Product/GetAvailableProductOffersQuery.php
  • packages/framework/src/Actions/Product/GetAvailableProductOffers.php
  • packages/framework/src/Actions/ProductOffer/CalculateCurrentPrice.php
  • packages/framework/src/Actions/Cart/Pipes/OffersAvailabilityCheck.php
  • packages/framework/src/Observers/ProductOfferObserver.php
  • packages/framework/src/Models/ProductOfferProductInventoryItem.php

Integrations And Automation

Excel

The packaged Excel surface provides a manufacturer-scoped product offers workbook for audit and review.

Source:

  • packages/admin/src/Livewire/Admin/Tools/Excel/ExportDialog/ProductOffersExport.php
  • packages/framework/src/Actions/Exports/ProductOffer/ProductOfferTemplateExport.php
  • packages/framework/src/Actions/Exports/ProductOffer/Sheets/ProductOfferSheet.php

ERP bridge

Product offers have a real DTO-backed ERP sync flow.

Sources:

  • packages/framework/src/Actions/ErpBridge/ProductOffer/SyncModelsFromErp.php
  • packages/framework/src/Actions/ErpBridge/ProductOffer/UpdateOrCreateModelFromDTO.php
  • packages/framework/src/Services/ErpBridge/ProductOffer/ProductOfferErpSyncService.php
  • packages/erp-bridge/src/Requests/ProductOffers/GetProductOffersRequest.php

Storefront and order-entry consumers

Product offers are consumed by:

  • storefront product pricing blocks
  • the legacy storefront product-offers API
  • internal order-entry offer selection dialogs

Sources:

  • packages/storefront/src/Livewire/Storefront/Product/OfferBlock.php
  • packages/framework/src/Http/Controllers/Api/Storefront/ProductsController.php
  • packages/admin/src/Livewire/Admin/Order/Items/AddItemToOrder/ProductOffersDialog.php

Where It Appears To End Users

ProductOffer is not a first-class packaged settings page in the inspected admin UI, but it directly shapes what end users see.

It appears through:

  • storefront product pricing
  • product cards and PDP pricing wrappers
  • cart and order item pricing
  • internal order-entry offer selection

Sources:

  • packages/storefront/src/Livewire/Storefront/Product/OfferBlock.php
  • packages/storefront/src/Livewire/Storefront/Product/PricingWrapper.php
  • packages/storefront/src/View/Components/Product/Pricing.php
  • packages/admin/src/Livewire/Admin/Order/Items/AddItemToOrder/ProductOffersDialog.php

Current Documentation Takeaways

  • ProductOffer is the pricing center of gravity in the framework.
  • Offer targeting is broader than simple customer segmentation. Location, address, and inventory context also matter.
  • The inspected packaged product does not expose a first-class manual offer-management screen, so pricing ownership is split across API, ERP, export, and consumer flows.

Open Questions

  • This first pass did not identify a packaged admin CRUD screen for product offers comparable to the promotion settings pages.
  • price_rule_id, price_zone_id, and custom_price_id appear on the model and in admin filters, but their packaged ownership surfaces were not confirmed in this sprint.