SetFocus Portfolio

18
Donald Woodhouse's Portfolio of work in the SetFocus LLC .NET Master's Program Donald Woodhouse 507 S Clayton St., Unit 2B Wilmington, DE 19805 (302)691-8285 [email protected]

description

 

Transcript of SetFocus Portfolio

Page 1: SetFocus Portfolio

Donald Woodhouse's Portfolioof work in the SetFocus LLC

.NET Master's Program

Donald Woodhouse507 S Clayton St., Unit 2B

Wilmington, DE 19805(302)691-8285

[email protected]

Page 2: SetFocus Portfolio

At SetFocus, we each individually wrote an entire application to interact with a Library database which was given to us. We wrote first the Windows interface (with school generated database interaction in hidden DLL's). Then we wrote all the database interaction in SQL stored procedures and ADO.NET code. Then we replaced in its entirety the Windows interface with an ASP.NET website interface.

Here is my Windows interface. Choosing Display Member from the Member Services menu gives the following screen, on which member 4004 has been chosen and View Member has been pressed. This is a juvenile member, with the associated adult 4003 shown as Adult Member Id. He has four items checked out, as shown. The birth date and adult member id are retrieved from the juvenile record. The address information comes indirectly from the associated adult member, but this is invisible from this level of code. The SQL stored procedure associates the information.

Page 3: SetFocus Portfolio

The code for the View Member Button follows. bl stands for Business Layer and is the entity which intermediates to connect to the data access code in the Data Access tier.

private void viewMemberButton_Click(object sender, EventArgs e) { try { if (Int16.TryParse(memberIdTextBox.Text, out memberId)) { myMember = bl.GetInformation(memberId);

if (myMember == null) { MessageBox.Show("Not a member"); firstNameLabel.Text = "First Name"; middleInitialLabel.Text = "Middle Initial"; lastNameLabel.Text = "Last Name"; streetLabel.Text = "Street"; cityLabel.Text = "City"; stateLabel.Text = "State"; zipCodeLabel.Text = "Zip Code"; phoneNumberLabel.Text = "Phone Number"; expirationDateLabel.Text = "Expiration Date"; } else { firstNameLabel.Text = "First Name " + myMember.FirstName; middleInitialLabel.Text = "Middle Initial " + myMember.MiddleInitial; lastNameLabel.Text = "Last Name " + myMember.LastName; streetLabel.Text = "Street " + myMember.Street; cityLabel.Text = "City " + myMember.City; stateLabel.Text = "State " + myMember.State; zipCodeLabel.Text = "Zip Code " + myMember.ZipCode; phoneNumberLabel.Text = "Phone Number " + myMember.PhoneNumber; expirationDateLabel.Text = "Expiration Date " + myMember.ExpirationDate.ToShortDateString();

if (myMember is DW.LibraryEntities.JuvenileMember) { DW.LibraryEntities.JuvenileMember jm = (DW.LibraryEntities.JuvenileMember)myMember; adultMemberIDLabel.Text = "Adult Member Id " + jm.AdultMemberID; birthDateLabel.Text = "Birth Date " + jm.BirthDate.ToShortDateString(); } else { adultMemberIDLabel.Text = ""; birthDateLabel.Text = ""; }

if (myMember.ExpirationDate < DateTime.Today) { expiredLabel.Visible = true; this.statusLabel.Text = "Membership is expired - member cannot check out books"; this.checkOutButton.Enabled = false; }

Page 4: SetFocus Portfolio

else { expiredLabel.Visible = false; }

DW.LibraryEntities.ItemsDataSet.ItemsDataTable items = bl.GetItems(memberId); itemsBindingSource.DataSource = items; if (items.Count > 3) { this.statusLabel.Text = "Member has reached the maximum # of books checked out"; this.checkOutButton.Enabled = false; } else { this.statusLabel.Text = ""; this.checkOutButton.Enabled = true; } } } else { MessageBox.Show("Invalid Member ID"); firstNameLabel.Text = "First Name"; middleInitialLabel.Text = "Middle Initial"; lastNameLabel.Text = "Last Name"; streetLabel.Text = "Street"; cityLabel.Text = "City"; stateLabel.Text = "State"; zipCodeLabel.Text = "Zip Code"; phoneNumberLabel.Text = "Phone Number"; expirationDateLabel.Text = "Expiration Date"; } } catch (Exception exc) { MessageBox.Show(exc.Message); } }

Since the member was tested to be a juvenile member, the adult member id and birth date were retrieved.

Page 5: SetFocus Portfolio

The add member services, Add Adult and Add Juvenile, are also on the Member Services menu. Add Adult gives the following screen on which I have added myself as a member. The OK button is grayed as it has already been clicked and the record added to the database.

Sample validation code follows, using regular expression:

private void lastNameTextBox_Validating(object sender, CancelEventArgs e) { //Regex regex = new Regex("^[A-Z][a-z, A-Z]*$"); //if (!(regex.IsMatch(lastNameTextBox.Text) && lastNameTextBox.Text.Length <= 15)) if (!(Regex.IsMatch(lastNameTextBox.Text, "^[A-Z][a-z]{0,14}$") && lastNameTextBox.Text.Length <= 15)) { e.Cancel = true; errorProvider1.SetError(lastNameTextBox, "Must be 1-15 letters, first letter capital"); } else errorProvider1.SetError(lastNameTextBox, null); }

The code for the OK button is this: private void okButton_Click(object sender, EventArgs e) { foreach (Control c in this.Controls) {

Page 6: SetFocus Portfolio

if (c is TextBox) { if ((errorProvider1.GetError(c) != null) && (errorProvider1.GetError(c) != "")) { c.Focus(); statusLabel.Text = "Please fix all errors"; return; } } }

DW.LibraryEntities. AdultMember myMember = new DW.LibraryEntities.AdultMember();

myMember.FirstName = this.FirstName; myMember.MiddleInitial = this.MiddleInitial; myMember.LastName = this.LastName; myMember.Street = this.Street; myMember.City = this.City; myMember.State = this.State; myMember.ZipCode = this.ZipCode; myMember.PhoneNumber = this.PhoneNumber;

try { bl.AddMember(myMember); this.statusLabel.Text = "Successfully added Member Id: " + myMember.MemberID; this.okButton.Enabled = false; } catch (LibraryException le) { this.statusLabel.Text = le.Message; }

} }

Page 7: SetFocus Portfolio

This is a sample of my ADO.NET code (to retrieve a member record):

public Member GetMember(short memberId) { Member myMember; AdultMember myAdultMember = new AdultMember(); JuvenileMember myJuvenileMember = new JuvenileMember(); using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.libraryConnectionString)) { using (SqlCommand cmd = new SqlCommand("GetMember", connection)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@member_no", memberId); SqlParameter adultOrJuvenile = new SqlParameter("@adult_or_juvenile", SqlDbType.Int); adultOrJuvenile.Direction = ParameterDirection.Output; cmd.Parameters.Add(adultOrJuvenile); try { connection.Open(); } catch { throw new LibraryException("Failed to open connection to library database."); } try {

using (SqlDataReader reader = cmd.ExecuteReader()) { reader.Read(); myJuvenileMember.FirstName = reader["firstname"].ToString(); if(!(reader.IsDBNull(2))) myJuvenileMember.MiddleInitial = reader["middleinitial"].ToString(); myJuvenileMember.LastName = reader["lastname"].ToString(); myJuvenileMember.Street = reader["street"].ToString(); myJuvenileMember.City = reader["city"].ToString(); myJuvenileMember.State = reader["state"].ToString(); myJuvenileMember.ZipCode = reader["zip"].ToString(); if(!(reader.IsDBNull(8))) myJuvenileMember.PhoneNumber = reader["phone_no"].ToString(); myJuvenileMember.ExpirationDate = (DateTime)reader["expr_date"]; myJuvenileMember.AdultMemberID = (short)reader["adult_member_no"]; myJuvenileMember.BirthDate = (DateTime)reader["birth_date"];

myMember = myJuvenileMember;

} if((int)(cmd.Parameters["@adult_or_juvenile"].Value) == 0) { myAdultMember.FirstName = myJuvenileMember.FirstName; myAdultMember.MiddleInitial = myJuvenileMember.MiddleInitial; myAdultMember.LastName = myJuvenileMember.LastName; myAdultMember.Street = myJuvenileMember.Street; myAdultMember.City = myJuvenileMember.City;

Page 8: SetFocus Portfolio

myAdultMember.State = myJuvenileMember.State; myAdultMember.ZipCode = myJuvenileMember.ZipCode; myAdultMember.PhoneNumber = myJuvenileMember.PhoneNumber; myAdultMember.ExpirationDate = myJuvenileMember.ExpirationDate;

myMember = myAdultMember; }

} catch(Exception ex) { throw new LibraryException(ex.Message); } } return myMember; } }

Page 9: SetFocus Portfolio

This is my SQL stored procedure which is used (GetMember). In all, I wrote 11 stored procedures for this project.

/****** Object: StoredProcedure [dbo].[GetMember] Script Date: 10/15/2008 00:15:50 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROC [dbo].[GetMember]

@member_no smallint = Null,@adult_or_juvenile int OUTPUT

ASIF @member_no IS NULL --No null member-no may be passed

BEGINRAISERROR('The member number may not be null.', 12, 1)RETURN

END

--If member is adultIF EXISTS (SELECT * FROM dbo.adult WHERE member_no = @member_no)BEGIN

SELECT lastname, firstname, middleinitial, street, city, state, zip, phone_no, expr_date,

adult_member_no = dbo.adult.member_no, birth_date = GETDATE()FROM dbo.member INNER JOIN dbo.adultON dbo.member.member_no = dbo.adult.member_noWHERE dbo.adult.member_no = @member_no

SET @adult_or_juvenile = 0 --Identifies adult memberEND

--If member is juvenileIF EXISTS (SELECT * FROM dbo.juvenile WHERE member_no = @member_no)BEGIN

SELECT lastname, firstname, middleinitial, street, city, state, zip, phone_no, expr_date, adult_member_no, birth_date

FROM dbo.member INNER JOIN dbo.juvenileON dbo.member.member_no = dbo.juvenile.member_noINNER JOIN dbo.adultON dbo.adult.member_no = dbo.juvenile.adult_member_noWHERE dbo.juvenile.member_no = @member_no

SET @adult_or_juvenile = 1 --Identifies juvenile memberEND

GO

Page 10: SetFocus Portfolio

In the website version, first you are presented with a login screen. You must be a member of the Librarian role to successfully log in to do work.

Page 11: SetFocus Portfolio

The View Member screen looks like this with member 4004 again selected:

Overdue items (only) are highlighted in red.

Page 12: SetFocus Portfolio

Check Out Item produces the following page. This is the display after the item has been checked out and Find is clicked again. It shows the item found checked out to the member. Best practice is to enter the ISBN and copy number and click Find to see if an item is checked out before trying to check it out to a member.

Page 13: SetFocus Portfolio

View Member will now produce this screen for Member 10001 (item not overdue and thus not in red):

An additional feature we added in this stage of the project was the Add Item feature, which adds a new copy of a given ISBN, first checking to see if it is a copy of the existing item, or an entirely new ISBN. For this the SQL proc follows:

/****** Object: StoredProcedure [dbo].[AddNewItem] Script Date: 10/15/2008 00:15:48 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO

CREATE PROC [dbo].[AddNewItem]@isbn int,@title varchar(63),@author varchar(31)

AS

DECLARE @title_no int

Page 14: SetFocus Portfolio

IF EXISTS (SELECT * from dbo.copy WHERE isbn = @isbn)BEGIN

RAISERROR('There is at least one copy of this isbn number in collection', 12, 1)RETURN

END

BEGIN TRANINSERT INTO dbo.title (title, author)

VALUES (@title, @author)SET @title_no = SCOPE_IDENTITY()IF @@ERROR <> 0BEGIN

RAISERROR('Failed to create title table entry', 12, 1)ROLLBACK TRANRETURN

ENDINSERT INTO dbo.item (isbn, title_no)

VALUES (@isbn, @title_no)IF @@ERROR <> 0BEGIN

RAISERROR('Failed to create item table entry', 12, 1)ROLLBACK TRANRETURN

ENDINSERT INTO dbo.copy (isbn, copy_no, title_no, on_loan)

VALUES(@isbn, 1, @title_no, 'N')IF @@ERROR <> 0BEGIN

RAISERROR('Failed to create copy table entry', 12, 1)ROLLBACK TRANRETURN

ENDCOMMIT TRANGO

Multiple database tables need to be updated for this, as entries in the title table, item table, and copy table need to be updated.