Ordering product sources

Shop owns source selection and product eligibility through IOrderingProductSourceService. Modules implement IOrderingProductSourceProvider in Infrastructure; they do not reference each other's transport or mapping code.

Configure one policy with platform properties:

Property Meaning
Shop.Ordering.ProductSource.AllContexts Apply to the entire installation; defaults to false.
Shop.Ordering.ProductSource.ProgramIds Comma-separated ordering program IDs to restrict.
Shop.Ordering.ProductSource.DepartmentIds Comma-separated provider department IDs to restrict.
Shop.Ordering.ProductSource.BeforeSourceKey Selected source before cutover.
Shop.Ordering.ProductSource.AfterSourceKey Selected source from cutover.
Shop.Ordering.ProductSource.CutoverMonday Optional Monday date in yyyy-MM-dd, at midnight in Denmark.

Program and department selectors are alternatives: either matching selector applies the policy. Unselected contexts retain their existing catalog behavior. No properties are automatically activated by module installation.

Source selection uses the requested delivery week in Danish time. Platform dates are system-local unless their DateTime.Kind identifies UTC. An unset cutover selects the before source, including when delivery has not yet been selected. Once a cutover is configured, missing delivery context and invalid dates fail closed. Catalog windows crossing the cutover fail closed; request individual weeks instead.

Products require exactly one valid source membership. Providers own their durable identity mappings. Missing, empty, duplicate, cross-source, or reused external identities are ineligible. Only the selected provider's availability matters; all registered identity providers are queried in batches to detect conflicting memberships. No native-product fallback exists in restricted contexts.

Catalog, browse and single-product reads filter before pagination. Basket addition, order validation and PCD outbound validation share that eligibility service. Checkout carries its resolved ordering program onto the order. Generic cart evaluation validates its explicit delivery context separately from the synthetic date used by existing pricing; missing context produces cart.product_source_unavailable when a configured cutover requires a week. A consuming ordering flow must supply its actual delivery context before cutover activation.

Placed-order validation, PCD dispatch and PCD delivery-time adjustment use immutable persisted ownership rather than recalculating the cutover. See order source ownership for routing and legacy classification. Site-wide policies stop PCD campaign generation after cutover. Context-specific policies retain shared campaigns for unrestricted contexts; restricted reads and writes still reject their PCD products after cutover.

This policy does not create provider mappings, dispatch external orders, confirm customer deadlines, or enable Group Plan editing. Source readiness and customer orderability remain separate.

Legacy basket ordering period

TimeCyclePeriodId is independent of DesiredDeliveryTime and persists through the existing OrderInfo draft relation. The initial draft insert includes period/program identity and any selected delivery date; subsequent field setters persist changes against that draft. SubmitCheckoutPage accepts time_cycle_period_id or an exact ordering_period_start_date/ordering_period_end_date window and returns the resolved ID. Selection requires one active, non-deleted period in the program's default ordering time cycle.

Checkout basket refresh retains the request environment, including account scope and authentication. Changing periods validates existing product source membership and any selected delivery date before saving the period. Add requests carry the period of the rendered product and cannot switch an already selected basket period. Invalid or stale context produces basket.invalid_ordering_period; actual delivery must fall within the period in the department time zone. Before delivery selection, source eligibility checks the whole period, including both cutover boundaries. Period-free flows preserve their existing delivery context; other repeat-order cycles retain their own period rules.

The legacy Shop.Order.Create filter synchronizes week selection before reloading products for programs with a default ordering cycle. It never assigns the period start to the customer's desired delivery date.

Source delivery deadlines are optional absolute instants on the shared period-source contract. Quote validation checks them against current time even when availability is cached. Passed deadlines use cart.source_deadline_passed; unavailable date projections preserve the reason for calendar explanations. Shipping schedules and source ordering availability both constrain the date choices.

The quote carries the absolute source customer-edit deadline into local line evidence. Shop persists the earliest of that deadline and the existing product/shipping edit deadline; source data cannot extend a stricter fulfillment constraint. Existing edits consume persisted line evidence, never client-supplied metadata, when no new trusted quote exists. Deadline resolution introduces no connector read inside the order transaction. Older orders without deadline evidence are not automatically backfilled.