/// <summary> /// Konstruktor. /// </summary> /// <param name="leaveManagerParentForm">Obiekt rodzica.</param> /// <param name="connection">Połączenie z bazą danych. Powinno być otwarte.</param> /// <param name="employeeId">Numer id pracownika, którego dotyczy zgłoszenie urlopowe.</param> /// <param name="firstDay">Data rozpoczęcia urlopu.</param> /// <param name="lastDay">Data zakończenia urlopu.</param> public FormLeaveConsideration(LeaveManagerForm leaveManagerParentForm, SqlConnection connection, Leave consideredLeave ) { InitializeComponent(); this.connection = connection; this.consideredLeave = consideredLeave; this.leaveManagerParentForm = leaveManagerParentForm; labelFirstDayValue.Text = consideredLeave.FirstDay.ToString("d"); labelLastDayValue.Text = consideredLeave.LastDay.ToString("d"); try { //Zczytanie imienia, nazwiska oraz pozycji pracownika. Employee employee = this.GetEmployee(consideredLeave.EmployeeId); labelNameValue.Text = employee.Name; labelPositionValue.Text = employee.Position; DateTime tmp = consideredLeave.FirstDay; bool[] days = this.GetWorkingDaysOfWeek(employee.EmployeeId); while (tmp <= consideredLeave.LastDay) { if (days[((int)tmp.DayOfWeek + 6) % 7] && !IsHoliday(tmp)) dataGridView.Rows.Add(tmp, this.GetSimiliarWorkerCount(this.GetPositionID(employee.Position), employee.EmployeeId, tmp), this.GetNeededEmployeesNo(tmp)); tmp = tmp.AddDays(1); } } catch (SqlException) { MessageBox.Show("SQL Error. This form will be close. Please try again later."); this.Close(); } catch (InvalidOperationException) { MessageBox.Show("Invalid operation. This form will be close. Please try again later"); this.Close(); } catch (EmployeeIdException) { MessageBox.Show("EmployeeID not found in database. This form will be close. Please try again later"); this.Close(); } catch (Exception ex) { MessageBox.Show("Unknown exception has occured" + ex.Message); this.Close(); } }
/// <summary> /// Konstruktor przeznaczony do tworzenia instancji edytującej istniejący wpis /// urlopowy. Ustawia wartości w elementach zczytujących dane (np. textbox, combobox) /// zgodne z wartościami w edytowanym wpisie urlopowym. /// </summary> /// <param name="connection">Połączenie do bazy danych. Powinno być otwarte.</param> /// <param name="leaveDaysList">Dostępna liczba dni urlopowych (bez dni zaległych).</param> /// <param name="oldLeaveDaysList">Dostępna liczba zaległych dni urlopowych.</param> /// <param name="employeeId">Numer id pracownika, którego dotyczy zgłoszenie urlopowe.</param> /// <param name="editedLeave">Obiekt reprezentujący edytowany wpis urlopowy.</param> public FormLeaveApplication(SqlConnection connection, Leave editedLeave) { InitializeComponent(); this.connection = connection; this.employeeId = editedLeave.EmployeeId; this.editMode = true; this.editedLeave = editedLeave; //Zczytanie listy typów urlopów i przypisanie do atrybutu klasy oraz do odpowiedniego //comboBox'a. try { comboBoxType.DataSource = leaveTypes = this.GetLeaveTypesList(); } catch (SqlException) { MessageBox.Show("SQL Error. This form will be close. Please try again later."); this.Close(); } catch (InvalidOperationException) { MessageBox.Show("Invalid operation. This form will be close. Please try again later"); this.Close(); } catch (Exception ex) { MessageBox.Show("Unknown exception has occured" + ex.Message); this.Close(); } //Zaznaczenie w comboBox'ie zawierającym typy urlopów typu edytowanego zgłoszenia. comboBoxType.SelectedIndex = comboBoxType.FindStringExact(editedLeave.LeaveType); /* Ustawienie ograniczenia odnośnie możliwości wyboru dnia rozpoczęcia i zakończenia urlopu. * Jeżeli pierwszy dzień w zgłoszeniu już był (jest wcześniej niż teraz), * to najwcześniejszą możliwą datą jest ten właśnie dzień. W innym wypadku najwcześniejszą możliwą * datą jest dzisiaj. */ if (editedLeave.FirstDay.CompareTo(DateTime.Now) <= 0) { dateTimePickerFirstDay.MinDate = editedLeave.FirstDay.Trim(TimeSpan.TicksPerDay); dateTimePickerLastDay.MinDate = editedLeave.FirstDay.Trim(TimeSpan.TicksPerDay); } else { dateTimePickerLastDay.MinDate = dateTimePickerFirstDay.MinDate = DateTime.Now.Trim(TimeSpan.TicksPerDay); } //Ograniczenie wyboru dnia rozpoczęcia i zakończenia. Najpóźniej na rok od dnia dzisiejszego. dateTimePickerFirstDay.MaxDate = DateTime.Now.Trim(TimeSpan.TicksPerDay).AddYears(1); dateTimePickerLastDay.MaxDate = DateTime.Now.Trim(TimeSpan.TicksPerDay).AddYears(1); /* Ustawienie wartości początkowej dla elementu wyboru dni rozpoczęcia i zakończenia * na dni rozpoczęcia i zakończenia w edytowanym zgłoszeniu. */ dateTimePickerFirstDay.Value = editedLeave.FirstDay; dateTimePickerLastDay.Value = editedLeave.LastDay; /* Jeżli zgłoszenie urlopowe jest typu, który konsumuje dni urlopowe, to następuje * obliczenie i ustawienie wartości etykiety z liczbą zużywanych przez urlop dni. */ if (leaveTypes[comboBoxType.SelectedIndex].ConsumesDays) { labelUsedDaysValue.Text = this.GetNumberOfWorkDays(dateTimePickerFirstDay.Value, dateTimePickerLastDay.Value, employeeId).ToString(); } else { labelUsedDaysValue.Text = "0"; } int oldLeaveDays = 0; int leaveDays = 0; this.GetDays(this.employeeId, ref leaveDays, ref oldLeaveDays); //Obliczenie i przypisanie do etykiety liczby dostępnych do zużycia dni. labelAvailableDaysValue.Text = (leaveDays + oldLeaveDays).ToString(); labelNormalValue.Text = leaveDays.ToString(); labelOldValue.Text = oldLeaveDays.ToString(); textBoxRemarks.Text = editedLeave.Remarks; //Zczytanie listy statusów. List<String> statusList = this.GetStatusTypes(); //Jeżeli status bieżącego urlopu nie jest approved, to usuwana jest możliwość wyboru tego statusu. if (!editedLeave.LeaveStatus.Equals("Approved")) { statusList.Remove("Approved"); } comboBoxStatus.DataSource = statusList; comboBoxStatus.SelectedIndex = comboBoxStatus.FindStringExact(editedLeave.LeaveStatus); }
//todo łądnie ogarnąć try i catche. /// <summary> /// Metoda obsługi zdarzenia wciśnięcia guzika ok. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonOk_Click(object sender, EventArgs e) { int numberOfUsedDays = this.GetNumberOfWorkDays(dateTimePickerFirstDay.Value, dateTimePickerLastDay.Value, employeeId); int leaveDays = 0; int oldLeaveDays = 0; int yearDays = 0; //Zczytanie aktualnych wartości dostępnych dni urlopowych. try { this.GetDays(employeeId, ref leaveDays, ref oldLeaveDays, ref yearDays); } catch (SqlException) { MessageBox.Show("SQL error. Please try connection to database or try again later"); return; } catch (InvalidOperationException) { MessageBox.Show("Invalid operation. Please try again later."); return; } catch (Exception ex) { MessageBox.Show("Unknown exception has occured" + ex.Message); return; } //Uaktualnienie warotości etykiet. labelAvailableDaysValue.Text = (leaveDays + oldLeaveDays).ToString(); labelNormalValue.Text = leaveDays.ToString(); labelOldValue.Text = oldLeaveDays.ToString(); //Sprawdzenie, czy nowe zgłoszenie nie wykorzystuje więcej dni, niż pracownik ma ich dostępnych. if (numberOfUsedDays <= oldLeaveDays + leaveDays) { //Sprawdzenie, czy zgłoszenie urlopowe wykorzystuje jakiekolwiek dni. if (numberOfUsedDays != 0) { /* Sprawdzenie, czy zgłoszenie nie koliduje z już istniejącym. * Jeżeli jest to nowe zgłoszenie (!editMode), to należy po prostu sprawdzić, czy * któryś z dni zgłoszenia nie jest już wykorzystany w innym zgłoszeniu. * Jeżeli jest to zgłoszenie edytowane, to należy sprawdzić, czy któryś z dni zgłoszenia * nie jest już wykorzystany w innym zgłoszeniu, ale należy pominąć sprawdzanie wpisu * edytowanego. * Jeżeli zgłoszenie jest zgłoszeniem chorobowego, to może kolidować z innymi zgłoszeniami. */ if ((!editMode && !this.IsDateFromPeriodUsed(dateTimePickerFirstDay.Value, dateTimePickerLastDay.Value, employeeId)) || (editMode && !this.IsDateFromPeriodUsed(dateTimePickerFirstDay.Value, dateTimePickerLastDay.Value, employeeId, editedLeave.FirstDay)) || comboBoxType.SelectedItem.ToString().Equals("Sick")) { string choosenStatus; if (comboBoxStatus.SelectedItem != null) choosenStatus = comboBoxStatus.SelectedItem.ToString(); else choosenStatus = "Pending validation"; //Stworzenie nowego obiektu urlopu. Leave leave = new Leave(employeeId, comboBoxType.SelectedItem.ToString(), choosenStatus, dateTimePickerFirstDay.Value, dateTimePickerLastDay.Value, textBoxRemarks.Text); if (editMode) { try { leave.Id = editedLeave.Id; this.EditLeave(leave); this.Close(); } catch (SqlException) { MessageBox.Show("SQL error. Please try connection to database or try again later"); } catch (InvalidOperationException) { MessageBox.Show("Invalid operation. Please try again later."); } catch (IsolationLevelException) { MessageBox.Show("Isolation level error. Please try again later or contact administrator"); } catch (ArgumentException) { MessageBox.Show("Wrong argument\n"); } catch (Exception ex) { MessageBox.Show("Unknown exception has occured" + ex.Message); } } else { //Jeżeli wybrano zgłoszenie chorobowe. if (comboBoxType.SelectedItem.ToString().Equals("Sick")) { try { //Dodanie urlopu. this.AddSickLeave(leave); this.Close(); } catch (SqlException) { MessageBox.Show("SQL error. Please try connection to database or try again later"); } catch (InvalidOperationException) { MessageBox.Show("Invalid operation. Please try again later."); } catch (IsolationLevelException) { MessageBox.Show("Isolation level error. Please try again later or contact administrator"); } catch (ArgumentOutOfRangeException) { MessageBox.Show("Wrong argument\n"); } catch (Exception ex) { MessageBox.Show("Unknown exception has occured" + ex.Message); } } else { try { this.AddLeave(leave); this.Close(); } catch (OverflowException) { MessageBox.Show("You don't have enough extraordinary days left."); } catch (SqlException) { MessageBox.Show("SQL error. Please try connection to database or try again later"); } catch (InvalidOperationException) { MessageBox.Show("Invalid operation. Please try again later."); } catch (IsolationLevelException) { MessageBox.Show("Isolation level error. Please try again later or contact administrator"); } catch (ArgumentOutOfRangeException) { MessageBox.Show("Wrong argument\n"); } catch (Exception ex) { MessageBox.Show("Unknown exception has occured" + ex.Message); } } } } else { MessageBox.Show("At least one day from selected period is already used for leave."); } } else { MessageBox.Show("No work days selected."); } } }
/// <summary> /// Metoda dodawania zgłoszenia urlopowego. /// Rozszerza formularz zgłoszenia urlopowego. /// </summary> /// <param name="form">Formularz wywołujący metodę.</param> /// <param name="leave">Obiekt reprezentujący nowy wpis urlopowy.</param> /// <exception cref="SqlException">An exception occurred while executing the command against a locked row.</exception> /// <exception cref="InvalidOperationException">The current state of the connection is closed.</exception> /// <exception cref="IsolationLevelException">Wyjątek występuje, gdy poziom izolacji uruchomionej w /// formularzu transakcji jest zbyt niski do zapewnienia poprawnego wykonania poleceń metody.</exception> /// <exception cref="ArgumentException">Występuje w przypadku próby odjęcia większej liczby dni, niż pracownik posiada.</exception> public static void AddLeave(this FormLeaveApplication form, Leave leave) { AddLeave((LeaveManagerForm)form, leave); }
/// <summary> /// Metoda pobierająca wpis urlopowy. /// </summary> /// <param name="form">Formularz potrzebujący metody.</param> /// <param name="id">Numer id pobieranego urlopu.</param> /// <returns>Obiekt reprezentujący dany urlop.</returns> /// <exception cref="SqlException">An exception occurred while executing the command against a locked row.</exception> /// <exception cref="InvalidOperationException">The current state of the connection is closed.</exception> private static Leave GetLeave(LeaveManagerForm form, int leaveId) { SqlCommand command = new SqlCommand("SELECT L.Employee_ID, LT.Name AS 'Type', " + "LS.Name AS 'Status', L.First_day, L.Last_day, " + "L.Remarks, L.Used_days FROM Leave L, Leave_type LT, Status_type LS WHERE Leave_ID = @Leave_ID", form.Connection); if (form.TransactionOn) command.Transaction = form.Transaction; command.Parameters.Add("@Leave_ID", SqlDbType.Int).Value = leaveId; SqlDataReader reader = command.ExecuteReader(); reader.Read(); Leave result = new Leave(leaveId, (int)reader["Employee_ID"], reader["Type"].ToString(), reader["Status"].ToString(), (DateTime)reader["First_day"], (DateTime)reader["Last_day"], reader["Remarks"].ToString(), (int)reader["Used_days"]); reader.Close(); return result; }
/// <summary> /// Metoda edytująca wpis urlopowy. /// </summary> /// <param name="form">Formularz potrzebujący metody.</param> /// <param name="leave">Obiekt urlopu wpisany w miejsce starego wpisu.</param> /// <param name="editedLeaveId">Numer id edytowanego wpisu urlopowego.</param> /// <exception cref="SqlException">An exception occurred while executing the command against a locked row.</exception> /// <exception cref="InvalidOperationException">The current state of the connection is closed.</exception> /// <exception cref="IsolationLevelException">Wyjątek występuje, gdy poziom izolacji uruchomionej w /// formularzu transakcji jest zbyt niski do zapewnienia poprawnego wykonania poleceń metody.</exception> /// <exception cref="ArgumentException">Występuje w przypadku próby wzięcia pracownikowi większej liczby dni, niż posiada.</exception> private static void EditLeave(LeaveManagerForm form, Leave leave) { /* Dla poprawnego działania tej metody konieczne jest aby posiadała ona transakcję * o odpowiednim poziomie izolacji. */ //Zmienna przechowująca stan transakcji przed uruchomieniem metody. bool isFormTransactionOn = form.TransactionOn; //Jeżeli formularz posiada uruchomioną transakcję. if (form.TransactionOn) { //Sprawdzenie, czy poziom izolacji istniejącej transakcji jest wystarczający. if (form.Transaction.IsolationLevel != IsolationLevel.RepeatableRead && form.Transaction.IsolationLevel != IsolationLevel.Serializable) { throw new IsolationLevelException(); } } else//Jeżeli formularz nie posiada uruchomionej transakcji. //Uruchomienie nowej transakcji na potrzeby tej metody z odpowiednim poziomem izolacji. form.BeginTransaction(IsolationLevel.RepeatableRead); try { //Zczytanie podmienianego urlopu. Leave oldLeave = GetLeave(form, leave.Id); //Jeżeli wpisywany urlop konsumuje dni urlopowe. if (ConsumesDays(form, leave.LeaveType)) { leave.UsedDays = GetNumberOfWorkDays(form, leave.FirstDay, leave.LastDay, leave.EmployeeId); //Obliczenie różnicy o którą trzeba zmienić liczbę dni urlopowych pracownika. int difference = oldLeave.UsedDays - leave.UsedDays; AddLeaveDays(form, leave.EmployeeId, difference); } else//Nowy urlop nie konsumuje dni. { leave.UsedDays = 0; //Jeżeli stary urlop konsumuje dni. if (ConsumesDays(form, oldLeave.LeaveType)) //Dodajemy pracownikowi tyle dni, ile stary urlop konsumował. AddLeaveDays(form, leave.EmployeeId, oldLeave.UsedDays); } //Polecenie sql aktualizujące wszystkie dane w starym wpisie. SqlCommand commandUpdate = new SqlCommand("UPDATE Leave SET LT_ID = (SELECT LT_ID FROM Leave_type WHERE Name = @Leave_type_name), LS_ID = " + "(SELECT ST_ID FROM Status_type WHERE Name = @Status_name), " + "First_day = @First_day, Last_day = @Last_day, Remarks = @Remarks, Used_days = @Used_days " + "WHERE Leave_ID = @OldLeave_ID", form.Connection, form.Transaction); commandUpdate.Parameters.Add("@OldLeave_ID", SqlDbType.Int).Value = leave.Id; //Jeżeli wpisywany urlop jest chorobowym, to niezależnie od ustawionego stanu jest ustawiony stan zatwierdzony. if (leave.LeaveStatus.Equals("Sick")) { commandUpdate.Parameters.Add("@Status_name", SqlDbType.VarChar).Value = "Approved"; } else { if (leave.LeaveStatus.Equals("Extraordinary")) { } else { commandUpdate.Parameters.Add("@Status_name", SqlDbType.VarChar).Value = leave.LeaveStatus; } } commandUpdate.Parameters.Add("@Employee_ID", SqlDbType.Int).Value = leave.EmployeeId; commandUpdate.Parameters.Add("@Leave_type_name", SqlDbType.VarChar).Value = leave.LeaveType; commandUpdate.Parameters.Add("@First_day", SqlDbType.Date).Value = leave.FirstDay; commandUpdate.Parameters.Add("@Last_day", SqlDbType.Date).Value = leave.LastDay; commandUpdate.Parameters.Add("@Remarks", SqlDbType.VarChar).Value = leave.Remarks; commandUpdate.Parameters.Add("@Used_days", SqlDbType.Int).Value = leave.UsedDays; commandUpdate.ExecuteNonQuery(); } catch (Exception e) { //Jeżeli transakcja formularza była uruchomiona tylko na potrzeby tej metody, to ją cofamy. if (!isFormTransactionOn) form.RollbackTransaction(); //Wyrzucamy wyjątek do dalszej obsługi. throw e; } //Jeżeli operacja powiodła się, a transakcja była uruchomiona tylko na potrzeby tej metody to ją zatwierdzamy. if (!isFormTransactionOn) form.CommitTransaction(); }
/// <summary> /// Dodanie chorobowego. /// </summary> /// <param name="form">Formularz potrzebujący metody.</param> /// <param name="leave">Obiekt reprezentujący dodawany urlop.</param> /// <exception cref="SqlException">An exception occurred while executing the command against a locked row.</exception> /// <exception cref="InvalidOperationException">The current state of the connection is closed.</exception> /// <exception cref="IsolationLevelException">Wyjątek występuje, gdy poziom izolacji uruchomionej w /// formularzu transakcji jest zbyt niski do zapewnienia poprawnego wykonania poleceń metody.</exception> private static void AddSickLeave(LeaveManagerForm form, Leave leave) { /* Dla poprawnego działania tej metody konieczne jest aby posiadała ona transakcję * o odpowiednim poziomie izolacji. */ //Zmienna przechowująca stan transakcji przed uruchomieniem metody. bool isFormTransactionOn = form.TransactionOn; //Jeżeli formularz posiada uruchomioną transakcję. if (form.TransactionOn) { //Sprawdzenie, czy poziom izolacji istniejącej transakcji jest wystarczający. if (form.Transaction.IsolationLevel != IsolationLevel.RepeatableRead && form.Transaction.IsolationLevel != IsolationLevel.Serializable) { throw new IsolationLevelException(); } } else//Jeżeli formularz nie posiada uruchomionej transakcji. //Uruchomienie nowej transakcji na potrzeby tej metody z odpowiednim poziomem izolacji. form.BeginTransaction(IsolationLevel.RepeatableRead); try { //Zczytanie urlopów pracownika, któremu dodajemy chorobowe. /// Kolumny tabeli: "Leave Id", "Status", "First day", "Last day", "Type", /// "Remarks", "No. used days" DataTable dataLeaves = GetLeaves(form, leave.EmployeeId); /* Zmienna w której będzie przechowywana liczba dni do zwrócenia pracownikowi. * Powiększa się w przypadku, gdy chorobowe zachodzi na jakiś urlop. */ int returnedLeaveDays = 0; int returnedDemandedDays = 0; //Dla każdego istniejącego w bazie urlopu. foreach (DataRow row in dataLeaves.Rows) { //Pierwszy dzień sprawdzanego urlopu jest później lub ten sam, co pierwszy dzień chorobowego if ((((DateTime)row.ItemArray.GetValue(2)).CompareTo(leave.FirstDay) >= 0) //i jest wcześniej lub taki sam jak ostatni dzień chorobowego. && (((DateTime)row.ItemArray.GetValue(2)).CompareTo(leave.LastDay) <= 0)) {//Czyli w praktyce: Zaczyna się w trakcie chorobowego -> jest anulowany. //Jeżeli zachodzący wpis to chorobowe. if (row.ItemArray.GetValue(4).ToString().Equals("Sick")) throw new EntryExistsException(); //Polecenie sql zmieniające stan zachodzącego urlopu na anulowany. SqlCommand commandUpdateLeave = new SqlCommand("UPDATE Leave SET " + "LS_ID = (SELECT ST_ID FROM Status_type WHERE Name = @Status_name), Used_days = @Used_days " + "WHERE Leave_ID = @Leave_ID", form.Connection, form.Transaction); commandUpdateLeave.Parameters.Add("@Status_name", SqlDbType.VarChar).Value = "Canceled"; commandUpdateLeave.Parameters.Add("@Leave_ID", SqlDbType.Int).Value = (int)row.ItemArray.GetValue(0); commandUpdateLeave.Parameters.Add("@Used_days", SqlDbType.Int).Value = 0; commandUpdateLeave.ExecuteNonQuery(); //Dodanie do liczby dni do zwrócenia pracownikowi dni anulowanego urlopu. returnedLeaveDays += (int)row.ItemArray.GetValue(6); if (row.ItemArray.GetValue(4).ToString().Equals("Extraordinary")) { returnedDemandedDays += (int)row.ItemArray.GetValue(6); } continue; } if ((leave.FirstDay.CompareTo((DateTime)row.ItemArray.GetValue(2)) >= 0)//Sick first day later than leave first day && (leave.FirstDay.CompareTo((DateTime)row.ItemArray.GetValue(3)) <= 0))//and earlier than leave last day. {//Czyli w praktyce: Kończy się w trakcie chorobowego -> jest 'przycinany' do ostatniego dnia przed chorobowym. SqlCommand commandUpdateLeave = new SqlCommand("UPDATE Leave SET " + "Last_day = @Last_day, Used_days = @Used_days WHERE Leave_ID = @Leave_ID", form.Connection, form.Transaction); commandUpdateLeave.Parameters.Add("@Last_day", SqlDbType.Date).Value = leave.FirstDay.AddDays(-1); commandUpdateLeave.Parameters.Add("@Leave_ID", SqlDbType.Int).Value = (int)row.ItemArray.GetValue(0); //Nowa liczba użytych dni to liczba użytych dni pomiędzy pierwszym dniem zmienianego urlopu i pierwszym-1 dniem chorobowego. commandUpdateLeave.Parameters.Add("@Used_days", SqlDbType.Int).Value = GetNumberOfWorkDays(form, (DateTime)row.ItemArray.GetValue(2), leave.FirstDay.AddDays(-1), leave.EmployeeId); commandUpdateLeave.ExecuteNonQuery(); int tmpReturnedDays = GetNumberOfWorkDays(form, leave.FirstDay.AddDays(-1), (DateTime)row.ItemArray.GetValue(1), leave.EmployeeId); //Dodanie do liczby dni do zwrócenia pracownikowi liczby dni za okres od początku chorobowego do końca urlopu. returnedLeaveDays += GetNumberOfWorkDays(form, leave.FirstDay.AddDays(-1), (DateTime)row.ItemArray.GetValue(1), leave.EmployeeId); //Jeżeli urlop był na żądanie. if (row.ItemArray.GetValue(4).ToString().Equals("Extraordinary")) { returnedDemandedDays += tmpReturnedDays; } continue; } } //Zwrócenie pracownikowi dni. AddLeaveDays(form, leave.EmployeeId, returnedLeaveDays); AddDemandDays(form, leave.EmployeeId, -returnedDemandedDays); //Dodanie urlopu. AddLeave(form, leave); } catch (Exception e) { //Jeżeli transakcja formularza była uruchomiona tylko na potrzeby tej metody, to ją cofamy. if (!isFormTransactionOn) form.RollbackTransaction(); //Wyrzucamy wyjątek do dalszej obsługi. throw e; } //Jeżeli operacja powiodła się, a transakcja była uruchomiona tylko na potrzeby tej metody to ją zatwierdzamy. if (!isFormTransactionOn) form.CommitTransaction(); }
/// <summary> /// Metoda dodawania zgłoszenia urlopowego. /// </summary> /// <param name="form">Formularz potrzebujący metody.</param> /// <param name="leave">Obiekt reprezentujący nowy wpis urlopowy.</param> /// <exception cref="SqlException">An exception occurred while executing the command against a locked row.</exception> /// <exception cref="InvalidOperationException">The current state of the connection is closed.</exception> /// <exception cref="IsolationLevelException">Wyjątek występuje, gdy poziom izolacji uruchomionej w /// formularzu transakcji jest zbyt niski do zapewnienia poprawnego wykonania poleceń metody.</exception> /// <exception cref="ArgumentException">Występuje w przypadku próby odjęcia większej liczby dni, niż pracownik posiada.</exception> private static void AddLeave(LeaveManagerForm form, Leave leave) { /* Dla poprawnego działania tej metody konieczne jest aby posiadała ona transakcję * o odpowiednim poziomie izolacji. */ //Zmienna przechowująca stan transakcji przed uruchomieniem metody. bool isFormTransactionOn = form.TransactionOn; //Jeżeli formularz posiada uruchomioną transakcję. if (form.TransactionOn) { //Sprawdzenie, czy poziom izolacji istniejącej transakcji jest wystarczający. if (form.Transaction.IsolationLevel != IsolationLevel.RepeatableRead && form.Transaction.IsolationLevel != IsolationLevel.Serializable) { throw new IsolationLevelException(); } } else//Jeżeli formularz nie posiada uruchomionej transakcji. //Uruchomienie nowej transakcji na potrzeby tej metody z odpowiednim poziomem izolacji. form.BeginTransaction(IsolationLevel.RepeatableRead); try { //Liczba zużytych przez urlop dni. int usedDays; //Jeżeli urlop konsumuje dni. if (ConsumesDays(form, leave.LeaveType)) { usedDays = GetNumberOfWorkDays(form, leave.FirstDay, leave.LastDay, leave.EmployeeId); //Odejmujemy pracownikowi dni za dany urlop. AddLeaveDays(form, leave.EmployeeId, -usedDays); } else { usedDays = 0; } //Polecenie sql Zczytujące największy nr id + 1 SqlCommand commandGetNewId = new SqlCommand("(SELECT MAX(Leave_ID) + 1 FROM Leave)", form.Connection, form.Transaction); int newLeaveId; try { newLeaveId = (int)commandGetNewId.ExecuteScalar(); } catch { //Jeżeli nie udało się zczytać id, to możliwe, że żaden wpis w bazie nie istnieje. Wtedy przypisujemy id = 0 newLeaveId = 0; } //Polecenie sql dodające nowy wpis urlopowy. SqlCommand commandInsertLeave = new SqlCommand("INSERT INTO Leave VALUES (@Leave_ID, @Employee_ID, " + "(SELECT LT_ID FROM Leave_type WHERE Name = @Leave_type_name), (SELECT ST_ID FROM Status_type WHERE Name = @Status_name), " + "@First_day, @Last_day, @Remarks, @Used_days)", form.Connection, form.Transaction); //Jeżeli wpis to chorobowe, to automatycznie otrzymuje stan zatwierdzony. if (leave.LeaveType.Equals("Sick")) { commandInsertLeave.Parameters.Add("@Status_name", SqlDbType.VarChar).Value = "Approved"; } else { //Jeżeli jest to urlop na żądanie, to automatycznie otrzymuje stan zatwierdzony. if (leave.LeaveType.Equals("Extraordinary")) { commandInsertLeave.Parameters.Add("@Status_name", SqlDbType.VarChar).Value = "Approved"; //Zaktualizowanie stanu liczby dostępnych dni na żądanie. AddDemandDays(form, leave.EmployeeId, usedDays); } else { commandInsertLeave.Parameters.Add("@Status_name", SqlDbType.VarChar).Value = leave.LeaveStatus; } } commandInsertLeave.Parameters.Add("@Leave_ID", SqlDbType.Int).Value = newLeaveId; commandInsertLeave.Parameters.Add("@Employee_ID", SqlDbType.Int).Value = leave.EmployeeId; commandInsertLeave.Parameters.Add("@Leave_type_name", SqlDbType.VarChar).Value = leave.LeaveType; commandInsertLeave.Parameters.Add("@First_day", SqlDbType.Date).Value = leave.FirstDay; commandInsertLeave.Parameters.Add("@Last_day", SqlDbType.Date).Value = leave.LastDay; commandInsertLeave.Parameters.Add("@Remarks", SqlDbType.VarChar).Value = leave.Remarks; commandInsertLeave.Parameters.Add("@Used_days", SqlDbType.Int).Value = usedDays; commandInsertLeave.ExecuteNonQuery(); } catch (Exception e) { //Jeżeli transakcja formularza była uruchomiona tylko na potrzeby tej metody, to ją cofamy. if (!isFormTransactionOn) form.RollbackTransaction(); //Wyrzucamy wyjątek do dalszej obsługi. throw e; } //Jeżeli operacja powiodła się, a transakcja była uruchomiona tylko na potrzeby tej metody to ją zatwierdzamy. if (!isFormTransactionOn) form.CommitTransaction(); }