codecombat/app/views/courses/EnrollmentsView.coffee

164 lines
5.7 KiB
CoffeeScript

app = require 'core/application'
CreateAccountModal = require 'views/core/CreateAccountModal'
Classroom = require 'models/Classroom'
Classrooms = require 'collections/Classrooms'
CocoCollection = require 'collections/CocoCollection'
Course = require 'models/Course'
Prepaids = require 'collections/Prepaids'
RootView = require 'views/core/RootView'
stripeHandler = require 'core/services/stripe'
template = require 'templates/courses/enrollments-view'
User = require 'models/User'
Users = require 'collections/Users'
utils = require 'core/utils'
Products = require 'collections/Products'
module.exports = class EnrollmentsView extends RootView
id: 'enrollments-view'
template: template
numberOfStudents: 15
pricePerStudent: 0
initialize: (options) ->
@ownedClassrooms = new Classrooms()
@ownedClassrooms.fetchMine({data: {project: '_id'}})
@supermodel.trackCollection(@ownedClassrooms)
@listenTo stripeHandler, 'received-token', @onStripeReceivedToken
@fromClassroom = utils.getQueryVariable('from-classroom')
@members = new Users()
# @listenTo @members, 'sync add remove', @calculateEnrollmentStats
@classrooms = new CocoCollection([], { url: "/db/classroom", model: Classroom })
@classrooms.comparator = '_id'
@listenToOnce @classrooms, 'sync', @onceClassroomsSync
@supermodel.loadCollection(@classrooms, 'classrooms', {data: {ownerID: me.id}})
@prepaids = new Prepaids()
@prepaids.comparator = '_id'
@prepaids.fetchByCreator(me.id)
@supermodel.loadCollection(@prepaids, 'prepaids')
@products = new Products()
@supermodel.loadCollection(@products, 'products')
super(options)
events:
'input #students-input': 'onInputStudentsInput'
'click .purchase-now': 'onClickPurchaseButton'
# 'click .enroll-students': 'onClickEnrollStudents'
onLoaded: ->
@calculateEnrollmentStats()
@pricePerStudent = @products.findWhere({name: 'course'}).get('amount')
super()
getPriceString: -> '$' + (@getPrice()/100).toFixed(2)
getPrice: -> @pricePerStudent * @numberOfStudents
onceClassroomsSync: ->
for classroom in @classrooms.models
@supermodel.trackRequests @members.fetchForClassroom(classroom, {remove: false, removeDeleted: true})
calculateEnrollmentStats: ->
@removeDeletedStudents()
@memberEnrolledMap = {}
for user in @members.models
@memberEnrolledMap[user.id] = user.get('coursePrepaidID')?
@totalEnrolled = _.reduce @members.models, ((sum, user) ->
sum + (if user.get('coursePrepaidID') then 1 else 0)
), 0
@numberOfStudents = @totalNotEnrolled = _.reduce @members.models, ((sum, user) ->
sum + (if not user.get('coursePrepaidID') then 1 else 0)
), 0
@classroomEnrolledMap = _.reduce @classrooms.models, ((map, classroom) =>
enrolled = _.reduce classroom.get('members'), ((sum, userID) =>
sum + (if @members.get(userID).get('coursePrepaidID') then 1 else 0)
), 0
map[classroom.id] = enrolled
map
), {}
@classroomNotEnrolledMap = _.reduce @classrooms.models, ((map, classroom) =>
enrolled = _.reduce classroom.get('members'), ((sum, userID) =>
sum + (if not @members.get(userID).get('coursePrepaidID') then 1 else 0)
), 0
map[classroom.id] = enrolled
map
), {}
true
removeDeletedStudents: (e) ->
for classroom in @classrooms.models
_.remove(classroom.get('members'), (memberID) =>
not @members.get(memberID) or @members.get(memberID)?.get('deleted')
)
true
onInputStudentsInput: ->
input = @$('#students-input').val()
if input isnt "" and (parseFloat(input) isnt parseInt(input) or _.isNaN parseInt(input))
@$('#students-input').val(@numberOfStudents)
else
@numberOfStudents = Math.max(parseInt(@$('#students-input').val()) or 0, 0)
@updatePrice()
updatePrice: ->
@renderSelectors '#price-form-group'
numberOfStudentsIsValid: -> 0 < @numberOfStudents < 100000
# onClickEnrollStudents: ->
# TODO: Needs "All students" in modal dropdown
onClickPurchaseButton: ->
return @openModalView new CreateAccountModal() if me.isAnonymous()
unless @numberOfStudentsIsValid()
alert("Please enter the maximum number of students needed for your class.")
return
@state = undefined
@stateMessage = undefined
@render()
# Show Stripe handler
application.tracker?.trackEvent 'Started course prepaid purchase', {
price: @pricePerStudent, students: @numberOfStudents}
stripeHandler.open
amount: @numberOfStudents * @pricePerStudent
description: "Full course access for #{@numberOfStudents} students"
bitcoin: true
alipay: if me.get('country') is 'china' or (me.get('preferredLanguage') or 'en-US')[...2] is 'zh' then true else 'auto'
onStripeReceivedToken: (e) ->
@state = 'purchasing'
@render?()
data =
maxRedeemers: @numberOfStudents
type: 'course'
stripe:
token: e.token.id
timestamp: new Date().getTime()
$.ajax({
url: '/db/prepaid/-/purchase',
data: data,
method: 'POST',
context: @
success: (prepaid) ->
application.tracker?.trackEvent 'Finished course prepaid purchase', {price: @pricePerStudent, seats: @numberOfStudents}
@state = 'purchased'
@prepaids.add(prepaid)
@render?()
error: (jqxhr, textStatus, errorThrown) ->
application.tracker?.trackEvent 'Failed course prepaid purchase', status: textStatus
if jqxhr.status is 402
@state = 'error'
@stateMessage = arguments[2]
else
@state = 'error'
@stateMessage = "#{jqxhr.status}: #{jqxhr.responseText}"
@render?()
})