Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/muffin_man.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
require "muffin_man/uploads/v20201101"
require "muffin_man/aplus_content/v20201101"
require "muffin_man/application_management/v20231130"
require "muffin_man/replenishment/v20221107"

module MuffinMan
class Error < StandardError; end
Expand Down
86 changes: 86 additions & 0 deletions lib/muffin_man/replenishment/v20221107.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# frozen_string_literal: true

module MuffinMan
module Replenishment
class V20221107 < SpApiClient
# Parameters for listOffers operation
LIST_OFFERS_PARAMS = %w[
filters
sort
pageSize
nextToken
].freeze

# Parameters for listOfferMetrics operation
LIST_OFFER_METRICS_PARAMS = %w[
filters
sort
pageSize
nextToken
].freeze

# Parameters for getSellingPartnerMetrics operation
GET_SELLING_PARTNER_METRICS_PARAMS = %w[
filters
sort
pageSize
nextToken
].freeze

# Get all of a selling partner's replenishment offers filtered by specific criteria
# @param marketplace_ids [Array<String>] A list of marketplace identifiers
# @param params [Hash] Optional filtering and pagination parameters
# @return [Typhoeus::Response] API response
def list_offers(marketplace_ids, params = {})
@local_var_path = "/replenishment/2022-11-07/offers/search"
@request_body = build_search_request_body(marketplace_ids, params, LIST_OFFERS_PARAMS)
@request_type = "POST"
call_api
end

# Get replenishment business metrics for each of a selling partner's offers
# @param marketplace_ids [Array<String>] A list of marketplace identifiers
# @param params [Hash] Optional filtering and pagination parameters
# @return [Typhoeus::Response] API response
def list_offer_metrics(marketplace_ids, params = {})
@local_var_path = "/replenishment/2022-11-07/offers/metrics/search"
@request_body = build_search_request_body(marketplace_ids, params, LIST_OFFER_METRICS_PARAMS)
@request_type = "POST"
call_api
end

# Get a selling partner's replenishment business metrics
# @param marketplace_ids [Array<String>] A list of marketplace identifiers
# @param params [Hash] Optional filtering and pagination parameters
# @return [Typhoeus::Response] API response
def get_selling_partner_metrics(marketplace_ids, params = {})
@local_var_path = "/replenishment/2022-11-07/sellingPartners/metrics/search"
@request_body = build_search_request_body(marketplace_ids, params, GET_SELLING_PARTNER_METRICS_PARAMS)
@request_type = "POST"
call_api
end

private

# Build request body for search operations
# @param marketplace_ids [Array<String>] A list of marketplace identifiers
# @param params [Hash] Parameters containing filters and other options
# @param allowed_params [Array<String>] List of allowed parameters for this operation
# @return [Hash] Request body
def build_search_request_body(marketplace_ids, params, allowed_params)
marketplace_ids = Array(marketplace_ids)

Copy link

Copilot AI Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the trailing whitespace after marketplace_ids = Array(marketplace_ids).

Suggested change

Copilot uses AI. Check for mistakes.
request_body = {
"marketplaceIds" => marketplace_ids
}

# Add allowed parameters from params
allowed_params.each do |param|
request_body[param] = params[param] if params.key?(param)
end

request_body
end
end
end
end
121 changes: 121 additions & 0 deletions spec/muffin_man/replenishment/v20221107_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# frozen_string_literal: true

RSpec.describe MuffinMan::Replenishment::V20221107 do
subject(:replenishment_client) { described_class.new(credentials) }
let(:marketplace_ids) { ["ATVPDKIKX0DER"] }

before do
stub_request_access_token
end

describe "#list_offers" do
it "makes a successful request with marketplace IDs only" do
stub_replenishment_list_offers
response = replenishment_client.list_offers(marketplace_ids)
expect(response.response_code).to eq(200)
expect(JSON.parse(response.body)["offers"]).to be_an(Array)
end

it "makes a successful request with filters" do
params = {
"filters" => {
"enabledOnly" => true,
"asins" => ["B001234567"]
}
}
stub_replenishment_list_offers_with_filters
response = replenishment_client.list_offers(marketplace_ids, params)
expect(response.response_code).to eq(200)
end

it "accepts single marketplace ID" do
stub_replenishment_list_offers
response = replenishment_client.list_offers("ATVPDKIKX0DER")
expect(response.response_code).to eq(200)
end
end

describe "#list_offer_metrics" do
it "makes a successful request for offer metrics" do
params = {
"filters" => {
"timeInterval" => {
"startDate" => "2023-01-01T00:00:00Z",
"endDate" => "2023-01-31T23:59:59Z"
},
"aggregationFrequency" => "MONTHLY"
}
}
stub_replenishment_list_offer_metrics
response = replenishment_client.list_offer_metrics(marketplace_ids, params)
expect(response.response_code).to eq(200)
expect(JSON.parse(response.body)["offerMetrics"]).to be_an(Array)
end

it "makes a successful request with forecast metrics" do
params = {
"filters" => {
"timeInterval" => {
"startDate" => "2023-02-01T00:00:00Z",
"endDate" => "2023-04-30T23:59:59Z"
},
"timePeriodType" => "FORECAST",
"aggregationFrequency" => "MONTHLY"
}
}
stub_replenishment_list_offer_metrics_forecast
response = replenishment_client.list_offer_metrics(marketplace_ids, params)
expect(response.response_code).to eq(200)
end
end

describe "#get_selling_partner_metrics" do
it "makes a successful request for all metrics" do
params = {
"filters" => {
"timeInterval" => {
"startDate" => "2023-01-01T00:00:00Z",
"endDate" => "2023-01-31T23:59:59Z"
},
"aggregationFrequency" => "MONTHLY"
}
}
stub_replenishment_get_selling_partner_metrics
response = replenishment_client.get_selling_partner_metrics(marketplace_ids, params)
expect(response.response_code).to eq(200)
expect(JSON.parse(response.body)["aggregatedMetrics"]).to be_an(Array)
end

it "makes a successful request with specific metrics" do
params = {
"filters" => {
"timeInterval" => {
"startDate" => "2023-01-01T00:00:00Z",
"endDate" => "2023-01-31T23:59:59Z"
},
"aggregationFrequency" => "MONTHLY",
"metrics" => ["SHIPPED_SUBSCRIPTION_UNITS", "TOTAL_SUBSCRIPTIONS_REVENUE"]
}
}
stub_replenishment_get_selling_partner_metrics_specific
response = replenishment_client.get_selling_partner_metrics(marketplace_ids, params)
expect(response.response_code).to eq(200)
end

it "makes a successful request with forecast metrics" do
params = {
"filters" => {
"timeInterval" => {
"startDate" => "2023-02-01T00:00:00Z",
"endDate" => "2023-04-30T23:59:59Z"
},
"timePeriodType" => "FORECAST",
"aggregationFrequency" => "MONTHLY"
}
}
stub_replenishment_get_selling_partner_metrics_forecast
response = replenishment_client.get_selling_partner_metrics(marketplace_ids, params)
expect(response.response_code).to eq(200)
end
end
end
62 changes: 62 additions & 0 deletions spec/support/replenishment/get_selling_partner_metrics.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"aggregatedMetrics": [
{
"timeInterval": {
"startDate": "2023-01-01T00:00:00Z",
"endDate": "2023-01-31T23:59:59Z"
},
"aggregationFrequency": "MONTHLY",
"marketplaceId": "ATVPDKIKX0DER",
"metrics": [
{
"metric": "SHIPPED_SUBSCRIPTION_UNITS",
"value": 1250
},
{
"metric": "TOTAL_SUBSCRIPTIONS_REVENUE",
"value": 15750.00,
"currencyCode": "USD"
},
{
"metric": "ACTIVE_SUBSCRIPTIONS",
"value": 485
},
{
"metric": "NOT_DELIVERED_DUE_TO_OOS",
"value": 15
},
{
"metric": "SUBSCRIBER_NON_SUBSCRIBER_AVERAGE_REVENUE",
"value": 32.47,
"currencyCode": "USD"
},
{
"metric": "LOST_REVENUE_DUE_TO_OOS",
"value": 180.00,
"currencyCode": "USD"
},
{
"metric": "COUPONS_REVENUE_PENETRATION",
"value": 12.5
},
{
"metric": "REVENUE_BY_DELIVERIES",
"value": 12.6,
"currencyCode": "USD"
},
{
"metric": "SUBSCRIBER_RETENTION",
"value": 87.2
},
{
"metric": "REVENUE_PENETRATION_BY_SELLER_FUNDING",
"value": 65.3
},
{
"metric": "SHARE_OF_COUPON_SUBSCRIPTIONS",
"value": 8.9
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"aggregatedMetrics": [
{
"timeInterval": {
"startDate": "2023-02-01T00:00:00Z",
"endDate": "2023-04-30T23:59:59Z"
},
"aggregationFrequency": "MONTHLY",
"timePeriodType": "FORECAST",
"marketplaceId": "ATVPDKIKX0DER",
"metrics": [
{
"metric": "SHIPPED_SUBSCRIPTION_UNITS",
"forecastPeriod": "30_DAYS",
"value": 425
},
{
"metric": "SHIPPED_SUBSCRIPTION_UNITS",
"forecastPeriod": "60_DAYS",
"value": 850
},
{
"metric": "SHIPPED_SUBSCRIPTION_UNITS",
"forecastPeriod": "90_DAYS",
"value": 1275
},
{
"metric": "TOTAL_SUBSCRIPTIONS_REVENUE",
"forecastPeriod": "30_DAYS",
"value": 5525.00,
"currencyCode": "USD"
},
{
"metric": "TOTAL_SUBSCRIPTIONS_REVENUE",
"forecastPeriod": "60_DAYS",
"value": 11050.00,
"currencyCode": "USD"
},
{
"metric": "TOTAL_SUBSCRIPTIONS_REVENUE",
"forecastPeriod": "90_DAYS",
"value": 16575.00,
"currencyCode": "USD"
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"aggregatedMetrics": [
{
"timeInterval": {
"startDate": "2023-01-01T00:00:00Z",
"endDate": "2023-01-31T23:59:59Z"
},
"aggregationFrequency": "MONTHLY",
"marketplaceId": "ATVPDKIKX0DER",
"metrics": [
{
"metric": "SHIPPED_SUBSCRIPTION_UNITS",
"value": 1250
},
{
"metric": "TOTAL_SUBSCRIPTIONS_REVENUE",
"value": 15750.00,
"currencyCode": "USD"
}
]
}
]
}
Loading
Loading