module Spaceship module Tunes class IAPDetail < TunesBase # @return (Spaceship::Tunes::Application) A reference to the application attr_accessor :application # @return (Integer) the IAP id attr_accessor :purchase_id # @return (Bool) if it is a news subscription attr_accessor :is_news_subscription # @return (String) the IAP Referencename attr_accessor :reference_name # @return (String) the IAP Product-Id attr_accessor :product_id # @return (String) free trial period attr_accessor :subscription_free_trial # @return (String) subscription duration attr_accessor :subscription_duration # @return (Bool) Cleared for sale flag attr_accessor :cleared_for_sale attr_accessor :review_screenshot # @return (String) the notes for the review team attr_accessor :review_notes # @return (Hash) subscription pricing target attr_accessor :subscription_price_target attr_mapping({ 'adamId' => :purchase_id, 'referenceName.value' => :reference_name, 'productId.value' => :product_id, 'isNewsSubscription' => :is_news_subscription, 'pricingDurationType.value' => :subscription_duration, 'freeTrialDurationType.value' => :subscription_free_trial, 'clearedForSale.value' => :cleared_for_sale }) # @return (Hash) Hash of languages # @example: { # 'de-DE': { # name: "Name shown in AppStore", # description: "Description of the In app Purchase" # # } # } def versions parsed_versions = {} raw_versions = raw_data["versions"].first["details"]["value"] raw_versions.each do |localized_version| language = localized_version["value"]["localeCode"] parsed_versions[language.to_sym] = { name: localized_version["value"]["name"]["value"], description: localized_version["value"]["description"]["value"] } end return parsed_versions end # transforms user-set versions to iTC ones def versions=(value = {}) if value.kind_of?(Array) # input that comes from iTC api return end new_versions = [] value.each do |language, current_version| new_versions << { "value" => { "name" => { "value" => current_version[:name] }, "description" => { "value" => current_version[:description] }, "localeCode" => language.to_s } } end raw_data.set(["versions"], [{ reviewNotes: { value: @review_notes }, contentHosting: raw_data['versions'].first['contentHosting'], "details" => { "value" => new_versions }, "id" => raw_data["versions"].first["id"] }]) end # transforms user-set intervals to iTC ones def pricing_intervals=(value = []) new_intervals = [] value.each do |current_interval| new_intervals << { "value" => { "tierStem" => current_interval[:tier], "priceTierEndDate" => current_interval[:end_date], "priceTierEffectiveDate" => current_interval[:begin_date], "grandfathered" => current_interval[:grandfathered], "country" => current_interval[:country] } } end raw_data.set(["pricingIntervals"], new_intervals) end # @return (Array) pricing intervals # @example: # [ # { # country: "WW", # begin_date: nil, # end_date: nil, # tier: 1 # } # ] def pricing_intervals @pricing_intervals ||= raw_data["pricingIntervals"].map do |interval| { tier: interval["value"]["tierStem"].to_i, begin_date: interval["value"]["priceTierEffectiveDate"], end_date: interval["value"]["priceTierEndDate"], grandfathered: interval["value"]["grandfathered"], country: interval["value"]["country"] } end end # @return (String) Human Readable type of the purchase def type Tunes::IAPType.get_from_string(raw_data["addOnType"]) end # @return (String) Human Readable status of the purchase def status Tunes::IAPStatus.get_from_string(raw_data["versions"].first["status"]) end # Saves the current In-App-Purchase def save! # Transform localization versions back to original format. versions_array = [] versions.each do |language, value| versions_array << { "value" => { "description" => { "value" => value[:description] }, "name" => { "value" => value[:name] }, "localeCode" => language.to_s } } end raw_data.set(["versions"], [{ reviewNotes: { value: @review_notes }, contentHosting: raw_data['versions'].first[:contentHosting], "details" => { "value" => versions_array }, id: raw_data["versions"].first["id"] }]) # transform pricingDetails intervals_array = [] pricing_intervals.each do |interval| intervals_array << { "value" => { "tierStem" => interval[:tier], "priceTierEffectiveDate" => interval[:begin_date], "priceTierEndDate" => interval[:end_date], "country" => interval[:country] || "WW", "grandfathered" => interval[:grandfathered] } } end if subscription_price_target intervals_array = [] pricing_calculator = client.iap_subscription_pricing_target(app_id: application.apple_id, purchase_id: purchase_id, currency: subscription_price_target[:currency], tier: subscription_price_target[:tier]) pricing_calculator.each do |language_code, value| intervals_array << { value: { tierStem: value["tierStem"], priceTierEffectiveDate: value["priceTierEffectiveDate"], priceTierEndDate: value["priceTierEndDate"], country: language_code, grandfathered: { value: "FUTURE_NONE" } } } end end raw_data.set(["pricingIntervals"], intervals_array) if @review_screenshot # Upload Screenshot upload_file = UploadFile.from_path @review_screenshot screenshot_data = client.upload_purchase_review_screenshot(application.apple_id, upload_file) raw_data["versions"][0]["reviewScreenshot"] = screenshot_data end # Update the Purchase client.update_iap!(app_id: application.apple_id, purchase_id: self.purchase_id, data: raw_data) end # Deletes In-App-Purchase def delete! client.delete_iap!(app_id: application.apple_id, purchase_id: self.purchase_id) end # Retrieves the actual prices for an iap. # # @return ([]) An empty array # if the iap is not yet cleared for sale # @return ([Spaceship::Tunes::PricingInfo]) An array of pricing infos from the same pricing tier # if the iap uses world wide pricing # @return ([Spaceship::Tunes::IAPSubscriptionPricingInfo]) An array of pricing infos from multple subscription pricing tiers # if the iap uses territorial pricing def pricing_info return [] unless cleared_for_sale return world_wide_pricing_info if world_wide_pricing? territorial_pricing_info end private # Checks wheather an iap uses world wide or territorial pricing. # # @return (true, false) def world_wide_pricing? pricing_intervals.fetch(0, {})[:country] == "WW" end # Maps a single pricing interval to pricing infos. # # @return ([Spaceship::Tunes::PricingInfo]) An array of pricing infos from the same tier def world_wide_pricing_info client .pricing_tiers .find { |p| p.tier_stem == pricing_intervals.first[:tier].to_s } .pricing_info end # Maps pricing intervals to their respective subscription pricing infos. # # @return ([Spaceship::Tunes::IAPSubscriptionPricingInfo]) An array of subscription pricing infos def territorial_pricing_info pricing_matrix = client.subscription_pricing_tiers(application.apple_id) pricing_intervals.map do |interval| pricing_matrix .find { |p| p.tier_stem == interval[:tier].to_s } .pricing_info .find { |i| i.country_code == interval[:country] } end end end end end