Version19.222

This commit is contained in:
acanas 2020-05-10 01:42:30 +02:00
parent 8427c5d8e6
commit 9e79ced203
6 changed files with 158 additions and 34 deletions

View File

@ -548,10 +548,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD: En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 19.221 (2020-05-09)" #define Log_PLATFORM_VERSION "SWAD 19.222 (2020-05-10)"
#define CSS_FILE "swad19.217.css" #define CSS_FILE "swad19.217.css"
#define JS_FILE "swad19.193.1.js" #define JS_FILE "swad19.193.1.js"
/* /*
Version 19.222: May 10, 2020 Changes in exam prints. (302787 lines)
Version 19.221: May 09, 2020 Changes in exam prints. (302686 lines) Version 19.221: May 09, 2020 Changes in exam prints. (302686 lines)
Version 19.220: May 09, 2020 Changes in exam prints. (302480 lines) Version 19.220: May 09, 2020 Changes in exam prints. (302480 lines)
1 change necessary in database: 1 change necessary in database:

View File

@ -61,6 +61,8 @@ extern struct Globals Gbl;
struct ExaPrn_Print struct ExaPrn_Print
{ {
long PrnCod; // Exam print code long PrnCod; // Exam print code
long EvtCod; // Event code associated to this print
long UsrCod; // User who answered the exam print
time_t TimeUTC[Dat_NUM_START_END_TIME]; time_t TimeUTC[Dat_NUM_START_END_TIME];
unsigned NumQsts; // Number of questions unsigned NumQsts; // Number of questions
unsigned NumQstsNotBlank; // Number of questions not blank unsigned NumQstsNotBlank; // Number of questions not blank
@ -83,9 +85,9 @@ struct ExaPrn_Print
/*****************************************************************************/ /*****************************************************************************/
static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print); static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print);
static void ExaPrn_ResetPrintExceptPrnCod (struct ExaPrn_Print *Print); static void ExaPrn_ResetPrintExceptEvtCodAndUsrCod (struct ExaPrn_Print *Print);
static bool ExaPrn_CheckIfMyPrintExists (const struct ExaEvt_Event *Event); static void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print);
static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam, static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam,
struct ExaPrn_Print *Print); struct ExaPrn_Print *Print);
static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print, static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print,
@ -97,6 +99,9 @@ static void ExaPrn_ComputeScoresAndStoreQuestionsOfPrint (struct ExaPrn_Print *P
bool UpdateQstScore); bool UpdateQstScore);
static void ExaPrn_StoreOneQstOfPrintInDB (const struct ExaPrn_Print *Print, static void ExaPrn_StoreOneQstOfPrintInDB (const struct ExaPrn_Print *Print,
unsigned NumQst); unsigned NumQst);
static void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print);
static void ExaPrn_ShowExamPrintToFillIt (struct Exa_Exam *Exam, static void ExaPrn_ShowExamPrintToFillIt (struct Exa_Exam *Exam,
struct ExaPrn_Print *Print); struct ExaPrn_Print *Print);
static void ExaPrn_WriteQstAndAnsToFill (const struct Exa_Exam *Exam, static void ExaPrn_WriteQstAndAnsToFill (const struct Exa_Exam *Exam,
@ -127,12 +132,14 @@ static void ExaPrn_PutParamPrnCod (long ExaCod);
static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print) static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print)
{ {
Print->PrnCod = -1L; Print->EvtCod = -1L;
ExaPrn_ResetPrintExceptPrnCod (Print); Print->UsrCod = -1L;
ExaPrn_ResetPrintExceptEvtCodAndUsrCod (Print);
} }
static void ExaPrn_ResetPrintExceptPrnCod (struct ExaPrn_Print *Print) static void ExaPrn_ResetPrintExceptEvtCodAndUsrCod (struct ExaPrn_Print *Print)
{ {
Print->PrnCod = -1L;
Print->TimeUTC[Dat_START_TIME] = Print->TimeUTC[Dat_START_TIME] =
Print->TimeUTC[Dat_END_TIME ] = (time_t) 0; Print->TimeUTC[Dat_END_TIME ] = (time_t) 0;
Print->NumQsts = Print->NumQsts =
@ -151,7 +158,6 @@ void ExaPrn_ShowExamPrint (void)
struct Exa_Exam Exam; struct Exa_Exam Exam;
struct ExaEvt_Event Event; struct ExaEvt_Event Event;
struct ExaPrn_Print Print; struct ExaPrn_Print Print;
bool PrintExists;
/***** Reset exams context *****/ /***** Reset exams context *****/
Exa_ResetExams (&Exams); Exa_ResetExams (&Exams);
@ -162,12 +168,17 @@ void ExaPrn_ShowExamPrint (void)
/***** Get and check parameters *****/ /***** Get and check parameters *****/
ExaEvt_GetAndCheckParameters (&Exams,&Exam,&Event); ExaEvt_GetAndCheckParameters (&Exams,&Exam,&Event);
/***** Check if already exists exam in database *****/ /***** Get print data from database *****/
PrintExists = ExaPrn_CheckIfMyPrintExists (&Event); Print.EvtCod = Event.EvtCod;
Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
ExaPrn_GetPrintDataByEvtCodAndUsrCod (&Print);
if (PrintExists) if (Print.PrnCod > 0) // Print exists
{ {
Ale_ShowAlert (Ale_INFO,"El examen ya existe."); Ale_ShowAlert (Ale_INFO,"El examen ya existe.");
/***** Get questions and answers from database *****/
ExaPrn_GetPrintQuestionsFromDB (&Print);
} }
else else
{ {
@ -188,16 +199,58 @@ void ExaPrn_ShowExamPrint (void)
} }
/*****************************************************************************/ /*****************************************************************************/
/********* Check if my exam print associated to a given event exists *********/ /********* Get data of an exam print using event code and user code **********/
/*****************************************************************************/ /*****************************************************************************/
// Return true if print exists
static bool ExaPrn_CheckIfMyPrintExists (const struct ExaEvt_Event *Event) static void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print)
{ {
return (DB_QueryCOUNT ("can not check if exam print exists", MYSQL_RES *mysql_res;
"SELECT COUNT(*) FROM exa_prints" MYSQL_ROW row;
" WHERE EvtCod=%ld AND UsrCod=%ld",
Event->EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); /***** Make database query *****/
if (DB_QuerySELECT (&mysql_res,"can not get data of an exam print",
"SELECT PrnCod," // row[0]
"UNIX_TIMESTAMP(StartTime)," // row[1]
"UNIX_TIMESTAMP(EndTime)," // row[2]
"NumQsts," // row[3]
"NumQstsNotBlank," // row[4]
"Sent," // row[5]
"Score" // row[6]
" FROM exa_prints"
" WHERE EvtCod=%ld AND UsrCod=%ld",
Print->EvtCod,Print->UsrCod) == 1)
{
row = mysql_fetch_row (mysql_res);
/* Get print code (row[0]) */
Print->PrnCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get date-time (row[1] and row[2] hold UTC date-time) */
Print->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]);
Print->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]);
/* Get number of questions (row[3]) */
if (sscanf (row[3],"%u",&Print->NumQsts) != 1)
Print->NumQsts = 0;
/* Get number of questions not blank (row[4]) */
if (sscanf (row[4],"%u",&Print->NumQstsNotBlank) != 1)
Print->NumQstsNotBlank = 0;
/* Get if exam has been sent (row[5]) */
Print->Sent = (row[5][0] == 'Y');
/* Get score (row[6]) */
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
if (sscanf (row[6],"%lf",&Print->Score) != 1)
Print->Score = 0.0;
Str_SetDecimalPointToLocal (); // Return to local system
}
else
ExaPrn_ResetPrintExceptEvtCodAndUsrCod (Print);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -444,6 +497,78 @@ static void ExaPrn_StoreOneQstOfPrintInDB (const struct ExaPrn_Print *Print,
Str_SetDecimalPointToLocal (); // Return to local system Str_SetDecimalPointToLocal (); // Return to local system
} }
/*****************************************************************************/
/************* Get the questions of an exam print from database **************/
/*****************************************************************************/
static void ExaPrn_GetPrintQuestionsFromDB (struct ExaPrn_Print *Print)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumQsts;
unsigned NumQst;
Tst_AnswerType_t AnswerType;
/***** Get questions of an exam print from database *****/
NumQsts =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get questions"
" of an exam print",
"SELECT exa_print_questions.QstCod," // row[0]
"exa_print_questions.SetCod," // row[1]
"tst_questions.AnsType," // row[2]
"exa_print_questions.Indexes," // row[3]
"exa_print_questions.Answers" // row[4]
" FROM exa_print_questions,tst_questions"
" WHERE exa_print_questions.PrnCod=%ld"
" AND exa_print_questions.QstCod=tst_questions.QstCod"
" ORDER BY exa_print_questions.QstInd",
Print->PrnCod);
/***** Get questions *****/
// The number of questions in table of print questions
// should match the number of questions got from print
if (NumQsts == Print->NumQsts)
for (NumQst = 0;
NumQst < NumQsts;
NumQst++)
{
row = mysql_fetch_row (mysql_res);
/* Get question code (row[0]) */
if ((Print->PrintedQuestions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get set code (row[1]) */
if ((Print->PrintedQuestions[NumQst].SetCod = Str_ConvertStrCodToLongCod (row[1])) < 0)
Lay_ShowErrorAndExit ("Wrong code of set.");
/* Get answer type (row[2]) */
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]);
/* Get indexes for this question (row[3]) */
Str_Copy (Print->PrintedQuestions[NumQst].StrIndexes,row[3],
Tst_MAX_BYTES_INDEXES_ONE_QST);
/* Get answers selected by user for this question (row[4]) */
Str_Copy (Print->PrintedQuestions[NumQst].StrAnswers,row[4],
Tst_MAX_BYTES_ANSWERS_ONE_QST);
/* Replace each comma by a separator of multiple parameters */
/* In database commas are used as separators instead of special chars */
Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrIndexes);
if (AnswerType == Tst_ANS_MULTIPLE_CHOICE)
// Only multiple choice questions have multiple answers separated by commas
// Other types of questions have a unique answer, and comma may be part of that answer
Par_ReplaceCommaBySeparatorMultiple (Print->PrintedQuestions[NumQst].StrAnswers);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
if (NumQsts != Print->NumQsts)
Lay_WrongExamExit ();
}
/*****************************************************************************/ /*****************************************************************************/
/****************** Show a test exam print to be answered ********************/ /****************** Show a test exam print to be answered ********************/
/*****************************************************************************/ /*****************************************************************************/

View File

@ -269,8 +269,6 @@ static void ExaSet_PutFormNewSet (struct Exa_Exams *Exams,
struct ExaSet_Set *Set, struct ExaSet_Set *Set,
unsigned MaxSetInd) unsigned MaxSetInd)
{ {
// extern const char *Hlp_ASSESSMENT_Exams_new_set;
// extern const char *Hlp_ASSESSMENT_Exams_edit_set;
extern const char *Txt_New_set_of_questions; extern const char *Txt_New_set_of_questions;
extern const char *Txt_Create_set_of_questions; extern const char *Txt_Create_set_of_questions;

View File

@ -533,8 +533,8 @@ void Tst_ReceiveTestDraft (void)
/* Get number of this test from form */ /* Get number of this test from form */
NumTst = Tst_GetParamNumTst (); NumTst = Tst_GetParamNumTst ();
/***** Get test exam from database *****/ /***** Get test exam print from database *****/
TstPrn_GetExamDataByExaCod (&Print); TstPrn_GetPrintDataByPrnCod (&Print);
/****** Get test status in database for this session-course-num.test *****/ /****** Get test status in database for this session-course-num.test *****/
if (Print.Sent) if (Print.Sent)
@ -542,8 +542,8 @@ void Tst_ReceiveTestDraft (void)
NumTst); NumTst);
else // Print not yet sent else // Print not yet sent
{ {
/***** Get test exam questions from database *****/ /***** Get test exam print questions from database *****/
TstPrn_GetExamQuestionsFromDB (&Print); TstPrn_GetPrintQuestionsFromDB (&Print);
/***** Get answers from form to assess a test *****/ /***** Get answers from form to assess a test *****/
Tst_GetAnswersFromForm (&Print); Tst_GetAnswersFromForm (&Print);
@ -590,7 +590,7 @@ void Tst_AssessTest (void)
NumTst = Tst_GetParamNumTst (); NumTst = Tst_GetParamNumTst ();
/***** Get test exam from database *****/ /***** Get test exam from database *****/
TstPrn_GetExamDataByExaCod (&Print); TstPrn_GetPrintDataByPrnCod (&Print);
/****** Get test status in database for this session-course-num.test *****/ /****** Get test status in database for this session-course-num.test *****/
if (Print.Sent) if (Print.Sent)
@ -599,7 +599,7 @@ void Tst_AssessTest (void)
else // Print not yet sent else // Print not yet sent
{ {
/***** Get test exam questions from database *****/ /***** Get test exam questions from database *****/
TstPrn_GetExamQuestionsFromDB (&Print); TstPrn_GetPrintQuestionsFromDB (&Print);
/***** Get answers from form to assess a test *****/ /***** Get answers from form to assess a test *****/
Tst_GetAnswersFromForm (&Print); Tst_GetAnswersFromForm (&Print);

View File

@ -1926,7 +1926,7 @@ void TstPrn_ShowOneExam (void)
Lay_ShowErrorAndExit ("Code of test is missing."); Lay_ShowErrorAndExit ("Code of test is missing.");
/***** Get test exam data *****/ /***** Get test exam data *****/
TstPrn_GetExamDataByExaCod (&Print); TstPrn_GetPrintDataByPrnCod (&Print);
TstCfg_SetConfigVisibility (TstVis_MAX_VISIBILITY); TstCfg_SetConfigVisibility (TstVis_MAX_VISIBILITY);
/***** Check if I can view this test exam *****/ /***** Check if I can view this test exam *****/
@ -1977,7 +1977,7 @@ void TstPrn_ShowOneExam (void)
if (ICanViewTest) // I am allowed to view this test exam if (ICanViewTest) // I am allowed to view this test exam
{ {
/***** Get questions and user's answers of the test exam from database *****/ /***** Get questions and user's answers of the test exam from database *****/
TstPrn_GetExamQuestionsFromDB (&Print); TstPrn_GetPrintQuestionsFromDB (&Print);
/***** Begin box *****/ /***** Begin box *****/
Box_BoxBegin (NULL,Txt_Test_result, Box_BoxBegin (NULL,Txt_Test_result,
@ -2200,7 +2200,7 @@ void TstPrn_ShowExamAnswers (struct UsrData *UsrDat,
/************ Get data of a test exam using its test exam code ***************/ /************ Get data of a test exam using its test exam code ***************/
/*****************************************************************************/ /*****************************************************************************/
void TstPrn_GetExamDataByExaCod (struct TstPrn_Print *Print) void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -2257,10 +2257,10 @@ void TstPrn_GetExamDataByExaCod (struct TstPrn_Print *Print)
} }
/*****************************************************************************/ /*****************************************************************************/
/************* Get the questions of a test exam from database ****************/ /*********** Get the questions of a test exam print from database ************/
/*****************************************************************************/ /*****************************************************************************/
void TstPrn_GetExamQuestionsFromDB (struct TstPrn_Print *Print) void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -2268,7 +2268,7 @@ void TstPrn_GetExamQuestionsFromDB (struct TstPrn_Print *Print)
unsigned NumQst; unsigned NumQst;
Tst_AnswerType_t AnswerType; Tst_AnswerType_t AnswerType;
/***** Get questions of a test exam from database *****/ /***** Get questions of a test exam print from database *****/
NumQsts = NumQsts =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get questions" (unsigned) DB_QuerySELECT (&mysql_res,"can not get questions"
" of a test exam", " of a test exam",
@ -2282,7 +2282,7 @@ void TstPrn_GetExamQuestionsFromDB (struct TstPrn_Print *Print)
" ORDER BY tst_exam_questions.QstInd", " ORDER BY tst_exam_questions.QstInd",
Print->PrnCod); Print->PrnCod);
/***** List questions *****/ /***** Get questions *****/
// The number of questions in table of exam questions // The number of questions in table of exam questions
// should match the number of questions got from exam // should match the number of questions got from exam
if (NumQsts == Print->NumQsts) if (NumQsts == Print->NumQsts)

View File

@ -99,9 +99,9 @@ void TstPrn_ShowOneExam (void);
void TstPrn_ShowExamAnswers (struct UsrData *UsrDat, void TstPrn_ShowExamAnswers (struct UsrData *UsrDat,
struct TstPrn_Print *Print, struct TstPrn_Print *Print,
unsigned Visibility); unsigned Visibility);
void TstPrn_GetExamDataByExaCod (struct TstPrn_Print *Print); void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print);
void TstPrn_GetExamQuestionsFromDB (struct TstPrn_Print *Print); void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print);
void TstPrn_RemoveExamsMadeByUsrInAllCrss (long UsrCod); void TstPrn_RemoveExamsMadeByUsrInAllCrss (long UsrCod);
void TstPrn_RemoveExamsMadeByUsrInCrs (long UsrCod,long CrsCod); void TstPrn_RemoveExamsMadeByUsrInCrs (long UsrCod,long CrsCod);
void TstPrn_RemoveCrsExams (long CrsCod); void TstPrn_RemoveCrsExams (long CrsCod);