@@ -29,105 +29,112 @@ sub initialize ($c) {
29
29
my $achievementID = $c -> stash(' achievementID' );
30
30
my $user = $c -> param(' user' );
31
31
32
- # Make sure this is defined for the template.
33
- $c -> stash-> {userRecords } = [];
32
+ # Make sure these are defined for the template.
33
+ $c -> stash-> {userRecords } = [];
34
+ $c -> stash-> {userAchievementRecords } = [];
34
35
35
36
# Check permissions
36
37
return unless $authz -> hasPermissions($user , ' edit_achievements' );
37
38
38
- my @all_users = $db -> listUsers;
39
+ $c -> stash-> {userRecords } =
40
+ [ $db -> getUsersWhere({ user_id => { not_like => ' set_id:%' } }, [qw/ section last_name first_name/ ]) ];
41
+ $c -> stash-> {userAchievementRecords } =
42
+ { map { $_ -> user_id => $_ } $db -> getUserAchievementsWhere({ achievement_id => $achievementID }) };
43
+
39
44
my %selectedUsers = map { $_ => 1 } $c -> param(' selected' );
40
45
41
46
my $doAssignToSelected = 0;
42
47
43
- # Check and see if we need to assign or unassign things
48
+ # Check and see if we need to assign or unassign achievements.
44
49
if (defined $c -> param(' assignToAll' )) {
45
50
$c -> addgoodmessage($c -> maketext(' Achievement has been assigned to all users.' ));
46
- %selectedUsers = map { $_ => 1 } @all_users ;
51
+ %selectedUsers = map { $_ -> user_id => 1 } @{ $c -> stash -> { userRecords } } ;
47
52
$doAssignToSelected = 1;
48
53
} elsif (defined $c -> param(' unassignFromAll' )
49
54
&& defined ($c -> param(' unassignFromAllSafety' ))
50
55
&& $c -> param(' unassignFromAllSafety' ) == 1)
51
56
{
52
57
%selectedUsers = ();
53
- $c -> addbadmessage ($c -> maketext(' Achievement has been unassigned to all students .' ));
58
+ $c -> addgoodmessage ($c -> maketext(' Achievement has been unassigned from all users .' ));
54
59
$doAssignToSelected = 1;
55
60
} elsif (defined $c -> param(' assignToSelected' )) {
56
61
$c -> addgoodmessage($c -> maketext(' Achievement has been assigned to selected users.' ));
57
62
$doAssignToSelected = 1;
58
63
} elsif (defined $c -> param(' unassignFromAll' )) {
59
- # no action taken
60
64
$c -> addbadmessage($c -> maketext(' No action taken' ));
61
65
}
62
66
63
- # do actual assignment and unassignment
67
+ # Do the actual assignment and unassignment.
64
68
if ($doAssignToSelected ) {
69
+ my $achievement = $db -> getAchievement($achievementID );
70
+
71
+ my %globalUserAchievements = map { $_ -> user_id => $_ } $db -> getGlobalUserAchievementsWhere;
65
72
66
- my %achievementUsers = map { $_ => 1 } $db -> listAchievementUsers($achievementID );
67
- foreach my $selectedUser (@all_users ) {
68
- if (exists $selectedUsers {$selectedUser } && $achievementUsers {$selectedUser }) {
69
- # update existing user data (in case fields were changed)
70
- my $userAchievement = $db -> getUserAchievement($selectedUser , $achievementID );
73
+ my (
74
+ @userAchievementsToInsert , @userAchievementsToUpdate , @userAchievementsToDelete ,
75
+ @globalUserAchievementsToInsert , @globalUserAchievementsToUpdate ,
76
+ );
77
+
78
+ for my $user (@{ $c -> stash-> {userRecords } }) {
79
+ my $userID = $user -> user_id;
80
+ if ($selectedUsers {$userID } && $c -> stash-> {userAchievementRecords }{$userID }) {
81
+ # Update existing user data (in case fields were changed).
82
+ my $updatedEarned = $c -> param(" $userID .earned" ) ? 1 : 0;
83
+ my $earned = $c -> stash-> {userAchievementRecords }{$userID }-> earned ? 1 : 0;
71
84
72
- my $updatedEarned = $c -> param(" $selectedUser .earned" ) ? 1 : 0;
73
- my $earned = $userAchievement -> earned ? 1 : 0;
74
85
if ($updatedEarned != $earned ) {
86
+ $c -> stash-> {userAchievementRecords }{$userID }-> earned($updatedEarned );
75
87
76
- $userAchievement -> earned($updatedEarned );
77
- my $globalUserAchievement = $db -> getGlobalUserAchievement($selectedUser );
78
- my $achievement = $db -> getAchievement($achievementID );
88
+ my $points = $achievement -> points || 0;
89
+ my $initialpoints = $globalUserAchievements {$userID }-> achievement_points || 0;
79
90
80
- my $points = $achievement -> points || 0;
81
- my $initialpoints = $globalUserAchievement -> achievement_points || 0;
82
- # add the correct number of points if we
83
- # are saying that the user now earned the
84
- # achievement, or remove them otherwise
91
+ # Add the correct number of points if we are saying that the
92
+ # user now earned the achievement, or remove them otherwise.
85
93
if ($updatedEarned ) {
86
-
87
- $globalUserAchievement -> achievement_points($initialpoints + $points );
94
+ $globalUserAchievements {$userID }-> achievement_points($initialpoints + $points );
88
95
} else {
89
- $globalUserAchievement -> achievement_points($initialpoints - $points );
96
+ $globalUserAchievements { $userID } -> achievement_points($initialpoints - $points );
90
97
}
91
98
92
- $db -> putGlobalUserAchievement( $globalUserAchievement );
99
+ push ( @globalUserAchievementsToUpdate , $globalUserAchievements { $userID } );
93
100
}
94
101
95
- $userAchievement -> counter($c -> param(" $selectedUser .counter" ));
96
- $db -> putUserAchievement($userAchievement );
97
-
98
- } elsif (exists $selectedUsers {$selectedUser }) {
99
- # add users that dont exist
100
- my $userAchievement = $db -> newUserAchievement();
101
- $userAchievement -> user_id($selectedUser );
102
- $userAchievement -> achievement_id($achievementID );
103
- $db -> addUserAchievement($userAchievement );
104
-
105
- # If they dont have global achievement data, then add that too
106
- if (not $db -> existsGlobalUserAchievement($selectedUser )) {
107
- my $globalUserAchievement = $db -> newGlobalUserAchievement();
108
- $globalUserAchievement -> user_id($selectedUser );
109
- $db -> addGlobalUserAchievement($globalUserAchievement );
102
+ my $updatedCounter = $c -> param(" $userID .counter" ) // ' ' ;
103
+ my $counter = $c -> stash-> {userAchievementRecords }{$userID }-> counter // ' ' ;
104
+ $c -> stash-> {userAchievementRecords }{$userID }-> counter($updatedCounter )
105
+ if $updatedCounter ne $counter ;
106
+
107
+ push (@userAchievementsToUpdate , $c -> stash-> {userAchievementRecords }{$userID })
108
+ if $updatedEarned != $earned || $updatedCounter ne $counter ;
109
+ } elsif ($selectedUsers {$userID }) {
110
+ # Add user achievements that don't exist.
111
+ $c -> stash-> {userAchievementRecords }{$userID } = $db -> newUserAchievement;
112
+ $c -> stash-> {userAchievementRecords }{$userID }-> user_id($userID );
113
+ $c -> stash-> {userAchievementRecords }{$userID }-> achievement_id($achievementID );
114
+ push (@userAchievementsToInsert , $c -> stash-> {userAchievementRecords }{$userID });
115
+
116
+ # If the user does not have global achievement data, then add that too.
117
+ if (!$globalUserAchievements {$userID }) {
118
+ $globalUserAchievements {$userID } = $db -> newGlobalUserAchievement(user_id => $userID );
119
+ push (@globalUserAchievementsToInsert , $globalUserAchievements {$userID });
110
120
}
111
-
112
121
} else {
113
- # delete users who are not selected
114
- # but dont delete users who dont exist
115
- next unless $achievementUsers { $selectedUser } ;
116
- $db -> deleteUserAchievement( $selectedUser , $achievementID ) ;
122
+ # Delete achievements for users that are not selected, but don't delete achievements that don't exist.
123
+ next unless $c -> stash -> { userAchievementRecords }{ $userID };
124
+ push ( @userAchievementsToDelete , $c -> stash -> { userAchievementRecords }{ $userID }) ;
125
+ delete $c -> stash -> { userAchievementRecords }{ $userID } ;
117
126
}
118
127
}
119
- }
120
128
121
- my @userRecords ;
122
- for my $currentUser (@all_users ) {
123
- my $userObj = $c -> db-> getUser($currentUser );
124
- die " Unable to find user object for $currentUser . " unless $userObj ;
125
- push (@userRecords , $userObj );
126
- }
127
- @userRecords =
128
- sort { (lc ($a -> section) cmp lc ($b -> section)) || (lc ($a -> last_name) cmp lc ($b -> last_name)) } @userRecords ;
129
+ $db -> GlobalUserAchievement-> insert_records(\@globalUserAchievementsToInsert ) if @globalUserAchievementsToInsert ;
130
+ $db -> GlobalUserAchievement-> update_records(\@globalUserAchievementsToUpdate ) if @globalUserAchievementsToUpdate ;
131
+ $db -> UserAchievement-> insert_records(\@userAchievementsToInsert ) if @userAchievementsToInsert ;
132
+ $db -> UserAchievement-> update_records(\@userAchievementsToUpdate ) if @userAchievementsToUpdate ;
129
133
130
- $c -> stash-> {userRecords } = \@userRecords ;
134
+ # This is one of the rare places this can be done since user achievements don't
135
+ # have any dependent rows in other tables that also need to be deleted.
136
+ $db -> UserAchievement-> delete_records(\@userAchievementsToDelete ) if @userAchievementsToDelete ;
137
+ }
131
138
132
139
return ;
133
140
}
0 commit comments