Opis aplikacji
Aplikacja będzie miała za zadanie katalogować i zarządzać szkoleniami BHP, a ponadto móc generować raporty z bieżącego szkolenia jak i ze szkoleń w historii. Docelowym użytkownikiem aplikacji będzie pojedynczy, zewnętrzny szkoleniowiec prowadzący szkolenia w pewnych zakładach pracy i mający pod opieką pewną grupę pracowników dla których konieczne są szkolenia, zarówno jednorazowe jak i okresowe.
Opis funkcjonalny
Pracownicy
Katalogowanie pracowników będzie polegać na ich grupowaniu względem zakładu pracy w którym pracują oraz wyświetlaniu wszystkich informacji powiązanych z danym pracownikiem. Jednocześnie będą dostępne zbiorcze zestawienia pracowników w celu przeglądu z możliwością sortowania względem wybranych informacji. Kolejnym elementem będzie rozbudowany filtr, umożliwiający przeszukiwanie bazy względem wielu kryteriów dotyczących pracowników i informacji z nimi związanych.
Z każdym pracownikiem będą związane następujące informacje:
dane teleadresowe
informacje o zakładzie pracy w którym pracuje
informacje o aktualnie ważnym badaniu lekarskim
informacje o aktualnie ważnym szkoleniu
pełna historia odbytych szkoleń
Zakłady pracy
Pracownicy będą katalogowani względem zakładów pracy w których pracują. Dodatkowo będzie zaimplementowana złożona wyszukiwarka tychże zakładów.
Z każdym zakładem pracy będą związane następujące informacje:
dane teleadresowe
lista pracowników
Kategorie szkoleń
Kategorie szkoleń będą tworzyły reprezentację różnych rodzajów szkoleń jakie są charakterystyczne dla poszczególnych grup pracowników, np. pracownicy fizyczni lub pracujący w szczególnych warunkach zdrowotnych. Kategorie szkoleń będą również kolejną metodą grupowania pracowników, gdyż każdy z pracowników, po odbyciu szkolenia będzie klasyfikowany do pewnej grupy zawodowej. Dla kategorii będzie również zaimplementowana złożona wyszukiwarka.
Dla kategorii szkoleń będą charakterystyczne następujące informacje:
nazwa, opis kategorii
okres ważności wskazujący po jakim czasie pracownik powinien być przeszkolony ponownie
liczba przeprowadzonych szkoleń
plik szablonu raportu, wskazujący szablon który powinien zostać użyty przy generowaniu raportu dla danego szkolenia
Szkolenia
Na wcześniej wybranej grupie pracowników, użytkownik będzie mógł przeprowadzić szkolenie zadanej kategorii. Informacja o szkoleniu zostanie dodana do historii szkoleń, a wszystkie inne informacje w bazie zostaną odpowiednio uaktualnione. Dodatkowo zostanie wygenerowany odpowiedni dla danej kategorii plik raportu, zawierające informacje na temat przeprowadzonego szkolenia a przeznaczony do wydruku. Plik wygenerowanego raportu również zostanie zapisany w historii. Dodatkowo będzie zaimplementowana rozbudowana wyszukiwarka.
Dla poszczególnych szkoleń będą dostępne następujące informacje:
charakterystyczny numer identyfikujący poszczególne szkolenia
kategoria, opis
data szkolenia
data ważności
plik szablonu raportu, który został użyty
Historia szkoleń
Wszystkie przeprowadzone szkolenia będą zapisywane. Będzie można przeglądać pełną historię przeprowadzonych szkoleń jak i historię szkoleń dla każdego pracownika z osobna. Dodatkowo będzie zaimplementowana rozbudowana wyszukiwarka.
Raporty
Raporty będą generowane po przeprowadzeniu szkolenia na podstawie wcześniej zdefiniowanych plików szablonów. Pliki szablonów będą reprezentowane przez dokumenty typu OpenXML, zawierające strukturę raportu ze zdefiniowanymi polami-argumentami, które będą uzupełniane informacjami charakterystycznymi dla przeprowadzonego szkolenia. Raporty automatycznie będą drukowane, z możliwością ponownego ich odtworzenia z historii szkoleń.
Technologie
Środowisko implementacji
MS Visual Studio 2010
.NET Framework 4.0
MS SQL Server 2008 R2
MS Word 2007
Open XML SDK 2.0
Elementy do wdrożenia testowego
Użycie bazy danych SQLExpress, przechowującej dane w pojedynczym pliku dołączanym do właściwej aplikacji. Rozwiązanie zapewnia niemal pełną funkcjonalność standardowej bazy danych bez konieczności instalowania bazy w silniku serwera. Wydaje się to być ciekawym rozwiązaniem dla aplikacji mającej stosunkowo niewielki narzut danych.
Użycie funkcji CLR (implementowanych przy użyciu C# i .NET Framework) wewnątrz bazy danych. Funkcje mogłyby zapewnić integralność informacji o plikach, przechowywanych w bazie z ich fizyczną reprezentacją na dysku na poziomie mechanizmów samej bazy.
Użycie biblioteki Open XML SDK 2.0 dającej możliwość manipulacją plikami formatu OpenXML w celu generowania elastycznych raportów na podstawie wcześniej przygotowywanych, standardowych i łatwych w tworzeniu dokumentów pakietu MS Office 2007 lub OpenOffice.
Projekt bazy danych
Baza danych będzie implementowana jako darmowa baza SQLExpress, która jest oparta na komercyjnym SZBD MS SQL Server 2008 R2.
Tabele
Wyzwalacze
Implementacja dodatkowych wyzwalaczy była konieczna ze względu na to, że MS SQL Server nie dopuszcza definiowania kluczy obcych, które tworzyły by w bazie zapętlone wywołania ON DELETE ACTION lub ON UPDATE ACTION.
Wyzwalacze dla tabeli Template
Wyzwalacz utrzymuje więzy integralności z innymi tabelami w przypadku usuwania danych.
CREATE TRIGGER [dbo].[ForDeleteTemplateTrigger]
ON [dbo].[Template]
FOR DELETE
AS
-- aktualizacja tabeli Training
UPDATE dbo.Training
SET ProtocolTemplateId = NULL
WHERE ProtocolTemplateId IN (SELECT Id FROM deleted)
UPDATE dbo.Training
SET CertificateTemplateId = NULL
WHERE CertificateTemplateId IN (SELECT Id FROM deleted)
-- aktualizacja tabeli TrainingCategory
UPDATE dbo.TrainingCategory
SET ProtocolTemplateId = NULL
WHERE ProtocolTemplateId IN (SELECT Id FROM deleted)
UPDATE dbo.TrainingCategory
SET CertificateTemplateId = NULL
WHERE CertificateTemplateId IN (SELECT Id FROM deleted)
GO
Wyzwalacz utrzymuje więzy integralności z innymi tabelami w przypadku modyfikowania klucza głównego.
-- Utrzymuje więzy integralności innych tabel z tabelą Template w przypadku modyfikowania klucza głównego.
CREATE TRIGGER [dbo].[ForUpdateTemplateTrigger]
ON [dbo].[Template]
FOR UPDATE
AS
-- aktualizacja tabel TrainingCategory i Training
IF UPDATE(Id)
BEGIN
DECLARE @insertedId uniqueidentifier, @deletedId uniqueidentifier
DECLARE ForUpdateInsertedRowsCursor CURSOR FOR
SELECT Id FROM inserted
DECLARE ForUpdateDeletedRowsCursor CURSOR FOR
SELECT Id FROM deleted
OPEN ForUpdateInsertedRowsCursor
OPEN ForUpdateDeletedRowsCursor
FETCH NEXT FROM ForUpdateInsertedRowsCursor
INTO @insertedId
FETCH NEXT FROM ForUpdateDeletedRowsCursor
INTO @deletedId
WHILE @@FETCH_STATUS = 0
BEGIN
-- aktualizacja tabeli TrainingCategory
UPDATE dbo.TrainingCategory
SET ProtocolTemplateId = @insertedId
WHERE ProtocolTemplateId = @deletedId
UPDATE dbo.TrainingCategory
SET CertificateTemplateId = @insertedId
WHERE CertificateTemplateId = @deletedId
-- aktualizacja tabeli Training
UPDATE dbo.Training
SET ProtocolTemplateId = @insertedId
WHERE ProtocolTemplateId = @deletedId
UPDATE dbo.Training
SET CertificateTemplateId = @insertedId
WHERE CertificateTemplateId = @deletedId
-- wczytanie kolejnego rekordu
FETCH NEXT FROM ForUpdateInsertedRowsCursor
INTO @insertedId
FETCH NEXT FROM ForUpdateDeletedRowsCursor
INTO @deletedId
END
CLOSE ForUpdateInsertedRowsCursor
CLOSE ForUpdateDeletedRowsCursor
DEALLOCATE ForUpdateInsertedRowsCursor
DEALLOCATE ForUpdateDeletedRowsCursor
END
Wyzwalacze dla tabeli TrainingCategory
Wyzwalacz utrzymuje więzy integralności z innymi tabelami w przypadku usuwania danych.
CREATE TRIGGER [dbo].[DeleteTrainingCategoryTrigger]
ON [dbo].[TrainingCategory]
FOR DELETE
AS
-- aktualizacja tabeli Training
UPDATE dbo.Training
SET TrainingCategoryId = NULL
WHERE TrainingCategoryId IN (SELECT Id FROM deleted)
GO
Wyzwalacz utrzymuje więzy integralności z innymi tabelami w przypadku modyfikowania klucza głównego.
CREATE TRIGGER [dbo].[UpdateTrainingCategoryTrigger]
ON [dbo].[TrainingCategory]
FOR UPDATE
AS
-- aktualizacja tabeli Training
IF UPDATE(Id)
BEGIN
DECLARE @insertedId uniqueidentifier, @deletedId uniqueidentifier
DECLARE InsertedRowsCursor CURSOR FOR
SELECT Id FROM inserted
DECLARE DeletedRowsCursor CURSOR FOR
SELECT Id FROM deleted
OPEN InsertedRowsCursor
OPEN DeletedRowsCursor
FETCH NEXT FROM InsertedRowsCursor
INTO @insertedId
FETCH NEXT FROM DeletedRowsCursor
INTO @deletedId
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE dbo.Training
SET TrainingCategoryId = @insertedId
WHERE TrainingCategoryId = @deletedId
FETCH NEXT FROM InsertedRowsCursor
INTO @insertedId
FETCH NEXT FROM DeletedRowsCursor
INTO @deletedId
END
CLOSE InsertedRowsCursor
CLOSE DeletedRowsCursor
DEALLOCATE InsertedRowsCursor
DEALLOCATE DeletedRowsCursor
END
Widoki
Widok zakładu pracy
Widok umożliwia wybranie istotnych dla użytkownika informacji dla danego zakładu pracy.
Diagram
Skrypt
CREATE VIEW [dbo].[TrainingCategoryView]
AS
SELECT dbo.TrainingCategory.Id, dbo.TrainingCategory.Name, dbo.TrainingCategory.ExpiryTime, dbo.TrainingCategory.Description, dbo.TrainingCategory.LastNumber,
ProtocolTemplate.Name AS ProtocolName, CertificateTemplate.Name AS CertificateName, ProtocolTemplate.Id AS ProtocolId,
CertificateTemplate.Id AS CertificateId
FROM dbo.Template AS CertificateTemplate RIGHT OUTER JOIN
dbo.TrainingCategory ON CertificateTemplate.Id = dbo.TrainingCategory.CertificateTemplateId LEFT OUTER JOIN
dbo.Template AS ProtocolTemplate ON dbo.TrainingCategory.ProtocolTemplateId = ProtocolTemplate.Id
Widok pracownika
Widok grupuje informacje na temat pracownika, jego zakładu pracy oraz aktualnie ważnego szkolenia.
Diagram
Skrypt
CREATE VIEW [dbo].[EmployeeDetailsView]
AS
SELECT dbo.Employee.Surname, dbo.Employee.Forename, dbo.Employee.Street, dbo.Employee.BuildingNumber, dbo.Employee.FlatNumber, dbo.Employee.City,
dbo.Employee.PostalCode, dbo.Employee.Post, dbo.Employee.Phone, dbo.Employee.Email, dbo.Employee.BirthDate, dbo.Employee.BirthPlace,
dbo.Employee.Position, dbo.Employee.CheckupExpiryDate, dbo.Employee.Id, dbo.Company.Name, dbo.Employee.CompanyId, dbo.Training.Number,
dbo.Training.TrainingDate, dbo.Training.ExpiryDate, dbo.TrainingCategory.Name AS CategoryName
FROM dbo.TrainingCategory RIGHT OUTER JOIN
dbo.Training ON dbo.TrainingCategory.Id = dbo.Training.TrainingCategoryId RIGHT OUTER JOIN
dbo.Company INNER JOIN
dbo.Employee ON dbo.Company.Id = dbo.Employee.CompanyId ON dbo.Training.Id = dbo.Employee.CurrentTrainingId
Widok kategorii szkoleń
Widok grupuje informacje na temat szkoleń i przypisanych raportów.
Diagram
Skrypt
CREATE VIEW [dbo].[TrainingCategoryView]
AS
SELECT dbo.TrainingCategory.Id, dbo.TrainingCategory.Name, dbo.TrainingCategory.ExpiryTime, dbo.TrainingCategory.Description, dbo.TrainingCategory.LastNumber,
ProtocolTemplate.Name AS ProtocolName, CertificateTemplate.Name AS CertificateName, ProtocolTemplate.Id AS ProtocolId,
CertificateTemplate.Id AS CertificateId
FROM dbo.Template AS CertificateTemplate RIGHT OUTER JOIN
dbo.TrainingCategory ON CertificateTemplate.Id = dbo.TrainingCategory.CertificateTemplateId LEFT OUTER JOIN
dbo.Template AS ProtocolTemplate ON dbo.TrainingCategory.ProtocolTemplateId = ProtocolTemplate.Id
Widok historii szkoleń
Widok grupuje informacje na temat szkoleń, ich kategorii oraz przypisanych raportów.
Diagram
Skrypt
CREATE VIEW [dbo].[TrainingHistoryView]
AS
SELECT dbo.Training.Id, dbo.Training.Number, dbo.Training.TrainingDate, dbo.Training.ExpiryDate, dbo.Training.Description, dbo.TrainingCategory.Name AS CategoryName,
ProtocolTemplate.Name AS ProtocolName, CertificateTemplate.Name AS CertificateName, ProtocolTemplate.Id AS ProtocolId, CertificateTemplate.Id AS CertificateId,
ProtocolTemplate.FileName AS ProtocolFileName, CertificateTemplate.FileName AS CertificateFileName
FROM dbo.Template AS ProtocolTemplate RIGHT OUTER JOIN
dbo.Training ON ProtocolTemplate.Id = dbo.Training.ProtocolTemplateId LEFT OUTER JOIN
dbo.TrainingCategory ON dbo.Training.TrainingCategoryId = dbo.TrainingCategory.Id LEFT OUTER JOIN
dbo.Template AS CertificateTemplate ON dbo.Training.CertificateTemplateId = CertificateTemplate.Id
Funkcje
IsTemplateUsing
Funkcja sprawdza czy dany plik szablonu jest gdziekolwiek wykorzystywany w bazie. Funkcja umożliwi wielokrotne wykorzystywanie tego samego pliku i jednocześnie automatyczne jego usuwanie, jeżeli nie będzie już potrzebny.
Skrypt
CREATE FUNCTION [dbo].[IsTempleteUsing]
(
@templateIdParam uniqueidentifier
)
RETURNS BIT
AS
BEGIN
IF EXISTS (SELECT Id FROM TrainingCategory WHERE ProtocolTemplateId = @templateIdParam)
RETURN 1
IF EXISTS (SELECT Id FROM TrainingCategory WHERE CertificateTemplateId = @templateIdParam)
RETURN 1
IF EXISTS (SELECT Id FROM Training WHERE ProtocolTemplateId = @templateIdParam)
RETURN 1
IF EXISTS (SELECT Id FROM Training WHERE CertificateTemplateId = @templateIdParam)
RETURN 1
RETURN 0
END
Procedury
SelectTrainingsByEmployeeId
Procedura umożliwia wybranie rekordów wszystkich szkoleń w których uczestniczył zadany pracownik.
Skrypt
CREATE PROCEDURE [dbo].[SelectTrainingsByEmployeeId]
@employeeIdParam uniqueidentifier
AS
SET NOCOUNT ON;
SELECT *
FROM dbo.TrainingHistoryView
WHERE (Id IN (SELECT TrainingId FROM dbo.EmployeeTraining WHERE (EmployeeId = @employeeIdParam)));
RETURN
SelectEmployeesByTrainingId
Procedura umożliwia wybranie wszystkich rekordów pracowników, którzy uczestniczyli w zadanym szkoleniu.
Skrypt
CREATE PROCEDURE [dbo].[SelectEmployeesByTrainingId]
@trainingIdParam uniqueidentifier
AS
SET NOCOUNT ON;
SELECT EmployeeDetailsView.Surname, EmployeeDetailsView.Forename, EmployeeDetailsView.Street, EmployeeDetailsView.BuildingNumber,
EmployeeDetailsView.FlatNumber, EmployeeDetailsView.City, EmployeeDetailsView.PostalCode, EmployeeDetailsView.Post, EmployeeDetailsView.Phone,
EmployeeDetailsView.Email, EmployeeDetailsView.BirthDate, EmployeeDetailsView.BirthPlace, EmployeeDetailsView.Position,
EmployeeDetailsView.CheckupExpiryDate, EmployeeDetailsView.Id, EmployeeDetailsView.Name, EmployeeDetailsView.CompanyId, EmployeeDetailsView.Number,
EmployeeDetailsView.TrainingDate, EmployeeDetailsView.ExpiryDate, EmployeeDetailsView.CategoryName
FROM EmployeeTraining INNER JOIN
EmployeeDetailsView ON EmployeeTraining.EmployeeId = EmployeeDetailsView.Id
WHERE (EmployeeTraining.TrainingId = @trainingIdParam)
RETURN
Diagram przypadków użycia
Diagram klas
Diagramy sekwencji
Przeprowadzenie szkolenia