swad-core/swad_attendance.c

3722 lines
131 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_attendance.c: control of attendance
/*
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.
2019-01-07 21:52:19 +01:00
Copyright (C) 1999-2019 Antonio Ca<EFBFBD>as Vargas
2014-12-01 23:55:08 +01:00
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 <linux/limits.h> // For PATH_MAX
#include <linux/stddef.h> // For NULL
#include <mysql/mysql.h> // To access MySQL databases
#include <stdlib.h> // For calloc
#include <string.h> // For string functions
#include "swad_attendance.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2014-12-01 23:55:08 +01:00
#include "swad_database.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_global.h"
#include "swad_group.h"
#include "swad_ID.h"
#include "swad_pagination.h"
#include "swad_parameter.h"
#include "swad_photo.h"
#include "swad_QR.h"
2019-03-26 11:53:21 +01:00
#include "swad_setting.h"
2017-06-11 20:09:59 +02:00
#include "swad_table.h"
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*************** External global variables from others modules ***************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/****************************** Private constants ****************************/
/*****************************************************************************/
2018-10-18 16:56:07 +02:00
#define Att_ATTENDANCE_TABLE_ID "att_table"
#define Att_ATTENDANCE_DETAILS_ID "att_details"
2018-10-18 11:29:02 +02:00
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/******************************** Private types ******************************/
/*****************************************************************************/
2015-11-13 01:27:44 +01:00
typedef enum
{
2016-03-20 02:08:13 +01:00
Att_NORMAL_VIEW_ONLY_ME,
Att_NORMAL_VIEW_STUDENTS,
2015-11-13 01:27:44 +01:00
Att_PRINT_VIEW,
} Att_TypeOfView_t;
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/****************************** Private variables ****************************/
/*****************************************************************************/
/*****************************************************************************/
/****************************** Private prototypes ***************************/
/*****************************************************************************/
static void Att_ShowAllAttEvents (void);
2016-12-04 23:09:28 +01:00
static void Att_ParamsWhichGroupsToShow (void);
2018-10-18 08:56:00 +02:00
static void Att_PutIconsInListOfAttEvents (void);
2016-03-20 00:33:27 +01:00
static void Att_PutIconToCreateNewAttEvent (void);
static void Att_PutButtonToCreateNewAttEvent (void);
static void Att_PutParamsToCreateNewAttEvent (void);
2014-12-01 23:55:08 +01:00
static void Att_ShowOneAttEvent (struct AttendanceEvent *Att,bool ShowOnlyThisAttEventComplete);
static void Att_WriteAttEventAuthor (struct AttendanceEvent *Att);
2017-01-29 12:42:19 +01:00
static void Att_GetParamAttOrder (void);
2015-04-02 18:39:49 +02:00
2015-11-13 01:27:44 +01:00
static void Att_PutFormToListMyAttendance (void);
static void Att_PutFormToListStdsAttendance (void);
2015-04-02 18:39:49 +02:00
static void Att_PutFormToListStdsParams (void);
2014-12-01 23:55:08 +01:00
static void Att_PutFormsToRemEditOneAttEvent (long AttCod,bool Hidden);
2015-12-13 19:37:08 +01:00
static void Att_PutParams (void);
2019-01-03 15:25:18 +01:00
static void Att_GetListAttEvents (Att_OrderNewestOldest_t OrderNewestOldest);
2014-12-01 23:55:08 +01:00
static void Att_GetDataOfAttEventByCodAndCheckCrs (struct AttendanceEvent *Att);
2016-12-29 23:07:30 +01:00
static void Att_ResetAttendanceEvent (struct AttendanceEvent *Att);
2019-02-15 21:09:18 +01:00
static void Att_GetAttEventDescriptionFromDB (long AttCod,char Description[Cns_MAX_BYTES_TEXT + 1]);
2014-12-01 23:55:08 +01:00
static bool Att_CheckIfSimilarAttEventExists (const char *Field,const char *Value,long AttCod);
static void Att_ShowLstGrpsToEditAttEvent (long AttCod);
static void Att_RemoveAllTheGrpsAssociatedToAnAttEvent (long AttCod);
static void Att_CreateGrps (long AttCod);
static void Att_GetAndWriteNamesOfGrpsAssociatedToAttEvent (struct AttendanceEvent *Att);
2016-09-06 18:29:13 +02:00
static void Att_RemoveAllUsrsFromAnAttEvent (long AttCod);
static void Att_RemoveAttEventFromCurrentCrs (long AttCod);
2014-12-01 23:55:08 +01:00
static void Att_ListAttOnlyMeAsStudent (struct AttendanceEvent *Att);
static void Att_ListAttStudents (struct AttendanceEvent *Att);
2017-05-20 12:04:12 +02:00
static void Att_WriteRowStdToCallTheRoll (unsigned NumStd,
struct UsrData *UsrDat,
struct AttendanceEvent *Att);
2018-12-03 19:49:54 +01:00
static void Att_PutLinkAttEvent (struct AttendanceEvent *AttEvent,
const char *Title,const char *Txt,
const char *LinkStyle);
2014-12-01 23:55:08 +01:00
static void Att_PutParamsCodGrps (long AttCod);
static void Att_GetNumStdsTotalWhoAreInAttEvent (struct AttendanceEvent *Att);
static unsigned Att_GetNumStdsFromAListWhoAreInAttEvent (long AttCod,long LstSelectedUsrCods[],unsigned NumStdsInList);
static bool Att_CheckIfUsrIsInTableAttUsr (long AttCod,long UsrCod,bool *Present);
static bool Att_CheckIfUsrIsPresentInAttEvent (long AttCod,long UsrCod);
2017-01-17 03:10:43 +01:00
static bool Att_CheckIfUsrIsPresentInAttEventAndGetComments (long AttCod,long UsrCod,
char CommentStd[Cns_MAX_BYTES_TEXT + 1],
char CommentTch[Cns_MAX_BYTES_TEXT + 1]);
2014-12-01 23:55:08 +01:00
static void Att_RegUsrInAttEventChangingComments (long AttCod,long UsrCod,bool Present,
const char *CommentStd,const char *CommentTch);
static void Att_RemoveUsrFromAttEvent (long AttCod,long UsrCod);
2015-11-13 01:27:44 +01:00
static void Usr_ListOrPrintMyAttendanceCrs (Att_TypeOfView_t TypeOfView);
static void Usr_ListOrPrintStdsAttendanceCrs (Att_TypeOfView_t TypeOfView);
2014-12-07 02:04:30 +01:00
static void Att_GetListSelectedUsrCods (unsigned NumStdsInList,long **LstSelectedUsrCods);
2014-12-08 01:30:47 +01:00
static void Att_GetListSelectedAttCods (char **StrAttCodsSelected);
2015-04-02 18:39:49 +02:00
2018-10-18 11:10:04 +02:00
static void Att_PutIconsMyAttList (void);
2015-11-13 01:27:44 +01:00
static void Att_PutFormToPrintMyListParams (void);
2018-10-18 11:10:04 +02:00
static void Att_PutIconsStdsAttList (void);
2016-03-20 02:08:13 +01:00
static void Att_PutParamsToPrintStdsList (void);
2015-04-02 18:39:49 +02:00
static void Att_PutButtonToShowDetails (void);
2015-11-13 01:27:44 +01:00
static void Att_ListEventsToSelect (Att_TypeOfView_t TypeOfView);
2018-10-18 11:10:04 +02:00
static void Att_PutIconToEditAttEvents (void);
static void Att_PutIconToViewAttEvents (void);
2016-03-20 02:08:13 +01:00
static void Att_ListStdsAttendanceTable (Att_TypeOfView_t TypeOfView,
unsigned NumStdsInList,
long *LstSelectedUsrCods);
2014-12-01 23:55:08 +01:00
static void Att_WriteTableHeadSeveralAttEvents (void);
static void Att_WriteRowStdSeveralAttEvents (unsigned NumStd,struct UsrData *UsrDat);
2019-02-13 21:24:54 +01:00
static void Att_PutCheckOrCross (bool Present);
2018-10-18 09:59:38 +02:00
static void Att_ListStdsWithAttEventsDetails (unsigned NumStdsInList,
2016-11-27 23:08:29 +01:00
long *LstSelectedUsrCods);
2014-12-06 02:21:34 +01:00
static void Att_ListAttEventsForAStd (unsigned NumStd,struct UsrData *UsrDat);
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************** List all the attendance events ***********************/
/*****************************************************************************/
void Att_SeeAttEvents (void)
{
/***** Get parameters *****/
2017-01-29 12:42:19 +01:00
Att_GetParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_GetParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Gbl.AttEvents.CurrentPage = Pag_GetParamPagNum (Pag_ATT_EVENTS);
2014-12-01 23:55:08 +01:00
2015-11-13 01:27:44 +01:00
/***** Get list of attendance events *****/
Att_GetListAttEvents (Att_NEWEST_FIRST);
2018-10-18 08:56:00 +02:00
/***** Put link to show list of attendance *****/
if (Gbl.AttEvents.Num &&
2016-03-20 00:33:27 +01:00
Gbl.Usrs.Me.UsrDat.Nickname[0])
2018-10-18 08:56:00 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
fprintf (Gbl.F.Out,"<div class=\"CONTEXT_MENU\">");
Att_PutFormToListMyAttendance ();
fprintf (Gbl.F.Out,"</div>");
break;
case Rol_NET:
case Rol_TCH:
case Rol_SYS_ADM:
fprintf (Gbl.F.Out,"<div class=\"CONTEXT_MENU\">");
Att_PutFormToListStdsAttendance ();
fprintf (Gbl.F.Out,"</div>");
break;
default:
break;
}
2014-12-01 23:55:08 +01:00
/***** Show all the attendance events *****/
2016-03-20 00:33:27 +01:00
Att_ShowAllAttEvents ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Show all the attendance events ***********************/
/*****************************************************************************/
static void Att_ShowAllAttEvents (void)
{
2016-11-13 21:08:14 +01:00
extern const char *Hlp_USERS_Attendance;
2015-01-02 12:57:26 +01:00
extern const char *Txt_Events;
2016-12-15 00:39:52 +01:00
extern const char *Txt_START_END_TIME_HELP[Dat_NUM_START_END_TIME];
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
2014-12-01 23:55:08 +01:00
extern const char *Txt_Event;
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2016-03-20 00:33:27 +01:00
extern const char *Txt_No_events;
2016-12-15 00:39:52 +01:00
Dat_StartEndTime_t Order;
2014-12-01 23:55:08 +01:00
struct Pagination Pagination;
unsigned NumAttEvent;
2017-06-04 18:18:54 +02:00
bool ICanEdit = (Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
2014-12-01 23:55:08 +01:00
2016-03-20 00:33:27 +01:00
/***** Compute variables related to pagination *****/
Pagination.NumItems = Gbl.AttEvents.Num;
2017-04-13 20:09:22 +02:00
Pagination.CurrentPage = (int) Gbl.AttEvents.CurrentPage;
2016-03-20 00:33:27 +01:00
Pag_CalculatePagination (&Pagination);
2017-04-13 20:09:22 +02:00
Gbl.AttEvents.CurrentPage = (unsigned) Pagination.CurrentPage;
2015-01-02 12:57:26 +01:00
2016-03-20 00:33:27 +01:00
/***** Write links to pages *****/
if (Pagination.MoreThanOnePage)
2017-04-17 11:57:55 +02:00
Pag_WriteLinksToPagesCentered (Pag_ATT_EVENTS,
0,
&Pagination);
2015-01-02 12:57:26 +01:00
2017-06-12 14:16:33 +02:00
/***** Start box *****/
2018-10-18 08:56:00 +02:00
Box_StartBox ("100%",Txt_Events,Att_PutIconsInListOfAttEvents,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Attendance,Box_NOT_CLOSABLE);
2015-01-02 12:57:26 +01:00
2016-03-20 00:33:27 +01:00
/***** Select whether show only my groups or all groups *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps)
2019-02-25 15:14:28 +01:00
{
2019-03-26 11:53:21 +01:00
Set_StartSettingsHead ();
2019-02-25 15:14:28 +01:00
Grp_ShowFormToSelWhichGrps (ActSeeAtt,Att_ParamsWhichGroupsToShow);
2019-03-26 11:53:21 +01:00
Set_EndSettingsHead ();
2019-02-25 15:14:28 +01:00
}
2015-01-02 12:57:26 +01:00
2016-03-20 00:33:27 +01:00
if (Gbl.AttEvents.Num)
{
2015-11-13 01:27:44 +01:00
/***** Table head *****/
2017-06-11 20:09:59 +02:00
Tbl_StartTableWideMargin (2);
2017-05-20 12:04:12 +02:00
fprintf (Gbl.F.Out,"<tr>"
"<th class=\"CONTEXT_COL\"></th>"); // Column for contextual icons
2016-12-15 00:39:52 +01:00
for (Order = Dat_START_TIME;
Order <= Dat_END_TIME;
2015-11-13 01:27:44 +01:00
Order++)
{
fprintf (Gbl.F.Out,"<th class=\"LEFT_MIDDLE\">");
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActSeeAtt);
2015-11-13 01:27:44 +01:00
Grp_PutParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Pag_PutHiddenParamPagNum (Pag_ATT_EVENTS,Gbl.AttEvents.CurrentPage);
2015-11-13 01:27:44 +01:00
Par_PutHiddenParamUnsigned ("Order",(unsigned) Order);
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_START_END_TIME_HELP[Order],"TIT_TBL",NULL);
2017-01-29 12:42:19 +01:00
if (Order == Gbl.AttEvents.SelectedOrder)
2015-11-13 01:27:44 +01:00
fprintf (Gbl.F.Out,"<u>");
2016-12-15 00:39:52 +01:00
fprintf (Gbl.F.Out,"%s",Txt_START_END_TIME[Order]);
2017-01-29 12:42:19 +01:00
if (Order == Gbl.AttEvents.SelectedOrder)
2015-11-13 01:27:44 +01:00
fprintf (Gbl.F.Out,"</u>");
fprintf (Gbl.F.Out,"</a>");
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2015-11-13 01:27:44 +01:00
fprintf (Gbl.F.Out,"</th>");
}
fprintf (Gbl.F.Out,"<th class=\"LEFT_MIDDLE\">"
"%s"
"</th>"
"<th class=\"RIGHT_MIDDLE\">"
"%s"
"</th>"
"</tr>",
Txt_Event,
2017-05-18 19:13:41 +02:00
Txt_ROLES_PLURAL_Abc[Rol_STD][Usr_SEX_UNKNOWN]);
2015-01-02 12:57:26 +01:00
2015-11-13 01:27:44 +01:00
/***** Write all the attendance events *****/
for (NumAttEvent = Pagination.FirstItemVisible, Gbl.RowEvenOdd = 0;
NumAttEvent <= Pagination.LastItemVisible;
NumAttEvent++)
2016-10-26 01:23:02 +02:00
Att_ShowOneAttEvent (&Gbl.AttEvents.Lst[NumAttEvent - 1],false);
2015-01-02 12:57:26 +01:00
2016-03-20 00:33:27 +01:00
/***** End table *****/
2017-06-11 20:09:59 +02:00
Tbl_EndTable ();
2016-03-20 00:33:27 +01:00
}
else // No events created
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_events);
2016-03-20 00:33:27 +01:00
/***** Button to create a new attendance event *****/
2016-03-20 02:08:13 +01:00
if (ICanEdit)
Att_PutButtonToCreateNewAttEvent ();
2016-03-20 00:33:27 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2017-06-10 21:38:10 +02:00
Box_EndBox ();
2014-12-01 23:55:08 +01:00
2016-03-20 00:33:27 +01:00
/***** Write again links to pages *****/
if (Pagination.MoreThanOnePage)
2017-04-17 11:57:55 +02:00
Pag_WriteLinksToPagesCentered (Pag_ATT_EVENTS,
0,
&Pagination);
2016-03-20 00:33:27 +01:00
/***** Free list of attendance events *****/
Att_FreeListAttEvents ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2019-02-25 15:14:28 +01:00
/***************** Put params to select which groups to show *****************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-12-04 23:09:28 +01:00
static void Att_ParamsWhichGroupsToShow (void)
{
2017-01-29 12:42:19 +01:00
Att_PutHiddenParamAttOrder ();
2017-04-13 20:09:22 +02:00
Pag_PutHiddenParamPagNum (Pag_ATT_EVENTS,Gbl.AttEvents.CurrentPage);
2014-12-01 23:55:08 +01:00
}
2018-10-18 08:56:00 +02:00
/*****************************************************************************/
/************* Put contextual icons in list of attendance events *************/
/*****************************************************************************/
static void Att_PutIconsInListOfAttEvents (void)
{
bool ICanEdit = (Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
/***** Put icon to create a new attendance event *****/
if (ICanEdit)
Att_PutIconToCreateNewAttEvent ();
/***** Put icon to print my QR code *****/
QR_PutLinkToPrintQRCode (ActPrnUsrQR,Usr_PutParamMyUsrCodEncrypted);
}
2016-03-20 00:33:27 +01:00
/*****************************************************************************/
/**************** Put icon to create a new attendance event ******************/
/*****************************************************************************/
static void Att_PutIconToCreateNewAttEvent (void)
{
extern const char *Txt_New_event;
2018-10-18 08:56:00 +02:00
/***** Put icon to create a new attendance event *****/
2019-01-10 15:26:33 +01:00
Ico_PutContextualIconToAdd (ActFrmNewAtt,NULL,
Att_PutParamsToCreateNewAttEvent,
Txt_New_event);
2016-03-20 00:33:27 +01:00
}
/*****************************************************************************/
/**************** Put button to create a new attendance event ****************/
/*****************************************************************************/
static void Att_PutButtonToCreateNewAttEvent (void)
{
extern const char *Txt_New_event;
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActFrmNewAtt);
2016-03-20 00:33:27 +01:00
Att_PutParamsToCreateNewAttEvent ();
2017-06-11 19:02:40 +02:00
Btn_PutConfirmButton (Txt_New_event);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-03-20 00:33:27 +01:00
}
/*****************************************************************************/
/************** Put parameters to create a new attendance event **************/
/*****************************************************************************/
static void Att_PutParamsToCreateNewAttEvent (void)
{
2017-01-29 12:42:19 +01:00
Att_PutHiddenParamAttOrder ();
2016-03-20 00:33:27 +01:00
Grp_PutParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Pag_PutHiddenParamPagNum (Pag_ATT_EVENTS,Gbl.AttEvents.CurrentPage);
2016-03-20 00:33:27 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************************* Show one attendance event *************************/
/*****************************************************************************/
// Only Att->AttCod must be filled
static void Att_ShowOneAttEvent (struct AttendanceEvent *Att,bool ShowOnlyThisAttEventComplete)
{
2015-12-29 11:35:01 +01:00
extern const char *Txt_Today;
2014-12-01 23:55:08 +01:00
extern const char *Txt_View_event;
2015-10-23 13:20:42 +02:00
static unsigned UniqueId = 0;
2019-02-15 21:09:18 +01:00
char Description[Cns_MAX_BYTES_TEXT + 1];
2014-12-01 23:55:08 +01:00
/***** Get data of this attendance event *****/
Att_GetDataOfAttEventByCodAndCheckCrs (Att);
Att_GetNumStdsTotalWhoAreInAttEvent (Att);
2017-05-02 11:39:17 +02:00
/***** Write first row of data of this attendance event *****/
/* Forms to remove/edit this attendance event */
2016-12-27 11:33:13 +01:00
fprintf (Gbl.F.Out,"<tr>"
2017-05-23 18:15:59 +02:00
"<td rowspan=\"2\" class=\"CONTEXT_COL");
if (!ShowOnlyThisAttEventComplete)
fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">");
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2017-05-02 11:39:17 +02:00
{
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2017-05-02 11:39:17 +02:00
case Rol_SYS_ADM:
Att_PutFormsToRemEditOneAttEvent (Att->AttCod,Att->Hidden);
break;
default:
break;
}
fprintf (Gbl.F.Out,"</td>");
/* Start date/time */
UniqueId++;
2017-05-07 17:26:46 +02:00
fprintf (Gbl.F.Out,"<td id=\"att_date_start_%u\" class=\"%s LEFT_BOTTOM",
2015-10-23 13:20:42 +02:00
UniqueId,
2014-12-01 23:55:08 +01:00
Att->Hidden ? (Att->Open ? "DATE_GREEN_LIGHT" :
"DATE_RED_LIGHT") :
(Att->Open ? "DATE_GREEN" :
"DATE_RED"));
if (!ShowOnlyThisAttEventComplete)
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">"
2015-10-23 13:20:42 +02:00
"<script type=\"text/javascript\">"
2017-05-04 17:06:26 +02:00
"writeLocalDateHMSFromUTC('att_date_start_%u',%ld,"
2017-05-05 09:41:56 +02:00
"%u,'<br />','%s',true,true,0x7);"
2015-10-23 13:20:42 +02:00
"</script>"
2015-07-28 00:51:32 +02:00
"</td>",
2017-05-04 17:06:26 +02:00
UniqueId,Att->TimeUTC[Att_START_TIME],
(unsigned) Gbl.Prefs.DateFormat,Txt_Today);
2014-12-01 23:55:08 +01:00
2017-05-02 11:39:17 +02:00
/* End date/time */
2017-05-07 17:26:46 +02:00
fprintf (Gbl.F.Out,"<td id=\"att_date_end_%u\" class=\"%s LEFT_BOTTOM",
2015-10-23 13:20:42 +02:00
UniqueId,
2014-12-01 23:55:08 +01:00
Att->Hidden ? (Att->Open ? "DATE_GREEN_LIGHT" :
"DATE_RED_LIGHT") :
(Att->Open ? "DATE_GREEN" :
"DATE_RED"));
if (!ShowOnlyThisAttEventComplete)
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">"
2015-10-23 13:20:42 +02:00
"<script type=\"text/javascript\">"
2017-05-04 17:06:26 +02:00
"writeLocalDateHMSFromUTC('att_date_end_%u',%ld,"
2017-05-05 09:41:56 +02:00
"%u,'<br />','%s',false,true,0x7);"
2015-10-23 13:20:42 +02:00
"</script>"
2014-12-22 14:08:19 +01:00
"</td>",
2017-05-04 17:06:26 +02:00
UniqueId,Att->TimeUTC[Att_END_TIME],
(unsigned) Gbl.Prefs.DateFormat,Txt_Today);
2014-12-01 23:55:08 +01:00
2017-05-02 11:39:17 +02:00
/* Attendance event title */
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP");
2014-12-01 23:55:08 +01:00
if (!ShowOnlyThisAttEventComplete)
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">");
2018-12-03 19:49:54 +01:00
Att_PutLinkAttEvent (Att,Txt_View_event,Att->Title,
Att->Hidden ? "ASG_TITLE_LIGHT" :
"ASG_TITLE");
2015-03-13 00:16:02 +01:00
fprintf (Gbl.F.Out,"</td>");
2014-12-01 23:55:08 +01:00
2017-05-02 11:39:17 +02:00
/* Number of students in this event */
2016-12-13 13:32:19 +01:00
fprintf (Gbl.F.Out,"<td class=\"%s RIGHT_TOP",
Att->Hidden ? "ASG_TITLE_LIGHT" :
"ASG_TITLE");
2014-12-01 23:55:08 +01:00
if (!ShowOnlyThisAttEventComplete)
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">"
2014-12-22 14:08:19 +01:00
"%u"
"</td>"
2014-12-01 23:55:08 +01:00
"</tr>",
Att->NumStdsTotal);
/***** Write second row of data of this attendance event *****/
fprintf (Gbl.F.Out,"<tr>"
2017-05-23 18:15:59 +02:00
"<td colspan=\"2\" class=\"LEFT_TOP");
if (!ShowOnlyThisAttEventComplete)
fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">");
2014-12-01 23:55:08 +01:00
/* Author of the attendance event */
Att_WriteAttEventAuthor (Att);
fprintf (Gbl.F.Out,"</td>");
/* Text of the attendance event */
2019-02-15 21:09:18 +01:00
Att_GetAttEventDescriptionFromDB (Att->AttCod,Description);
2014-12-01 23:55:08 +01:00
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
2019-02-15 21:09:18 +01:00
Description,Cns_MAX_BYTES_TEXT,false); // Convert from HTML to recpectful HTML
Str_InsertLinks (Description,Cns_MAX_BYTES_TEXT,60); // Insert links
2017-05-23 18:15:59 +02:00
fprintf (Gbl.F.Out,"<td colspan=\"2\" class=\"LEFT_TOP");
if (!ShowOnlyThisAttEventComplete)
fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd);
fprintf (Gbl.F.Out,"\">");
2014-12-01 23:55:08 +01:00
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps)
2014-12-01 23:55:08 +01:00
Att_GetAndWriteNamesOfGrpsAssociatedToAttEvent (Att);
2015-09-06 11:36:34 +02:00
fprintf (Gbl.F.Out,"<div class=\"%s\">%s</div>",
2014-12-01 23:55:08 +01:00
Att->Hidden ? "DAT_LIGHT" :
"DAT",
2019-02-15 21:09:18 +01:00
Description);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</td>"
"</tr>");
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
}
/*****************************************************************************/
/****************** Write the author of an attendance event ******************/
/*****************************************************************************/
static void Att_WriteAttEventAuthor (struct AttendanceEvent *Att)
{
2017-03-04 01:59:27 +01:00
Usr_WriteAuthor1Line (Att->UsrCod,Att->Hidden);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**** Get parameter with the type or order in list of attendance events ******/
/*****************************************************************************/
2017-01-29 12:42:19 +01:00
static void Att_GetParamAttOrder (void)
2014-12-01 23:55:08 +01:00
{
2017-01-29 21:41:08 +01:00
Gbl.AttEvents.SelectedOrder = (Dat_StartEndTime_t)
Par_GetParToUnsignedLong ("Order",
0,
Dat_NUM_START_END_TIME - 1,
(unsigned long) Att_ORDER_DEFAULT);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*** Put a hidden parameter with the type of order in list of att. events ****/
/*****************************************************************************/
2017-01-29 12:42:19 +01:00
void Att_PutHiddenParamAttOrder (void)
2014-12-01 23:55:08 +01:00
{
2017-01-29 12:42:19 +01:00
Par_PutHiddenParamUnsigned ("Order",(unsigned) Gbl.AttEvents.SelectedOrder);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**** Put a link (form) to list assistance of students to several events *****/
/*****************************************************************************/
2015-11-13 01:27:44 +01:00
static void Att_PutFormToListMyAttendance (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Attendance_list;
2019-01-12 03:00:59 +01:00
Lay_PutContextualLinkIconText (ActSeeLstMyAtt,NULL,NULL,
"list-ol.svg",
Txt_Attendance_list);
2015-11-13 01:27:44 +01:00
}
/*****************************************************************************/
/** Put a link (form) to list my assistance (as student) to several events ***/
/*****************************************************************************/
static void Att_PutFormToListStdsAttendance (void)
{
extern const char *Txt_Attendance_list;
2019-01-12 03:00:59 +01:00
Lay_PutContextualLinkIconText (ActReqLstStdAtt,NULL,
Att_PutFormToListStdsParams,
"list-ol.svg",
Txt_Attendance_list);
2015-04-02 18:39:49 +02:00
}
static void Att_PutFormToListStdsParams (void)
{
2017-01-29 12:42:19 +01:00
Att_PutHiddenParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_PutParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Pag_PutHiddenParamPagNum (Pag_ATT_EVENTS,Gbl.AttEvents.CurrentPage);
2014-12-01 23:55:08 +01:00
}
2017-03-25 17:49:28 +01:00
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************** Put a link (form) to edit one attendance event ***************/
/*****************************************************************************/
static void Att_PutFormsToRemEditOneAttEvent (long AttCod,bool Hidden)
{
2015-12-13 19:37:08 +01:00
Gbl.AttEvents.AttCodToEdit = AttCod; // Used as parameters in contextual links
2014-12-01 23:55:08 +01:00
/***** Put form to remove attendance event *****/
2017-06-11 19:13:28 +02:00
Ico_PutContextualIconToRemove (ActReqRemAtt,Att_PutParams);
2014-12-01 23:55:08 +01:00
/***** Put form to hide/show attendance event *****/
if (Hidden)
2019-03-25 19:05:10 +01:00
Ico_PutContextualIconToUnhide (ActShoAtt,NULL,Att_PutParams);
2014-12-01 23:55:08 +01:00
else
2019-03-25 19:05:10 +01:00
Ico_PutContextualIconToHide (ActHidAtt,NULL,Att_PutParams);
2014-12-01 23:55:08 +01:00
/***** Put form to edit attendance event *****/
2017-06-11 19:13:28 +02:00
Ico_PutContextualIconToEdit (ActEdiOneAtt,Att_PutParams);
2015-12-13 19:37:08 +01:00
}
/*****************************************************************************/
/***************** Params used to edit an attendance event *******************/
/*****************************************************************************/
static void Att_PutParams (void)
{
Att_PutParamAttCod (Gbl.AttEvents.AttCodToEdit);
2017-01-29 12:42:19 +01:00
Att_PutHiddenParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_PutParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Pag_PutHiddenParamPagNum (Pag_ATT_EVENTS,Gbl.AttEvents.CurrentPage);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************* List all the attendance events ************************/
/*****************************************************************************/
2019-01-03 15:25:18 +01:00
static void Att_GetListAttEvents (Att_OrderNewestOldest_t OrderNewestOldest)
2014-12-01 23:55:08 +01:00
{
2019-01-03 15:25:18 +01:00
static const char *HiddenSubQuery[Rol_NUM_ROLES] =
{
" AND Hidden='N'", // Rol_UNK
" AND Hidden='N'", // Rol_GST
" AND Hidden='N'", // Rol_USR
" AND Hidden='N'", // Rol_STD
" AND Hidden='N'", // Rol_NET
"", // Rol_TCH
" AND Hidden='N'", // Rol_DEG_ADM
" AND Hidden='N'", // Rol_CTR_ADM
" AND Hidden='N'", // Rol_INS_ADM
"", // Rol_SYS_ADM
};
static const char *OrderBySubQuery[Dat_NUM_START_END_TIME][Att_NUM_ORDERS_NEWEST_OLDEST] =
{
{ // Dat_START_TIME
"StartTime DESC,EndTime DESC,Title DESC", // Att_NEWEST_FIRST
"StartTime,EndTime,Title", // Att_OLDEST_FIRST
},
{ // Dat_END_TIME
"EndTime DESC,StartTime DESC,Title DESC", // Att_NEWEST_FIRST
"EndTime,StartTime,Title", // Att_OLDEST_FIRST
}
};
2014-12-01 23:55:08 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows;
unsigned NumAttEvent;
if (Gbl.AttEvents.LstIsRead)
Att_FreeListAttEvents ();
/***** Get list of attendance events from database *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.WhichGrps == Grp_ONLY_MY_GROUPS)
2018-10-30 13:59:37 +01:00
NumRows = 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_grp) OR"
" AttCod IN (SELECT att_grp.AttCod FROM att_grp,crs_grp_usr"
" WHERE crs_grp_usr.UsrCod=%ld"
" AND att_grp.GrpCod=crs_grp_usr.GrpCod))"
" ORDER BY %s",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod,
2019-01-03 15:25:18 +01:00
HiddenSubQuery[Gbl.Usrs.Me.Role.Logged],
Gbl.Usrs.Me.UsrDat.UsrCod,
OrderBySubQuery[Gbl.AttEvents.SelectedOrder][OrderNewestOldest]);
2019-04-04 10:45:15 +02:00
else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS
2018-10-30 13:59:37 +01:00
NumRows = DB_QuerySELECT (&mysql_res,"can not get attendance events",
"SELECT AttCod"
" FROM att_events"
" WHERE CrsCod=%ld%s"
" ORDER BY %s",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod,
2019-01-03 15:25:18 +01:00
HiddenSubQuery[Gbl.Usrs.Me.Role.Logged],
OrderBySubQuery[Gbl.AttEvents.SelectedOrder][OrderNewestOldest]);
2014-12-01 23:55:08 +01:00
2018-10-30 01:00:46 +01:00
if (NumRows) // Attendance events found...
2014-12-01 23:55:08 +01:00
{
Gbl.AttEvents.Num = (unsigned) NumRows;
/***** Create list of attendance events *****/
if ((Gbl.AttEvents.Lst = (struct AttendanceEvent *) calloc (NumRows,sizeof (struct AttendanceEvent))) == NULL)
2018-10-18 20:06:54 +02:00
Lay_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
/***** Get the attendance events codes *****/
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
{
/* Get next attendance event code */
row = mysql_fetch_row (mysql_res);
if ((Gbl.AttEvents.Lst[NumAttEvent].AttCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Error: wrong attendance event code.");
}
}
else
Gbl.AttEvents.Num = 0;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
Gbl.AttEvents.LstIsRead = true;
}
/*****************************************************************************/
/********* Get attendance event data using its code and check course *********/
/*****************************************************************************/
static void Att_GetDataOfAttEventByCodAndCheckCrs (struct AttendanceEvent *Att)
{
if (Att_GetDataOfAttEventByCod (Att))
{
2019-04-04 10:45:15 +02:00
if (Att->CrsCod != Gbl.Hierarchy.Crs.CrsCod)
2014-12-01 23:55:08 +01:00
Lay_ShowErrorAndExit ("Attendance event does not belong to current course.");
}
else // Attendance event not found
Lay_ShowErrorAndExit ("Error when getting attendance event.");
}
/*****************************************************************************/
/**************** Get attendance event data using its code *******************/
/*****************************************************************************/
// Returns true if attendance event exists
// This function can be called from web service, so do not display messages
bool Att_GetDataOfAttEventByCod (struct AttendanceEvent *Att)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-30 13:59:37 +01:00
unsigned long NumRows;
2016-12-29 23:33:01 +01:00
bool Found = false;
2014-12-01 23:55:08 +01:00
2016-12-29 23:07:30 +01:00
/***** Reset attendance event data *****/
Att_ResetAttendanceEvent (Att);
2016-12-29 23:33:01 +01:00
if (Att->AttCod > 0)
2014-12-01 23:55:08 +01:00
{
2016-12-29 23:33:01 +01:00
/***** Build query *****/
2018-10-30 13:59:37 +01:00
NumRows = DB_QuerySELECT (&mysql_res,"can not get attendance event data",
"SELECT AttCod,CrsCod,Hidden,UsrCod,"
"UNIX_TIMESTAMP(StartTime),"
"UNIX_TIMESTAMP(EndTime),"
"NOW() BETWEEN StartTime AND EndTime,"
"CommentTchVisible,"
"Title"
" FROM att_events"
" WHERE AttCod=%ld",
Att->AttCod);
2016-12-29 23:33:01 +01:00
/***** Get data of attendance event from database *****/
2018-10-30 13:59:37 +01:00
if ((Found = (NumRows != 0))) // Attendance event found...
2016-12-29 23:33:01 +01:00
{
/* Get row */
row = mysql_fetch_row (mysql_res);
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get code of the attendance event (row[0]) */
Att->AttCod = Str_ConvertStrCodToLongCod (row[0]);
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get code of the course (row[1]) */
Att->CrsCod = Str_ConvertStrCodToLongCod (row[1]);
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get whether the attendance event is hidden or not (row[2]) */
Att->Hidden = (row[2][0] == 'Y');
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get author of the attendance event (row[3]) */
Att->UsrCod = Str_ConvertStrCodToLongCod (row[3]);
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get start date (row[4] holds the start UTC time) */
Att->TimeUTC[Att_START_TIME] = Dat_GetUNIXTimeFromStr (row[4]);
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get end date (row[5] holds the end UTC time) */
Att->TimeUTC[Att_END_TIME ] = Dat_GetUNIXTimeFromStr (row[5]);
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get whether the attendance event is open or closed (row(6)) */
Att->Open = (row[6][0] == '1');
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get whether the attendance event is visible or not (row[7]) */
Att->CommentTchVisible = (row[7][0] == 'Y');
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/* Get the title of the attendance event (row[8]) */
2017-01-17 03:10:43 +01:00
Str_Copy (Att->Title,row[8],
2017-03-07 01:56:41 +01:00
Att_MAX_BYTES_ATTENDANCE_EVENT_TITLE);
2016-12-29 23:33:01 +01:00
}
2014-12-01 23:55:08 +01:00
2016-12-29 23:33:01 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
2014-12-01 23:55:08 +01:00
return Found;
}
2016-12-29 23:07:30 +01:00
/*****************************************************************************/
/********************** Clear all attendance event data **********************/
/*****************************************************************************/
static void Att_ResetAttendanceEvent (struct AttendanceEvent *Att)
{
2017-01-17 14:24:54 +01:00
if (Att->AttCod <= 0) // If > 0 ==> keep values of AttCod and Selected
{
2016-12-29 23:33:01 +01:00
Att->AttCod = -1L;
2017-01-17 14:52:13 +01:00
Att->NumStdsTotal = 0;
Att->NumStdsFromList = 0;
2017-01-17 14:24:54 +01:00
Att->Selected = false;
}
2016-12-29 23:07:30 +01:00
Att->CrsCod = -1L;
Att->Hidden = false;
Att->UsrCod = -1L;
Att->TimeUTC[Att_START_TIME] =
Att->TimeUTC[Att_END_TIME ] = (time_t) 0;
Att->Open = false;
Att->Title[0] = '\0';
Att->CommentTchVisible = false;
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************** Free list of attendance events ***********************/
/*****************************************************************************/
void Att_FreeListAttEvents (void)
{
if (Gbl.AttEvents.LstIsRead && Gbl.AttEvents.Lst)
{
/***** Free memory used by the list of attendance events *****/
free ((void *) Gbl.AttEvents.Lst);
Gbl.AttEvents.Lst = NULL;
Gbl.AttEvents.Num = 0;
Gbl.AttEvents.LstIsRead = false;
}
}
/*****************************************************************************/
/***************** Get attendance event text from database *******************/
/*****************************************************************************/
2019-02-15 21:09:18 +01:00
static void Att_GetAttEventDescriptionFromDB (long AttCod,char Description[Cns_MAX_BYTES_TEXT + 1])
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows;
/***** Get text of attendance event from database *****/
2018-10-30 13:59:37 +01:00
NumRows = DB_QuerySELECT (&mysql_res,"can not get attendance event text",
"SELECT Txt FROM att_events"
" WHERE AttCod=%ld AND CrsCod=%ld",
2019-04-04 10:45:15 +02:00
AttCod,Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
/***** The result of the query must have one row or none *****/
if (NumRows == 1)
{
2017-01-13 01:51:23 +01:00
/* Get row */
2014-12-01 23:55:08 +01:00
row = mysql_fetch_row (mysql_res);
2017-01-13 01:51:23 +01:00
/* Get info text */
2019-02-15 21:09:18 +01:00
Str_Copy (Description,row[0],
2017-01-17 03:10:43 +01:00
Cns_MAX_BYTES_TEXT);
2014-12-01 23:55:08 +01:00
}
else
2019-02-15 21:09:18 +01:00
Description[0] = '\0';
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
if (NumRows > 1)
Lay_ShowErrorAndExit ("Error when getting attendance event text.");
}
/*****************************************************************************/
/************** Write parameter with code of attendance event ****************/
/*****************************************************************************/
void Att_PutParamAttCod (long AttCod)
{
Par_PutHiddenParamLong ("AttCod",AttCod);
}
/*****************************************************************************/
/*************** Get parameter with code of attendance event *****************/
/*****************************************************************************/
long Att_GetParamAttCod (void)
{
2017-01-28 20:32:50 +01:00
/***** Get code of attendance event *****/
return Par_GetParToLong ("AttCod");
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Ask for confirmation of removing of an attendance event ***********/
/*****************************************************************************/
void Att_AskRemAttEvent (void)
{
extern const char *Txt_Do_you_really_want_to_remove_the_event_X;
extern const char *Txt_Remove_event;
struct AttendanceEvent Att;
/***** Get parameters *****/
2017-01-29 12:42:19 +01:00
Att_GetParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_GetParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Gbl.AttEvents.CurrentPage = Pag_GetParamPagNum (Pag_ATT_EVENTS);
2014-12-01 23:55:08 +01:00
/***** Get attendance event code *****/
if ((Att.AttCod = Att_GetParamAttCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of attendance event is missing.");
/***** Get data of the attendance event from database *****/
Att_GetDataOfAttEventByCodAndCheckCrs (&Att);
/***** Button of confirmation of removing *****/
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActRemAtt);
2014-12-01 23:55:08 +01:00
Att_PutParamAttCod (Att.AttCod);
2017-01-29 12:42:19 +01:00
Att_PutHiddenParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_PutParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Pag_PutHiddenParamPagNum (Pag_ATT_EVENTS,Gbl.AttEvents.CurrentPage);
2014-12-01 23:55:08 +01:00
2019-02-15 23:38:44 +01:00
/* Ask for confirmation of removing */
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_Do_you_really_want_to_remove_the_event_X,
2019-02-15 23:38:44 +01:00
Att.Title);
2017-06-11 19:02:40 +02:00
Btn_PutRemoveButton (Txt_Remove_event);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
/***** Show attendance events again *****/
Att_SeeAttEvents ();
}
/*****************************************************************************/
2016-09-06 18:29:13 +02:00
/** Get param., remove an attendance event and show attendance events again **/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-09-06 18:29:13 +02:00
void Att_GetAndRemAttEvent (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Event_X_removed;
struct AttendanceEvent Att;
/***** Get attendance event code *****/
if ((Att.AttCod = Att_GetParamAttCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of attendance event is missing.");
/***** Get data of the attendance event from database *****/
2016-09-06 18:29:13 +02:00
// Inside this function, the course is checked to be the current one
Att_GetDataOfAttEventByCodAndCheckCrs (&Att);
2014-12-01 23:55:08 +01:00
2016-09-06 18:29:13 +02:00
/***** Remove the attendance event from database *****/
Att_RemoveAttEventFromDB (Att.AttCod);
2014-12-01 23:55:08 +01:00
/***** Write message to show the change made *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Event_X_removed,
2019-02-15 23:38:44 +01:00
Att.Title);
2014-12-01 23:55:08 +01:00
/***** Show attendance events again *****/
Att_SeeAttEvents ();
}
2016-09-06 18:29:13 +02:00
/*****************************************************************************/
/**************** Remove an attendance event from database *******************/
/*****************************************************************************/
void Att_RemoveAttEventFromDB (long AttCod)
{
/***** Remove users registered in the attendance event *****/
Att_RemoveAllUsrsFromAnAttEvent (AttCod);
/***** Remove all the groups of this attendance event *****/
Att_RemoveAllTheGrpsAssociatedToAnAttEvent (AttCod);
/***** Remove attendance event *****/
Att_RemoveAttEventFromCurrentCrs (AttCod);
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************************* Hide an attendance event **************************/
/*****************************************************************************/
void Att_HideAttEvent (void)
{
extern const char *Txt_Event_X_is_now_hidden;
struct AttendanceEvent Att;
/***** Get attendance event code *****/
if ((Att.AttCod = Att_GetParamAttCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of attendance event is missing.");
/***** Get data of the attendance event from database *****/
Att_GetDataOfAttEventByCodAndCheckCrs (&Att);
/***** Hide attendance event *****/
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not hide attendance event",
"UPDATE att_events SET Hidden='Y'"
" WHERE AttCod=%ld AND CrsCod=%ld",
2019-04-04 10:45:15 +02:00
Att.AttCod,Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
/***** Write message to show the change made *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Event_X_is_now_hidden,
2019-02-15 23:38:44 +01:00
Att.Title);
2014-12-01 23:55:08 +01:00
/***** Show attendance events again *****/
Att_SeeAttEvents ();
}
/*****************************************************************************/
/************************* Show an attendance event **************************/
/*****************************************************************************/
void Att_ShowAttEvent (void)
{
extern const char *Txt_Event_X_is_now_visible;
struct AttendanceEvent Att;
/***** Get attendance event code *****/
if ((Att.AttCod = Att_GetParamAttCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of attendance event is missing.");
/***** Get data of the attendance event from database *****/
Att_GetDataOfAttEventByCodAndCheckCrs (&Att);
/***** Hide attendance event *****/
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not show attendance event",
"UPDATE att_events SET Hidden='N'"
" WHERE AttCod=%ld AND CrsCod=%ld",
2019-04-04 10:45:15 +02:00
Att.AttCod,Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
/***** Write message to show the change made *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Event_X_is_now_visible,
2019-02-15 23:38:44 +01:00
Att.Title);
2014-12-01 23:55:08 +01:00
/***** Show attendance events again *****/
Att_SeeAttEvents ();
}
/*****************************************************************************/
/***** Check if the title or the folder of an attendance event exists ********/
/*****************************************************************************/
static bool Att_CheckIfSimilarAttEventExists (const char *Field,const char *Value,long AttCod)
{
2018-11-03 13:13:11 +01:00
/***** 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",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod,
2018-11-03 13:13:11 +01:00
Field,Value,AttCod) != 0);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Put a form to create a new attendance event *****************/
/*****************************************************************************/
void Att_RequestCreatOrEditAttEvent (void)
{
2016-11-27 23:08:29 +01:00
extern const char *Hlp_USERS_Attendance_new_event;
extern const char *Hlp_USERS_Attendance_edit_event;
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormInBox[The_NUM_THEMES];
2014-12-01 23:55:08 +01:00
extern const char *Txt_New_event;
extern const char *Txt_Edit_event;
2014-12-04 01:19:42 +01:00
extern const char *Txt_Teachers_comment;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Title;
extern const char *Txt_Hidden_MALE_PLURAL;
extern const char *Txt_Visible_MALE_PLURAL;
extern const char *Txt_Description;
extern const char *Txt_Create_event;
2019-02-18 18:27:45 +01:00
extern const char *Txt_Save_changes;
2014-12-01 23:55:08 +01:00
struct AttendanceEvent Att;
bool ItsANewAttEvent;
2019-02-15 21:09:18 +01:00
char Description[Cns_MAX_BYTES_TEXT + 1];
2014-12-01 23:55:08 +01:00
/***** Get parameters *****/
2017-01-29 12:42:19 +01:00
Att_GetParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_GetParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Gbl.AttEvents.CurrentPage = Pag_GetParamPagNum (Pag_ATT_EVENTS);
2014-12-01 23:55:08 +01:00
/***** Get the code of the attendance event *****/
2016-12-29 23:07:30 +01:00
Att.AttCod = Att_GetParamAttCod ();
ItsANewAttEvent = (Att.AttCod <= 0);
2014-12-01 23:55:08 +01:00
/***** Get from the database the data of the attendance event *****/
if (ItsANewAttEvent)
{
2016-12-29 23:07:30 +01:00
/* Reset attendance event data */
2016-12-29 23:33:01 +01:00
Att.AttCod = -1L;
2016-12-29 23:07:30 +01:00
Att_ResetAttendanceEvent (&Att);
/* Initialize some fields */
2019-04-04 10:45:15 +02:00
Att.CrsCod = Gbl.Hierarchy.Crs.CrsCod;
2016-12-29 23:07:30 +01:00
Att.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
2015-10-27 19:00:21 +01:00
Att.TimeUTC[Att_START_TIME] = Gbl.StartExecutionTimeUTC;
Att.TimeUTC[Att_END_TIME ] = Gbl.StartExecutionTimeUTC + (2 * 60 * 60); // +2 hours
2014-12-01 23:55:08 +01:00
Att.Open = true;
}
else
{
/* Get data of the attendance event from database */
Att_GetDataOfAttEventByCodAndCheckCrs (&Att);
/* Get text of the attendance event from database */
2019-02-15 21:09:18 +01:00
Att_GetAttEventDescriptionFromDB (Att.AttCod,Description);
2014-12-01 23:55:08 +01:00
}
2015-04-11 17:33:14 +02:00
/***** Start form *****/
2014-12-01 23:55:08 +01:00
if (ItsANewAttEvent)
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActNewAtt);
2014-12-01 23:55:08 +01:00
else
{
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActChgAtt);
2014-12-01 23:55:08 +01:00
Att_PutParamAttCod (Att.AttCod);
}
2017-01-29 12:42:19 +01:00
Att_PutHiddenParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_PutParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Pag_PutHiddenParamPagNum (Pag_ATT_EVENTS,Gbl.AttEvents.CurrentPage);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2017-06-11 22:26:40 +02:00
if (ItsANewAttEvent)
Box_StartBoxTable (NULL,Txt_New_event,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Attendance_new_event,Box_NOT_CLOSABLE,2);
2017-06-11 22:26:40 +02:00
else
2017-10-01 00:48:36 +02:00
Box_StartBoxTable (NULL,
Att.Title[0] ? Att.Title :
Txt_Edit_event,
NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Attendance_edit_event,Box_NOT_CLOSABLE,2);
2014-12-01 23:55:08 +01:00
/***** Attendance event title *****/
fprintf (Gbl.F.Out,"<tr>"
2016-12-20 23:41:33 +01:00
"<td class=\"RIGHT_TOP\">"
"<label for=\"Title\" class=\"%s\">%s:</label>"
2014-12-22 14:08:19 +01:00
"</td>"
2015-07-28 00:51:32 +02:00
"<td class=\"LEFT_TOP\">"
2016-12-20 23:41:33 +01:00
"<input type=\"text\" id=\"Title\" name=\"Title\""
2016-11-19 14:58:40 +01:00
" size=\"45\" maxlength=\"%u\" value=\"%s\""
" required=\"required\" />"
2014-12-01 23:55:08 +01:00
"</td>"
"</tr>",
2019-02-22 21:47:50 +01:00
The_ClassFormInBox[Gbl.Prefs.Theme],Txt_Title,
2017-03-07 01:56:41 +01:00
Att_MAX_CHARS_ATTENDANCE_EVENT_TITLE,Att.Title);
2014-12-01 23:55:08 +01:00
2015-10-24 21:41:41 +02:00
/***** Assignment start and end dates *****/
2016-12-03 20:08:01 +01:00
Dat_PutFormStartEndClientLocalDateTimes (Att.TimeUTC,Dat_FORM_SECONDS_ON);
2014-12-01 23:55:08 +01:00
/***** Visibility of comments *****/
fprintf (Gbl.F.Out,"<tr>"
2016-12-20 23:41:33 +01:00
"<td class=\"RIGHT_TOP\">"
"<label for=\"ComTchVisible\" class=\"%s\">%s:</label>"
2014-12-22 14:08:19 +01:00
"</td>"
2015-07-28 00:51:32 +02:00
"<td class=\"LEFT_TOP\">"
2016-12-20 23:41:33 +01:00
"<select id=\"ComTchVisible\" name=\"ComTchVisible\">",
2019-02-22 21:47:50 +01:00
The_ClassFormInBox[Gbl.Prefs.Theme],Txt_Teachers_comment);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<option value=\"N\"");
if (!Att.CommentTchVisible)
fprintf (Gbl.F.Out," selected=\"selected\"");
fprintf (Gbl.F.Out,">%s</option>",
Txt_Hidden_MALE_PLURAL);
fprintf (Gbl.F.Out,"<option value=\"Y\"");
if (Att.CommentTchVisible)
fprintf (Gbl.F.Out," selected=\"selected\"");
fprintf (Gbl.F.Out,">%s</option>",
Txt_Visible_MALE_PLURAL);
fprintf (Gbl.F.Out,"</select>"
"</td>"
"</tr>");
/***** Attendance event description *****/
fprintf (Gbl.F.Out,"<tr>"
2016-12-20 23:41:33 +01:00
"<td class=\"RIGHT_TOP\">"
"<label for=\"Txt\" class=\"%s\">%s:</label>"
2014-12-22 14:08:19 +01:00
"</td>"
2015-07-28 00:51:32 +02:00
"<td class=\"LEFT_TOP\">"
2016-12-20 23:41:33 +01:00
"<textarea id=\"Txt\" name=\"Txt\""
" cols=\"60\" rows=\"5\">",
2019-02-22 21:47:50 +01:00
The_ClassFormInBox[Gbl.Prefs.Theme],Txt_Description);
2014-12-01 23:55:08 +01:00
if (!ItsANewAttEvent)
2019-02-15 21:09:18 +01:00
fprintf (Gbl.F.Out,"%s",Description);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</textarea>"
"</td>"
"</tr>");
/***** Groups *****/
Att_ShowLstGrpsToEditAttEvent (Att.AttCod);
2017-06-12 14:16:33 +02:00
/***** End table, send button and end box *****/
2015-03-24 17:47:26 +01:00
if (ItsANewAttEvent)
2017-06-11 19:02:40 +02:00
Box_EndBoxTableWithButton (Btn_CREATE_BUTTON,Txt_Create_event);
2015-03-24 17:47:26 +01:00
else
2019-02-18 18:27:45 +01:00
Box_EndBoxTableWithButton (Btn_CONFIRM_BUTTON,Txt_Save_changes);
2014-12-01 23:55:08 +01:00
2015-04-11 17:33:14 +02:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
/***** Show current attendance events *****/
2015-11-13 01:27:44 +01:00
Att_GetListAttEvents (Att_NEWEST_FIRST);
2016-03-20 00:33:27 +01:00
Att_ShowAllAttEvents ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Show list of groups to edit and attendance event **************/
/*****************************************************************************/
static void Att_ShowLstGrpsToEditAttEvent (long AttCod)
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormInBox[The_NUM_THEMES];
2014-12-01 23:55:08 +01:00
extern const char *Txt_Groups;
extern const char *Txt_The_whole_course;
unsigned NumGrpTyp;
/***** Get list of groups types and groups in this course *****/
Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.GrpTypes.Num)
2014-12-01 23:55:08 +01:00
{
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<tr>"
2015-09-05 19:19:39 +02:00
"<td class=\"%s RIGHT_TOP\">"
2014-12-22 14:08:19 +01:00
"%s:"
"</td>"
2015-07-28 00:51:32 +02:00
"<td class=\"LEFT_TOP\">",
2019-02-22 21:47:50 +01:00
The_ClassFormInBox[Gbl.Prefs.Theme],Txt_Groups);
2017-06-10 21:38:10 +02:00
Box_StartBoxTable ("100%",NULL,NULL,
2017-06-12 15:03:29 +02:00
NULL,Box_NOT_CLOSABLE,0);
2014-12-01 23:55:08 +01:00
/***** First row: checkbox to select the whole course *****/
fprintf (Gbl.F.Out,"<tr>"
2015-07-28 00:51:32 +02:00
"<td colspan=\"7\" class=\"DAT LEFT_MIDDLE\">"
2016-12-20 14:03:46 +01:00
"<label>"
2014-12-01 23:55:08 +01:00
"<input type=\"checkbox\" id=\"WholeCrs\" name=\"WholeCrs\" value=\"Y\"");
if (!Att_CheckIfAttEventIsAssociatedToGrps (AttCod))
fprintf (Gbl.F.Out," checked=\"checked\"");
2016-12-20 14:03:46 +01:00
fprintf (Gbl.F.Out," onclick=\"uncheckChildren(this,'GrpCods')\" />"
"%s %s"
"</label>"
"</td>"
2014-12-01 23:55:08 +01:00
"</tr>",
2019-04-04 10:45:15 +02:00
Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName);
2014-12-01 23:55:08 +01:00
/***** List the groups for each group type *****/
for (NumGrpTyp = 0;
2019-04-04 10:45:15 +02:00
NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num;
2014-12-01 23:55:08 +01:00
NumGrpTyp++)
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps)
Grp_ListGrpsToEditAsgAttSvyGam (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp],
2019-04-03 20:57:04 +02:00
AttCod,Grp_ATT_EVENT);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2017-06-10 21:38:10 +02:00
Box_EndBoxTable ();
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</td>"
"</tr>");
}
/***** Free list of groups types and groups in this course *****/
Grp_FreeListGrpTypesAndGrps ();
}
/*****************************************************************************/
/*************** Receive form to create a new attendance event ***************/
/*****************************************************************************/
void Att_RecFormAttEvent (void)
{
extern const char *Txt_Already_existed_an_event_with_the_title_X;
extern const char *Txt_You_must_specify_the_title_of_the_event;
extern const char *Txt_Created_new_event_X;
extern const char *Txt_The_event_has_been_modified;
2015-10-23 13:20:42 +02:00
struct AttendanceEvent OldAtt;
2016-09-07 18:02:25 +02:00
struct AttendanceEvent ReceivedAtt;
2014-12-01 23:55:08 +01:00
bool ItsANewAttEvent;
2016-09-07 18:02:25 +02:00
bool ReceivedAttEventIsCorrect = true;
2019-02-15 21:09:18 +01:00
char Description[Cns_MAX_BYTES_TEXT + 1];
2014-12-01 23:55:08 +01:00
/***** Get the code of the attendance event *****/
2016-09-07 18:02:25 +02:00
ItsANewAttEvent = ((ReceivedAtt.AttCod = Att_GetParamAttCod ()) == -1L);
2014-12-01 23:55:08 +01:00
if (!ItsANewAttEvent)
{
/* Get data of the old (current) attendance event from database */
2016-09-07 18:02:25 +02:00
OldAtt.AttCod = ReceivedAtt.AttCod;
2014-12-01 23:55:08 +01:00
Att_GetDataOfAttEventByCodAndCheckCrs (&OldAtt);
2016-09-19 22:03:58 +02:00
ReceivedAtt.Hidden = OldAtt.Hidden;
2014-12-01 23:55:08 +01:00
}
2015-10-23 13:20:42 +02:00
/***** Get start/end date-times *****/
2016-09-07 18:02:25 +02:00
ReceivedAtt.TimeUTC[Att_START_TIME] = Dat_GetTimeUTCFromForm ("StartTimeUTC");
ReceivedAtt.TimeUTC[Att_END_TIME ] = Dat_GetTimeUTCFromForm ("EndTimeUTC" );
2014-12-01 23:55:08 +01:00
/***** Get boolean parameter that indicates if teacher's comments are visible by students *****/
2017-01-28 20:32:50 +01:00
ReceivedAtt.CommentTchVisible = Par_GetParToBool ("ComTchVisible");
2014-12-01 23:55:08 +01:00
/***** Get attendance event title *****/
2017-03-07 01:56:41 +01:00
Par_GetParToText ("Title",ReceivedAtt.Title,Att_MAX_BYTES_ATTENDANCE_EVENT_TITLE);
2014-12-01 23:55:08 +01:00
2019-02-15 21:09:18 +01:00
/***** Get attendance event description *****/
Par_GetParToHTML ("Txt",Description,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous)
2014-12-01 23:55:08 +01:00
/***** Adjust dates *****/
2016-09-07 18:02:25 +02:00
if (ReceivedAtt.TimeUTC[Att_START_TIME] == 0)
ReceivedAtt.TimeUTC[Att_START_TIME] = Gbl.StartExecutionTimeUTC;
if (ReceivedAtt.TimeUTC[Att_END_TIME] == 0)
2017-01-28 15:58:46 +01:00
ReceivedAtt.TimeUTC[Att_END_TIME] = ReceivedAtt.TimeUTC[Att_START_TIME] + 2 * 60 * 60; // +2 hours // TODO: 2 * 60 * 60 should be in a #define in swad_config.h
2014-12-01 23:55:08 +01:00
/***** Check if title is correct *****/
2016-09-07 18:02:25 +02:00
if (ReceivedAtt.Title[0]) // If there's an attendance event title
2014-12-01 23:55:08 +01:00
{
/* If title of attendance event was in database... */
2016-09-07 18:02:25 +02:00
if (Att_CheckIfSimilarAttEventExists ("Title",ReceivedAtt.Title,ReceivedAtt.AttCod))
2014-12-01 23:55:08 +01:00
{
2016-09-07 18:02:25 +02:00
ReceivedAttEventIsCorrect = false;
2019-02-15 23:38:44 +01:00
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_Already_existed_an_event_with_the_title_X,
2019-02-15 23:38:44 +01:00
ReceivedAtt.Title);
2014-12-01 23:55:08 +01:00
}
}
else // If there is not an attendance event title
{
2016-09-07 18:02:25 +02:00
ReceivedAttEventIsCorrect = false;
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_must_specify_the_title_of_the_event);
2014-12-01 23:55:08 +01:00
}
/***** Create a new attendance event or update an existing one *****/
2016-09-07 18:02:25 +02:00
if (ReceivedAttEventIsCorrect)
2014-12-01 23:55:08 +01:00
{
/* Get groups for this attendance events */
2017-01-19 20:55:31 +01:00
Grp_GetParCodsSeveralGrps ();
2014-12-01 23:55:08 +01:00
if (ItsANewAttEvent)
{
2016-09-07 18:02:25 +02:00
ReceivedAtt.Hidden = false; // New attendance events are visible by default
2019-02-15 21:09:18 +01:00
Att_CreateAttEvent (&ReceivedAtt,Description); // Add new attendance event to database
2014-12-01 23:55:08 +01:00
/***** Write success message *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Created_new_event_X,
2019-02-15 23:38:44 +01:00
ReceivedAtt.Title);
2014-12-01 23:55:08 +01:00
}
else
{
2019-02-15 21:09:18 +01:00
Att_UpdateAttEvent (&ReceivedAtt,Description);
2014-12-01 23:55:08 +01:00
/***** Write success message *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_The_event_has_been_modified);
2014-12-01 23:55:08 +01:00
}
/* Free memory for list of selected groups */
Grp_FreeListCodSelectedGrps ();
}
else
Att_RequestCreatOrEditAttEvent ();
/***** Show attendance events again *****/
Att_SeeAttEvents ();
}
/*****************************************************************************/
/********************* Create a new attendance event *************************/
/*****************************************************************************/
2019-02-15 21:09:18 +01:00
void Att_CreateAttEvent (struct AttendanceEvent *Att,const char *Description)
2014-12-01 23:55:08 +01:00
{
/***** Create a new attendance event *****/
2018-11-03 01:45:36 +01:00
Att->AttCod =
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')",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod,
2018-11-03 01:45:36 +01:00
Att->Hidden ? 'Y' :
'N',
Gbl.Usrs.Me.UsrDat.UsrCod,
Att->TimeUTC[Att_START_TIME],
Att->TimeUTC[Att_END_TIME ],
Att->CommentTchVisible ? 'Y' :
'N',
Att->Title,
2019-02-15 21:09:18 +01:00
Description);
2014-12-01 23:55:08 +01:00
/***** Create groups *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
2014-12-01 23:55:08 +01:00
Att_CreateGrps (Att->AttCod);
}
/*****************************************************************************/
/****************** Update an existing attendance event **********************/
/*****************************************************************************/
2019-02-15 21:09:18 +01:00
void Att_UpdateAttEvent (struct AttendanceEvent *Att,const char *Description)
2014-12-01 23:55:08 +01:00
{
/***** Update the data of the attendance event *****/
2018-11-03 12:16:40 +01:00
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",
Att->Hidden ? 'Y' :
'N',
Att->TimeUTC[Att_START_TIME],
Att->TimeUTC[Att_END_TIME ],
Att->CommentTchVisible ? 'Y' :
'N',
Att->Title,
2019-02-15 21:09:18 +01:00
Description,
2019-04-04 10:45:15 +02:00
Att->AttCod,Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
/***** Update groups *****/
/* Remove old groups */
Att_RemoveAllTheGrpsAssociatedToAnAttEvent (Att->AttCod);
/* Create new groups */
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
2014-12-01 23:55:08 +01:00
Att_CreateGrps (Att->AttCod);
}
/*****************************************************************************/
/******** Check if an attendance event is associated to any group ************/
/*****************************************************************************/
bool Att_CheckIfAttEventIsAssociatedToGrps (long AttCod)
{
/***** Get if an attendance event is associated to a group from database *****/
2018-11-03 13:13:11 +01:00
return (DB_QueryCOUNT ("can not check if an attendance event"
" is associated to groups",
"SELECT COUNT(*) FROM att_grp WHERE AttCod=%ld",
AttCod) != 0);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Check if an attendance event is associated to a group *************/
/*****************************************************************************/
bool Att_CheckIfAttEventIsAssociatedToGrp (long AttCod,long GrpCod)
{
/***** Get if an attendance event is associated to a group from database *****/
2018-11-03 13:13:11 +01:00
return (DB_QueryCOUNT ("can not check if an attendance event"
" is associated to a group",
"SELECT COUNT(*) FROM att_grp"
" WHERE AttCod=%ld AND GrpCod=%ld",
AttCod,GrpCod) != 0);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****************** Remove groups of an attendance event *********************/
/*****************************************************************************/
static void Att_RemoveAllTheGrpsAssociatedToAnAttEvent (long AttCod)
{
/***** Remove groups of the attendance event *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove the groups"
" associated to an attendance event",
"DELETE FROM att_grp WHERE AttCod=%ld",
AttCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Remove one group from all the attendance events ***************/
/*****************************************************************************/
void Att_RemoveGroup (long GrpCod)
{
/***** Remove group from all the attendance events *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove group from the associations"
" between attendance events and groups",
"DELETE FROM att_grp WHERE GrpCod=%ld",
GrpCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******** Remove groups of one type from all the attendance events ***********/
/*****************************************************************************/
void Att_RemoveGroupsOfType (long GrpTypCod)
{
/***** Remove group from all the attendance events *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove groups of a type from the associations"
" between attendance events and groups",
"DELETE FROM att_grp USING crs_grp,att_grp"
" WHERE crs_grp.GrpTypCod=%ld"
" AND crs_grp.GrpCod=att_grp.GrpCod",
GrpTypCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************** Create groups of an attendance event **********************/
/*****************************************************************************/
static void Att_CreateGrps (long AttCod)
{
unsigned NumGrpSel;
/***** Create groups of the attendance event *****/
for (NumGrpSel = 0;
2019-04-04 10:45:15 +02:00
NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps;
2014-12-01 23:55:08 +01:00
NumGrpSel++)
/* Create group */
2018-11-02 19:37:11 +01:00
DB_QueryINSERT ("can not associate a group to an attendance event",
"INSERT INTO att_grp"
" (AttCod,GrpCod)"
" VALUES"
" (%ld,%ld)",
AttCod,
2019-04-04 10:45:15 +02:00
Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****** Get and write the names of the groups of an attendance event *********/
/*****************************************************************************/
static void Att_GetAndWriteNamesOfGrpsAssociatedToAttEvent (struct AttendanceEvent *Att)
{
extern const char *Txt_Group;
extern const char *Txt_Groups;
extern const char *Txt_and;
extern const char *Txt_The_whole_course;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumGrp;
unsigned NumGrps;
/***** Get groups associated to an attendance event from database *****/
2018-10-30 13:59:37 +01:00
NumGrps = (unsigned) DB_QuerySELECT (&mysql_res,"can not get groups of an attendance event",
2019-01-07 21:52:19 +01:00
"SELECT crs_grp_types.GrpTypName,"
"crs_grp.GrpName,"
"classrooms.ShortName"
" FROM (att_grp,crs_grp,crs_grp_types)"
" LEFT JOIN classrooms"
" ON crs_grp.ClaCod=classrooms.ClaCod"
2018-10-30 13:59:37 +01:00
" WHERE att_grp.AttCod=%ld"
" AND att_grp.GrpCod=crs_grp.GrpCod"
" AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod"
" ORDER BY crs_grp_types.GrpTypName,crs_grp.GrpName",
Att->AttCod);
2014-12-01 23:55:08 +01:00
/***** Write heading *****/
2015-04-11 17:33:14 +02:00
fprintf (Gbl.F.Out,"<div class=\"%s\">%s: ",
2014-12-01 23:55:08 +01:00
Att->Hidden ? "ASG_GRP_LIGHT" :
"ASG_GRP",
(NumGrps == 1) ? Txt_Group :
Txt_Groups);
/***** Write groups *****/
if (NumGrps) // Groups found...
{
/* Get and write the group types and names */
for (NumGrp = 0;
NumGrp < NumGrps;
NumGrp++)
{
/* Get next group */
row = mysql_fetch_row (mysql_res);
2019-01-07 21:52:19 +01:00
/* Write group type name (row[0]) and group name (row[1]) */
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"%s %s",row[0],row[1]);
2019-01-07 21:52:19 +01:00
/* Write the name of the classroom (row[2]) */
if (row[2]) // May be NULL because of LEFT JOIN
if (row[2][0])
fprintf (Gbl.F.Out," (%s)",row[2]);
/* Write separator */
2014-12-01 23:55:08 +01:00
if (NumGrps >= 2)
{
2019-01-07 21:52:19 +01:00
if (NumGrp == NumGrps - 2)
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out," %s ",Txt_and);
if (NumGrps >= 3)
2019-01-07 21:52:19 +01:00
if (NumGrp < NumGrps - 2)
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,", ");
}
}
}
else
fprintf (Gbl.F.Out,"%s %s",
2019-04-04 10:45:15 +02:00
Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName);
2014-12-01 23:55:08 +01:00
2015-04-11 17:33:14 +02:00
fprintf (Gbl.F.Out,"</div>");
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
2016-09-06 18:29:13 +02:00
/*****************************************************************************/
/*********** Remove all users registered in an attendance event **************/
/*****************************************************************************/
static void Att_RemoveAllUsrsFromAnAttEvent (long AttCod)
{
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove attendance event",
"DELETE FROM att_usr WHERE AttCod=%ld",
AttCod);
2016-09-06 18:29:13 +02:00
}
/*****************************************************************************/
/* Remove one user from all the attendance events where he/she is registered */
/*****************************************************************************/
void Att_RemoveUsrFromAllAttEvents (long UsrCod)
{
/***** Remove group from all the attendance events *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove user from all attendance events",
"DELETE FROM att_usr WHERE UsrCod=%ld",
UsrCod);
2016-09-06 18:29:13 +02:00
}
/*****************************************************************************/
/*********** Remove one student from all the attendance events ***************/
/*****************************************************************************/
void Att_RemoveUsrFromCrsAttEvents (long UsrCod,long CrsCod)
{
/***** Remove group from all the attendance events *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove user from attendance events of a course",
"DELETE FROM att_usr USING att_events,att_usr"
" WHERE att_events.CrsCod=%ld"
" AND att_events.AttCod=att_usr.AttCod"
" AND att_usr.UsrCod=%ld",
CrsCod,UsrCod);
2016-09-06 18:29:13 +02:00
}
/*****************************************************************************/
/*********************** Remove an attendance event **************************/
/*****************************************************************************/
static void Att_RemoveAttEventFromCurrentCrs (long AttCod)
{
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove attendance event",
"DELETE FROM att_events"
" WHERE AttCod=%ld AND CrsCod=%ld",
2019-04-04 10:45:15 +02:00
AttCod,Gbl.Hierarchy.Crs.CrsCod);
2016-09-06 18:29:13 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*************** Remove all the attendance events of a course ****************/
/*****************************************************************************/
void Att_RemoveCrsAttEvents (long CrsCod)
{
/***** Remove students *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove all the students registered"
" in events of a course",
"DELETE FROM att_usr USING att_events,att_usr"
" WHERE att_events.CrsCod=%ld"
" AND att_events.AttCod=att_usr.AttCod",
CrsCod);
2014-12-01 23:55:08 +01:00
/***** Remove groups *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove all the groups associated"
" to attendance events of a course",
"DELETE FROM att_grp USING att_events,att_grp"
" WHERE att_events.CrsCod=%ld"
" AND att_events.AttCod=att_grp.AttCod",
CrsCod);
2014-12-01 23:55:08 +01:00
/***** Remove attendance events *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove all the attendance events of a course",
"DELETE FROM att_events WHERE CrsCod=%ld",
CrsCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Get number of attendance events in a course *****************/
/*****************************************************************************/
unsigned Att_GetNumAttEventsInCrs (long CrsCod)
{
/***** Get number of attendance events in a course from database *****/
2018-11-03 13:13:11 +01:00
return
(unsigned) DB_QueryCOUNT ("can not get number of attendance events"
" in course",
"SELECT COUNT(*) FROM att_events"
" WHERE CrsCod=%ld",
CrsCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** 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)
2019-04-03 20:57:04 +02:00
unsigned Att_GetNumCoursesWithAttEvents (Hie_Level_t Scope)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumCourses;
/***** Get number of courses with attendance events from database *****/
switch (Scope)
{
2019-04-03 20:57:04 +02:00
case Hie_SYS:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT CrsCod)"
" FROM att_events"
" WHERE CrsCod>0");
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_INS:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM centres,degrees,courses,att_events"
" WHERE centres.InsCod=%ld"
" AND centres.CtrCod=degrees.CtrCod"
" AND degrees.DegCod=courses.DegCod"
" AND courses.Status=0"
" AND courses.CrsCod=att_events.CrsCod",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Ins.InsCod);
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_CTR:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM degrees,courses,att_events"
" WHERE degrees.CtrCod=%ld"
" AND degrees.DegCod=courses.DegCod"
" AND courses.Status=0"
" AND courses.CrsCod=att_events.CrsCod",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Ctr.CtrCod);
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_DEG:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT att_events.CrsCod)"
" FROM courses,att_events"
" WHERE courses.DegCod=%ld"
" AND courses.Status=0"
" AND courses.CrsCod=att_events.CrsCod",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Deg.DegCod);
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_CRS:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of courses with attendance events",
"SELECT COUNT(DISTINCT CrsCod)"
" FROM att_events"
" WHERE CrsCod=%ld",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
break;
default:
2018-10-24 23:03:11 +02:00
Lay_WrongScopeExit ();
2014-12-01 23:55:08 +01:00
break;
}
/***** Get number of courses *****/
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&NumCourses) != 1)
Lay_ShowErrorAndExit ("Error when getting number of courses with attendance events.");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return NumCourses;
}
/*****************************************************************************/
/********************* Get number of attendance events ***********************/
/*****************************************************************************/
// Returns the number of attendance events
// in this location (all the platform, current degree or current course)
2019-04-03 20:57:04 +02:00
unsigned Att_GetNumAttEvents (Hie_Level_t Scope,unsigned *NumNotif)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumAttEvents;
/***** Get number of attendance events from database *****/
switch (Scope)
{
2019-04-03 20:57:04 +02:00
case Hie_SYS:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*),SUM(NumNotif)"
" FROM att_events"
" WHERE CrsCod>0");
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_INS:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*),SUM(att_events.NumNotif)"
" FROM centres,degrees,courses,att_events"
" WHERE centres.InsCod=%ld"
" AND centres.CtrCod=degrees.CtrCod"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=att_events.CrsCod",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Ins.InsCod);
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_CTR:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*),SUM(att_events.NumNotif)"
" FROM degrees,courses,att_events"
" WHERE degrees.CtrCod=%ld"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=att_events.CrsCod",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Ctr.CtrCod);
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_DEG:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*),SUM(att_events.NumNotif)"
" FROM courses,att_events"
" WHERE courses.DegCod=%ld"
" AND courses.CrsCod=att_events.CrsCod",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Deg.DegCod);
2014-12-01 23:55:08 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_CRS:
2018-10-30 13:59:37 +01:00
DB_QuerySELECT (&mysql_res,"can not get number of attendance events",
"SELECT COUNT(*),SUM(NumNotif)"
" FROM att_events"
" WHERE CrsCod=%ld",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
break;
default:
2018-10-24 23:03:11 +02:00
Lay_WrongScopeExit ();
2014-12-01 23:55:08 +01:00
break;
}
/***** Get number of attendance events *****/
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&NumAttEvents) != 1)
Lay_ShowErrorAndExit ("Error when getting number of attendance events.");
2016-11-16 23:19:52 +01:00
/***** Get number of notifications by email *****/
2014-12-01 23:55:08 +01:00
if (row[1])
{
if (sscanf (row[1],"%u",NumNotif) != 1)
Lay_ShowErrorAndExit ("Error when getting number of notifications of attendance events.");
}
else
*NumNotif = 0;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return NumAttEvents;
}
/*****************************************************************************/
/************************ Show one attendance event **************************/
/*****************************************************************************/
void Att_SeeOneAttEvent (void)
{
2016-11-13 21:08:14 +01:00
extern const char *Hlp_USERS_Attendance;
2015-04-11 17:33:14 +02:00
extern const char *Txt_Event;
2014-12-01 23:55:08 +01:00
struct AttendanceEvent Att;
/***** Get attendance event code *****/
if (Gbl.AttEvents.AttCod <= 0)
if ((Gbl.AttEvents.AttCod = Att_GetParamAttCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of attendance event is missing.");
/***** Get parameters *****/
2017-01-29 12:42:19 +01:00
Att_GetParamAttOrder ();
2014-12-01 23:55:08 +01:00
Grp_GetParamWhichGrps ();
2017-04-13 20:09:22 +02:00
Gbl.AttEvents.CurrentPage = Pag_GetParamPagNum (Pag_ATT_EVENTS);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2017-06-10 21:38:10 +02:00
Box_StartBoxTable (NULL,Txt_Event,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Attendance,Box_NOT_CLOSABLE,2);
2017-06-12 14:16:33 +02:00
2014-12-01 23:55:08 +01:00
Att.AttCod = Gbl.AttEvents.AttCod;
Att_ShowOneAttEvent (&Att,true);
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2017-06-10 21:38:10 +02:00
Box_EndBoxTable ();
2014-12-01 23:55:08 +01:00
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2014-12-01 23:55:08 +01:00
{
2017-05-18 19:13:41 +02:00
case Rol_STD:
2014-12-01 23:55:08 +01:00
Att_ListAttOnlyMeAsStudent (&Att);
break;
2017-05-21 21:23:13 +02:00
case Rol_NET:
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2015-04-07 21:44:24 +02:00
case Rol_SYS_ADM:
2014-12-01 23:55:08 +01:00
/***** Show list of students *****/
Att_ListAttStudents (&Att);
break;
default:
break;
}
}
/*****************************************************************************/
/*********************** List me as student in one event *********************/
/*****************************************************************************/
// Att must be filled before calling this function
static void Att_ListAttOnlyMeAsStudent (struct AttendanceEvent *Att)
{
2016-11-13 21:08:14 +01:00
extern const char *Hlp_USERS_Attendance;
2019-02-18 18:27:45 +01:00
extern const char *Txt_Attendance;
2014-12-04 01:19:42 +01:00
extern const char *Txt_Student_comment;
extern const char *Txt_Teachers_comment;
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2019-02-18 18:27:45 +01:00
extern const char *Txt_Save_changes;
2014-12-01 23:55:08 +01:00
2019-03-26 11:53:21 +01:00
/***** Get my setting about photos in users' list for current course *****/
2014-12-01 23:55:08 +01:00
Usr_GetMyPrefAboutListWithPhotosFromDB ();
2015-04-11 17:33:14 +02:00
/***** Start form *****/
2014-12-01 23:55:08 +01:00
if (Att->Open)
{
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActRecAttMe);
2014-12-01 23:55:08 +01:00
Att_PutParamAttCod (Att->AttCod);
}
2019-02-18 18:27:45 +01:00
/***** List students (only me) *****/
/* Start box */
Box_StartBox (NULL,Txt_Attendance,NULL,
Hlp_USERS_Attendance,Box_NOT_CLOSABLE);
/* Start table */
Tbl_StartTableWideMargin (2);
/* Header */
2016-11-14 10:05:41 +01:00
fprintf (Gbl.F.Out,"<tr>"
2014-12-26 22:11:03 +01:00
"<th></th>"
"<th></th>"
"<th></th>");
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Listing.WithPhotos)
2015-09-28 18:28:29 +02:00
fprintf (Gbl.F.Out,"<th style=\"width:22px;\"></th>");
2015-07-28 00:51:32 +02:00
fprintf (Gbl.F.Out,"<th colspan=\"2\" class=\"TIT_TBL LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2015-09-06 20:02:14 +02:00
"<th class=\"LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2015-09-06 20:02:14 +02:00
"<th class=\"LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2014-12-01 23:55:08 +01:00
"</tr>",
2017-05-18 19:13:41 +02:00
Txt_ROLES_SINGUL_Abc[Rol_STD][Usr_SEX_UNKNOWN],
2014-12-04 01:19:42 +01:00
Txt_Student_comment,
Txt_Teachers_comment);
2014-12-01 23:55:08 +01:00
/* List of students (only me) */
Att_WriteRowStdToCallTheRoll (1,&Gbl.Usrs.Me.UsrDat,Att);
2019-02-18 18:27:45 +01:00
/* End table */
Tbl_EndTable ();
2014-12-01 23:55:08 +01:00
2019-02-18 18:27:45 +01:00
/* Send button */
2014-12-01 23:55:08 +01:00
if (Att->Open)
{
2019-02-18 18:27:45 +01:00
Btn_PutConfirmButton (Txt_Save_changes);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
}
2019-02-18 18:27:45 +01:00
/* End box */
Box_EndBox ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** List students who attended to one event *********************/
/*****************************************************************************/
// Att must be filled before calling this function
static void Att_ListAttStudents (struct AttendanceEvent *Att)
{
2016-11-13 21:08:14 +01:00
extern const char *Hlp_USERS_Attendance;
2015-04-11 17:33:14 +02:00
extern const char *Txt_Attendance;
2014-12-04 01:19:42 +01:00
extern const char *Txt_Student_comment;
extern const char *Txt_Teachers_comment;
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2019-02-18 18:27:45 +01:00
extern const char *Txt_Save_changes;
2014-12-01 23:55:08 +01:00
unsigned NumStd;
struct UsrData UsrDat;
2016-11-25 03:21:02 +01:00
/***** Get groups to show ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2014-12-01 23:55:08 +01:00
/***** Get and order list of students in this course *****/
2019-04-03 20:57:04 +02:00
Usr_GetListUsrs (Hie_CRS,Rol_STD);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** Start box *****/
2017-06-10 21:38:10 +02:00
Box_StartBox (NULL,Txt_Attendance,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Attendance,Box_NOT_CLOSABLE);
2016-11-25 03:21:02 +01:00
/***** Form to select groups *****/
2017-07-02 18:53:35 +02:00
Grp_ShowFormToSelectSeveralGroups (ActSeeOneAtt,Grp_ONLY_MY_GROUPS);
2017-05-25 11:04:38 +02:00
/***** Start section with user list *****/
2017-05-25 13:43:54 +02:00
Lay_StartSection (Usr_USER_LIST_SECTION_ID);
2016-11-25 03:21:02 +01:00
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Get my preference about photos in users' list for current course *****/
Usr_GetMyPrefAboutListWithPhotosFromDB ();
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2019-02-18 18:27:45 +01:00
/* Start form */
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActRecAttStd);
2014-12-01 23:55:08 +01:00
Att_PutParamAttCod (Att->AttCod);
Grp_PutParamsCodGrps ();
2019-02-18 18:27:45 +01:00
/* Start table */
2017-06-11 20:09:59 +02:00
Tbl_StartTableWideMargin (2);
2017-05-01 12:36:24 +02:00
2019-02-18 18:27:45 +01:00
/* Header */
2017-05-01 12:36:24 +02:00
fprintf (Gbl.F.Out,"<tr>"
2014-12-26 22:11:03 +01:00
"<th></th>"
"<th></th>"
"<th></th>");
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Listing.WithPhotos)
2015-09-28 18:28:29 +02:00
fprintf (Gbl.F.Out,"<th style=\"width:22px;\"></th>");
2015-09-06 20:02:14 +02:00
fprintf (Gbl.F.Out,"<th colspan=\"2\" class=\"LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2015-09-06 20:02:14 +02:00
"<th class=\"LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2015-09-06 20:02:14 +02:00
"<th class=\"LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2014-12-01 23:55:08 +01:00
"</tr>",
2017-05-18 19:13:41 +02:00
Txt_ROLES_SINGUL_Abc[Rol_STD][Usr_SEX_UNKNOWN],
2014-12-04 01:19:42 +01:00
Txt_Student_comment,
Txt_Teachers_comment);
2014-12-01 23:55:08 +01:00
/* List of students */
2014-12-07 02:04:30 +01:00
for (NumStd = 0, Gbl.RowEvenOdd = 0;
2017-05-18 19:13:41 +02:00
NumStd < Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs;
2014-12-01 23:55:08 +01:00
NumStd++)
{
2016-07-26 02:41:31 +02:00
/* Copy user's basic data from list */
2017-05-18 19:13:41 +02:00
Usr_CopyBasicUsrDataFromList (&UsrDat,&Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd]);
2016-07-26 02:41:31 +02:00
/* Get list of user's IDs */
ID_GetListIDsFromUsrCod (&UsrDat);
Att_WriteRowStdToCallTheRoll (NumStd + 1,&UsrDat,Att);
2014-12-01 23:55:08 +01:00
}
2019-02-18 18:27:45 +01:00
/* End table */
2017-06-11 20:09:59 +02:00
Tbl_EndTable ();
2016-11-25 03:21:02 +01:00
/* Send button */
2019-02-18 18:27:45 +01:00
Btn_PutConfirmButton (Txt_Save_changes);
2014-12-01 23:55:08 +01:00
2015-04-11 17:33:14 +02:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
2017-05-29 21:34:43 +02:00
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0
/***** Show warning indicating no students found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_STD);
2014-12-01 23:55:08 +01:00
2017-05-25 11:04:38 +02:00
/***** End section with user list *****/
2017-05-25 13:43:54 +02:00
Lay_EndSection ();
2017-05-25 11:04:38 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2017-06-10 21:38:10 +02:00
Box_EndBox ();
2016-11-25 03:21:02 +01:00
2014-12-01 23:55:08 +01:00
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
}
/*****************************************************************************/
/************ Write a row of a table with the data of a student **************/
/*****************************************************************************/
2017-05-20 12:04:12 +02:00
static void Att_WriteRowStdToCallTheRoll (unsigned NumStd,
struct UsrData *UsrDat,
struct AttendanceEvent *Att)
2014-12-01 23:55:08 +01:00
{
bool Present;
2017-01-28 15:58:46 +01:00
char PhotoURL[PATH_MAX + 1];
2014-12-01 23:55:08 +01:00
bool ShowPhoto;
2017-01-28 15:58:46 +01:00
char CommentStd[Cns_MAX_BYTES_TEXT + 1];
char CommentTch[Cns_MAX_BYTES_TEXT + 1];
2018-10-10 23:56:42 +02:00
bool ItsMe;
2017-05-20 12:04:12 +02:00
bool ICanChangeStdAttendance;
bool ICanEditStdComment;
bool ICanEditTchComment;
/***** Set who can edit *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2017-05-20 12:04:12 +02:00
{
case Rol_STD:
// A student can see only her/his attendance
2018-10-10 23:56:42 +02:00
ItsMe = Usr_ItsMe (UsrDat->UsrCod);
if (!ItsMe)
2017-05-20 12:04:12 +02:00
Lay_ShowErrorAndExit ("Wrong call.");
ICanChangeStdAttendance = false;
ICanEditStdComment = Att->Open; // Attendance event is open
ICanEditTchComment = false;
break;
case Rol_TCH:
ICanChangeStdAttendance = true;
ICanEditStdComment = false;
ICanEditTchComment = true;
break;
case Rol_SYS_ADM:
ICanChangeStdAttendance = true;
ICanEditStdComment = false;
ICanEditTchComment = false;
break;
default:
ICanChangeStdAttendance = false;
ICanEditStdComment = false;
ICanEditTchComment = false;
break;
}
2014-12-01 23:55:08 +01:00
2019-02-13 21:24:54 +01:00
/***** Check if this student is already present in the current event *****/
2014-12-01 23:55:08 +01:00
Present = Att_CheckIfUsrIsPresentInAttEventAndGetComments (Att->AttCod,UsrDat->UsrCod,CommentStd,CommentTch);
2019-02-13 21:24:54 +01:00
/***** Icon to show if the user is already present *****/
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<tr>"
2016-07-25 20:24:07 +02:00
"<td class=\"BT%u\">"
2019-02-13 21:24:54 +01:00
"<label for=\"Std%u\">",
Gbl.RowEvenOdd,NumStd);
Att_PutCheckOrCross (Present);
fprintf (Gbl.F.Out,"</label>"
"</td>");
2014-12-01 23:55:08 +01:00
/***** Checkbox to select user *****/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"CENTER_TOP COLOR%u\">"
2016-12-21 00:06:11 +01:00
"<input type=\"checkbox\" id=\"Std%u\" name=\"UsrCodStd\""
" value=\"%s\"",
Gbl.RowEvenOdd,NumStd,
2015-09-03 00:59:03 +02:00
UsrDat->EncryptedUsrCod);
2014-12-01 23:55:08 +01:00
if (Present) // This student has attended to the event?
fprintf (Gbl.F.Out," checked=\"checked\"");
2017-05-20 12:04:12 +02:00
if (!ICanChangeStdAttendance)
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out," disabled=\"disabled\"");
2014-12-22 14:08:19 +01:00
fprintf (Gbl.F.Out," />"
"</td>");
2014-12-01 23:55:08 +01:00
/***** Write number of student in the list *****/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"%s RIGHT_TOP COLOR%u\">"
2014-12-22 14:08:19 +01:00
"%u"
"</td>",
2019-02-14 00:33:51 +01:00
UsrDat->Accepted ? "DAT_N" :
"DAT",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2014-12-01 23:55:08 +01:00
NumStd);
/***** Show student's photo *****/
if (Gbl.Usrs.Listing.WithPhotos)
{
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
Gbl.RowEvenOdd);
2017-01-28 15:58:46 +01:00
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (UsrDat,PhotoURL);
2014-12-30 15:14:43 +01:00
Pho_ShowUsrPhoto (UsrDat,ShowPhoto ? PhotoURL :
NULL,
2016-01-14 10:31:09 +01:00
"PHOTO45x60",Pho_ZOOM,false);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</td>");
}
/***** Write user's ID ******/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"%s LEFT_TOP COLOR%u\">",
2014-12-01 23:55:08 +01:00
UsrDat->Accepted ? "DAT_SMALL_N" :
2014-12-22 14:08:19 +01:00
"DAT_SMALL",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd);
2017-05-09 20:56:02 +02:00
ID_WriteUsrIDs (UsrDat,NULL);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</td>");
/***** Write student's name *****/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"%s LEFT_TOP COLOR%u\">%s",
2014-12-01 23:55:08 +01:00
UsrDat->Accepted ? "DAT_SMALL_N" :
"DAT_SMALL",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2014-12-01 23:55:08 +01:00
UsrDat->Surname1);
if (UsrDat->Surname2[0])
fprintf (Gbl.F.Out," %s",UsrDat->Surname2);
fprintf (Gbl.F.Out,", %s</td>",
UsrDat->FirstName);
/***** Student's comment: write form or text */
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"DAT_SMALL LEFT_TOP COLOR%u\">",
Gbl.RowEvenOdd);
2017-05-20 12:04:12 +02:00
if (ICanEditStdComment) // Show with form
2016-12-26 18:35:52 +01:00
fprintf (Gbl.F.Out,"<textarea name=\"CommentStd%ld\""
" cols=\"40\" rows=\"3\">"
"%s"
"</textarea>",
2014-12-01 23:55:08 +01:00
UsrDat->UsrCod,CommentStd);
2017-05-20 12:04:12 +02:00
else // Show without form
2014-12-01 23:55:08 +01:00
{
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
CommentStd,Cns_MAX_BYTES_TEXT,false);
fprintf (Gbl.F.Out,"%s",CommentStd);
}
fprintf (Gbl.F.Out,"</td>");
/***** Teacher's comment: write form, text or nothing */
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"DAT_SMALL LEFT_TOP COLOR%u\">",
Gbl.RowEvenOdd);
2017-05-20 12:04:12 +02:00
if (ICanEditTchComment) // Show with form
2016-12-26 18:35:52 +01:00
fprintf (Gbl.F.Out,"<textarea name=\"CommentTch%ld\""
" cols=\"40\" rows=\"3\">"
"%s"
"</textarea>",
2014-12-01 23:55:08 +01:00
UsrDat->UsrCod,CommentTch);
2017-05-20 12:04:12 +02:00
else if (Att->CommentTchVisible) // Show without form
2014-12-01 23:55:08 +01:00
{
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
CommentTch,Cns_MAX_BYTES_TEXT,false);
fprintf (Gbl.F.Out,"%s",CommentTch);
}
fprintf (Gbl.F.Out,"</td>"
"</tr>");
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
}
2018-12-03 19:49:54 +01:00
/*****************************************************************************/
/**************** Put link to view one attendance event **********************/
/*****************************************************************************/
static void Att_PutLinkAttEvent (struct AttendanceEvent *AttEvent,
const char *Title,const char *Txt,
const char *LinkStyle)
{
Frm_StartForm (ActSeeOneAtt);
Att_PutParamAttCod (AttEvent->AttCod);
Att_PutParamsCodGrps (AttEvent->AttCod);
Frm_LinkFormSubmit (Title,LinkStyle,NULL);
fprintf (Gbl.F.Out,"%s</a>",Txt);
Frm_EndForm ();
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/****** Put parameters with the default groups in an attendance event ********/
/*****************************************************************************/
static void Att_PutParamsCodGrps (long AttCod)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumGrp;
unsigned NumGrps;
/***** Get groups associated to an attendance event from database *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps)
2018-10-30 13:59:37 +01:00
NumGrps = (unsigned) DB_QuerySELECT (&mysql_res,"can not get groups of an attendance event",
"SELECT GrpCod FROM att_grp"
" WHERE att_grp.AttCod=%ld",
AttCod);
2014-12-01 23:55:08 +01:00
else
NumGrps = 0;
/***** Get groups *****/
if (NumGrps) // Groups found...
{
fprintf (Gbl.F.Out,"<input type=\"hidden\" name=\"GrpCods\" value=\"");
2014-12-08 01:30:47 +01:00
/* Get groups */
2014-12-01 23:55:08 +01:00
for (NumGrp = 0;
NumGrp < NumGrps;
NumGrp++)
{
/* Get next group */
row = mysql_fetch_row (mysql_res);
/* Write group code */
if (NumGrp)
fprintf (Gbl.F.Out,"%c",Par_SEPARATOR_PARAM_MULTIPLE);
fprintf (Gbl.F.Out,"%s",row[0]);
}
fprintf (Gbl.F.Out,"\" />");
}
else
/***** Write the boolean parameter that indicates if all the groups must be listed *****/
Par_PutHiddenParamChar ("AllGroups",'Y');
/***** Free structure that stores the query result *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps)
2014-12-01 23:55:08 +01:00
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/*************** Save me as students who attended to an event ****************/
/*****************************************************************************/
void Att_RegisterMeAsStdInAttEvent (void)
{
extern const char *Txt_Your_comment_has_been_updated;
struct AttendanceEvent Att;
bool Present;
2017-01-28 15:58:46 +01:00
char CommentParamName[10 + 10 + 1];
char CommentStd[Cns_MAX_BYTES_TEXT + 1];
char CommentTch[Cns_MAX_BYTES_TEXT + 1];
2014-12-01 23:55:08 +01:00
/***** Get attendance event code *****/
if ((Att.AttCod = Att_GetParamAttCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of attendance event is missing.");
Att_GetDataOfAttEventByCodAndCheckCrs (&Att); // This checks that event belong to current course
if (Att.Open)
{
/***** Get comments for this student *****/
2018-10-10 23:56:42 +02:00
Present = Att_CheckIfUsrIsPresentInAttEventAndGetComments (Att.AttCod,Gbl.Usrs.Me.UsrDat.UsrCod,
CommentStd,CommentTch);
2018-10-17 01:08:42 +02:00
snprintf (CommentParamName,sizeof (CommentParamName),
"CommentStd%ld",
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-01 23:55:08 +01:00
Par_GetParToHTML (CommentParamName,CommentStd,Cns_MAX_BYTES_TEXT);
if (Present ||
CommentStd[0] ||
CommentTch[0])
/***** Register student *****/
Att_RegUsrInAttEventChangingComments (Att.AttCod,Gbl.Usrs.Me.UsrDat.UsrCod,
Present,CommentStd,CommentTch);
else
/***** Remove student *****/
Att_RemoveUsrFromAttEvent (Att.AttCod,Gbl.Usrs.Me.UsrDat.UsrCod);
/***** Write final message *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Your_comment_has_been_updated);
2014-12-01 23:55:08 +01:00
}
/***** Show the attendance event again *****/
Gbl.AttEvents.AttCod = Att.AttCod;
Att_SeeOneAttEvent ();
}
/*****************************************************************************/
/***************** Save students who attended to an event ********************/
/*****************************************************************************/
/* Algorithm:
2017-05-18 19:13:41 +02:00
1. Get list of students in the groups selected: Gbl.Usrs.LstUsrs[Rol_STD]
2014-12-01 23:55:08 +01:00
2. Mark all students in the groups selected setting Remove=true
2019-03-11 13:33:34 +01:00
3. Get list of students marked as present by me: Gbl.Usrs.Selected.List[Rol_STD]
4. Loop over the list Gbl.Usrs.Selected.List[Rol_STD],
2014-12-01 23:55:08 +01:00
that holds the list of the students marked as present,
2017-05-18 19:13:41 +02:00
marking the students in Gbl.Usrs.LstUsrs[Rol_STD].Lst as Remove=false
2014-12-01 23:55:08 +01:00
5. Delete from att_usr all the students marked as Remove=true
6. Replace (insert without duplicated) into att_usr all the students marked as Remove=false
*/
void Att_RegisterStudentsInAttEvent (void)
{
extern const char *Txt_Presents;
extern const char *Txt_Absents;
struct AttendanceEvent Att;
unsigned NumStd;
const char *Ptr;
bool Present;
unsigned NumStdsPresent;
unsigned NumStdsAbsent;
struct UsrData UsrData;
2017-01-28 15:58:46 +01:00
char CommentParamName[10 + 10 + 1];
char CommentStd[Cns_MAX_BYTES_TEXT + 1];
char CommentTch[Cns_MAX_BYTES_TEXT + 1];
2014-12-01 23:55:08 +01:00
/***** Get attendance event code *****/
if ((Att.AttCod = Att_GetParamAttCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of attendance event is missing.");
Att_GetDataOfAttEventByCodAndCheckCrs (&Att); // This checks that event belong to current course
/***** Get groups selected *****/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2017-05-18 19:13:41 +02:00
/***** 1. Get list of students in the groups selected: Gbl.Usrs.LstUsrs[Rol_STD] *****/
2014-12-01 23:55:08 +01:00
/* Get list of students in the groups selected */
2019-04-03 20:57:04 +02:00
Usr_GetListUsrs (Hie_CRS,Rol_STD);
2014-12-01 23:55:08 +01:00
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs) // If there are students in the groups selected...
2014-12-01 23:55:08 +01:00
{
/***** 2. Mark all students in the groups selected setting Remove=true *****/
for (NumStd = 0;
2017-05-18 19:13:41 +02:00
NumStd < Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs;
2014-12-01 23:55:08 +01:00
NumStd++)
2017-05-18 19:13:41 +02:00
Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].Remove = true;
2014-12-01 23:55:08 +01:00
2019-03-11 13:33:34 +01:00
/***** 3. Get list of students marked as present by me: Gbl.Usrs.Selected.List[Rol_STD] *****/
2016-07-04 14:03:04 +02:00
Usr_GetListsSelectedUsrsCods ();
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrData);
2019-03-11 13:33:34 +01:00
/***** 4. Loop over the list Gbl.Usrs.Selected.List[Rol_STD],
2014-12-01 23:55:08 +01:00
that holds the list of the students marked as present,
2017-05-18 19:13:41 +02:00
marking the students in Gbl.Usrs.LstUsrs[Rol_STD].Lst as Remove=false *****/
2019-03-11 13:33:34 +01:00
Ptr = Gbl.Usrs.Selected.List[Rol_STD];
2014-12-01 23:55:08 +01:00
while (*Ptr)
{
2017-03-13 14:22:36 +01:00
Par_GetNextStrUntilSeparParamMult (&Ptr,UsrData.EncryptedUsrCod,
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
2014-12-01 23:55:08 +01:00
Usr_GetUsrCodFromEncryptedUsrCod (&UsrData);
2016-07-26 02:41:31 +02:00
if (UsrData.UsrCod > 0) // Student exists in database
2014-12-01 23:55:08 +01:00
/***** Mark student to not be removed *****/
for (NumStd = 0;
2017-05-18 19:13:41 +02:00
NumStd < Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs;
2014-12-01 23:55:08 +01:00
NumStd++)
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].UsrCod == UsrData.UsrCod)
2014-12-01 23:55:08 +01:00
{
2017-05-18 19:13:41 +02:00
Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].Remove = false;
2014-12-01 23:55:08 +01:00
break; // Found! Exit loop
}
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrData);
/***** Free memory *****/
2016-07-04 14:03:04 +02:00
/* Free memory used by list of selected students' codes */
Usr_FreeListsSelectedUsrsCods ();
2014-12-01 23:55:08 +01:00
// 5. Delete from att_usr all the students marked as Remove=true
// 6. Replace (insert without duplicated) into att_usr all the students marked as Remove=false
for (NumStd = 0, NumStdsAbsent = NumStdsPresent = 0;
2017-05-18 19:13:41 +02:00
NumStd < Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs;
2014-12-01 23:55:08 +01:00
NumStd++)
{
/***** Get comments for this student *****/
2017-05-18 19:13:41 +02:00
Att_CheckIfUsrIsPresentInAttEventAndGetComments (Att.AttCod,Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].UsrCod,CommentStd,CommentTch);
2018-10-17 01:08:42 +02:00
snprintf (CommentParamName,sizeof (CommentParamName),
"CommentTch%ld",
Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].UsrCod);
2014-12-01 23:55:08 +01:00
Par_GetParToHTML (CommentParamName,CommentTch,Cns_MAX_BYTES_TEXT);
2017-05-18 19:13:41 +02:00
Present = !Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].Remove;
2014-12-01 23:55:08 +01:00
if (Present ||
CommentStd[0] ||
CommentTch[0])
/***** Register student *****/
2017-05-18 19:13:41 +02:00
Att_RegUsrInAttEventChangingComments (Att.AttCod,Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].UsrCod,
2014-12-01 23:55:08 +01:00
Present,CommentStd,CommentTch);
else
/***** Remove student *****/
2017-05-18 19:13:41 +02:00
Att_RemoveUsrFromAttEvent (Att.AttCod,Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumStd].UsrCod);
2014-12-01 23:55:08 +01:00
if (Present)
NumStdsPresent++;
else
NumStdsAbsent++;
}
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Write final message *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,"%s: %u<br />"
2019-02-15 23:38:44 +01:00
"%s: %u",
Txt_Presents,NumStdsPresent,
Txt_Absents ,NumStdsAbsent );
2014-12-01 23:55:08 +01:00
}
2017-05-18 19:13:41 +02:00
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0
2017-02-09 19:27:18 +01:00
/***** Show warning indicating no students found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Show the attendance event again *****/
Gbl.AttEvents.AttCod = Att.AttCod;
Att_SeeOneAttEvent ();
/***** Free memory for list of groups selected *****/
Grp_FreeListCodSelectedGrps ();
}
/*****************************************************************************/
/******* Get number of students from a list who attended to an event *********/
/*****************************************************************************/
static void Att_GetNumStdsTotalWhoAreInAttEvent (struct AttendanceEvent *Att)
{
/***** Count number of students registered in an event in database *****/
2018-11-03 13:13:11 +01:00
Att->NumStdsTotal =
(unsigned) DB_QueryCOUNT ("can not get number of students"
" who are registered in an event",
"SELECT COUNT(*) FROM att_usr"
" WHERE AttCod=%ld AND Present='Y'",
Att->AttCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******* Get number of students from a list who attended to an event *********/
/*****************************************************************************/
static unsigned Att_GetNumStdsFromAListWhoAreInAttEvent (long AttCod,long LstSelectedUsrCods[],unsigned NumStdsInList)
{
2018-11-04 20:51:38 +01:00
char *SubQueryAllUsrs = NULL;
char SubQueryOneUsr[1 + 1 + 10 + 1];
2014-12-01 23:55:08 +01:00
unsigned NumStd;
unsigned NumStdsInAttEvent = 0;
2017-01-16 01:51:01 +01:00
size_t MaxLength;
2014-12-01 23:55:08 +01:00
if (NumStdsInList)
{
2018-11-04 20:51:38 +01:00
/***** Allocate space for subquery *****/
2017-01-16 01:51:01 +01:00
MaxLength = 256 + NumStdsInList * (1 + 1 + 10);
2018-11-04 20:51:38 +01:00
if ((SubQueryAllUsrs = (char *) malloc (MaxLength + 1)) == NULL)
2018-10-18 20:06:54 +02:00
Lay_NotEnoughMemoryExit ();
2018-11-04 20:51:38 +01:00
SubQueryAllUsrs[0] = '\0';
2014-12-01 23:55:08 +01:00
/***** Count number of students registered in an event in database *****/
for (NumStd = 0;
NumStd < NumStdsInList;
NumStd++)
2018-11-04 20:51:38 +01:00
if (NumStd)
{
snprintf (SubQueryOneUsr,sizeof (SubQueryOneUsr),
",%ld",
LstSelectedUsrCods[NumStd]);
Str_Concat (SubQueryAllUsrs,SubQueryOneUsr,
MaxLength);
}
else
snprintf (SubQueryAllUsrs,sizeof (SubQueryOneUsr),
"%ld",
LstSelectedUsrCods[NumStd]);
NumStdsInAttEvent =
(unsigned) DB_QueryCOUNT ("can not get number of students"
" from a list who are registered in an event",
"SELECT COUNT(*) FROM att_usr"
" WHERE AttCod=%ld"
" AND UsrCod IN (%s) AND Present='Y'",
AttCod,SubQueryAllUsrs);
2018-11-04 21:28:11 +01:00
/***** Free memory for subquery string *****/
free ((void *) SubQueryAllUsrs);
2014-12-01 23:55:08 +01:00
}
return NumStdsInAttEvent;
}
/*****************************************************************************/
/***************** Check if a student attended to an event *******************/
/*****************************************************************************/
static bool Att_CheckIfUsrIsInTableAttUsr (long AttCod,long UsrCod,bool *Present)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-30 13:59:37 +01:00
unsigned long NumRows;
2014-12-01 23:55:08 +01:00
bool InDBTable;
/***** Check if a student is registered in an event in database *****/
2018-10-30 13:59:37 +01:00
NumRows = DB_QuerySELECT (&mysql_res,"can not get if a student"
" is already registered"
" in an event",
"SELECT Present FROM att_usr"
" WHERE AttCod=%ld AND UsrCod=%ld",
AttCod,UsrCod);
if (NumRows)
2014-12-01 23:55:08 +01:00
{
InDBTable = true;
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get if present (row[0]) */
2016-09-07 18:48:10 +02:00
*Present = (row[0][0] == 'Y');
2014-12-01 23:55:08 +01:00
}
else // User is not present
{
InDBTable = false;
*Present = false;
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return InDBTable;
}
/*****************************************************************************/
/***************** Check if a student attended to an event *******************/
/*****************************************************************************/
static bool Att_CheckIfUsrIsPresentInAttEvent (long AttCod,long UsrCod)
{
bool Present;
Att_CheckIfUsrIsInTableAttUsr (AttCod,UsrCod,&Present);
return Present;
}
/*****************************************************************************/
/***************** Check if a student attended to an event *******************/
/*****************************************************************************/
2017-01-17 03:10:43 +01:00
static bool Att_CheckIfUsrIsPresentInAttEventAndGetComments (long AttCod,long UsrCod,
char CommentStd[Cns_MAX_BYTES_TEXT + 1],
char CommentTch[Cns_MAX_BYTES_TEXT + 1])
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-30 13:59:37 +01:00
unsigned long NumRows;
2014-12-01 23:55:08 +01:00
bool Present;
/***** Check if a students is registered in an event in database *****/
2018-10-30 13:59:37 +01:00
NumRows = DB_QuerySELECT (&mysql_res,"can not get if a student"
" is already registered"
" in an event",
"SELECT Present,CommentStd,CommentTch"
" FROM att_usr"
" WHERE AttCod=%ld AND UsrCod=%ld",
AttCod,UsrCod);
if (NumRows)
2014-12-01 23:55:08 +01:00
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get if present (row[0]) */
2016-09-07 18:48:10 +02:00
Present = (row[0][0] == 'Y');
2014-12-01 23:55:08 +01:00
/* Get student's comment (row[1]) */
2017-01-17 03:10:43 +01:00
Str_Copy (CommentStd,row[1],
Cns_MAX_BYTES_TEXT);
2014-12-01 23:55:08 +01:00
/* Get teacher's comment (row[2]) */
2017-01-17 03:10:43 +01:00
Str_Copy (CommentTch,row[2],
Cns_MAX_BYTES_TEXT);
2014-12-01 23:55:08 +01:00
}
else // User is not present
{
Present = false;
CommentStd[0] =
CommentTch[0] = '\0';
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return Present;
}
/*****************************************************************************/
/******* Register a user in an attendance event not changing comments ********/
/*****************************************************************************/
void Att_RegUsrInAttEventNotChangingComments (long AttCod,long UsrCod)
{
bool Present;
/***** Check if user is already in table att_usr (present or not) *****/
if (Att_CheckIfUsrIsInTableAttUsr (AttCod,UsrCod,&Present)) // User is in table att_usr
{
// If already present ==> nothing to do
if (!Present)
/***** Set user as present in database *****/
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not set user as present in an event",
"UPDATE att_usr SET Present='Y'"
" WHERE AttCod=%ld AND UsrCod=%ld",
AttCod,UsrCod);
2014-12-01 23:55:08 +01:00
}
else // User is not in table att_usr
Att_RegUsrInAttEventChangingComments (AttCod,UsrCod,true,"","");
}
/*****************************************************************************/
/********* Register a user in an attendance event changing comments **********/
/*****************************************************************************/
static void Att_RegUsrInAttEventChangingComments (long AttCod,long UsrCod,bool Present,
const char *CommentStd,const char *CommentTch)
{
/***** Register user as assistant to an event in database *****/
2018-11-02 16:39:35 +01:00
DB_QueryREPLACE ("can not register user in an event",
"REPLACE INTO att_usr"
" (AttCod,UsrCod,Present,CommentStd,CommentTch)"
" VALUES"
" (%ld,%ld,'%c','%s','%s')",
AttCod,UsrCod,
Present ? 'Y' :
'N',
CommentStd,
CommentTch);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Remove a user from an event **************************/
/*****************************************************************************/
static void Att_RemoveUsrFromAttEvent (long AttCod,long UsrCod)
{
/***** Remove user if there is no comment in database *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove student from an event",
"DELETE FROM att_usr WHERE AttCod=%ld AND UsrCod=%ld",
AttCod,UsrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************ Remove users absent without comments from an event *************/
/*****************************************************************************/
void Att_RemoveUsrsAbsentWithoutCommentsFromAttEvent (long AttCod)
{
/***** Clean table att_usr *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove users absent"
" without comments from an event",
"DELETE FROM att_usr"
" WHERE AttCod=%ld AND Present='N'"
" AND CommentStd='' AND CommentTch=''",
AttCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Request listing attendance of students to several events **********/
/*****************************************************************************/
2015-11-13 01:27:44 +01:00
void Usr_ReqListStdsAttendanceCrs (void)
2014-12-01 23:55:08 +01:00
{
2016-11-27 23:08:29 +01:00
extern const char *Hlp_USERS_Attendance_attendance_list;
2018-10-18 11:10:04 +02:00
extern const char *Txt_Attendance;
2015-04-11 17:33:14 +02:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2019-03-12 10:28:50 +01:00
extern const char *Txt_View_attendance;
2014-12-01 23:55:08 +01:00
2015-11-13 01:27:44 +01:00
/***** Get list of attendance events *****/
Att_GetListAttEvents (Att_OLDEST_FIRST);
2014-12-01 23:55:08 +01:00
/***** Get and update type of list,
2015-11-13 01:27:44 +01:00
number of columns in class photo
and preference about view photos *****/
2014-12-01 23:55:08 +01:00
Usr_GetAndUpdatePrefsAboutUsrList ();
2016-11-25 03:21:02 +01:00
/***** Get groups to show ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
/***** Get and order lists of users from current course *****/
2019-04-03 20:57:04 +02:00
Usr_GetListUsrs (Hie_CRS,Rol_STD);
2016-11-25 03:21:02 +01:00
2018-10-18 11:10:04 +02:00
/***** Start box *****/
Box_StartBox (NULL,Txt_Attendance,Att_PutIconsStdsAttList,
Hlp_USERS_Attendance_attendance_list,Box_NOT_CLOSABLE);
2017-06-12 14:16:33 +02:00
/***** Start box *****/
2017-06-11 22:26:40 +02:00
Box_StartBox (NULL,Txt_ROLES_PLURAL_Abc[Rol_STD][Usr_SEX_UNKNOWN],NULL,
2018-10-18 11:10:04 +02:00
NULL,Box_NOT_CLOSABLE);
2016-11-24 22:54:57 +01:00
2014-12-01 23:55:08 +01:00
/***** Form to select groups *****/
2017-07-02 18:53:35 +02:00
Grp_ShowFormToSelectSeveralGroups (ActReqLstStdAtt,Grp_ONLY_MY_GROUPS);
2017-05-25 11:04:38 +02:00
/***** Start section with user list *****/
2017-05-25 13:43:54 +02:00
Lay_StartSection (Usr_USER_LIST_SECTION_ID);
2014-12-01 23:55:08 +01:00
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs)
2014-12-01 23:55:08 +01:00
{
2017-05-18 19:13:41 +02:00
if (Usr_GetIfShowBigList (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs,NULL))
2015-11-13 01:27:44 +01:00
{
/***** Get list of selected users *****/
2016-07-04 14:03:04 +02:00
Usr_GetListsSelectedUsrsCods ();
2014-12-01 23:55:08 +01:00
2015-11-13 01:27:44 +01:00
/***** Draw a class photo with students of the course *****/
2015-10-02 01:04:28 +02:00
/* Form to select type of list used for select several users */
2015-11-13 01:27:44 +01:00
Usr_ShowFormsToSelectUsrListType (ActReqLstStdAtt);
2015-10-02 01:04:28 +02:00
2015-11-13 01:27:44 +01:00
/* Start form */
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActSeeLstStdAtt);
2015-11-13 01:27:44 +01:00
Grp_PutParamsCodGrps ();
2014-12-01 23:55:08 +01:00
2015-11-13 01:27:44 +01:00
/* Write list of students to select some of them */
2017-06-11 20:09:59 +02:00
Tbl_StartTableCenter (0);
2017-05-18 19:13:41 +02:00
Usr_ListUsersToSelect (Rol_STD);
2017-06-11 20:09:59 +02:00
Tbl_EndTable ();
2014-12-07 02:04:30 +01:00
2015-11-13 01:27:44 +01:00
/* Send button */
2019-03-12 10:28:50 +01:00
Btn_PutConfirmButton (Txt_View_attendance);
2015-04-11 17:33:14 +02:00
2015-11-13 01:27:44 +01:00
/* End form */
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
2016-07-04 14:03:04 +02:00
/***** Free memory used by list of selected users' codes *****/
Usr_FreeListsSelectedUsrsCods ();
2015-11-13 01:27:44 +01:00
}
2014-12-01 23:55:08 +01:00
}
2017-05-29 21:34:43 +02:00
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0
/***** Show warning indicating no students found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_STD);
2014-12-01 23:55:08 +01:00
2017-05-25 11:04:38 +02:00
/***** End section with user list *****/
2017-05-25 13:43:54 +02:00
Lay_EndSection ();
2017-05-25 11:04:38 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2017-06-10 21:38:10 +02:00
Box_EndBox ();
2016-11-24 22:54:57 +01:00
2018-10-18 11:10:04 +02:00
/***** End box *****/
Box_EndBox ();
2014-12-01 23:55:08 +01:00
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
2015-11-13 01:27:44 +01:00
/***** Free list of attendance events *****/
Att_FreeListAttEvents ();
}
/*****************************************************************************/
/********** List my attendance (I am a student) to several events ************/
/*****************************************************************************/
void Usr_ListMyAttendanceCrs (void)
{
2016-03-20 02:08:13 +01:00
Usr_ListOrPrintMyAttendanceCrs (Att_NORMAL_VIEW_ONLY_ME);
2015-11-13 01:27:44 +01:00
}
void Usr_PrintMyAttendanceCrs (void)
{
Usr_ListOrPrintMyAttendanceCrs (Att_PRINT_VIEW);
}
static void Usr_ListOrPrintMyAttendanceCrs (Att_TypeOfView_t TypeOfView)
{
2018-10-18 09:59:38 +02:00
extern const char *Hlp_USERS_Attendance_attendance_list;
extern const char *Txt_Attendance;
2015-11-13 01:27:44 +01:00
unsigned NumAttEvent;
/***** Get list of attendance events *****/
Att_GetListAttEvents (Att_OLDEST_FIRST);
/***** Get boolean parameter that indicates if details must be shown *****/
2017-01-28 20:32:50 +01:00
Gbl.AttEvents.ShowDetails = Par_GetParToBool ("ShowDetails");
2015-11-13 01:27:44 +01:00
/***** Get list of groups selected ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
/***** Get number of students in each event *****/
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
/* Get number of students in this event */
Gbl.AttEvents.Lst[NumAttEvent].NumStdsFromList = Att_GetNumStdsFromAListWhoAreInAttEvent (Gbl.AttEvents.Lst[NumAttEvent].AttCod,
&Gbl.Usrs.Me.UsrDat.UsrCod,1);
/***** Get list of attendance events selected *****/
Att_GetListSelectedAttCods (&Gbl.AttEvents.StrAttCodsSelected);
2018-10-18 09:59:38 +02:00
/***** Start box *****/
Box_StartBox (NULL,Txt_Attendance,
2018-10-18 11:10:04 +02:00
TypeOfView == Att_NORMAL_VIEW_ONLY_ME ? Att_PutIconsMyAttList :
2018-10-18 09:59:38 +02:00
NULL,
TypeOfView == Att_NORMAL_VIEW_ONLY_ME ? Hlp_USERS_Attendance_attendance_list :
NULL,
Box_NOT_CLOSABLE);
2015-11-13 01:27:44 +01:00
/***** List events to select *****/
Att_ListEventsToSelect (TypeOfView);
/***** Get my preference about photos in users' list for current course *****/
Usr_GetMyPrefAboutListWithPhotosFromDB ();
/***** Show table with attendances for every student in list *****/
Att_ListStdsAttendanceTable (TypeOfView,1,&Gbl.Usrs.Me.UsrDat.UsrCod);
/***** Show details or put button to show details *****/
if (Gbl.AttEvents.ShowDetails)
2018-10-18 09:59:38 +02:00
Att_ListStdsWithAttEventsDetails (1,&Gbl.Usrs.Me.UsrDat.UsrCod);
/***** End box *****/
Box_EndBox ();
2015-11-13 01:27:44 +01:00
/***** Free memory for list of attendance events selected *****/
free ((void *) Gbl.AttEvents.StrAttCodsSelected);
/***** Free list of groups selected *****/
Grp_FreeListCodSelectedGrps ();
/***** Free list of attendance events *****/
Att_FreeListAttEvents ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* List attendance of students to several events *****************/
/*****************************************************************************/
2015-11-13 01:27:44 +01:00
void Usr_ListStdsAttendanceCrs (void)
{
2016-03-20 02:08:13 +01:00
Usr_ListOrPrintStdsAttendanceCrs (Att_NORMAL_VIEW_STUDENTS);
2015-11-13 01:27:44 +01:00
}
void Usr_PrintStdsAttendanceCrs (void)
{
Usr_ListOrPrintStdsAttendanceCrs (Att_PRINT_VIEW);
}
static void Usr_ListOrPrintStdsAttendanceCrs (Att_TypeOfView_t TypeOfView)
2014-12-01 23:55:08 +01:00
{
2018-10-18 09:59:38 +02:00
extern const char *Hlp_USERS_Attendance_attendance_list;
extern const char *Txt_Attendance;
2019-03-11 00:51:54 +01:00
extern const char *Txt_You_must_select_one_ore_more_users;
2014-12-01 23:55:08 +01:00
unsigned NumStdsInList;
long *LstSelectedUsrCods;
2014-12-06 02:21:34 +01:00
unsigned NumAttEvent;
2014-12-01 23:55:08 +01:00
/***** Get list of attendance events *****/
Att_GetListAttEvents (Att_OLDEST_FIRST);
2019-03-11 14:16:55 +01:00
/***** Get list of selected students if not already got *****/
2016-07-04 14:03:04 +02:00
Usr_GetListsSelectedUsrsCods ();
2014-12-01 23:55:08 +01:00
/* Check the number of students to list */
2015-09-30 23:10:15 +02:00
if ((NumStdsInList = Usr_CountNumUsrsInListOfSelectedUsrs ()))
2014-12-01 23:55:08 +01:00
{
2014-12-08 14:29:11 +01:00
/***** Get boolean parameter that indicates if details must be shown *****/
2017-01-28 20:32:50 +01:00
Gbl.AttEvents.ShowDetails = Par_GetParToBool ("ShowDetails");
2014-12-08 14:29:11 +01:00
2014-12-08 01:30:47 +01:00
/***** Get list of groups selected ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2014-12-01 23:55:08 +01:00
2014-12-07 02:04:30 +01:00
/***** Get list of students selected to show their attendances *****/
Att_GetListSelectedUsrCods (NumStdsInList,&LstSelectedUsrCods);
2014-12-06 02:21:34 +01:00
2014-12-01 23:55:08 +01:00
/***** Get number of students in each event *****/
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
/* Get number of students in this event */
2014-12-06 02:21:34 +01:00
Gbl.AttEvents.Lst[NumAttEvent].NumStdsFromList = Att_GetNumStdsFromAListWhoAreInAttEvent (Gbl.AttEvents.Lst[NumAttEvent].AttCod,
2015-11-13 01:27:44 +01:00
LstSelectedUsrCods,NumStdsInList);
2014-12-01 23:55:08 +01:00
2014-12-07 02:04:30 +01:00
/***** Get list of attendance events selected *****/
2015-04-02 18:39:49 +02:00
Att_GetListSelectedAttCods (&Gbl.AttEvents.StrAttCodsSelected);
2014-12-08 01:30:47 +01:00
2018-10-18 09:59:38 +02:00
/***** Start box *****/
Box_StartBox (NULL,Txt_Attendance,
2018-10-18 11:10:04 +02:00
TypeOfView == Att_NORMAL_VIEW_STUDENTS ? Att_PutIconsStdsAttList :
2018-10-18 09:59:38 +02:00
NULL,
TypeOfView == Att_NORMAL_VIEW_STUDENTS ? Hlp_USERS_Attendance_attendance_list :
NULL,
Box_NOT_CLOSABLE);
2014-12-07 02:04:30 +01:00
/***** List events to select *****/
2015-11-13 01:27:44 +01:00
Att_ListEventsToSelect (TypeOfView);
2014-12-01 23:55:08 +01:00
/***** Get my preference about photos in users' list for current course *****/
Usr_GetMyPrefAboutListWithPhotosFromDB ();
2014-12-06 02:21:34 +01:00
/***** Show table with attendances for every student in list *****/
2015-11-13 01:27:44 +01:00
Att_ListStdsAttendanceTable (TypeOfView,NumStdsInList,LstSelectedUsrCods);
2014-12-01 23:55:08 +01:00
2014-12-08 14:29:11 +01:00
/***** Show details or put button to show details *****/
2015-04-02 18:39:49 +02:00
if (Gbl.AttEvents.ShowDetails)
2018-10-18 09:59:38 +02:00
Att_ListStdsWithAttEventsDetails (NumStdsInList,LstSelectedUsrCods);
/***** End box *****/
Box_EndBox ();
2014-12-08 14:29:11 +01:00
/***** Free memory for list of attendance events selected *****/
2015-04-02 18:39:49 +02:00
free ((void *) Gbl.AttEvents.StrAttCodsSelected);
2014-12-01 23:55:08 +01:00
/***** Free list of user codes *****/
free ((void *) LstSelectedUsrCods);
2014-12-08 01:30:47 +01:00
/***** Free list of groups selected *****/
Grp_FreeListCodSelectedGrps ();
2014-12-01 23:55:08 +01:00
}
else // No students selected
{
2019-03-11 00:51:54 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_must_select_one_ore_more_users);
2015-11-13 01:27:44 +01:00
Usr_ReqListStdsAttendanceCrs (); // ...show again the form
2014-12-01 23:55:08 +01:00
}
2016-07-04 14:03:04 +02:00
/***** Free memory used by list of selected users' codes *****/
Usr_FreeListsSelectedUsrsCods ();
2014-12-01 23:55:08 +01:00
/***** Free list of attendance events *****/
Att_FreeListAttEvents ();
}
2014-12-07 02:04:30 +01:00
/*****************************************************************************/
/********** Get list of students selected to show their attendances **********/
/*****************************************************************************/
static void Att_GetListSelectedUsrCods (unsigned NumStdsInList,long **LstSelectedUsrCods)
{
unsigned NumStd;
const char *Ptr;
struct UsrData UsrDat;
/***** Create list of user codes *****/
if ((*LstSelectedUsrCods = (long *) calloc ((size_t) NumStdsInList,sizeof (long))) == NULL)
2018-10-18 20:06:54 +02:00
Lay_NotEnoughMemoryExit ();
2014-12-07 02:04:30 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2019-03-11 13:33:34 +01:00
/***** Loop over the list Gbl.Usrs.Selected.List[Rol_UNK] getting users' codes *****/
for (NumStd = 0, Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
2014-12-07 02:04:30 +01:00
NumStd < NumStdsInList && *Ptr;
NumStd++)
{
2017-03-13 14:22:36 +01:00
Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod,
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
2014-12-07 02:04:30 +01:00
Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
(*LstSelectedUsrCods)[NumStd] = UsrDat.UsrCod;
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
/*****************************************************************************/
/****************** Get list of attendance events selected *******************/
/*****************************************************************************/
2014-12-08 01:30:47 +01:00
static void Att_GetListSelectedAttCods (char **StrAttCodsSelected)
2014-12-07 02:04:30 +01:00
{
unsigned MaxSizeListAttCodsSelected;
unsigned NumAttEvent;
const char *Ptr;
long AttCod;
2017-01-28 15:58:46 +01:00
char LongStr[1 + 10 + 1];
2014-12-08 01:30:47 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumGrpsInThisEvent;
unsigned NumGrpInThisEvent;
long GrpCodInThisEvent;
unsigned NumGrpSel;
2014-12-07 02:04:30 +01:00
/***** Allocate memory for list of attendance events selected *****/
2017-01-28 15:58:46 +01:00
MaxSizeListAttCodsSelected = Gbl.AttEvents.Num * (1 + 10 + 1);
if ((*StrAttCodsSelected = (char *) malloc (MaxSizeListAttCodsSelected + 1)) == NULL)
2018-10-18 20:06:54 +02:00
Lay_NotEnoughMemoryExit ();
2014-12-07 02:04:30 +01:00
/***** Get parameter multiple with list of attendance events selected *****/
2014-12-08 01:30:47 +01:00
Par_GetParMultiToText ("AttCods",*StrAttCodsSelected,MaxSizeListAttCodsSelected);
2014-12-07 02:04:30 +01:00
2014-12-08 01:30:47 +01:00
/***** Set which attendance events will be shown as selected (checkboxes on) *****/
if ((*StrAttCodsSelected)[0]) // There are events selected
{
/* Reset selection */
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
Gbl.AttEvents.Lst[NumAttEvent].Selected = false;
2014-12-07 02:04:30 +01:00
2014-12-08 01:30:47 +01:00
/* Set some events as selected */
for (Ptr = *StrAttCodsSelected;
2014-12-07 02:04:30 +01:00
*Ptr;
)
{
/* Get next attendance event selected */
2017-01-28 15:58:46 +01:00
Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,1 + 10);
2014-12-07 02:04:30 +01:00
AttCod = Str_ConvertStrCodToLongCod (LongStr);
2014-12-08 01:30:47 +01:00
/* Set each event in *StrAttCodsSelected as selected */
2014-12-07 02:04:30 +01:00
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
if (Gbl.AttEvents.Lst[NumAttEvent].AttCod == AttCod)
Gbl.AttEvents.Lst[NumAttEvent].Selected = true;
}
2014-12-08 01:30:47 +01:00
}
else // No events selected
{
/***** Set which events will be marked as selected by default *****/
2019-04-04 10:45:15 +02:00
if (!Gbl.Crs.Grps.NumGrps || // Course has no groups
2014-12-08 01:30:47 +01:00
Gbl.Usrs.ClassPhoto.AllGroups) // All groups selected
/* Set all events as selected */
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
2014-12-07 02:04:30 +01:00
Gbl.AttEvents.Lst[NumAttEvent].Selected = true;
2014-12-08 01:30:47 +01:00
else // Course has groups and not all of them are selected
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
{
/* Reset selection */
Gbl.AttEvents.Lst[NumAttEvent].Selected = false;
2014-12-07 02:04:30 +01:00
2014-12-08 01:30:47 +01:00
/* Set this event as selected? */
if (Gbl.AttEvents.Lst[NumAttEvent].NumStdsFromList) // Some students attended to this event
Gbl.AttEvents.Lst[NumAttEvent].Selected = true;
else // No students attended to this event
{
/***** Get groups associated to an attendance event from database *****/
2018-10-30 13:59:37 +01:00
NumGrpsInThisEvent = (unsigned) DB_QuerySELECT (&mysql_res,"can not get groups"
" of an attendance event",
"SELECT GrpCod FROM att_grp"
" WHERE att_grp.AttCod=%ld",
Gbl.AttEvents.Lst[NumAttEvent].AttCod);
2014-12-08 01:30:47 +01:00
if (NumGrpsInThisEvent) // This event is associated to groups
/* Get groups associated to this event */
for (NumGrpInThisEvent = 0;
NumGrpInThisEvent < NumGrpsInThisEvent &&
!Gbl.AttEvents.Lst[NumAttEvent].Selected;
NumGrpInThisEvent++)
{
/* Get next group associated to this event */
row = mysql_fetch_row (mysql_res);
if ((GrpCodInThisEvent = Str_ConvertStrCodToLongCod (row[0])) > 0)
/* Check if this group is selected */
for (NumGrpSel = 0;
2019-04-04 10:45:15 +02:00
NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps &&
2014-12-08 01:30:47 +01:00
!Gbl.AttEvents.Lst[NumAttEvent].Selected;
NumGrpSel++)
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel] == GrpCodInThisEvent)
2014-12-08 01:30:47 +01:00
Gbl.AttEvents.Lst[NumAttEvent].Selected = true;
}
else // This event is not associated to groups
Gbl.AttEvents.Lst[NumAttEvent].Selected = true;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
}
}
2014-12-07 02:04:30 +01:00
}
2014-12-08 14:29:11 +01:00
/*****************************************************************************/
2018-10-18 11:10:04 +02:00
/******* Put contextual icons when listing my assistance (as student) ********/
2014-12-08 14:29:11 +01:00
/*****************************************************************************/
2018-10-18 11:10:04 +02:00
static void Att_PutIconsMyAttList (void)
2014-12-08 14:29:11 +01:00
{
2018-10-18 11:10:04 +02:00
/***** Put icon to print my assistance (as student) to several events *****/
2017-06-11 19:13:28 +02:00
Ico_PutContextualIconToPrint (ActPrnLstMyAtt,Att_PutFormToPrintMyListParams);
2018-10-18 11:10:04 +02:00
/***** Put icon to print my QR code *****/
QR_PutLinkToPrintQRCode (ActPrnUsrQR,Usr_PutParamMyUsrCodEncrypted);
2015-04-02 18:39:49 +02:00
}
2015-11-13 01:27:44 +01:00
static void Att_PutFormToPrintMyListParams (void)
{
if (Gbl.AttEvents.ShowDetails)
Par_PutHiddenParamChar ("ShowDetails",'Y');
2018-10-18 11:10:04 +02:00
if (Gbl.AttEvents.StrAttCodsSelected)
if (Gbl.AttEvents.StrAttCodsSelected[0])
Par_PutHiddenParamString ("AttCods",Gbl.AttEvents.StrAttCodsSelected);
2015-11-13 01:27:44 +01:00
}
/*****************************************************************************/
2016-03-20 02:08:13 +01:00
/******** Put icon to print assistance of students to several events *********/
2015-11-13 01:27:44 +01:00
/*****************************************************************************/
2018-10-18 11:10:04 +02:00
static void Att_PutIconsStdsAttList (void)
2015-11-13 01:27:44 +01:00
{
2018-10-18 11:10:04 +02:00
/***** Put icon to print assistance of students to several events *****/
2017-06-11 19:13:28 +02:00
Ico_PutContextualIconToPrint (ActPrnLstStdAtt,Att_PutParamsToPrintStdsList);
2018-10-18 11:10:04 +02:00
/***** Put icon to print my QR code *****/
QR_PutLinkToPrintQRCode (ActPrnUsrQR,Usr_PutParamMyUsrCodEncrypted);
2015-11-13 01:27:44 +01:00
}
2016-03-20 02:08:13 +01:00
static void Att_PutParamsToPrintStdsList (void)
2015-04-02 18:39:49 +02:00
{
if (Gbl.AttEvents.ShowDetails)
2014-12-08 14:29:11 +01:00
Par_PutHiddenParamChar ("ShowDetails",'Y');
Grp_PutParamsCodGrps ();
2019-03-11 13:33:34 +01:00
Usr_PutHiddenParUsrCodAll (ActPrnLstStdAtt,Gbl.Usrs.Selected.List[Rol_UNK]);
2018-10-18 11:10:04 +02:00
if (Gbl.AttEvents.StrAttCodsSelected)
if (Gbl.AttEvents.StrAttCodsSelected[0])
Par_PutHiddenParamString ("AttCods",Gbl.AttEvents.StrAttCodsSelected);
2014-12-08 14:29:11 +01:00
}
/*****************************************************************************/
/**** Put a link (form) to list assistance of students to several events *****/
/*****************************************************************************/
2015-04-02 18:39:49 +02:00
static void Att_PutButtonToShowDetails (void)
2014-12-08 14:29:11 +01:00
{
extern const char *Txt_Show_more_details;
/***** Button to show more details *****/
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (Gbl.Action.Act,Att_ATTENDANCE_DETAILS_ID);
2014-12-08 14:29:11 +01:00
Par_PutHiddenParamChar ("ShowDetails",'Y');
Grp_PutParamsCodGrps ();
2019-03-11 13:33:34 +01:00
Usr_PutHiddenParUsrCodAll (Gbl.Action.Act,Gbl.Usrs.Selected.List[Rol_UNK]);
2018-10-18 11:10:04 +02:00
if (Gbl.AttEvents.StrAttCodsSelected)
if (Gbl.AttEvents.StrAttCodsSelected[0])
Par_PutHiddenParamString ("AttCods",Gbl.AttEvents.StrAttCodsSelected);
2017-06-11 19:02:40 +02:00
Btn_PutConfirmButton (Txt_Show_more_details);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-08 14:29:11 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********** Write list of those attendance events that have students *********/
/*****************************************************************************/
2015-11-13 01:27:44 +01:00
static void Att_ListEventsToSelect (Att_TypeOfView_t TypeOfView)
2014-12-01 23:55:08 +01:00
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormInBoxBold[The_NUM_THEMES];
2014-12-04 01:19:42 +01:00
extern const char *Txt_Events;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Event;
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2015-12-29 11:35:01 +01:00
extern const char *Txt_Today;
2014-12-08 01:30:47 +01:00
extern const char *Txt_Update_attendance;
2015-10-24 20:46:11 +02:00
unsigned UniqueId;
2014-12-01 23:55:08 +01:00
unsigned NumAttEvent;
2018-10-18 09:59:38 +02:00
bool NormalView = (TypeOfView == Att_NORMAL_VIEW_ONLY_ME ||
TypeOfView == Att_NORMAL_VIEW_STUDENTS);
/***** Start box *****/
Box_StartBox (NULL,Txt_Events,
2018-10-18 11:10:04 +02:00
TypeOfView == Att_NORMAL_VIEW_ONLY_ME ? Att_PutIconToViewAttEvents :
(TypeOfView == Att_NORMAL_VIEW_STUDENTS ? Att_PutIconToEditAttEvents :
NULL),
2018-10-18 09:59:38 +02:00
NULL,
Box_NOT_CLOSABLE);
2014-12-01 23:55:08 +01:00
2014-12-08 14:29:11 +01:00
/***** Start form to update the attendance
depending on the events selected *****/
2018-10-18 09:59:38 +02:00
if (NormalView)
2014-12-08 01:30:47 +01:00
{
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (Gbl.Action.Act,Att_ATTENDANCE_TABLE_ID);
2014-12-08 14:29:11 +01:00
Grp_PutParamsCodGrps ();
2019-03-11 13:33:34 +01:00
Usr_PutHiddenParUsrCodAll (Gbl.Action.Act,Gbl.Usrs.Selected.List[Rol_UNK]);
2014-12-08 01:30:47 +01:00
}
2014-12-05 02:33:47 +01:00
2018-10-18 09:59:38 +02:00
/***** Start table *****/
Tbl_StartTableWide (2);
2014-12-08 14:29:11 +01:00
/***** Heading row *****/
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<tr>"
2019-02-14 10:25:08 +01:00
"<th colspan=\"4\" class=\"LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2015-09-06 20:02:14 +02:00
"<th class=\"RIGHT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2014-12-01 23:55:08 +01:00
"</tr>",
Txt_Event,
2017-05-18 19:13:41 +02:00
Txt_ROLES_PLURAL_Abc[Rol_STD][Usr_SEX_UNKNOWN]);
2014-12-01 23:55:08 +01:00
2014-12-08 01:30:47 +01:00
/***** List the events *****/
2015-10-24 20:46:11 +02:00
for (NumAttEvent = 0, UniqueId = 1, Gbl.RowEvenOdd = 0;
2014-12-01 23:55:08 +01:00
NumAttEvent < Gbl.AttEvents.Num;
2015-10-24 20:46:11 +02:00
NumAttEvent++, UniqueId++, Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd)
2014-12-07 02:04:30 +01:00
{
2014-12-08 14:29:11 +01:00
/* Get data of the attendance event from database */
2014-12-07 02:04:30 +01:00
Att_GetDataOfAttEventByCodAndCheckCrs (&Gbl.AttEvents.Lst[NumAttEvent]);
Att_GetNumStdsTotalWhoAreInAttEvent (&Gbl.AttEvents.Lst[NumAttEvent]);
2014-12-01 23:55:08 +01:00
2014-12-08 14:29:11 +01:00
/* Write a row for this event */
2014-12-07 02:04:30 +01:00
fprintf (Gbl.F.Out,"<tr>"
2019-02-14 00:33:51 +01:00
"<td class=\"DAT CENTER_TOP COLOR%u\">"
2016-12-21 00:06:11 +01:00
"<input type=\"checkbox\""
" id=\"Att%u\" name=\"AttCods\" value=\"%ld\"",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2016-12-21 00:06:11 +01:00
NumAttEvent,
2014-12-07 02:04:30 +01:00
Gbl.AttEvents.Lst[NumAttEvent].AttCod);
if (Gbl.AttEvents.Lst[NumAttEvent].Selected)
fprintf (Gbl.F.Out," checked=\"checked\"");
2014-12-08 01:30:47 +01:00
fprintf (Gbl.F.Out," />"
"</td>"
2019-02-14 00:33:51 +01:00
"<td class=\"DAT RIGHT_TOP COLOR%u\">"
2016-12-21 00:06:11 +01:00
"<label for=\"Att%u\">%u:</label>"
2014-12-22 14:08:19 +01:00
"</td>"
2019-02-14 00:33:51 +01:00
"<td class=\"DAT LEFT_TOP COLOR%u\">"
2016-12-21 00:06:11 +01:00
"<label for=\"Att%u\">"
2019-02-14 10:25:08 +01:00
"<span id=\"att_date_start_%u\"></span>"
2016-12-21 00:06:11 +01:00
"</label>"
2015-10-23 13:20:42 +02:00
"<script type=\"text/javascript\">"
2017-05-04 17:06:26 +02:00
"writeLocalDateHMSFromUTC('att_date_start_%u',%ld,"
2017-05-05 09:41:56 +02:00
"%u,',&nbsp;','%s',true,true,0x7);"
2015-10-23 13:20:42 +02:00
"</script>"
2014-12-22 14:08:19 +01:00
"</td>"
2019-02-14 10:25:08 +01:00
"<td class=\"DAT LEFT_TOP COLOR%u\">"
"%s"
"</td>"
2019-02-14 00:33:51 +01:00
"<td class=\"DAT RIGHT_TOP COLOR%u\">"
2014-12-22 14:08:19 +01:00
"%u"
"</td>"
2014-12-07 02:04:30 +01:00
"</tr>",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2016-12-21 00:06:11 +01:00
NumAttEvent,NumAttEvent + 1,
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2019-02-14 10:25:08 +01:00
NumAttEvent,UniqueId,
2015-10-23 13:20:42 +02:00
UniqueId,Gbl.AttEvents.Lst[NumAttEvent].TimeUTC[Att_START_TIME],
2017-05-04 17:06:26 +02:00
(unsigned) Gbl.Prefs.DateFormat,Txt_Today,
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2019-02-14 10:25:08 +01:00
Gbl.AttEvents.Lst[NumAttEvent].Title,
Gbl.RowEvenOdd,
2014-12-07 02:04:30 +01:00
Gbl.AttEvents.Lst[NumAttEvent].NumStdsTotal);
}
/***** Put button to refresh *****/
2018-10-18 09:59:38 +02:00
if (NormalView)
2014-12-08 01:30:47 +01:00
{
2014-12-08 14:29:11 +01:00
fprintf (Gbl.F.Out,"<tr>"
2019-02-14 10:25:08 +01:00
"<td colspan=\"5\" class=\"CENTER_MIDDLE\">");
2019-01-12 19:46:33 +01:00
Frm_LinkFormSubmitAnimated (Txt_Update_attendance,
2019-02-22 21:47:50 +01:00
The_ClassFormInBoxBold[Gbl.Prefs.Theme],
NULL);
2019-01-12 19:46:33 +01:00
Ico_PutCalculateIconWithText (Txt_Update_attendance);
2014-12-08 14:29:11 +01:00
fprintf (Gbl.F.Out,"</td>"
"</tr>");
}
2014-12-08 01:30:47 +01:00
2018-10-18 09:59:38 +02:00
/***** End table *****/
Tbl_EndTable ();
2014-12-08 14:29:11 +01:00
/***** End form *****/
2018-10-18 09:59:38 +02:00
if (NormalView)
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2018-10-18 09:59:38 +02:00
/***** End box *****/
Box_EndBox ();
}
/*****************************************************************************/
2018-10-18 11:10:04 +02:00
/************ Put icon to list (with edition) attendance events **************/
2018-10-18 09:59:38 +02:00
/*****************************************************************************/
2018-10-18 11:10:04 +02:00
static void Att_PutIconToEditAttEvents (void)
2018-10-18 09:59:38 +02:00
{
Ico_PutContextualIconToEdit (ActSeeAtt,NULL);
2014-12-05 02:33:47 +01:00
}
/*****************************************************************************/
2018-10-18 11:10:04 +02:00
/*********** Put icon to list (without edition) attendance events ************/
/*****************************************************************************/
static void Att_PutIconToViewAttEvents (void)
{
Ico_PutContextualIconToView (ActSeeAtt,NULL);
}
/*****************************************************************************/
2014-12-06 02:21:34 +01:00
/*********** Show table with attendances for every student in list ***********/
2014-12-05 02:33:47 +01:00
/*****************************************************************************/
2016-03-20 02:08:13 +01:00
static void Att_ListStdsAttendanceTable (Att_TypeOfView_t TypeOfView,
unsigned NumStdsInList,
long *LstSelectedUsrCods)
2014-12-05 02:33:47 +01:00
{
2014-12-06 02:21:34 +01:00
extern const char *Txt_Number_of_students;
struct UsrData UsrDat;
unsigned NumStd;
2014-12-05 02:33:47 +01:00
unsigned NumAttEvent;
2014-12-06 02:21:34 +01:00
unsigned Total;
2018-10-18 09:59:38 +02:00
bool PutButtonShowDetails = (TypeOfView != Att_PRINT_VIEW &&
!Gbl.AttEvents.ShowDetails);
2014-12-05 02:33:47 +01:00
2014-12-06 02:21:34 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2014-12-05 02:33:47 +01:00
2018-10-18 11:29:02 +02:00
/***** Start section with attendance table *****/
Lay_StartSection (Att_ATTENDANCE_TABLE_ID);
2018-10-18 09:59:38 +02:00
/***** Start table *****/
Tbl_StartTableCenter (2);
2014-12-08 14:29:11 +01:00
/***** Heading row *****/
2014-12-06 02:21:34 +01:00
Att_WriteTableHeadSeveralAttEvents ();
2014-12-05 02:33:47 +01:00
2014-12-06 02:21:34 +01:00
/***** List the students *****/
2014-12-07 02:04:30 +01:00
for (NumStd = 0, Gbl.RowEvenOdd = 0;
2014-12-06 02:21:34 +01:00
NumStd < NumStdsInList;
NumStd++)
{
UsrDat.UsrCod = LstSelectedUsrCods[NumStd];
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS)) // Get from the database the data of the student
2017-10-05 22:29:33 +02:00
if (Usr_CheckIfICanViewAtt (&UsrDat))
2017-06-09 15:04:02 +02:00
{
UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat);
Att_WriteRowStdSeveralAttEvents (NumStd,&UsrDat);
}
2014-12-06 02:21:34 +01:00
}
2014-12-05 02:33:47 +01:00
2014-12-06 02:21:34 +01:00
/***** Last row with the total of students present in each event *****/
2015-11-13 01:27:44 +01:00
if (NumStdsInList > 1)
{
fprintf (Gbl.F.Out,"<tr>"
"<td colspan=\"%u\" class=\"DAT_N_LINE_TOP RIGHT_MIDDLE\">"
"%s:"
"</td>",
Gbl.Usrs.Listing.WithPhotos ? 4 :
3,
Txt_Number_of_students);
for (NumAttEvent = 0, Total = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
if (Gbl.AttEvents.Lst[NumAttEvent].Selected)
{
fprintf (Gbl.F.Out,"<td class=\"DAT_N_LINE_TOP RIGHT_MIDDLE\">"
"%u"
"</td>",
Gbl.AttEvents.Lst[NumAttEvent].NumStdsFromList);
Total += Gbl.AttEvents.Lst[NumAttEvent].NumStdsFromList;
}
fprintf (Gbl.F.Out,"<td class=\"DAT_N_LINE_TOP RIGHT_MIDDLE\">"
"%u"
"</td>"
"</tr>",
Total);
}
2014-12-01 23:55:08 +01:00
2016-03-20 02:08:13 +01:00
/***** End table *****/
2017-06-11 20:09:59 +02:00
Tbl_EndTable ();
2016-03-20 02:08:13 +01:00
2015-04-11 17:33:14 +02:00
/***** Button to show more details *****/
2016-03-21 18:37:28 +01:00
if (PutButtonShowDetails)
2015-04-11 17:33:14 +02:00
Att_PutButtonToShowDetails ();
2018-10-18 11:29:02 +02:00
/***** End section with attendance table *****/
Lay_EndSection ();
2014-12-06 02:21:34 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/* Write table heading for listing of students in several attendance events **/
/*****************************************************************************/
static void Att_WriteTableHeadSeveralAttEvents (void)
{
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-01 23:55:08 +01:00
extern const char *Txt_Attendance;
unsigned NumAttEvent;
2018-12-03 19:49:54 +01:00
char StrNumAttEvent[10 + 1];
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<tr>"
2015-09-06 20:02:14 +02:00
"<th colspan=\"%u\" class=\"LEFT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>",
2014-12-05 02:33:47 +01:00
Gbl.Usrs.Listing.WithPhotos ? 4 :
3,
2017-05-18 19:13:41 +02:00
Txt_ROLES_SINGUL_Abc[Rol_STD][Usr_SEX_UNKNOWN]);
2014-12-01 23:55:08 +01:00
for (NumAttEvent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
2014-12-08 01:30:47 +01:00
if (Gbl.AttEvents.Lst[NumAttEvent].Selected)
2014-12-01 23:55:08 +01:00
{
/***** Get data of this attendance event *****/
Att_GetDataOfAttEventByCodAndCheckCrs (&Gbl.AttEvents.Lst[NumAttEvent]);
2018-12-03 19:49:54 +01:00
/***** Put link to this attendance event *****/
fprintf (Gbl.F.Out,"<th class=\"CENTER_MIDDLE\" title=\"%s\">",
Gbl.AttEvents.Lst[NumAttEvent].Title);
snprintf (StrNumAttEvent,sizeof (StrNumAttEvent),
"%u",
NumAttEvent + 1);
Att_PutLinkAttEvent (&Gbl.AttEvents.Lst[NumAttEvent],
Gbl.AttEvents.Lst[NumAttEvent].Title,
StrNumAttEvent,
NULL);
fprintf (Gbl.F.Out,"</th>");
2014-12-01 23:55:08 +01:00
}
2015-09-06 20:02:14 +02:00
fprintf (Gbl.F.Out,"<th class=\"RIGHT_MIDDLE\">"
2014-12-26 22:11:03 +01:00
"%s"
"</th>"
2014-12-01 23:55:08 +01:00
"</tr>",
Txt_Attendance);
}
/*****************************************************************************/
/************ Write a row of a table with the data of a student **************/
/*****************************************************************************/
static void Att_WriteRowStdSeveralAttEvents (unsigned NumStd,struct UsrData *UsrDat)
{
2017-01-28 15:58:46 +01:00
char PhotoURL[PATH_MAX + 1];
2014-12-01 23:55:08 +01:00
bool ShowPhoto;
unsigned NumAttEvent;
bool Present;
unsigned NumTimesPresent;
/***** Write number of student in the list *****/
fprintf (Gbl.F.Out,"<tr>"
2015-09-03 00:59:03 +02:00
"<td class=\"%s RIGHT_MIDDLE COLOR%u\">"
2014-12-22 14:08:19 +01:00
"%u"
"</td>",
2019-02-14 00:33:51 +01:00
UsrDat->Accepted ? "DAT_N" :
"DAT",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2014-12-01 23:55:08 +01:00
NumStd + 1);
/***** Show student's photo *****/
if (Gbl.Usrs.Listing.WithPhotos)
{
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE COLOR%u\""
2015-09-28 18:28:29 +02:00
" style=\"width:22px;\">",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd);
2017-01-28 15:58:46 +01:00
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (UsrDat,PhotoURL);
2014-12-30 15:14:43 +01:00
Pho_ShowUsrPhoto (UsrDat,ShowPhoto ? PhotoURL :
NULL,
2016-01-14 10:31:09 +01:00
"PHOTO21x28",Pho_ZOOM,false);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</td>");
}
/***** Write user's ID ******/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"%s LEFT_MIDDLE COLOR%u\">",
2014-12-01 23:55:08 +01:00
UsrDat->Accepted ? "DAT_SMALL_N" :
2014-12-22 14:08:19 +01:00
"DAT_SMALL",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd);
2017-05-09 20:56:02 +02:00
ID_WriteUsrIDs (UsrDat,NULL);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</td>");
/***** Write student's name *****/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"%s LEFT_MIDDLE COLOR%u\">"
2014-12-22 14:08:19 +01:00
"%s",
2014-12-01 23:55:08 +01:00
UsrDat->Accepted ? "DAT_SMALL_N" :
"DAT_SMALL",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2014-12-01 23:55:08 +01:00
UsrDat->Surname1);
if (UsrDat->Surname2[0])
fprintf (Gbl.F.Out," %s",UsrDat->Surname2);
fprintf (Gbl.F.Out,", %s</td>",
UsrDat->FirstName);
2019-02-13 21:24:54 +01:00
/***** Check/cross to show if the user is present/absent *****/
2014-12-01 23:55:08 +01:00
for (NumAttEvent = 0, NumTimesPresent = 0;
NumAttEvent < Gbl.AttEvents.Num;
NumAttEvent++)
2014-12-08 01:30:47 +01:00
if (Gbl.AttEvents.Lst[NumAttEvent].Selected)
2014-12-01 23:55:08 +01:00
{
2019-02-13 21:24:54 +01:00
/* Check if this student is already registered in the current event */
2014-12-01 23:55:08 +01:00
// Here it is not necessary to get comments
2019-02-13 21:24:54 +01:00
Present = Att_CheckIfUsrIsPresentInAttEvent (Gbl.AttEvents.Lst[NumAttEvent].AttCod,
UsrDat->UsrCod);
/* Write check or cross */
fprintf (Gbl.F.Out,"<td class=\"BM%u\">",
Gbl.RowEvenOdd);
Att_PutCheckOrCross (Present);
fprintf (Gbl.F.Out,"</td>");
2014-12-01 23:55:08 +01:00
if (Present)
NumTimesPresent++;
}
/***** Last column with the number of times this user is present *****/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"DAT_N RIGHT_MIDDLE COLOR%u\">"
2014-12-22 14:08:19 +01:00
"%u"
"</td>"
2014-12-01 23:55:08 +01:00
"</tr>",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2014-12-22 14:08:19 +01:00
NumTimesPresent);
2014-12-01 23:55:08 +01:00
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
}
2014-12-06 02:21:34 +01:00
2019-02-13 21:24:54 +01:00
/*****************************************************************************/
/*********************** Put check or cross character ************************/
/*****************************************************************************/
static void Att_PutCheckOrCross (bool Present)
{
extern const char *Txt_Present;
extern const char *Txt_Absent;
fprintf (Gbl.F.Out,"<div class=\"");
if (Present)
fprintf (Gbl.F.Out,"ATT_CHECK\" title=\"%s\">"
"&check;",
Txt_Present);
else
fprintf (Gbl.F.Out,"ATT_CROSS\" title=\"%s\">"
"&cross;",
Txt_Absent);
fprintf (Gbl.F.Out,"</div>");
}
2014-12-06 02:21:34 +01:00
/*****************************************************************************/
/**************** List the students with details and comments ****************/
/*****************************************************************************/
2018-10-18 09:59:38 +02:00
static void Att_ListStdsWithAttEventsDetails (unsigned NumStdsInList,
2016-11-27 23:08:29 +01:00
long *LstSelectedUsrCods)
2014-12-06 02:21:34 +01:00
{
extern const char *Txt_Details;
struct UsrData UsrDat;
unsigned NumStd;
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2018-10-18 16:56:07 +02:00
/***** Start section with attendance details *****/
Lay_StartSection (Att_ATTENDANCE_DETAILS_ID);
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2017-06-10 21:38:10 +02:00
Box_StartBoxTable (NULL,Txt_Details,NULL,
2018-10-18 09:59:38 +02:00
NULL,Box_NOT_CLOSABLE,2);
2014-12-06 02:21:34 +01:00
/***** List students with attendance details *****/
2014-12-07 02:04:30 +01:00
for (NumStd = 0, Gbl.RowEvenOdd = 0;
2014-12-06 02:21:34 +01:00
NumStd < NumStdsInList;
NumStd++)
{
UsrDat.UsrCod = LstSelectedUsrCods[NumStd];
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS)) // Get from the database the data of the student
2017-10-05 22:29:33 +02:00
if (Usr_CheckIfICanViewAtt (&UsrDat))
2017-06-09 15:04:02 +02:00
{
UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat);
Att_ListAttEventsForAStd (NumStd,&UsrDat);
}
2014-12-06 02:21:34 +01:00
}
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2017-06-10 21:38:10 +02:00
Box_EndBoxTable ();
2014-12-06 02:21:34 +01:00
2018-10-18 16:56:07 +02:00
/***** End section with attendance details *****/
Lay_EndSection ();
2014-12-06 02:21:34 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
/*****************************************************************************/
/*************** Write list of attendance events for a student ***************/
/*****************************************************************************/
static void Att_ListAttEventsForAStd (unsigned NumStd,struct UsrData *UsrDat)
{
2015-12-29 11:35:01 +01:00
extern const char *Txt_Today;
2014-12-06 02:21:34 +01:00
extern const char *Txt_Student_comment;
extern const char *Txt_Teachers_comment;
2017-01-28 15:58:46 +01:00
char PhotoURL[PATH_MAX + 1];
2014-12-06 02:21:34 +01:00
bool ShowPhoto;
unsigned NumAttEvent;
2015-10-24 20:46:11 +02:00
unsigned UniqueId;
2014-12-06 02:21:34 +01:00
bool Present;
2015-11-13 01:27:44 +01:00
bool ShowCommentStd;
bool ShowCommentTch;
2017-01-17 03:10:43 +01:00
char CommentStd[Cns_MAX_BYTES_TEXT + 1];
char CommentTch[Cns_MAX_BYTES_TEXT + 1];
2014-12-06 02:21:34 +01:00
/***** Write number of student in the list *****/
2019-02-14 00:33:51 +01:00
NumStd++;
2014-12-06 02:21:34 +01:00
fprintf (Gbl.F.Out,"<tr>"
2015-09-03 00:59:03 +02:00
"<td class=\"%s RIGHT_MIDDLE COLOR%u\">"
2014-12-22 14:08:19 +01:00
"%u:"
"</td>",
2019-02-14 00:33:51 +01:00
UsrDat->Accepted ? "DAT_N" :
"DAT",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2019-02-14 00:33:51 +01:00
NumStd);
2014-12-06 02:21:34 +01:00
/***** Show student's photo *****/
2019-02-14 00:33:51 +01:00
fprintf (Gbl.F.Out,"<td colspan=\"2\" class=\"RIGHT_MIDDLE COLOR%u\">",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd);
2017-01-28 15:58:46 +01:00
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (UsrDat,PhotoURL);
2014-12-30 15:14:43 +01:00
Pho_ShowUsrPhoto (UsrDat,ShowPhoto ? PhotoURL :
NULL,
2016-01-14 10:31:09 +01:00
"PHOTO21x28",Pho_ZOOM,false);
2014-12-06 02:21:34 +01:00
fprintf (Gbl.F.Out,"</td>");
/***** Write user's ID ******/
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE COLOR%u\">"
2014-12-06 02:21:34 +01:00
"<table>"
"<tr>"
2015-07-28 00:51:32 +02:00
"<td class=\"%s LEFT_MIDDLE\">",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
2019-02-14 00:33:51 +01:00
UsrDat->Accepted ? "DAT_N" :
"DAT");
2017-05-09 20:56:02 +02:00
ID_WriteUsrIDs (UsrDat,NULL);
2014-12-06 02:21:34 +01:00
fprintf (Gbl.F.Out,"</td>");
/***** Write student's name *****/
2015-07-28 00:51:32 +02:00
fprintf (Gbl.F.Out,"<td class=\"%s LEFT_MIDDLE\">%s",
2014-12-06 02:21:34 +01:00
UsrDat->Accepted ? "DAT_SMALL_N" :
"DAT_SMALL",
UsrDat->Surname1);
if (UsrDat->Surname2[0])
fprintf (Gbl.F.Out," %s",UsrDat->Surname2);
fprintf (Gbl.F.Out,", %s</td>"
"</tr>"
"</table>"
"</td>"
"</tr>",
UsrDat->FirstName);
/***** List the events with students *****/
2015-10-24 20:46:11 +02:00
for (NumAttEvent = 0, UniqueId = 1;
2014-12-06 02:21:34 +01:00
NumAttEvent < Gbl.AttEvents.Num;
2015-10-24 20:46:11 +02:00
NumAttEvent++, UniqueId++)
2014-12-07 02:04:30 +01:00
if (Gbl.AttEvents.Lst[NumAttEvent].Selected)
2014-12-06 02:21:34 +01:00
{
/***** Get data of the attendance event from database *****/
Att_GetDataOfAttEventByCodAndCheckCrs (&Gbl.AttEvents.Lst[NumAttEvent]);
Att_GetNumStdsTotalWhoAreInAttEvent (&Gbl.AttEvents.Lst[NumAttEvent]);
/***** Get comments for this student *****/
Present = Att_CheckIfUsrIsPresentInAttEventAndGetComments (Gbl.AttEvents.Lst[NumAttEvent].AttCod,UsrDat->UsrCod,CommentStd,CommentTch);
2015-11-13 01:27:44 +01:00
ShowCommentStd = CommentStd[0];
ShowCommentTch = CommentTch[0] &&
2017-06-04 18:18:54 +02:00
(Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
2015-11-13 01:27:44 +01:00
Gbl.AttEvents.Lst[NumAttEvent].CommentTchVisible);
2014-12-06 02:21:34 +01:00
/***** Write a row for this event *****/
fprintf (Gbl.F.Out,"<tr>"
2015-09-03 00:59:03 +02:00
"<td class=\"COLOR%u\"></td>"
2019-02-14 00:33:51 +01:00
"<td class=\"%s RIGHT_TOP COLOR%u\">"
2014-12-22 14:08:19 +01:00
"%u:"
"</td>"
2019-02-14 00:33:51 +01:00
"<td class=\"BT%u\">",
2019-02-13 21:24:54 +01:00
Gbl.RowEvenOdd,
2019-02-14 00:33:51 +01:00
Present ? "DAT_GREEN" :
"DAT_RED",
2019-02-13 21:24:54 +01:00
Gbl.RowEvenOdd,
NumAttEvent + 1,
Gbl.RowEvenOdd);
Att_PutCheckOrCross (Present);
2019-02-14 00:33:51 +01:00
fprintf (Gbl.F.Out,"</td>"
"<td class=\"DAT LEFT_TOP COLOR%u\">"
"<span id=\"att_date_start_%u_%u\"></span>"
"<br />%s"
2015-10-23 13:20:42 +02:00
"<script type=\"text/javascript\">"
2019-02-14 00:33:51 +01:00
"writeLocalDateHMSFromUTC('att_date_start_%u_%u',%ld,"
2017-05-05 09:41:56 +02:00
"%u,',&nbsp;','%s',true,true,0x7);"
2015-10-23 13:20:42 +02:00
"</script>"
"</td>"
2014-12-06 02:21:34 +01:00
"</tr>",
2019-02-14 00:33:51 +01:00
Gbl.RowEvenOdd,
NumStd,UniqueId,
2015-10-23 13:20:42 +02:00
Gbl.AttEvents.Lst[NumAttEvent].Title,
2019-02-14 00:33:51 +01:00
NumStd,UniqueId,
Gbl.AttEvents.Lst[NumAttEvent].TimeUTC[Att_START_TIME],
2017-05-04 17:06:26 +02:00
(unsigned) Gbl.Prefs.DateFormat,Txt_Today);
2014-12-06 02:21:34 +01:00
/***** Write comments for this student *****/
2015-11-13 01:27:44 +01:00
if (ShowCommentStd || ShowCommentTch)
2014-12-06 02:21:34 +01:00
{
fprintf (Gbl.F.Out,"<tr>"
2015-09-03 00:59:03 +02:00
"<td class=\"COLOR%u\"></td>"
"<td class=\"COLOR%u\"></td>"
2019-02-14 00:33:51 +01:00
"<td class=\"BT%u\"></td>"
2015-09-03 00:59:03 +02:00
"<td class=\"DAT LEFT_MIDDLE COLOR%u\">"
2014-12-06 02:21:34 +01:00
"<dl>",
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd,
Gbl.RowEvenOdd,
2019-02-14 00:33:51 +01:00
Gbl.RowEvenOdd,
2015-09-03 00:59:03 +02:00
Gbl.RowEvenOdd);
2015-11-13 01:27:44 +01:00
if (ShowCommentStd)
2014-12-06 02:21:34 +01:00
{
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
CommentStd,Cns_MAX_BYTES_TEXT,false);
fprintf (Gbl.F.Out,"<dt>%s:</dt><dd>%s</dd>",
Txt_Student_comment,
CommentStd);
}
2015-11-13 01:27:44 +01:00
if (ShowCommentTch)
2014-12-06 02:21:34 +01:00
{
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
CommentTch,Cns_MAX_BYTES_TEXT,false);
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<dt>%s:</dt>"
"<dd>%s</dd>",
2014-12-06 02:21:34 +01:00
Txt_Teachers_comment,
CommentTch);
}
fprintf (Gbl.F.Out,"</dl>"
"</td>"
"</tr>");
}
}
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
}