2014-11-27 10:32:57 +00:00
/* @see ./routes.coffee for routing*/
var _ = require ( 'lodash' ) ;
var shared = require ( 'habitrpg-shared' ) ;
var nconf = require ( 'nconf' ) ;
var utils = require ( './../../utils' ) ;
var moment = require ( 'moment' ) ;
var isProduction = nconf . get ( "NODE_ENV" ) === "production" ;
var stripe = require ( './stripe' ) ;
var paypal = require ( './paypal' ) ;
2014-11-26 22:14:23 +00:00
var members = require ( '../members' )
var async = require ( 'async' ) ;
2014-11-23 00:50:03 +00:00
var iap = require ( './iap' ) ;
2014-11-27 10:32:57 +00:00
function revealMysteryItems ( user ) {
_ . each ( shared . content . gear . flat , function ( item ) {
if (
item . klass === 'mystery' &&
2014-11-29 02:24:56 +00:00
moment ( ) . isAfter ( shared . content . mystery [ item . mystery ] . start ) &&
moment ( ) . isBefore ( shared . content . mystery [ item . mystery ] . end ) &&
2014-11-27 10:32:57 +00:00
! user . items . gear . owned [ item . key ] &&
! ~ user . purchased . plan . mysteryItems . indexOf ( item . key )
) {
user . purchased . plan . mysteryItems . push ( item . key ) ;
}
} ) ;
}
2014-11-27 01:13:25 +00:00
exports . createSubscription = function ( data , cb ) {
var recipient = data . gift ? data . gift . member : data . user ;
2014-11-28 23:11:13 +00:00
//if (!recipient.purchased.plan) recipient.purchased.plan = {}; // FIXME double-check, this should never be the case
2014-11-27 01:13:25 +00:00
var p = recipient . purchased . plan ;
2014-12-03 23:43:27 +00:00
var months = + ( data . gift ? data . gift . subscription . months : data . sub . months ) ;
2014-11-28 23:11:13 +00:00
var block = shared . content . subscriptionBlocks [ months ] ;
if ( data . gift ) {
2014-12-01 00:18:54 +00:00
if ( p . customerId && ! p . dateTerminated ) { // User has active plan
2014-12-03 23:43:27 +00:00
p . extraMonths += months ;
2014-12-01 00:18:54 +00:00
} else {
p . dateTerminated = moment ( p . dateTerminated ) . add ( { months : months } ) . toDate ( ) ;
2014-11-28 23:11:13 +00:00
}
2014-12-01 00:18:54 +00:00
if ( ! p . customerId ) p . customerId = 'Gift' ; // don't override existing customer, but all sub need a customerId
2014-11-28 23:11:13 +00:00
} else {
_ ( p ) . merge ( { // override with these values
planId : block . key ,
customerId : data . customerId ,
dateUpdated : new Date ( ) ,
gemsBought : 0 ,
paymentMethod : data . paymentMethod ,
extraMonths : + p . extraMonths
+ + ( p . dateTerminated ? moment ( p . dateTerminated ) . diff ( new Date ( ) , 'months' , true ) : 0 ) ,
dateTerminated : null
} ) . defaults ( { // allow non-override if a plan was previously used
dateCreated : new Date ( ) ,
mysteryItems : [ ]
} ) ;
}
2014-11-28 21:44:40 +00:00
// Block sub perks
2014-11-28 23:11:13 +00:00
var perks = Math . floor ( months / 3 ) ;
if ( perks ) {
p . consecutive . offset += months ;
p . consecutive . gemCapExtra += perks * 5 ;
2014-11-28 21:44:40 +00:00
if ( p . consecutive . gemCapExtra > 25 ) p . consecutive . gemCapExtra = 25 ;
2014-11-28 23:11:13 +00:00
p . consecutive . trinkets += perks ;
2014-11-28 21:44:40 +00:00
}
2014-11-27 01:13:25 +00:00
revealMysteryItems ( recipient ) ;
if ( isProduction ) {
2014-12-03 23:43:27 +00:00
if ( ! data . gift ) utils . txnEmail ( data . user , 'subscription-begins' ) ;
2014-11-27 01:13:25 +00:00
utils . ga . event ( 'subscribe' , data . paymentMethod ) . send ( ) ;
2014-11-28 23:11:13 +00:00
utils . ga . transaction ( data . user . _id , block . price ) . item ( block . price , 1 , data . paymentMethod . toLowerCase ( ) + '-subscription' , data . paymentMethod ) . send ( ) ;
2014-11-27 01:13:25 +00:00
}
data . user . purchased . txnCount ++ ;
if ( data . gift ) members . sendMessage ( data . user , data . gift . member , data . gift ) ;
async . parallel ( [
function ( cb2 ) { data . user . save ( cb2 ) } ,
function ( cb2 ) { data . gift ? data . gift . member . save ( cb2 ) : cb2 ( null ) ; }
] , cb ) ;
2014-11-27 10:32:57 +00:00
}
/ * *
* Sets their subscription to be cancelled later
* /
2014-12-01 00:18:54 +00:00
exports . cancelSubscription = function ( data , cb ) {
var p = data . user . purchased . plan ,
now = moment ( ) ,
remaining = data . nextBill ? moment ( data . nextBill ) . diff ( new Date , 'days' ) : 30 ;
2014-11-26 19:39:30 +00:00
p . dateTerminated =
moment ( now . format ( 'MM' ) + '/' + moment ( p . dateUpdated ) . format ( 'DD' ) + '/' + now . format ( 'YYYY' ) )
2014-12-01 00:18:54 +00:00
. add ( { days : remaining } ) // end their subscription 1mo from their last payment
2014-11-28 23:11:13 +00:00
. add ( { months : Math . ceil ( p . extraMonths ) } ) // plus any extra time (carry-over, gifted subscription, etc) they have. FIXME: moment can't add months in fractions...
2014-11-27 10:32:57 +00:00
. toDate ( ) ;
2014-11-26 19:39:30 +00:00
p . extraMonths = 0 ; // clear extra time. If they subscribe again, it'll be recalculated from p.dateTerminated
2014-12-01 00:18:54 +00:00
data . user . save ( cb ) ;
if ( isProduction ) utils . txnEmail ( data . user , 'cancel-subscription' ) ;
utils . ga . event ( 'unsubscribe' , data . paymentMethod ) . send ( ) ;
2014-11-27 10:32:57 +00:00
}
2014-11-26 22:14:23 +00:00
exports . buyGems = function ( data , cb ) {
2014-11-27 01:13:25 +00:00
var amt = data . gift ? data . gift . gems . amount / 4 : 5 ;
2014-11-26 22:14:23 +00:00
( data . gift ? data . gift . member : data . user ) . balance += amt ;
data . user . purchased . txnCount ++ ;
if ( isProduction ) {
2014-12-03 23:43:27 +00:00
if ( ! data . gift ) utils . txnEmail ( data . user , 'donation' ) ;
2014-11-26 22:14:23 +00:00
utils . ga . event ( 'checkout' , data . paymentMethod ) . send ( ) ;
//TODO ga.transaction to reflect whether this is gift or self-purchase
2014-12-01 00:18:54 +00:00
utils . ga . transaction ( data . user . _id , amt ) . item ( amt , 1 , data . paymentMethod . toLowerCase ( ) + "-checkout" , "Gems > " + data . paymentMethod ) . send ( ) ;
2014-11-26 22:14:23 +00:00
}
if ( data . gift ) members . sendMessage ( data . user , data . gift . member , data . gift ) ;
async . parallel ( [
function ( cb2 ) { data . user . save ( cb2 ) } ,
function ( cb2 ) { data . gift ? data . gift . member . save ( cb2 ) : cb2 ( null ) ; }
] , cb ) ;
2014-11-27 10:32:57 +00:00
}
exports . stripeCheckout = stripe . checkout ;
exports . stripeSubscribeCancel = stripe . subscribeCancel ;
exports . stripeSubscribeEdit = stripe . subscribeEdit ;
exports . paypalSubscribe = paypal . createBillingAgreement ;
exports . paypalSubscribeSuccess = paypal . executeBillingAgreement ;
exports . paypalSubscribeCancel = paypal . cancelSubscription ;
exports . paypalCheckout = paypal . createPayment ;
exports . paypalCheckoutSuccess = paypal . executePayment ;
2014-11-23 00:50:03 +00:00
exports . paypalIPN = paypal . ipn ;
exports . iapAndroidVerify = iap . androidVerify ;
exports . iapIosVerify = iap . iosVerify ;