Class: Feed::Google::MerchantApi::PromotionBuilder

Inherits:
Object
  • Object
show all
Defined in:
app/services/feed/google/merchant_api/promotion_builder.rb

Overview

Maps a Coupon (tier-3 promotional pricing) to a Merchant API v1 Promotion
hash for the promotions data source — the "special offer" badge layer that sits
alongside the product feed's struck-through salePrice.

Only coupons that can be expressed as a Google promotion AND satisfy Google's
promotion policy (min 5% / $5 off, effective period present and <= 6 months)
produce a promotion; everything else returns nil so the processor can skip it.
Price-forcing/adjustable/matrix coupons (DP/MP/MX/?) are not public offers and
are dropped.

Product applicability is decided by the caller: an empty item_id_inclusion
means a site-wide promotion (ALL_PRODUCTS); a non-empty list scopes it to
specific offers (SPECIFIC_PRODUCTS). The builder itself reads only scalar
coupon attributes so it stays DB-free and trivially testable.

Feed is an ActiveRecord model, so this uses the compact class Feed::Google::…
form rather than reopening module Feed.

Examples:

PromotionBuilder.new(coupon, target_country: 'US', currency: 'USD').as_json

Constant Summary collapse

MIN_PERCENT_OFF =

Google rejects promotions below these thresholds.

5
MIN_MONEY_OFF =
5
MAX_EFFECTIVE_MONTHS =

Google caps a promotion's effective period at 6 months.

6
LONG_TITLE_LIMIT =

Google long_title is capped at 60 characters.

60

Instance Method Summary collapse

Constructor Details

#initialize(coupon, target_country:, currency:, item_id_inclusion: []) ⇒ PromotionBuilder

Returns a new instance of PromotionBuilder.

Parameters:

  • coupon (Coupon)
  • target_country (String)

    'US' / 'CA' (matches the promotions data source)

  • currency (String)

    ISO currency for money-off promotions ('USD' / 'CAD')

  • item_id_inclusion (Array<String>) (defaults to: [])

    offer ids to scope the promotion to;
    empty/nil means the promotion applies to all products.



39
40
41
42
43
44
# File 'app/services/feed/google/merchant_api/promotion_builder.rb', line 39

def initialize(coupon, target_country:, currency:, item_id_inclusion: [])
  @c = coupon
  @country = target_country
  @currency = currency
  @item_ids = Array(item_id_inclusion).compact_blank
end

Instance Method Details

#as_jsonHash?

Returns a Merchant API Promotion, or nil if the coupon can't be a
Google promotion (unrepresentable value type or fails policy).

Returns:

  • (Hash, nil)

    a Merchant API Promotion, or nil if the coupon can't be a
    Google promotion (unrepresentable value type or fails policy).



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'app/services/feed/google/merchant_api/promotion_builder.rb', line 48

def as_json
  value = coupon_value or return nil
  period = effective_period or return nil

  {
    promotionId: @c.code,
    contentLanguage: 'en',
    targetCountry: @country,
    redemptionChannel: ['ONLINE'],
    attributes: {
      productApplicability: @item_ids.present? ? 'SPECIFIC_PRODUCTS' : 'ALL_PRODUCTS',
      itemIdInclusion: @item_ids.presence,
      offerType: @c.auto_apply ? 'NO_CODE' : 'GENERIC_CODE',
      genericRedemptionCode: (@c.code unless @c.auto_apply),
      longTitle: long_title,
      promotionEffectiveTimePeriod: period,
      **value
    }.compact
  }
end