1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-10 21:24:20 +01:00
fab-manager/app/assets/javascripts/controllers/events.coffee.erb
2016-06-14 09:57:39 +02:00

511 lines
16 KiB
Plaintext

'use strict'
Application.Controllers.controller "EventsController", ["$scope", "$state", 'Event', ($scope, $state, Event) ->
### PRIVATE STATIC CONSTANTS ###
# Number of events added to the page when the user clicks on 'load next events'
EVENTS_PER_PAGE = 12
### PUBLIC SCOPE ###
## The events displayed on the page
$scope.events = []
## By default, the pagination mode is activated to limit the page size
$scope.paginateActive = true
## The currently displayed page number
$scope.page = 1
##
# Adds EVENTS_PER_PAGE events to the bottom of the page, grouped by month
##
$scope.loadMoreEvents = ->
Event.query {page: $scope.page}, (data) ->
$scope.events = $scope.events.concat data
if data.length > 0
$scope.paginateActive = false if ($scope.page-2)*EVENTS_PER_PAGE+data.length >= data[0].nb_total_events
$scope.eventsGroupByMonth = _.groupBy($scope.events, (obj) ->
_.map ['month', 'year'], (key, value) -> obj[key]
)
$scope.monthOrder = _.sortBy _.keys($scope.eventsGroupByMonth), (k)->
monthYearArray = k.split(',')
date = new Date()
date.setMonth(monthYearArray[0])
date.setYear(monthYearArray[1])
return -date.getTime()
else
$scope.paginateActive = false
$scope.page += 1
##
# Callback to redirect the user to the specified event page
# @param event {{id:number}}
##
$scope.showEvent = (event) ->
$state.go('app.public.events_show', {id: event.id})
### PRIVATE SCOPE ###
##
# Kind of constructor: these actions will be realized first when the controller is loaded
##
initialize = ->
$scope.loadMoreEvents()
## !!! MUST BE CALLED AT THE END of the controller
initialize()
]
Application.Controllers.controller "ShowEventController", ["$scope", "$state", "$stateParams", "Event", '$uibModal', 'Member', 'Reservation', 'Price', 'CustomAsset', 'eventPromise', 'reducedAmountAlert', 'growl', '_t'
($scope, $state, $stateParams, Event, $uibModal, Member, Reservation, Price, CustomAsset, eventPromise, reducedAmountAlert, growl, _t) ->
### PUBLIC SCOPE ###
$scope.reducedAmountAlert = reducedAmountAlert.setting.value
## reservations for the currently shown event
$scope.reservations = []
## user to deal with
$scope.ctrl =
member: {}
## parameters for a new reservation
$scope.reserve =
nbPlaces: []
nbReducedPlaces: []
nbReservePlaces: 0
nbReserveReducedPlaces: 0
toReserve: false
amountTotal : 0
# get the details for the current event (event's id is recovered from the current URL)
$scope.event = eventPromise
##
# Callback to delete the provided event (admins only)
# @param event {$resource} angular's Event $resource
##
$scope.deleteEvent = (event) ->
event.$delete ->
$state.go('app.public.events_list')
##
# Callback to call when the number of places change in the current booking
##
$scope.changeNbPlaces = ->
reste = $scope.event.nb_free_places - $scope.reserve.nbReservePlaces
$scope.reserve.nbReducedPlaces = [0..reste]
$scope.computeEventAmount()
##
# Callback to call when the number of discounted places change in the current booking
##
$scope.changeNbReducedPlaces = ->
reste = $scope.event.nb_free_places - $scope.reserve.nbReserveReducedPlaces
$scope.reserve.nbPlaces = [0..reste]
$scope.computeEventAmount()
##
# Callback to reset the current reservation parameters
# @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
##
$scope.cancelReserve = (e)->
e.preventDefault()
resetEventReserve()
##
# Callback to allow the user to set the details for his reservation
##
$scope.reserveEvent = ->
if $scope.event.nb_total_places > 0
$scope.reserveSuccess = false
if !$scope.isAuthenticated()
$scope.login null, (user)->
$scope.reserve.toReserve = !$scope.reserve.toReserve
if user.role isnt 'admin'
$scope.ctrl.member = user
else
$scope.reserve.toReserve = !$scope.reserve.toReserve
##
# Callback to deal with the reservations of the user selected in the dropdown list instead of the current user's
# reservations. (admins only)
##
$scope.updateMember = ->
resetEventReserve()
$scope.reserveSuccess = false
if $scope.ctrl.member
Member.get {id: $scope.ctrl.member.id}, (member) ->
$scope.ctrl.member = member
getReservations($scope.event.id, 'Event', $scope.ctrl.member.id)
##
# Callback to trigger the payment process of the current reservation
##
$scope.payEvent = ->
# first, we check that a user was selected
if Object.keys($scope.ctrl.member).length > 0
reservation = mkReservation($scope.ctrl.member, $scope.reserve, $scope.event)
if $scope.currentUser.role isnt 'admin' and $scope.reserve.amountTotal > 0
payByStripe(reservation)
else
if $scope.currentUser.role is 'admin' or $scope.reserve.amountTotal is 0
payOnSite(reservation)
else
# otherwise we alert, this error musn't occur when the current user is not admin
growl.error(_t('please_select_a_member_first'))
##
# Callback to validate the booking of a free event
##
$scope.validReserveEvent = ->
reservation =
user_id: $scope.ctrl.member.id
reservable_id: $scope.event.id
reservable_type: 'Event'
slots_attributes: []
nb_reserve_places: $scope.reserve.nbReservePlaces
nb_reserve_reduced_places: $scope.reserve.nbReserveReducedPlaces
reservation.slots_attributes.push
start_at: $scope.event.start_date
end_at: $scope.event.end_date
availability_id: $scope.event.availability.id
$scope.attempting = true
Reservation.save reservation: reservation, (reservation) ->
afterPayment(reservation)
$scope.attempting = false
, (response)->
$scope.alerts = []
$scope.alerts.push
msg: response.data.card[0]
type: 'danger'
$scope.attempting = false
##
# Callback to alter an already booked reservation date. A modal window will be opened to allow the user to choose
# a new date for his reservation (if any available)
# @param reservation {{id:number, reservable_id:number, nb_reserve_places:number, nb_reserve_reduced_places:number}}
# @param e {Object} see https://docs.angularjs.org/guide/expression#-event-
##
$scope.modifyReservation = (reservation, e)->
e.preventDefault()
e.stopPropagation()
index = $scope.reservations.indexOf(reservation)
$uibModal.open
templateUrl: '<%= asset_path "events/modify_event_reservation_modal.html" %>'
resolve:
event: -> $scope.event
reservation: -> reservation
controller: ['$scope', '$uibModalInstance', 'event', 'reservation', 'Reservation', ($scope, $uibModalInstance, event, reservation, Reservation) ->
# we copy the controller's resolved parameters into the scope
$scope.event = event
$scope.reservation = angular.copy reservation
# set the reservable_id to the first available event
for e in event.recurrence_events
if e.nb_free_places > (reservation.nb_reserve_places + reservation.nb_reserve_reduced_places)
$scope.reservation.reservable_id = e.id
break
# Callback to validate the new reservation's date
$scope.ok = ->
eventToPlace = null
angular.forEach event.recurrence_events, (e)->
if e.id is parseInt($scope.reservation.reservable_id, 10)
eventToPlace = e
$scope.reservation.slots[0].start_at = eventToPlace.start_date
$scope.reservation.slots[0].end_at = eventToPlace.end_date
$scope.reservation.slots[0].availability_id = eventToPlace.availability_id
$scope.reservation.slots_attributes = $scope.reservation.slots
$scope.attempting = true
Reservation.update {id: reservation.id}, {reservation: $scope.reservation}, (reservation) ->
$uibModalInstance.close(reservation)
$scope.attempting = true
, (response)->
$scope.alerts = []
angular.forEach response, (v, k)->
angular.forEach v, (err)->
$scope.alerts.push({msg: k+': '+err, type: 'danger'})
$scope.attempting = false
# Callback to cancel the modification
$scope.cancel = ->
$uibModalInstance.dismiss('cancel')
]
.result['finally'](null).then (reservation)->
$scope.reservations.splice(index, 1)
$scope.event.nb_free_places = $scope.event.nb_free_places + reservation.nb_reserve_places + reservation.nb_reserve_reduced_places
angular.forEach $scope.event.recurrence_events, (e)->
if e.id is parseInt(reservation.reservable_id, 10)
e.nb_free_places = e.nb_free_places - reservation.nb_reserve_places - reservation.nb_reserve_reduced_places
##
# Checks if the provided reservation is able to be modified
# @param reservation {{nb_reserve_places:number, nb_reserve_reduced_places:number}}
##
$scope.reservationCanModify = (reservation)->
isAble = false
angular.forEach $scope.event.recurrence_events, (e)->
isAble = true if e.nb_free_places > (reservation.nb_reserve_places + reservation.nb_reserve_reduced_places)
isAble
##
# Compute the total amount for the current reservation according to the previously set parameters
# and assign the result in $scope.reserve.amountTotal
##
$scope.computeEventAmount = ->
# first we check that a user was selected
if Object.keys($scope.ctrl.member).length > 0
r = mkReservation($scope.ctrl.member, $scope.reserve, $scope.event)
Price.compute {reservation: r}, (res) ->
$scope.reserve.amountTotal = res.price
else
$scope.reserve.amountTotal = null
### PRIVATE SCOPE ###
##
# Kind of constructor: these actions will be realized first when the controller is loaded
##
initialize = ->
# gather the current user or the list of users if the current user is an admin
if $scope.currentUser
if $scope.currentUser.role isnt 'admin'
$scope.ctrl.member = $scope.currentUser
# check that the event's reduced rate is initialized
if !$scope.event.reduced_amount
$scope.event.reduced_amount = 0
# initialize the "reserve" object with the event's data
$scope.reserve.nbPlaces = [0..$scope.event.nb_free_places]
$scope.reserve.nbReducedPlaces = [0..$scope.event.nb_free_places]
# if non-admin, get the current user's reservations into $scope.reservations
if $scope.currentUser
getReservations($scope.event.id, 'Event', $scope.currentUser.id)
##
# Retrieve the reservations for the couple event / user
# @param reservable_id {number} the current event id
# @param reservable_type {string} 'Event'
# @param user_id {number} the user's id (current or managed)
##
getReservations = (reservable_id, reservable_type, user_id)->
Reservation.query(reservable_id: reservable_id, reservable_type: reservable_type, user_id: user_id).$promise.then (reservations)->
$scope.reservations = reservations
##
# Create an hash map implementing the Reservation specs
# @param member {Object} User as retreived from the API: current user / selected user if current is admin
# @param reserve {Object} Reservation parameters (places...)
# @param event {Object} Current event (Atelier/Stage)
# @return {{user_id:Number, reservable_id:Number, reservable_type:String, slots_attributes:Array<Object>, nb_reserve_places:Number, nb_reserve_reduced_places:Number}}
##
mkReservation = (member, reserve, event) ->
reservation =
user_id: member.id
reservable_id: event.id
reservable_type: 'Event'
slots_attributes: []
nb_reserve_places: reserve.nbReservePlaces
nb_reserve_reduced_places: reserve.nbReserveReducedPlaces
reservation.slots_attributes.push
start_at: event.start_date
end_at: event.end_date
availability_id: event.availability.id
offered: event.offered || false
reservation
##
# Set the current reservation to the default values. This implies to reservation form to be hidden.
##
resetEventReserve = ->
if $scope.event
$scope.reserve =
nbPlaces: [0..$scope.event.nb_free_places]
nbReducedPlaces: [0..$scope.event.nb_free_places]
nbReservePlaces: 0
nbReserveReducedPlaces: 0
toReserve: false
amountTotal : 0
$scope.event.offered = false
##
# Open a modal window which trigger the stripe payment process
# @param reservation {Object} to book
##
payByStripe = (reservation) ->
$uibModal.open
templateUrl: '<%= asset_path "stripe/payment_modal.html" %>'
size: 'md'
resolve:
reservation: ->
reservation
price: ->
Price.compute({reservation: reservation}).$promise
cgv: ->
CustomAsset.get({name: 'cgv-file'}).$promise
objectToPay: ->
eventToReserve: $scope.event
reserve: $scope.reserve
member: $scope.ctrl.member
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'cgv', 'Auth', 'Reservation', 'growl', ($scope, $uibModalInstance, $state, reservation, price, cgv, Auth, Reservation, growl) ->
# Price
$scope.amount = price.price
# CGV
$scope.cgv = cgv.custom_asset
# Reservation
$scope.reservation = reservation
# Callback for the stripe payment authorization
$scope.payment = (status, response) ->
if response.error
growl.error(response.error.message)
else
$scope.attempting = true
$scope.reservation.card_token = response.id
Reservation.save reservation: $scope.reservation, (reservation) ->
$uibModalInstance.close(reservation)
, (response)->
$scope.alerts = []
$scope.alerts.push
msg: response.data.card[0]
type: 'danger'
$scope.attempting = false
]
.result['finally'](null).then (reservation)->
afterPayment(reservation)
##
# Open a modal window which trigger the local payment process
# @param reservation {Object} to book
##
payOnSite = (reservation) ->
$uibModal.open
templateUrl: '<%= asset_path "shared/valid_reservation_modal.html" %>'
size: 'sm'
resolve:
reservation: ->
reservation
price: ->
Price.compute({reservation: reservation}).$promise
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'Auth', 'Reservation', ($scope, $uibModalInstance, $state, reservation, price, Auth, Reservation) ->
# Price
$scope.amount = price.price
# Reservation
$scope.reservation = reservation
# Button label
if $scope.amount > 0
$scope.validButtonName = _t('confirm_(payment_on_site)')
else
$scope.validButtonName = _t('confirm')
# Callback to validate the payment
$scope.ok = ->
$scope.attempting = true
Reservation.save reservation: $scope.reservation, (reservation) ->
$uibModalInstance.close(reservation)
$scope.attempting = true
, (response)->
$scope.alerts = []
angular.forEach response, (v, k)->
angular.forEach v, (err)->
$scope.alerts.push
msg: k+': '+err
type: 'danger'
$scope.attempting = false
# Callback to cancel the payment
$scope.cancel = ->
$uibModalInstance.dismiss('cancel')
]
.result['finally'](null).then (reservation)->
afterPayment(reservation)
##
# What to do after the payment was successful
# @param resveration {Object} booked reservation
##
afterPayment = (reservation)->
$scope.event.nb_free_places = $scope.event.nb_free_places - reservation.nb_reserve_places - reservation.nb_reserve_reduced_places
resetEventReserve()
$scope.reserveSuccess = true
$scope.reservations.push reservation
if $scope.currentUser.role == 'admin'
$scope.ctrl.member = null
## !!! MUST BE CALLED AT THE END of the controller
initialize()
]