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 & PromotionsOffer ResolutionProduct Offer
Primary implementation paths:
packages/framework/src/Models/ProductOffer.phppackages/framework/src/Actions/ProductOfferpackages/framework/src/Http/Controllers/Api/Admin/ProductOffersController.phppackages/framework/src/Actions/Product/GetAvailableProductOffers.phppackages/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
| Channel | Role | Notes |
|---|---|---|
| Admin API | Direct | CRUD and list/filter operations live in ProductOffersController |
| Excel export | Direct read-only | Product offers can be exported by manufacturer |
| ERP bridge | Direct | Product offers sync from ERP DTOs |
| Admin order-entry dialogs | Direct read-only | Operators can inspect available offers while adding an item to an order |
| Storefront product pricing | Indirect | Product and cart pricing resolve from available offers |
| Storefront offer API | Direct read-only | Deprecated storefront API can still list offers for a product |
Sources:
packages/framework/src/Http/Controllers/Api/Admin/ProductOffersController.phppackages/admin/src/Livewire/Admin/Tools/Excel/ExportDialog/ProductOffersExport.phppackages/framework/src/Actions/ErpBridge/ProductOffer/SyncModelsFromErp.phppackages/admin/src/Livewire/Admin/Order/Items/AddItemToOrder/ProductOffersDialog.phppackages/storefront/src/Livewire/Storefront/Product/OfferBlock.phppackages/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_idproduct_inventory_location_idcustomer_idregular_pricesale_pricemsrp_pricedate_on_sale_fromdate_on_sale_tomin_quantityshipping_addressesbilling_addressesstatescountriesshipping_postal_codes
Sources:
packages/framework/src/Actions/ProductOffer/CreateProductOffer.phppackages/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_typeexcept_zipstarget_priceprice_rule_idprice_zone_idcustom_price_idcustomer_group_idsweighted_costcustomon_holdcurrencyspecial_costextra_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 Group | Purpose |
|---|---|
| product linkage | product_id, product_inventory_item_id, product_inventory_location_id, product_vendor_id |
| pricing inputs | regular_price, sale_price, msrp_price, current_price, target_price, weighted_cost, cost |
| targeting | customer, customer groups, countries, states, postal codes, shipping and billing addresses |
| commercial state | price_type, min_quantity, custom, on_hold |
Calculation behavior:
Calculateruns 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
PriceHistoryentry
Sources:
packages/framework/src/Models/ProductOffer.phppackages/framework/src/Actions/ProductOffer/Calculate.phppackages/framework/src/Actions/ProductOffer/CalculateCurrentPrice.phppackages/framework/src/Actions/ProductOffer/CalculateCost.phppackages/framework/src/Actions/ProductOffer/CalculateMarkup.phppackages/framework/src/Actions/ProductOffer/CalculateMarginPercentage.php
Relationships
ProductOffer directly relates to:
productproductInventoryItemproductInventoryItemsproductInventoryLocationproductVendorcustomercustomerscustomerGroupsshippingPostalCodesstatescountriesshippingAddressesbillingAddressesshippingZonesorderItemspriceHistories
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
PriceHistoryrows - 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.phppackages/framework/src/Actions/Product/GetAvailableProductOffers.phppackages/framework/src/Actions/ProductOffer/CalculateCurrentPrice.phppackages/framework/src/Actions/Cart/Pipes/OffersAvailabilityCheck.phppackages/framework/src/Observers/ProductOfferObserver.phppackages/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.phppackages/framework/src/Actions/Exports/ProductOffer/ProductOfferTemplateExport.phppackages/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.phppackages/framework/src/Actions/ErpBridge/ProductOffer/UpdateOrCreateModelFromDTO.phppackages/framework/src/Services/ErpBridge/ProductOffer/ProductOfferErpSyncService.phppackages/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.phppackages/framework/src/Http/Controllers/Api/Storefront/ProductsController.phppackages/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.phppackages/storefront/src/Livewire/Storefront/Product/PricingWrapper.phppackages/storefront/src/View/Components/Product/Pricing.phppackages/admin/src/Livewire/Admin/Order/Items/AddItemToOrder/ProductOffersDialog.php
Current Documentation Takeaways
ProductOfferis 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, andcustom_price_idappear on the model and in admin filters, but their packaged ownership surfaces were not confirmed in this sprint.