Version 21.0.1: Sep 13, 2021 Queries moved to module swad_follow_database.

This commit is contained in:
acanas 2021-09-13 23:11:15 +02:00
parent 719df886c8
commit 304d2c1275
10 changed files with 422 additions and 413 deletions

View File

@ -602,13 +602,15 @@ TODO: FIX BUG, URGENT! En las fechas como par
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
*/
#define Log_PLATFORM_VERSION "SWAD 20.100.5 (2021-09-12)"
#define Log_PLATFORM_VERSION "SWAD 21.0.1 (2021-09-13)"
#define CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.69.1.js"
/*
TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
Version 21.0.1: Sep 13, 2021 Queries moved to module swad_follow_database. (314910 lines)
Version 21.0: Sep 13, 2021 Fixed bug in degrees photo. (314914 lines)
Version 20.100.5: Sep 12, 2021 Fixed bug removing all students in a course. Reported by José Luis Bernier Villamor and Francisco J. Pelayo Valle. (314909 lines)
Version 20.100.4: Sep 11, 2021 Queries moved to module swad_timeline_database. (314934 lines)
Version 20.100.3: Sep 11, 2021 Queries moved to module swad_file_browser. (314923 lines)

View File

@ -472,7 +472,7 @@ void CrsCfg_ChangeCrsDeg (void)
struct Deg_Degree NewDeg;
/***** Get parameter with degree code *****/
NewDeg.DegCod = Deg_GetAndCheckParamOtherDegCod (1);
NewDeg.DegCod = Deg_GetAndCheckParamOtherDegCod (1L);
/***** Check if degree has changed *****/
if (NewDeg.DegCod != Gbl.Hierarchy.Crs.DegCod)

View File

@ -1194,7 +1194,7 @@ void Deg_RemoveDegree (void)
Deg_EditingDegreeConstructor ();
/***** Get degree code *****/
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1);
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L);
/***** Get data of degree *****/
Deg_GetDataOfDegreeByCod (Deg_EditingDeg);
@ -1387,7 +1387,7 @@ void Deg_RenameDegreeShort (void)
Deg_EditingDegreeConstructor ();
/***** Rename degree *****/
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1);
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L);
Deg_RenameDegree (Deg_EditingDeg,Cns_SHRT_NAME);
}
@ -1397,7 +1397,7 @@ void Deg_RenameDegreeFull (void)
Deg_EditingDegreeConstructor ();
/***** Rename degree *****/
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1);
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L);
Deg_RenameDegree (Deg_EditingDeg,Cns_FULL_NAME);
}
@ -1488,7 +1488,7 @@ void Deg_ChangeDegreeType (void)
/***** Get parameters from form *****/
/* Get degree code */
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1);
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L);
/* Get the new degree type */
NewDegTypCod = DegTyp_GetAndCheckParamOtherDegTypCod (1);
@ -1521,7 +1521,7 @@ void Deg_ChangeDegWWW (void)
/***** Get parameters from form *****/
/* Get the code of the degree */
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1);
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L);
/* Get the new WWW for the degree */
Par_GetParToText ("WWW",NewWWW,Cns_MAX_BYTES_WWW);
@ -1561,7 +1561,7 @@ void Deg_ChangeDegStatus (void)
/***** Get parameters from form *****/
/* Get degree code */
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1);
Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L);
/* Get parameter with status */
Status = (Deg_Status_t)

View File

@ -41,6 +41,7 @@
#include "swad_figure_cache.h"
#include "swad_file_browser.h"
#include "swad_follow.h"
#include "swad_follow_database.h"
#include "swad_form.h"
#include "swad_forum.h"
#include "swad_global.h"
@ -2380,11 +2381,6 @@ static void Fig_GetAndShowFollowStats (void)
extern const char *Txt_Followed;
extern const char *Txt_Followers;
extern const char *Txt_FollowPerFollow[2];
static const char *FieldDB[2] =
{
"FollowedCod",
"FollowerCod"
};
unsigned Fol;
unsigned NumUsrsTotal;
unsigned NumUsrs;
@ -2410,100 +2406,7 @@ static void Fig_GetAndShowFollowStats (void)
Fol < 2;
Fol++)
{
switch (Gbl.Scope.Current)
{
case HieLvl_SYS:
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT %s)"
" FROM usr_follow",
FieldDB[Fol]);
break;
case HieLvl_CTY:
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM ins_instits,"
"ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Cty.CtyCod,
FieldDB[Fol]);
break;
case HieLvl_INS:
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ctr_centers.InsCod=%ld"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Ins.InsCod,
FieldDB[Fol]);
break;
case HieLvl_CTR:
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE deg_degrees.CtrCod=%ld"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Ctr.CtrCod,
FieldDB[Fol]);
break;
case HieLvl_DEG:
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM crs_courses,"
"crs_users,"
"usr_follow"
" WHERE crs_courses.DegCod=%ld"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Deg.DegCod,
FieldDB[Fol]);
break;
case HieLvl_CRS:
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM crs_users,"
"usr_follow"
" WHERE crs_users.CrsCod=%ld"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Crs.CrsCod,
FieldDB[Fol]);
break;
default:
Err_WrongScopeExit ();
NumUsrs = 0; // Not reached. Initialized to av oid warning
break;
}
NumUsrs = Fol_DB_GetNumFollowinFollowers (Fol);
/***** Write number of followed / followers *****/
HTM_TR_Begin (NULL);
@ -2531,118 +2434,7 @@ static void Fig_GetAndShowFollowStats (void)
Fol < 2;
Fol++)
{
switch (Gbl.Scope.Current)
{
case HieLvl_SYS:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)"
" FROM (SELECT COUNT(%s) AS N"
" FROM usr_follow"
" GROUP BY %s) AS F",
FieldDB[Fol],
FieldDB[1 - Fol]);
break;
case HieLvl_CTY:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM ins_instits,"
"ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Cty.CtyCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
break;
case HieLvl_INS:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ctr_centers.InsCod=%ld"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Ins.InsCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
break;
case HieLvl_CTR:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE deg_degrees.CtrCod=%ld"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Ctr.CtrCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
break;
case HieLvl_DEG:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM crs_courses,"
"crs_users,"
"usr_follow"
" WHERE crs_courses.DegCod=%ld"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Deg.DegCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
break;
case HieLvl_CRS:
Average = DB_QuerySELECTDouble ("can not get number of questions"
" per survey",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM crs_users,"
"usr_follow"
" WHERE crs_users.CrsCod=%ld"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Crs.CrsCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
break;
default:
Err_WrongScopeExit ();
Average = 0.0; // Not reached
break;
}
Average = Fol_DB_GetNumFollowedPerFollower (Fol);
/***** Write number of followed per follower *****/
HTM_TR_Begin (NULL);

View File

@ -80,7 +80,4 @@ void Fol_GetNotifFollower (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1],
void Fol_RemoveUsrFromUsrFollow (long UsrCod);
void Fol_DB_CreateTmpTableMeAndUsrsIFollow (void);
void Fol_DB_DropTmpTableMeAndUsrsIFollow (void);
#endif

View File

@ -40,6 +40,12 @@
/***************************** Private constants *****************************/
/*****************************************************************************/
static const char *FieldDB[2] =
{
"FollowedCod",
"FollowerCod"
};
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
@ -311,6 +317,208 @@ unsigned Fol_DB_GetListFollowers (long UsrCod,MYSQL_RES **mysql_res)
UsrCod);
}
/*****************************************************************************/
/************** Get and show number of following and followers ***************/
/*****************************************************************************/
unsigned Fol_DB_GetNumFollowinFollowers (unsigned Fol)
{
switch (Gbl.Scope.Current)
{
case HieLvl_SYS:
return (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT %s)"
" FROM usr_follow",
FieldDB[Fol]);
case HieLvl_CTY:
return (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM ins_instits,"
"ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Cty.CtyCod,
FieldDB[Fol]);
case HieLvl_INS:
return (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ctr_centers.InsCod=%ld"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Ins.InsCod,
FieldDB[Fol]);
case HieLvl_CTR:
return (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE deg_degrees.CtrCod=%ld"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Ctr.CtrCod,
FieldDB[Fol]);
case HieLvl_DEG:
return (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM crs_courses,"
"crs_users,"
"usr_follow"
" WHERE crs_courses.DegCod=%ld"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Deg.DegCod,
FieldDB[Fol]);
case HieLvl_CRS:
return (unsigned)
DB_QueryCOUNT ("can not get the total number of following/followers",
"SELECT COUNT(DISTINCT usr_follow.%s)"
" FROM crs_users,"
"usr_follow"
" WHERE crs_users.CrsCod=%ld"
" AND crs_users.UsrCod=usr_follow.%s",
FieldDB[Fol],
Gbl.Hierarchy.Crs.CrsCod,
FieldDB[Fol]);
default:
Err_WrongScopeExit ();
return 0; // Not reached
}
}
/*****************************************************************************/
/************** Get and show number of following and followers ***************/
/*****************************************************************************/
double Fol_DB_GetNumFollowedPerFollower (unsigned Fol)
{
switch (Gbl.Scope.Current)
{
case HieLvl_SYS:
return DB_QuerySELECTDouble ("can not get number of followed per follower",
"SELECT AVG(N)"
" FROM (SELECT COUNT(%s) AS N"
" FROM usr_follow"
" GROUP BY %s) AS F",
FieldDB[Fol],
FieldDB[1 - Fol]);
case HieLvl_CTY:
return DB_QuerySELECTDouble ("can not get number of followed per follower",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM ins_instits,"
"ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Cty.CtyCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
case HieLvl_INS:
return DB_QuerySELECTDouble ("can not get number of followed per follower",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM ctr_centers,"
"deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE ctr_centers.InsCod=%ld"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Ins.InsCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
case HieLvl_CTR:
return DB_QuerySELECTDouble ("can not get number of followed per follower",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM deg_degrees,"
"crs_courses,"
"crs_users,"
"usr_follow"
" WHERE deg_degrees.CtrCod=%ld"
" AND deg_degrees.DegCod=crs_courses.DegCod"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Ctr.CtrCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
case HieLvl_DEG:
return DB_QuerySELECTDouble ("can not get number of followed per follower",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM crs_courses,"
"crs_users,"
"usr_follow"
" WHERE crs_courses.DegCod=%ld"
" AND crs_courses.CrsCod=crs_users.CrsCod"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Deg.DegCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
case HieLvl_CRS:
return DB_QuerySELECTDouble ("can not get number of followed per follower",
"SELECT AVG(N)"
" FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N"
" FROM crs_users,"
"usr_follow"
" WHERE crs_users.CrsCod=%ld"
" AND crs_users.UsrCod=usr_follow.%s"
" GROUP BY %s) AS F",
FieldDB[Fol],
Gbl.Hierarchy.Crs.CrsCod,
FieldDB[Fol],
FieldDB[1 - Fol]);
default:
Err_WrongScopeExit ();
return 0.0; // Not reached
}
}
/*****************************************************************************/
/******************************** Follow user ********************************/
/*****************************************************************************/

View File

@ -53,6 +53,9 @@ unsigned Fol_DB_GetNumFollowers (long UsrCod);
unsigned Fol_DB_GetListFollowing (long UsrCod,MYSQL_RES **mysql_res);
unsigned Fol_DB_GetListFollowers (long UsrCod,MYSQL_RES **mysql_res);
unsigned Fol_DB_GetNumFollowinFollowers (unsigned Fol);
double Fol_DB_GetNumFollowedPerFollower (unsigned Fol);
void Fol_DB_FollowUsr (long UsrCod);
void Fol_DB_UnfollowUsr (long UsrCod);

View File

@ -1388,8 +1388,11 @@ void Pho_CalcPhotoDegree (void)
Fil_CreateDirIfNotExists (Cfg_PATH_PHOTO_TMP_PRIVATE);
/***** Get the degree which photo will be computed *****/
DegCod = Deg_GetAndCheckParamOtherDegCod (1);
DegCod = Deg_GetAndCheckParamOtherDegCod (-1L); // Parameter may be omitted
// (when selecting classphoto/list)
if (DegCod > 0)
{
/***** Prevent the computing of an average photo too recently updated *****/
if (Pho_GetTimeAvgPhotoWasComputed (DegCod) >=
Gbl.StartExecutionTimeUTC - Cfg_MIN_TIME_TO_RECOMPUTE_AVG_PHOTO)
@ -1420,6 +1423,7 @@ void Pho_CalcPhotoDegree (void)
/***** Free memory for students list *****/
Usr_FreeUsrsList (Rol_STD);
}
/***** Show photos *****/
Pho_ShowOrPrintPhotoDegree (Pho_DEGREES_SEE);
@ -2134,6 +2138,7 @@ static void Pho_ShowOrPrintClassPhotoDegrees (struct Pho_DegPhotos *DegPhotos,
/***** Form to select type of list used to display degree photos *****/
if (SeeOrPrint == Pho_DEGREES_SEE)
Usr_ShowFormsToSelectUsrListType (Pho_PutParamsDegPhoto,DegPhotos);
HTM_TABLE_BeginCenter ();
/***** Get and print degrees *****/

View File

@ -422,9 +422,11 @@ static void Sta_PutFormCrsHits (struct Sta_Stats *Stats)
HTM_SELECT_End ();
HTM_Txt (")");
HTM_LABEL_End ();
HTM_TD_End ();
HTM_TR_End ();
HTM_TABLE_End ();
/***** Hidden param used to get client time zone *****/