Version19.112.9

This commit is contained in:
Antonio Cañas Vargas 2020-01-05 14:09:28 +01:00
parent e747318bbf
commit e9bd881967
23 changed files with 192 additions and 163 deletions

View File

@ -1032,7 +1032,7 @@ int swad__loginBySessionKey (struct soap *soap,
/***** Get course (row[2]) *****/ /***** Get course (row[2]) *****/
Gbl.Hierarchy.Crs.CrsCod = Str_ConvertStrCodToLongCod (row[2]); Gbl.Hierarchy.Crs.CrsCod = Str_ConvertStrCodToLongCod (row[2]);
Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs);
loginBySessionKeyOut->courseCode = (int) Gbl.Hierarchy.Crs.CrsCod; loginBySessionKeyOut->courseCode = (int) Gbl.Hierarchy.Crs.CrsCod;
Str_Copy (loginBySessionKeyOut->courseName,Gbl.Hierarchy.Crs.FullName, Str_Copy (loginBySessionKeyOut->courseName,Gbl.Hierarchy.Crs.FullName,
Hie_MAX_BYTES_FULL_NAME); Hie_MAX_BYTES_FULL_NAME);
@ -3013,7 +3013,7 @@ int swad__getNotifications (struct soap *soap,
/* Get course (row[7]) */ /* Get course (row[7]) */
Crs.CrsCod = Str_ConvertStrCodToLongCod (row[7]); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[7]);
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
/* Get user's code of the user who caused the event (row[3]) */ /* Get user's code of the user who caused the event (row[3]) */
Gbl.Usrs.Other.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[3]); Gbl.Usrs.Other.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[3]);

View File

@ -492,7 +492,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD: En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 19.112.8 (2020-01-05)" #define Log_PLATFORM_VERSION "SWAD 19.112.9 (2020-01-05)"
#define CSS_FILE "swad19.112.css" #define CSS_FILE "swad19.112.css"
#define JS_FILE "swad19.91.1.js" #define JS_FILE "swad19.91.1.js"
/* /*
@ -501,7 +501,9 @@ ps2pdf source.ps destination.pdf
// TODO: No se puede entrar con DNI '1' suponiendo que no tenga password ¿por qué? // TODO: No se puede entrar con DNI '1' suponiendo que no tenga password ¿por qué?
// TODO: Mapas más estrechos en móvil // TODO: Mapas más estrechos en móvil
// TODO: Quitar todos los EXTRA_DATA. // TODO: Quitar todos los EXTRA_DATA.
// TODO: ¿ Cachear Usr_GetNumUsrsInCrssOfDeg ?
Version 19.112.9: Jan 05, 2020 Optimization in number of users in a course. (278419 lines)
Version 19.112.8: Jan 05, 2020 Optimization in number of courses in a degree. (278396 lines) Version 19.112.8: Jan 05, 2020 Optimization in number of courses in a degree. (278396 lines)
Version 19.112.7: Jan 05, 2020 Optimization in number of degrees in a centre. (278384 lines) Version 19.112.7: Jan 05, 2020 Optimization in number of degrees in a centre. (278384 lines)
Version 19.112.6: Jan 05, 2020 Optimization in number of courses in a centre. (278374 lines) Version 19.112.6: Jan 05, 2020 Optimization in number of courses in a centre. (278374 lines)

View File

@ -206,7 +206,7 @@ void Cht_ShowListOfAvailableChatRooms (void)
if ((Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0])) > 0) if ((Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0])) > 0)
{ {
/* Get data of this course */ /* Get data of this course */
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
/* Link to the room of this course */ /* Link to the room of this course */
IsLastItemInLevel[2] = (NumRow == NumRows - 1); IsLastItemInLevel[2] = (NumRow == NumRows - 1);
@ -557,7 +557,7 @@ void Cht_OpenChatWindow (void)
/* Get data of this course */ /* Get data of this course */
Crs.CrsCod = Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod; Crs.CrsCod = Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (ThisRoomShortName,sizeof (ThisRoomShortName), snprintf (ThisRoomShortName,sizeof (ThisRoomShortName),
"%s", "%s",

View File

@ -343,7 +343,7 @@ static void Crs_WriteListMyCoursesToSelectOne (void)
/***** Get data of this course *****/ /***** Get data of this course *****/
Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]);
if (!Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (!Crs_GetDataOfCourseByCod (&Crs))
Lay_ShowErrorAndExit ("Course not found."); Lay_ShowErrorAndExit ("Course not found.");
/***** Write link to course *****/ /***** Write link to course *****/
@ -658,14 +658,6 @@ static void Crs_GetListCrssInCurrentDeg (Crs_WhatCourses_t WhatCourses)
/* Get next course */ /* Get next course */
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
Crs_GetDataOfCourseFromRow (Crs,row); Crs_GetDataOfCourseFromRow (Crs,row);
/* Get number of users in this course */
Crs->NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod);
Crs->NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod);
Crs->NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod);
Crs->NumUsrs[Rol_UNK] = Crs->NumUsrs[Rol_STD] +
Crs->NumUsrs[Rol_NET] +
Crs->NumUsrs[Rol_TCH];
} }
} }
@ -865,6 +857,7 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year)
const char *BgColor; const char *BgColor;
Crs_StatusTxt_t StatusTxt; Crs_StatusTxt_t StatusTxt;
bool ThisYearHasCourses = false; bool ThisYearHasCourses = false;
unsigned NumUsrs[Rol_NUM_ROLES];
/***** Write all the courses of this year *****/ /***** Write all the courses of this year *****/
for (NumCrs = 0; for (NumCrs = 0;
@ -892,13 +885,19 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year)
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/* Get number of users */
NumUsrs[Rol_UNK] = Usr_GetNumUsrsInCrs (Rol_UNK,Crs->CrsCod);
NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod);
NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod);
NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod);
/* Put green tip if course has users */ /* Put green tip if course has users */
HTM_TD_Begin ("class=\"%s CM %s\" title=\"%s\"", HTM_TD_Begin ("class=\"%s CM %s\" title=\"%s\"",
TxtClassNormal,BgColor, TxtClassNormal,BgColor,
Crs->NumUsrs[Rol_UNK] ? Txt_COURSE_With_users : NumUsrs[Rol_UNK] ? Txt_COURSE_With_users :
Txt_COURSE_Without_users); Txt_COURSE_Without_users);
HTM_Txt (Crs->NumUsrs[Rol_UNK] ? "✓" : HTM_Txt (NumUsrs[Rol_UNK] ? "✓" :
" "); " ");
HTM_TD_End (); HTM_TD_End ();
/* Institutional code of the course */ /* Institutional code of the course */
@ -925,13 +924,13 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year)
/* Current number of teachers in this course */ /* Current number of teachers in this course */
HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor);
HTM_Unsigned (Crs->NumUsrs[Rol_TCH] + HTM_Unsigned (NumUsrs[Rol_TCH] +
Crs->NumUsrs[Rol_NET]); NumUsrs[Rol_NET]);
HTM_TD_End (); HTM_TD_End ();
/* Current number of students in this course */ /* Current number of students in this course */
HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor);
HTM_Unsigned (Crs->NumUsrs[Rol_STD]); HTM_Unsigned (NumUsrs[Rol_STD]);
HTM_TD_End (); HTM_TD_End ();
/* Course status */ /* Course status */
@ -1065,6 +1064,7 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year)
unsigned NumCrs; unsigned NumCrs;
struct UsrData UsrDat; struct UsrData UsrDat;
bool ICanEdit; bool ICanEdit;
unsigned NumUsrs[Rol_NUM_ROLES];
Crs_StatusTxt_t StatusTxt; Crs_StatusTxt_t StatusTxt;
unsigned StatusUnsigned; unsigned StatusUnsigned;
@ -1081,11 +1081,17 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year)
{ {
ICanEdit = Crs_CheckIfICanEdit (Crs); ICanEdit = Crs_CheckIfICanEdit (Crs);
/* Get number of users */
NumUsrs[Rol_UNK] = Usr_GetNumUsrsInCrs (Rol_UNK,Crs->CrsCod);
NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod);
NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod);
NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod);
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/* Put icon to remove course */ /* Put icon to remove course */
HTM_TD_Begin ("class=\"BM\""); HTM_TD_Begin ("class=\"BM\"");
if (Crs->NumUsrs[Rol_UNK] || // Course has users ==> deletion forbidden if (NumUsrs[Rol_UNK] || // Course has users ==> deletion forbidden
!ICanEdit) !ICanEdit)
Ico_PutIconRemovalNotAllowed (); Ico_PutIconRemovalNotAllowed ();
else // Crs->NumUsrs == 0 && ICanEdit else // Crs->NumUsrs == 0 && ICanEdit
@ -1168,13 +1174,13 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year)
/* Current number of teachers in this course */ /* Current number of teachers in this course */
HTM_TD_Begin ("class=\"DAT RM\""); HTM_TD_Begin ("class=\"DAT RM\"");
HTM_Unsigned (Crs->NumUsrs[Rol_TCH] + HTM_Unsigned (NumUsrs[Rol_TCH] +
Crs->NumUsrs[Rol_NET]); NumUsrs[Rol_NET]);
HTM_TD_End (); HTM_TD_End ();
/* Current number of students in this course */ /* Current number of students in this course */
HTM_TD_Begin ("class=\"DAT RM\""); HTM_TD_Begin ("class=\"DAT RM\"");
HTM_Unsigned (Crs->NumUsrs[Rol_STD]); HTM_Unsigned (NumUsrs[Rol_STD]);
HTM_TD_End (); HTM_TD_End ();
/* Course requester */ /* Course requester */
@ -1567,14 +1573,15 @@ void Crs_RemoveCourse (void)
Crs_EditingCrs->CrsCod = Crs_GetAndCheckParamOtherCrsCod (1); Crs_EditingCrs->CrsCod = Crs_GetAndCheckParamOtherCrsCod (1);
/***** Get data of the course from database *****/ /***** Get data of the course from database *****/
Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_EXTRA_DATA); Crs_GetDataOfCourseByCod (Crs_EditingCrs);
if (Crs_CheckIfICanEdit (Crs_EditingCrs)) if (Crs_CheckIfICanEdit (Crs_EditingCrs))
{ {
/***** Check if this course has users *****/ /***** Check if this course has users *****/
if (Crs_EditingCrs->NumUsrs[Rol_UNK]) // Course has users ==> don't remove if (Usr_GetNumUsrsInCrs (Rol_UNK,Crs_EditingCrs->CrsCod)) // Course has users ==> don't remove
Ale_ShowAlert (Ale_WARNING,Txt_To_remove_a_course_you_must_first_remove_all_users_in_the_course); Ale_ShowAlert (Ale_WARNING,
else // Course has no users ==> remove it Txt_To_remove_a_course_you_must_first_remove_all_users_in_the_course);
else // Course has no users ==> remove it
{ {
/***** Remove course *****/ /***** Remove course *****/
Crs_RemoveCourseCompletely (Crs_EditingCrs->CrsCod); Crs_RemoveCourseCompletely (Crs_EditingCrs->CrsCod);
@ -1594,8 +1601,7 @@ void Crs_RemoveCourse (void)
/********************* Get data of a course from its code ********************/ /********************* Get data of a course from its code ********************/
/*****************************************************************************/ /*****************************************************************************/
bool Crs_GetDataOfCourseByCod (struct Course *Crs, bool Crs_GetDataOfCourseByCod (struct Course *Crs)
Crs_GetExtraData_t GetExtraData)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -1608,10 +1614,6 @@ bool Crs_GetDataOfCourseByCod (struct Course *Crs,
Crs->RequesterUsrCod = -1L; Crs->RequesterUsrCod = -1L;
Crs->ShrtName[0] = '\0'; Crs->ShrtName[0] = '\0';
Crs->FullName[0] = '\0'; Crs->FullName[0] = '\0';
Crs->NumUsrs[Rol_UNK] =
Crs->NumUsrs[Rol_STD] =
Crs->NumUsrs[Rol_NET] =
Crs->NumUsrs[Rol_TCH] = 0;
/***** Check if course code is correct *****/ /***** Check if course code is correct *****/
if (Crs->CrsCod > 0) if (Crs->CrsCod > 0)
@ -1633,18 +1635,6 @@ bool Crs_GetDataOfCourseByCod (struct Course *Crs,
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
Crs_GetDataOfCourseFromRow (Crs,row); Crs_GetDataOfCourseFromRow (Crs,row);
/* Get extra data */
if (GetExtraData == Crs_GET_EXTRA_DATA)
{
/* Get number of users in this course */
Crs->NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod);
Crs->NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod);
Crs->NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod);
Crs->NumUsrs[Rol_UNK] = Crs->NumUsrs[Rol_STD] +
Crs->NumUsrs[Rol_NET] +
Crs->NumUsrs[Rol_TCH];
}
/* Set return value */ /* Set return value */
CrsFound = true; CrsFound = true;
} }
@ -1749,6 +1739,9 @@ void Crs_RemoveCourseCompletely (long CrsCod)
DB_QueryDELETE ("can not remove a course", DB_QueryDELETE ("can not remove a course",
"DELETE FROM courses WHERE CrsCod=%ld", "DELETE FROM courses WHERE CrsCod=%ld",
CrsCod); CrsCod);
/***** Flush caches *****/
Usr_FlushCacheNumUsrsInCrs ();
} }
} }
@ -1767,7 +1760,7 @@ static void Crs_EmptyCourseCompletely (long CrsCod)
{ {
/***** Get course data *****/ /***** Get course data *****/
Crs.CrsCod = CrsCod; Crs.CrsCod = CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_EXTRA_DATA); Crs_GetDataOfCourseByCod (&Crs);
/***** Remove all the students in the course *****/ /***** Remove all the students in the course *****/
Enr_RemAllStdsInCrs (&Crs); Enr_RemAllStdsInCrs (&Crs);
@ -1923,7 +1916,7 @@ void Crs_ChangeInsCrsCod (void)
Par_GetParToText ("InsCrsCod",NewInstitutionalCrsCod,Crs_MAX_BYTES_INSTITUTIONAL_CRS_COD); Par_GetParToText ("InsCrsCod",NewInstitutionalCrsCod,Crs_MAX_BYTES_INSTITUTIONAL_CRS_COD);
/* Get data of the course */ /* Get data of the course */
Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (Crs_EditingCrs);
if (Crs_CheckIfICanEdit (Crs_EditingCrs)) if (Crs_CheckIfICanEdit (Crs_EditingCrs))
{ {
@ -1969,7 +1962,7 @@ void Crs_ChangeCrsYear (void)
Par_GetParToText ("OthCrsYear",YearStr,2); Par_GetParToText ("OthCrsYear",YearStr,2);
NewYear = Deg_ConvStrToYear (YearStr); NewYear = Deg_ConvStrToYear (YearStr);
Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (Crs_EditingCrs);
if (Crs_CheckIfICanEdit (Crs_EditingCrs)) if (Crs_CheckIfICanEdit (Crs_EditingCrs))
{ {
@ -2100,7 +2093,7 @@ void Crs_RenameCourse (struct Course *Crs,Cns_ShrtOrFullName_t ShrtOrFullName)
Par_GetParToText (ParamName,NewCrsName,MaxBytes); Par_GetParToText (ParamName,NewCrsName,MaxBytes);
/***** Get from the database the data of the degree *****/ /***** Get from the database the data of the degree *****/
Crs_GetDataOfCourseByCod (Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (Crs);
if (Crs_CheckIfICanEdit (Crs)) if (Crs_CheckIfICanEdit (Crs))
{ {
@ -2201,7 +2194,7 @@ void Crs_ChangeCrsStatus (void)
Status = Crs_GetStatusBitsFromStatusTxt (StatusTxt); // New status Status = Crs_GetStatusBitsFromStatusTxt (StatusTxt); // New status
/***** Get data of course *****/ /***** Get data of course *****/
Crs_GetDataOfCourseByCod (Crs_EditingCrs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (Crs_EditingCrs);
/***** Update status in table of courses *****/ /***** Update status in table of courses *****/
DB_QueryUPDATE ("can not update the status of a course", DB_QueryUPDATE ("can not update the status of a course",
@ -2838,8 +2831,6 @@ void Crs_RemoveOldCrss (void)
static void Crs_EditingCourseConstructor (void) static void Crs_EditingCourseConstructor (void)
{ {
Rol_Role_t Role;
/***** Pointer must be NULL *****/ /***** Pointer must be NULL *****/
if (Crs_EditingCrs != NULL) if (Crs_EditingCrs != NULL)
Lay_ShowErrorAndExit ("Error initializing course."); Lay_ShowErrorAndExit ("Error initializing course.");
@ -2856,10 +2847,6 @@ static void Crs_EditingCourseConstructor (void)
Crs_EditingCrs->Status = 0; Crs_EditingCrs->Status = 0;
Crs_EditingCrs->ShrtName[0] = '\0'; Crs_EditingCrs->ShrtName[0] = '\0';
Crs_EditingCrs->FullName[0] = '\0'; Crs_EditingCrs->FullName[0] = '\0';
for (Role = (Rol_Role_t) 0;
Role <= (Rol_Role_t) (Rol_NUM_ROLES - 1);
Role++)
Crs_EditingCrs->NumUsrs[Role] = 0;
} }
static void Crs_EditingCourseDestructor (void) static void Crs_EditingCourseDestructor (void)

View File

@ -85,15 +85,8 @@ struct Course
long RequesterUsrCod; // User code of the person who requested the creation of this course long RequesterUsrCod; // User code of the person who requested the creation of this course
char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1]; // Short name of course char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1]; // Short name of course
char FullName[Hie_MAX_BYTES_FULL_NAME + 1]; // Full name of course char FullName[Hie_MAX_BYTES_FULL_NAME + 1]; // Full name of course
unsigned NumUsrs[Rol_NUM_ROLES]; // Number of users
}; };
typedef enum
{
Crs_GET_BASIC_DATA,
Crs_GET_EXTRA_DATA,
} Crs_GetExtraData_t;
/*****************************************************************************/ /*****************************************************************************/
/***************************** Public prototypes *****************************/ /***************************** Public prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
@ -120,8 +113,7 @@ void Crs_RecFormReqCrs (void);
void Crs_RecFormNewCrs (void); void Crs_RecFormNewCrs (void);
void Crs_RemoveCourse (void); void Crs_RemoveCourse (void);
bool Crs_GetDataOfCourseByCod (struct Course *Crs, bool Crs_GetDataOfCourseByCod (struct Course *Crs);
Crs_GetExtraData_t GetExtraData);
void Crs_RemoveCourseCompletely (long CrsCod); void Crs_RemoveCourseCompletely (long CrsCod);
void Crs_ChangeInsCrsCod (void); void Crs_ChangeInsCrsCod (void);
void Crs_ChangeCrsYear (void); void Crs_ChangeCrsYear (void);

View File

@ -427,7 +427,7 @@ static void CrsCfg_NumUsrsInCrs (Rol_Role_t Role)
/* Data */ /* Data */
HTM_TD_Begin ("class=\"DAT LB\""); HTM_TD_Begin ("class=\"DAT LB\"");
HTM_Unsigned (Gbl.Hierarchy.Crs.NumUsrs[Role]); HTM_Unsigned (Usr_GetNumUsrsInCrs (Role,Gbl.Hierarchy.Crs.CrsCod));
HTM_TD_End (); HTM_TD_End ();
HTM_TR_End (); HTM_TR_End ();

View File

@ -184,7 +184,7 @@ void Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs (void)
{ {
/***** Put link to register students *****/ /***** Put link to register students *****/
if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher
if (!Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]) // No students in course if (!Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // No students in course
Usr_ShowWarningNoUsersFound (Rol_STD); Usr_ShowWarningNoUsersFound (Rol_STD);
} }
@ -675,7 +675,7 @@ static void Enr_ShowFormRegRemSeveralUsrs (Rol_Role_t Role)
Enr_PutLinkToAdminOneUsr (ActReqMdfOneStd); Enr_PutLinkToAdminOneUsr (ActReqMdfOneStd);
/* Put link to remove all the students in the current course */ /* Put link to remove all the students in the current course */
if (Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]) // This course has students if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // This course has students
Enr_PutLinkToRemAllStdsThisCrs (); Enr_PutLinkToRemAllStdsThisCrs ();
break; break;
case Rol_NET: case Rol_NET:
@ -1821,17 +1821,18 @@ void Enr_AskRemAllStdsThisCrs (void)
extern const char *Hlp_USERS_Administration_remove_all_students; extern const char *Hlp_USERS_Administration_remove_all_students;
extern const char *Txt_Remove_all_students; extern const char *Txt_Remove_all_students;
extern const char *Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_; extern const char *Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_;
unsigned NumStds = Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod);
/***** Begin box *****/ /***** Begin box *****/
Box_BoxBegin (NULL,Txt_Remove_all_students,NULL, Box_BoxBegin (NULL,Txt_Remove_all_students,NULL,
Hlp_USERS_Administration_remove_all_students,Box_NOT_CLOSABLE); Hlp_USERS_Administration_remove_all_students,Box_NOT_CLOSABLE);
if (Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]) if (NumStds)
{ {
/***** Show question and button to remove students *****/ /***** Show question and button to remove students *****/
/* Start alert */ /* Start alert */
Ale_ShowAlertAndButton1 (Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_, Ale_ShowAlertAndButton1 (Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_,
Gbl.Hierarchy.Crs.NumUsrs[Rol_STD], NumStds,
Gbl.Hierarchy.Crs.FullName); Gbl.Hierarchy.Crs.FullName);
/* Show form to request confirmation */ /* Show form to request confirmation */
@ -2002,9 +2003,9 @@ void Enr_SignUpInCrs (void)
/***** Notify teachers or admins by email about the new enrolment request *****/ /***** Notify teachers or admins by email about the new enrolment request *****/
// If this course has teachers ==> send notification to teachers // If this course has teachers ==> send notification to teachers
// If this course has no teachers and I want to be a teacher ==> send notification to administrators or superusers // If this course has no teachers and I want to be a teacher ==> send notification to administrators or superusers
if (Gbl.Hierarchy.Crs.NumUsrs[Rol_TCH] || if (RoleFromForm == Rol_TCH) // TODO: What happens in user wants to enrole as a non-editing teacher?
RoleFromForm == Rol_TCH) if (Usr_GetNumUsrsInCrs (Rol_TCH,Gbl.Hierarchy.Crs.CrsCod))
Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod); Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod);
} }
} }
@ -2820,7 +2821,7 @@ static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected)
HTM_TD_End (); HTM_TD_End ();
/***** Link to course *****/ /***** Link to course *****/
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
Deg.DegCod = Crs.DegCod; Deg.DegCod = Crs.DegCod;
Deg_GetDataOfDegreeByCod (&Deg); Deg_GetDataOfDegreeByCod (&Deg);
HTM_TD_Begin ("class=\"DAT LT\""); HTM_TD_Begin ("class=\"DAT LT\"");
@ -2836,7 +2837,7 @@ static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected)
/***** Number of teachers in the course *****/ /***** Number of teachers in the course *****/
HTM_TD_Begin ("class=\"DAT RT\""); HTM_TD_Begin ("class=\"DAT RT\"");
HTM_Unsigned (Crs.NumUsrs[Rol_TCH]); HTM_Unsigned (Usr_GetNumUsrsInCrs (Rol_TCH,Crs.CrsCod));
HTM_TD_End (); HTM_TD_End ();
/***** User photo *****/ /***** User photo *****/

View File

@ -1607,7 +1607,7 @@ static void Exa_GetNotifContentExamAnnouncement (char **ContentStr)
/***** Get data of course *****/ /***** Get data of course *****/
Crs.CrsCod = Gbl.ExamAnns.ExaDat.CrsCod; Crs.CrsCod = Gbl.ExamAnns.ExaDat.CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
/***** Get data of degree *****/ /***** Get data of degree *****/
Deg.DegCod = Crs.DegCod; Deg.DegCod = Crs.DegCod;

View File

@ -6898,7 +6898,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>", "%s, %s <strong>%s</strong>",
Txt_documents_management_area, Txt_documents_management_area,
@ -6908,7 +6908,7 @@ static void Brw_WriteCurrentClipboard (void)
GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod;
Grp_GetDataOfGroupByCod (&GrpDat); Grp_GetDataOfGroupByCod (&GrpDat);
Crs.CrsCod = GrpDat.CrsCod; Crs.CrsCod = GrpDat.CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>", "%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>",
Txt_documents_management_area, Txt_documents_management_area,
@ -6917,7 +6917,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>", "%s, %s <strong>%s</strong>",
Txt_teachers_files_area, Txt_teachers_files_area,
@ -6927,7 +6927,7 @@ static void Brw_WriteCurrentClipboard (void)
GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod;
Grp_GetDataOfGroupByCod (&GrpDat); Grp_GetDataOfGroupByCod (&GrpDat);
Crs.CrsCod = GrpDat.CrsCod; Crs.CrsCod = GrpDat.CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>", "%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>",
Txt_teachers_files_area, Txt_teachers_files_area,
@ -6936,7 +6936,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>", "%s, %s <strong>%s</strong>",
Txt_shared_files_area, Txt_shared_files_area,
@ -6946,7 +6946,7 @@ static void Brw_WriteCurrentClipboard (void)
GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod;
Grp_GetDataOfGroupByCod (&GrpDat); Grp_GetDataOfGroupByCod (&GrpDat);
Crs.CrsCod = GrpDat.CrsCod; Crs.CrsCod = GrpDat.CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>", "%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>",
Txt_shared_files_area, Txt_shared_files_area,
@ -6955,7 +6955,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_ASG_USR: case Brw_ADMI_ASG_USR:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>, %s <strong>%s</strong>", "%s, %s <strong>%s</strong>, %s <strong>%s</strong>",
Txt_assignments_area, Txt_assignments_area,
@ -6964,7 +6964,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_WRK_USR: case Brw_ADMI_WRK_USR:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>, %s <strong>%s</strong>", "%s, %s <strong>%s</strong>, %s <strong>%s</strong>",
Txt_works_area, Txt_works_area,
@ -6973,7 +6973,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_ASG_CRS: case Brw_ADMI_ASG_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
Usr_UsrDataConstructor (&UsrDat); Usr_UsrDataConstructor (&UsrDat);
UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod;
Usr_GetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS); Usr_GetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS);
@ -6986,7 +6986,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_WRK_CRS: case Brw_ADMI_WRK_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
Usr_UsrDataConstructor (&UsrDat); Usr_UsrDataConstructor (&UsrDat);
UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod;
Usr_GetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS); Usr_GetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS);
@ -7003,7 +7003,7 @@ static void Brw_WriteCurrentClipboard (void)
Prj.PrjCod = Gbl.FileBrowser.Clipboard.Cod; Prj.PrjCod = Gbl.FileBrowser.Clipboard.Cod;
Prj_GetDataOfProjectByCod (&Prj); Prj_GetDataOfProjectByCod (&Prj);
Crs.CrsCod = Prj.CrsCod; Crs.CrsCod = Prj.CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>, %s <strong>%s</strong>", "%s, %s <strong>%s</strong>, %s <strong>%s</strong>",
Gbl.FileBrowser.Clipboard.FileBrowser == Brw_ADMI_DOC_PRJ ? Txt_project_documents : Gbl.FileBrowser.Clipboard.FileBrowser == Brw_ADMI_DOC_PRJ ? Txt_project_documents :
@ -7014,7 +7014,7 @@ static void Brw_WriteCurrentClipboard (void)
break; break;
case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>", "%s, %s <strong>%s</strong>",
Txt_marks_management_area, Txt_marks_management_area,
@ -7024,7 +7024,7 @@ static void Brw_WriteCurrentClipboard (void)
GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod;
Grp_GetDataOfGroupByCod (&GrpDat); Grp_GetDataOfGroupByCod (&GrpDat);
Crs.CrsCod = GrpDat.CrsCod; Crs.CrsCod = GrpDat.CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), snprintf (TxtClipboardZone,sizeof (TxtClipboardZone),
"%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>", "%s, %s <strong>%s</strong>, %s <strong>%s %s</strong>",
Txt_marks_management_area, Txt_marks_management_area,
@ -7906,7 +7906,7 @@ static void Brw_PasteClipboard (void)
case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_CRS:
case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (Crs_GetDataOfCourseByCod (&Crs))
snprintf (PathOrg,sizeof (PathOrg), snprintf (PathOrg,sizeof (PathOrg),
"%s/%ld/%s", "%s/%ld/%s",
Cfg_PATH_CRS_PRIVATE,Crs.CrsCod, Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,
@ -7921,7 +7921,7 @@ static void Brw_PasteClipboard (void)
GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod;
Grp_GetDataOfGroupByCod (&GrpDat); Grp_GetDataOfGroupByCod (&GrpDat);
Crs.CrsCod = GrpDat.CrsCod; Crs.CrsCod = GrpDat.CrsCod;
if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (Crs_GetDataOfCourseByCod (&Crs))
snprintf (PathOrg,sizeof (PathOrg), snprintf (PathOrg,sizeof (PathOrg),
"%s/%ld/%s/%ld/%s", "%s/%ld/%s/%ld/%s",
Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_GRP, Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_GRP,
@ -7933,7 +7933,7 @@ static void Brw_PasteClipboard (void)
case Brw_ADMI_ASG_CRS: case Brw_ADMI_ASG_CRS:
case Brw_ADMI_WRK_CRS: case Brw_ADMI_WRK_CRS:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (Crs_GetDataOfCourseByCod (&Crs))
{ {
Usr_UsrDataConstructor (&UsrDat); Usr_UsrDataConstructor (&UsrDat);
UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod;
@ -7952,7 +7952,7 @@ static void Brw_PasteClipboard (void)
case Brw_ADMI_ASG_USR: case Brw_ADMI_ASG_USR:
case Brw_ADMI_WRK_USR: case Brw_ADMI_WRK_USR:
Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod;
if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (Crs_GetDataOfCourseByCod (&Crs))
snprintf (PathOrg,sizeof (PathOrg), snprintf (PathOrg,sizeof (PathOrg),
"%s/%ld/%s/%02u/%ld/%s", "%s/%ld/%s/%02u/%ld/%s",
Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_USR, Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_USR,
@ -7966,7 +7966,7 @@ static void Brw_PasteClipboard (void)
case Brw_ADMI_ASS_PRJ: case Brw_ADMI_ASS_PRJ:
PrjCod = Gbl.FileBrowser.Clipboard.Cod; PrjCod = Gbl.FileBrowser.Clipboard.Cod;
Crs.CrsCod = Prj_GetCourseOfProject (PrjCod); Crs.CrsCod = Prj_GetCourseOfProject (PrjCod);
if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (Crs_GetDataOfCourseByCod (&Crs))
snprintf (PathOrg,sizeof (PathOrg), snprintf (PathOrg,sizeof (PathOrg),
"%s/%ld/%s/%02u/%ld/%s", "%s/%ld/%s/%02u/%ld/%s",
Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_PRJ, Cfg_PATH_CRS_PRIVATE,Crs.CrsCod,Cfg_FOLDER_PRJ,
@ -11076,7 +11076,7 @@ void Brw_GetCrsGrpFromFileMetadata (Brw_FileBrowser_t FileBrowser,long Cod,
/* Cod stores the course code */ /* Cod stores the course code */
*GrpCod = -1L; *GrpCod = -1L;
*CrsCod = Crs.CrsCod = Cod; *CrsCod = Crs.CrsCod = Cod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
*DegCod = Deg.DegCod = Crs.DegCod; *DegCod = Deg.DegCod = Crs.DegCod;
Deg_GetDataOfDegreeByCod (&Deg); Deg_GetDataOfDegreeByCod (&Deg);
*CtrCod = Ctr.CtrCod = Deg.CtrCod; *CtrCod = Ctr.CtrCod = Deg.CtrCod;
@ -11091,7 +11091,7 @@ void Brw_GetCrsGrpFromFileMetadata (Brw_FileBrowser_t FileBrowser,long Cod,
*GrpCod = GrpDat.GrpCod = Cod; *GrpCod = GrpDat.GrpCod = Cod;
Grp_GetDataOfGroupByCod (&GrpDat); Grp_GetDataOfGroupByCod (&GrpDat);
*CrsCod = Crs.CrsCod = GrpDat.CrsCod; *CrsCod = Crs.CrsCod = GrpDat.CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
*DegCod = Deg.DegCod = Crs.DegCod; *DegCod = Deg.DegCod = Crs.DegCod;
Deg_GetDataOfDegreeByCod (&Deg); Deg_GetDataOfDegreeByCod (&Deg);
*CtrCod = Ctr.CtrCod = Deg.CtrCod; *CtrCod = Ctr.CtrCod = Deg.CtrCod;
@ -11103,7 +11103,7 @@ void Brw_GetCrsGrpFromFileMetadata (Brw_FileBrowser_t FileBrowser,long Cod,
/* Cod stores the project code */ /* Cod stores the project code */
*GrpCod = -1L; *GrpCod = -1L;
*CrsCod = Crs.CrsCod = Prj_GetCourseOfProject (Cod); *CrsCod = Crs.CrsCod = Prj_GetCourseOfProject (Cod);
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
*DegCod = Deg.DegCod = Crs.DegCod; *DegCod = Deg.DegCod = Crs.DegCod;
Deg_GetDataOfDegreeByCod (&Deg); Deg_GetDataOfDegreeByCod (&Deg);
*CtrCod = Ctr.CtrCod = Deg.CtrCod; *CtrCod = Ctr.CtrCod = Deg.CtrCod;
@ -11711,7 +11711,7 @@ void Brw_RemoveUsrWorksInAllCrss (struct UsrData *UsrDat)
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get data of course */ /* Get data of course */
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
Brw_RemoveUsrWorksInCrs (UsrDat,&Crs); Brw_RemoveUsrWorksInCrs (UsrDat,&Crs);
NumCrssWorksRemoved++; NumCrssWorksRemoved++;
} }

View File

@ -2207,14 +2207,14 @@ void For_SetForumName (struct Forum *Forum,
break; break;
case For_FORUM_COURSE_USRS: case For_FORUM_COURSE_USRS:
Crs.CrsCod = Forum->Location; Crs.CrsCod = Forum->Location;
if (!Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (!Crs_GetDataOfCourseByCod (&Crs))
Lay_ShowErrorAndExit ("Course not found."); Lay_ShowErrorAndExit ("Course not found.");
Str_Copy (ForumName,Crs.ShrtName, Str_Copy (ForumName,Crs.ShrtName,
For_MAX_BYTES_FORUM_NAME); For_MAX_BYTES_FORUM_NAME);
break; break;
case For_FORUM_COURSE_TCHS: case For_FORUM_COURSE_TCHS:
Crs.CrsCod = Forum->Location; Crs.CrsCod = Forum->Location;
if (!Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (!Crs_GetDataOfCourseByCod (&Crs))
Lay_ShowErrorAndExit ("Course not found."); Lay_ShowErrorAndExit ("Course not found.");
snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1, snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1,
"%s%s",Crs.ShrtName, "%s%s",Crs.ShrtName,

View File

@ -794,10 +794,14 @@ struct Globals
} NumUsrsWhoClaimToBelongToCtr; } NumUsrsWhoClaimToBelongToCtr;
struct struct
{ {
Rol_Role_t Role;
long CtrCod; long CtrCod;
unsigned NumUsrs; unsigned NumUsrs;
} NumUsrsInCrssOfCtr; } NumUsrsInCrssOfCtr[Rol_NUM_ROLES];
struct
{
long CrsCod;
unsigned NumUsrs;
} NumUsrsInCrs[Rol_NUM_ROLES];
struct struct
{ {
long UsrCod; long UsrCod;

View File

@ -161,17 +161,17 @@ void Hlp_ShowHelpWhatWouldYouLikeToDo (void)
if (Gbl.Usrs.Me.MyCrss.Num) // I am enroled in some courses if (Gbl.Usrs.Me.MyCrss.Num) // I am enroled in some courses
{ {
if (Gbl.Hierarchy.Level == Hie_CRS && // Course selected if (Gbl.Hierarchy.Level == Hie_CRS && // Course selected
!Gbl.Hierarchy.Crs.NumUsrs[Rol_STD] && // Current course has no students
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role == Rol_TCH) // I am a teacher in current course Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role == Rol_TCH) // I am a teacher in current course
{ if (!Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod))// Current course has no students
/* Request students enrolment */ {
Hlp_ShowRowHelpWhatWouldYouLikeToDo (Str_BuildStringStr (Txt_Register_students_in_COURSE_X, /* Request students enrolment */
Gbl.Hierarchy.Crs.ShrtName), Hlp_ShowRowHelpWhatWouldYouLikeToDo (Str_BuildStringStr (Txt_Register_students_in_COURSE_X,
ActReqEnrSevStd, Gbl.Hierarchy.Crs.ShrtName),
Btn_CREATE_BUTTON,Txt_Register_students); ActReqEnrSevStd,
Str_FreeString (); Btn_CREATE_BUTTON,Txt_Register_students);
} Str_FreeString ();
}
if (Gbl.Action.Act != ActMyCrs) // I am not seeing the action to list my courses if (Gbl.Action.Act != ActMyCrs) // I am not seeing the action to list my courses
/* Request list my courses */ /* Request list my courses */

View File

@ -525,8 +525,7 @@ void Hie_InitHierarchy (void)
/***** If course code is available, get course data *****/ /***** If course code is available, get course data *****/
if (Gbl.Hierarchy.Crs.CrsCod > 0) if (Gbl.Hierarchy.Crs.CrsCod > 0)
{ {
if (Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs, // Course found if (Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs)) // Course found
Crs_GET_EXTRA_DATA)) // Get extra data because they may be needed later
Gbl.Hierarchy.Deg.DegCod = Gbl.Hierarchy.Crs.DegCod; Gbl.Hierarchy.Deg.DegCod = Gbl.Hierarchy.Crs.DegCod;
else else
Hie_ResetHierarchy (); Hie_ResetHierarchy ();

View File

@ -1561,7 +1561,7 @@ void Lay_WriteHeaderClassPhoto (bool PrintView,bool DrawingClassPhoto,
/***** Get data of course *****/ /***** Get data of course *****/
Crs.CrsCod = CrsCod; Crs.CrsCod = CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
/***** Begin table *****/ /***** Begin table *****/
HTM_TABLE_BeginWidePadding (10); HTM_TABLE_BeginWidePadding (10);

View File

@ -623,8 +623,7 @@ void Mrk_ShowMyMarks (void)
} }
else // Course zone else // Course zone
{ {
// if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // If there are students in this course if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // If there are students in this course
if (Gbl.Hierarchy.Crs.NumUsrs[Rol_STD])
{ {
Gbl.Usrs.Other.UsrDat.UsrCod = Usr_GetRamdomStdFromCrs (Gbl.Hierarchy.Crs.CrsCod); Gbl.Usrs.Other.UsrDat.UsrCod = Usr_GetRamdomStdFromCrs (Gbl.Hierarchy.Crs.CrsCod);
UsrDat = &Gbl.Usrs.Other.UsrDat; UsrDat = &Gbl.Usrs.Other.UsrDat;

View File

@ -1030,7 +1030,7 @@ void Msg_GetParamMsgsCrsCod (void)
{ {
/* Get data of course */ /* Get data of course */
Crs.CrsCod = Gbl.Msg.FilterCrsCod; Crs.CrsCod = Gbl.Msg.FilterCrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
Str_Copy (Gbl.Msg.FilterCrsShrtName,Crs.ShrtName, Str_Copy (Gbl.Msg.FilterCrsShrtName,Crs.ShrtName,
Hie_MAX_BYTES_SHRT_NAME); Hie_MAX_BYTES_SHRT_NAME);
@ -2597,7 +2597,7 @@ void Msg_GetDistinctCoursesInMyMessages (void)
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]);
if (Crs.CrsCod >= 0 && Gbl.Msg.NumCourses < Crs_MAX_COURSES_PER_USR) if (Crs.CrsCod >= 0 && Gbl.Msg.NumCourses < Crs_MAX_COURSES_PER_USR)
if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (Crs_GetDataOfCourseByCod (&Crs))
{ {
Gbl.Msg.Courses[Gbl.Msg.NumCourses].CrsCod = Crs.CrsCod; Gbl.Msg.Courses[Gbl.Msg.NumCourses].CrsCod = Crs.CrsCod;
Str_Copy (Gbl.Msg.Courses[Gbl.Msg.NumCourses].ShrtName,Crs.ShrtName, Str_Copy (Gbl.Msg.Courses[Gbl.Msg.NumCourses].ShrtName,Crs.ShrtName,
@ -3279,7 +3279,7 @@ bool Msg_WriteCrsOrgMsg (long CrsCod)
Crs.CrsCod = CrsCod; Crs.CrsCod = CrsCod;
/* Get data of current degree */ /* Get data of current degree */
if (Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA)) if (Crs_GetDataOfCourseByCod (&Crs))
{ {
ThereIsOrgCrs = true; ThereIsOrgCrs = true;
if ((FromThisCrs = (CrsCod == Gbl.Hierarchy.Crs.CrsCod))) // Message sent from current course if ((FromThisCrs = (CrsCod == Gbl.Hierarchy.Crs.CrsCod))) // Message sent from current course

View File

@ -415,7 +415,7 @@ void Ntf_ShowMyNotifications (void)
/* Get course code (row[5]) */ /* Get course code (row[5]) */
Crs.CrsCod = Str_ConvertStrCodToLongCod (row[5]); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[5]);
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
/* Get message/post/... code (row[6]) */ /* Get message/post/... code (row[6]) */
Cod = Str_ConvertStrCodToLongCod (row[6]); Cod = Str_ConvertStrCodToLongCod (row[6]);
@ -1244,7 +1244,7 @@ unsigned Ntf_StoreNotifyEventsToAllUsrs (Ntf_NotifyEvent_t NotifyEvent,long Cod)
case Ntf_EVENT_ENROLMENT_TCH: // This function should not be called in this case case Ntf_EVENT_ENROLMENT_TCH: // This function should not be called in this case
return 0; return 0;
case Ntf_EVENT_ENROLMENT_REQUEST: case Ntf_EVENT_ENROLMENT_REQUEST:
if (Gbl.Hierarchy.Crs.NumUsrs[Rol_TCH]) if (Usr_GetNumUsrsInCrs (Rol_TCH,Gbl.Hierarchy.Crs.CrsCod))
{ {
// If this course has teachers ==> send notification to teachers // If this course has teachers ==> send notification to teachers
NumRows = DB_QuerySELECT (&mysql_res,"can not get users" NumRows = DB_QuerySELECT (&mysql_res,"can not get users"
@ -1662,7 +1662,7 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct UsrData *ToUsrDat,unsign
/* Get course code (row[5]) */ /* Get course code (row[5]) */
Crs.CrsCod = Str_ConvertStrCodToLongCod (row[5]); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[5]);
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
/* Get message/post/... code (row[6]) */ /* Get message/post/... code (row[6]) */
Cod = Str_ConvertStrCodToLongCod (row[6]); Cod = Str_ConvertStrCodToLongCod (row[6]);

View File

@ -1161,7 +1161,7 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
/***** Get course data *****/ /***** Get course data *****/
Crs.CrsCod = CrsCod; Crs.CrsCod = CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_EXTRA_DATA); Crs_GetDataOfCourseByCod (&Crs);
/***** Get degree data *****/ /***** Get degree data *****/
Deg.DegCod = Crs.DegCod; Deg.DegCod = Crs.DegCod;

View File

@ -3619,7 +3619,7 @@ static void Sta_ShowNumHitsPerCourse (unsigned long NumRows,
Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get data of current degree */ /* Get data of current degree */
CrsOK = Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); CrsOK = Crs_GetDataOfCourseByCod (&Crs);
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);

View File

@ -1631,7 +1631,7 @@ static void TL_WriteNote (const struct TL_Note *SocNot,
case TL_NOTE_NOTICE: case TL_NOTE_NOTICE:
/* Get course data */ /* Get course data */
Crs.CrsCod = SocNot->HieCod; Crs.CrsCod = SocNot->HieCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
break; break;
case TL_NOTE_FORUM_POST: case TL_NOTE_FORUM_POST:
/* Get forum type of the post */ /* Get forum type of the post */

View File

@ -1547,7 +1547,7 @@ static void TT_TimeTableDrawCell (unsigned Weekday,unsigned Interval,unsigned Co
if (Gbl.TimeTable.Type == TT_MY_TIMETABLE) if (Gbl.TimeTable.Type == TT_MY_TIMETABLE)
{ {
Crs.CrsCod = CrsCod; Crs.CrsCod = CrsCod;
Crs_GetDataOfCourseByCod (&Crs,Crs_GET_BASIC_DATA); Crs_GetDataOfCourseByCod (&Crs);
if (ClassType == TT_LECTURE || if (ClassType == TT_LECTURE ||
ClassType == TT_PRACTICAL) ClassType == TT_PRACTICAL)
{ {

View File

@ -4167,14 +4167,56 @@ static void Usr_WriteUsrData (const char *BgColor,
/************* Get number of users with a role in a course *******************/ /************* Get number of users with a role in a course *******************/
/*****************************************************************************/ /*****************************************************************************/
void Usr_FlushCacheNumUsrsInCrs (void)
{
Gbl.Cache.NumUsrsInCrs[Rol_UNK].CrsCod =
Gbl.Cache.NumUsrsInCrs[Rol_STD].CrsCod =
Gbl.Cache.NumUsrsInCrs[Rol_NET].CrsCod =
Gbl.Cache.NumUsrsInCrs[Rol_TCH].CrsCod = -1L;
Gbl.Cache.NumUsrsInCrs[Rol_UNK].NumUsrs =
Gbl.Cache.NumUsrsInCrs[Rol_STD].NumUsrs =
Gbl.Cache.NumUsrsInCrs[Rol_NET].NumUsrs =
Gbl.Cache.NumUsrsInCrs[Rol_TCH].NumUsrs = 0;
}
unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod) unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod)
{ {
/***** Get the number of teachers in a course from database ******/ /***** 1. Fast check: Trivial case *****/
return if (CrsCod <= 0)
(unsigned) DB_QueryCOUNT ("can not get the number of users in a course", return 0;
"SELECT COUNT(*) FROM crs_usr"
" WHERE CrsCod=%ld AND Role=%u", /***** 2. Fast check: Trivial case *****/
CrsCod,(unsigned) Role); switch (Role)
{
case Rol_UNK: // Here Rol_UNK means all
case Rol_STD:
case Rol_NET:
case Rol_TCH:
break;
default:
return 0;
}
/***** 3. Fast check: If cached... *****/
if (CrsCod == Gbl.Cache.NumUsrsInCrs[Role].CrsCod)
return Gbl.Cache.NumUsrsInCrs[Role].NumUsrs;
/***** 4. Slow: number of users in a course from database *****/
Gbl.Cache.NumUsrsInCrs[Role].CrsCod = CrsCod;
if (Role == Rol_UNK)
Gbl.Cache.NumUsrsInCrs[Rol_UNK].NumUsrs =
(unsigned) DB_QueryCOUNT ("can not get the number of users in a course",
"SELECT COUNT(*) FROM crs_usr"
" WHERE CrsCod=%ld",
CrsCod);
else
Gbl.Cache.NumUsrsInCrs[Role].NumUsrs =
(unsigned) DB_QueryCOUNT ("can not get the number of users in a course",
"SELECT COUNT(*) FROM crs_usr"
" WHERE CrsCod=%ld AND Role=%u",
CrsCod,(unsigned) Role);
return Gbl.Cache.NumUsrsInCrs[Role].NumUsrs;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -4202,9 +4244,15 @@ unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod)
void Usr_FlushCacheNumUsrsInCrssOfCtr (void) void Usr_FlushCacheNumUsrsInCrssOfCtr (void)
{ {
Gbl.Cache.NumUsrsInCrssOfCtr.Role = Rol_UNK; Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].CtrCod =
Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod = -1L; Gbl.Cache.NumUsrsInCrssOfCtr[Rol_STD].CtrCod =
Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = 0; Gbl.Cache.NumUsrsInCrssOfCtr[Rol_NET].CtrCod =
Gbl.Cache.NumUsrsInCrssOfCtr[Rol_TCH].CtrCod = -1L;
Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].NumUsrs =
Gbl.Cache.NumUsrsInCrssOfCtr[Rol_STD].NumUsrs =
Gbl.Cache.NumUsrsInCrssOfCtr[Rol_NET].NumUsrs =
Gbl.Cache.NumUsrsInCrssOfCtr[Rol_TCH].NumUsrs = 0;
} }
unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod)
@ -4213,17 +4261,27 @@ unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod)
if (CtrCod <= 0) if (CtrCod <= 0)
return 0; return 0;
/***** 2. Fast check: If cached... *****/ /***** 2. Fast check: Trivial case *****/
if (Role == Gbl.Cache.NumUsrsInCrssOfCtr.Role && switch (Role)
CtrCod == Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod) {
return Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs; case Rol_UNK: // Here Rol_UNK means all
case Rol_STD:
case Rol_NET:
case Rol_TCH:
break;
default:
return 0;
}
/***** 3. Slow: get number of users in courses of a centre /***** 3. Fast check: If cached... *****/
if (CtrCod == Gbl.Cache.NumUsrsInCrssOfCtr[Role].CtrCod)
return Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs;
/***** 4. Slow: get number of users in courses of a centre
from database *****/ from database *****/
Gbl.Cache.NumUsrsInCrssOfCtr.Role = Role; Gbl.Cache.NumUsrsInCrssOfCtr[Role].CtrCod = CtrCod;
Gbl.Cache.NumUsrsInCrssOfCtr.CtrCod = CtrCod;
if (Role == Rol_UNK) // Any user if (Role == Rol_UNK) // Any user
Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].NumUsrs =
(unsigned) DB_QueryCOUNT ("can not get the number of users" (unsigned) DB_QueryCOUNT ("can not get the number of users"
" in courses of a centre", " in courses of a centre",
"SELECT COUNT(DISTINCT crs_usr.UsrCod)" "SELECT COUNT(DISTINCT crs_usr.UsrCod)"
@ -4235,7 +4293,7 @@ unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod)
else else
// This query is very slow. // This query is very slow.
// It's a bad idea to get number of teachers or students for a big list of centres // It's a bad idea to get number of teachers or students for a big list of centres
Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs = Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs =
(unsigned) DB_QueryCOUNT ("can not get the number of users" (unsigned) DB_QueryCOUNT ("can not get the number of users"
" in courses of a centre", " in courses of a centre",
"SELECT COUNT(DISTINCT crs_usr.UsrCod)" "SELECT COUNT(DISTINCT crs_usr.UsrCod)"
@ -4245,7 +4303,7 @@ unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod)
" AND courses.CrsCod=crs_usr.CrsCod" " AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.Role=%u", " AND crs_usr.Role=%u",
CtrCod,(unsigned) Role); CtrCod,(unsigned) Role);
return Gbl.Cache.NumUsrsInCrssOfCtr.NumUsrs; return Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -9804,21 +9862,7 @@ double Usr_GetNumUsrsPerCrs (Rol_Role_t Role)
(unsigned) Role); (unsigned) Role);
break; break;
case Hie_CRS: case Hie_CRS:
switch (Role) return (double) Usr_GetNumUsrsInCrs (Role,Gbl.Hierarchy.Crs.CrsCod);
{
case Rol_UNK:
return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_UNK]; // Any user
case Rol_STD:
return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_STD]; // Students
case Rol_NET:
return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_UNK]; // Non-editing teachers
case Rol_TCH:
return (double) Gbl.Hierarchy.Crs.NumUsrs[Rol_UNK]; // Teachers
default:
Rol_WrongRoleExit ();
break; // Not reached
}
break;
default: default:
Lay_WrongScopeExit (); Lay_WrongScopeExit ();
break; break;

View File

@ -407,6 +407,7 @@ void Usr_WriteRowUsrMainData (unsigned NumUsr,struct UsrData *UsrDat,
bool PutCheckBoxToSelectUsr,Rol_Role_t Role, bool PutCheckBoxToSelectUsr,Rol_Role_t Role,
struct SelectedUsrs *SelectedUsrs); struct SelectedUsrs *SelectedUsrs);
void Usr_FlushCacheNumUsrsInCrs (void);
unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod); unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod);
unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod); unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod);
void Usr_FlushCacheNumUsrsInCrssOfCtr (void); void Usr_FlushCacheNumUsrsInCrssOfCtr (void);