swad-core/swad_degree_type.c

1070 lines
37 KiB
C
Raw Normal View History

2016-03-20 16:30:52 +01:00
// swad_degree_type.c: degree types
/*
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.
2021-02-09 12:43:45 +01:00
Copyright (C) 1999-2021 Antonio Ca<EFBFBD>as Vargas
2016-03-20 16:30:52 +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 <ctype.h> // For isprint, isspace, etc.
#include <stdbool.h> // For boolean type
2019-12-29 12:39:00 +01:00
#include <stddef.h> // For NULL
2016-03-20 16:30:52 +01:00
#include <stdlib.h> // For exit, system, calloc, free, etc.
#include <string.h> // For string functions
#include <mysql/mysql.h> // To access MySQL databases
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2016-03-20 16:30:52 +01:00
#include "swad_config.h"
#include "swad_database.h"
#include "swad_degree.h"
#include "swad_degree_type.h"
#include "swad_error.h"
2020-04-14 17:15:17 +02:00
#include "swad_figure.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2016-03-20 16:30:52 +01:00
#include "swad_global.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
2016-03-20 16:30:52 +01:00
#include "swad_parameter.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
2019-04-08 12:01:08 +02:00
/**************************** Public constants *******************************/
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
/*****************************************************************************/
2019-04-08 12:01:08 +02:00
/****************************** Private types ********************************/
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
/*****************************************************************************/
2019-04-08 12:01:08 +02:00
/**************************** Private variables ******************************/
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
2019-04-08 23:34:58 +02:00
static struct DegreeType *DT_EditingDegTyp = NULL; // Static variable to keep the degree type being edited
2019-04-08 12:01:08 +02:00
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
2019-04-08 12:01:08 +02:00
/*************************** Private prototypes ******************************/
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
2021-02-11 22:57:09 +01:00
static void DT_SeeDegreeTypes (Act_Action_t NextAction,Hie_Lvl_Level_t Scope,
2017-03-24 13:29:52 +01:00
DT_Order_t DefaultOrder);
2017-03-24 13:22:54 +01:00
static DT_Order_t DT_GetParamDegTypOrder (DT_Order_t DefaultOrder);
2017-03-24 01:09:27 +01:00
2020-04-06 23:18:02 +02:00
static void DT_ListDegreeTypes (Act_Action_t NextAction,
2021-02-11 22:57:09 +01:00
Hie_Lvl_Level_t Scope,
2020-04-06 23:18:02 +02:00
DT_Order_t SelectedOrder);
2018-11-15 12:52:56 +01:00
2019-04-08 12:01:08 +02:00
static void DT_EditDegreeTypesInternal (void);
2020-04-08 18:18:46 +02:00
static void DT_PutIconsEditingDegreeTypes (__attribute__((unused)) void *Args);
2018-11-15 12:52:56 +01:00
2016-03-20 22:31:57 +01:00
static void DT_ListDegreeTypesForSeeing (void);
2020-04-08 13:40:21 +02:00
static void DT_PutIconsListingDegTypes (__attribute__((unused)) void *Args);
static void DT_PutIconToEditDegTypes (__attribute__((unused)) void *Args);
2016-03-20 22:31:57 +01:00
static void DT_ListDegreeTypesForEdition (void);
2016-03-20 16:30:52 +01:00
2019-04-08 12:01:08 +02:00
static void DT_PutFormToCreateDegreeType (void);
2020-04-06 23:18:02 +02:00
static void DT_PutHeadDegreeTypesForSeeing (Act_Action_t NextAction,
2021-02-11 22:57:09 +01:00
Hie_Lvl_Level_t Scope,
2020-04-06 23:18:02 +02:00
DT_Order_t SelectedOrder);
2016-03-20 22:31:57 +01:00
static void DT_PutHeadDegreeTypesForEdition (void);
static void DT_CreateDegreeType (struct DegreeType *DegTyp);
2016-03-20 16:30:52 +01:00
2020-10-13 22:34:31 +02:00
static void DT_PutParamOtherDegTypCod (void *DegTypCod);
2016-03-20 16:30:52 +01:00
2016-03-20 22:31:57 +01:00
static unsigned DT_CountNumDegsOfType (long DegTypCod);
static void DT_RemoveDegreeTypeCompletely (long DegTypCod);
static bool DT_CheckIfDegreeTypeNameExists (const char *DegTypName,long DegTypCod);
2016-03-20 16:30:52 +01:00
2019-04-08 12:01:08 +02:00
static void DT_EditingDegreeTypeConstructor (void);
static void DT_EditingDegreeTypeDestructor (void);
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
/************** Show selector of degree types for statistics *****************/
/*****************************************************************************/
2020-04-12 21:33:02 +02:00
void DT_WriteSelectorDegreeTypes (long SelectedDegTypCod)
2016-03-20 16:30:52 +01:00
{
extern const char *Txt_Any_type_of_degree;
unsigned NumDegTyp;
2016-06-09 17:56:57 +02:00
/***** Form to select degree types *****/
/* Get list of degree types */
2021-02-11 22:57:09 +01:00
DT_GetListDegreeTypes (Hie_Lvl_SYS,DT_ORDER_BY_DEGREE_TYPE);
2016-03-20 16:30:52 +01:00
2016-06-09 17:56:57 +02:00
/* List degree types */
2020-04-27 03:16:55 +02:00
HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE,
2019-11-05 15:47:35 +01:00
"id=\"OthDegTypCod\" name=\"OthDegTypCod\"");
2019-11-06 19:45:20 +01:00
HTM_OPTION (HTM_Type_STRING,"-1",
2020-04-12 21:33:02 +02:00
SelectedDegTypCod == -1L,false,
2019-11-06 19:45:20 +01:00
"%s",Txt_Any_type_of_degree);
2016-03-20 16:30:52 +01:00
for (NumDegTyp = 0;
2019-04-04 10:45:15 +02:00
NumDegTyp < Gbl.DegTypes.Num;
2016-03-20 16:30:52 +01:00
NumDegTyp++)
2019-11-06 19:45:20 +01:00
HTM_OPTION (HTM_Type_LONG,&Gbl.DegTypes.Lst[NumDegTyp].DegTypCod,
2020-04-12 21:33:02 +02:00
Gbl.DegTypes.Lst[NumDegTyp].DegTypCod == SelectedDegTypCod,false,
2019-11-06 19:45:20 +01:00
"%s",Gbl.DegTypes.Lst[NumDegTyp].DegTypName);
2019-11-05 08:46:38 +01:00
HTM_SELECT_End ();
2016-03-20 16:30:52 +01:00
/***** Free list of degree types *****/
2016-03-20 22:31:57 +01:00
DT_FreeListDegreeTypes ();
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/***************************** Show degree types *****************************/
/*****************************************************************************/
2017-03-26 17:32:19 +02:00
void DT_SeeDegreeTypesInDegTab (void)
2017-03-24 12:23:42 +01:00
{
2021-02-11 22:57:09 +01:00
DT_SeeDegreeTypes (ActSeeDegTyp,Hie_Lvl_SYS,
2017-03-24 12:23:42 +01:00
DT_ORDER_BY_DEGREE_TYPE); // Default order if not specified
}
void DT_SeeDegreeTypesInStaTab (void)
{
2017-03-24 13:29:52 +01:00
DT_SeeDegreeTypes (ActSeeUseGbl,Gbl.Scope.Current,
2017-03-24 12:23:42 +01:00
DT_ORDER_BY_NUM_DEGREES); // Default order if not specified
}
2021-02-11 22:57:09 +01:00
static void DT_SeeDegreeTypes (Act_Action_t NextAction,Hie_Lvl_Level_t Scope,
2017-03-24 13:29:52 +01:00
DT_Order_t DefaultOrder)
2016-03-20 16:30:52 +01:00
{
2017-03-24 13:22:54 +01:00
DT_Order_t SelectedOrder;
2017-03-24 01:09:27 +01:00
/***** Get parameter with the type of order in the list of degree types *****/
2017-03-24 13:22:54 +01:00
SelectedOrder = DT_GetParamDegTypOrder (DefaultOrder);
2017-03-24 01:09:27 +01:00
2016-03-20 16:30:52 +01:00
/***** Get list of degree types *****/
2017-03-24 13:29:52 +01:00
DT_GetListDegreeTypes (Scope,SelectedOrder);
2016-03-20 16:30:52 +01:00
/***** List degree types *****/
2020-04-06 23:18:02 +02:00
DT_ListDegreeTypes (NextAction,Scope,SelectedOrder);
2016-03-20 16:30:52 +01:00
/***** Free list of degree types *****/
2016-03-20 22:31:57 +01:00
DT_FreeListDegreeTypes ();
2016-03-20 16:30:52 +01:00
}
2017-03-24 01:09:27 +01:00
/*****************************************************************************/
/******* Get parameter with the type or order in list of degree types ********/
/*****************************************************************************/
2017-03-24 13:22:54 +01:00
static DT_Order_t DT_GetParamDegTypOrder (DT_Order_t DefaultOrder)
2017-03-24 01:09:27 +01:00
{
2017-03-24 13:22:54 +01:00
return (DT_Order_t) Par_GetParToUnsignedLong ("Order",
0,
DT_NUM_ORDERS - 1,
(unsigned long) DefaultOrder);
2017-03-24 01:09:27 +01:00
}
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
/***************************** List degree types *****************************/
/*****************************************************************************/
2017-03-24 12:23:42 +01:00
// This function can be called from:
// - center tab => NextAction = ActSeeDegTyp
2017-03-26 17:32:19 +02:00
// - statistic tab => NextAction = ActSeeUseGbl
2016-03-20 16:30:52 +01:00
2020-04-06 23:18:02 +02:00
static void DT_ListDegreeTypes (Act_Action_t NextAction,
2021-02-11 22:57:09 +01:00
Hie_Lvl_Level_t Scope,
2020-04-06 23:18:02 +02:00
DT_Order_t SelectedOrder)
2016-03-20 16:30:52 +01:00
{
extern const char *Hlp_CENTER_DegreeTypes;
2017-12-19 18:41:19 +01:00
extern const char *Hlp_ANALYTICS_Figures_types_of_degree;
2017-03-24 12:23:42 +01:00
extern const char *Txt_Types_of_degree;
2017-04-30 14:03:45 +02:00
extern const char *Txt_No_types_of_degree;
extern const char *Txt_Create_another_type_of_degree;
extern const char *Txt_Create_type_of_degree;
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2017-04-30 14:03:45 +02:00
switch (NextAction)
{
case ActSeeDegTyp:
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_Types_of_degree,
2020-04-08 13:40:21 +02:00
DT_PutIconsListingDegTypes,NULL,
Hlp_CENTER_DegreeTypes,Box_NOT_CLOSABLE);
2017-04-30 14:03:45 +02:00
break;
case ActSeeUseGbl:
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_Types_of_degree,
2020-04-08 13:40:21 +02:00
DT_PutIconToEditDegTypes,NULL,
2017-12-19 18:41:19 +01:00
Hlp_ANALYTICS_Figures_types_of_degree,Box_NOT_CLOSABLE);
2017-04-30 14:03:45 +02:00
break;
default: // Bad call
return;
}
2016-03-20 16:30:52 +01:00
2019-04-04 10:45:15 +02:00
if (Gbl.DegTypes.Num)
2017-03-24 12:23:42 +01:00
{
/***** Write heading *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWideMarginPadding (2);
2020-04-06 23:18:02 +02:00
DT_PutHeadDegreeTypesForSeeing (NextAction,Scope,SelectedOrder);
2017-03-24 12:23:42 +01:00
/***** List current degree types for seeing *****/
2016-03-20 22:31:57 +01:00
DT_ListDegreeTypesForSeeing ();
2017-03-24 12:23:42 +01:00
2017-04-30 14:03:45 +02:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2017-03-24 12:23:42 +01:00
}
2017-04-30 14:03:45 +02:00
else // No degree types created
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_types_of_degree);
2017-04-30 14:03:45 +02:00
/***** Button to create degree type *****/
if (DT_CheckIfICanCreateDegreeTypes ())
{
Frm_BeginForm (ActEdiDegTyp);
2019-04-04 10:45:15 +02:00
Btn_PutConfirmButton (Gbl.DegTypes.Num ? Txt_Create_another_type_of_degree :
2017-04-30 14:03:45 +02:00
Txt_Create_type_of_degree);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-04-30 14:03:45 +02:00
}
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/************************ Put forms to edit degree types *********************/
/*****************************************************************************/
2017-04-30 14:03:45 +02:00
void DT_EditDegreeTypes (void)
2019-04-08 12:01:08 +02:00
{
/***** Degree type constructor *****/
DT_EditingDegreeTypeConstructor ();
/***** Edit degree types *****/
DT_EditDegreeTypesInternal ();
/***** Degree type destructor *****/
DT_EditingDegreeTypeDestructor ();
}
static void DT_EditDegreeTypesInternal (void)
2016-03-20 16:30:52 +01:00
{
extern const char *Hlp_CENTER_DegreeTypes_edit;
2017-04-30 14:03:45 +02:00
extern const char *Txt_Types_of_degree;
/***** Get list of degree types *****/
2021-02-11 22:57:09 +01:00
DT_GetListDegreeTypes (Hie_Lvl_SYS,DT_ORDER_BY_DEGREE_TYPE);
2016-03-20 16:30:52 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_Types_of_degree,
2020-04-08 18:18:46 +02:00
DT_PutIconsEditingDegreeTypes,NULL,
Hlp_CENTER_DegreeTypes_edit,Box_NOT_CLOSABLE);
2016-03-20 16:30:52 +01:00
/***** Put a form to create a new degree type *****/
2016-03-20 22:31:57 +01:00
DT_PutFormToCreateDegreeType ();
2016-03-20 16:30:52 +01:00
/***** Forms to edit current degree types *****/
2019-04-04 10:45:15 +02:00
if (Gbl.DegTypes.Num)
2016-03-20 22:31:57 +01:00
DT_ListDegreeTypesForEdition ();
2017-04-30 14:03:45 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2017-04-30 14:03:45 +02:00
/***** Free list of degree types *****/
DT_FreeListDegreeTypes ();
2016-03-20 16:30:52 +01:00
}
2018-11-15 12:52:56 +01:00
/*****************************************************************************/
/************ Put contextual icons when editing degree types *****************/
/*****************************************************************************/
2020-04-08 18:18:46 +02:00
static void DT_PutIconsEditingDegreeTypes (__attribute__((unused)) void *Args)
2018-11-15 12:52:56 +01:00
{
2020-04-08 18:18:46 +02:00
/***** Put icon to view degree types *****/
DT_PutIconToViewDegreeTypes ();
2018-11-15 12:52:56 +01:00
2020-04-08 18:18:46 +02:00
/***** Put icon to view degrees *****/
Deg_PutIconToViewDegrees ();
2018-11-15 12:52:56 +01:00
2020-04-08 18:18:46 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_DEGREE_TYPES);
2018-11-15 12:52:56 +01:00
}
/*****************************************************************************/
/******************* Put link (form) to view degree types ********************/
/*****************************************************************************/
void DT_PutIconToViewDegreeTypes (void)
{
extern const char *Txt_Types_of_degree;
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkOnlyIcon (ActSeeDegTyp,NULL,
NULL,NULL,
2019-01-12 03:00:59 +01:00
"sitemap.svg",
Txt_Types_of_degree);
2018-11-15 12:52:56 +01:00
}
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
/******************* List current degree types for seeing ********************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
static void DT_ListDegreeTypesForSeeing (void)
2016-03-20 16:30:52 +01:00
{
unsigned NumDegTyp;
const char *BgColor;
/***** List degree types with forms for edition *****/
for (NumDegTyp = 0;
2019-04-04 10:45:15 +02:00
NumDegTyp < Gbl.DegTypes.Num;
2016-03-20 16:30:52 +01:00
NumDegTyp++)
{
2019-04-04 10:45:15 +02:00
BgColor = (Gbl.DegTypes.Lst[NumDegTyp].DegTypCod ==
Gbl.Hierarchy.Deg.DegTypCod) ? "LIGHT_BLUE" :
Gbl.ColorRows[Gbl.RowEvenOdd];
2016-03-20 16:30:52 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-08 15:49:01 +02:00
/* Number of degree type in this list */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"DAT_N RM %s\"",BgColor);
2019-11-10 13:31:47 +01:00
HTM_Unsigned (NumDegTyp + 1);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2017-03-24 01:09:27 +01:00
/* Name of degree type */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"DAT_N LM %s\"",BgColor);
2019-11-10 12:36:37 +01:00
HTM_Txt (Gbl.DegTypes.Lst[NumDegTyp].DegTypName);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2016-03-20 16:30:52 +01:00
/* Number of degrees of this type */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"DAT_N RM %s\"",BgColor);
2019-11-10 13:31:47 +01:00
HTM_Unsigned (Gbl.DegTypes.Lst[NumDegTyp].NumDegs);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2019-10-07 00:05:24 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2016-03-20 16:30:52 +01:00
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
}
}
2017-03-24 13:58:35 +01:00
/*****************************************************************************/
/************** Put contextual icons in list of degree types *****************/
/*****************************************************************************/
2020-04-08 13:40:21 +02:00
static void DT_PutIconsListingDegTypes (__attribute__((unused)) void *Args)
2017-03-24 13:58:35 +01:00
{
2020-04-08 13:40:21 +02:00
/***** Put icon to edit degree types *****/
DT_PutIconToEditDegTypes (NULL);
2017-03-24 13:58:35 +01:00
2020-04-08 13:40:21 +02:00
/***** Put icon to view degrees *****/
Deg_PutIconToViewDegrees ();
2018-11-15 12:52:56 +01:00
2020-04-08 13:40:21 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_DEGREE_TYPES);
2017-03-24 13:58:35 +01:00
}
2016-03-20 16:30:52 +01:00
/*****************************************************************************/
/******************* Put link (form) to edit degree types ********************/
/*****************************************************************************/
2020-04-08 13:40:21 +02:00
static void DT_PutIconToEditDegTypes (__attribute__((unused)) void *Args)
2016-03-20 16:30:52 +01:00
{
if (Gbl.Hierarchy.Level == Hie_Lvl_CTR && // Only editable if center tab is visible
2020-04-08 13:40:21 +02:00
DT_CheckIfICanCreateDegreeTypes ())
Ico_PutContextualIconToEdit (ActEdiDegTyp,NULL,
NULL,NULL);
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/******************* List current degree types for edition *******************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
static void DT_ListDegreeTypesForEdition (void)
2016-03-20 16:30:52 +01:00
{
unsigned NumDegTyp;
/***** Write heading *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWidePadding (2);
2016-03-20 22:31:57 +01:00
DT_PutHeadDegreeTypesForEdition ();
2016-03-20 16:30:52 +01:00
/***** List degree types with forms for edition *****/
for (NumDegTyp = 0;
2019-04-04 10:45:15 +02:00
NumDegTyp < Gbl.DegTypes.Num;
2016-03-20 16:30:52 +01:00
NumDegTyp++)
{
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 00:05:24 +02:00
/* Put icon to remove degree type */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"BM\"");
2019-04-04 10:45:15 +02:00
if (Gbl.DegTypes.Lst[NumDegTyp].NumDegs) // Degree type has degrees => deletion forbidden
2017-06-11 19:13:28 +02:00
Ico_PutIconRemovalNotAllowed ();
2016-03-20 16:30:52 +01:00
else
2020-10-13 22:34:31 +02:00
Ico_PutContextualIconToRemove (ActRemDegTyp,NULL,
DT_PutParamOtherDegTypCod,&Gbl.DegTypes.Lst[NumDegTyp].DegTypCod);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2016-03-20 16:30:52 +01:00
/* Degree type code */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"DAT CODE\"");
2019-11-10 13:38:17 +01:00
HTM_Long (Gbl.DegTypes.Lst[NumDegTyp].DegTypCod);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2016-03-20 16:30:52 +01:00
/* Name of degree type */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"LM\"");
Frm_BeginForm (ActRenDegTyp);
2020-10-13 22:34:31 +02:00
DT_PutParamOtherDegTypCod (&Gbl.DegTypes.Lst[NumDegTyp].DegTypCod);
2019-11-04 12:25:48 +01:00
HTM_INPUT_TEXT ("DegTypName",Deg_MAX_CHARS_DEGREE_TYPE_NAME,
2020-04-27 03:16:55 +02:00
Gbl.DegTypes.Lst[NumDegTyp].DegTypName,
HTM_SUBMIT_ON_CHANGE,
2019-11-04 12:25:48 +01:00
"size=\"25\" required=\"required\"");
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2016-03-20 16:30:52 +01:00
/* Number of degrees of this type */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"DAT RM\"");
2019-11-10 13:31:47 +01:00
HTM_Unsigned (Gbl.DegTypes.Lst[NumDegTyp].NumDegs);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2019-10-07 00:05:24 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2016-03-20 16:30:52 +01:00
}
2017-04-30 14:03:45 +02:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2017-04-30 14:03:45 +02:00
}
/*****************************************************************************/
/******************** Check if I can create degree types *********************/
/*****************************************************************************/
bool DT_CheckIfICanCreateDegreeTypes (void)
{
2017-06-04 18:18:54 +02:00
return (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/******************** Put a form to create a new degree type *****************/
/*****************************************************************************/
2019-04-08 12:01:08 +02:00
static void DT_PutFormToCreateDegreeType (void)
2016-03-20 16:30:52 +01:00
{
extern const char *Txt_New_type_of_degree;
extern const char *Txt_Create_type_of_degree;
2019-10-20 22:00:28 +02:00
/***** Begin form *****/
Frm_BeginForm (ActNewDegTyp);
2016-03-20 16:30:52 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box and table *****/
2020-03-26 02:54:30 +01:00
Box_BoxTableBegin (NULL,Txt_New_type_of_degree,
NULL,NULL,
2017-06-12 15:03:29 +02:00
NULL,Box_NOT_CLOSABLE,2);
2016-03-20 16:30:52 +01:00
/***** Write heading *****/
2017-04-30 14:03:45 +02:00
DT_PutHeadDegreeTypesForEdition ();
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 00:05:24 +02:00
/***** Column to remove degree type, disabled here *****/
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"BM\"");
HTM_TD_End ();
2017-04-30 14:03:45 +02:00
/***** Degree type code *****/
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"CODE\"");
HTM_TD_End ();
2016-03-20 16:30:52 +01:00
/***** Degree type name *****/
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"LM\"");
2020-04-27 03:16:55 +02:00
HTM_INPUT_TEXT ("DegTypName",Deg_MAX_CHARS_DEGREE_TYPE_NAME,DT_EditingDegTyp->DegTypName,
HTM_DONT_SUBMIT_ON_CHANGE,
2019-11-04 12:25:48 +01:00
"size=\"25\" required=\"required\"");
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2016-03-20 16:30:52 +01:00
2017-04-30 14:03:45 +02:00
/***** Number of degrees of this degree type ****/
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"DAT RM\"");
2019-11-10 13:51:07 +01:00
HTM_Unsigned (0);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2019-10-07 00:05:24 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2017-04-30 14:03:45 +02:00
2017-06-12 14:16:33 +02:00
/***** End table, send button and end box *****/
2019-11-25 23:18:08 +01:00
Box_BoxTableWithButtonEnd (Btn_CREATE_BUTTON,Txt_Create_type_of_degree);
2016-03-20 16:30:52 +01:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/***************** Write header with fields of a degree type *****************/
/*****************************************************************************/
2020-04-06 23:18:02 +02:00
static void DT_PutHeadDegreeTypesForSeeing (Act_Action_t NextAction,
2021-02-11 22:57:09 +01:00
Hie_Lvl_Level_t Scope,
2020-04-06 23:18:02 +02:00
DT_Order_t SelectedOrder)
2016-03-20 16:30:52 +01:00
{
2017-03-24 01:09:27 +01:00
extern const char *Txt_DEGREE_TYPES_HELP_ORDER[DT_NUM_ORDERS];
extern const char *Txt_DEGREE_TYPES_ORDER[DT_NUM_ORDERS];
DT_Order_t Order;
2020-04-06 23:18:02 +02:00
struct Fig_Figures Figures;
2016-03-20 16:30:52 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
HTM_TH_Empty (1);
2019-12-15 01:10:36 +01:00
for (Order = DT_ORDER_BY_DEGREE_TYPE;
2017-03-24 01:09:27 +01:00
Order <= DT_ORDER_BY_NUM_DEGREES;
Order++)
{
2019-10-23 19:05:05 +02:00
HTM_TH_Begin (1,1,Order == DT_ORDER_BY_DEGREE_TYPE ? "LM" :
2019-10-15 15:23:38 +02:00
"RM");
2017-03-24 01:09:27 +01:00
2019-10-20 22:00:28 +02:00
/* Begin form to change order */
Frm_BeginForm (NextAction);
2017-03-24 12:23:42 +01:00
if (NextAction == ActSeeUseGbl)
2020-04-06 23:18:02 +02:00
{
Figures.Scope = Scope;
Figures.FigureType = Fig_DEGREE_TYPES;
Fig_PutHiddenParamFigures (&Figures);
}
2019-11-03 13:19:32 +01:00
Par_PutHiddenParamUnsigned (NULL,"Order",(unsigned) Order);
2017-03-24 12:23:42 +01:00
/* Link with the head of this column */
2019-11-20 10:17:42 +01:00
HTM_BUTTON_SUBMIT_Begin (Txt_DEGREE_TYPES_HELP_ORDER[Order],"BT_LINK TIT_TBL",NULL);
2017-03-24 13:22:54 +01:00
if (Order == SelectedOrder)
2019-11-10 16:41:47 +01:00
HTM_U_Begin ();
2019-11-10 12:36:37 +01:00
HTM_Txt (Txt_DEGREE_TYPES_ORDER[Order]);
2017-03-24 13:22:54 +01:00
if (Order == SelectedOrder)
2019-11-10 16:41:47 +01:00
HTM_U_End ();
2019-11-18 11:23:48 +01:00
HTM_BUTTON_End ();
2017-03-24 12:23:42 +01:00
/* End form */
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-03-24 01:09:27 +01:00
2019-10-23 19:05:05 +02:00
HTM_TH_End ();
2017-03-24 01:09:27 +01:00
}
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/***************** Write header with fields of a degree type *****************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
static void DT_PutHeadDegreeTypesForEdition (void)
2016-03-20 16:30:52 +01:00
{
extern const char *Txt_Code;
2016-03-20 16:55:34 +01:00
extern const char *Txt_Type_of_degree;
2016-03-20 16:30:52 +01:00
extern const char *Txt_Degrees;
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-11 15:36:50 +02:00
2019-10-23 19:05:05 +02:00
HTM_TH (1,1,"BM",NULL);
HTM_TH (1,1,"CM",Txt_Code);
HTM_TH (1,1,"CM",Txt_Type_of_degree);
HTM_TH (1,1,"RM",Txt_Degrees);
2019-10-11 15:36:50 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/************************** Create a new degree type *************************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
static void DT_CreateDegreeType (struct DegreeType *DegTyp)
2016-03-20 16:30:52 +01:00
{
/***** Create a new degree type *****/
2018-11-02 19:37:11 +01:00
DB_QueryINSERT ("can not create a new type of degree",
"INSERT INTO deg_types"
" SET DegTypName='%s'",
2018-11-02 19:37:11 +01:00
DegTyp->DegTypName);
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/**************** Create a list with all the degree types ********************/
/*****************************************************************************/
2021-02-11 22:57:09 +01:00
void DT_GetListDegreeTypes (Hie_Lvl_Level_t Scope,DT_Order_t Order)
2016-03-20 16:30:52 +01:00
{
2017-03-24 01:09:27 +01:00
static const char *OrderBySubQuery[DT_NUM_ORDERS] =
{
2019-11-21 00:40:35 +01:00
[DT_ORDER_BY_DEGREE_TYPE] = "DegTypName",
[DT_ORDER_BY_NUM_DEGREES] = "NumDegs DESC,DegTypName",
2017-03-24 01:09:27 +01:00
};
2016-03-20 16:30:52 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumTyp;
2016-03-20 16:30:52 +01:00
/***** Get types of degree from database *****/
2017-03-24 13:22:54 +01:00
switch (Scope)
2017-03-24 13:01:42 +01:00
{
2021-02-11 22:57:09 +01:00
case Hie_Lvl_SYS:
2017-03-24 13:01:42 +01:00
/* Get
all degree types with degrees
union with
all degree types without any degree */
2020-01-11 13:52:56 +01:00
Gbl.DegTypes.Num = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get types of degree",
"(SELECT deg_types.DegTypCod," // row[0]
"deg_types.DegTypName," // row[1]
"COUNT(deg_degrees.DegCod) AS NumDegs" // row[2]
" FROM deg_degrees,"
"deg_types"
" WHERE deg_degrees.DegTypCod=deg_types.DegTypCod"
" GROUP BY deg_degrees.DegTypCod)"
2020-01-11 13:52:56 +01:00
" UNION "
"(SELECT DegTypCod," // row[0]
"DegTypName," // row[1]
"0 AS NumDegs" // row[2]
// do not use '0' because
// NumDegs will be casted to string
// and order will be wrong
" FROM deg_types"
2020-01-11 13:52:56 +01:00
" WHERE DegTypCod NOT IN"
" (SELECT DegTypCod"
" FROM deg_degrees))"
2020-01-11 13:52:56 +01:00
" ORDER BY %s",
OrderBySubQuery[Order]);
2017-03-24 13:01:42 +01:00
break;
2021-02-11 22:57:09 +01:00
case Hie_Lvl_CTY:
2017-03-24 13:01:42 +01:00
/* Get only degree types with degrees in the current country */
2020-01-11 13:52:56 +01:00
Gbl.DegTypes.Num = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get types of degree",
"SELECT deg_types.DegTypCod," // row[0]
"deg_types.DegTypName," // row[1]
"COUNT(deg_degrees.DegCod) AS NumDegs" // row[2]
" FROM ins_instits,"
"ctr_centers,"
"deg_degrees,"
"deg_types"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegTypCod=deg_types.DegTypCod"
" GROUP BY deg_degrees.DegTypCod"
2020-01-11 13:52:56 +01:00
" ORDER BY %s",
Gbl.Hierarchy.Cty.CtyCod,
OrderBySubQuery[Order]);
2017-03-24 13:01:42 +01:00
break;
2021-02-11 22:57:09 +01:00
case Hie_Lvl_INS:
2017-03-24 13:01:42 +01:00
/* Get only degree types with degrees in the current institution */
2020-01-11 13:52:56 +01:00
Gbl.DegTypes.Num = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get types of degree",
"SELECT deg_types.DegTypCod," // row[0]
"deg_types.DegTypName," // row[1]
"COUNT(deg_degrees.DegCod) AS NumDegs" // row[2]
" FROM ctr_centers,"
"deg_degrees,"
"deg_types"
" WHERE ctr_centers.InsCod=%ld"
" AND ctr_centers.CtrCod=deg_degrees.CtrCod"
" AND deg_degrees.DegTypCod=deg_types.DegTypCod"
" GROUP BY deg_degrees.DegTypCod"
2020-01-11 13:52:56 +01:00
" ORDER BY %s",
Gbl.Hierarchy.Ins.InsCod,
OrderBySubQuery[Order]);
2017-03-24 13:01:42 +01:00
break;
2021-02-11 22:57:09 +01:00
case Hie_Lvl_CTR:
/* Get only degree types with degrees in the current center */
2020-01-11 13:52:56 +01:00
Gbl.DegTypes.Num = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get types of degree",
"SELECT deg_types.DegTypCod," // row[0]
"deg_types.DegTypName," // row[1]
"COUNT(deg_degrees.DegCod) AS NumDegs" // row[2]
" FROM deg_degrees,"
"deg_types"
" WHERE deg_degrees.CtrCod=%ld"
" AND deg_degrees.DegTypCod=deg_types.DegTypCod"
" GROUP BY deg_degrees.DegTypCod"
2020-01-11 13:52:56 +01:00
" ORDER BY %s",
Gbl.Hierarchy.Ctr.CtrCod,
OrderBySubQuery[Order]);
2017-03-24 13:01:42 +01:00
break;
2021-02-11 22:57:09 +01:00
case Hie_Lvl_DEG:
case Hie_Lvl_CRS:
2017-03-24 13:01:42 +01:00
/* Get only degree types with degrees in the current degree */
2020-01-11 13:52:56 +01:00
Gbl.DegTypes.Num = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get types of degree",
"SELECT deg_types.DegTypCod," // row[0]
"deg_types.DegTypName," // row[1]
"COUNT(deg_degrees.DegCod) AS NumDegs" // row[2]
" FROM deg_degrees,"
"deg_types"
" WHERE deg_degrees.DegCod=%ld"
" AND deg_degrees.DegTypCod=deg_types.DegTypCod"
" GROUP BY deg_degrees.DegTypCod"
2020-01-11 13:52:56 +01:00
" ORDER BY %s",
Gbl.Hierarchy.Deg.DegCod,
OrderBySubQuery[Order]);
2017-03-24 13:01:42 +01:00
break;
default:
Err_WrongScopeExit ();
2017-03-24 13:01:42 +01:00
break;
}
2016-03-20 16:30:52 +01:00
/***** Get degree types *****/
2019-04-04 10:45:15 +02:00
if (Gbl.DegTypes.Num)
2016-03-20 16:30:52 +01:00
{
/***** Create a list of degree types *****/
if ((Gbl.DegTypes.Lst = calloc (Gbl.DegTypes.Num,
sizeof (*Gbl.DegTypes.Lst))) == NULL)
Err_NotEnoughMemoryExit ();
2016-03-20 16:30:52 +01:00
/***** Get degree types *****/
for (NumTyp = 0;
NumTyp < Gbl.DegTypes.Num;
NumTyp++)
2016-03-20 16:30:52 +01:00
{
/* Get next degree type */
row = mysql_fetch_row (mysql_res);
/* Get degree type code (row[0]) */
if ((Gbl.DegTypes.Lst[NumTyp].DegTypCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Err_WrongDegTypExit ();
2016-03-20 16:30:52 +01:00
/* Get degree type name (row[1]) */
Str_Copy (Gbl.DegTypes.Lst[NumTyp].DegTypName,row[1],
sizeof (Gbl.DegTypes.Lst[NumTyp].DegTypName) - 1);
2016-03-20 16:30:52 +01:00
/* Number of degrees of this type (row[2]) */
if (sscanf (row[2],"%u",&Gbl.DegTypes.Lst[NumTyp].NumDegs) != 1)
Err_ShowErrorAndExit ("Error when getting number of degrees of a type");
2016-03-20 16:30:52 +01:00
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/********* Free list of degree types and list of degrees of each type ********/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
void DT_FreeListDegreeTypes (void)
2016-03-20 16:30:52 +01:00
{
/***** Free memory used by the list of degree types *****/
2019-04-04 10:45:15 +02:00
if (Gbl.DegTypes.Lst)
2016-03-20 16:30:52 +01:00
{
2019-11-06 19:45:20 +01:00
free (Gbl.DegTypes.Lst);
2019-04-04 10:45:15 +02:00
Gbl.DegTypes.Lst = NULL;
Gbl.DegTypes.Num = 0;
2016-03-20 16:30:52 +01:00
}
}
/*****************************************************************************/
/***************** Receive form to create a new degree type ******************/
/*****************************************************************************/
2020-05-05 21:49:00 +02:00
void DT_ReceiveFormNewDegreeType (void)
2016-03-20 16:30:52 +01:00
{
extern const char *Txt_The_type_of_degree_X_already_exists;
2019-04-08 13:06:17 +02:00
extern const char *Txt_Created_new_type_of_degree_X;
2016-03-20 16:30:52 +01:00
extern const char *Txt_You_must_specify_the_name_of_the_new_type_of_degree;
2019-04-08 12:01:08 +02:00
/***** Degree type constructor *****/
DT_EditingDegreeTypeConstructor ();
2016-03-20 16:30:52 +01:00
/***** Get parameters from form *****/
/* Get the name of degree type */
2019-04-08 12:01:08 +02:00
Par_GetParToText ("DegTypName",DT_EditingDegTyp->DegTypName,Deg_MAX_BYTES_DEGREE_TYPE_NAME);
2016-03-20 16:30:52 +01:00
2019-04-08 12:01:08 +02:00
if (DT_EditingDegTyp->DegTypName[0]) // If there's a degree type name
2016-03-20 16:30:52 +01:00
{
/***** If name of degree type was in database... *****/
2019-04-08 12:01:08 +02:00
if (DT_CheckIfDegreeTypeNameExists (DT_EditingDegTyp->DegTypName,-1L))
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_type_of_degree_X_already_exists,
DT_EditingDegTyp->DegTypName);
2016-03-20 16:30:52 +01:00
else // Add new degree type to database
2019-04-08 13:06:17 +02:00
{
2019-04-08 12:01:08 +02:00
DT_CreateDegreeType (DT_EditingDegTyp);
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_Created_new_type_of_degree_X,
DT_EditingDegTyp->DegTypName);
}
2016-03-20 16:30:52 +01:00
}
else // If there is not a degree type name
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_must_specify_the_name_of_the_new_type_of_degree);
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/**************************** Remove a degree type ***************************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
void DT_RemoveDegreeType (void)
2016-03-20 16:30:52 +01:00
{
extern const char *Txt_To_remove_a_type_of_degree_you_must_first_remove_all_degrees_of_that_type;
extern const char *Txt_Type_of_degree_X_removed;
2019-04-08 12:01:08 +02:00
/***** Degree type constructor *****/
DT_EditingDegreeTypeConstructor ();
2016-03-20 16:30:52 +01:00
/***** Get the code of the degree type *****/
2019-04-08 12:01:08 +02:00
DT_EditingDegTyp->DegTypCod = DT_GetAndCheckParamOtherDegTypCod (1);
2016-03-20 16:30:52 +01:00
/***** Get data of the degree type from database *****/
2019-04-08 12:01:08 +02:00
if (!DT_GetDataOfDegreeTypeByCod (DT_EditingDegTyp))
Err_WrongDegTypExit ();
2016-03-20 16:30:52 +01:00
/***** Check if this degree type has degrees *****/
2019-04-08 12:01:08 +02:00
if (DT_EditingDegTyp->NumDegs) // Degree type has degrees => don't remove
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_To_remove_a_type_of_degree_you_must_first_remove_all_degrees_of_that_type);
2017-03-26 17:32:19 +02:00
else // Degree type has no degrees => remove it
2016-03-20 16:30:52 +01:00
{
/***** Remove degree type *****/
2019-04-08 12:01:08 +02:00
DT_RemoveDegreeTypeCompletely (DT_EditingDegTyp->DegTypCod);
2016-03-20 16:30:52 +01:00
/***** Write message to show the change made *****/
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_Type_of_degree_X_removed,
DT_EditingDegTyp->DegTypName);
2016-03-20 16:30:52 +01:00
}
}
/*****************************************************************************/
/***************** Write parameter with code of degree type ******************/
/*****************************************************************************/
2020-10-13 22:34:31 +02:00
static void DT_PutParamOtherDegTypCod (void *DegTypCod)
2016-03-20 16:30:52 +01:00
{
2020-10-13 22:34:31 +02:00
if (DegTypCod)
Par_PutHiddenParamLong (NULL,"OthDegTypCod",*((long *) DegTypCod));
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/******************* Get parameter with code of degree type ******************/
/*****************************************************************************/
2017-05-31 21:05:59 +02:00
long DT_GetAndCheckParamOtherDegTypCod (long MinCodAllowed)
2016-03-20 16:30:52 +01:00
{
2017-05-31 21:05:59 +02:00
long DegTypCod;
/***** Get and check parameter with code of degree type *****/
if ((DegTypCod = Par_GetParToLong ("OthDegTypCod")) < MinCodAllowed)
Err_WrongDegTypExit ();
2017-05-31 21:05:59 +02:00
return DegTypCod;
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/**************** Count number of degrees in a degree type ******************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
static unsigned DT_CountNumDegsOfType (long DegTypCod)
2016-03-20 16:30:52 +01:00
{
/***** Get number of degrees of a type from database *****/
return (unsigned)
DB_QueryCOUNT ("can not get number of degrees of a type",
"SELECT COUNT(*)"
" FROM deg_degrees"
" WHERE DegTypCod=%ld",
DegTypCod);
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/****************** Get data of a degree type from its code ******************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
bool DT_GetDataOfDegreeTypeByCod (struct DegreeType *DegTyp)
2016-03-20 16:30:52 +01:00
{
/***** Trivial check: code of degree type should be >= 0 *****/
2016-03-20 16:30:52 +01:00
if (DegTyp->DegTypCod <= 0)
{
DegTyp->DegTypName[0] = '\0';
DegTyp->NumDegs = 0;
return false;
}
/***** Get the name of a type of degree from database *****/
DB_QuerySELECTString (DegTyp->DegTypName,sizeof (DegTyp->DegTypName) - 1,
"can not get the name of a type of degree",
"SELECT DegTypName"
" FROM deg_types"
" WHERE DegTypCod=%ld",
DegTyp->DegTypCod);
if (DegTyp->DegTypName[0])
2016-03-20 16:30:52 +01:00
{
/* Count number of degrees of this type */
2016-03-20 22:31:57 +01:00
DegTyp->NumDegs = DT_CountNumDegsOfType (DegTyp->DegTypCod);
return true;
2016-03-20 16:30:52 +01:00
}
DegTyp->DegTypName[0] = '\0';
DegTyp->NumDegs = 0;
return false;
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/******************** Remove a degree type and its degrees *******************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
static void DT_RemoveDegreeTypeCompletely (long DegTypCod)
2016-03-20 16:30:52 +01:00
{
MYSQL_RES *mysql_res;
unsigned NumDegs;
unsigned NumDeg;
2016-03-20 16:30:52 +01:00
long DegCod;
/***** Get degrees of a type from database *****/
NumDegs = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get degrees of a type",
"SELECT DegCod"
" FROM deg_degrees"
" WHERE DegTypCod=%ld",
DegTypCod);
2016-03-20 16:30:52 +01:00
/* Get degrees of this type */
for (NumDeg = 0;
NumDeg < NumDegs;
NumDeg++)
2016-03-20 16:30:52 +01:00
{
/* Get next degree */
if ((DegCod = DB_GetNextCode (mysql_res)) < 0)
Err_WrongDegreeExit ();
2016-03-20 16:30:52 +01:00
/* Remove degree */
Deg_RemoveDegreeCompletely (DegCod);
}
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
/***** Remove the degree type *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove a type of degree",
"DELETE FROM deg_types"
" WHERE DegTypCod=%ld",
2018-11-02 22:00:31 +01:00
DegTypCod);
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/**************************** Rename a degree type ***************************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
void DT_RenameDegreeType (void)
2016-03-20 16:30:52 +01:00
{
extern const char *Txt_The_type_of_degree_X_already_exists;
extern const char *Txt_The_type_of_degree_X_has_been_renamed_as_Y;
extern const char *Txt_The_name_of_the_type_of_degree_X_has_not_changed;
2017-03-07 11:03:05 +01:00
char NewNameDegTyp[Deg_MAX_BYTES_DEGREE_TYPE_NAME + 1];
2016-03-20 16:30:52 +01:00
2019-04-08 12:01:08 +02:00
/***** Degree type constructor *****/
DT_EditingDegreeTypeConstructor ();
2016-03-20 16:30:52 +01:00
/***** Get parameters from form *****/
/* Get the code of the degree type */
2019-04-08 12:01:08 +02:00
DT_EditingDegTyp->DegTypCod = DT_GetAndCheckParamOtherDegTypCod (1);
2016-03-20 16:30:52 +01:00
/* Get the new name for the degree type */
2017-03-07 11:03:05 +01:00
Par_GetParToText ("DegTypName",NewNameDegTyp,Deg_MAX_BYTES_DEGREE_TYPE_NAME);
2016-03-20 16:30:52 +01:00
/***** Get from the database the old name of the degree type *****/
2019-04-08 12:01:08 +02:00
if (!DT_GetDataOfDegreeTypeByCod (DT_EditingDegTyp))
Err_WrongDegTypExit ();
2016-03-20 16:30:52 +01:00
/***** Check if new name is empty *****/
2019-12-20 00:30:54 +01:00
if (NewNameDegTyp[0])
2016-03-20 16:30:52 +01:00
{
2019-01-02 15:10:51 +01:00
/***** Check if old and new names are the same
(this happens when return is pressed without changes) *****/
2019-04-08 12:01:08 +02:00
if (strcmp (DT_EditingDegTyp->DegTypName,NewNameDegTyp)) // Different names
2016-03-20 16:30:52 +01:00
{
/***** If degree type was in database... *****/
2019-04-08 12:01:08 +02:00
if (DT_CheckIfDegreeTypeNameExists (NewNameDegTyp,DT_EditingDegTyp->DegTypCod))
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_type_of_degree_X_already_exists,
NewNameDegTyp);
2016-03-20 16:30:52 +01:00
else
{
/* Update the table changing old name by new name */
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not update the type of a degree",
"UPDATE deg_types"
" SET DegTypName='%s'"
2018-11-03 12:16:40 +01:00
" WHERE DegTypCod=%ld",
NewNameDegTyp,
DT_EditingDegTyp->DegTypCod);
2016-03-20 16:30:52 +01:00
/* Write message to show the change made */
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_type_of_degree_X_has_been_renamed_as_Y,
DT_EditingDegTyp->DegTypName,NewNameDegTyp);
2016-03-20 16:30:52 +01:00
}
2019-04-08 13:06:17 +02:00
2016-03-20 16:30:52 +01:00
}
else // The same name
2019-04-08 13:06:17 +02:00
Ale_CreateAlert (Ale_INFO,NULL,
Txt_The_name_of_the_type_of_degree_X_has_not_changed,
NewNameDegTyp);
2016-03-20 16:30:52 +01:00
}
2019-12-20 00:30:54 +01:00
else
Ale_CreateAlertYouCanNotLeaveFieldEmpty ();
2016-03-20 16:30:52 +01:00
2019-04-08 13:06:17 +02:00
/***** Set degree type name *****/
2019-04-08 12:01:08 +02:00
Str_Copy (DT_EditingDegTyp->DegTypName,NewNameDegTyp,
sizeof (DT_EditingDegTyp->DegTypName) - 1);
2016-03-20 16:30:52 +01:00
}
/*****************************************************************************/
/****************** Check if name of degree type exists **********************/
/*****************************************************************************/
2016-03-20 22:31:57 +01:00
static bool DT_CheckIfDegreeTypeNameExists (const char *DegTypName,long DegTypCod)
2016-03-20 16:30:52 +01:00
{
/***** Get number of degree types with a name from database *****/
2018-11-03 13:13:11 +01:00
return (DB_QueryCOUNT ("can not check if the name of a type of degree"
" already existed",
"SELECT COUNT(*)"
" FROM deg_types"
" WHERE DegTypName='%s'"
" AND DegTypCod<>%ld",
2018-11-03 13:13:11 +01:00
DegTypName,DegTypCod) != 0);
2016-03-20 16:30:52 +01:00
}
2019-04-08 12:01:08 +02:00
/*****************************************************************************/
2019-04-08 13:06:17 +02:00
/********** Show message of success after changing a degree type *************/
/*****************************************************************************/
void DT_ContEditAfterChgDegTyp (void)
{
/***** Show possible delayed alerts *****/
Ale_ShowAlerts (NULL);
/***** Show the form again *****/
DT_EditDegreeTypesInternal ();
/***** Degree type destructor *****/
DT_EditingDegreeTypeDestructor ();
}
/*****************************************************************************/
2019-04-08 12:01:08 +02:00
/********************* Degree type constructor/destructor ********************/
/*****************************************************************************/
static void DT_EditingDegreeTypeConstructor (void)
{
/***** Pointer must be NULL *****/
if (DT_EditingDegTyp != NULL)
Err_WrongDegTypExit ();
2019-04-08 12:01:08 +02:00
/***** Allocate memory for degree type *****/
if ((DT_EditingDegTyp = malloc (sizeof (*DT_EditingDegTyp))) == NULL)
Err_NotEnoughMemoryExit ();
2019-04-08 12:01:08 +02:00
/***** Reset degree type *****/
DT_EditingDegTyp->DegTypCod = -1L;
DT_EditingDegTyp->DegTypName[0] = '\0';
DT_EditingDegTyp->NumDegs = 0;
}
static void DT_EditingDegreeTypeDestructor (void)
{
/***** Free memory used for degree type *****/
if (DT_EditingDegTyp != NULL)
{
2019-11-06 19:45:20 +01:00
free (DT_EditingDegTyp);
2019-04-08 12:01:08 +02:00
DT_EditingDegTyp = NULL;
}
}