diff --git a/db/manifest b/db/manifest
index 825013c73..40053da47 100755
--- a/db/manifest
+++ b/db/manifest
@@ -312,4 +312,5 @@ track_downloads.sql
jam_track_lang_idx.sql
giftcard.sql
add_description_to_crash_dumps.sql
-acappella.sql
\ No newline at end of file
+acappella.sql
+purchasable_gift_cards.sql
\ No newline at end of file
diff --git a/db/up/purchasable_gift_cards.sql b/db/up/purchasable_gift_cards.sql
new file mode 100644
index 000000000..9ef8d29fa
--- /dev/null
+++ b/db/up/purchasable_gift_cards.sql
@@ -0,0 +1,24 @@
+
+
+CREATE TABLE gift_card_types (
+ id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
+ card_type VARCHAR(64) NOT NULL,
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+);
+
+INSERT INTO gift_card_types (id, card_type) VALUES ('jam_tracks_5', 'jam_tracks_5');
+INSERT INTO gift_card_types (id, card_type) VALUES ('jam_tracks_10', 'jam_tracks_10');
+
+CREATE TABLE gift_card_purchases (
+ id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
+ user_id VARCHAR(64) NOT NULL REFERENCES users(id) ON DELETE SET NULL,
+ gift_card_type_id VARCHAR(64) REFERENCES gift_card_types(id) ON DELETE SET NULL,
+ recurly_adjustment_uuid VARCHAR(500),
+ recurly_adjustment_credit_uuid VARCHAR(500),
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+);
+
+
+ALTER TABLE sale_line_items ADD COLUMN gift_card_purchase_id VARCHAR(64) REFERENCES gift_card_purchases(id);
diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb
index 1cbb0cdab..b3772ec14 100755
--- a/ruby/lib/jam_ruby.rb
+++ b/ruby/lib/jam_ruby.rb
@@ -254,6 +254,8 @@ require "jam_ruby/models/band_search"
require "jam_ruby/import/tency_stem_mapping"
require "jam_ruby/models/jam_track_search"
require "jam_ruby/models/gift_card"
+require "jam_ruby/models/gift_card_purchase"
+require "jam_ruby/models/gift_card_type"
include Jampb
diff --git a/ruby/lib/jam_ruby/models/affiliate_partner.rb b/ruby/lib/jam_ruby/models/affiliate_partner.rb
index db41ddd12..e88aed9c7 100644
--- a/ruby/lib/jam_ruby/models/affiliate_partner.rb
+++ b/ruby/lib/jam_ruby/models/affiliate_partner.rb
@@ -119,18 +119,16 @@ class JamRuby::AffiliatePartner < ActiveRecord::Base
end
def should_attribute_sale?(shopping_cart)
- if shopping_cart.is_jam_track?
- if created_within_affiliate_window(shopping_cart.user, Time.now)
- product_info = shopping_cart.product_info
- # subtract the total quantity from the freebie quantity, to see how much we should attribute to them
- real_quantity = product_info[:quantity].to_i - product_info[:marked_for_redeem].to_i
- {fee_in_cents: (1.99 * 100 * real_quantity * rate.to_f).round}
- else
- false
- end
+
+ if created_within_affiliate_window(shopping_cart.user, Time.now)
+ product_info = shopping_cart.product_info
+ # subtract the total quantity from the freebie quantity, to see how much we should attribute to them
+ real_quantity = product_info[:quantity].to_i - product_info[:marked_for_redeem].to_i
+ {fee_in_cents: (product_info[:price] * 100 * real_quantity * rate.to_f).round}
else
- raise 'shopping cart type not implemented yet'
+ false
end
+
end
def cumulative_earnings_in_dollars
diff --git a/ruby/lib/jam_ruby/models/anonymous_user.rb b/ruby/lib/jam_ruby/models/anonymous_user.rb
index 9d711b349..55c788e90 100644
--- a/ruby/lib/jam_ruby/models/anonymous_user.rb
+++ b/ruby/lib/jam_ruby/models/anonymous_user.rb
@@ -15,10 +15,15 @@ module JamRuby
ShoppingCart.where(anonymous_user_id: @id).order('created_at DESC')
end
+
def destroy_all_shopping_carts
ShoppingCart.destroy_all(anonymous_user_id: @id)
end
+ def destroy_jam_track_shopping_carts
+ ShoppingCart.destroy_all(anonymous_user_id: @id, cart_type: JamTrack::PRODUCT_TYPE)
+ end
+
def admin
false
end
diff --git a/ruby/lib/jam_ruby/models/gift_card.rb b/ruby/lib/jam_ruby/models/gift_card.rb
index 8a8469a27..0dc5f94e8 100644
--- a/ruby/lib/jam_ruby/models/gift_card.rb
+++ b/ruby/lib/jam_ruby/models/gift_card.rb
@@ -1,14 +1,15 @@
+# represents the gift card you hold in your hand
module JamRuby
class GiftCard < ActiveRecord::Base
@@log = Logging.logger[GiftCard]
+ JAM_TRACKS_5 = 'jam_tracks_5'
JAM_TRACKS_10 = 'jam_tracks_10'
- JAM_TRACKS_20 = 'jam_tracks_20'
CARD_TYPES =
[
- JAM_TRACKS_10,
- JAM_TRACKS_20
+ JAM_TRACKS_5,
+ JAM_TRACKS_10
]
@@ -21,10 +22,10 @@ module JamRuby
def check_gifted
if user && user_id_changed?
- if card_type == JAM_TRACKS_10
+ if card_type == JAM_TRACKS_5
+ user.gifted_jamtracks += 5
+ elsif card_type == JAM_TRACKS_10
user.gifted_jamtracks += 10
- elsif card_type == JAM_TRACKS_20
- user.gifted_jamtracks += 20
else
raise "unknown card type #{card_type}"
end
diff --git a/ruby/lib/jam_ruby/models/gift_card_purchase.rb b/ruby/lib/jam_ruby/models/gift_card_purchase.rb
new file mode 100644
index 000000000..0cfb00807
--- /dev/null
+++ b/ruby/lib/jam_ruby/models/gift_card_purchase.rb
@@ -0,0 +1,17 @@
+# reperesents the gift card you buy from the site (but physical gift card is modeled by GiftCard)
+module JamRuby
+ class GiftCardPurchase < ActiveRecord::Base
+
+ @@log = Logging.logger[GiftCardPurchase]
+
+ attr_accessible :user, :gift_card_type
+
+ def name
+ gift_card_type.sale_display
+ end
+
+ # who purchased the card?
+ belongs_to :user, class_name: "JamRuby::User"
+ belongs_to :gift_card_type, class_name: "JamRuby::GiftCardType"
+ end
+end
diff --git a/ruby/lib/jam_ruby/models/gift_card_type.rb b/ruby/lib/jam_ruby/models/gift_card_type.rb
new file mode 100644
index 000000000..e6336a9b1
--- /dev/null
+++ b/ruby/lib/jam_ruby/models/gift_card_type.rb
@@ -0,0 +1,66 @@
+# reperesents the gift card you buy from the site (but physical gift card is modeled by GiftCard)
+module JamRuby
+ class GiftCardType < ActiveRecord::Base
+
+ @@log = Logging.logger[GiftCardType]
+
+ PRODUCT_TYPE = 'GiftCardType'
+
+ JAM_TRACKS_5 = 'jam_tracks_5'
+ JAM_TRACKS_10 = 'jam_tracks_10'
+ CARD_TYPES =
+ [
+ JAM_TRACKS_5,
+ JAM_TRACKS_10
+ ]
+
+ validates :card_type, presence: true, inclusion: {in: CARD_TYPES}
+
+ def self.jam_track_5
+ GiftCardType.find(JAM_TRACKS_5)
+ end
+
+ def self.jam_track_10
+ GiftCardType.find(JAM_TRACKS_10)
+ end
+
+ def name
+ sale_display
+ end
+
+ def price
+ if card_type == JAM_TRACKS_5
+ 10.00
+ elsif card_type == JAM_TRACKS_10
+ 20.00
+ else
+ raise "unknown card type #{card_type}"
+ end
+ end
+
+
+ def sale_display
+ if card_type == JAM_TRACKS_5
+ 'JamTracks Gift Card (5)'
+ elsif card_type == JAM_TRACKS_10
+ 'JamTracks Gift Card (10)'
+ else
+ raise "unknown card type #{card_type}"
+ end
+ end
+
+ def plan_code
+ if card_type == JAM_TRACKS_5
+ "jamtrack-giftcard-5"
+ elsif card_type == JAM_TRACKS_10
+ "jamtrack-giftcard-10"
+ else
+ raise "unknown card type #{card_type}"
+ end
+ end
+
+ def sales_region
+ 'Worldwide'
+ end
+ end
+end
diff --git a/ruby/lib/jam_ruby/models/jam_track.rb b/ruby/lib/jam_ruby/models/jam_track.rb
index aea976d89..9303af65b 100644
--- a/ruby/lib/jam_ruby/models/jam_track.rb
+++ b/ruby/lib/jam_ruby/models/jam_track.rb
@@ -155,6 +155,9 @@ module JamRuby
true
end
+ def sale_display
+ "JamTrack: " + name
+ end
def duplicate_positions?
counter = {}
jam_track_tracks.each do |track|
diff --git a/ruby/lib/jam_ruby/models/recurly_transaction_web_hook.rb b/ruby/lib/jam_ruby/models/recurly_transaction_web_hook.rb
index 9d0fc9bd4..006611f61 100644
--- a/ruby/lib/jam_ruby/models/recurly_transaction_web_hook.rb
+++ b/ruby/lib/jam_ruby/models/recurly_transaction_web_hook.rb
@@ -92,53 +92,15 @@ module JamRuby
transaction.save!
# now that we have the transaction saved, we also need to delete the jam_track_right if this is a refund, or voided
-
-
if transaction.transaction_type == 'refund' || transaction.transaction_type == 'void'
sale = Sale.find_by_recurly_invoice_id(transaction.invoice_id)
- if sale && sale.is_jam_track_sale?
- if sale.sale_line_items.length == 1
- if sale.recurly_total_in_cents == transaction.amount_in_cents
- line_item = sale.sale_line_items[0]
- jam_track = line_item.product
- jam_track_right = jam_track.right_for_user(transaction.user) if jam_track
- if jam_track_right
- line_item.affiliate_refunded = true
- line_item.affiliate_refunded_at = Time.now
- line_item.save!
+ if sale
+ AdminMailer.recurly_alerts(transaction.user, {
+ subject: "ACTION REQUIRED: #{transaction.user.email} has refund on invoice",
+ body: "You will have to manually revoke any JamTrackRights in our database for the appropriate JamTracks"
+ }).deliver
- jam_track_right.destroy
-
- # associate which JamTrack we assume this is related to in this one success case
- transaction.jam_track = jam_track
- transaction.save!
-
- AdminMailer.recurly_alerts(transaction.user, {
- subject: "NOTICE: #{transaction.user.email} has had JamTrack: #{jam_track.name} revoked",
- body: "A #{transaction.transaction_type} event came from Recurly for sale with Recurly invoice ID #{sale.recurly_invoice_id}. We deleted their right to the track in our own database as a result."
- }).deliver
- else
- AdminMailer.recurly_alerts(transaction.user, {
- subject: "NOTICE: #{transaction.user.email} got a refund, but unable to find JamTrackRight to delete",
- body: "This should just mean the user already has no rights to the JamTrackRight when the refund came in. Not a big deal, but sort of weird..."
- }).deliver
- end
-
- else
- AdminMailer.recurly_alerts(transaction.user, {
- subject: "ACTION REQUIRED: #{transaction.user.email} got a refund it was not for total value of a JamTrack sale",
- body: "We received a #{transaction.transaction_type} notice for an amount that was not the same as the original sale. So, no action was taken in the database. sale total: #{sale.recurly_total_in_cents}, refund amount: #{transaction.amount_in_cents}"
- }).deliver
- end
-
-
- else
- AdminMailer.recurly_alerts(transaction.user, {
- subject: "ACTION REQUIRED: #{transaction.user.email} has refund on invoice with multiple JamTracks",
- body: "You will have to manually revoke any JamTrackRights in our database for the appropriate JamTracks"
- }).deliver
- end
else
AdminMailer.recurly_alerts(transaction.user, {
subject: "ACTION REQUIRED: #{transaction.user.email} has refund with no correlator to sales",
diff --git a/ruby/lib/jam_ruby/models/sale.rb b/ruby/lib/jam_ruby/models/sale.rb
index 6e3bb7cfb..9b0fb2047 100644
--- a/ruby/lib/jam_ruby/models/sale.rb
+++ b/ruby/lib/jam_ruby/models/sale.rb
@@ -69,28 +69,6 @@ module JamRuby
}
end
- def self.preview_invoice(current_user, shopping_carts)
-
- line_items = {jam_tracks: []}
- shopping_carts_jam_tracks = []
- shopping_carts_subscriptions = []
- shopping_carts.each do |shopping_cart|
-
- if shopping_cart.is_jam_track?
- shopping_carts_jam_tracks << shopping_cart
- else
- # XXX: this may have to be revisited when we actually have something other than JamTracks for puchase
- shopping_carts_subscriptions << shopping_cart
- end
- end
-
- jam_track_items = preview_invoice_jam_tracks(current_user, shopping_carts_jam_tracks)
- line_items[:jam_tracks] = jam_track_items if jam_track_items
-
- # TODO: process shopping_carts_subscriptions
-
- line_items
- end
def self.ios_purchase(current_user, jam_track, receipt)
jam_track_right = JamRuby::JamTrackRight.find_or_create_by_user_id_and_jam_track_id(current_user.id, jam_track.id) do |jam_track_right|
@@ -105,19 +83,14 @@ module JamRuby
def self.place_order(current_user, shopping_carts)
sales = []
- shopping_carts_jam_tracks = []
- shopping_carts_subscriptions = []
- shopping_carts.each do |shopping_cart|
- if shopping_cart.is_jam_track?
- shopping_carts_jam_tracks << shopping_cart
- else
- # XXX: this may have to be revisited when we actually have something other than JamTracks for puchase
- shopping_carts_subscriptions << shopping_cart
- end
+
+ if Sale.is_mixed(shopping_carts)
+ # the controller checks this too; this is just an extra-level of sanity checking
+ return sales
end
- jam_track_sale = order_jam_tracks(current_user, shopping_carts_jam_tracks)
+ jam_track_sale = order_jam_tracks(current_user, shopping_carts)
sales << jam_track_sale if jam_track_sale
# TODO: process shopping_carts_subscriptions
@@ -125,18 +98,10 @@ module JamRuby
sales
end
- def self.preview_invoice_jam_tracks(current_user, shopping_carts_jam_tracks)
- ### XXX TODO;
- # we currently use a fake plan in Recurly to estimate taxes using the Pricing.Attach metod in Recurly.js
-
- # if we were to implement this the right way (ensure adjustments are on the account as necessary), then it would be better (more correct)
- # just a pain to implement
- end
-
- def self.is_only_freebie(shopping_carts_jam_tracks)
+ def self.is_only_freebie(shopping_carts)
free = true
- shopping_carts_jam_tracks.each do |cart|
+ shopping_carts.each do |cart|
free = cart.product_info[:free]
if !free
@@ -162,7 +127,23 @@ module JamRuby
# this method will either return a valid sale, or throw a RecurlyClientError or ActiveRecord validation error (save! failed)
# it may return an nil sale if the JamTrack(s) specified by the shopping carts are already owned
- def self.order_jam_tracks(current_user, shopping_carts_jam_tracks)
+ def self.order_jam_tracks(current_user, shopping_carts)
+
+ shopping_carts_jam_tracks = []
+ shopping_carts_subscriptions = []
+ shopping_carts_gift_cards = []
+
+ shopping_carts.each do |shopping_cart|
+ if shopping_cart.is_jam_track?
+ shopping_carts_jam_tracks << shopping_cart
+ elsif shopping_cart.is_gift_card?
+ shopping_carts_gift_cards << shopping_cart
+ else
+ # XXX: this may have to be revisited when we actually have something other than JamTracks for puchase
+ raise "unknown shopping cart type #{shopping_cart.cart_type}"
+ shopping_carts_subscriptions << shopping_cart
+ end
+ end
client = RecurlyClient.new
@@ -171,8 +152,8 @@ module JamRuby
sale = create_jam_track_sale(current_user)
if sale.valid?
- if is_only_freebie(shopping_carts_jam_tracks)
- sale.process_jam_tracks(current_user, shopping_carts_jam_tracks, nil)
+ if is_only_freebie(shopping_carts)
+ sale.process_shopping_carts(current_user, shopping_carts, nil)
sale.recurly_subtotal_in_cents = 0
sale.recurly_tax_in_cents = 0
@@ -187,11 +168,13 @@ module JamRuby
return sale
end
- sale_line_item = sale.sale_line_items[0]
- sale_line_item.recurly_tax_in_cents = 0
- sale_line_item.recurly_total_in_cents = 0
- sale_line_item.recurly_currency = 'USD'
- sale_line_item.recurly_discount_in_cents = 0
+ sale.sale_line_items.each do |sale_line_item|
+ sale_line_item = sale.sale_line_items[0]
+ sale_line_item.recurly_tax_in_cents = 0
+ sale_line_item.recurly_total_in_cents = 0
+ sale_line_item.recurly_currency = 'USD'
+ sale_line_item.recurly_discount_in_cents = 0
+ end
sale.save
else
@@ -201,7 +184,7 @@ module JamRuby
purge_pending_adjustments(account)
- created_adjustments = sale.process_jam_tracks(current_user, shopping_carts_jam_tracks, account)
+ created_adjustments = sale.process_shopping_carts(current_user, shopping_carts, account)
# now invoice the sale ... almost done
@@ -257,13 +240,13 @@ module JamRuby
sale
end
- def process_jam_tracks(current_user, shopping_carts_jam_tracks, account)
+ def process_shopping_carts(current_user, shopping_carts, account)
created_adjustments = []
begin
- shopping_carts_jam_tracks.each do |shopping_cart|
- process_jam_track(current_user, shopping_cart, account, created_adjustments)
+ shopping_carts.each do |shopping_cart|
+ process_shopping_cart(current_user, shopping_cart, account, created_adjustments)
end
rescue Recurly::Error, NoMethodError => x
# rollback any adjustments created if error
@@ -279,7 +262,7 @@ module JamRuby
end
- def process_jam_track(current_user, shopping_cart, account, created_adjustments)
+ def process_shopping_cart(current_user, shopping_cart, account, created_adjustments)
recurly_adjustment_uuid = nil
recurly_adjustment_credit_uuid = nil
@@ -287,15 +270,20 @@ module JamRuby
shopping_cart.reload
# get the JamTrack in this shopping cart
- jam_track = shopping_cart.cart_product
+ cart_product = shopping_cart.cart_product
- if jam_track.right_for_user(current_user)
- # if the user already owns the JamTrack, we should just skip this cart item, and destroy it
- # if this occurs, we have to reload every shopping_cart as we iterate. so, we do at the top of the loop
- ShoppingCart.remove_jam_track_from_cart(current_user, shopping_cart)
- return
+ if shopping_cart.is_jam_track?
+ jam_track = cart_product
+ if jam_track.right_for_user(current_user)
+ # if the user already owns the JamTrack, we should just skip this cart item, and destroy it
+ # if this occurs, we have to reload every shopping_cart as we iterate. so, we do at the top of the loop
+ ShoppingCart.remove_jam_track_from_cart(current_user, shopping_cart)
+ return
+ end
end
+
+
if account
# ask the shopping cart to create the correct Recurly adjustment attributes for a JamTrack
adjustments = shopping_cart.create_adjustment_attributes(current_user)
@@ -328,45 +316,69 @@ module JamRuby
# if the sale line item is invalid, blow up the transaction
unless sale_line_item.valid?
- @log.error("sale item invalid! #{sale_line_item.errors.inspect}")
+ @@log.error("sale item invalid! #{sale_line_item.errors.inspect}")
puts("sale item invalid! #{sale_line_item.errors.inspect}")
Stats.write('web.recurly.purchase.sale_invalid', {message: sale_line_item.errors.to_s, value: 1})
raise RecurlyClientError.new(sale_line_item.errors)
end
- # create a JamTrackRight (this needs to be in a transaction too to make sure we don't make these by accident)
- jam_track_right = JamRuby::JamTrackRight.find_or_create_by_user_id_and_jam_track_id(current_user.id, jam_track.id) do |jam_track_right|
- jam_track_right.redeemed = shopping_cart.free?
- end
+ if shopping_cart.is_jam_track?
+ jam_track = cart_product
- # also if the purchase was a free one, then:
- # first, mark the free has_redeemable_jamtrack field if that's still true
- # and if still they have more free things, then redeem the giftable_jamtracks
- if shopping_cart.free?
- if user.has_redeemable_jamtrack
- User.where(id: current_user.id).update_all(has_redeemable_jamtrack: false)
- current_user.has_redeemable_jamtrack = false
- else
- User.where(id: current_user.id).update_all(gifted_jamtracks: current_user.gifted_jamtracks - 1)
- current_user.gifted_jamtracks = current_user.gifted_jamtracks - 1
+ # create a JamTrackRight (this needs to be in a transaction too to make sure we don't make these by accident)
+ jam_track_right = JamRuby::JamTrackRight.find_or_create_by_user_id_and_jam_track_id(current_user.id, jam_track.id) do |jam_track_right|
+ jam_track_right.redeemed = shopping_cart.free?
end
- end
-
- # this can't go in the block above, as it's here to fix bad subscription UUIDs in an update path
- if jam_track_right.recurly_adjustment_uuid != recurly_adjustment_uuid
- jam_track_right.recurly_adjustment_uuid = recurly_adjustment_uuid
- jam_track_right.recurly_adjustment_credit_uuid = recurly_adjustment_credit_uuid
- unless jam_track_right.save
- raise RecurlyClientError.new(jam_track_right.errors)
+ # also if the purchase was a free one, then:
+ # first, mark the free has_redeemable_jamtrack field if that's still true
+ # and if still they have more free things, then redeem the giftable_jamtracks
+ if shopping_cart.free?
+ if user.has_redeemable_jamtrack
+ User.where(id: current_user.id).update_all(has_redeemable_jamtrack: false)
+ current_user.has_redeemable_jamtrack = false
+ else
+ User.where(id: current_user.id).update_all(gifted_jamtracks: current_user.gifted_jamtracks - 1)
+ current_user.gifted_jamtracks = current_user.gifted_jamtracks - 1
+ end
end
+
+
+ # this can't go in the block above, as it's here to fix bad subscription UUIDs in an update path
+ if jam_track_right.recurly_adjustment_uuid != recurly_adjustment_uuid
+ jam_track_right.recurly_adjustment_uuid = recurly_adjustment_uuid
+ jam_track_right.recurly_adjustment_credit_uuid = recurly_adjustment_credit_uuid
+ unless jam_track_right.save
+ raise RecurlyClientError.new(jam_track_right.errors)
+ end
+ end
+
+ # blow up the transaction if the JamTrackRight did not get created
+ raise RecurlyClientError.new(jam_track_right.errors) if jam_track_right.errors.any?
+
+ elsif shopping_cart.is_gift_card?
+ gift_card_type = cart_product
+ raise "gift card is null" if gift_card_type.nil?
+ raise if current_user.nil?
+
+ shopping_cart.quantity.times do |item|
+ gift_card_purchase = GiftCardPurchase.new(
+ {
+ user: current_user,
+ gift_card_type: gift_card_type
+ })
+
+ unless gift_card_purchase.save
+ raise RecurlyClientError.new(gift_card_purchase.errors)
+ end
+ end
+
+ else
+ raise 'unknown shopping cart type: ' + shopping_cart.cart_type
end
# delete the shopping cart; it's been dealt with
shopping_cart.destroy if shopping_cart
-
- # blow up the transaction if the JamTrackRight did not get created
- raise RecurlyClientError.new(jam_track_right.errors) if jam_track_right.errors.any?
end
@@ -396,7 +408,7 @@ module JamRuby
def self.create_jam_track_sale(user)
sale = Sale.new
sale.user = user
- sale.sale_type = JAMTRACK_SALE
+ sale.sale_type = JAMTRACK_SALE # gift cards and jam tracks are sold with this type of sale
sale.order_total = 0
sale.save
sale
diff --git a/ruby/lib/jam_ruby/models/sale_line_item.rb b/ruby/lib/jam_ruby/models/sale_line_item.rb
index 7d744cfe5..5cbe5ad87 100644
--- a/ruby/lib/jam_ruby/models/sale_line_item.rb
+++ b/ruby/lib/jam_ruby/models/sale_line_item.rb
@@ -4,14 +4,16 @@ module JamRuby
JAMBLASTER = 'JamBlaster'
JAMCLOUD = 'JamCloud'
JAMTRACK = 'JamTrack'
+ GIFTCARD = 'GiftCardType'
belongs_to :sale, class_name: 'JamRuby::Sale'
belongs_to :jam_track, class_name: 'JamRuby::JamTrack'
belongs_to :jam_track_right, class_name: 'JamRuby::JamTrackRight'
+ belongs_to :gift_card, class_name: 'JamRuby::GiftCard'
belongs_to :affiliate_referral, class_name: 'JamRuby::AffiliatePartner', foreign_key: :affiliate_referral_id
has_many :recurly_transactions, class_name: 'JamRuby::RecurlyTransactionWebHook', inverse_of: :sale_line_item, foreign_key: 'subscription_id', primary_key: 'recurly_subscription_uuid'
- validates :product_type, inclusion: {in: [JAMBLASTER, JAMCLOUD, JAMTRACK]}
+ validates :product_type, inclusion: {in: [JAMBLASTER, JAMCLOUD, JAMTRACK, GIFTCARD]}
validates :unit_price, numericality: {only_integer: false}
validates :quantity, numericality: {only_integer: true}
validates :free, numericality: {only_integer: true}
@@ -21,9 +23,19 @@ module JamRuby
validates :recurly_plan_code, presence:true
validates :sale, presence:true
+ def is_jam_track?
+ product_type == JAMTRACK
+ end
+
+ def is_gift_card?
+ product_type == GIFTCARD
+ end
+
def product
if product_type == JAMTRACK
JamTrack.find_by_id(product_id)
+ elsif product_type == GIFTCARD
+ GiftCardType.find_by_id(product_id)
else
raise 'unsupported product type'
end
diff --git a/ruby/lib/jam_ruby/models/shopping_cart.rb b/ruby/lib/jam_ruby/models/shopping_cart.rb
index c113c5a99..fb531c2bd 100644
--- a/ruby/lib/jam_ruby/models/shopping_cart.rb
+++ b/ruby/lib/jam_ruby/models/shopping_cart.rb
@@ -28,7 +28,7 @@ module JamRuby
def product_info
product = self.cart_product
- {name: product.name, price: product.price, product_id: cart_id, plan_code: product.plan_code, real_price: real_price(product), total_price: total_price(product), quantity: quantity, marked_for_redeem: marked_for_redeem, free: free?, sales_region: product.sales_region} unless product.nil?
+ {type: cart_type, name: product.name, price: product.price, product_id: cart_id, plan_code: product.plan_code, real_price: real_price(product), total_price: total_price(product), quantity: quantity, marked_for_redeem: marked_for_redeem, free: free?, sales_region: product.sales_region, sale_display:product.sale_display} unless product.nil?
end
# multiply quantity by price
@@ -90,6 +90,7 @@ module JamRuby
end
def self.create user, product, quantity = 1, mark_redeem = false
+
cart = ShoppingCart.new
if user.is_a?(User)
cart.user = user
@@ -110,40 +111,42 @@ module JamRuby
cart_type == JamTrack::PRODUCT_TYPE
end
+ def is_gift_card?
+ cart_type == GiftCardType::PRODUCT_TYPE
+ end
# returns an array of adjustments for the shopping cart
def create_adjustment_attributes(current_user)
- raise "not a jam track" unless is_jam_track?
+ raise "not a jam track or gift card" unless is_jam_track? || is_gift_card?
info = self.product_info
if free?
-
- puts "GOT A FREEBIE!"
# create the credit, then the pseudo charge
[
{
accounting_code: PURCHASE_FREE_CREDIT,
currency: 'USD',
unit_amount_in_cents: -(info[:total_price] * 100).to_i,
- description: "JamTrack: " + info[:name] + " (Credit)",
+ description: info[:sale_display] + " (Credit)",
tax_exempt: true
},
{
accounting_code: PURCHASE_FREE,
currency: 'USD',
unit_amount_in_cents: (info[:total_price] * 100).to_i,
- description: "JamTrack: " + info[:name],
+ description: info[:sale_display],
tax_exempt: true
}
]
else
+
[
{
accounting_code: PURCHASE_NORMAL,
currency: 'USD',
unit_amount_in_cents: (info[:total_price] * 100).to_i,
- description: "JamTrack: " + info[:name],
+ description: info[:sale_display],
tax_exempt: false
}
]
@@ -152,8 +155,13 @@ module JamRuby
def self.move_to_user(user, anonymous_user, shopping_carts)
shopping_carts.each do |shopping_cart|
- mark_redeem = ShoppingCart.user_has_redeemable_jam_track?(user)
- cart = ShoppingCart.create(user, shopping_cart.cart_product, shopping_cart.quantity, mark_redeem)
+ if shopping_cart.is_jam_track?
+ mark_redeem = ShoppingCart.user_has_redeemable_jam_track?(user)
+ cart = ShoppingCart.create(user, shopping_cart.cart_product, shopping_cart.quantity, mark_redeem)
+ else
+ cart = ShoppingCart.create(user, shopping_cart.cart_product, shopping_cart.quantity, false)
+ end
+
end
anonymous_user.destroy_all_shopping_carts
@@ -197,7 +205,7 @@ module JamRuby
if clear
# if you are an anonymous user, we make sure there is nothing else in your shopping cart ... keep it clean for the 'new user rummaging around for a freebie scenario'
- any_user.destroy_all_shopping_carts
+ any_user.destroy_jam_track_shopping_carts
any_user.reload
end
@@ -207,6 +215,14 @@ module JamRuby
cart
end
+ def self.add_item_to_cart(any_user, item)
+ cart = nil
+ ShoppingCart.transaction do
+ cart = ShoppingCart.create(any_user, item, 1, false)
+ end
+ cart
+ end
+
# deletes a jam track from the shopping cart, updating redeem flag as necessary
def self.remove_jam_track_from_cart(any_user, cart)
ShoppingCart.transaction do
@@ -236,6 +252,12 @@ module JamRuby
end
end
+ def self.remove_item_from_cart(any_user, cart)
+ ShoppingCart.transaction do
+ cart.destroy
+ end
+ end
+
# if the number of items in the shopping cart is less than gifted_jamtracks on the user, then fix them all up
def self.apply_gifted_jamtracks(user)
jam_track_carts = user.shopping_carts.where(cart_type:JamTrack::PRODUCT_TYPE)
diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb
index f802954ea..907cd9776 100644
--- a/ruby/lib/jam_ruby/models/user.rb
+++ b/ruby/lib/jam_ruby/models/user.rb
@@ -150,6 +150,8 @@ module JamRuby
# gift cards
has_many :gift_cards, :class_name=> "JamRuby::GiftCard"
+ has_many :gift_card_purchases, :class_name=> "JamRuby::GiftCardPurchase"
+
# affiliate_partner
has_one :affiliate_partner, :class_name => "JamRuby::AffiliatePartner", :foreign_key => :partner_user_id, inverse_of: :partner_user
@@ -1678,6 +1680,11 @@ module JamRuby
ShoppingCart.where("user_id=?", self).destroy_all
end
+ def destroy_jam_track_shopping_carts
+ ShoppingCart.destroy_all(anonymous_user_id: @id, cart_type: JamTrack::PRODUCT_TYPE)
+ end
+
+
def unsubscribe_token
self.class.create_access_token(self)
end
diff --git a/ruby/spec/factories.rb b/ruby/spec/factories.rb
index 1a9097e68..024ecdc20 100644
--- a/ruby/spec/factories.rb
+++ b/ruby/spec/factories.rb
@@ -862,7 +862,16 @@ FactoryGirl.define do
factory :gift_card, class: 'JamRuby::GiftCard' do
sequence(:code) {n.to_s}
- card_type = JamRuby::GiftCard::JAM_TRACKS_10
+ card_type JamRuby::GiftCardType::JAM_TRACKS_5
+ end
+
+ factory :gift_card_type, class: 'JamRuby::GiftCardType' do
+ card_type JamRuby::GiftCardType::JAM_TRACKS_5
+ end
+
+ factory :gift_card_purchase, class: 'JamRuby::GiftCardPurchase' do
+
+ association :user, factory: :user
end
end
diff --git a/ruby/spec/jam_ruby/models/recurly_transaction_web_hook_spec.rb b/ruby/spec/jam_ruby/models/recurly_transaction_web_hook_spec.rb
index ba89aee20..bce945d20 100644
--- a/ruby/spec/jam_ruby/models/recurly_transaction_web_hook_spec.rb
+++ b/ruby/spec/jam_ruby/models/recurly_transaction_web_hook_spec.rb
@@ -135,7 +135,7 @@ describe RecurlyTransactionWebHook do
RecurlyTransactionWebHook.create_from_xml(document)
- JamTrackRight.find_by_id(jam_track_right.id).should be_nil
+ JamTrackRight.find_by_id(jam_track_right.id).should_not be_nil
end
it "deletes jam_track_right when voided" do
@@ -154,7 +154,7 @@ describe RecurlyTransactionWebHook do
RecurlyTransactionWebHook.create_from_xml(document)
- JamTrackRight.find_by_id(jam_track_right.id).should be_nil
+ JamTrackRight.find_by_id(jam_track_right.id).should_not be_nil
end
end
diff --git a/ruby/spec/jam_ruby/models/sale_line_item_spec.rb b/ruby/spec/jam_ruby/models/sale_line_item_spec.rb
index 334166734..4d0340259 100644
--- a/ruby/spec/jam_ruby/models/sale_line_item_spec.rb
+++ b/ruby/spec/jam_ruby/models/sale_line_item_spec.rb
@@ -6,6 +6,7 @@ describe SaleLineItem do
let(:user) {FactoryGirl.create(:user)}
let(:user2) {FactoryGirl.create(:user)}
let(:jam_track) {FactoryGirl.create(:jam_track)}
+ let(:gift_card) {FactoryGirl.create(:gift_card_type, card_type: GiftCardType::JAM_TRACKS_10)}
describe "associations" do
@@ -23,7 +24,7 @@ describe SaleLineItem do
describe "state" do
- it "success" do
+ it "jam track success" do
sale = Sale.create_jam_track_sale(user)
shopping_cart = ShoppingCart.create(user, jam_track)
sale_line_item = SaleLineItem.create_from_shopping_cart(sale, shopping_cart, 'some_recurly_uuid', nil, nil)
@@ -37,5 +38,20 @@ describe SaleLineItem do
success: true
})
end
+
+ it "gift card success" do
+ sale = Sale.create_jam_track_sale(user)
+ shopping_cart = ShoppingCart.create(user, gift_card)
+ sale_line_item = SaleLineItem.create_from_shopping_cart(sale, shopping_cart, 'some_recurly_uuid', nil, nil)
+ transaction = FactoryGirl.create(:recurly_transaction_web_hook, subscription_id: 'some_recurly_uuid')
+
+ sale_line_item.reload
+ sale_line_item.state.should eq({
+ void: false,
+ refund: false,
+ fail: false,
+ success: true
+ })
+ end
end
end
diff --git a/ruby/spec/jam_ruby/models/sale_spec.rb b/ruby/spec/jam_ruby/models/sale_spec.rb
index 6119a5973..fc89145cb 100644
--- a/ruby/spec/jam_ruby/models/sale_spec.rb
+++ b/ruby/spec/jam_ruby/models/sale_spec.rb
@@ -7,6 +7,7 @@ describe Sale do
let(:jam_track) {FactoryGirl.create(:jam_track)}
let(:jam_track2) {FactoryGirl.create(:jam_track)}
let(:jam_track3) {FactoryGirl.create(:jam_track)}
+ let(:gift_card) {GiftCardType.jam_track_5}
def assert_free_line_item(sale_line_item, jamtrack)
sale_line_item.recurly_tax_in_cents.should be_nil
@@ -68,6 +69,7 @@ describe Sale do
let(:jamtrack3) { FactoryGirl.create(:jam_track) }
let(:jamtrack4) { FactoryGirl.create(:jam_track) }
let(:jam_track_price_in_cents) { (jamtrack.price * 100).to_i }
+ let(:gift_card_price_in_cents) { (gift_card.price * 100).to_i }
let(:client) { RecurlyClient.new }
let(:billing_info) {
info = {}
@@ -95,6 +97,77 @@ describe Sale do
end
end
+ it "for a gift card" do
+ shopping_cart = ShoppingCart.create user, gift_card, 1, false
+ client.find_or_create_account(user, billing_info)
+
+ sales = Sale.place_order(user, [shopping_cart])
+
+ user.reload
+ user.sales.length.should eq(1)
+
+ sales.should eq(user.sales)
+ sale = sales[0]
+ sale.recurly_invoice_id.should_not be_nil
+
+ sale.recurly_subtotal_in_cents.should eq(gift_card_price_in_cents)
+ sale.recurly_tax_in_cents.should eq(0)
+ sale.recurly_total_in_cents.should eq(gift_card_price_in_cents)
+ sale.recurly_currency.should eq('USD')
+
+ sale.order_total.should eq(gift_card.price)
+ sale.sale_line_items.length.should == 1
+ sale_line_item = sale.sale_line_items[0]
+ # validate we are storing pricing info from recurly
+ sale_line_item.recurly_tax_in_cents.should eq(0)
+ sale_line_item.recurly_total_in_cents.should eq(gift_card_price_in_cents)
+ sale_line_item.recurly_currency.should eq('USD')
+ sale_line_item.recurly_discount_in_cents.should eq(0)
+ sale_line_item.product_type.should eq(GiftCardType::PRODUCT_TYPE)
+ sale_line_item.unit_price.should eq(gift_card.price)
+ sale_line_item.quantity.should eq(1)
+ sale_line_item.free.should eq(0)
+ sale_line_item.sales_tax.should be_nil
+ sale_line_item.shipping_handling.should eq(0)
+ sale_line_item.recurly_plan_code.should eq(gift_card.plan_code)
+ sale_line_item.product_id.should eq(gift_card.id)
+ sale_line_item.recurly_subscription_uuid.should be_nil
+ sale_line_item.recurly_adjustment_uuid.should_not be_nil
+ sale_line_item.recurly_adjustment_credit_uuid.should be_nil
+ sale_line_item.recurly_adjustment_uuid.should_not be_nil
+
+ # verify subscription is in Recurly
+ recurly_account = client.get_account(user)
+ adjustments = recurly_account.adjustments
+ adjustments.should_not be_nil
+ adjustments.should have(1).items
+ purchase= adjustments[0]
+ purchase.unit_amount_in_cents.should eq((gift_card.price * 100).to_i)
+ purchase.accounting_code.should eq(ShoppingCart::PURCHASE_NORMAL)
+ purchase.description.should eq("JamTracks Gift Card (5)")
+ purchase.state.should eq('invoiced')
+ purchase.uuid.should eq(sale_line_item.recurly_adjustment_uuid)
+
+ invoices = recurly_account.invoices
+ invoices.should have(1).items
+ invoice = invoices[0]
+ invoice.uuid.should eq(sale.recurly_invoice_id)
+ invoice.line_items.should have(1).items # should have single adjustment associated
+ invoice.line_items[0].should eq(purchase)
+ invoice.subtotal_in_cents.should eq((gift_card.price * 100).to_i)
+ invoice.total_in_cents.should eq((gift_card.price * 100).to_i)
+ invoice.state.should eq('collected')
+
+ # verify jam_track_rights data
+ user.gift_card_purchases.should_not be_nil
+ user.gift_card_purchases.should have(1).items
+ user.gift_card_purchases.last.gift_card_type.should eq(GiftCardType.jam_track_5)
+ user.has_redeemable_jamtrack.should be_true
+
+ sale_line_item.affiliate_referral.should be_nil
+ sale_line_item.affiliate_referral_fee_in_cents.should be_nil
+ end
+
it "for a free jam track" do
shopping_cart = ShoppingCart.create user, jamtrack, 1, true
@@ -195,48 +268,25 @@ describe Sale do
# OK! Now make a second purchase; this time, buy one free, one not free
shopping_cart3 = ShoppingCart.create user, jamtrack3, 1, true
- shopping_cart4 = ShoppingCart.create user, jamtrack4, 1, false
client.find_or_create_account(user, billing_info)
- sales = Sale.place_order(user, [shopping_cart3, shopping_cart4])
+ sales = Sale.place_order(user, [shopping_cart3])
user.reload
user.sales.length.should eq(2)
sale = sales[0]
sale.reload
- sale.recurly_invoice_id.should_not be_nil
+ sale.recurly_invoice_id.should be_nil
sale.recurly_subtotal_in_cents.should eq(0)
sale.recurly_tax_in_cents.should eq(0)
sale.recurly_total_in_cents.should eq(0)
sale.recurly_currency.should eq('USD')
sale.order_total.should eq(0)
- sale.sale_line_items.length.should == 2
+ sale.sale_line_items.length.should == 1
assert_free_line_item(sale.sale_line_items[0], jamtrack3)
-
- paid_right = JamTrackRight.where(user_id:user.id).where(jam_track_id: jamtrack4.id).first
-
- sale_line_item.recurly_total_in_cents.should eq(jam_track_price_in_cents)
- sale_line_item.recurly_currency.should eq('USD')
- sale_line_item.recurly_discount_in_cents.should eq(0)
- sale_line_item.product_type.should eq(JamTrack::PRODUCT_TYPE)
- sale_line_item.unit_price.should eq(jamtrack4.price)
- sale_line_item.quantity.should eq(1)
- sale_line_item.free.should eq(0)
- sale_line_item.sales_tax.should be_nil
- sale_line_item.shipping_handling.should eq(0)
- sale_line_item.recurly_plan_code.should eq(jamtrack4.plan_code)
- sale_line_item.product_id.should eq(jamtrack.id)
- sale_line_item.recurly_subscription_uuid.should be_nil
- sale_line_item.recurly_adjustment_uuid.should_not be_nil
- sale_line_item.recurly_adjustment_credit_uuid.should be_nil
- sale_line_item.recurly_adjustment_uuid.should eq(paid_right.recurly_adjustment_uuid)
-
- user.has_redeemable_jamtrack.should be_false
- user.gifted_jamtracks.should eq(0)
-
end
it "for a free jam track with an affiliate association" do
diff --git a/ruby/spec/jam_ruby/models/shopping_cart_spec.rb b/ruby/spec/jam_ruby/models/shopping_cart_spec.rb
index 58a528c7b..8d3b724b1 100644
--- a/ruby/spec/jam_ruby/models/shopping_cart_spec.rb
+++ b/ruby/spec/jam_ruby/models/shopping_cart_spec.rb
@@ -10,6 +10,8 @@ describe ShoppingCart do
let(:jam_track5) { FactoryGirl.create(:jam_track) }
let(:jam_track6) { FactoryGirl.create(:jam_track) }
let(:jam_track7) { FactoryGirl.create(:jam_track) }
+ let(:gift_card) {FactoryGirl.create(:gift_card_type)}
+ let(:gift_card2) {FactoryGirl.create(:gift_card_type)}
before(:each) do
ShoppingCart.delete_all
@@ -29,7 +31,6 @@ describe ShoppingCart do
user.shopping_carts[0].quantity.should == 1
end
-
it "maintains only one free JamTrack in ShoppingCart" do
cart1 = ShoppingCart.add_jam_track_to_cart(user, jam_track, clear: true)
cart1.should_not be_nil
@@ -39,8 +40,12 @@ describe ShoppingCart do
cart2.errors.any?.should be_false
user.reload
user.shopping_carts.length.should eq(1)
- cart3 = ShoppingCart.add_jam_track_to_cart(user, jam_track2, clear: true)
- cart3.errors.any?.should be_false
+ cart3 = ShoppingCart.add_item_to_cart(user, gift_card)
+ cart3.errors.any?.should be_true
+ user.reload
+ user.shopping_carts.length.should eq(1)
+ cart4 = ShoppingCart.add_jam_track_to_cart(user, jam_track2, clear: true)
+ cart4.errors.any?.should be_false
user.reload
user.shopping_carts.length.should eq(1)
end
@@ -56,6 +61,10 @@ describe ShoppingCart do
cart2.errors.any?.should be_true
end
+ it "a second giftcard just adds quantity" do
+
+ end
+
describe "redeemable behavior" do
it "removes redeemable item to shopping cart (maintains only one in cart)" do
@@ -153,6 +162,25 @@ describe ShoppingCart do
end
end
+ describe "gift cards" do
+ it "can not add multiple of same type" do
+ cart1 = ShoppingCart.add_item_to_cart(user, gift_card)
+ cart1.should_not be_nil
+ cart1.errors.any?.should be_false
+
+ user.reload
+ user.has_redeemable_jamtrack = true
+ user.shopping_carts.length.should eq(1)
+ user.shopping_carts[0].quantity.should eql(1)
+
+ cart2 = ShoppingCart.add_item_to_cart(user, gift_card)
+ cart2.should_not be_nil
+ # it's the same type, so it's blocked
+ cart2.errors.any?.should be_true
+ cart2.errors[:cart_id].should eq(["has already been taken"])
+ end
+ end
+
describe "mixed" do
it "non-free then free" do
# you shouldn't be able to add a free after a non-free
diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb
index 93ec5dda7..7f189e159 100644
--- a/ruby/spec/spec_helper.rb
+++ b/ruby/spec/spec_helper.rb
@@ -95,13 +95,13 @@ end
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
- DatabaseCleaner.clean_with(:deletion, {pre_count: true, reset_ids:false, :except => %w[instruments genres icecast_server_groups jamcompany jamisp geoipblocks geoipisp geoiplocations cities regions countries generic_state spatial_ref_sys] })
+ DatabaseCleaner.clean_with(:deletion, {pre_count: true, reset_ids:false, :except => %w[gift_card_types instruments genres icecast_server_groups jamcompany jamisp geoipblocks geoipisp geoiplocations cities regions countries generic_state spatial_ref_sys] })
end
config.around(:each) do |example|
# set no_transaction: true as metadata on your test to use deletion strategy instead
if example.metadata[:no_transaction]
- DatabaseCleaner.strategy = :deletion, {pre_count: true, reset_ids:false, :except => %w[instruments genres icecast_server_groups jamcompany jamisp geoipblocks geoipisp geoiplocations cities regions countries generic_state spatial_ref_sys] }
+ DatabaseCleaner.strategy = :deletion, {pre_count: true, reset_ids:false, :except => %w[gift_card_types instruments genres icecast_server_groups jamcompany jamisp geoipblocks geoipisp geoiplocations cities regions countries generic_state spatial_ref_sys] }
else
DatabaseCleaner.strategy = :transaction
end
diff --git a/web/app/assets/javascripts/checkout_complete.js b/web/app/assets/javascripts/checkout_complete.js
index 4f1e96110..aa52214b9 100644
--- a/web/app/assets/javascripts/checkout_complete.js
+++ b/web/app/assets/javascripts/checkout_complete.js
@@ -15,6 +15,7 @@
var $templatePurchasedJamTrack = null;
var $thanksPanel = null;
var $jamTrackInBrowser = null;
+ var $giftCardPurchased = null;
var $purchasedJamTrack = null;
var $purchasedJamTrackHeader = null;
var $purchasedJamTracks = null;
@@ -75,9 +76,17 @@
else {
$thanksPanel.removeClass('hidden')
handleJamTracksPurchased(purchaseResponse.jam_tracks)
+ handleGiftCardsPurchased(purchaseResponse.gift_cards)
}
}
+
+ function handleGiftCardsPurchased(gift_cards) {
+ // were any GiftCards purchased?
+ if(gift_cards && gift_cards.length > 0) {
+ $giftCardPurchased.removeClass('hidden')
+ }
+ }
function handleJamTracksPurchased(jamTracks) {
// were any JamTracks purchased?
var jamTracksPurchased = jamTracks && jamTracks.length > 0;
@@ -194,6 +203,7 @@
$templatePurchasedJamTrack = $('#template-purchased-jam-track');
$thanksPanel = $screen.find(".thanks-panel");
$jamTrackInBrowser = $screen.find(".thanks-detail.jam-tracks-in-browser");
+ $giftCardPurchased = $screen.find('.thanks-detail.gift-card')
$purchasedJamTrack = $thanksPanel.find(".thanks-detail.purchased-jam-track");
$purchasedJamTrackHeader = $purchasedJamTrack.find(".purchased-jam-track-header");
$purchasedJamTracks = $purchasedJamTrack.find(".purchased-list")
diff --git a/web/app/assets/javascripts/checkout_order.js b/web/app/assets/javascripts/checkout_order.js
index 168b965d6..a69c0a39c 100644
--- a/web/app/assets/javascripts/checkout_order.js
+++ b/web/app/assets/javascripts/checkout_order.js
@@ -135,15 +135,7 @@
}
}
- function displayTax(effectiveQuantity, item_tax, total_with_tax) {
- var totalTax = 0;
- var totalPrice = 0;
-
- var unitTax = item_tax * effectiveQuantity;
- totalTax += unitTax;
-
- var totalUnitPrice = total_with_tax * effectiveQuantity;
- totalPrice += totalUnitPrice;
+ function displayTax(totalTax, totalPrice) {
$screen.find('.order-right-page .order-items-value.taxes').text('$' + totalTax.toFixed(2))
$screen.find('.order-right-page .order-items-value.grand-total').text('$' + totalPrice.toFixed(2))
@@ -181,8 +173,16 @@
taxRate = 0.0825;
}
- var unitTax = 1.99 * taxRate;
- displayTax(effectiveQuantity, unitTax, 1.99 + unitTax)
+ var estimatedTax = 0;
+ var estimatedTotal = 0;
+
+ context._.each(carts, function(cart) {
+ var cart_quantity = cart.product_info.quantity - cart.product_info.marked_for_redeem
+ estimatedTax += cart.product_info.price * cart_quantity * taxRate;
+ estimatedTotal += cart.product_info.price * cart_quantity;
+ })
+
+ displayTax(Math.round(estimatedTax*100)/100, Math.round((estimatedTotal + estimatedTax)*100)/100)
}
else {
checkoutUtils.configureRecurly()
diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js
index b2d7a604a..10461d496 100644
--- a/web/app/assets/javascripts/jam_rest.js
+++ b/web/app/assets/javascripts/jam_rest.js
@@ -1805,6 +1805,17 @@
return deferred
}
+ function addGiftCardToShoppingCart(options) {
+ var deferred = $.ajax({
+ type: "POST",
+ url: '/api/shopping_carts/add_gift_card?' + $.param(options),
+ dataType: "json",
+ contentType: 'application/json'
+ });
+
+ return deferred
+ }
+
function getShoppingCarts() {
// the need for the time de-duplicator indicates we are doing something wrong on the server
return $.ajax({
@@ -2188,6 +2199,7 @@
this.enqueueJamTrack = enqueueJamTrack;
this.getBackingTracks = getBackingTracks;
this.addJamtrackToShoppingCart = addJamtrackToShoppingCart;
+ this.addGiftCardToShoppingCart = addGiftCardToShoppingCart;
this.getShoppingCarts = getShoppingCarts;
this.removeShoppingCart = removeShoppingCart;
this.clearShoppingCart = clearShoppingCart;
diff --git a/web/app/assets/javascripts/react-components/landing/GiftCardLandingPage.js.jsx.coffee b/web/app/assets/javascripts/react-components/landing/GiftCardLandingPage.js.jsx.coffee
new file mode 100644
index 000000000..e55cceb26
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/landing/GiftCardLandingPage.js.jsx.coffee
@@ -0,0 +1,93 @@
+context = window
+rest = context.JK.Rest()
+
+@GiftCardLandingPage = React.createClass({
+
+ render: () ->
+
+ if this.state.done
+ ctaButtonText10 = 'sending you in...'
+ ctaButtonText20 = 'sending you in...'
+ else if this.state.processing
+ ctaButtonText10 = 'hold on...'
+ ctaButtonText20 = 'hold on...'
+ else
+ ctaButtonText10 = `ADD $10 CARD
TO CART`
+ ctaButtonText20 = `ADD $20 CARD
TO CART`
+
+
+ ctaButtons =
+ `
+
+
+ Click the play buttons below to preview the master mix and 20-second samples of all the isolated tracks.
++ Get a $10 gift card (good for 5 songs) or a $20 gift card (good for 10 songs), and your happy + gift card getter can choose their favorites from our catalog of 3,700+ popular songs. +
+ {ctaButtons} + or browse our catalog of 3,700+ songs ++ JamTracks by JamKazam are the best way to play along with your favorite songs. Far better and different than traditional + backing tracks, our JamTracks are complete multi-track professional recordings, with fully isolated tracks for each part of the music. + And our free app and Internet service are packed with features that give you unmatched creative freedom to learn, practice, record, play with others, and share your performances. +
+