Version 20.75: May 11, 2021 New module swad_assignment_database for database queries related to assignments.

This commit is contained in:
acanas 2021-05-13 12:50:36 +02:00
parent b30caef053
commit ab5d53a996
14 changed files with 1708 additions and 1377 deletions

View File

@ -29,7 +29,7 @@
OBJS = swad_account.o swad_account_database.o swad_action.o swad_agenda.o \
swad_agenda_database.o swad_alert.o swad_announcement.o \
swad_announcement_database.o swad_API.o swad_assignment.o \
swad_assignment_database.o swad_attendance.o \
swad_assignment_database.o swad_attendance.o swad_attendance_database.o \
swad_banner.o swad_box.o swad_building.o swad_button.o \
swad_calendar.o swad_call_for_exam.o swad_center.o \
swad_center_config.o swad_chat.o swad_config.o swad_connected.o \

View File

@ -103,7 +103,7 @@ cp -f /home/acanas/swad/swad/swad /var/www/cgi-bin/
#include "swad_account.h"
#include "swad_API.h"
#include "swad_attendance.h"
#include "swad_attendance_database.h"
#include "swad_database.h"
#include "swad_error.h"
#include "swad_file_browser.h"
@ -3182,7 +3182,7 @@ int swad__sendAttendanceUsers (struct soap *soap,
free (SubQueryAllUsrs);
/* Clean attendance users table */
Att_RemoveUsrsAbsentWithoutCommentsFromAttEvent (Event.AttCod);
Att_DB_RemoveUsrsAbsentWithoutCommentsFromAttEvent (Event.AttCod);
}
/***** Free memory used for user's data *****/

View File

@ -31,7 +31,7 @@
#include "swad_account_database.h"
#include "swad_agenda_database.h"
#include "swad_announcement_database.h"
#include "swad_attendance.h"
#include "swad_attendance_database.h"
#include "swad_box.h"
#include "swad_calendar.h"
#include "swad_database.h"

View File

@ -1391,7 +1391,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActReqRemAtt ] = {1067,-1,TabUnk,ActSeeAtt ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_AskRemAttEvent ,NULL},
[ActRemAtt ] = {1068,-1,TabUnk,ActSeeAtt ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_GetAndRemAttEvent ,NULL},
[ActHidAtt ] = {1069,-1,TabUnk,ActSeeAtt ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_HideAttEvent ,NULL},
[ActShoAtt ] = {1070,-1,TabUnk,ActSeeAtt ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_ShowAttEvent ,NULL},
[ActShoAtt ] = {1070,-1,TabUnk,ActSeeAtt ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_UnhideAttEvent ,NULL},
[ActSeeOneAtt ] = {1071,-1,TabUnk,ActSeeAtt ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_SeeOneAttEvent ,NULL},
[ActRecAttStd ] = {1072,-1,TabUnk,ActSeeAtt ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_RegisterStudentsInAttEvent ,NULL},
[ActRecAttMe ] = {1076,-1,TabUnk,ActSeeAtt ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Att_RegisterMeAsStdInAttEvent ,NULL},

View File

@ -98,7 +98,7 @@ static void Asg_PutParamAsgCod (long AsgCod);
static void Asg_ShowLstGrpsToEditAssignment (long AsgCod);
static void Asg_CreateAssignment (struct Asg_Assignment *Asg,const char *Txt);
static void Asg_UpdateAssignment (struct Asg_Assignment *Asg,const char *Txt);
static void Asg_CreateGrps (long AsgCod);
static void Asg_CreateGroups (long AsgCod);
static void Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (struct Asg_Assignment *Asg);
static bool Asg_CheckIfIBelongToCrsOrGrpsThisAssignment (long AsgCod);
@ -684,25 +684,20 @@ static void Asg_PutParams (void *Assignments)
static void Asg_GetListAssignments (struct Asg_Assignments *Assignments)
{
extern unsigned (*Asg_DB_GetListAssignments[Grp_NUM_WHICH_GROUPS]) (MYSQL_RES **mysql_res,
Dat_StartEndTime_t SelectedOrder);
MYSQL_RES *mysql_res;
unsigned NumAsgs;
unsigned NumAsg;
if (Assignments->LstIsRead)
Asg_FreeListAssignments (Assignments);
/***** Get list of assignments from database *****/
if (Gbl.Crs.Grps.WhichGrps == Grp_MY_GROUPS)
NumAsgs = Asg_DB_GetListAssignmentsMyGrps (&mysql_res,Assignments->SelectedOrder);
else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS
NumAsgs = Asg_DB_GetListAssignmentsAllGrps (&mysql_res,Assignments->SelectedOrder);
if (NumAsgs) // Assignments found...
Assignments->Num = Asg_DB_GetListAssignments[Gbl.Crs.Grps.WhichGrps] (&mysql_res,Assignments->SelectedOrder);
if (Assignments->Num) // Assignments found...
{
Assignments->Num = (unsigned) NumAsgs;
/***** Create list of assignments *****/
if ((Assignments->LstAsgCods = calloc (NumAsgs,
if ((Assignments->LstAsgCods = calloc ((size_t) Assignments->Num,
sizeof (*Assignments->LstAsgCods))) == NULL)
Err_NotEnoughMemoryExit ();
@ -714,8 +709,6 @@ static void Asg_GetListAssignments (struct Asg_Assignments *Assignments)
if ((Assignments->LstAsgCods[NumAsg] = DB_GetNextCode (mysql_res)) <= 0)
Err_WrongAssignmentExit ();
}
else
Assignments->Num = 0;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@ -993,7 +986,7 @@ void Asg_RemoveAssignment (void)
Brw_RemoveFoldersAssignmentsIfExistForAllUsrs (Asg.Folder);
/***** Remove all the groups of this assignment *****/
Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (Asg.AsgCod);
Asg_DB_RemoveGrpsAssociatedToAnAssignment (Asg.AsgCod);
/***** Remove assignment *****/
Asg_DB_RemoveAssignment (Asg.AsgCod);
@ -1469,7 +1462,7 @@ static void Asg_CreateAssignment (struct Asg_Assignment *Asg,const char *Txt)
/***** Create groups *****/
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
Asg_CreateGrps (Asg->AsgCod);
Asg_CreateGroups (Asg->AsgCod);
}
/*****************************************************************************/
@ -1483,26 +1476,26 @@ static void Asg_UpdateAssignment (struct Asg_Assignment *Asg,const char *Txt)
/***** Update groups *****/
/* Remove old groups */
Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (Asg->AsgCod);
Asg_DB_RemoveGrpsAssociatedToAnAssignment (Asg->AsgCod);
/* Create new groups */
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
Asg_CreateGrps (Asg->AsgCod);
Asg_CreateGroups (Asg->AsgCod);
}
/*****************************************************************************/
/********************* Create groups of an assignment ************************/
/*****************************************************************************/
static void Asg_CreateGrps (long AsgCod)
static void Asg_CreateGroups (long AsgCod)
{
unsigned NumGrpSel;
unsigned NumGrp;
/***** Create groups of the assignment *****/
for (NumGrpSel = 0;
NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps;
NumGrpSel++)
Asg_DB_CreateGrp (AsgCod,Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]);
for (NumGrp = 0;
NumGrp < Gbl.Crs.Grps.LstGrpsSel.NumGrps;
NumGrp++)
Asg_DB_CreateGroup (AsgCod,Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrp]);
}
/*****************************************************************************/

View File

@ -38,6 +38,17 @@
extern struct Globals Gbl;
/*****************************************************************************/
/****************************** Public variables *****************************/
/*****************************************************************************/
unsigned (*Asg_DB_GetListAssignments[Grp_NUM_WHICH_GROUPS]) (MYSQL_RES **mysql_res,
Dat_StartEndTime_t SelectedOrder) =
{
[Grp_MY_GROUPS ] = Asg_DB_GetListAssignmentsMyGrps,
[Grp_ALL_GROUPS] = Asg_DB_GetListAssignmentsAllGrps,
};
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
@ -65,10 +76,6 @@ static const char *Asg_DB_OrderSubQuery[Dat_NUM_START_END_TIME] =
"Title DESC",
};
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
@ -364,7 +371,7 @@ unsigned Asg_DB_GetGrps (MYSQL_RES **mysql_res,long AsgCod)
/********************* Create a group of an assignment ************************/
/*****************************************************************************/
void Asg_DB_CreateGrp (long AsgCod,long GrpCod)
void Asg_DB_CreateGroup (long AsgCod,long GrpCod)
{
DB_QueryINSERT ("can not associate a group to an assignment",
"INSERT INTO asg_groups"
@ -410,7 +417,7 @@ void Asg_DB_RemoveGroupsOfType (long GrpTypCod)
/********************* Remove groups of an assignment ************************/
/*****************************************************************************/
void Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (long AsgCod)
void Asg_DB_RemoveGrpsAssociatedToAnAssignment (long AsgCod)
{
/***** Remove groups of the assignment *****/
DB_QueryDELETE ("can not remove the groups associated to an assignment",

View File

@ -30,6 +30,7 @@
#include "swad_assignment.h"
#include "swad_database.h"
#include "swad_file_browser.h"
#include "swad_group.h"
/*****************************************************************************/
/************************** Public types and constants ***********************/
@ -63,10 +64,10 @@ void Asg_DB_RemoveAssignment (long AsgCod);
bool Asg_DB_CheckIfICanDoAssignment (long AsgCod);
unsigned Asg_DB_GetGrps (MYSQL_RES **mysql_res,long AsgCod);
void Asg_DB_CreateGrp (long AsgCod,long GrpCod);
void Asg_DB_CreateGroup (long AsgCod,long GrpCod);
void Asg_DB_RemoveGroup (long GrpCod);
void Asg_DB_RemoveGroupsOfType (long GrpTypCod);
void Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (long AsgCod);
void Asg_DB_RemoveGrpsAssociatedToAnAssignment (long AsgCod);
void Asg_DB_RemoveGrpsAssociatedToAsgsInCrs (long CrsCod);
void Asg_DB_RemoveCrsAssignments (long CrsCod);

File diff suppressed because it is too large Load Diff

View File

@ -96,21 +96,13 @@ void Att_GetAndRemAttEvent (void);
void Att_RemoveAttEventFromDB (long AttCod);
void Att_HideAttEvent (void);
void Att_ShowAttEvent (void);
void Att_UnhideAttEvent (void);
void Att_ReceiveFormAttEvent (void);
void Att_CreateAttEvent (struct Att_Event *Event,const char *Description);
void Att_UpdateAttEvent (struct Att_Event *Event,const char *Description);
void Att_RemoveGroupsOfType (long GrpTypCod);
void Att_RemoveGroup (long GrpCod);
void Att_DB_RemoveUsrFromAllAttEvents (long UsrCod);
void Att_DB_RemoveUsrFromCrsAttEvents (long UsrCod,long CrsCod);
void Att_RemoveCrsAttEvents (long CrsCod);
unsigned Att_DB_GetNumAttEventsInCrs(long CrsCod);
unsigned Att_DB_GetNumCoursesWithAttEvents (Hie_Lvl_Level_t Scope);
unsigned Att_GetNumAttEvents (Hie_Lvl_Level_t Scope,unsigned *NumNotif);
void Att_SeeOneAttEvent (void);
@ -119,7 +111,6 @@ void Att_RegisterMeAsStdInAttEvent (void);
void Att_RegisterStudentsInAttEvent (void);
void Att_RegUsrInAttEventNotChangingComments (long AttCod,long UsrCod);
void Att_RemoveUsrsAbsentWithoutCommentsFromAttEvent (long AttCod);
void Att_ReqListUsrsAttendanceCrs (void);
void Att_ListMyAttendanceCrs (void);

759
swad_attendance_database.c Normal file
View File

@ -0,0 +1,759 @@
// swad_attendance_database.c: control of attendance operations with database
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2021 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************** Headers **********************************/
/*****************************************************************************/
#include <mysql/mysql.h> // To access MySQL databases
#include "swad_attendance.h"
#include "swad_attendance_database.h"
#include "swad_database.h"
#include "swad_error.h"
#include "swad_global.h"
/*****************************************************************************/
/*************** External global variables from others modules ***************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/******************************* Public variables ****************************/
/*****************************************************************************/
unsigned (*Att_DB_GetListAttEvents[Grp_NUM_WHICH_GROUPS]) (MYSQL_RES **mysql_res,
Dat_StartEndTime_t SelectedOrder,
Att_OrderNewestOldest_t OrderNewestOldest) =
{
[Grp_MY_GROUPS ] = Att_DB_GetListAttEventsMyGrps,
[Grp_ALL_GROUPS] = Att_DB_GetListAttEventsAllGrps,
};
/*****************************************************************************/
/****************************** Private constants ****************************/
/*****************************************************************************/
static const char *Att_DB_HiddenSubQuery[Rol_NUM_ROLES] =
{
[Rol_UNK ] = " AND Hidden='N'",
[Rol_GST ] = " AND Hidden='N'",
[Rol_USR ] = " AND Hidden='N'",
[Rol_STD ] = " AND Hidden='N'",
[Rol_NET ] = " AND Hidden='N'",
[Rol_TCH ] = "",
[Rol_DEG_ADM] = " AND Hidden='N'",
[Rol_CTR_ADM] = " AND Hidden='N'",
[Rol_INS_ADM] = " AND Hidden='N'",
[Rol_SYS_ADM] = "",
};
static const char *Att_DB_OrderBySubQuery[Dat_NUM_START_END_TIME][Att_NUM_ORDERS_NEWEST_OLDEST] =
{
[Dat_START_TIME][Att_NEWEST_FIRST] = "StartTime DESC,"
"EndTime DESC,"
"Title DESC",
[Dat_START_TIME][Att_OLDEST_FIRST] = "StartTime,"
"EndTime,"
"Title",
[Dat_END_TIME ][Att_NEWEST_FIRST] = "EndTime DESC,"
"StartTime DESC,"
"Title DESC",
[Dat_END_TIME ][Att_OLDEST_FIRST] = "EndTime,"
"StartTime,"
"Title",
};
/*****************************************************************************/
/******************************** Private types ******************************/
/*****************************************************************************/
/*****************************************************************************/
/****************************** Private prototypes ***************************/
/*****************************************************************************/
/*****************************************************************************/
/**************** Get list of attendance events in my groups *****************/
/*****************************************************************************/
unsigned Att_DB_GetListAttEventsMyGrps (MYSQL_RES **mysql_res,
Dat_StartEndTime_t SelectedOrder,
Att_OrderNewestOldest_t OrderNewestOldest)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get attendance events",
"SELECT AttCod"
" FROM att_events"
" WHERE CrsCod=%ld"
"%s"
" AND (AttCod NOT IN"
" (SELECT AttCod"
" FROM att_groups)"
" OR"
" AttCod IN"
" (SELECT att_groups.AttCod"
" FROM grp_users,"
"att_groups"
" WHERE grp_users.UsrCod=%ld"
" AND att_groups.GrpCod=grp_users.GrpCod))"
" ORDER BY %s",
Gbl.Hierarchy.Crs.CrsCod,
Att_DB_HiddenSubQuery[Gbl.Usrs.Me.Role.Logged],
Gbl.Usrs.Me.UsrDat.UsrCod,
Att_DB_OrderBySubQuery[SelectedOrder][OrderNewestOldest]);
}
/*****************************************************************************/
/********************* Get list of all attendance events *********************/
/*****************************************************************************/
unsigned Att_DB_GetListAttEventsAllGrps (MYSQL_RES **mysql_res,
Dat_StartEndTime_t SelectedOrder,
Att_OrderNewestOldest_t OrderNewestOldest)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get attendance events",
"SELECT AttCod"
" FROM att_events"
" WHERE CrsCod=%ld%s"
" ORDER BY %s",
Gbl.Hierarchy.Crs.CrsCod,
Att_DB_HiddenSubQuery[Gbl.Usrs.Me.Role.Logged],
Att_DB_OrderBySubQuery[SelectedOrder][OrderNewestOldest]);
}
/*****************************************************************************/
/**************** Get attendance event data using its code *******************/
/*****************************************************************************/
unsigned Att_DB_GetDataOfAttEventByCod (MYSQL_RES **mysql_res,long AttCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get attendance event data",
"SELECT AttCod," // row[0]
"CrsCod," // row[1]
"Hidden," // row[2]
"UsrCod," // row[3]
"UNIX_TIMESTAMP(StartTime)," // row[4]
"UNIX_TIMESTAMP(EndTime)," // row[5]
"NOW() BETWEEN StartTime AND EndTime," // row[6]
"CommentTchVisible," // row[7]
"Title" // row[8]
" FROM att_events"
" WHERE AttCod=%ld",
AttCod);
}
/*****************************************************************************/
/***************** Get attendance event text from database *******************/
/*****************************************************************************/
void Att_DB_GetAttEventDescription (long AttCod,char Description[Cns_MAX_BYTES_TEXT + 1])
{
/***** Get text of attendance event from database *****/
DB_QuerySELECTString (Description,Cns_MAX_BYTES_TEXT,"can not get attendance event text",
"SELECT Txt"
" FROM att_events"
" WHERE AttCod=%ld"
" AND CrsCod=%ld",
AttCod,
Gbl.Hierarchy.Crs.CrsCod);
}
/*****************************************************************************/
/***** Check if the title or the folder of an attendance event exists ********/
/*****************************************************************************/
bool Att_DB_CheckIfSimilarAttEventExists (const char *Field,const char *Value,long AttCod)
{
/***** Get number of attendance events
with a field value from database *****/
return (DB_QueryCOUNT ("can not get similar attendance events",
"SELECT COUNT(*)"
" FROM att_events"
" WHERE CrsCod=%ld"
" AND %s='%s'"
" AND AttCod<>%ld",
Gbl.Hierarchy.Crs.CrsCod,
Field,Value,
AttCod) != 0);
}
/*****************************************************************************/
/********************* Create a new attendance event *************************/
/*****************************************************************************/
long Att_DB_CreateAttEvent (const struct Att_Event *Event,const char *Description)
{
return
DB_QueryINSERTandReturnCode ("can not create new attendance event",
"INSERT INTO att_events"
" (CrsCod,Hidden,UsrCod,"
"StartTime,EndTime,"
"CommentTchVisible,Title,Txt)"
" VALUES"
" (%ld,'%c',%ld,"
"FROM_UNIXTIME(%ld),FROM_UNIXTIME(%ld),"
"'%c','%s','%s')",
Gbl.Hierarchy.Crs.CrsCod,
Event->Hidden ? 'Y' :
'N',
Gbl.Usrs.Me.UsrDat.UsrCod,
Event->TimeUTC[Att_START_TIME],
Event->TimeUTC[Att_END_TIME ],
Event->CommentTchVisible ? 'Y' :
'N',
Event->Title,
Description);
}
/*****************************************************************************/
/****************** Update the data of an attendance event *******************/
/*****************************************************************************/
void Att_DB_UpdateAttEvent (const struct Att_Event *Event,const char *Description)
{
DB_QueryUPDATE ("can not update attendance event",
"UPDATE att_events"
" SET Hidden='%c',"
"StartTime=FROM_UNIXTIME(%ld),"
"EndTime=FROM_UNIXTIME(%ld),"
"CommentTchVisible='%c',"
"Title='%s',"
"Txt='%s'"
" WHERE AttCod=%ld"
" AND CrsCod=%ld", // Extra check
Event->Hidden ? 'Y' :
'N',
Event->TimeUTC[Att_START_TIME],
Event->TimeUTC[Att_END_TIME ],
Event->CommentTchVisible ? 'Y' :
'N',
Event->Title,
Description,
Event->AttCod,
Gbl.Hierarchy.Crs.CrsCod);
}
/*****************************************************************************/
/********************** Hide/unhide an attendance event **********************/
/*****************************************************************************/
void Att_DB_HideAttEvent (long AttCod)
{
DB_QueryUPDATE ("can not hide attendance event",
"UPDATE att_events"
" SET Hidden='Y'"
" WHERE AttCod=%ld"
" AND CrsCod=%ld", // Extra check
AttCod,
Gbl.Hierarchy.Crs.CrsCod);
}
void Att_DB_UnhideAttEvent (long AttCod)
{
DB_QueryUPDATE ("can not unhide attendance event",
"UPDATE att_events"
" SET Hidden='N'"
" WHERE AttCod=%ld"
" AND CrsCod=%ld",
AttCod,
Gbl.Hierarchy.Crs.CrsCod);
}
/*****************************************************************************/
/****************** Create group of an attendance event **********************/
/*****************************************************************************/
void Att_DB_CreateGroup (long AttCod,long GrpCod)
{
DB_QueryINSERT ("can not associate a group to an attendance event",
"INSERT INTO att_groups"
" (AttCod,GrpCod)"
" VALUES"
" (%ld,%ld)",
AttCod,
GrpCod);
}
/*****************************************************************************/
/************ Get group codes associated to an attendance event **************/
/*****************************************************************************/
unsigned Att_DB_GetGrpCodsAssociatedToEvent (MYSQL_RES **mysql_res,long AttCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get groups of an attendance event",
"SELECT GrpCod" // row[0]
" FROM att_groups"
" WHERE att_groups.AttCod=%ld",
AttCod);
}
/*****************************************************************************/
/**************** Get groups associated to an attendance event ***************/
/*****************************************************************************/
unsigned Att_DB_GetGroupsAssociatedToEvent (MYSQL_RES **mysql_res,long AttCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get groups of an attendance event",
"SELECT grp_types.GrpTypName," // row[0]
"grp_groups.GrpName," // row[1]
"roo_rooms.ShortName" // row[2]
" FROM (att_groups,"
"grp_groups,"
"grp_types)"
" LEFT JOIN roo_rooms"
" ON grp_groups.RooCod=roo_rooms.RooCod"
" WHERE att_groups.AttCod=%ld"
" AND att_groups.GrpCod=grp_groups.GrpCod"
" AND grp_groups.GrpTypCod=grp_types.GrpTypCod"
" ORDER BY grp_types.GrpTypName,"
"grp_groups.GrpName",
AttCod);
}
/*****************************************************************************/
/************* Remove one group from all the attendance events ***************/
/*****************************************************************************/
void Att_DB_RemoveGroup (long GrpCod)
{
/***** Remove group from all the attendance events *****/
DB_QueryDELETE ("can not remove group from the associations"
" between attendance events and groups",
"DELETE FROM att_groups"
" WHERE GrpCod=%ld",
GrpCod);
}
/*****************************************************************************/
/******** Remove groups of one type from all the attendance events ***********/
/*****************************************************************************/
void Att_DB_RemoveGroupsOfType (long GrpTypCod)
{
/***** Remove group from all the attendance events *****/
DB_QueryDELETE ("can not remove groups of a type from the associations"
" between attendance events and groups",
"DELETE FROM att_groups"
" USING grp_groups,"
"att_groups"
" WHERE grp_groups.GrpTypCod=%ld"
" AND grp_groups.GrpCod=att_groups.GrpCod",
GrpTypCod);
}
/*****************************************************************************/
/****************** Remove groups of an attendance event *********************/
/*****************************************************************************/
void Att_DB_RemoveGrpsAssociatedToAnAttEvent (long AttCod)
{
DB_QueryDELETE ("can not remove the groups"
" associated to an attendance event",
"DELETE FROM att_groups"
" WHERE AttCod=%ld",
AttCod);
}
/*****************************************************************************/
/******* Get number of students from a list who attended to an event *********/
/*****************************************************************************/
unsigned Att_DB_GetNumStdsTotalWhoAreInAttEvent (long AttCod)
{
return (unsigned)
DB_QueryCOUNT ("can not get number of students registered in an event",
"SELECT COUNT(*)"
" FROM att_users"
" WHERE AttCod=%ld"
" AND Present='Y'",
AttCod);
}
/*****************************************************************************/
/********** Get number of users from a list in an attendance event ***********/
/*****************************************************************************/
unsigned Att_DB_GetNumStdsFromListWhoAreInAttEvent (long AttCod,const char *SubQueryUsrs)
{
return (unsigned)
DB_QueryCOUNT ("can not get number of students from a list"
" who are registered in an event",
"SELECT COUNT(*)"
" FROM att_users"
" WHERE AttCod=%ld"
" AND UsrCod IN (%s)"
" AND Present='Y'",
AttCod,SubQueryUsrs);
}
/*****************************************************************************/
/******************* Check if a user attended to an event ********************/
/*****************************************************************************/
// Return if user is in table
bool Att_DB_CheckIfUsrIsInTableAttUsr (long AttCod,long UsrCod,bool *Present)
{
char StrPresent[1 + 1];
/***** Check if a user is registered in an event in database *****/
DB_QuerySELECTString (StrPresent,1,"can not check if a user"
" is already registered in an event",
"SELECT Present"
" FROM att_users"
" WHERE AttCod=%ld"
" AND UsrCod=%ld",
AttCod,
UsrCod);
if (StrPresent[0])
{
*Present = (StrPresent[0] == 'Y');
return true; // User is in table
}
*Present = false;
return false; // User is not in table
}
/*****************************************************************************/
/********** Get if a student attended to an event and get comments ***********/
/*****************************************************************************/
unsigned Att_DB_GetPresentAndComments (MYSQL_RES **mysql_res,long AttCod,long UsrCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get if a student"
" is already registered in an event",
"SELECT Present," // row[0]
"CommentStd," // row[1]
"CommentTch" // row[2]
" FROM att_users"
" WHERE AttCod=%ld"
" AND UsrCod=%ld",
AttCod,
UsrCod);
}
/*****************************************************************************/
/********* Register a user in an attendance event changing comments **********/
/*****************************************************************************/
void Att_DB_RegUsrInAttEventChangingComments (long AttCod,long UsrCod,
bool Present,
const char *CommentStd,
const char *CommentTch)
{
/***** Register user as assistant to an event in database *****/
DB_QueryREPLACE ("can not register user in an event",
"REPLACE INTO att_users"
" (AttCod,UsrCod,Present,CommentStd,CommentTch)"
" VALUES"
" (%ld,%ld,'%c','%s','%s')",
AttCod,
UsrCod,
Present ? 'Y' :
'N',
CommentStd,
CommentTch);
}
/*****************************************************************************/
/**************** Set user as present in an attendance event *****************/
/*****************************************************************************/
void Att_DB_SetUsrAsPresent (long AttCod,long UsrCod)
{
DB_QueryUPDATE ("can not set user as present in an event",
"UPDATE att_users"
" SET Present='Y'"
" WHERE AttCod=%ld"
" AND UsrCod=%ld",
AttCod,
UsrCod);
}
/*****************************************************************************/
/********************** Remove a user from an event **************************/
/*****************************************************************************/
void Att_DB_RemoveUsrFromAttEvent (long AttCod,long UsrCod)
{
DB_QueryDELETE ("can not remove student from an event",
"DELETE FROM att_users"
" WHERE AttCod=%ld"
" AND UsrCod=%ld",
AttCod,UsrCod);
}
/*****************************************************************************/
/************ Remove users absent without comments from an event *************/
/*****************************************************************************/
void Att_DB_RemoveUsrsAbsentWithoutCommentsFromAttEvent (long AttCod)
{
/***** Clean table att_users *****/
DB_QueryDELETE ("can not remove users absent"
" without comments from an event",
"DELETE FROM att_users"
" WHERE AttCod=%ld"
" AND Present='N'"
" AND CommentStd=''"
" AND CommentTch=''",
AttCod);
}
/*****************************************************************************/
/*********** Remove all users registered in an attendance event **************/
/*****************************************************************************/
void Att_DB_RemoveAllUsrsFromAnAttEvent (long AttCod)
{
DB_QueryDELETE ("can not remove attendance event",
"DELETE FROM att_users"
" WHERE AttCod=%ld",
AttCod);
}
/*****************************************************************************/
/* Remove one user from all the attendance events where he/she is registered */
/*****************************************************************************/
void Att_DB_RemoveUsrFromAllAttEvents (long UsrCod)
{
DB_QueryDELETE ("can not remove user from all attendance events",
"DELETE FROM att_users"
" WHERE UsrCod=%ld",
UsrCod);
}
/*****************************************************************************/
/*********** Remove one student from all the attendance events ***************/
/*****************************************************************************/
void Att_DB_RemoveUsrFromCrsAttEvents (long UsrCod,long CrsCod)
{
DB_QueryDELETE ("can not remove user from attendance events of a course",
"DELETE FROM att_users"
" USING att_events,"
"att_users"
" WHERE att_events.CrsCod=%ld"
" AND att_events.AttCod=att_users.AttCod"
" AND att_users.UsrCod=%ld",
CrsCod,UsrCod);
}
/*****************************************************************************/
/*********************** Remove an attendance event **************************/
/*****************************************************************************/
void Att_DB_RemoveAttEventFromCurrentCrs (long AttCod)
{
DB_QueryDELETE ("can not remove attendance event",
"DELETE FROM att_events"
" WHERE AttCod=%ld AND CrsCod=%ld",
AttCod,Gbl.Hierarchy.Crs.CrsCod);
}
/*****************************************************************************/
/************* Remove users in all attendance events of a course *************/
/*****************************************************************************/
void Att_DB_RemoveUsrsFromCrsAttEvents (long CrsCod)
{
DB_QueryDELETE ("can not remove users registered"
" in attendance events of a course",
"DELETE FROM att_users"
" USING att_events,"
"att_users"
" WHERE att_events.CrsCod=%ld"
" AND att_events.AttCod=att_users.AttCod",
CrsCod);
}
/*****************************************************************************/
/************ Remove groups in all attendance events of a course *************/
/*****************************************************************************/
void Att_DB_RemoveGrpsAssociatedToCrsAttEvents (long CrsCod)
{
DB_QueryDELETE ("can not remove all groups associated"
" to attendance events of a course",
"DELETE FROM att_groups"
" USING att_events,"
"att_groups"
" WHERE att_events.CrsCod=%ld"
" AND att_events.AttCod=att_groups.AttCod",
CrsCod);
}
/*****************************************************************************/
/***************** Remove all attendance events of a course ******************/
/*****************************************************************************/
void Att_DB_RemoveCrsAttEvents (long CrsCod)
{
DB_QueryDELETE ("can not remove all attendance events of a course",
"DELETE FROM att_events"
" WHERE CrsCod=%ld",
CrsCod);
}
/*****************************************************************************/
/*************** Get number of attendance events in a course *****************/
/*****************************************************************************/
unsigned Att_DB_GetNumAttEventsInCrs (long CrsCod)
{
/***** Get number of attendance events in a course from database *****/
return (unsigned)
DB_QueryCOUNT ("can not get number of attendance events in course",
"SELECT COUNT(*)"
" FROM att_events"
" WHERE CrsCod=%ld",
CrsCod);
}
/*****************************************************************************/
/*************** Get number of courses with attendance events ****************/
/*****************************************************************************/
// Returns the number of courses with attendance events
// in this location (all the platform, current degree or current course)
unsigned Att_DB_GetNumCoursesWithAttEvents (Hie_Lvl_Level_t Scope)
{
switch (Scope)
{
case Hie_Lvl_SYS:
return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT CrsCod)"
" FROM att_events"
" WHERE CrsCod>0");
case Hie_Lvl_INS:
return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM ctr_centers,"
"deg_degrees,"
"crs_courses,"
"att_events"
" WHERE ctr_centers.InsCod=%ld"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Ins.InsCod);
case Hie_Lvl_CTR:
return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM deg_degrees,"
"crs_courses,"
"att_events"
" WHERE deg_degrees.CtrCod=%ld"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Ctr.CtrCod);
case Hie_Lvl_DEG:
return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM crs_courses,"
"att_events"
" WHERE crs_courses.DegCod=%ld"
" AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Deg.DegCod);
case Hie_Lvl_CRS:
return DB_QueryCOUNT ("can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT CrsCod)"
" FROM att_events"
" WHERE CrsCod=%ld",
Gbl.Hierarchy.Crs.CrsCod);
default:
Err_WrongScopeExit ();
return 0; // Not reached
}
}
/*****************************************************************************/
/********************* Get number of attendance events ***********************/
/*****************************************************************************/
unsigned Att_DB_GetNumAttEvents (MYSQL_RES **mysql_res,Hie_Lvl_Level_t Scope)
{
switch (Scope)
{
case Hie_Lvl_SYS:
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," // row[0]
"SUM(NumNotif)" // row[1]
" FROM att_events"
" WHERE CrsCod>0");
case Hie_Lvl_INS:
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," // row[0]
"SUM(att_events.NumNotif)" // row[1]
" FROM ctr_centers,"
"deg_degrees,"
"crs_courses,"
"att_events"
" WHERE ctr_centers.InsCod=%ld"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Ins.InsCod);
case Hie_Lvl_CTR:
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," // row[0]
"SUM(att_events.NumNotif)" // row[1]
" FROM deg_degrees,"
"crs_courses,"
"att_events"
" WHERE deg_degrees.CtrCod=%ld"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Ctr.CtrCod);
case Hie_Lvl_DEG:
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," // row[0]
"SUM(att_events.NumNotif)" // row[1]
" FROM crs_courses,"
"att_events"
" WHERE crs_courses.DegCod=%ld"
" AND crs_courses.CrsCod=att_events.CrsCod",
Gbl.Hierarchy.Deg.DegCod);
case Hie_Lvl_CRS:
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get number of attendance events",
"SELECT COUNT(*)," // row[0]
"SUM(NumNotif)" // row[1]
" FROM att_events"
" WHERE CrsCod=%ld",
Gbl.Hierarchy.Crs.CrsCod);
default:
Err_WrongScopeExit ();
return 0; // Not reached
}
}

View File

@ -0,0 +1,91 @@
// swad_attendance_database.h: control of attendance operations with database
#ifndef _SWAD_ATT_DB
#define _SWAD_ATT_DB
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2021 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include "swad_attendance.h"
#include "swad_date.h"
#include "swad_group.h"
/*****************************************************************************/
/************************** Public types and constants ***********************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
unsigned Att_DB_GetListAttEventsMyGrps (MYSQL_RES **mysql_res,
Dat_StartEndTime_t SelectedOrder,
Att_OrderNewestOldest_t OrderNewestOldest);
unsigned Att_DB_GetListAttEventsAllGrps (MYSQL_RES **mysql_res,
Dat_StartEndTime_t SelectedOrder,
Att_OrderNewestOldest_t OrderNewestOldest);
unsigned Att_DB_GetDataOfAttEventByCod (MYSQL_RES **mysql_res,long AttCod);
void Att_DB_GetAttEventDescription (long AttCod,char Description[Cns_MAX_BYTES_TEXT + 1]);
bool Att_DB_CheckIfSimilarAttEventExists (const char *Field,const char *Value,long AttCod);
long Att_DB_CreateAttEvent (const struct Att_Event *Event,const char *Description);
void Att_DB_UpdateAttEvent (const struct Att_Event *Event,const char *Description);
void Att_DB_HideAttEvent (long AttCod);
void Att_DB_UnhideAttEvent (long AttCod);
void Att_DB_CreateGroup (long AttCod,long GrpCod);
unsigned Att_DB_GetGrpCodsAssociatedToEvent (MYSQL_RES **mysql_res,long AttCod);
unsigned Att_DB_GetGroupsAssociatedToEvent (MYSQL_RES **mysql_res,long AttCod);
void Att_DB_RemoveGroup (long GrpCod);
void Att_DB_RemoveGroupsOfType (long GrpTypCod);
void Att_DB_RemoveGrpsAssociatedToAnAttEvent (long AttCod);
unsigned Att_DB_GetNumStdsTotalWhoAreInAttEvent (long AttCod);
unsigned Att_DB_GetNumStdsFromListWhoAreInAttEvent (long AttCod,const char *SubQueryUsrs);
bool Att_DB_CheckIfUsrIsInTableAttUsr (long AttCod,long UsrCod,bool *Present);
unsigned Att_DB_GetPresentAndComments (MYSQL_RES **mysql_res,long AttCod,long UsrCod);
void Att_DB_RegUsrInAttEventChangingComments (long AttCod,long UsrCod,
bool Present,
const char *CommentStd,
const char *CommentTch);
void Att_DB_SetUsrAsPresent (long AttCod,long UsrCod);
void Att_DB_RemoveUsrFromAttEvent (long AttCod,long UsrCod);
void Att_DB_RemoveUsrsAbsentWithoutCommentsFromAttEvent (long AttCod);
void Att_DB_RemoveAllUsrsFromAnAttEvent (long AttCod);
void Att_DB_RemoveUsrFromAllAttEvents (long UsrCod);
void Att_DB_RemoveUsrFromCrsAttEvents (long UsrCod,long CrsCod);
void Att_DB_RemoveAttEventFromCurrentCrs (long AttCod);
void Att_DB_RemoveUsrsFromCrsAttEvents (long CrsCod);
void Att_DB_RemoveGrpsAssociatedToCrsAttEvents (long CrsCod);
void Att_DB_RemoveCrsAttEvents (long CrsCod);
unsigned Att_DB_GetNumAttEventsInCrs (long CrsCod);
unsigned Att_DB_GetNumCoursesWithAttEvents (Hie_Lvl_Level_t Scope);
unsigned Att_DB_GetNumAttEvents (MYSQL_RES **mysql_res,Hie_Lvl_Level_t Scope);
#endif

View File

@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
*/
#define Log_PLATFORM_VERSION "SWAD 20.75 (2021-05-11)"
#define Log_PLATFORM_VERSION "SWAD 20.76 (2021-05-13)"
#define CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.69.1.js"
/*
TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
Version 20.76: May 11, 2021 New module swad_atendance_database for database queries related to attendante events. (311109 lines)
Version 20.75: May 11, 2021 New module swad_assignment_database for database queries related to assignments. (310858 lines)
Version 20.74: May 11, 2021 New module swad_announcement_database for database queries related to announcements. (310629 lines)
Version 20.73: May 10, 2021 New module swad_agenda_database for database queries related to agenda. (310474 lines)

View File

@ -32,7 +32,7 @@
#include "swad_account.h"
#include "swad_announcement.h"
#include "swad_attendance.h"
#include "swad_attendance_database.h"
#include "swad_box.h"
#include "swad_database.h"
#include "swad_duplicate.h"

View File

@ -33,7 +33,7 @@
#include "swad_action.h"
#include "swad_assignment_database.h"
#include "swad_attendance.h"
#include "swad_attendance_database.h"
#include "swad_box.h"
#include "swad_database.h"
#include "swad_error.h"
@ -4147,7 +4147,7 @@ static void Grp_RemoveGroupTypeCompletely (void)
Asg_DB_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod);
/***** Remove the associations of attendance events to groups of this type *****/
Att_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod);
Att_DB_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod);
/***** Remove the associations of matches to groups of this type *****/
Mch_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod);
@ -4216,7 +4216,7 @@ static void Grp_RemoveGroupCompletely (void)
Asg_DB_RemoveGroup (GrpDat.GrpCod);
/***** Remove this group from all attendance events *****/
Att_RemoveGroup (GrpDat.GrpCod);
Att_DB_RemoveGroup (GrpDat.GrpCod);
/***** Remove this group from all matches *****/
Mch_RemoveGroup (GrpDat.GrpCod);