2015-05-05 03:10:25 +02:00
class API :: MembersController < API :: ApiController
before_action :authenticate_user! , except : [ :last_subscribed ]
2016-03-23 18:39:41 +01:00
before_action :set_member , only : [ :update , :destroy , :merge ]
2015-05-05 03:10:25 +02:00
respond_to :json
def index
2016-03-23 18:39:41 +01:00
@requested_attributes = params [ :requested_attributes ]
2016-06-23 11:42:10 +02:00
@query = policy_scope ( User )
2016-06-16 16:09:22 +02:00
unless params [ :page ] . nil? and params [ :size ] . nil?
2016-06-23 11:42:10 +02:00
@query = @query . page ( params [ :page ] . to_i ) . per ( params [ :size ] . to_i )
2016-06-16 16:09:22 +02:00
end
2016-06-23 11:42:10 +02:00
# remove unmerged profiles from list
@members = @query . to_a
2018-12-12 17:24:31 +01:00
@members . delete_if ( & :need_completion? )
2015-05-05 03:10:25 +02:00
end
def last_subscribed
2016-06-27 12:49:20 +02:00
@query = User . active . with_role ( :member ) . includes ( profile : [ :user_avatar ] ) . where ( 'is_allow_contact = true AND confirmed_at IS NOT NULL' ) . order ( 'created_at desc' ) . limit ( params [ :last ] )
2016-06-23 11:42:10 +02:00
# remove unmerged profiles from list
@members = @query . to_a
2018-12-12 17:24:31 +01:00
@members . delete_if ( & :need_completion? )
2016-06-23 11:42:10 +02:00
2016-03-23 18:39:41 +01:00
@requested_attributes = [ 'profile' ]
2015-05-05 03:10:25 +02:00
render :index
end
def show
@member = User . friendly . find ( params [ :id ] )
authorize @member
end
def create
authorize User
if ! user_params [ :password ] and ! user_params [ :password_confirmation ]
generated_password = Devise . friendly_token . first ( 8 )
@member = User . new ( user_params . merge ( password : generated_password ) . permit! )
else
@member = User . new ( user_params . permit! )
end
2016-03-23 18:39:41 +01:00
# if the user is created by an admin and the authentication is made through an SSO, generate a migration token
if current_user . is_admin? and AuthProvider . active . providable_type != DatabaseProvider . name
@member . generate_auth_migration_token
end
2015-05-05 03:10:25 +02:00
if @member . save
2018-12-10 13:24:00 +01:00
@member . generate_subscription_invoice
2015-05-05 03:10:25 +02:00
@member . send_confirmation_instructions
if ! user_params [ :password ] and ! user_params [ :password_confirmation ]
2016-03-23 18:39:41 +01:00
UsersMailer . delay . notify_user_account_created ( @member , generated_password )
2015-05-05 03:10:25 +02:00
else
2016-03-23 18:39:41 +01:00
UsersMailer . delay . notify_user_account_created ( @member , user_params [ :password ] )
2015-05-05 03:10:25 +02:00
end
render :show , status : :created , location : member_path ( @member )
else
render json : @member . errors , status : :unprocessable_entity
end
end
def update
authorize @member
2018-12-12 17:24:31 +01:00
members_service = MembersService . new ( @member )
2015-05-05 03:10:25 +02:00
2018-12-12 17:24:31 +01:00
if user_params [ :group_id ] && @member . group_id != user_params [ :group_id ] . to_i && ! @member . subscribed_plan . nil?
2016-03-23 18:39:41 +01:00
# here a group change is requested but unprocessable, handle the exception
@member . errors [ :group_id ] = t ( 'members.unable_to_change_the_group_while_a_subscription_is_running' )
2015-05-05 03:10:25 +02:00
render json : @member . errors , status : :unprocessable_entity
2016-03-23 18:39:41 +01:00
else
# otherwise, run the user update
2018-12-12 17:24:31 +01:00
if members_service . update ( user_params )
2016-03-23 18:39:41 +01:00
# Update password without logging out
2018-12-12 17:24:31 +01:00
sign_in ( @member , bypass : true ) unless current_user . id != params [ :id ] . to_i
2016-03-23 18:39:41 +01:00
render :show , status : :ok , location : member_path ( @member )
else
render json : @member . errors , status : :unprocessable_entity
end
end
end
def destroy
authorize @member
@member . soft_destroy
sign_out ( @member )
head :no_content
end
2016-03-31 11:52:49 +02:00
# export subscriptions
2016-03-23 18:39:41 +01:00
def export_subscriptions
authorize :export
2016-07-12 13:10:06 +02:00
2018-12-12 17:24:31 +01:00
export = Export . where ( category : 'users' , export_type : 'subscriptions' ) . where ( 'created_at > ?' , Subscription . maximum ( 'updated_at' ) ) . last
2016-07-27 17:00:06 +02:00
if export . nil? || ! FileTest . exist? ( export . file )
2018-12-12 17:24:31 +01:00
@export = Export . new ( category : 'users' , export_type : 'subscriptions' , user : current_user )
2016-07-27 17:00:06 +02:00
if @export . save
2018-12-12 17:24:31 +01:00
render json : { export_id : @export . id } , status : :ok
2016-07-27 17:00:06 +02:00
else
render json : @export . errors , status : :unprocessable_entity
end
else
2018-12-12 17:24:31 +01:00
send_file File . join ( Rails . root , export . file ) ,
type : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ,
disposition : 'attachment'
2016-07-27 17:00:06 +02:00
end
2016-03-23 18:39:41 +01:00
end
# export reservations
def export_reservations
authorize :export
2016-07-12 13:00:56 +02:00
2018-12-12 17:24:31 +01:00
export = Export . where ( category : 'users' , export_type : 'reservations' )
. where ( 'created_at > ?' , Reservation . maximum ( 'updated_at' ) )
. last
2016-07-27 17:00:06 +02:00
if export . nil? || ! FileTest . exist? ( export . file )
2018-12-12 17:24:31 +01:00
@export = Export . new ( category : 'users' , export_type : 'reservations' , user : current_user )
2016-07-27 17:00:06 +02:00
if @export . save
2018-12-12 17:24:31 +01:00
render json : { export_id : @export . id } , status : :ok
2016-07-27 17:00:06 +02:00
else
render json : @export . errors , status : :unprocessable_entity
end
else
2018-12-12 17:24:31 +01:00
send_file File . join ( Rails . root , export . file ) ,
type : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ,
disposition : 'attachment'
2016-07-27 17:00:06 +02:00
end
2015-05-05 03:10:25 +02:00
end
def export_members
authorize :export
2016-07-12 12:48:26 +02:00
2018-12-12 17:24:31 +01:00
export = Export . where ( category : 'users' , export_type : 'members' )
. where ( 'created_at > ?' , User . with_role ( :member ) . maximum ( 'updated_at' ) )
. last
2016-07-27 17:00:06 +02:00
if export . nil? || ! FileTest . exist? ( export . file )
2018-12-12 17:24:31 +01:00
@export = Export . new ( category : 'users' , export_type : 'members' , user : current_user )
2016-07-27 17:00:06 +02:00
if @export . save
2018-12-12 17:24:31 +01:00
render json : { export_id : @export . id } , status : :ok
2016-07-27 17:00:06 +02:00
else
render json : @export . errors , status : :unprocessable_entity
end
else
2018-12-12 17:24:31 +01:00
send_file File . join ( Rails . root , export . file ) ,
type : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ,
disposition : 'attachment'
2016-07-27 17:00:06 +02:00
end
2015-05-05 03:10:25 +02:00
end
2016-03-23 18:39:41 +01:00
def merge
authorize @member
# here the user query to be mapped to his already existing account
token = params . require ( :user ) . permit ( :auth_token ) [ :auth_token ]
2016-11-23 16:30:19 +01:00
@account = User . find_by ( auth_token : token )
2016-03-23 18:39:41 +01:00
if @account
2018-12-12 17:24:31 +01:00
members_service = MembersService . new ( @account )
2016-03-23 18:39:41 +01:00
begin
2018-12-12 17:24:31 +01:00
if members_service . merge_from_sso ( @member )
2016-03-23 18:39:41 +01:00
@member = @account
# finally, log on the real account
2018-12-12 17:24:31 +01:00
sign_in ( @member , bypass : true )
2016-03-23 18:39:41 +01:00
render :show , status : :ok , location : member_path ( @member )
else
render json : @member . errors , status : :unprocessable_entity
end
rescue DuplicateIndexError = > error
2018-12-12 17:24:31 +01:00
render json : { error : t ( 'members.please_input_the_authentication_code_sent_to_the_address' , EMAIL : error . message ) } , status : :unprocessable_entity
2016-03-23 18:39:41 +01:00
end
else
2018-12-12 17:24:31 +01:00
render json : { error : t ( 'members.your_authentication_code_is_not_valid' ) } , status : :unprocessable_entity
2016-03-23 18:39:41 +01:00
end
end
2016-05-30 15:39:19 +02:00
def list
authorize User
p = params . require ( :query ) . permit ( :search , :order_by , :page , :size )
2018-12-12 17:24:31 +01:00
render json : { error : 'page must be an integer' } , status : :unprocessable_entity unless p [ :page ] . is_a? Integer
render json : { error : 'size must be an integer' } , status : :unprocessable_entity unless p [ :size ] . is_a? Integer
2016-05-30 15:39:19 +02:00
direction = ( p [ :order_by ] [ 0 ] == '-' ? 'DESC' : 'ASC' )
order_key = ( p [ :order_by ] [ 0 ] == '-' ? p [ :order_by ] [ 1 , p [ :order_by ] . size ] : p [ :order_by ] )
2018-12-12 17:24:31 +01:00
order_key = case order_key
when 'last_name'
'profiles.last_name'
when 'first_name'
'profiles.first_name'
when 'email'
'users.email'
when 'phone'
'profiles.phone'
when 'group'
'groups.name'
when 'plan'
'plans.base_name'
else
'users.id'
end
2016-05-30 15:39:19 +02:00
2016-06-27 12:47:03 +02:00
@query = User . includes ( :profile , :group , :subscriptions )
2018-12-12 17:24:31 +01:00
. joins ( :profile , :group , :roles , 'LEFT JOIN "subscriptions" ON "subscriptions"."user_id" = "users"."id" LEFT JOIN "plans" ON "plans"."id" = "subscriptions"."plan_id"' )
. where ( " users.is_active = 'true' AND roles.name = 'member' " )
. order ( " #{ order_key } #{ direction } " )
. page ( p [ :page ] )
. per ( p [ :size ] )
2016-05-30 15:39:19 +02:00
# ILIKE => PostgreSQL case-insensitive LIKE
2016-06-23 11:42:10 +02:00
@query = @query . where ( 'profiles.first_name ILIKE :search OR profiles.last_name ILIKE :search OR profiles.phone ILIKE :search OR email ILIKE :search OR groups.name ILIKE :search OR plans.base_name ILIKE :search' , search : " % #{ p [ :search ] } % " ) if p [ :search ] . size > 0
@members = @query . to_a
2016-05-30 15:39:19 +02:00
end
2016-06-14 09:57:39 +02:00
def search
@members = User . includes ( :profile )
2018-12-12 17:24:31 +01:00
. joins ( :profile , :roles , 'LEFT JOIN "subscriptions" ON "subscriptions"."user_id" = "users"."id"' )
. where ( " users.is_active = 'true' AND roles.name = 'member' " )
. where ( " lower(f_unaccent(profiles.first_name)) ~ regexp_replace(:search, E' \\ \\ s+', '|') OR lower(f_unaccent(profiles.last_name)) ~ regexp_replace(:search, E' \\ \\ s+', '|') " , search : params [ :query ] . downcase )
2016-06-14 09:57:39 +02:00
2016-06-16 09:30:38 +02:00
if current_user . is_member?
# non-admin can only retrieve users with "public profiles"
@members = @members . where ( " users.is_allow_contact = 'true' " )
else
# only admins have the ability to filter by subscription
if params [ :subscription ] === 'true'
@members = @members . where ( 'subscriptions.id IS NOT NULL AND subscriptions.expired_at >= :now' , now : Date . today . to_s )
elsif params [ :subscription ] === 'false'
@members = @members . where ( 'subscriptions.id IS NULL OR subscriptions.expired_at < :now' , now : Date . today . to_s )
end
2016-06-14 09:57:39 +02:00
end
2016-06-23 11:42:10 +02:00
@members = @members . to_a
2016-06-14 09:57:39 +02:00
end
2016-06-21 14:39:44 +02:00
def mapping
authorize User
@members = User . includes ( :profile )
end
2015-05-05 03:10:25 +02:00
private
2018-12-12 17:24:31 +01:00
def set_member
@member = User . find ( params [ :id ] )
end
def user_params
if current_user . id == params [ :id ] . to_i
params . require ( :user ) . permit ( :username , :email , :password , :password_confirmation , :group_id , :is_allow_contact ,
:is_allow_newsletter ,
profile_attributes : [ :id , :first_name , :last_name , :gender , :birthday , :phone , :interest ,
:software_mastered , :website , :job , :facebook , :twitter ,
:google_plus , :viadeo , :linkedin , :instagram , :youtube , :vimeo ,
:dailymotion , :github , :echosciences , :pinterest , :lastfm , :flickr ,
user_avatar_attributes : % i [ id attachment destroy ] ,
address_attributes : % i [ id address ] ,
organization_attributes : [ :id , :name ,
address_attributes : % i [ id address ] ] ] )
elsif current_user . is_admin?
params . require ( :user ) . permit ( :username , :email , :password , :password_confirmation , :invoicing_disabled ,
:is_allow_contact , :is_allow_newsletter , :group_id ,
training_ids : [ ] , tag_ids : [ ] ,
profile_attributes : [ :id , :first_name , :last_name , :gender , :birthday , :phone , :interest ,
:software_mastered , :website , :job , :facebook , :twitter ,
:google_plus , :viadeo , :linkedin , :instagram , :youtube , :vimeo ,
:dailymotion , :github , :echosciences , :pinterest , :lastfm , :flickr ,
user_avatar_attributes : % i [ id attachment destroy ] ,
address_attributes : % i [ id address ] ,
organization_attributes : [ :id , :name ,
address_attributes : % i [ id address ] ] ] )
2016-03-23 18:39:41 +01:00
2015-05-05 03:10:25 +02:00
end
2018-12-12 17:24:31 +01:00
end
2015-05-05 03:10:25 +02:00
end