diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2570d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,165 @@ +.idea/ +.vscode/ + + +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/BD_2023_projekt.pdf b/BD_2023_projekt.pdf new file mode 100644 index 0000000..b60bf96 Binary files /dev/null and b/BD_2023_projekt.pdf differ diff --git a/README.md b/README.md index 438ff38..8d9cf85 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,11 @@ Authors: - Paweł Czajczyk - Szymon Rybski +## Project specification +Full project specification is provided [here](https://github.com/Bleidhu/Introduction__To_Databases_2024_AGH_Project/blob/main/BD_2023_projekt.pdf) ## Technical details +### DB engine +As required by the project rules MS SQL was used. ### Tools used: - Database diagrams: [Vertabello](https://vertabelo.com/) - MD notes: [Markdown Editor](https://hackmd.io/) @@ -14,12 +18,7 @@ Authors: - Files in the repo can be directly edited throught this link: [Edit In Browser](https://vscode.dev/github/Bleidhu/Introduction__To_Databases_2024_AGH_Project/tree/main?vscode-lang=pl-pl) - For drawing not related to the database [Excalidraw](https://excalidraw.com/) can be used -### Used Databases -| Database | user | password | owner | -|-----------------------------------------------------------|------|----------|-------| -| main (only modified after changes are verified on test) | | | | -| test (for testing purposes) | | | | -| backup (only modified if changes made to main are desired)| | | | + ### File structure diff --git a/db_logic/db_init.sql b/db_logic/db_init.sql new file mode 100644 index 0000000..83bbf51 --- /dev/null +++ b/db_logic/db_init.sql @@ -0,0 +1,694 @@ +-- Created by Vertabelo (http://vertabelo.com) +-- Last modification date: 2025-01-26 23:43:08.163 + +-- Table: Cities +CREATE TABLE Cities +( + city_id int NOT NULL IDENTITY (1, 1), + city_name nvarchar(30) NOT NULL, + CONSTRAINT Cities_pk PRIMARY KEY (city_id) +); + +-- Table: Countries +CREATE TABLE Countries +( + country_id int NOT NULL IDENTITY (1, 1), + country_name nvarchar(30) NOT NULL, + CONSTRAINT Countries_pk PRIMARY KEY (country_id) +); + +-- Table: Course_meeting_attendance_list +CREATE TABLE Course_meeting_attendance_list +( + user_id int NOT NULL, + course_id int NOT NULL, + meeting_id int NOT NULL, + was_present bit NOT NULL, + CONSTRAINT Course_meeting_attendance_list_pk PRIMARY KEY (user_id, meeting_id, course_id) +); + +-- Reference: Course_meeting_attendance_list_Course_module_meetings (table: Course_meeting_attendance_list) +ALTER TABLE Course_meeting_attendance_list + ADD CONSTRAINT Course_meeting_attendance_list_Course_module_meetings + FOREIGN KEY (meeting_id, course_id) + REFERENCES Course_module_meetings (meeting_id, course_id); + +-- Reference: Course_meeting_attendance_list_Users (table: Course_meeting_attendance_list) +ALTER TABLE Course_meeting_attendance_list + ADD CONSTRAINT Course_meeting_attendance_list_Users + FOREIGN KEY (user_id) + REFERENCES Users (user_id); + +-- Table: Course_module_meetings +CREATE TABLE Course_module_meetings +( + course_id int NOT NULL, + meeting_id int NOT NULL, + meeting_date datetime NOT NULL, + language_id int NOT NULL, + translator_id int NOT NULL, + lecturer_id int NOT NULL, + duration time NOT NULL, + place_limit int NOT NULL, + module_id int NOT NULL, + meeting_type_id int NOT NULL, + meeting_name nvarchar(30) NOT NULL, + CONSTRAINT place_limit CHECK (place_limit >= 0), + CONSTRAINT Course_module_meetings_pk PRIMARY KEY (meeting_id, course_id) +); +-- Reference: Course_module_meetings_Course_modules (table: Course_module_meetings) +ALTER TABLE Course_module_meetings + ADD CONSTRAINT Course_module_meetings_Course_modules + FOREIGN KEY (module_id) + REFERENCES Course_modules (course_module_id); + +-- Reference: Course_module_meetings_Employees (table: Course_module_meetings) +ALTER TABLE Course_module_meetings + ADD CONSTRAINT Course_module_meetings_Employees + FOREIGN KEY (lecturer_id) + REFERENCES Employees (employee_id); + +-- Reference: Course_module_meetings_Languages (table: Course_module_meetings) +ALTER TABLE Course_module_meetings + ADD CONSTRAINT Course_module_meetings_Languages + FOREIGN KEY (language_id) + REFERENCES Languages (language_id); + +-- Reference: Translators_Course_module_meetings (table: Course_module_meetings) +ALTER TABLE Course_module_meetings + ADD CONSTRAINT Translators_Course_module_meetings + FOREIGN KEY (translator_id) + REFERENCES Translators (translator_id); + +-- Reference: meeting_type_Course_module_meetings (table: Course_module_meetings) +ALTER TABLE Course_module_meetings + ADD CONSTRAINT meeting_type_Course_module_meetings + FOREIGN KEY (meeting_type_id) + REFERENCES meeting_type (meeting_type_id); + +-- Table: Course_modules +CREATE TABLE Course_modules +( + course_module_id int NOT NULL IDENTITY (1, 1), + module_type_id int NOT NULL, + module_name nvarchar(30) NOT NULL, + course_id int NOT NULL, + CONSTRAINT course_module_id PRIMARY KEY (course_module_id) +); + +-- Reference: Course_modules_module_type (table: Course_modules) +ALTER TABLE Course_modules + ADD CONSTRAINT Course_modules_module_type + FOREIGN KEY (module_type_id) + REFERENCES module_type (module_type_id); + +-- Reference: Courses_Course_modules (table: Course_modules) +ALTER TABLE Course_modules + ADD CONSTRAINT Courses_Course_modules + FOREIGN KEY (course_id) + REFERENCES Courses (course_id); + +-- Table: Course_stationary_meeting +CREATE TABLE Course_stationary_meeting +( + id int NOT NULL IDENTITY (1, 1), + course_id int NOT NULL, + meeting_id int NOT NULL, + classroom nvarchar(10) NOT NULL, + CONSTRAINT Course_stationary_meeting_pk PRIMARY KEY (id) +); +-- Reference: Course_module_meetings_Course_module_meeting_stationary (table: Course_stationary_meeting) +ALTER TABLE Course_stationary_meeting + ADD CONSTRAINT Course_module_meetings_Course_module_meeting_stationary + FOREIGN KEY (meeting_id, course_id) + REFERENCES Course_module_meetings (meeting_id, course_id); + + +-- Table: Course_sync_async_meeting +CREATE TABLE Course_sync_async_meeting +( + id int NOT NULL IDENTITY (1, 1), + course_id int NOT NULL, + meeting_id int NOT NULL, + access_to datetime NOT NULL, + video_link nvarchar(30) NOT NULL, + stream_link nvarchar(30) NULL, + CONSTRAINT Course_sync_async_meeting_pk PRIMARY KEY (id) +); +-- Reference: Course_video_access_Course_module_meetings (table: Course_sync_async_meeting) +ALTER TABLE Course_sync_async_meeting + ADD CONSTRAINT Course_video_access_Course_module_meetings + FOREIGN KEY (meeting_id, course_id) + REFERENCES Course_module_meetings (meeting_id, course_id); + + +-- Table: Courses +CREATE TABLE Courses +( + course_id int NOT NULL IDENTITY (1, 1), + course_name nvarchar(30) NOT NULL, + course_description nvarchar(300) NOT NULL, + start_date date NOT NULL, + students_limit int NOT NULL, + price money NOT NULL, + course_coordinator_id int NOT NULL, + visible_from date NOT NULL, + CONSTRAINT courses_price_check CHECK (price >= 0), + CONSTRAINT Courses_pk PRIMARY KEY (course_id) +); + +-- Reference: Courses_Employees (table: Courses) +ALTER TABLE Courses + ADD CONSTRAINT Courses_Employees + FOREIGN KEY (course_coordinator_id) + REFERENCES Employees (employee_id); + + +-- Table: Employee_Roles +CREATE TABLE Employee_Roles +( + role_id int NOT NULL IDENTITY (1, 1), + role_name nvarchar(30) NOT NULL, + CONSTRAINT Employee_Roles_pk PRIMARY KEY (role_id) +); + +-- Table: Employees +CREATE TABLE Employees +( + employee_id int NOT NULL IDENTITY (1, 1), + first_name nvarchar(30) NOT NULL, + last_name nvarchar(30) NOT NULL, + hire_date date NOT NULL, + birth_date date NOT NULL, + phone nvarchar(9) NOT NULL CHECK ((PATINDEX('%[^0-9]%', phone) = 0 AND LEN(phone) = 9)), + email nvarchar(50) NOT NULL, + role_id int NOT NULL, + city_id int NOT NULL, + country_id int NOT NULL, + CONSTRAINT employee_birth_date_check CHECK (year(getdate()) - year(birth_date) < 100), + CONSTRAINT Employees_pk PRIMARY KEY (employee_id) +); + +-- Reference: Employees_Cities (table: Employees) +ALTER TABLE Employees + ADD CONSTRAINT Employees_Cities + FOREIGN KEY (city_id) + REFERENCES Cities (city_id); + +-- Reference: Employees_Countries (table: Employees) +ALTER TABLE Employees + ADD CONSTRAINT Employees_Countries + FOREIGN KEY (country_id) + REFERENCES Countries (country_id); + +-- Reference: Employees_Employee_Roles (table: Employees) +ALTER TABLE Employees + ADD CONSTRAINT Employees_Employee_Roles + FOREIGN KEY (role_id) + REFERENCES Employee_Roles (role_id); + + +-- Table: Event_types +CREATE TABLE Event_types +( + type_id int NOT NULL IDENTITY (1, 1), + event_name nvarchar(30) NOT NULL, + CONSTRAINT Event_types_pk PRIMARY KEY (type_id) +); + +-- Table: Exams +CREATE TABLE Exams +( + studies_id int NOT NULL, + user_id int NOT NULL, + grade numeric(2, 1) NOT NULL, + CONSTRAINT grade_check CHECK (grade in (2.0, 3.0, 3.5, 4.0, 4.5, 5.0)), + CONSTRAINT Exams_pk PRIMARY KEY (studies_id, user_id) +); + +-- Reference: Exams_Studies (table: Exams) +ALTER TABLE Exams + ADD CONSTRAINT Exams_Studies + FOREIGN KEY (studies_id) + REFERENCES Studies (studies_id); + +-- Reference: Exams_Users (table: Exams) +ALTER TABLE Exams + ADD CONSTRAINT Exams_Users + FOREIGN KEY (user_id) + REFERENCES Users (user_id); + + +-- Table: Intership_meeting_attendance_list +CREATE TABLE Intership_meeting_attendance_list +( + inter_meeting_id int NOT NULL, + studies_id int NOT NULL, + user_id int NOT NULL, + was_present bit NOT NULL, + CONSTRAINT Intership_meeting_attendance_list_pk PRIMARY KEY (inter_meeting_id, user_id, studies_id) +); + +-- Reference: Intership_meeting_attendance_list_Intership_meetings (table: Intership_meeting_attendance_list) +ALTER TABLE Intership_meeting_attendance_list + ADD CONSTRAINT Intership_meeting_attendance_list_Intership_meetings + FOREIGN KEY (inter_meeting_id, studies_id) + REFERENCES Intership_meetings (inter_meeting_id, studies_id); + +-- Reference: Intership_meeting_attendance_list_Users (table: Intership_meeting_attendance_list) +ALTER TABLE Intership_meeting_attendance_list + ADD CONSTRAINT Intership_meeting_attendance_list_Users + FOREIGN KEY (user_id) + REFERENCES Users (user_id); + + +-- Table: Intership_meetings +CREATE TABLE Intership_meetings +( + studies_id int NOT NULL, + inter_meeting_id int NOT NULL IDENTITY (1, 1), + meetind_date datetime NOT NULL, + CONSTRAINT Intership_meetings_pk PRIMARY KEY (inter_meeting_id, studies_id) +); + +-- Reference: Intership_meetings_Studies (table: Intership_meetings) +ALTER TABLE Intership_meetings + ADD CONSTRAINT Intership_meetings_Studies + FOREIGN KEY (studies_id) + REFERENCES Studies (studies_id); + +-- Table: Languages +CREATE TABLE Languages +( + language_id int NOT NULL IDENTITY (1, 1), + language_name nvarchar(30) NOT NULL, + CONSTRAINT Languages_pk PRIMARY KEY (language_id) +); + +-- Table: Order_course +CREATE TABLE Order_course +( + order_detail_id int NOT NULL, + course_id int NOT NULL, + CONSTRAINT Order_course_pk PRIMARY KEY (order_detail_id) +); + +-- Reference: Order_course_Courses (table: Order_course) +ALTER TABLE Order_course + ADD CONSTRAINT Order_course_Courses + FOREIGN KEY (course_id) + REFERENCES Courses (course_id); + +-- Reference: Order_course_Order_details (table: Order_course) +ALTER TABLE Order_course + ADD CONSTRAINT Order_course_Order_details + FOREIGN KEY (order_detail_id) + REFERENCES Order_details (order_detail_id); + + +-- Table: Order_details +CREATE TABLE Order_details +( + order_detail_id int NOT NULL IDENTITY (1, 1), + order_id int NOT NULL, + type_id int NOT NULL, + price money NOT NULL, + CONSTRAINT order_details_price_check CHECK (price >= 0), + CONSTRAINT Order_details_pk PRIMARY KEY (order_detail_id) +); +-- Reference: Order_details_Event_types (table: Order_details) +ALTER TABLE Order_details + ADD CONSTRAINT Order_details_Event_types + FOREIGN KEY (type_id) + REFERENCES Event_types (type_id); + +-- Reference: Order_details_Orders (table: Order_details) +ALTER TABLE Order_details + ADD CONSTRAINT Order_details_Orders + FOREIGN KEY (order_id) + REFERENCES Orders (order_id); + + +-- Table: Order_module_studies +CREATE TABLE Order_module_studies +( + order_detail_id int NOT NULL, + module_id int NOT NULL, + CONSTRAINT Order_module_studies_pk PRIMARY KEY (order_detail_id) +); + +-- Reference: Order_meeting_studies_Order_details (table: Order_module_studies) +ALTER TABLE Order_module_studies + ADD CONSTRAINT Order_meeting_studies_Order_details + FOREIGN KEY (order_detail_id) + REFERENCES Order_details (order_detail_id); + +-- Reference: Studies_Module_Order_meeting_studies (table: Order_module_studies) +ALTER TABLE Order_module_studies + ADD CONSTRAINT Studies_Module_Order_meeting_studies + FOREIGN KEY (module_id) + REFERENCES Studies_Module (studies_module_id); + +-- Table: Order_studies +CREATE TABLE Order_studies +( + order_detail_id int NOT NULL, + studies_id int NOT NULL, + CONSTRAINT Order_studies_pk PRIMARY KEY (order_detail_id) +); + +-- Reference: Order_studies_Order_details (table: Order_studies) +ALTER TABLE Order_studies + ADD CONSTRAINT Order_studies_Order_details + FOREIGN KEY (order_detail_id) + REFERENCES Order_details (order_detail_id); + +-- Reference: Order_studies_Studies (table: Order_studies) +ALTER TABLE Order_studies + ADD CONSTRAINT Order_studies_Studies + FOREIGN KEY (studies_id) + REFERENCES Studies (studies_id); + + +-- Table: Order_webinars +CREATE TABLE Order_webinars +( + order_detail_id int NOT NULL, + webinar_id int NOT NULL, + CONSTRAINT Order_webinars_pk PRIMARY KEY (order_detail_id) +); + +-- Reference: Order_webinars_Order_details (table: Order_webinars) +ALTER TABLE Order_webinars + ADD CONSTRAINT Order_webinars_Order_details + FOREIGN KEY (order_detail_id) + REFERENCES Order_details (order_detail_id); + +-- Reference: Order_webinars_Webinar_info (table: Order_webinars) +ALTER TABLE Order_webinars + ADD CONSTRAINT Order_webinars_Webinar_info + FOREIGN KEY (webinar_id) + REFERENCES Webinars (webinar_id); + + +-- Table: Orders +CREATE TABLE Orders +( + order_id int NOT NULL IDENTITY (1, 1), + user_id int NOT NULL, + is_paid bit NOT NULL, + max_paid_date datetime NOT NULL, + CONSTRAINT Orders_pk PRIMARY KEY (order_id) +); + +-- Table: Studies +CREATE TABLE Studies +( + studies_id int NOT NULL IDENTITY (1, 1), + studies_name nvarchar(30) NOT NULL, + studies_description nvarchar(300) NOT NULL, + start_date date NOT NULL, + students_limit int NOT NULL, + price money NOT NULL, + studies_coordinator_id int NOT NULL, + visible_from date NOT NULL, + CONSTRAINT studies_price_check CHECK (price >= 0), + CONSTRAINT Studies_pk PRIMARY KEY (studies_id) +); + +-- Reference: Studies_Employees (table: Studies) +ALTER TABLE Studies + ADD CONSTRAINT Studies_Employees + FOREIGN KEY (studies_coordinator_id) + REFERENCES Employees (employee_id); + + +-- Table: Studies_Module +CREATE TABLE Studies_Module +( + studies_module_id int NOT NULL IDENTITY (1, 1), + module_type_id int NOT NULL, + module_name nvarchar(30) NOT NULL, + studies_id int NOT NULL, + price_for_module money NOT NULL, + CONSTRAINT price_check CHECK (price_for_module >= 0), + CONSTRAINT studies_module_id PRIMARY KEY (studies_module_id) +); + +-- Reference: Studiies_Module_Studies (table: Studies_Module) +ALTER TABLE Studies_Module + ADD CONSTRAINT Studiies_Module_Studies + FOREIGN KEY (studies_id) + REFERENCES Studies (studies_id); + +-- Reference: Studiies_Module_module_type (table: Studies_Module) +ALTER TABLE Studies_Module + ADD CONSTRAINT Studiies_Module_module_type + FOREIGN KEY (module_type_id) + REFERENCES module_type (module_type_id); + + +-- Table: Studies_makeup_meeting_attendance_list +CREATE TABLE Studies_makeup_meeting_attendance_list +( + makeup_list_id int NOT NULL IDENTITY (1, 1), + user_id int NOT NULL, + studies_id int NOT NULL, + meeting_id int NOT NULL, + used bit NOT NULL DEFAULT 0, + CONSTRAINT Studies_makeup_meeting_attendance_list_pk PRIMARY KEY (makeup_list_id) +); + +-- Reference: Studies_makeup_meeting_attendacne_list_Studies_module_meetings (table: Studies_makeup_meeting_attendance_list) +ALTER TABLE Studies_makeup_meeting_attendance_list + ADD CONSTRAINT Studies_makeup_meeting_attendacne_list_Studies_module_meetings + FOREIGN KEY (meeting_id, studies_id) + REFERENCES Studies_module_meetings (meeting_id, studies_id); + +-- Reference: Studies_makeup_meeting_attendacne_list_Users (table: Studies_makeup_meeting_attendance_list) +ALTER TABLE Studies_makeup_meeting_attendance_list + ADD CONSTRAINT Studies_makeup_meeting_attendacne_list_Users + FOREIGN KEY (user_id) + REFERENCES Users (user_id); + + +-- Table: Studies_meeting_attendance_list +CREATE TABLE Studies_meeting_attendance_list +( + user_id int NOT NULL, + studies_id int NOT NULL, + meeting_id int NOT NULL, + was_present bit NOT NULL, + did_makeup bit NOT NULL DEFAULT 0, + CONSTRAINT Studies_meeting_attendance_list_pk PRIMARY KEY (user_id, studies_id, meeting_id) +); +-- Reference: Studies_meeting_attendance_list_Studies_module_meetings (table: Studies_meeting_attendance_list) +ALTER TABLE Studies_meeting_attendance_list + ADD CONSTRAINT Studies_meeting_attendance_list_Studies_module_meetings + FOREIGN KEY (meeting_id, studies_id) + REFERENCES Studies_module_meetings (meeting_id, studies_id); + +-- Reference: Studies_meeting_attendance_list_Users (table: Studies_meeting_attendance_list) +ALTER TABLE Studies_meeting_attendance_list + ADD CONSTRAINT Studies_meeting_attendance_list_Users + FOREIGN KEY (user_id) + REFERENCES Users (user_id); + + +-- Table: Studies_module_meetings +CREATE TABLE Studies_module_meetings +( + meeting_id int NOT NULL, + studies_id int NOT NULL, + meeting_date datetime NOT NULL, + language_id int NOT NULL, + translator_id int NULL, + lecturer_id int NOT NULL, + duration time NOT NULL, + place_limit int NOT NULL, + module_id int NOT NULL, + topic_id int NOT NULL, + meeting_name nvarchar(30) NOT NULL, + meeting_type_id int NOT NULL, + CONSTRAINT Studies_module_meetings_pk PRIMARY KEY (meeting_id, studies_id) +); + +-- Reference: Studies_module_meetings_Employees (table: Studies_module_meetings) +ALTER TABLE Studies_module_meetings + ADD CONSTRAINT Studies_module_meetings_Employees + FOREIGN KEY (lecturer_id) + REFERENCES Employees (employee_id); + +-- Reference: Studies_module_meetings_Studiies_Module (table: Studies_module_meetings) +ALTER TABLE Studies_module_meetings + ADD CONSTRAINT Studies_module_meetings_Studiies_Module + FOREIGN KEY (module_id) + REFERENCES Studies_Module (studies_module_id); + +-- Reference: Studies_module_meetings_Translators (table: Studies_module_meetings) +ALTER TABLE Studies_module_meetings + ADD CONSTRAINT Studies_module_meetings_Translators + FOREIGN KEY (translator_id) + REFERENCES Translators (translator_id); + +-- Reference: Studies_module_meetings_meeting_type (table: Studies_module_meetings) +ALTER TABLE Studies_module_meetings + ADD CONSTRAINT Studies_module_meetings_meeting_type + FOREIGN KEY (meeting_type_id) + REFERENCES meeting_type (meeting_type_id); + +-- Reference: topics_list_Studies_module_meetings (table: Studies_module_meetings) +ALTER TABLE Studies_module_meetings + ADD CONSTRAINT topics_list_Studies_module_meetings + FOREIGN KEY (topic_id) + REFERENCES topics_list (topic_id); + +-- Table: Studies_stationary_meeting +CREATE TABLE Studies_stationary_meeting +( + id int NOT NULL IDENTITY (1, 1), + studies_id int NOT NULL, + meeting_id int NOT NULL, + classroom nvarchar(6) NOT NULL, + CONSTRAINT Studies_stationary_meeting_pk PRIMARY KEY (id) +); +-- Reference: Studies_module_meeting_stationary_Studies_module_meetings (table: Studies_stationary_meeting) +ALTER TABLE Studies_stationary_meeting + ADD CONSTRAINT Studies_module_meeting_stationary_Studies_module_meetings + FOREIGN KEY (meeting_id, studies_id) + REFERENCES Studies_module_meetings (meeting_id, studies_id); + + +-- Table: Studies_sync_async_meeting +CREATE TABLE Studies_sync_async_meeting +( + id int NOT NULL IDENTITY (1, 1), + studies_id int NOT NULL, + meeting_id int NOT NULL, + access_to datetime NOT NULL, + video_link nvarchar(30) NOT NULL, + stream_link nvarchar(30) NULL, + CONSTRAINT Studies_sync_async_meeting_pk PRIMARY KEY (id) +); +-- Reference: Studies_sync_async_meeting_Studies_module_meetings (table: Studies_sync_async_meeting) +ALTER TABLE Studies_sync_async_meeting + ADD CONSTRAINT Studies_sync_async_meeting_Studies_module_meetings + FOREIGN KEY (meeting_id, studies_id) + REFERENCES Studies_module_meetings (meeting_id, studies_id); + + +-- Table: Translators +CREATE TABLE Translators +( + translator_id int NULL IDENTITY (1, 1), + employee_id int NOT NULL, + CONSTRAINT Translators_pk PRIMARY KEY (translator_id) +); + +-- Reference: Translators_Employees (table: Translators) +ALTER TABLE Translators + ADD CONSTRAINT Translators_Employees + FOREIGN KEY (employee_id) + REFERENCES Employees (employee_id); + + +-- Table: Translators_languages_used +CREATE TABLE Translators_languages_used +( + id int NOT NULL IDENTITY (1, 1), + translator_id int NOT NULL, + language_id int NOT NULL, + CONSTRAINT Translators_languages_used_pk PRIMARY KEY (id) +); + +-- Reference: Translators_languages_used_Languages (table: Translators_languages_used) +ALTER TABLE Translators_languages_used + ADD CONSTRAINT Translators_languages_used_Languages + FOREIGN KEY (language_id) + REFERENCES Languages (language_id); + +-- Reference: Translators_languages_used_Translators (table: Translators_languages_used) +ALTER TABLE Translators_languages_used + ADD CONSTRAINT Translators_languages_used_Translators + FOREIGN KEY (translator_id) + REFERENCES Translators (translator_id); + + +-- Table: Users +CREATE TABLE Users +( + user_id int NOT NULL IDENTITY (1, 1), + email nvarchar(50) NOT NULL, + first_name nvarchar(30) NOT NULL, + last_name nvarchar(30) NOT NULL, + city_id int NOT NULL, + country_id int NOT NULL, + phone nvarchar(9) NOT NULL CHECK (PATINDEX('%[^0-9]%', phone) = 0 AND LEN(phone) = 9), + street nvarchar(30) NOT NULL, + house_number int NOT NULL, + birth_date date NOT NULL, + CONSTRAINT users_birth_date_check CHECK (datediff(year, birth_date, getdate()) < 100), + CONSTRAINT Users_pk PRIMARY KEY (user_id) +); +-- Reference: Cities_Users (table: Users) +ALTER TABLE Users + ADD CONSTRAINT Cities_Users + FOREIGN KEY (city_id) + REFERENCES Cities (city_id); + +-- Reference: Countries_Users (table: Users) +ALTER TABLE Users + ADD CONSTRAINT Countries_Users + FOREIGN KEY (country_id) + REFERENCES Countries (country_id); + +-- Table: Webinars +CREATE TABLE Webinars +( + webinar_id int NOT NULL IDENTITY (1, 1), + name nvarchar(30) NOT NULL, + description nvarchar(300) NOT NULL, + teacher_id int NOT NULL, + price money NOT NULL, + can_buy_from date NOT NULL, + recording_link nvarchar(30) NOT NULL, + start_date date NOT NULL, + CONSTRAINT webinar_price_check CHECK (price >= 0), + CONSTRAINT Webinars_pk PRIMARY KEY (webinar_id) +); + +-- Reference: Webinar_info_Employees (table: Webinars) +ALTER TABLE Webinars + ADD CONSTRAINT Webinar_info_Employees + FOREIGN KEY (teacher_id) + REFERENCES Employees (employee_id); + + +-- Table: meeting_type +CREATE TABLE meeting_type +( + meeting_type_id int NOT NULL IDENTITY (1, 1), + meeting_name nvarchar(30) NOT NULL, + CONSTRAINT meeting_type_pk PRIMARY KEY (meeting_type_id) +); + +-- Table: module_type +CREATE TABLE module_type +( + module_type_id int NOT NULL IDENTITY (1, 1), + module_name nvarchar(30) NOT NULL, + CONSTRAINT module_type_pk PRIMARY KEY (module_type_id) +); + +-- Table: topics_list +CREATE TABLE topics_list +( + topic_id int NOT NULL IDENTITY (1, 1), + topic_name nvarchar(30) NOT NULL, + topic_description nvarchar(300) NOT NULL, + CONSTRAINT topics_list_pk PRIMARY KEY (topic_id) +); + + +-- End of file. + diff --git a/db_logic/functions/check_course_places_left.sql b/db_logic/functions/check_course_places_left.sql new file mode 100644 index 0000000..616f9d6 --- /dev/null +++ b/db_logic/functions/check_course_places_left.sql @@ -0,0 +1,10 @@ +-- sprawdza ile zostało wolnych miejsc na na kursie +create function check_course_places_left(@course_id int) + returns int as +begin + declare @limit int; + declare @result int; +select @limit = students_limit from Courses where course_id = @course_id; +select @result = @limit - (select count(*) from courses_enrolled_list where course_id = @course_id); +return @result; +end \ No newline at end of file diff --git a/db_logic/functions/check_if_user_pass_studies.sql b/db_logic/functions/check_if_user_pass_studies.sql new file mode 100644 index 0000000..293b830 --- /dev/null +++ b/db_logic/functions/check_if_user_pass_studies.sql @@ -0,0 +1,48 @@ +-- sprawdza czy student ma zaliczone wszystkie przedmioty z danego semestru, +-- frekwencje na poziomie 80% oraz 100% na praktykach +create function check_if_user_pass_studies(@studies_id int, @user_id int) + returns bit as +begin + declare @total_attendance float; + declare @intership_absence int; + declare @exam_grade float; + declare @enrolled bit; + +-- jesli nie jest zapisany na dany przedmiot to nie zalicza + select @enrolled = count(*) from studies_enrolled_list + where studies_id = @studies_id + and user_id = @user_id; + + if @enrolled = 0 + return 0; + +-- jesli nie ma 80% frekwencji to nie zalicza + select @total_attendance = dbo.get_user_attendance_percentage(@studies_id, @user_id); + + if @total_attendance < 80 + return 0; + +-- jesli ma nieobecnosci na praktykach to nie zalicza + select @intership_absence = count(*) from Intership_meeting_attendance_list + where studies_id = @studies_id + and user_id = @user_id + and was_present = 0; + + if @intership_absence > 0 + return 0; + +-- jesli ma niezaliczony egzamin to nie zalicza + select @exam_grade = grade from Exams + where studies_id = @studies_id + and user_id = @user_id; + + if @exam_grade is null or @exam_grade < 3 + return 0; + + + +-- w przeciwnym wypadku zalicza + return 1; + +end + diff --git a/db_logic/functions/check_studies_places_left.sql b/db_logic/functions/check_studies_places_left.sql new file mode 100644 index 0000000..8c04746 --- /dev/null +++ b/db_logic/functions/check_studies_places_left.sql @@ -0,0 +1,10 @@ +-- sprawdza ile zostało wolnych miejsc na na studiach +create function check_studies_places_left(@studies_id int) + returns int as +begin + declare @limit int; + declare @result int; +select @limit = students_limit from Studies where studies_id = @studies_id; +select @result = @limit - (select count(*) from studies_enrolled_list sel where studies_id = @studies_id); +return @result; +end \ No newline at end of file diff --git a/db_logic/functions/get_average_grade_in_exam.sql b/db_logic/functions/get_average_grade_in_exam.sql new file mode 100644 index 0000000..4744160 --- /dev/null +++ b/db_logic/functions/get_average_grade_in_exam.sql @@ -0,0 +1,10 @@ +-- Sprawdza średnią ocenę w egzaminie dla danego przedmiotu, I guess +create function get_average_grade_in_exam(@studies_id int) + returns float +as +begin + declare @average float; + select @average = avg(grade) from Exams where studies_id = @studies_id; + return @average; +end +go diff --git a/db_logic/functions/get_learning_progress_of_a_student.sql b/db_logic/functions/get_learning_progress_of_a_student.sql new file mode 100644 index 0000000..55acfba --- /dev/null +++ b/db_logic/functions/get_learning_progress_of_a_student.sql @@ -0,0 +1,25 @@ +create function get_learning_progress_of_a_student(@user_id int) + returns table + as + return ( + select @user_id, topid_id from + ( + select topic_id from Studies_meeting_attendance_list + inner join Studies_module_meetings on + Studies_module_meetings.studies_id = Studies_meeting_attendance_list.studies_id + where user_id = @user_id and was_present = 1 + union + select topic_id from Studies_makeup_attendance_list + inner join Studies_module_meetings on + Studies_module_meetings.studies_id = Studies_makeup_attendance_list.studies_id + where user_id = @user_id + ) as covered_topics inner join topics_list on + topics_list.topic_id = covered_topics.topic_id + ); +-- +-- try +-- begin transaction +-- end +-- catch +-- rollback +-- throw diff --git a/db_logic/functions/get_total_order_cost.sql b/db_logic/functions/get_total_order_cost.sql new file mode 100644 index 0000000..48489ee --- /dev/null +++ b/db_logic/functions/get_total_order_cost.sql @@ -0,0 +1,10 @@ +create function get_total_order_cost(@order_id int) + returns int + as + begin + declare @total_cost float + select @total_cost = sum(price) from Order_details where order_id = @order_id + return @total_cost + end +go + diff --git a/db_logic/functions/get_user_attendance.sql b/db_logic/functions/get_user_attendance.sql new file mode 100644 index 0000000..e3cc187 --- /dev/null +++ b/db_logic/functions/get_user_attendance.sql @@ -0,0 +1,28 @@ +CREATE FUNCTION get_user_attendance_percentage +( + @studies_id INT, + @user_id INT +) + RETURNS FLOAT +AS +BEGIN + DECLARE @total_meetings INT; + DECLARE @present_meetings INT; + + SELECT @total_meetings = COUNT(*) + FROM Studies_module_meetings + WHERE studies_id = @studies_id; + + SELECT @present_meetings = COUNT(*) + FROM Studies_meeting_attendance_list + WHERE studies_id = @studies_id + AND user_id = @user_id + AND (was_present = 1 OR did_makeup = 1); + + -- Jeśli brak spotkań, zwróć 0 (unikamy dzielenia przez 0) + IF @total_meetings = 0 + RETURN 0; + + -- Zwróć procent obecności + RETURN CAST(@present_meetings AS FLOAT) / CAST(@total_meetings AS FLOAT) * 100; +END; diff --git a/db_logic/functions/get_uset_schedule.sql b/db_logic/functions/get_user_schedule.sql similarity index 100% rename from db_logic/functions/get_uset_schedule.sql rename to db_logic/functions/get_user_schedule.sql diff --git a/db_logic/functions/was_user_present_in_a_topic.sql b/db_logic/functions/was_user_present_in_a_topic.sql new file mode 100644 index 0000000..2e05677 --- /dev/null +++ b/db_logic/functions/was_user_present_in_a_topic.sql @@ -0,0 +1,25 @@ +create function was_user_present_in_a_topic ( @topic_id int, @user_id int) +returns bit +begin + declare @result bit = 0; + + if @user_id in (select user_id from dbo.Studies_meeting_attendance_list + inner join dbo.Studies_module_meetings on + dbo.Studies_module_meetings.meeting_id = dbo.Studies_meeting_attendance_list.meeting_id and + dbo.Studies_module_meetings.studies_id = dbo.Studies_meeting_attendance_list.studies_id + where topic_id = @topic_id + ) or ( + @user_id in (select user_id from dbo.Studies_makeup_meeting_attendance_list + inner join dbo.Studies_module_meetings on + dbo.Studies_module_meetings.meeting_id = dbo.Studies_makeup_meeting_attendance_list.meeting_id and + dbo.Studies_module_meetings.studies_id = dbo.Studies_makeup_meeting_attendance_list.studies_id + where topic_id = @topic_id + )) + begin + set @result = 1; + end + + return @result +end +go + diff --git a/db_logic/procedures/add_city.sql b/db_logic/procedures/add_city.sql new file mode 100644 index 0000000..df5f795 --- /dev/null +++ b/db_logic/procedures/add_city.sql @@ -0,0 +1,17 @@ +-- Create a stored procedure to add a new city +CREATE PROCEDURE add_city + @CityName NVARCHAR(30) -- Parameter for the city name +AS +BEGIN + IF @CityName IS NULL OR LTRIM(RTRIM(@CityName)) = '' + BEGIN + THROW 50005, 'City name cannot be empty', 16; + END + + BEGIN + INSERT INTO Cities (city_name) + VALUES (@CityName); + END +END; +go + diff --git a/db_logic/procedures/add_employee.sql b/db_logic/procedures/add_employee.sql new file mode 100644 index 0000000..4b3745a --- /dev/null +++ b/db_logic/procedures/add_employee.sql @@ -0,0 +1,38 @@ +CREATE PROCEDURE add_employee( + @FirstName NVARCHAR(30), + @LastName NVARCHAR(30), + @HireDate DATE, + @BirthDate DATE, + @Phone NVARCHAR(9), + @Email NVARCHAR(50), + @RoleID INT, + @CityID INT, + @CountryID INT +) +AS +BEGIN + INSERT INTO Employees ( + first_name, + last_name, + hire_date, + birth_date, + phone, + email, + role_id, + city_id, + country_id + ) + VALUES ( + @FirstName, + @LastName, + @HireDate, + @BirthDate, + @Phone, + @Email, + @RoleID, + @CityID, + @CountryID + ); + END; +go + diff --git a/db_logic/procedures/add_event_type.sql b/db_logic/procedures/add_event_type.sql new file mode 100644 index 0000000..05e36bd --- /dev/null +++ b/db_logic/procedures/add_event_type.sql @@ -0,0 +1,12 @@ +CREATE PROCEDURE add_event_type + @event_name NVARCHAR(30) +AS +BEGIN + BEGIN + INSERT INTO Event_types (event_name) + VALUES (@event_name); + + END +END; +go + diff --git a/db_logic/procedures/add_exams.sql b/db_logic/procedures/add_exams.sql new file mode 100644 index 0000000..58a0f12 --- /dev/null +++ b/db_logic/procedures/add_exams.sql @@ -0,0 +1,15 @@ +create procedure add_exams (@studies_id int, @user_id int, @grade int) +as begin + if exists ( select 1 from dbo.studies_enrolled_list + where dbo.studies_enrolled_list.studies_id = @studies_id + and dbo.studies_enrolled_list.user_id = @user_id + ) + begin + insert into Exams (studies_id, user_id, grade) values (@studies_id,@user_id,@grade); + print 'Values added!'; + end + else + throw 50020, 'There is not such student that is enrolled in this course', 1; +end +go + diff --git a/db_logic/procedures/add_internship_meeting.sql b/db_logic/procedures/add_internship_meeting.sql new file mode 100644 index 0000000..5b16989 --- /dev/null +++ b/db_logic/procedures/add_internship_meeting.sql @@ -0,0 +1,17 @@ +create procedure add_internship_meeting +( @studies_id int, @meeting_date datetime ) +as begin + + if exists ( select 1 from Studies where studies_id = @studies_id) + begin + insert into Intership_meetings (studies_id, meetind_date) + values (@studies_id, @meeting_date); + print 'Values added'; + end + else + begin + throw 50020, 'Value could not be added',16; + end +end +go + diff --git a/db_logic/procedures/add_product_to_order.sql b/db_logic/procedures/add_product_to_order.sql new file mode 100644 index 0000000..16c5bcb --- /dev/null +++ b/db_logic/procedures/add_product_to_order.sql @@ -0,0 +1,137 @@ +-- dodanie produktu do ISTNIEJACEGO zamówienia +create procedure add_product_to_order @order_id int, + @product_id int, + @product_type_id int +as +begin + declare @is_order_exists bit; + declare @is_product_exists bit; + declare @product_type varchar(50); + declare @product_price decimal(10, 2); + declare @order_detail_id int; + + begin TRY + set transaction isolation level serializable; + begin transaction; + -- Sprawdzenie, czy zamówienie istnieje + select @is_order_exists = case + when exists (select 1 + from dbo.orders + where order_id = @order_id) then 1 + else 0 end; + + if @is_order_exists = 0 + begin + throw 50001, 'Zamówienie o podanym ID nie istnieje.', 1; + end + +-- sprawdzenie typu produktu + select @product_type = event_name + from Event_types + where type_id = @product_type_id; + + if @product_type is null + begin + throw 50002, 'Nieprawidłowy typ produktu.', 1; + end + + -- Sprawdzenie, czy produkt istnieje + select @is_product_exists = case + when @product_type = 'Webinar' then + IIF(exists (select 1 + from dbo.webinars + where webinar_id = @product_id), 1, 0) + when @product_type = 'Course' then + IIF(exists (select 1 + from dbo.courses + where course_id = @product_id), 1, 0) + when @product_type = 'Studies' then + IIF(exists (select 1 + from dbo.studies + where studies_id = @product_id), 1, 0) + when @product_type = 'Study_Module' then + IIF(exists (select 1 + from dbo.Studies_Module + where studies_module_id = @product_id), 1, 0) + else 0 + end + + + -- jeśli produkt nie istnieje + if @is_product_exists = 0 + begin + throw 50003, 'Produkt o podanym ID nie istnieje.', 1; + end + + -- pobranie ceny produktu + select @product_price = case + when @product_type = 'Webinar' then + (select price from webinars where webinar_id = @product_id) + when @product_type = 'Course' then + (select price from courses where course_id = @product_id) + when @product_type = 'Studies' then + (select price from studies where studies_id = @product_id) + when @product_type = 'Study_Module' then + (select price_for_module + from Studies_Module + where studies_module_id = @product_id) + else 0 + end + +-- dodanie produktu do order_details + insert into Order_details (order_id, type_id, price) + values (@order_id, @product_type_id, @product_price); + select @order_detail_id = SCOPE_IDENTITY(); + +-- dodanie zakupu do odpowiedniej tabeli + if @product_type = 'Webinar' + begin + -- id z order_details i id webinaru + insert into Order_webinars (order_detail_id, webinar_id) + values (@order_detail_id, @product_id); + end + +-- jesli to kurs i dodatkowo czy są wolne miejsca + else if @product_type = 'Course' + begin + if dbo.check_course_places_left(@product_id) > 0 + begin + insert into Order_course (order_detail_id, course_id) + values (@order_detail_id, @product_id); + end + else + begin + throw 50004, 'Brak miejsc na kurs.', 1; + end + end + + else if @product_type = 'Studies' + begin + if dbo.check_studies_places_left(@product_id) > 0 + begin + insert into Order_studies (order_detail_id, studies_id) + values (@order_detail_id, @product_id); + end + else + begin + throw 50005, 'Brak miejsc na studia.', 1; + end + end + + +-- dla modułów bez limitu miejsc + else if @product_type = 'Study_Module' + begin + insert into Order_module_studies (order_detail_id, module_id) + values (@order_detail_id, @product_id); + end + commit transaction; + + SELECT * FROM Order_details WHERE order_id = @order_id; + end TRY + begin CATCH + if @@TRANCOUNT > 0 + rollback transaction; + throw; + end CATCH +end \ No newline at end of file diff --git a/db_logic/procedures/add_study.sql b/db_logic/procedures/add_study.sql new file mode 100644 index 0000000..d982cb9 --- /dev/null +++ b/db_logic/procedures/add_study.sql @@ -0,0 +1,25 @@ +create procedure add_study( + @study_id int output , + @studies_name nvarchar(30), + @studies_description nvarchar(300), + @start_date date, + @students_limit int, + @price money, + @studies_coordinator_id int, + @visible_from date +) as + begin + if @students_limit <= 0 + throw 50000, 'Students limit has to be positive',11; + else if @price < 0 + throw 50001, 'Price cannot be negative',16; + + if not exists(select 1 from dbo.Employees where employee_id = @studies_coordinator_id) + throw 50002, 'Coordinator ID does not exist', 11; + + insert into dbo.Studies (studies_name, studies_description, start_date, students_limit, price, studies_coordinator_id, visible_from) + values (@studies_name,@studies_description,@start_date, + @students_limit, @price, @studies_coordinator_id, @visible_from) + end; +go + diff --git a/db_logic/procedures/add_topic.sql b/db_logic/procedures/add_topic.sql new file mode 100644 index 0000000..b96c247 --- /dev/null +++ b/db_logic/procedures/add_topic.sql @@ -0,0 +1,18 @@ +create procedure add_topic( + @topic_name nvarchar(30), + @topic_description nvarchar(30) +) +as +begin + if not exists ( + select 1 + from dbo.topics_list + where topic_name = @topic_name + ) + begin + insert into dbo.topics_list (topic_name, topic_description) + values (@topic_name, @topic_description); + end +END; +go + diff --git a/db_logic/procedures/add_webinar.sql b/db_logic/procedures/add_webinar.sql new file mode 100644 index 0000000..2f59508 --- /dev/null +++ b/db_logic/procedures/add_webinar.sql @@ -0,0 +1,24 @@ +CREATE PROCEDURE add_webinar + @name nvarchar(30), + @description nvarchar(300), + @teacher_id int, + @price money, + @can_buy_from date, + @recording_link nvarchar(30), + @start_date date +AS +BEGIN + + IF @price < 0 + BEGIN + THROW 50010, 'Cena musi być dodatnia', 16; + RETURN; + END + + INSERT INTO Webinars (name, description, teacher_id, price, can_buy_from, recording_link, start_date) + VALUES (@name, @description, @teacher_id, @price, @can_buy_from, @recording_link, @start_date); + + PRINT 'Webinar został dodany'; +END; +go + diff --git a/db_logic/procedures/alter_limit_of_courses.sql b/db_logic/procedures/alter_limit_of_courses.sql new file mode 100644 index 0000000..0af2b47 --- /dev/null +++ b/db_logic/procedures/alter_limit_of_courses.sql @@ -0,0 +1,24 @@ +CREATE PROCEDURE alter_limit_of_courses + @course_id INT, + @new_limit INT +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @current_enrolled_students INT; + + SELECT @current_enrolled_students = COUNT(*) + FROM Order_course + WHERE course_id = @course_id; + + IF @new_limit < @current_enrolled_students + BEGIN + THROW 50018, 'There are more current enrolled students than the new limit.', 16; + END + ELSE + BEGIN + UPDATE Course_module_meetings + SET place_limit = @new_limit + WHERE course_id = @course_id; + END +END; \ No newline at end of file diff --git a/db_logic/procedures/alter_limit_of_studies.sql b/db_logic/procedures/alter_limit_of_studies.sql new file mode 100644 index 0000000..d24dbc8 --- /dev/null +++ b/db_logic/procedures/alter_limit_of_studies.sql @@ -0,0 +1,25 @@ +CREATE PROCEDURE alter_limit_of_studies + @studies_id INT, + @new_limit INT +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @current_enrolled_students INT; + + SELECT @current_enrolled_students = COUNT(*) + FROM Order_studies + WHERE studies_id = @studies_id; + + + IF @new_limit < @current_enrolled_students + BEGIN + THROW 50003, 'There are more current enrolled students than the new limit.', 16; + END + ELSE + BEGIN + UPDATE Studies_module_meetings + SET place_limit = @new_limit + WHERE studies_id = @studies_id; + END +END; \ No newline at end of file diff --git a/db_logic/procedures/create_study.sql b/db_logic/procedures/create_study.sql new file mode 100644 index 0000000..936be3c --- /dev/null +++ b/db_logic/procedures/create_study.sql @@ -0,0 +1,25 @@ +create procedure create_study( + @study_id int output , + @studies_name nvarchar(30), + @studies_description nvarchar(300), + @start_date date, + @students_limit int, + @price money, + @studies_coordinator_id int, + @visible_from date +) as + begin + if @students_limit <= 0 + throw 50000, 'Students limit has to be positive',11; + else if @price < 0 + throw 50001, 'Price cannot be negative',16; + + if not exists(select 1 from dbo.Employees where employee_id = @studies_coordinator_id) + throw 50002, 'Coordinator ID does not exist', 11; + + insert into dbo.Studies (studies_name, studies_description, start_date, students_limit, price, studies_coordinator_id, visible_from) + values (@studies_name,@studies_description,@start_date, + @students_limit, @price, @studies_coordinator_id, @visible_from) + end; +go + diff --git a/db_logic/procedures/get_user_attendance_procedure.sql b/db_logic/procedures/get_user_attendance_procedure.sql new file mode 100644 index 0000000..8f40ff9 --- /dev/null +++ b/db_logic/procedures/get_user_attendance_procedure.sql @@ -0,0 +1,53 @@ +-- sprawdza % obecnosci studenta na zajeciach + +create procedure get_user_attendance_procedure @studies_id int, @user_id int, @result float output +as +begin + declare @meeting_id int; + declare @was_present bit; + declare @did_makeup bit; + declare @total_meetings int = 0; + declare @present_meetings int = 0; + + declare @status int; + + declare attendance_cursor cursor for + select meeting_id, was_present, did_makeup + from Studies_meeting_attendance_list + where studies_id = @studies_id + and user_id = @user_id; + +-- dla kazdego rekordu w attendance_list sprawdz czy student byl obecny, jesli nie to sprawdz czy odrobil zajecia + open attendance_cursor; + fetch next from attendance_cursor into @meeting_id, @was_present, @did_makeup; + while @@fetch_status = 0 + begin + if @was_present = 1 + set @present_meetings = @present_meetings + 1; + else + if @did_makeup = 1 + set @present_meetings = @present_meetings + 1; + else + begin + -- jesli student nie byl obecny i nie odrobil zajec to sprawdz czy ma odrobione zajecia + exec @status = set_attendance_for_student_that_makeup_meeting + @studies_id, + @meeting_id, + @user_id; + if @status = 0 + begin + set @present_meetings = @present_meetings + 1; + end + + end + set @total_meetings = @total_meetings + 1; + fetch next from attendance_cursor into @meeting_id, @was_present, @did_makeup; + end + close attendance_cursor; + deallocate attendance_cursor; + + if @total_meetings = 0 + set @result = 0; + else + set @result = @present_meetings / @total_meetings; +end \ No newline at end of file diff --git a/db_logic/procedures/set_attendance_for_student_that_makeup_meeting.sql b/db_logic/procedures/set_attendance_for_student_that_makeup_meeting.sql index 0b1ee0e..01f6cdd 100644 --- a/db_logic/procedures/set_attendance_for_student_that_makeup_meeting.sql +++ b/db_logic/procedures/set_attendance_for_student_that_makeup_meeting.sql @@ -9,19 +9,36 @@ BEGIN declare @makeup_meeting_id INT; declare @topic_id INT; - select @topic_id = topic_id from Studies_module_meetings where meeting_id = @meeting_id and studies_id = @studies_id; - - select top 1 @makeup_meeting_id = makeup_list_id from Studies_makeup_meeting_attendance_list smmal - join Studies_module_meetings smm on smmal.meeting_id = smm.meeting_id and smmal.studies_id = smm.studies_id - where topic_id = @topic_id and user_id = @user_id and smmal.used = 0; + select @topic_id = topic_id + from Studies_module_meetings + where meeting_id = @meeting_id + and studies_id = @studies_id; + + select top 1 @makeup_meeting_id = makeup_list_id + from Studies_makeup_meeting_attendance_list smmal + join Studies_module_meetings smm on smmal.meeting_id = smm.meeting_id and smmal.studies_id = smm.studies_id + where topic_id = @topic_id + and user_id = @user_id + and smmal.used = 0; if @makeup_meeting_id is not null begin update Studies_makeup_meeting_attendance_list set used = 1 where makeup_list_id = @makeup_meeting_id; - update Studies_meeting_attendance_list set did_makeup = 1 where meeting_id = @meeting_id and studies_id = @studies_id and user_id = @user_id; - end + update Studies_meeting_attendance_list + set did_makeup = 1 + where meeting_id = @meeting_id + and studies_id = @studies_id + and user_id = @user_id; + return 0; + end + else + begin +-- jednak zwracanie succes/failure bo wykorzystujemy w check_user_attendance + return 1; +-- raiserror ('Student did not make up the meeting', 16, 1); + end END; diff --git a/db_logic/procedures/check_course_attendance.sql b/db_logic/procedures/update_course_attendance.sql similarity index 93% rename from db_logic/procedures/check_course_attendance.sql rename to db_logic/procedures/update_course_attendance.sql index ab1347d..b5ad82a 100644 --- a/db_logic/procedures/check_course_attendance.sql +++ b/db_logic/procedures/update_course_attendance.sql @@ -1,6 +1,6 @@ -- jeśli użytkownik jest zapisany na podane studia ustaw ze byl obecny -CREATE PROCEDURE check_course_attendance @user_id INT, +CREATE PROCEDURE update_course_attendance @user_id INT, @course_id INT, @meeting_id INT AS diff --git a/db_logic/procedures/check_for_students_that_missed_meeting.sql b/db_logic/procedures/update_students_that_missed_meeting.sql similarity index 91% rename from db_logic/procedures/check_for_students_that_missed_meeting.sql rename to db_logic/procedures/update_students_that_missed_meeting.sql index 44ac1a4..5ed75a1 100644 --- a/db_logic/procedures/check_for_students_that_missed_meeting.sql +++ b/db_logic/procedures/update_students_that_missed_meeting.sql @@ -1,6 +1,6 @@ -- dla wszystkich użytkowników, którzy nie maja zaznaczonej obencości na zajęciach ustaw, że byli na nich nieobecni -CREATE PROCEDURE check_for_students_that_missed_meeting @studies_id INT, +CREATE PROCEDURE update_students_that_missed_meeting @studies_id INT, @meeting_id INT AS BEGIN diff --git a/db_logic/procedures/check_studies_attendance.sql b/db_logic/procedures/update_studies_attendance.sql similarity index 95% rename from db_logic/procedures/check_studies_attendance.sql rename to db_logic/procedures/update_studies_attendance.sql index 09b1359..513560d 100644 --- a/db_logic/procedures/check_studies_attendance.sql +++ b/db_logic/procedures/update_studies_attendance.sql @@ -1,6 +1,6 @@ -- sprawdzanie obecnosci -CREATE PROCEDURE check_studies_attendance @user_id INT, +CREATE PROCEDURE update_studies_attendance @user_id INT, @studies_id INT, @meeting_id INT AS diff --git a/db_logic/triggers/update_order_pay_date.sql b/db_logic/triggers/update_order_pay_date.sql new file mode 100644 index 0000000..59cb425 --- /dev/null +++ b/db_logic/triggers/update_order_pay_date.sql @@ -0,0 +1,89 @@ +-- DROP TRIGGER IF EXISTS update_order_pay_date; + +-- po dodaniu zamówienia sprawdza czy data zamówienia jest wcześniejsza niż data ostatniego opłaconego produktu +create trigger update_order_pay_date + on Order_details + after insert + as +begin + declare @order_id int; + declare @product_type_id int; + declare @product_type varchar(50); + declare @product_id int; + declare @order_detail_id int; + declare @start_date date; + + declare inserted_cursor cursor for + select order_id, type_id, order_detail_id + from inserted; + + open inserted_cursor; + fetch next from inserted_cursor into @order_id, @product_type_id, @order_detail_id; + + while @@FETCH_STATUS = 0 + begin + select @product_type = case + when @product_type_id = 1 then 'Webinar' + when @product_type_id = 2 then 'Course' + when @product_type_id = 3 then 'Studies' + when @product_type_id = 4 then 'Study_Module' + else 'Unknown' + end; + + if @product_type = 'Course' + begin + select @product_id = course_id + from Order_course + where order_detail_id = @order_detail_id; + + select @start_date = start_date + from Courses + where course_id = @product_id; + end + else if @product_type = 'Studies' + begin + select @product_id = studies_id + from Order_studies + where order_detail_id = @order_detail_id; + + select @start_date = start_date + from Studies + where studies_id = @product_id; + end + else if @product_type = 'Webinar' + begin + select @product_id = webinar_id + from Order_webinars + where order_detail_id = @order_detail_id; + + select @start_date = start_date + from Webinars + where webinar_id = @product_id; + end + else if @product_type = 'Study_Module' + begin + select @product_id = module_id + from Order_module_studies + where order_detail_id = @order_detail_id; + + select @start_date = min(meeting_date) + from Studies_module_meetings + where module_id = @product_id; + end + else + begin + fetch next from inserted_cursor into @order_id, @product_type_id, @order_detail_id; + continue; + end + + update Orders + set max_paid_date = dateadd(day, -3, @start_date) + where order_id = @order_id + and max_paid_date < dateadd(day, -3, @start_date); + + fetch next from inserted_cursor into @order_id, @product_type_id, @order_detail_id; + end + + close inserted_cursor; + deallocate inserted_cursor; +end \ No newline at end of file diff --git a/db_logic/views/lecturer_topics.sql b/db_logic/views/lecturer_topics.sql new file mode 100644 index 0000000..6103167 --- /dev/null +++ b/db_logic/views/lecturer_topics.sql @@ -0,0 +1,6 @@ +select Employees.employee_id, concat(Employees.first_name, ' ', Employees.last_name) as full_name, topic_name + from Employees + inner join Studies_module_meetings on + Employees.employee_id = Studies_module_meetings.lecturer_id + inner join topics_list on + Studies_module_meetings.topic_id = topics_list.topic_id \ No newline at end of file diff --git a/docs/database_descriptions/database_diagram.md b/docs/database_descriptions/database_diagram.md index d510450..ca2c5b2 100644 --- a/docs/database_descriptions/database_diagram.md +++ b/docs/database_descriptions/database_diagram.md @@ -1,6 +1,6 @@ # Diagram bazy danych -![diagram](./docs/images/diagram.png) +![diagram](../images/diagram.png) [diagram w wersji svg](https://bleidhu.github.io/Introduction__To_Databases_2024_AGH_Project/images/diagram.svg) diff --git a/docs/images/diagram.png b/docs/images/diagram.png index 6299f0e..8e9939a 100644 Binary files a/docs/images/diagram.png and b/docs/images/diagram.png differ diff --git a/docs/images/diagram.svg b/docs/images/diagram.svg index da0ee16..0a2bd0d 100644 --- a/docs/images/diagram.svg +++ b/docs/images/diagram.svg @@ -1,4 +1,4 @@ -{"leftTopX": 4578, "leftTopY": 6976, "rightBottomX": 7517, "rightBottomY": 9553}CourseWebinarPeopleStudiesOrders and PaymentsUsersuser_idemailfirst_namelast_namecity_idcountry_idphonestreethouse_numberbirth_dateintnvarchar(50)nvarchar(30)nvarchar(30)intintnvarchar(9)nvarchar(30)intdatePKFKFKCoursescourse_idcourse_namecourse_descriptionstart_datestudents_limitpricecourse_coordinatorvisible_fromintnvarchar(30)nvarchar(300)dateintmoneyintdatePKFKmodule_typemodule_type_imodule_namemodule_typeintnvarchar(30)nvarchar(30)PKCourse_module_meetingscourse_idmeeting_idmeeting_datelanguage_idtranslator_idlecturer_iddurationplace_limitmodule_idmeeting_type_idmeeting_nameintintdatetimeintintinttimeintintintnvarchar(30)PKPKFKFKFKFKFKCourse_module_meeting_stationaidcourse_idmeeting_idclassroomintintintnvarchar(10)PKFKFKEmployeesemployee_idfirst_namelast_namehire_datebirth_datephoneemailrole_idcity_idcountry_idintnvarchar(30)nvarchar(30)datedatenvarchar(9)nvarchar(50)intintintPKFKFKFKWebinar_infowebinar_idteacher_idpricecan_buy_fromrecording_linkstart_dateintintmoneydatenvarchar(30)datePKFKEmployee_Rolesrole_idemployee_irole_nameintintintPKLanguageslanguage_idlanguage_naintnvarchar(30)PKCountriescountry_idcountry_naintnvarchar(30)PKCourse_sync_async_meetingidcourse_idmeeting_idaccessTovideo_linkstream_linkintintintdatetimenvarchar(30)nvarchar(30)PKFKFKNCourse_meeting_attendance_listuser_idcourse_idmeeting_idwas_presentintintintbitPK FKPK FKPK FKCitiescity_idcity_namintnvarchar(30)PKTranslatorstranslator_idemployee_idintintPKFKTranslators_languages_useidtranslator_idlanguage_idintintintPKFKFKStudiesstudies_idstudies_namestudies_descriptionstart_datestudents_limitpricestudies_coordinatorvisible_fromintnvarchar(30)nvarchar(300)dateintmoneyintdatePKFKStudies_module_meetingsmeeting_idstudies_idmeeting_datelanguage_idtranslator_idlecturer_iddurationplace_limitmodule_idtopic_idmeeting_namemeeting_type_idintintdatetimenvarchar(30)intinttimeintintintnvarchar(30)intPKPKFKFKFKFKFKStudies_sync_async_meetingidstudies_idmeeting_idaccessTovideo_linkstream_linkintintintdatetimenvarchar(30)nvarchar(30)PKFKFKStudies_module_meeting_stationaryidstudies_idmeeting_idclassroomintintintnvarchar(6)PKFKFKStudies_meeting_attendance_listuser_idstudies_idmeeting_idwas_presenttopic_idintintintbitintPK FKPK FKPK FKIntership_meetingsinter_meeting_idstudies_idintership_idmeetind_dateintintintdatetimePKFKIntership_meeting_attendance_listinter_meeting_iduser_idwas_presentintintbitPK FKPK FKOrdersorder_iduser_idis_paidpricemax_paid_daintintbitmoneydatetimePKOrder_detailsorder_detail_idorder_idtype_idintintintPKFKFKEvent_typestype_idevent_nameintnvarchar(30)PKOrder_webinarsorder_detail_idwebinar_idintintPK FKFKOrder_courseorder_detail_idcourse_idintintPK FKFKOrder_studiesorder_detail_idstudies_idintintPK FKFKOrder_module_studiesorder_detail_idmodule_idintintPK FKFKmeeting_typemeeting_typemeeting_typeintnvarchar(30)PKtopics_listtopic_idtopic_nametopic_descriptiintnvarchar(30)nvarchar(30)PKStudies_makeup_meeting_attendancemakeup_list_iduser_idstudies_idmeeting_idtopic_idintintintintintPKFKFKFKExamsstudies_iuser_idgradeintintnumeric(2,1)PK FKPK FKCourse_modulescourse_module_module_type_idmodule_namecourse_idintintnvarcharintPKFKFKStudies_Modulestudies_module_idmodule_type_idmodule_namestudies_idprice_for_free_listenersintintnvarchar(30)intmoneyPKFKFK +{"leftTopX": 4728, "leftTopY": 7126, "rightBottomX": 7667, "rightBottomY": 9703}CourseWebinarPeopleStudiesOrders and PaymentsUsersuser_idemailfirst_namelast_namecity_idcountry_idphonestreethouse_numberbirth_dateintnvarchar(50)nvarchar(30)nvarchar(30)intintnvarchar(9)nvarchar(30)intdatePKFKFKCoursescourse_idcourse_namecourse_descriptionstart_datestudents_limitpricecourse_coordinatorvisible_fromintnvarchar(30)nvarchar(300)dateintmoneyintdatePKFKmodule_typemodule_type_imodule_nameintnvarchar(30)PKCourse_module_meetingscourse_idmeeting_idmeeting_datelanguage_idtranslator_idlecturer_iddurationplace_limitmodule_idmeeting_type_idmeeting_nameintintdatetimeintintinttimeintintintnvarchar(30)PKPKFKFKFKFKFKCourse_stationary_meetingidcourse_idmeeting_idclassroomintintintnvarchar(10)PKFKFKEmployeesemployee_idfirst_namelast_namehire_datebirth_datephoneemailrole_idcity_idcountry_idintnvarchar(30)nvarchar(30)datedatenvarchar(9)nvarchar(50)intintintPKFKFKFKWebinarswebinar_idnamedescriptionteacher_idpricecan_buy_fromrecording_linkstart_dateintnvarchar(30)nvarchar(300)intmoneydatenvarchar(30)datePKFKEmployee_Rolesrole_idrole_naintnvarchar(30)PKLanguageslanguage_idlanguage_naintnvarchar(30)PKCountriescountry_idcountry_naintnvarchar(30)PKCourse_sync_async_meetingidcourse_idmeeting_idaccess_tovideo_linkstream_linkintintintdatetimenvarchar(30)nvarchar(30)PKFKFKNCourse_meeting_attendance_listuser_idcourse_idmeeting_idwas_presentintintintbitPK FKPK FKPK FKCitiescity_idcity_namintnvarchar(30)PKTranslatorstranslator_idemployee_idintintPKFKTranslators_languages_useidtranslator_idlanguage_idintintintPKFKFKStudiesstudies_idstudies_namestudies_descriptionstart_datestudents_limitpricestudies_coordinatorvisible_fromintnvarchar(30)nvarchar(300)dateintmoneyintdatePKFKStudies_module_meetingsmeeting_idstudies_idmeeting_datelanguage_idtranslator_idlecturer_iddurationplace_limitmodule_idtopic_idmeeting_namemeeting_type_idintintdatetimeintintinttimeintintintnvarchar(30)intPKPKN FKFKFKFKFKStudies_sync_async_meetingidstudies_idmeeting_idaccess_tovideo_linkstream_linkintintintdatetimenvarchar(30)nvarchar(30)PKFKFKNStudies_stationary_meetingidstudies_idmeeting_idclassroomintintintnvarchar(6)PKFKFKStudies_meeting_attendance_listuser_idstudies_idmeeting_idwas_presentdid_makeupintintintbitbitPK FKPK FKPK FKIntership_meetingsstudies_idinter_meetingmeetind_dateintintdatetimePK FKPKIntership_meeting_attendance_listinter_meeting_idstudies_iduser_idwas_presentintintintbitPK FKPK FKPK FKOrdersorder_iduser_idis_paidmax_paid_daintintbitdatetimePKOrder_detailsorder_detail_idorder_idtype_idpriceintintintmoneyPKFKFKEvent_typestype_idevent_nameintnvarchar(30)PKOrder_webinarsorder_detail_idwebinar_idintintPK FKFKOrder_courseorder_detail_idcourse_idintintPK FKFKOrder_studiesorder_detail_idstudies_idintintPK FKFKOrder_module_studiesorder_detail_idmodule_idintintPK FKFKmeeting_typemeeting_typemeeting_namintnvarchar(30)PKtopics_listtopic_idtopic_nametopic_descriptiintnvarchar(30)nvarchar(300)PKStudies_makeup_meeting_attendancemakeup_list_iduser_idstudies_idmeeting_idusedintintintintbitPKFKFKFKExamsstudies_iuser_idgradeintintnumeric(2,1)PK FKPK FKCourse_modulescourse_module_module_type_idmodule_namecourse_idintintnvarchar(30)intPKFKFKStudies_Modulestudies_module_idmodule_type_idmodule_namestudies_idprice_for_moduleintintnvarchar(30)intmoneyPKFKFK diff --git a/docs/raports_generation/concatenated_output.md b/docs/raports_generation/concatenated_output.md index a05de90..c6a7cde 100644 --- a/docs/raports_generation/concatenated_output.md +++ b/docs/raports_generation/concatenated_output.md @@ -1,12 +1,13 @@ -# Raport 5 +# Raport Końcowy Zespół 1 Skład zespołu : Paweł Czajczyk Julia Demitraszek -Szymon Rybski # Opis funkcji systemu dla firmy oferującej kursy i szkolenia +Szymon Rybski -- [Raport 5](#raport-5) +- [Raport Końcowy](#raport-końcowy) +- [Opis funkcji systemu dla firmy oferującej kursy i szkolenia](#opis-funkcji-systemu-dla-firmy-oferującej-kursy-i-szkolenia) - [Role Użytkowników i Funkcje Systemu](#role-użytkowników-i-funkcje-systemu) - [1. Role Użytkowników](#1-role-użytkowników) - [Administrator](#administrator) @@ -23,14 +24,14 @@ Szymon Rybski # Opis funkcji systemu dla firmy oferującej kursy i szkolenia - [Diagram bazy danych](#diagram-bazy-danych) - [Kod do generowania bazy danych:](#kod-do-generowania-bazy-danych) - [Widoki w bazie danych](#widoki-w-bazie-danych) - - [Wypisanie użytkowników, którzy ukończyli dane studia z wynikiem pozytywnym](#wypisanie-użytkowników-którzy-ukończyli-dane-studia-z-wynikiem-pozytywnym) - [Liczba zamówień dla poszczególnych użytkowników](#liczba-zamówień-dla-poszczególnych-użytkowników) - [Użytkownicy zapisani na dany kurs](#użytkownicy-zapisani-na-dany-kurs) - [Użytkownicy zapisani na dane studia](#użytkownicy-zapisani-na-dane-studia) - [Użytkownicy zapisani na dany webinar](#użytkownicy-zapisani-na-dany-webinar) - [Procedury w bazie danych](#procedury-w-bazie-danych) - - [Sprawdzanie listy obecności dla kursu](#sprawdzanie-listy-obecności-dla-kursu) - - [Odnajdywanie studentów, którzy nie byli obecni na spotkaniu](#odnajdywanie-studentów-którzy-nie-byli-obecni-na-spotkaniu) + - [Dodanie produktu do istniejącego zamówienia (z transakcja w przypadku niepowodzenia)](#dodanie-produktu-do-istniejącego-zamówienia-z-transakcja-w-przypadku-niepowodzenia) + - [Sprawdzanie listy obecności dla kursu (sprawdzanie przez prowadzącego)](#sprawdzanie-listy-obecności-dla-kursu-sprawdzanie-przez-prowadzącego) + - [Dla wszystkich użytkowników, którzy nie maja zaznaczonej obencości na zajęciach ustaw, że byli na nich nieobecni](#dla-wszystkich-użytkowników-którzy-nie-maja-zaznaczonej-obencości-na-zajęciach-ustaw-że-byli-na-nich-nieobecni) - [Sprawdzanie listy obecności dla studiów](#sprawdzanie-listy-obecności-dla-studiów) - [Sprawdzanie łącznej wartości zamówień](#sprawdzanie-łącznej-wartości-zamówień) - [Ustawianie obecności dla studenta](#ustawianie-obecności-dla-studenta) @@ -39,16 +40,23 @@ Szymon Rybski # Opis funkcji systemu dla firmy oferującej kursy i szkolenia - [Dodanie nowego miasta](#dodanie-nowego-miasta) - [Dodanie nowego pracownika](#dodanie-nowego-pracownika) - [Dodanie nowego typu wydarzenia](#dodanie-nowego-typu-wydarzenia) - - [Sprawdzenie czy użytkownik jest zapisany na kurs](#sprawdzenie-czy-użytkownik-jest-zapisany-na-kurs) - - [Usuniecie studiów o danym indeksie](#usuniecie-studiów-o-danym-indeksie) - - [Usuniecie użytkownika o danym indeksie](#usuniecie-użytkownika-o-danym-indeksie) + - [Sprawdzenie czy użytkownik jest zapisany na kurs przez prowadzacego](#sprawdzenie-czy-użytkownik-jest-zapisany-na-kurs-przez-prowadzacego) - [Dodanie webinaru](#dodanie-webinaru) + - [sprawdz % frekwencji danego studenta na zajeciach (wersja procedura, funckja - nizej)](#sprawdz--frekwencji-danego-studenta-na-zajeciach-wersja-procedura-funckja---nizej) - [Funkcje w bazie danych](#funkcje-w-bazie-danych) + - [Sprawdz frekwencje studenta na studiach](#sprawdz-frekwencje-studenta-na-studiach) - [Obliczanie średniej oceny dla użytkownika](#obliczanie-średniej-oceny-dla-użytkownika) + - [Sprawdzenie czy użytkownik zdał studia](#sprawdzenie-czy-użytkownik-zdał-studia) - [Generowanie planu zajęć dla użytkownika](#generowanie-planu-zajęć-dla-użytkownika) - [Czy użytkownik uczestniczył w zajęciach o danym temacie](#czy-użytkownik-uczestniczył-w-zajęciach-o-danym-temacie) + - [Sprawdzenie pozostałych miejsc na kursie](#sprawdzenie-pozostałych-miejsc-na-kursie) + - [Sprawdzenie pozostałych miejsc na studiach](#sprawdzenie-pozostałych-miejsc-na-studiach) + - [Trigery](#trigery) + - [Po dodaniu produktu do zamówienia, zaaktualizuj maksymalna date zapłaty, na 3 dni przed startem](#po-dodaniu-produktu-do-zamówienia-zaaktualizuj-maksymalna-date-zapłaty-na-3-dni-przed-startem) +# Opis funkcji systemu dla firmy oferującej kursy i szkolenia + ## Role Użytkowników i Funkcje Systemu System zarządzający kursami i szkoleniami obsługuje różnorodne formy kształcenia, takie jak webinary, kursy, i studia. Poniżej znajduje się opis funkcji realizowanych przez system oraz zakres uprawnień poszczególnych użytkowników. @@ -141,21 +149,16 @@ System zarządzający kursami i szkoleniami obsługuje różnorodne formy kszta # Diagram bazy danych -![diagram](./docs/images/diagram.png) - +![diagram.png](../images/diagram.png) [diagram w wersji svg](https://bleidhu.github.io/Introduction__To_Databases_2024_AGH_Project/images/diagram.svg) # Kod do generowania bazy danych: +```sql -```SQL --- Created by Vertabelo (http://vertabelo.com) --- Last modification date: 2024-12-17 22:38:54.732 - --- tables -- Table: Cities CREATE TABLE Cities ( - city_id int NOT NULL, + city_id int NOT NULL IDENTITY (1, 1), city_name nvarchar(30) NOT NULL, CONSTRAINT Cities_pk PRIMARY KEY (city_id) ); @@ -163,7 +166,7 @@ CREATE TABLE Cities -- Table: Countries CREATE TABLE Countries ( - country_id int NOT NULL, + country_id int NOT NULL IDENTITY (1, 1), country_name nvarchar(30) NOT NULL, CONSTRAINT Countries_pk PRIMARY KEY (country_id) ); @@ -190,24 +193,6 @@ ALTER TABLE Course_meeting_attendance_list FOREIGN KEY (user_id) REFERENCES Users (user_id); - --- Table: Course_module_meeting_stationary -CREATE TABLE Course_module_meeting_stationary -( - id int NOT NULL, - course_id int NOT NULL, - meeting_id int NOT NULL, - classroom nvarchar(10) NOT NULL, - CONSTRAINT Course_module_meeting_stationary_pk PRIMARY KEY (id) -); - --- Reference: Course_module_meetings_Course_module_meeting_stationary (table: Course_module_meeting_stationary) -ALTER TABLE Course_module_meeting_stationary - ADD CONSTRAINT Course_module_meetings_Course_module_meeting_stationary - FOREIGN KEY (meeting_id, course_id) - REFERENCES Course_module_meetings (meeting_id, course_id); - - -- Table: Course_module_meetings CREATE TABLE Course_module_meetings ( @@ -225,13 +210,6 @@ CREATE TABLE Course_module_meetings CONSTRAINT place_limit CHECK (place_limit >= 0), CONSTRAINT Course_module_meetings_pk PRIMARY KEY (meeting_id, course_id) ); - --- Reference: Course_module_Course_module_meetings (table: Course_module_meetings) -ALTER TABLE Course_module_meetings - ADD CONSTRAINT Course_module_Course_module_meetings - FOREIGN KEY (module_id) - REFERENCES module_type (module_type_id); - -- Reference: Course_module_meetings_Course_modules (table: Course_module_meetings) ALTER TABLE Course_module_meetings ADD CONSTRAINT Course_module_meetings_Course_modules @@ -262,14 +240,13 @@ ALTER TABLE Course_module_meetings FOREIGN KEY (meeting_type_id) REFERENCES meeting_type (meeting_type_id); - -- Table: Course_modules CREATE TABLE Course_modules ( - course_module_id int NOT NULL, - module_type_id int NOT NULL, - module_name nvarchar NOT NULL, - course_id int NOT NULL, + course_module_id int NOT NULL IDENTITY (1, 1), + module_type_id int NOT NULL, + module_name nvarchar(30) NOT NULL, + course_id int NOT NULL, CONSTRAINT course_module_id PRIMARY KEY (course_module_id) ); @@ -285,30 +262,44 @@ ALTER TABLE Course_modules FOREIGN KEY (course_id) REFERENCES Courses (course_id); +-- Table: Course_stationary_meeting +CREATE TABLE Course_stationary_meeting +( + id int NOT NULL IDENTITY (1, 1), + course_id int NOT NULL, + meeting_id int NOT NULL, + classroom nvarchar(10) NOT NULL, + CONSTRAINT Course_stationary_meeting_pk PRIMARY KEY (id) +); +-- Reference: Course_module_meetings_Course_module_meeting_stationary (table: Course_stationary_meeting) +ALTER TABLE Course_stationary_meeting + ADD CONSTRAINT Course_module_meetings_Course_module_meeting_stationary + FOREIGN KEY (meeting_id, course_id) + REFERENCES Course_module_meetings (meeting_id, course_id); + -- Table: Course_sync_async_meeting CREATE TABLE Course_sync_async_meeting ( - id int NOT NULL, + id int NOT NULL IDENTITY (1, 1), course_id int NOT NULL, meeting_id int NOT NULL, - accessTo datetime NOT NULL, + access_to datetime NOT NULL, video_link nvarchar(30) NOT NULL, stream_link nvarchar(30) NULL, CONSTRAINT Course_sync_async_meeting_pk PRIMARY KEY (id) ); - - -- Reference: Course_video_access_Course_module_meetings (table: Course_sync_async_meeting) ALTER TABLE Course_sync_async_meeting ADD CONSTRAINT Course_video_access_Course_module_meetings FOREIGN KEY (meeting_id, course_id) REFERENCES Course_module_meetings (meeting_id, course_id); + -- Table: Courses CREATE TABLE Courses ( - course_id int NOT NULL, + course_id int NOT NULL IDENTITY (1, 1), course_name nvarchar(30) NOT NULL, course_description nvarchar(300) NOT NULL, start_date date NOT NULL, @@ -319,6 +310,7 @@ CREATE TABLE Courses CONSTRAINT courses_price_check CHECK (price >= 0), CONSTRAINT Courses_pk PRIMARY KEY (course_id) ); + -- Reference: Courses_Employees (table: Courses) ALTER TABLE Courses ADD CONSTRAINT Courses_Employees @@ -329,16 +321,15 @@ ALTER TABLE Courses -- Table: Employee_Roles CREATE TABLE Employee_Roles ( - role_id int NOT NULL, - employee_id int NOT NULL, - role_name int NOT NULL, + role_id int NOT NULL IDENTITY (1, 1), + role_name nvarchar(30) NOT NULL, CONSTRAINT Employee_Roles_pk PRIMARY KEY (role_id) ); -- Table: Employees CREATE TABLE Employees ( - employee_id int NOT NULL, + employee_id int NOT NULL IDENTITY (1, 1), first_name nvarchar(30) NOT NULL, last_name nvarchar(30) NOT NULL, hire_date date NOT NULL, @@ -352,7 +343,6 @@ CREATE TABLE Employees CONSTRAINT Employees_pk PRIMARY KEY (employee_id) ); - -- Reference: Employees_Cities (table: Employees) ALTER TABLE Employees ADD CONSTRAINT Employees_Cities @@ -375,7 +365,7 @@ ALTER TABLE Employees -- Table: Event_types CREATE TABLE Event_types ( - type_id int NOT NULL, + type_id int NOT NULL IDENTITY (1, 1), event_name nvarchar(30) NOT NULL, CONSTRAINT Event_types_pk PRIMARY KEY (type_id) ); @@ -390,7 +380,6 @@ CREATE TABLE Exams CONSTRAINT Exams_pk PRIMARY KEY (studies_id, user_id) ); - -- Reference: Exams_Studies (table: Exams) ALTER TABLE Exams ADD CONSTRAINT Exams_Studies @@ -408,16 +397,17 @@ ALTER TABLE Exams CREATE TABLE Intership_meeting_attendance_list ( inter_meeting_id int NOT NULL, + studies_id int NOT NULL, user_id int NOT NULL, was_present bit NOT NULL, - CONSTRAINT Intership_meeting_attendance_list_pk PRIMARY KEY (inter_meeting_id, user_id) + CONSTRAINT Intership_meeting_attendance_list_pk PRIMARY KEY (inter_meeting_id, user_id, studies_id) ); -- Reference: Intership_meeting_attendance_list_Intership_meetings (table: Intership_meeting_attendance_list) ALTER TABLE Intership_meeting_attendance_list ADD CONSTRAINT Intership_meeting_attendance_list_Intership_meetings - FOREIGN KEY (inter_meeting_id) - REFERENCES Intership_meetings (inter_meeting_id); + FOREIGN KEY (inter_meeting_id, studies_id) + REFERENCES Intership_meetings (inter_meeting_id, studies_id); -- Reference: Intership_meeting_attendance_list_Users (table: Intership_meeting_attendance_list) ALTER TABLE Intership_meeting_attendance_list @@ -425,28 +415,26 @@ ALTER TABLE Intership_meeting_attendance_list FOREIGN KEY (user_id) REFERENCES Users (user_id); + -- Table: Intership_meetings CREATE TABLE Intership_meetings ( - inter_meeting_id int NOT NULL, studies_id int NOT NULL, - intership_id int NOT NULL, + inter_meeting_id int NOT NULL IDENTITY (1, 1), meetind_date datetime NOT NULL, - CONSTRAINT Intership_meetings_pk PRIMARY KEY (inter_meeting_id) + CONSTRAINT Intership_meetings_pk PRIMARY KEY (inter_meeting_id, studies_id) ); - -- Reference: Intership_meetings_Studies (table: Intership_meetings) ALTER TABLE Intership_meetings ADD CONSTRAINT Intership_meetings_Studies FOREIGN KEY (studies_id) REFERENCES Studies (studies_id); - -- Table: Languages CREATE TABLE Languages ( - language_id int NOT NULL, + language_id int NOT NULL IDENTITY (1, 1), language_name nvarchar(30) NOT NULL, CONSTRAINT Languages_pk PRIMARY KEY (language_id) ); @@ -459,7 +447,6 @@ CREATE TABLE Order_course CONSTRAINT Order_course_pk PRIMARY KEY (order_detail_id) ); - -- Reference: Order_course_Courses (table: Order_course) ALTER TABLE Order_course ADD CONSTRAINT Order_course_Courses @@ -476,13 +463,13 @@ ALTER TABLE Order_course -- Table: Order_details CREATE TABLE Order_details ( - order_detail_id int NOT NULL, - order_id int NOT NULL, - type_id int NOT NULL, + order_detail_id int NOT NULL IDENTITY (1, 1), + order_id int NOT NULL, + type_id int NOT NULL, + price money NOT NULL, + CONSTRAINT order_details_price_check CHECK (price >= 0), CONSTRAINT Order_details_pk PRIMARY KEY (order_detail_id) ); - - -- Reference: Order_details_Event_types (table: Order_details) ALTER TABLE Order_details ADD CONSTRAINT Order_details_Event_types @@ -504,7 +491,6 @@ CREATE TABLE Order_module_studies CONSTRAINT Order_module_studies_pk PRIMARY KEY (order_detail_id) ); - -- Reference: Order_meeting_studies_Order_details (table: Order_module_studies) ALTER TABLE Order_module_studies ADD CONSTRAINT Order_meeting_studies_Order_details @@ -556,25 +542,23 @@ ALTER TABLE Order_webinars ALTER TABLE Order_webinars ADD CONSTRAINT Order_webinars_Webinar_info FOREIGN KEY (webinar_id) - REFERENCES Webinar_info (webinar_id); + REFERENCES Webinars (webinar_id); -- Table: Orders CREATE TABLE Orders ( - order_id int NOT NULL, + order_id int NOT NULL IDENTITY (1, 1), user_id int NOT NULL, is_paid bit NOT NULL, - price money NOT NULL, max_paid_date datetime NOT NULL, - CONSTRAINT orders_price_check CHECK (price >= 0), CONSTRAINT Orders_pk PRIMARY KEY (order_id) ); -- Table: Studies CREATE TABLE Studies ( - studies_id int NOT NULL, + studies_id int NOT NULL IDENTITY (1, 1), studies_name nvarchar(30) NOT NULL, studies_description nvarchar(300) NOT NULL, start_date date NOT NULL, @@ -596,12 +580,12 @@ ALTER TABLE Studies -- Table: Studies_Module CREATE TABLE Studies_Module ( - studies_module_id int NOT NULL, - module_type_id int NOT NULL, - module_name nvarchar(30) NOT NULL, - studies_id int NOT NULL, - price_for_free_listeners money NOT NULL, - CONSTRAINT price_check CHECK (price_for_free_listeners >= 0), + studies_module_id int NOT NULL IDENTITY (1, 1), + module_type_id int NOT NULL, + module_name nvarchar(30) NOT NULL, + studies_id int NOT NULL, + price_for_module money NOT NULL, + CONSTRAINT price_check CHECK (price_for_module >= 0), CONSTRAINT studies_module_id PRIMARY KEY (studies_module_id) ); @@ -621,11 +605,11 @@ ALTER TABLE Studies_Module -- Table: Studies_makeup_meeting_attendance_list CREATE TABLE Studies_makeup_meeting_attendance_list ( - makeup_list_id int NOT NULL, + makeup_list_id int NOT NULL IDENTITY (1, 1), user_id int NOT NULL, studies_id int NOT NULL, meeting_id int NOT NULL, - topic_id int NOT NULL, + used bit NOT NULL DEFAULT 0, CONSTRAINT Studies_makeup_meeting_attendance_list_pk PRIMARY KEY (makeup_list_id) ); @@ -641,6 +625,7 @@ ALTER TABLE Studies_makeup_meeting_attendance_list FOREIGN KEY (user_id) REFERENCES Users (user_id); + -- Table: Studies_meeting_attendance_list CREATE TABLE Studies_meeting_attendance_list ( @@ -648,11 +633,9 @@ CREATE TABLE Studies_meeting_attendance_list studies_id int NOT NULL, meeting_id int NOT NULL, was_present bit NOT NULL, - topic_id int NOT NULL, + did_makeup bit NOT NULL DEFAULT 0, CONSTRAINT Studies_meeting_attendance_list_pk PRIMARY KEY (user_id, studies_id, meeting_id) ); - - -- Reference: Studies_meeting_attendance_list_Studies_module_meetings (table: Studies_meeting_attendance_list) ALTER TABLE Studies_meeting_attendance_list ADD CONSTRAINT Studies_meeting_attendance_list_Studies_module_meetings @@ -666,31 +649,14 @@ ALTER TABLE Studies_meeting_attendance_list REFERENCES Users (user_id); --- Table: Studies_module_meeting_stationary -CREATE TABLE Studies_module_meeting_stationary -( - id int NOT NULL, - studies_id int NOT NULL, - meeting_id int NOT NULL, - classroom nvarchar(6) NOT NULL, - CONSTRAINT Studies_module_meeting_stationary_pk PRIMARY KEY (id) -); - - --- Reference: Studies_module_meeting_stationary_Studies_module_meetings (table: Studies_module_meeting_stationary) -ALTER TABLE Studies_module_meeting_stationary - ADD CONSTRAINT Studies_module_meeting_stationary_Studies_module_meetings - FOREIGN KEY (meeting_id, studies_id) - REFERENCES Studies_module_meetings (meeting_id, studies_id); - -- Table: Studies_module_meetings CREATE TABLE Studies_module_meetings ( meeting_id int NOT NULL, studies_id int NOT NULL, meeting_date datetime NOT NULL, - language_id nvarchar(30) NOT NULL, - translator_id int NOT NULL, + language_id int NOT NULL, + translator_id int NULL, lecturer_id int NOT NULL, duration time NOT NULL, place_limit int NOT NULL, @@ -701,7 +667,6 @@ CREATE TABLE Studies_module_meetings CONSTRAINT Studies_module_meetings_pk PRIMARY KEY (meeting_id, studies_id) ); - -- Reference: Studies_module_meetings_Employees (table: Studies_module_meetings) ALTER TABLE Studies_module_meetings ADD CONSTRAINT Studies_module_meetings_Employees @@ -726,56 +691,65 @@ ALTER TABLE Studies_module_meetings FOREIGN KEY (meeting_type_id) REFERENCES meeting_type (meeting_type_id); --- Reference: module_type_Studies_module_meetings (table: Studies_module_meetings) -ALTER TABLE Studies_module_meetings - ADD CONSTRAINT module_type_Studies_module_meetings - FOREIGN KEY (module_id) - REFERENCES module_type (module_type_id); - -- Reference: topics_list_Studies_module_meetings (table: Studies_module_meetings) ALTER TABLE Studies_module_meetings ADD CONSTRAINT topics_list_Studies_module_meetings FOREIGN KEY (topic_id) REFERENCES topics_list (topic_id); +-- Table: Studies_stationary_meeting +CREATE TABLE Studies_stationary_meeting +( + id int NOT NULL IDENTITY (1, 1), + studies_id int NOT NULL, + meeting_id int NOT NULL, + classroom nvarchar(6) NOT NULL, + CONSTRAINT Studies_stationary_meeting_pk PRIMARY KEY (id) +); +-- Reference: Studies_module_meeting_stationary_Studies_module_meetings (table: Studies_stationary_meeting) +ALTER TABLE Studies_stationary_meeting + ADD CONSTRAINT Studies_module_meeting_stationary_Studies_module_meetings + FOREIGN KEY (meeting_id, studies_id) + REFERENCES Studies_module_meetings (meeting_id, studies_id); + -- Table: Studies_sync_async_meeting CREATE TABLE Studies_sync_async_meeting ( - id int NOT NULL, + id int NOT NULL IDENTITY (1, 1), studies_id int NOT NULL, meeting_id int NOT NULL, - accessTo datetime NOT NULL, + access_to datetime NOT NULL, video_link nvarchar(30) NOT NULL, - stream_link nvarchar(30) NOT NULL, + stream_link nvarchar(30) NULL, CONSTRAINT Studies_sync_async_meeting_pk PRIMARY KEY (id) ); - -- Reference: Studies_sync_async_meeting_Studies_module_meetings (table: Studies_sync_async_meeting) ALTER TABLE Studies_sync_async_meeting ADD CONSTRAINT Studies_sync_async_meeting_Studies_module_meetings FOREIGN KEY (meeting_id, studies_id) REFERENCES Studies_module_meetings (meeting_id, studies_id); + -- Table: Translators CREATE TABLE Translators ( - translator_id int NOT NULL, + translator_id int NOT NULL IDENTITY (1, 1), employee_id int NOT NULL, CONSTRAINT Translators_pk PRIMARY KEY (translator_id) ); - -- Reference: Translators_Employees (table: Translators) ALTER TABLE Translators ADD CONSTRAINT Translators_Employees FOREIGN KEY (employee_id) REFERENCES Employees (employee_id); + -- Table: Translators_languages_used CREATE TABLE Translators_languages_used ( - id int NOT NULL, + id int NOT NULL IDENTITY (1, 1), translator_id int NOT NULL, language_id int NOT NULL, CONSTRAINT Translators_languages_used_pk PRIMARY KEY (id) @@ -793,10 +767,11 @@ ALTER TABLE Translators_languages_used FOREIGN KEY (translator_id) REFERENCES Translators (translator_id); + -- Table: Users CREATE TABLE Users ( - user_id int NOT NULL, + user_id int NOT NULL IDENTITY (1, 1), email nvarchar(50) NOT NULL, first_name nvarchar(30) NOT NULL, last_name nvarchar(30) NOT NULL, @@ -809,6 +784,7 @@ CREATE TABLE Users CONSTRAINT users_birth_date_check CHECK (datediff(year, birth_date, getdate()) < 100), CONSTRAINT Users_pk PRIMARY KEY (user_id) ); +-- Reference: Cities_Users (table: Users) ALTER TABLE Users ADD CONSTRAINT Cities_Users FOREIGN KEY (city_id) @@ -820,90 +796,65 @@ ALTER TABLE Users FOREIGN KEY (country_id) REFERENCES Countries (country_id); - --- Table: Webinar_info -CREATE TABLE Webinar_info +-- Table: Webinars +CREATE TABLE Webinars ( - webinar_id int NOT NULL, - teacher_id int NOT NULL, - price money NOT NULL, - can_buy_from date NOT NULL, - recording_link nvarchar(30) NOT NULL, - start_date date NOT NULL, + webinar_id int NOT NULL IDENTITY (1, 1), + name nvarchar(30) NOT NULL, + description nvarchar(300) NOT NULL, + teacher_id int NOT NULL, + price money NOT NULL, + can_buy_from date NOT NULL, + recording_link nvarchar(30) NOT NULL, + start_date date NOT NULL, CONSTRAINT webinar_price_check CHECK (price >= 0), - CONSTRAINT Webinar_info_pk PRIMARY KEY (webinar_id) + CONSTRAINT Webinars_pk PRIMARY KEY (webinar_id) ); --- Reference: Webinar_info_Employees (table: Webinar_info) -ALTER TABLE Webinar_info +-- Reference: Webinar_info_Employees (table: Webinars) +ALTER TABLE Webinars ADD CONSTRAINT Webinar_info_Employees FOREIGN KEY (teacher_id) REFERENCES Employees (employee_id); + -- Table: meeting_type CREATE TABLE meeting_type ( - meeting_type_id int NOT NULL, - meeting_type nvarchar(30) NOT NULL, + meeting_type_id int NOT NULL IDENTITY (1, 1), + meeting_name nvarchar(30) NOT NULL, CONSTRAINT meeting_type_pk PRIMARY KEY (meeting_type_id) ); -- Table: module_type CREATE TABLE module_type ( - module_type_id int NOT NULL, + module_type_id int NOT NULL IDENTITY (1, 1), module_name nvarchar(30) NOT NULL, - module_type nvarchar(30) NOT NULL, CONSTRAINT module_type_pk PRIMARY KEY (module_type_id) ); -- Table: topics_list CREATE TABLE topics_list ( - topic_id int NOT NULL, - topic_name nvarchar(30) NOT NULL, - topic_description nvarchar(30) NOT NULL, + topic_id int NOT NULL IDENTITY (1, 1), + topic_name nvarchar(30) NOT NULL, + topic_description nvarchar(300) NOT NULL, CONSTRAINT topics_list_pk PRIMARY KEY (topic_id) ); --- End of file. +-- End of file. ``` -## Widoki w bazie danych - -### Wypisanie użytkowników, którzy ukończyli dane studia z wynikiem pozytywnym -```sql -create view dbo.check_if_user_passed as - select user_id, cast(1 as bit) as pass - from Users u - where not exists(select 1 - from Intership_meeting_attendance_list ia - where u.user_id = ia.user_id - and was_present = 0) - and ((select SUM(IIF(was_present = 1, 1, 0)) from Studies_meeting_attendance_list sa) - / (select count(was_present) from Studies_meeting_attendance_list sa)) >= 0.8 - and (select grade from Exams e where e.user_id = u.user_id) >= 3.0 - union - select user_id, cast(0 as bit) as pass - from Users u - where user_id not in (select user_id - from Users u - where not exists(select 1 - from Intership_meeting_attendance_list ia - where u.user_id = ia.user_id - and was_present = 0) - and ((select SUM(IIF(was_present = 1, 1, 0)) from Studies_meeting_attendance_list sa) - / (select count(was_present) from Studies_meeting_attendance_list sa)) >= 0.8 - and (select grade from Exams e where e.user_id = u.user_id) >= 3.0) -go +## Widoki w bazie danych -``` ### Liczba zamówień dla poszczególnych użytkowników +`` ```sql create view dbo.number_of_orders_by_user as with what_user_ordered as (select Orders.user_id, @@ -960,6 +911,8 @@ create view dbo.number_of_orders_by_user as group by t.user_id go ``` +~Julia Demitraszek + ### Użytkownicy zapisani na dany kurs @@ -972,8 +925,8 @@ create view dbo.courses_enrolled_list as where o.is_paid = 1 or (getdate() < max_paid_date) go - ``` +~Szymon Rybski ### Użytkownicy zapisani na dane studia @@ -987,6 +940,7 @@ create view dbo.studies_enrolled_list as or (getdate() < max_paid_date) go ``` +~Szymon Rybski ### Użytkownicy zapisani na dany webinar @@ -999,17 +953,157 @@ create view dbo.webinar_enrolled_list as where o.is_paid = 1 or (getdate() < max_paid_date) go - ``` - +~Szymon Rybski ## Procedury w bazie danych +### Dodanie produktu do istniejącego zamówienia (z transakcja w przypadku niepowodzenia) +```sql +-- dodanie produktu do ISTNIEJACEGO zamówienia +create procedure add_product_to_order @order_id int, + @product_id int, + @product_type_id int +as +begin + declare @is_order_exists bit; + declare @is_product_exists bit; + declare @product_type varchar(50); + declare @product_price decimal(10, 2); + declare @order_detail_id int; + + begin TRY + set transaction isolation level serializable; + begin transaction; + -- Sprawdzenie, czy zamówienie istnieje + select @is_order_exists = case + when exists (select 1 + from dbo.orders + where order_id = @order_id) then 1 + else 0 end; + + if @is_order_exists = 0 + begin + throw 50001, 'Zamówienie o podanym ID nie istnieje.', 1; + end + +-- sprawdzenie typu produktu + select @product_type = event_name + from Event_types + where type_id = @product_type_id; + + if @product_type is null + begin + throw 50002, 'Nieprawidłowy typ produktu.', 1; + end + + -- Sprawdzenie, czy produkt istnieje + select @is_product_exists = case + when @product_type = 'Webinar' then + IIF(exists (select 1 + from dbo.webinars + where webinar_id = @product_id), 1, 0) + when @product_type = 'Course' then + IIF(exists (select 1 + from dbo.courses + where course_id = @product_id), 1, 0) + when @product_type = 'Studies' then + IIF(exists (select 1 + from dbo.studies + where studies_id = @product_id), 1, 0) + when @product_type = 'Study_Module' then + IIF(exists (select 1 + from dbo.Studies_Module + where studies_module_id = @product_id), 1, 0) + else 0 + end + + + -- jeśli produkt nie istnieje + if @is_product_exists = 0 + begin + throw 50003, 'Produkt o podanym ID nie istnieje.', 1; + end + + -- pobranie ceny produktu + select @product_price = case + when @product_type = 'Webinar' then + (select price from webinars where webinar_id = @product_id) + when @product_type = 'Course' then + (select price from courses where course_id = @product_id) + when @product_type = 'Studies' then + (select price from studies where studies_id = @product_id) + when @product_type = 'Study_Module' then + (select price_for_module + from Studies_Module + where studies_module_id = @product_id) + else 0 + end + +-- dodanie produktu do order_details + insert into Order_details (order_id, type_id, price) + values (@order_id, @product_type_id, @product_price); + select @order_detail_id = SCOPE_IDENTITY(); + +-- dodanie zakupu do odpowiedniej tabeli + if @product_type = 'Webinar' + begin + -- id z order_details i id webinaru + insert into Order_webinars (order_detail_id, webinar_id) + values (@order_detail_id, @product_id); + end + +-- jesli to kurs i dodatkowo czy są wolne miejsca + else if @product_type = 'Course' + begin + if dbo.check_course_places_left(@product_id) > 0 + begin + insert into Order_course (order_detail_id, course_id) + values (@order_detail_id, @product_id); + end + else + begin + throw 50004, 'Brak miejsc na kurs.', 1; + end + end + + else if @product_type = 'Studies' + begin + if dbo.check_studies_places_left(@product_id) > 0 + begin + insert into Order_studies (order_detail_id, studies_id) + values (@order_detail_id, @product_id); + end + else + begin + throw 50005, 'Brak miejsc na studia.', 1; + end + end + + +-- dla modułów bez limitu miejsc + else if @product_type = 'Study_Module' + begin + insert into Order_module_studies (order_detail_id, module_id) + values (@order_detail_id, @product_id); + end + commit transaction; + + SELECT * FROM Order_details WHERE order_id = @order_id; + end TRY + begin CATCH + if @@TRANCOUNT > 0 + rollback transaction; + throw; + end CATCH +end +``` +~Paweł Czajczyk -### Sprawdzanie listy obecności dla kursu +### Sprawdzanie listy obecności dla kursu (sprawdzanie przez prowadzącego) ```sql -CREATE PROCEDURE check_course_attendance @user_id INT, +CREATE PROCEDURE update_course_attendance @user_id INT, @course_id INT, @meeting_id INT AS @@ -1033,12 +1127,13 @@ BEGIN END; ``` +~Szymon Rybski -### Odnajdywanie studentów, którzy nie byli obecni na spotkaniu +### Dla wszystkich użytkowników, którzy nie maja zaznaczonej obencości na zajęciach ustaw, że byli na nich nieobecni ```sql -CREATE PROCEDURE check_for_students_that_missed_meeting @studies_id INT, - @meeting_id INT +CREATE PROCEDURE update_students_that_missed_meeting @studies_id INT, + @meeting_id INT AS BEGIN set nocount on; @@ -1056,6 +1151,7 @@ BEGIN END; ``` +~Paweł Czajczyk ### Sprawdzanie listy obecności dla studiów @@ -1088,6 +1184,7 @@ BEGIN END; ``` +~Szymon Rybski ### Sprawdzanie łącznej wartości zamówień @@ -1100,9 +1197,13 @@ begin return @total_cost end ``` +~Julia Demitraszek ### Ustawianie obecności dla studenta ```sql +-- jesli uzytkownik ma jakies odrobione zajecia z tym samym tematem co przesłane to ustaw ze odrobil zajecia +-- oraz odrobienia oznacz jako "zuzyte" + CREATE PROCEDURE set_attendance_for_student_that_makeup_meeting @studies_id INT, @meeting_id INT, @user_id INT @@ -1111,26 +1212,44 @@ BEGIN declare @makeup_meeting_id INT; declare @topic_id INT; - select @topic_id = topic_id from Studies_module_meetings where meeting_id = @meeting_id and studies_id = @studies_id; + select @topic_id = topic_id + from Studies_module_meetings + where meeting_id = @meeting_id + and studies_id = @studies_id; - select top 1 @makeup_meeting_id = makeup_list_id from Studies_makeup_meeting_attendance_list smmal - join Studies_module_meetings smm on smmal.meeting_id = smm.meeting_id and smmal.studies_id = smm.studies_id - where topic_id = @topic_id and user_id = @user_id and smmal.used = 0; + select top 1 @makeup_meeting_id = makeup_list_id + from Studies_makeup_meeting_attendance_list smmal + join Studies_module_meetings smm on smmal.meeting_id = smm.meeting_id and smmal.studies_id = smm.studies_id + where topic_id = @topic_id + and user_id = @user_id + and smmal.used = 0; if @makeup_meeting_id is not null begin update Studies_makeup_meeting_attendance_list set used = 1 where makeup_list_id = @makeup_meeting_id; - update Studies_meeting_attendance_list set did_makeup = 1 where meeting_id = @meeting_id and studies_id = @studies_id and user_id = @user_id; - end + update Studies_meeting_attendance_list + set did_makeup = 1 + where meeting_id = @meeting_id + and studies_id = @studies_id + and user_id = @user_id; + return 0; + end + else + begin +-- jednak zwracanie succes/failure bo wykorzystujemy w check_user_attendance + return 1; +-- raiserror ('Student did not make up the meeting', 16, 1); + end END; ``` +~Paweł Czajczyk ### Dodanie nowego tematu -``` sql +```sql create procedure add_topic( @topic_name nvarchar(30), @topic_description nvarchar(30) @@ -1148,6 +1267,7 @@ begin end end; ``` +~Szymon Rybski ### Dodanie nowego użytkownika @@ -1181,12 +1301,11 @@ BEGIN @Email, @FirstName, @LastName, @CityID, @CountryID, @Phone, @Street, @HouseNumber, @BirthDate ); END; - ``` +~Julia Demitraszek ### Dodanie nowego miasta - -``` sql +```sql CREATE PROCEDURE add_city @CityName NVARCHAR(30) AS @@ -1204,6 +1323,7 @@ BEGIN END; GO ``` +~Julia Demitraszek ### Dodanie nowego pracownika @@ -1244,8 +1364,8 @@ BEGIN @CountryID ); END; - ``` +~Julia Demitraszek ### Dodanie nowego typu wydarzenia @@ -1261,10 +1381,11 @@ BEGIN END END; ``` +~Szymon Rybski -### Sprawdzenie czy użytkownik jest zapisany na kurs +### Sprawdzenie czy użytkownik jest zapisany na kurs przez prowadzacego -``` sql +```sql CREATE PROCEDURE check_course_attendance @user_id INT, @course_id INT, @@ -1292,52 +1413,9 @@ BEGIN END; go ``` +~Julia Demitraszek -### Usuniecie studiów o danym indeksie -```sql -CREATE PROCEDURE delete_study - @study_id INT -AS -BEGIN - SET NOCOUNT ON; - - IF NOT EXISTS (SELECT 1 FROM Studies WHERE studies_id = @study_id) - BEGIN - PRINT 'Nie znaleziono studiow'; - RETURN; - END - - DELETE FROM Studies - WHERE studies_id = @study_id; - - PRINT 'Studia usuniete'; -END - -``` - -### Usuniecie użytkownika o danym indeksie -```sql -CREATE PROCEDURE delete_user - @user_id INT -AS -BEGIN - SET NOCOUNT ON; - - IF NOT EXISTS (SELECT 1 FROM Users WHERE user_id = @user_id) - BEGIN - PRINT 'Uzytkownik nie znaleziony'; - RETURN; - END - - DELETE FROM Users - WHERE user_id = @user_id; - - PRINT 'Uzytkownik usuniety'; -END - -``` - ### Dodanie webinaru ```sql @@ -1363,10 +1441,101 @@ BEGIN PRINT 'Webinar został dodany'; END; - ``` +~Szymon Rybski + +### sprawdz % frekwencji danego studenta na zajeciach (wersja procedura, funckja - nizej) +```sql + +create procedure get_user_attendance_procedure @studies_id int, @user_id int, @result float output +as +begin + declare @meeting_id int; + declare @was_present bit; + declare @did_makeup bit; + declare @total_meetings int = 0; + declare @present_meetings int = 0; + + declare @status int; + + declare attendance_cursor cursor for + select meeting_id, was_present, did_makeup + from Studies_meeting_attendance_list + where studies_id = @studies_id + and user_id = @user_id; + +-- dla kazdego rekordu w attendance_list sprawdz czy student byl obecny, jesli nie to sprawdz czy odrobil zajecia + open attendance_cursor; + fetch next from attendance_cursor into @meeting_id, @was_present, @did_makeup; + while @@fetch_status = 0 + begin + if @was_present = 1 + set @present_meetings = @present_meetings + 1; + else + if @did_makeup = 1 + set @present_meetings = @present_meetings + 1; + else + begin + -- jesli student nie byl obecny i nie odrobil zajec to sprawdz czy ma odrobione zajecia + exec @status = set_attendance_for_student_that_makeup_meeting + @studies_id, + @meeting_id, + @user_id; + if @status = 0 + begin + set @present_meetings = @present_meetings + 1; + end + + end + set @total_meetings = @total_meetings + 1; + fetch next from attendance_cursor into @meeting_id, @was_present, @did_makeup; + end + close attendance_cursor; + deallocate attendance_cursor; + + if @total_meetings = 0 + set @result = 0; + else + set @result = @present_meetings / @total_meetings; +end +``` +~Paweł Czajczyk + ## Funkcje w bazie danych +### Sprawdz frekwencje studenta na studiach +```sql +CREATE FUNCTION get_user_attendance_percentage +( + @studies_id INT, + @user_id INT +) + RETURNS FLOAT +AS +BEGIN + DECLARE @total_meetings INT; + DECLARE @present_meetings INT; + + SELECT @total_meetings = COUNT(*) + FROM Studies_module_meetings + WHERE studies_id = @studies_id; + + SELECT @present_meetings = COUNT(*) + FROM Studies_meeting_attendance_list + WHERE studies_id = @studies_id + AND user_id = @user_id + AND (was_present = 1 OR did_makeup = 1); + + -- Jeśli brak spotkań, zwróć 0 (unikamy dzielenia przez 0) + IF @total_meetings = 0 + RETURN 0; + + -- Zwróć procent obecności + RETURN CAST(@present_meetings AS FLOAT) / CAST(@total_meetings AS FLOAT) * 100; +END; +``` +~Paweł Czajczyk + ### Obliczanie średniej oceny dla użytkownika ```sql create function get_user_average_grade(@user_id int) @@ -1378,6 +1547,59 @@ select @average = avg(grade) from Exams where user_id = @user_id; return @average; end; ``` +~Julia Demitraszek + +### Sprawdzenie czy użytkownik zdał studia +```sql +-- sprawdza czy student ma zaliczone wszystkie przedmioty z danego semestru, +-- frekwencje na poziomie 80% oraz 100% na praktykach +create function check_if_user_pass_studies(@studies_id int, @user_id int) + returns bit as +begin + declare @total_attendance float; + declare @intership_absence int; + declare @exam_grade float; + declare @enrolled bit; + +-- jesli nie jest zapisany na dany przedmiot to nie zalicza + select @enrolled = count(*) from studies_enrolled_list + where studies_id = @studies_id + and user_id = @user_id; + + if @enrolled = 0 + return 0; + +-- jesli nie ma 80% frekwencji to nie zalicza + select @total_attendance = dbo.get_user_attendance_percentage(@studies_id, @user_id); + + if @total_attendance < 80 + return 0; + +-- jesli ma nieobecnosci na praktykach to nie zalicza + select @intership_absence = count(*) from Intership_meeting_attendance_list + where studies_id = @studies_id + and user_id = @user_id + and was_present = 0; + + if @intership_absence > 0 + return 0; + +-- jesli ma niezaliczony egzamin to nie zalicza + select @exam_grade = grade from Exams + where studies_id = @studies_id + and user_id = @user_id; + + if @exam_grade is null or @exam_grade < 3 + return 0; + + + +-- w przeciwnym wypadku zalicza + return 1; + +end +``` +~Paweł Czajczyk ### Generowanie planu zajęć dla użytkownika ```sql @@ -1414,6 +1636,7 @@ CREATE FUNCTION get_user_schedule(@user_id INT) ); ``` +~Julia Demitraszek ### Czy użytkownik uczestniczył w zajęciach o danym temacie @@ -1442,7 +1665,126 @@ begin return @result end go +``` +~Szymon Rybski +### Sprawdzenie pozostałych miejsc na kursie +```sql +create function check_course_places_left(@course_id int) + returns int as +begin + declare @limit int; + declare @result int; +select @limit = students_limit from Courses where course_id = @course_id; +select @result = @limit - (select count(*) from courses_enrolled_list where course_id = @course_id); +return @result; +end +``` +~Paweł Czajczyk +### Sprawdzenie pozostałych miejsc na studiach +```sql +create function check_studies_places_left(@studies_id int) + returns int as +begin + declare @limit int; + declare @result int; +select @limit = students_limit from Studies where studies_id = @studies_id; +select @result = @limit - (select count(*) from studies_enrolled_list sel where studies_id = @studies_id); +return @result; +end ``` +~Paweł Czajczyk + +## Trigery + +### Po dodaniu produktu do zamówienia, zaaktualizuj maksymalna date zapłaty, na 3 dni przed startem +```sql +create trigger update_order_pay_date + on Order_details + after insert + as +begin + declare @order_id int; + declare @product_type_id int; + declare @product_type varchar(50); + declare @product_id int; + declare @order_detail_id int; + declare @start_date date; + + declare inserted_cursor cursor for + select order_id, type_id, order_detail_id + from inserted; + open inserted_cursor; + fetch next from inserted_cursor into @order_id, @product_type_id, @order_detail_id; + + while @@FETCH_STATUS = 0 + begin + select @product_type = case + when @product_type_id = 1 then 'Webinar' + when @product_type_id = 2 then 'Course' + when @product_type_id = 3 then 'Studies' + when @product_type_id = 4 then 'Study_Module' + else 'Unknown' + end; + + if @product_type = 'Course' + begin + select @product_id = course_id + from Order_course + where order_detail_id = @order_detail_id; + + select @start_date = start_date + from Courses + where course_id = @product_id; + end + else if @product_type = 'Studies' + begin + select @product_id = studies_id + from Order_studies + where order_detail_id = @order_detail_id; + + select @start_date = start_date + from Studies + where studies_id = @product_id; + end + else if @product_type = 'Webinar' + begin + select @product_id = webinar_id + from Order_webinars + where order_detail_id = @order_detail_id; + + select @start_date = start_date + from Webinars + where webinar_id = @product_id; + end + else if @product_type = 'Study_Module' + begin + select @product_id = module_id + from Order_module_studies + where order_detail_id = @order_detail_id; + + select @start_date = min(meeting_date) + from Studies_module_meetings + where module_id = @product_id; + end + else + begin + fetch next from inserted_cursor into @order_id, @product_type_id, @order_detail_id; + continue; + end + + update Orders + set max_paid_date = dateadd(day, -3, @start_date) + where order_id = @order_id + and max_paid_date < dateadd(day, -3, @start_date); + + fetch next from inserted_cursor into @order_id, @product_type_id, @order_detail_id; + end + + close inserted_cursor; + deallocate inserted_cursor; +end +``` +~Paweł Czajczyk \ No newline at end of file diff --git a/docs/raports_generation/concatenated_output.pdf b/docs/raports_generation/concatenated_output.pdf index a96fa5e..5a3f584 100644 Binary files a/docs/raports_generation/concatenated_output.pdf and b/docs/raports_generation/concatenated_output.pdf differ diff --git a/utils/dummy_data_generator/__pycache__/course_names.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/course_names.cpython-310.pyc deleted file mode 100644 index 3765e1b..0000000 Binary files a/utils/dummy_data_generator/__pycache__/course_names.cpython-310.pyc and /dev/null differ diff --git a/utils/dummy_data_generator/__pycache__/db_tables_classes.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/db_tables_classes.cpython-310.pyc deleted file mode 100644 index 975a851..0000000 Binary files a/utils/dummy_data_generator/__pycache__/db_tables_classes.cpython-310.pyc and /dev/null differ diff --git a/utils/dummy_data_generator/__pycache__/dummy_values.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/dummy_values.cpython-310.pyc deleted file mode 100644 index fb8a018..0000000 Binary files a/utils/dummy_data_generator/__pycache__/dummy_values.cpython-310.pyc and /dev/null differ diff --git a/utils/dummy_data_generator/__pycache__/employees_generation.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/employees_generation.cpython-310.pyc deleted file mode 100644 index 0ace248..0000000 Binary files a/utils/dummy_data_generator/__pycache__/employees_generation.cpython-310.pyc and /dev/null differ diff --git a/utils/dummy_data_generator/__pycache__/studies_generator.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/studies_generator.cpython-310.pyc deleted file mode 100644 index 627f46e..0000000 Binary files a/utils/dummy_data_generator/__pycache__/studies_generator.cpython-310.pyc and /dev/null differ diff --git a/utils/dummy_data_generator/__pycache__/users_generation.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/users_generation.cpython-310.pyc deleted file mode 100644 index 0ca29d7..0000000 Binary files a/utils/dummy_data_generator/__pycache__/users_generation.cpython-310.pyc and /dev/null differ diff --git a/utils/dummy_data_generator/__pycache__/utility_functions.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/utility_functions.cpython-310.pyc deleted file mode 100644 index 91d4620..0000000 Binary files a/utils/dummy_data_generator/__pycache__/utility_functions.cpython-310.pyc and /dev/null differ diff --git a/utils/dummy_data_generator/__pycache__/webinars_generation.cpython-310.pyc b/utils/dummy_data_generator/__pycache__/webinars_generation.cpython-310.pyc deleted file mode 100644 index 1d1e3da..0000000 Binary files a/utils/dummy_data_generator/__pycache__/webinars_generation.cpython-310.pyc and /dev/null differ