Skip to content

OfferEvent

OfferEvent schema

Properties

  • AggregateId (string, format: {FulfillmentSystemId}-{FulfillmentSystemCustomerId}-{ShippingOrderId})Unique ID for shipping order within Integration Broker.
  • CorrelationId (string)Unique ID for SOB-external event trigger.
  • AggregateType (string)Type of event schema.
  • EventActionUser (['string', 'null'])Username of user who triggered event.
  • EventDateTimeUtc (string)UTC based datetime of when event was triggered.
  • EventName (string)Name of triggered event.
  • EventNameValuePairs (['array', 'null'])

    • Items (object)
  • EventPublisherApp (string)Name of source application that published event.

  • EventSchemaVersion (string)Version of event schema being used.
  • EventSource (string)Name of system where event was triggered.
  • Offer (object)Offer properties.

    • CustomerId (['string', 'null'])Customer that the offer belongs to.
    • Id (string, required)Unique ID assigned to the offer by SOB.
    • OmsOfferId (['string', 'null'])Unique ID assigned to the offer by the OMS.
    • XmPieTemplateId (['string', 'null'])Id of XMPie template to be used in production.
    • XmPieUStoreId (['string', 'null'])Id of offer in UStore, for variable template production.
    • AccessGroups (['array', 'null'])An array of access groups assigned to have access to the offer.

      • Items (string)
    • AdditionalPropsRequiredOnOrder (['array', 'null'])Any properties that are required for this offer that wouldn't otherwise be required for an offer order.

      • Items (object)

        • Hint (['string', 'null'])Hint for entry of the value.
        • IsDeleted (['boolean', 'null'])Flag to indicate the property is deleted. Name will be the key.
        • Label (['string', 'null'])Label for presenting the prompt to the client.
        • Name (string, required)Name of required property.
        • Type (['string', 'null'])Type of property.
        • Value (['string', 'null'])Default Value.
    • AvailableEndDate (['string', 'null'])Date that offer is no longer available for sale.

    • AvailableStartDate (['string', 'null'])Date that offer is available for sale.
    • CategoryIds (['array', 'null'])An array of category IDs identifying the categories an offer is assigned.

      • Items (string)
    • Comments (['string', 'null'])Additional information about the offer.

    • DefaultPrice (['number', 'null'])Default price of the offer if no price classes are applied.
    • DeliveryScheduleCron (['string', 'null'])Cron expression that defines the delivery schedule.
    • Description (['string', 'null'])More detailed description of the offer.
    • DoSuppressShippingAndHandling (['boolean', 'null'])Disable shipping and handling fees being applied to the offer.
    • FixedOrderQuantities (['array', 'null'])Indicates the offer should only be orderable in the defined quantities.

      • Items (integer)
    • FullImageUrl (['string', 'null'])URL of full product image for the offer.

    • IsActive (['boolean', 'null'])Flag indicating whether offer is available for sale, if within the availability dates.
    • IsAvailableViaCoopFunds (['boolean', 'null'])Flag indicating whether offer is available for payment with Coop funds.
    • IsDeleted (['boolean', 'null'])Flag indicating a soft delete of the offer.
    • IsInventoried (['boolean', 'null'])Flag indicating whether offer is inventoried.
    • IsTaxable (['boolean', 'null'])Indicates whether the offer can be taxed.
    • Number (['string', 'null'])Number to identify offer.
    • OfferType (['string', 'null'])Indicates whether the offer is a product list, drop ship, etc.
    • OmniChannel (['object', 'null'])Offer OmniChannel.

      • Offers (['array', 'null'])

        • Items (object)

          • OfferId (['string', 'null'])ID of the offer in the omni channel.
          • DeliveryChannel (['string', 'null'])Delivery channel for the offer.
    • OmsLastUpdateDateTimeUtc (['string', 'null'])UTC DateTime that the offer was last updated by the system that manages it. This value is set by the OMS.

    • OnlyShipMethodsAvailable (['array', 'null'])If an offer is only available via a defined set of ship methods, they are declared in this array.

      • Items (string)
    • OrderMaximum (['integer', 'null'])The maximum quantity of the offer that can be ordered.

    • OrderMinimum (['integer', 'null'])The minimum quantity of the offer that can be ordered.
    • PdfUrl (['string', 'null'])URL of a PDF that may be associated with the offer.
    • PriceClasses (['array', 'null'])An array of different classes of pricing by access group.

      • Items (object)

        • IsDeleted (['boolean', 'null'])Flag to indicate price class has been deleted. The key to identify the item being removed is the Name.
        • Name (['string', 'null'])Name of access group this pricing applies to.
        • Price (['number', 'null'])Default price for the access group if not covered by price tiers.
        • PriceTiers (['array', 'null'])Pricing tiered by quantity being ordered.

          • Items (object)

            • IsDeleted (['boolean', 'null'])Flag to indicate price tier has been deleted. If a minimum or maximum quantity is provided, that can be used as the key. If not, we assume it is the default - no min, no max - and consider that deleted.
            • MaximumQuantity (['integer', 'null'])Ending quantity of the range for this price.
            • MinimumQuantity (['integer', 'null'])Starting quantity of the range for this price.
            • PageCounts (['array', 'null'])Collection of PageCounts.

              • Items (object)

                • MaximumPages (['integer', 'null'])Maximum Page Count Allowed.
                • MinimumPages (['integer', 'null'])Minimum Page Count Allowed.
                • Price (['number', 'null'])Price.
            • Price (['number', 'null'])The price of the offer within this quantity range.

    • ProductClusters (['array', 'null'])An array of any product clusters included in the offer.

      • Items (object)

        • Id (string, required)SOB unique ID for the cluster.
        • IsDeleted (['boolean', 'null'])Flag to indicate this cluster has been removed.
        • Products (['array', 'null'])An array of products included in the offer. This and/or a cluster must be included if the offer type is Product List.

          • Items (object)

            • ProductId (['string', 'null'])SOB unique ID for the product.
            • AssociatedFileName (['string', 'null'])File name of associated file, if applicable.
            • IsDeleted (['boolean', 'null'])Flag to indicate this product has been removed.
            • PageCount (['integer', 'null'])PageCount for Template.
            • ProductColor (['string', 'null'])Color of the product, if applicable.
            • ProductDescription (['string', 'null'])Description of the product.
            • ProductNumber (['string', 'null'])Number to identify product.
            • ProductQuantityInOffer (integer, required)Indicates the quantity of the selected cluster item included in the offer.
            • ProductSize (['string', 'null'])Size of the product, if applicable.
    • RequiresApproval (['boolean', 'null'])Flag indicating whether offer requires approval for order-fulfillment.

    • SecureEmailBody (['string', 'null'])If this offer is a secure email type, this is the body that should be used.
    • SecureEmailSubject (['string', 'null'])If this offer is a secure email type, this is the subject that should be used.
    • Surcharge (['number', 'null'])Offer Surcharge.
    • ThumbnailUrl (['string', 'null'])URL of thumbnail image for the offer.
    • UnitOfMeasure (['string', 'null'])Orderable units of the offer.
    • WeightInPounds (['number', 'null'])Weight of offer.
  • EventName (string)Name of triggered event. Must be one of: ["Offer Created", "Offer Updated", "Offer Deleted"].

Quicktype Command

quicktype \
    --framework SystemTextJson  \
    --lang cs  \
    --number-type double  \
    --src-lang schema  \
    --no-check-required  \
    --density dense  \
    --features complete  \
    --namespace OtpSchema.Event.Offer.OfferEvent  \
    --src .working/build/internal/json-schema-for-cs/OfferEvent.json -o .working/build/internal/csharp/OtpSchema/Event/Offer/OfferEvent.cs
OfferEvent
// <auto-generated />
//
// To parse this JSON data, add NuGet 'System.Text.Json' then do:
//
//    using OtpSchema.Event.Offer.OfferEvent;
//
//    var offerEvent = OfferEvent.FromJson(jsonString);
#nullable enable
#pragma warning disable CS8618
#pragma warning disable CS8601
#pragma warning disable CS8603

namespace OtpSchema.Event.Offer.OfferEvent
{
    using System;
    using System.Collections.Generic;

    using System.Text.Json;
    using System.Text.Json.Serialization;
    using System.Globalization;
    using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
    using N = System.Text.Json.Serialization.JsonIgnoreCondition;

    /// <summary>OfferEvent schema; ; Details for Shipping Order JSON schema</summary>
    public partial class OfferEvent
    {
        [J("AggregateId")]         public string AggregateId { get; set; }                               // Unique ID for shipping order within Integration Broker
        [J("AggregateType")]       public string AggregateType { get; set; }                             // Type of event schema
        [J("CorrelationId")]       public string CorrelationId { get; set; }                             // Unique ID for SOB-external event trigger
        [J("EventActionUser")]     public string EventActionUser { get; set; }                           // Username of user who triggered event
        [J("EventDateTimeUtc")]    public string EventDateTimeUtc { get; set; }                          // UTC based datetime of when event was triggered
        [J("EventName")]           public AggregateId EventName { get; set; }                            // Name of triggered event
        [J("EventNameValuePairs")] public Dictionary<string, object>[] EventNameValuePairs { get; set; }
        [J("EventPublisherApp")]   public string EventPublisherApp { get; set; }                         // Name of source application that published event
        [J("EventSchemaVersion")]  public string EventSchemaVersion { get; set; }                        // Version of event schema being used
        [J("EventSource")]         public string EventSource { get; set; }                               // Name of system where event was triggered
        [J("Offer")]               public OfferEventOffer Offer { get; set; }                            // Offer properties
    }

    /// <summary>Offer properties</summary>
    public partial class OfferEventOffer
    {
        [J("AccessGroups")]                   public string[] AccessGroups { get; set; }                                           // An array of access groups assigned to have access to the offer
        [J("AdditionalPropsRequiredOnOrder")] public AdditionalPropsRequiredOnOrder[] AdditionalPropsRequiredOnOrder { get; set; } // Any properties that are required for this offer that wouldn't otherwise be required for; an offer order
        [J("AvailableEndDate")]               public string AvailableEndDate { get; set; }                                         // Date that offer is no longer available for sale
        [J("AvailableStartDate")]             public string AvailableStartDate { get; set; }                                       // Date that offer is available for sale
        [J("CategoryIds")]                    public string[] CategoryIds { get; set; }                                            // An array of category IDs identifying the categories an offer is assigned
        [J("Comments")]                       public string Comments { get; set; }                                                 // Additional information about the offer
        [J("CustomerId")]                     public string CustomerId { get; set; }                                               // Customer that the offer belongs to
        [J("DefaultPrice")]                   public double? DefaultPrice { get; set; }                                            // Default price of the offer if no price classes are applied
        [J("DeliveryScheduleCron")]           public string DeliveryScheduleCron { get; set; }                                     // Cron expression that defines the delivery schedule
        [J("Description")]                    public string Description { get; set; }                                              // More detailed description of the offer
        [J("DoSuppressShippingAndHandling")]  public bool? DoSuppressShippingAndHandling { get; set; }                             // Disable shipping and handling fees being applied to the offer
        [J("FixedOrderQuantities")]           public long[] FixedOrderQuantities { get; set; }                                     // Indicates the offer should only be orderable in the defined quantities
        [J("FullImageUrl")]                   public string FullImageUrl { get; set; }                                             // URL of full product image for the offer
        [J("Id")]                             public string Id { get; set; }                                                       // Unique ID assigned to the offer by SOB
        [J("IsActive")]                       public bool? IsActive { get; set; }                                                  // Flag indicating whether offer is available for sale, if within the availability dates
        [J("IsAvailableViaCoopFunds")]        public bool? IsAvailableViaCoopFunds { get; set; }                                   // Flag indicating whether offer is available for payment with Coop funds
        [J("IsDeleted")]                      public bool? IsDeleted { get; set; }                                                 // Flag indicating a soft delete of the offer
        [J("IsInventoried")]                  public bool? IsInventoried { get; set; }                                             // Flag indicating whether offer is inventoried
        [J("IsTaxable")]                      public bool? IsTaxable { get; set; }                                                 // Indicates whether the offer can be taxed
        [J("Number")]                         public string Number { get; set; }                                                   // Number to identify offer
        [J("OfferType")]                      public string OfferType { get; set; }                                                // Indicates whether the offer is a product list, drop ship, etc
        [J("OmniChannel")]                    public OmniChannel OmniChannel { get; set; }                                         // Offer OmniChannel
        [J("OmsLastUpdateDateTimeUtc")]       public string OmsLastUpdateDateTimeUtc { get; set; }                                 // UTC DateTime that the offer was last updated by the system that manages it. This value is; set by the OMS
        [J("OmsOfferId")]                     public string OmsOfferId { get; set; }                                               // Unique ID assigned to the offer by the OMS
        [J("OnlyShipMethodsAvailable")]       public string[] OnlyShipMethodsAvailable { get; set; }                               // If an offer is only available via a defined set of ship methods, they are declared in; this array
        [J("OrderMaximum")]                   public long? OrderMaximum { get; set; }                                              // The maximum quantity of the offer that can be ordered
        [J("OrderMinimum")]                   public long? OrderMinimum { get; set; }                                              // The minimum quantity of the offer that can be ordered
        [J("PdfUrl")]                         public string PdfUrl { get; set; }                                                   // URL of a PDF that may be associated with the offer
        [J("PriceClasses")]                   public PriceClass[] PriceClasses { get; set; }                                       // An array of different classes of pricing by access group
        [J("ProductClusters")]                public ProductCluster[] ProductClusters { get; set; }                                // An array of any product clusters included in the offer
        [J("RequiresApproval")]               public bool? RequiresApproval { get; set; }                                          // Flag indicating whether offer requires approval for order-fulfillment
        [J("SecureEmailBody")]                public string SecureEmailBody { get; set; }                                          // If this offer is a secure email type, this is the body that should be used
        [J("SecureEmailSubject")]             public string SecureEmailSubject { get; set; }                                       // If this offer is a secure email type, this is the subject that should be used
        [J("Surcharge")]                      public double? Surcharge { get; set; }                                               // Offer Surcharge
        [J("ThumbnailUrl")]                   public string ThumbnailUrl { get; set; }                                             // URL of thumbnail image for the offer
        [J("UnitOfMeasure")]                  public string UnitOfMeasure { get; set; }                                            // Orderable units of the offer
        [J("WeightInPounds")]                 public double? WeightInPounds { get; set; }                                          // Weight of offer
        [J("XmPieTemplateId")]                public string XmPieTemplateId { get; set; }                                          // Id of XMPie template to be used in production
        [J("XmPieUStoreId")]                  public string XmPieUStoreId { get; set; }                                            // Id of offer in UStore, for variable template production
    }

    public partial class AdditionalPropsRequiredOnOrder
    {
        [J("Hint")]      public string Hint { get; set; }     // Hint for entry of the value
        [J("IsDeleted")] public bool? IsDeleted { get; set; } // Flag to indicate the property is deleted. Name will be the key
        [J("Label")]     public string Label { get; set; }    // Label for presenting the prompt to the client
        [J("Name")]      public string Name { get; set; }     // Name of required property
        [J("Type")]      public string Type { get; set; }     // Type of property
        [J("Value")]     public string Value { get; set; }    // Default Value
    }

    public partial class OmniChannel
    {
        [J("Offers")] public OfferElement[] Offers { get; set; }
    }

    public partial class OfferElement
    {
        [J("DeliveryChannel")] public string DeliveryChannel { get; set; } // Delivery channel for the offer
        [J("OfferId")]         public string OfferId { get; set; }         // ID of the offer in the omni channel
    }

    public partial class PriceClass
    {
        [J("IsDeleted")]  public bool? IsDeleted { get; set; }        // Flag to indicate price class has been deleted. The key to identify the item being removed; is the Name
        [J("Name")]       public string Name { get; set; }            // Name of access group this pricing applies to
        [J("Price")]      public double? Price { get; set; }          // Default price for the access group if not covered by price tiers
        [J("PriceTiers")] public PriceTier[] PriceTiers { get; set; } // Pricing tiered by quantity being ordered
    }

    public partial class PriceTier
    {
        [J("IsDeleted")]       public bool? IsDeleted { get; set; }        // Flag to indicate price tier has been deleted. If a minimum or maximum quantity is; provided, that can be used as the key. If not, we assume it is the default - no min, no; max - and consider that deleted
        [J("MaximumQuantity")] public long? MaximumQuantity { get; set; }  // Ending quantity of the range for this price
        [J("MinimumQuantity")] public long? MinimumQuantity { get; set; }  // Starting quantity of the range for this price
        [J("PageCounts")]      public PageCount[] PageCounts { get; set; } // Collection of PageCounts
        [J("Price")]           public double? Price { get; set; }          // The price of the offer within this quantity range
    }

    public partial class PageCount
    {
        [J("MaximumPages")] public long? MaximumPages { get; set; } // Maximum Page Count Allowed
        [J("MinimumPages")] public long? MinimumPages { get; set; } // Minimum Page Count Allowed
        [J("Price")]        public double? Price { get; set; }      // Price
    }

    public partial class ProductCluster
    {
        [J("Id")]        public string Id { get; set; }          // SOB unique ID for the cluster
        [J("IsDeleted")] public bool? IsDeleted { get; set; }    // Flag to indicate this cluster has been removed
        [J("Products")]  public Product[] Products { get; set; } // An array of products included in the offer. This and/or a cluster must be included if the; offer type is Product List
    }

    public partial class Product
    {
        [J("AssociatedFileName")]     public string AssociatedFileName { get; set; }   // File name of associated file, if applicable
        [J("IsDeleted")]              public bool? IsDeleted { get; set; }             // Flag to indicate this product has been removed
        [J("PageCount")]              public long? PageCount { get; set; }             // PageCount for Template
        [J("ProductColor")]           public string ProductColor { get; set; }         // Color of the product, if applicable
        [J("ProductDescription")]     public string ProductDescription { get; set; }   // Description of the product
        [J("ProductId")]              public string ProductId { get; set; }            // SOB unique ID for the product
        [J("ProductNumber")]          public string ProductNumber { get; set; }        // Number to identify product
        [J("ProductQuantityInOffer")] public long ProductQuantityInOffer { get; set; } // Indicates the quantity of the selected cluster item included in the offer
        [J("ProductSize")]            public string ProductSize { get; set; }          // Size of the product, if applicable
    }

    /// <summary>Name of triggered event</summary>
    public enum AggregateId { OfferCreated, OfferDeleted, OfferUpdated };

    public partial class OfferEvent
    {
        public static OfferEvent FromJson(string json) => JsonSerializer.Deserialize<OfferEvent>(json, OtpSchema.Event.Offer.OfferEvent.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this OfferEvent self) => JsonSerializer.Serialize(self, OtpSchema.Event.Offer.OfferEvent.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)
        {
            Converters =
            {
                AggregateIdConverter.Singleton,
                new DateOnlyConverter(),
                new TimeOnlyConverter(),
                IsoDateTimeOffsetConverter.Singleton
            },
        };
    }

    internal class AggregateIdConverter : JsonConverter<AggregateId>
    {
        public override bool CanConvert(Type t) => t == typeof(AggregateId);

        public override AggregateId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value = reader.GetString();
            switch (value)
            {
                case "Offer Created":
                    return AggregateId.OfferCreated;
                case "Offer Deleted":
                    return AggregateId.OfferDeleted;
                case "Offer Updated":
                    return AggregateId.OfferUpdated;
            }
            throw new Exception("Cannot unmarshal type AggregateId");
        }

        public override void Write(Utf8JsonWriter writer, AggregateId value, JsonSerializerOptions options)
        {
            switch (value)
            {
                case AggregateId.OfferCreated:
                    JsonSerializer.Serialize(writer, "Offer Created", options);
                    return;
                case AggregateId.OfferDeleted:
                    JsonSerializer.Serialize(writer, "Offer Deleted", options);
                    return;
                case AggregateId.OfferUpdated:
                    JsonSerializer.Serialize(writer, "Offer Updated", options);
                    return;
            }
            throw new Exception("Cannot marshal type AggregateId");
        }

        public static readonly AggregateIdConverter Singleton = new AggregateIdConverter();
    }

    public class DateOnlyConverter : JsonConverter<DateOnly>
    {
        private readonly string serializationFormat;
        public DateOnlyConverter() : this(null) { }

        public DateOnlyConverter(string? serializationFormat)
        {
                this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
        }

        public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
                var value = reader.GetString();
                return DateOnly.Parse(value!);
        }

        public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
                => writer.WriteStringValue(value.ToString(serializationFormat));
    }

    public class TimeOnlyConverter : JsonConverter<TimeOnly>
    {
        private readonly string serializationFormat;

        public TimeOnlyConverter() : this(null) { }

        public TimeOnlyConverter(string? serializationFormat)
        {
                this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
        }

        public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
                var value = reader.GetString();
                return TimeOnly.Parse(value!);
        }

        public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
                => writer.WriteStringValue(value.ToString(serializationFormat));
    }

    internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
    {
        public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);

        private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

        private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
        private string? _dateTimeFormat;
        private CultureInfo? _culture;

        public DateTimeStyles DateTimeStyles
        {
                get => _dateTimeStyles;
                set => _dateTimeStyles = value;
        }

        public string? DateTimeFormat
        {
                get => _dateTimeFormat ?? string.Empty;
                set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
        }

        public CultureInfo Culture
        {
                get => _culture ?? CultureInfo.CurrentCulture;
                set => _culture = value;
        }

        public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
        {
                string text;


                if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
                        || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
                {
                        value = value.ToUniversalTime();
                }

                text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);

                writer.WriteStringValue(text);
        }

        public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
                string? dateText = reader.GetString();

                if (string.IsNullOrEmpty(dateText) == false)
                {
                        if (!string.IsNullOrEmpty(_dateTimeFormat))
                        {
                                return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
                        }
                        else
                        {
                                return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
                        }
                }
                else
                {
                        return default(DateTimeOffset);
                }
        }


        public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
    }
}
#pragma warning restore CS8618
#pragma warning restore CS8601
#pragma warning restore CS8603

OfferEvent
{
  "$schema": "http://json-schema.org/draft-07/schema#", 
  "$id": "OfferEvent.json", 
  "description": "OfferEvent schema", 
  "type": "object", 
  "allOf": [
    {
      "$schema": "http://json-schema.org/draft-07/schema#", 
      "$id": "EventBase.json", 
      "description": "Details for Shipping Order JSON schema", 
      "type": "object", 
      "properties": {
        "AggregateId": {
          "description": "Unique ID for shipping order within Integration Broker", 
          "type": "string", 
          "format": "{FulfillmentSystemId}-{FulfillmentSystemCustomerId}-{ShippingOrderId}"
        }, 
        "CorrelationId": {"description": "Unique ID for SOB-external event trigger", "type": "string"}, 
        "AggregateType": {"description": "Type of event schema", "type": "string"}, 
        "EventActionUser": {
          "description": "Username of user who triggered event", 
          "type": ["string", "null"], 
          "veraCoreSource": "SHPACK_UserName in warehouse DB.  SHPACK in the OMS contains a SeqId for the warehouse table."
        }, 
        "EventDateTimeUtc": {
          "description": "UTC based datetime of when event was triggered", 
          "type": "string"
        }, 
        "EventName": {"description": "Name of triggered event", "type": "string"}, 
        "EventNameValuePairs": { "type": ["array", "null"], "items": {"type": "object"} }, 
        "EventPublisherApp": {
          "description": "Name of source application that published event", 
          "type": "string"
        }, 
        "EventSchemaVersion": {"description": "Version of event schema being used", "type": "string"}, 
        "EventSource": {"description": "Name of system where event was triggered", "type": "string"}
      }, 
      "required": [
        "AggregateId", "AggregateType", "CorrelationId", "EventDateTimeUtc", "EventName", 
        "EventPublisherApp", "EventSchemaVersion", "EventSource"
      ]
    }, 
    {
      "type": "object", 
      "properties": {
        "Offer": {
          "$schema": "http://json-schema.org/draft-07/schema#", 
          "$id": "Offer.json", 
          "description": "Offer properties", 
          "type": "object", 
          "properties": {
            "CustomerId": {
              "description": "Customer that the offer belongs to", 
              "type": ["string", "null"]
            }, 
            "Id": {"description": "Unique ID assigned to the offer by SOB", "type": "string"}, 
            "OmsOfferId": {
              "description": "Unique ID assigned to the offer by the OMS", 
              "type": ["string", "null"]
            }, 
            "XmPieTemplateId": {
              "description": "Id of XMPie template to be used in production", 
              "type": ["string", "null"]
            }, 
            "XmPieUStoreId": {
              "description": "Id of offer in UStore, for variable template production", 
              "type": ["string", "null"]
            }, 
            "AccessGroups": {
              "description": "An array of access groups assigned to have access to the offer", 
              "type": ["array", "null"], 
              "items": {"type": "string"}
            }, 
            "AdditionalPropsRequiredOnOrder": {
              "description": "Any properties that are required for this offer that wouldn't otherwise be required for an offer order", 
              "type": ["array", "null"], 
              "items": {
                "type": "object", 
                "properties": {
                  "Hint": { "description": "Hint for entry of the value", "type": ["string", "null"] }, 
                  "IsDeleted": {
                    "description": "Flag to indicate the property is deleted. Name will be the key", 
                    "type": ["boolean", "null"]
                  }, 
                  "Label": {
                    "description": "Label for presenting the prompt to the client", 
                    "type": ["string", "null"]
                  }, 
                  "Name": {"description": "Name of required property", "type": "string"}, 
                  "Type": { "description": "Type of property", "type": ["string", "null"] }, 
                  "Value": { "description": "Default Value", "type": ["string", "null"] }
                }, 
                "required": ["Name"]
              }
            }, 
            "AvailableEndDate": {
              "description": "Date that offer is no longer available for sale", 
              "type": ["string", "null"]
            }, 
            "AvailableStartDate": {
              "description": "Date that offer is available for sale", 
              "type": ["string", "null"]
            }, 
            "CategoryIds": {
              "description": "An array of category IDs identifying the categories an offer is assigned", 
              "type": ["array", "null"], 
              "items": {"type": "string"}
            }, 
            "Comments": {
              "description": "Additional information about the offer", 
              "type": ["string", "null"]
            }, 
            "DefaultPrice": {
              "description": "Default price of the offer if no price classes are applied", 
              "type": ["number", "null"]
            }, 
            "DeliveryScheduleCron": {
              "description": "Cron expression that defines the delivery schedule", 
              "type": ["string", "null"]
            }, 
            "Description": {
              "description": "More detailed description of the offer", 
              "type": ["string", "null"]
            }, 
            "DoSuppressShippingAndHandling": {
              "description": "Disable shipping and handling fees being applied to the offer", 
              "type": ["boolean", "null"]
            }, 
            "FixedOrderQuantities": {
              "description": "Indicates the offer should only be orderable in the defined quantities", 
              "type": ["array", "null"], 
              "items": {"type": "integer"}
            }, 
            "FullImageUrl": {
              "description": "URL of full product image for the offer", 
              "type": ["string", "null"]
            }, 
            "IsActive": {
              "description": "Flag indicating whether offer is available for sale, if within the availability dates", 
              "type": ["boolean", "null"]
            }, 
            "IsAvailableViaCoopFunds": {
              "description": "Flag indicating whether offer is available for payment with Coop funds", 
              "type": ["boolean", "null"]
            }, 
            "IsDeleted": {
              "description": "Flag indicating a soft delete of the offer", 
              "type": ["boolean", "null"]
            }, 
            "IsInventoried": {
              "description": "Flag indicating whether offer is inventoried", 
              "type": ["boolean", "null"]
            }, 
            "IsTaxable": {
              "description": "Indicates whether the offer can be taxed", 
              "type": ["boolean", "null"]
            }, 
            "Number": { "description": "Number to identify offer", "type": ["string", "null"] }, 
            "OfferType": {
              "description": "Indicates whether the offer is a product list, drop ship, etc", 
              "type": ["string", "null"]
            }, 
            "OmniChannel": {
              "description": "Offer OmniChannel", 
              "type": ["object", "null"], 
              "properties": {
                "Offers": {
                  "type": ["array", "null"], 
                  "items": {
                    "type": "object", 
                    "properties": {
                      "OfferId": {
                        "description": "ID of the offer in the omni channel", 
                        "type": ["string", "null"]
                      }, 
                      "DeliveryChannel": { "description": "Delivery channel for the offer", "type": ["string", "null"] }
                    }
                  }
                }
              }
            }, 
            "OmsLastUpdateDateTimeUtc": {
              "description": "UTC DateTime that the offer was last updated by the system that manages it. This value is set by the OMS", 
              "type": ["string", "null"]
            }, 
            "OnlyShipMethodsAvailable": {
              "description": "If an offer is only available via a defined set of ship methods, they are declared in this array", 
              "type": ["array", "null"], 
              "items": {"type": "string"}
            }, 
            "OrderMaximum": {
              "description": "The maximum quantity of the offer that can be ordered", 
              "type": ["integer", "null"]
            }, 
            "OrderMinimum": {
              "description": "The minimum quantity of the offer that can be ordered", 
              "type": ["integer", "null"]
            }, 
            "PdfUrl": {
              "description": "URL of a PDF that may be associated with the offer", 
              "type": ["string", "null"]
            }, 
            "PriceClasses": {
              "description": "An array of different classes of pricing by access group", 
              "type": ["array", "null"], 
              "items": {
                "type": "object", 
                "properties": {
                  "IsDeleted": {
                    "description": "Flag to indicate price class has been deleted. The key to identify the item being removed is the Name", 
                    "type": ["boolean", "null"]
                  }, 
                  "Name": {
                    "description": "Name of access group this pricing applies to", 
                    "type": ["string", "null"]
                  }, 
                  "Price": {
                    "description": "Default price for the access group if not covered by price tiers", 
                    "type": ["number", "null"]
                  }, 
                  "PriceTiers": {
                    "description": "Pricing tiered by quantity being ordered", 
                    "type": ["array", "null"], 
                    "items": {
                      "type": "object", 
                      "properties": {
                        "IsDeleted": {
                          "description": "Flag to indicate price tier has been deleted. If a minimum or maximum quantity is provided, that can be used as the key. If not, we assume it is the default - no min, no max - and consider that deleted", 
                          "type": ["boolean", "null"]
                        }, 
                        "MaximumQuantity": {
                          "description": "Ending quantity of the range for this price", 
                          "type": ["integer", "null"]
                        }, 
                        "MinimumQuantity": {
                          "description": "Starting quantity of the range for this price", 
                          "type": ["integer", "null"]
                        }, 
                        "PageCounts": {
                          "description": "Collection of PageCounts", 
                          "type": ["array", "null"], 
                          "items": {
                            "type": "object", 
                            "properties": {
                              "MaximumPages": { "description": "Maximum Page Count Allowed", "type": ["integer", "null"] }, 
                              "MinimumPages": { "description": "Minimum Page Count Allowed", "type": ["integer", "null"] }, 
                              "Price"       : { "description": "Price"                     , "type": ["number", "null"]  }
                            }
                          }
                        }, 
                        "Price": {
                          "description": "The price of the offer within this quantity range", 
                          "type": ["number", "null"]
                        }
                      }
                    }
                  }
                }
              }
            }, 
            "ProductClusters": {
              "description": "An array of any product clusters included in the offer", 
              "type": ["array", "null"], 
              "items": {
                "type": "object", 
                "properties": {
                  "Id": {"description": "SOB unique ID for the cluster", "type": "string"}, 
                  "IsDeleted": {
                    "description": "Flag to indicate this cluster has been removed", 
                    "type": ["boolean", "null"]
                  }, 
                  "Products": {
                    "description": "An array of products included in the offer. This and/or a cluster must be included if the offer type is Product List", 
                    "type": ["array", "null"], 
                    "items": {
                      "type": "object", 
                      "properties": {
                        "ProductId": { "description": "SOB unique ID for the product", "type": ["string", "null"] }, 
                        "AssociatedFileName": {
                          "description": "File name of associated file, if applicable", 
                          "type": ["string", "null"]
                        }, 
                        "IsDeleted": {
                          "description": "Flag to indicate this product has been removed", 
                          "type": ["boolean", "null"]
                        }, 
                        "PageCount": { "description": "PageCount for Template", "type": ["integer", "null"] }, 
                        "ProductColor": {
                          "description": "Color of the product, if applicable", 
                          "type": ["string", "null"]
                        }, 
                        "ProductDescription": { "description": "Description of the product", "type": ["string", "null"] }, 
                        "ProductNumber": { "description": "Number to identify product", "type": ["string", "null"] }, 
                        "ProductQuantityInOffer": {
                          "description": "Indicates the quantity of the selected cluster item included in the offer", 
                          "type": "integer"
                        }, 
                        "ProductSize": {
                          "description": "Size of the product, if applicable", 
                          "type": ["string", "null"]
                        }
                      }, 
                      "required": ["ProductQuantityInOffer"]
                    }
                  }
                }, 
                "required": ["Id"]
              }
            }, 
            "RequiresApproval": {
              "description": "Flag indicating whether offer requires approval for order-fulfillment", 
              "type": ["boolean", "null"]
            }, 
            "SecureEmailBody": {
              "description": "If this offer is a secure email type, this is the body that should be used", 
              "type": ["string", "null"]
            }, 
            "SecureEmailSubject": {
              "description": "If this offer is a secure email type, this is the subject that should be used", 
              "type": ["string", "null"]
            }, 
            "Surcharge": { "description": "Offer Surcharge", "type": ["number", "null"] }, 
            "ThumbnailUrl": {
              "description": "URL of thumbnail image for the offer", 
              "type": ["string", "null"]
            }, 
            "UnitOfMeasure": { "description": "Orderable units of the offer", "type": ["string", "null"] }, 
            "WeightInPounds": { "description": "Weight of offer", "type": ["number", "null"] }
          }, 
          "required": ["Id"]
        }
      }, 
      "required": ["Offer"]
    }, 
    {
      "type": "object", 
      "properties": {
        "EventName": {
          "description": "Name of triggered event", 
          "type": "string", 
          "enum": ["Offer Created", "Offer Updated", "Offer Deleted"]
        }
      }
    }
  ]
}