diff --git a/admin/spec/factories.rb b/admin/spec/factories.rb index 156fb1a6f..ba112d2e1 100644 --- a/admin/spec/factories.rb +++ b/admin/spec/factories.rb @@ -11,6 +11,7 @@ FactoryGirl.define do state "NC" country "US" terms_of_service true + resue_card true factory :admin do diff --git a/db/manifest b/db/manifest index 47d2d2bf1..157316e1c 100755 --- a/db/manifest +++ b/db/manifest @@ -262,3 +262,4 @@ jam_track_importer.sql jam_track_pro_licensing_update.sql jam_track_redeemed.sql shopping_cart_anonymous.sql +user_reuse_card.sql \ No newline at end of file diff --git a/db/up/user_reuse_card.sql b/db/up/user_reuse_card.sql new file mode 100644 index 000000000..27ac34d5b --- /dev/null +++ b/db/up/user_reuse_card.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN reuse_card BOOLEAN DEFAULT TRUE NOT NULL; \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 02ce5486a..447438190 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -171,6 +171,7 @@ module JamRuby validates_confirmation_of :password, :if => :should_validate_password? validates :terms_of_service, :acceptance => {:accept => true, :on => :create, :allow_nil => false } + validates :reuse_card, :inclusion => {:in => [true, false]} validates :subscribe_email, :inclusion => {:in => [nil, true, false]} validates :musician, :inclusion => {:in => [true, false]} validates :show_whats_next, :inclusion => {:in => [nil, true, false]} @@ -928,6 +929,8 @@ module JamRuby signup_confirm_url = options[:signup_confirm_url] affiliate_referral_id = options[:affiliate_referral_id] recaptcha_failed = options[:recaptcha_failed] + any_user = options[:any_user] + reuse_card = options[:reuse_card] user = User.new @@ -938,6 +941,7 @@ module JamRuby user.subscribe_email = true user.terms_of_service = terms_of_service user.musician = musician + user.reuse_card unless reuse_card.nil? # FIXME: Setting random password for social network logins. This # is because we have validations all over the place on this. @@ -982,6 +986,9 @@ module JamRuby user.photo_url = photo_url + # copy over the shopping cart to the new user, if a shopping cart is provided + user.shopping_carts = any_user.shopping_carts if any_user + unless fb_signup.nil? user.update_fb_authorization(fb_signup) diff --git a/ruby/spec/factories.rb b/ruby/spec/factories.rb index 18dbeb8bf..c81f6d38e 100644 --- a/ruby/spec/factories.rb +++ b/ruby/spec/factories.rb @@ -18,6 +18,7 @@ FactoryGirl.define do musician true terms_of_service true last_jam_audio_latency 5 + resue_card true #u.association :musician_instrument, factory: :musician_instrument, user: u diff --git a/web/app/assets/javascripts/checkout_payment.js b/web/app/assets/javascripts/checkout_payment.js index e8085c018..efd403a56 100644 --- a/web/app/assets/javascripts/checkout_payment.js +++ b/web/app/assets/javascripts/checkout_payment.js @@ -15,8 +15,7 @@ var $shippingAddress = null; var $shippingAsBilling = null; var $paymentInfoPanel = null; - var $orderPanel = null; - var $orderContent = null; + var $accountSignup = null; var userDetail = null; var step = null; var billing_info = null; @@ -366,11 +365,30 @@ $paymentInfoPanel.find("#payment-info-next").addClass("disabled"); $paymentInfoPanel.find("#payment-info-next").off("click"); - rest.createRecurlyAccount({billing_info: billing_info}) + var reuse_card = $paymentMethod.find('#save-card').is(':checked'); + + + var email = null; + var password = null; + var isLoggedIn = context.JK.currentUserId; + if(!isLoggedIn) { + email = $accountSignup.find('input[name="email"]').val() + password = $accountSignup.find('input[name="password"]').val() + } + + rest.createRecurlyAccount({billing_info: billing_info, terms_of_service: true, email: email, password: password, reuse_card: reuse_card}) .done(function() { - moveToOrder(); $paymentInfoPanel.find("#payment-info-next").removeClass("disabled"); $paymentInfoPanel.find("#payment-info-next").on("click", next); + + if(isLoggedIn) { + context.location = '/client#checkout_order' + } + else { + // this means the account was created; we need to reload the page for this to take effect + context.location = '/client#checkout_order' + context.location.reload() + } }) .fail(errorHandling); } @@ -387,6 +405,20 @@ $paymentMethod.find('#divCardVerify').addClass("error"); $paymentMethod.find('#card-verify').after(""); } + else if(key == 'email') { + var $email = $accountSignup.find('input[name="email"]') + var $field = $email.closest('.field') + $field.find('.error-text').remove() + $field.addClass("error"); + $field.append(""); + } + else if(key == 'password') { + var $email = $accountSignup.find('input[name="password"]') + var $field = $email.closest('.field') + $field.find('.error-text').remove() + $field.addClass("error"); + $field.append(""); + } }); $paymentInfoPanel.find("#payment-info-next").addClass("disabled"); @@ -399,12 +431,8 @@ populateOrderPage(); } - function clearOrderPage() { - $orderContent.empty(); - } function populateOrderPage() { - clearOrderPage(); rest.getShoppingCarts() .done(renderOrderPage) @@ -415,9 +443,6 @@ window.location = '/client#/checkout_order'; } - - - function toggleShippingAsBilling(e) { e.preventDefault(); @@ -432,7 +457,7 @@ } function events() { - $paymentInfoPanel.find("#payment-info-next").on('click', next); + $screen.find("#payment-info-next").on('click', next); $shippingAsBilling.on('ifChanged', toggleShippingAsBilling); } @@ -454,7 +479,7 @@ } function initializeControls() { - $("form.payment-info").iCheck({ + $("form.payment-info").addClass(context.JK.currentUserId ? 'signed-in' : 'not-signed-in').iCheck({ checkboxClass: 'icheckbox_minimal', radioClass: 'iradio_minimal', inheritClass: true @@ -474,15 +499,14 @@ app.bindScreen('checkout_payment', screenBindings); $screen = $("#checkoutPaymentScreen"); - $paymentInfoPanel = $screen.find(".checkout-payment-info"); - $orderPanel = $screen.find(".order-panel"); + $paymentInfoPanel = $screen.find("#checkout-payment-info"); $navigation = $screen.find(".checkout-navigation-bar"); $billingInfo = $paymentInfoPanel.find(".billing-address"); $shippingInfo = $paymentInfoPanel.find(".shipping-address"); $paymentMethod = $paymentInfoPanel.find(".payment-method"); + $accountSignup = $paymentInfoPanel.find('.jamkazam-account-signup') $shippingAddress = $paymentInfoPanel.find(".shipping-address-detail"); $shippingAsBilling = $paymentInfoPanel.find("#shipping-as-billing"); - $orderContent = $orderPanel.find(".order-content"); if($screen.length == 0) throw "$screen must be specified"; if($navigation.length == 0) throw "$navigation must be specified"; diff --git a/web/app/assets/stylesheets/client/checkout_payment.css.scss b/web/app/assets/stylesheets/client/checkout_payment.css.scss index 70c735815..0bec39083 100644 --- a/web/app/assets/stylesheets/client/checkout_payment.css.scss +++ b/web/app/assets/stylesheets/client/checkout_payment.css.scss @@ -36,11 +36,23 @@ width: 100%; display:block; background-color:#262626; + padding-bottom: 10px; + margin-bottom: 20px; - input[type="text"] { + input[type="text"], input[type="password"] { width: 90%; } + &.signed-in { + .row.second { + .left-side { + width:100%; + } + .right-side { + display:none; + } + } + } .row { margin-top:20px; @@ -62,7 +74,7 @@ .jamkazam-account-signup { .account-label { padding-top: 4px; - width: 30%; + width: 35%; float: left; text-align: left; padding-left: 5px; @@ -70,7 +82,7 @@ } .account-value { - width: 70%; + width: 65%; text-align: left; float: left; @include border_box_sizing; @@ -131,25 +143,31 @@ .shipping-as-billing { float:left; display:block; - margin-right:5px; + margin: 0 5px 10px; } .divBillingHelper { padding-top: 2px; + + label { + + } } .shipping-label { - padding-top: 8px; - width: 30%; + padding-top: 4px; + width: 35%; float: left; - text-align: right; - margin-right: 5px; + text-align: left; + padding-left: 5px; + @include border_box_sizing; } .shipping-value { width: 65%; text-align: left; float: left; + @include border_box_sizing; } } } diff --git a/web/app/controllers/api_recurly_controller.rb b/web/app/controllers/api_recurly_controller.rb index a7fedb452..6b658074c 100644 --- a/web/app/controllers/api_recurly_controller.rb +++ b/web/app/controllers/api_recurly_controller.rb @@ -1,15 +1,55 @@ require 'jam_ruby/recurly_client' class ApiRecurlyController < ApiController - before_filter :api_signed_in_user + before_filter :api_signed_in_user, :except => [:create_account] before_filter :create_client respond_to :json # create Recurly account def create_account - @account = @client.find_or_create_account(current_user, params[:billing_info]) - render :json=>account_json(@account) - rescue RecurlyClientError => x - render json: { :message => x.inspect, errors: x.errors }, :status => 404 + + billing_info = params[:billing_info] + + if current_user + # keep reuse card up-to-date + User.where(id: current_user.id).update_all(reuse_card: params[:reuse_card]) + else + options = { + remote_ip: request.remote_ip, + first_name: billing_info[:first_name], + last_name: billing_info[:last_name], + email: params[:email], + password: params[:password], + password_confirmation: params[:password], + terms_of_service: params[:terms_of_service], + instruments: [{ :instrument_id => 'other', :proficiency_level => 3, :priority => 1 }], + birth_date: nil, + location: { :country => billing_info.country, :state => billing_info.state, :city => billing_info.city}, + musician: true, + recaptcha_failed: false, + invited_user: nil, + fb_signup: nil, + signup_confirm_url: ApplicationHelper.base_uri(request) + "/confirm", + any_user: any_user, + reuse_card: params[:reuse_card] + } + + user = UserManager.new.signup(options) + + if user.errors.any? + # render any @user.errors on error + respond_with_model(user) + return + else + sign_in user + end + end + + begin + @account = @client.find_or_create_account(current_user, billing_info) + render :json=>account_json(@account) + rescue RecurlyClientError => x + render json: { :message => x.inspect, errors: x.errors }, :status => 404 + end end def delete_account diff --git a/web/app/views/api_users/show.rabl b/web/app/views/api_users/show.rabl index b005b0fa8..af67eb49b 100644 --- a/web/app/views/api_users/show.rabl +++ b/web/app/views/api_users/show.rabl @@ -1,6 +1,6 @@ object @user -attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :follower_count, :following_count, :recording_count, :session_count, :biography, :favorite_count, :audio_latency, :upcoming_session_count +attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :follower_count, :following_count, :recording_count, :session_count, :biography, :favorite_count, :audio_latency, :upcoming_session_count, :reuse_card if @user.musician? node :location do @user.location end diff --git a/web/app/views/clients/_checkout_payment.html.slim b/web/app/views/clients/_checkout_payment.html.slim index 6554a1564..2b8b3862f 100644 --- a/web/app/views/clients/_checkout_payment.html.slim +++ b/web/app/views/clients/_checkout_payment.html.slim @@ -17,7 +17,7 @@ div layout="screen" layout-id="checkout_payment" id="checkoutPaymentScreen" clas | There are no "hidden" charges or fees, thank you! form class="payment-info" id="checkout-payment-info" - .row + .row.first .left-side .billing-address h2.billing-caption BILLING ADDRESS @@ -107,7 +107,7 @@ div layout="screen" layout-id="checkout_payment" id="checkoutPaymentScreen" clas .clearall .clearall .clearall - .row + .row.second .left-side .shipping-address h2.shipping-address-label SHIPPING ADDRESS @@ -117,48 +117,49 @@ div layout="screen" layout-id="checkout_payment" id="checkoutPaymentScreen" clas label for="shipping-as-billing" Same as billing address .clearall .shipping-address-detail.hidden - #divShippingFirstName + #divShippingFirstName.field .shipping-label label for="shipping-first-name" First Name: .shipping-value input type="text" id="shipping-first-name" .clearall - #divShippingLastName + #divShippingLastName.field .shipping-label label for="shipping-last-name" Last Name: .shipping-value input type="text" id="shipping-last-name" .clearall - #divShippingAddress1 + #divShippingAddress1.field .shipping-label label for="shipping-address1" Address 1: .shipping-value input type="text" id="shipping-address1" .clearall - .shipping-label - label for="shipping-address2" Address 2: - .shipping-value - input type="text" id="shipping-address2" - .clearall - #divShippingCity + #divShippingAddress2.field + .shipping-label + label for="shipping-address2" Address 2: + .shipping-value + input type="text" id="shipping-address2" + .clearall + #divShippingCity.field .shipping-label label for="shipping-city" City: .shipping-value input type="text" id="shipping-city" .clearall - #divShippingState + #divShippingState.field .shipping-label label for="shipping-state" State/Region: .shipping-value input type="text" id="shipping-state" .clearall - #divShippingZip + #divShippingZip.field .shipping-label label for="shipping-zip" Zip: .shipping-value input type="text" id="shipping-zip" .clearall - #divShippingCountry + #divShippingCountry.field .shipping-label label for="shipping-country" Country: .shipping-value @@ -169,14 +170,16 @@ div layout="screen" layout-id="checkout_payment" id="checkoutPaymentScreen" clas h2.jamkazam-account-caption JAMKAZAM ACCOUNT #divJamKazamEmail.field .account-label - label.account-label for="email" Email: + label for="email" Email Address: .account-value input name="email" type="text" + .clearall #divJamKazamPassword.field .account-label label for="email" Password: .account-value input name="password" type="password" + .clearall .clearall diff --git a/web/spec/factories.rb b/web/spec/factories.rb index 59a8089fa..af9c1e1c7 100644 --- a/web/spec/factories.rb +++ b/web/spec/factories.rb @@ -20,6 +20,7 @@ FactoryGirl.define do terms_of_service true subscribe_email true last_jam_audio_latency 5 + resue_card true factory :fan do musician false diff --git a/websocket-gateway/spec/factories.rb b/websocket-gateway/spec/factories.rb index a32281fbb..fb4307c47 100644 --- a/websocket-gateway/spec/factories.rb +++ b/websocket-gateway/spec/factories.rb @@ -11,6 +11,7 @@ FactoryGirl.define do state "NC" country "US" terms_of_service true + resue_card true factory :admin do