Introduction
This is a web application by which any organization can manage tasks among its employees. This project has various small parts like commenting on task, upload and download files, task forwarding, editing existing and creating new project, task, employee, user and clients etc and crystal reports.
This is a full project. In this project I use C#, SQL Server and various components of ASP.NET. Reader of this article may find this article helpful while using this components.I would like share this whole project with every body with code and descriptions.
Project Description:
1. Every project has some number of tasks and employees. All tasks under a project can only be handled by these employees.
2. A task is assigned to only one employee at a time. Task can be forwarded to other employee of that project.
3. An employee can comment on his task, attach file with task, forward the task to other employee of its project and also can download attachment of his task.
4. There are two types of employee, named Admin and User. Both of the type must be an employee.
5. A user can only comment on his task, attach file with task, forward the task to other employee of its project and also can download attachment of his task.
6. An Admin user has some extra privilege including all privilege of a user.
- Admin can create project, edit project information, add / remove employee to a project and can close a project.
- Admin can create task, edit task information and close task.
- Admin can create employee, edit employee information.
- Admin can set user type.
- Admin can view project, task , task history, employee reports(Crystal Report)
**While creating a project Admin will be a member of the project by default.
**A project can only be closed if its entire tasks are close.
7. All types of user must log in by user ID and password. According to their type there will be different privilege, as discus earlier.
Using the code
1. Attach the database in your "SQL Server Management Studio Express".
2. Run the application on Microsoft Visual Studio as web site.
3. Locate the database for Crystal Reports.
4. Read "How to.txt" & "Readme.txt"
Project Detail
3 Layer architecture
In this project I use three layer architecture. UI layer collaborate with BLL layer, BLL layer collaborate with DAL layer. I use 3 layer architecture because it gives flexibility. After some time if any change is needed in particular layer I would only change in that layer. That time i will not bother for other layer. Suppose I want to change some business logic I will only consantrat on the business logic layer (BLL). That time i dont need to think about the entire project rather a particular layer. 3 layer architecture also gives more OOP sence in the project.
Log In & Home page
Every user must login by his user name and password. After clicking on Log in button codes behind the page will call a method of UserManager class,CheckUserIdAndPassword(userID,password), which takes user ID and password as parameter check it with database if any match found returns user type. If no match found this method will return empty string and which conclude as wrong password. Code also add a session variable which is user id.
Code behind log in page.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
public partial class UI_LogInUI : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Session.Abandon();
LoadUserId();
}
}
protected void logInButton_Click(object sender, EventArgs e)
{
string userType = null;
try
{
UserManager userManagerObject = new UserManager();
userType = userManagerObject.CheckUserIdAndPassword(employeeIdDropDownList.SelectedItem.Value, passwordTextBox.Text);
}
catch (SqlException sqlExceptionObj)
{
Label4.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
Label4.Text = exceptionObj.Message;
}
switch (userType)
{
case "Admin":
Session["userID"] = employeeIdDropDownList.SelectedItem.Value;
Response.Redirect("AdimHomePage.aspx");
break;
case "Normal":
Session["userID"] = employeeIdDropDownList.SelectedItem.Value;
Response.Redirect("NormalUserUIPage.aspx");
break;
default:
Label4.Text = " Invalid Password! Please retype the Password";
break;
}
}
private void LoadUserId()
{
try
{
UserManager userManagerObject = new UserManager();
employeeIdDropDownList.DataSource = userManagerObject.GetUserTable();
employeeIdDropDownList.DataTextField = "user_Employee_Id";
employeeIdDropDownList.DataValueField = "user_Employee_Id";
employeeIdDropDownList.DataBind();
}
catch (SqlException sqlExceptionObj)
{
Label4.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
Label4.Text = exceptionObj.Message;
}
}
}
After log in Admin user and user will see different type of home page according to there user type.
Admin home page :
I used two different Master page for two different user type. Admin master page has a manu which provides administrative privilege.
User home page:
Both Master page retrieve the user id from session variable and populate users task and project list.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class UI_MasterPage : System.Web.UI.MasterPage
{
string employeeId = null;
string employeeName = null;
protected void Page_Load(object sender, EventArgs e)
{
try
{
employeeId = Session["userID"].ToString();
employeeName = GetEmployeeName();
userNameLabel.Text = "Admin user : " + employeeName;
Session["userName"] = employeeName;
}
catch (NullReferenceException nullReferenceExceptionObject)
{
userNameLabel.Text = "Cant find User Id. Session time may out. "+nullReferenceExceptionObject.Message;
mainContentPlaceHolder.Visible = false;
menuMain.Visible = false;
homeHyperLink.Visible = false;
}
}
private string GetEmployeeName()
{
EmployeeManager employeeManagerObject = new EmployeeManager();
Employee employeeObject= employeeManagerObject.SelectEmployee(employeeId);
return employeeObject.Name;
}
}
User home page contains two Bulleted Lists. One lists all projects, other lists all open tasks. Project bulleted list’s display mode is “Text” and task bulleted list’s display mode is “Link button”.
I use the task ID as the value of the items in the bulleted list to find out which task is selected. As bulleted list contains List Items and bulleted list don’t provides selected items value directly, to find the value of bulleted list item (task) is clicked, I use a tricky solution. I use the “BulletedListEventArgs e” which provides data for the System.Web.UI.WebControls.BulletedList.Click event of a System.Web.UI.WebControls.BulletedList control. I save the item that fires the event in a list item variable and get value from it.
protected void tasksOfUserBulletedList_Click(object sender, BulletedListEventArgs e)
{
ListItem listItemObj = tasksOfUserBulletedList.Items[e.Index];
taskId = listItemObj.Value;
Session["taskID"] = taskId;
Response.Redirect("AdminViewTaskUIPage.aspx");
}
Task
If a user clicks a task, page is redirect to another page, where he will be able to see task detail, comments, and attachments with this task. He can comment on the task, attach files, and download files attached with the task. If user wants to forward the task to any other employee he can also forward the task.
This is the main business part of this project.
Commenting
User can comment on this task. This comment can be use as a note or as an instruction.
Notice that comment is saved with the task.
Upload File
User can also attach file with the task
Notice that file is attached with the task and listed in the right hand side of the picture. Also notice that user insert a comment with this attachment, this will tell who attach the file and what does the attachment do.
Code behind posting a comment and upload a file (attachment).
protected void postCommentButton_Click(object sender, EventArgs e)
{
if (DataValidator.IsEmpty(commentTextBox.Text))
{
errorLabel.Text = "No comment to post";
return;
}
SaveComment();
commentTextBox.Text = "";
}
private void SaveComment()
{
try
{
Comment commentObj = new Comment();
if (attachmentFileUpload.PostedFile.FileName != "")
{
UploadAttachment();
string fileName = attachmentFileUpload.FileName;
string fileDestinationPath = @"Attached files\" + fileName;
commentObj.CommentAttachment = fileDestinationPath;
}
commentObj.CommentTaskId = taskObj.Id;
commentObj.CommentEmployeeName = taskObj.Employee_AssignTo;
commentObj.CommentEmployeeId = taskObj.Employee_Id;
commentObj.CommentDate = System.DateTime.Now;
commentObj.Comments = commentTextBox.Text;
CommentManager commentManagerObject = new CommentManager();
commentManagerObject.SaveComment(commentObj);
LoadAllComments();
}
catch (PrimaryKeyException primaryKeyExceptionObj)
{
errorLabel.Text = primaryKeyExceptionObj.Message;
}
catch (SqlException sqlExceptionObj)
{
errorLabel.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
errorLabel.Text = exceptionObj.Message;
}
}
private void UploadAttachment()
{
try
{
string fileSourcePath = attachmentFileUpload.PostedFile.FileName;
string fileName = attachmentFileUpload.FileName;
string fileDestinationPath = Server.MapPath("~/");
fileDestinationPath = fileDestinationPath + @"Attached files\" + fileName;
WebClient webClientObj = new WebClient();
webClientObj.UploadFile(fileDestinationPath, fileSourcePath);
}
catch (SqlException sqlExceptionObj)
{
errorLabel.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
errorLabel.Text = exceptionObj.Message;
}
}
Download File
A user can download a attachment of the task by clicking on the file in the attachment Bulleted list. This will open a download window. User can save file in his hard disk or open directly. Remember that if user's pc has any "Download Accelerator" installed, it will force to download the .aspx page not the file. So disable "Download Accelerator" (if any) before trying to download any attachment.
Download window.
Selecting location where to download the file
Download complete.
Code behind download a file (attachment).
protected void attachmentBulletedList_Click(object sender, BulletedListEventArgs e)
{
try
{
ListItem listItemObj = attachmentBulletedList.Items[e.Index];
string sourcePath = listItemObj.Value;
Response.AddHeader("Content-Disposition", "attachment;filename=\"" + listItemObj.Text + "\"");
Response.ContentType = "application/octet-stream";
Response.WriteFile(listItemObj.Value);
}
catch (SqlException sqlExceptionObj)
{
errorLabel.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
errorLabel.Text = exceptionObj.Message;
}
}
Forwarding a task
A user can also forward a task to other employees of the project. To forward a task user have to check on the "Forward to check box". While checked a DDL and a new button will appear with text on it "Post & Forward" and "post comment" button will disappear. DLL contains all employees of the project. If user unchecked the "Forward to check box", "Post & Forward" and DDL will disappear and "post comment" button will reappear.
Notice that user is forwarding the task to another employee of the project named "Habibur Rahman". A task can only be forwarded to employees of the same project. Before forward a user must comment on the task telling what to do next or task status. It is also possible to attach a file during forwarding.
After forwarding a task the user is no longer handling the task. So the task will removed from the task list of his home page.
When the new user of the task "Habibur Rahman" log in, he will see the task in his task list.
Notice that user name is different.
The new user can now work on the task.
Code behind forward the task to other employee of the project.
protected void postAndForwardButton_Click(object sender, EventArgs e)
{
if (DataValidator.IsEmpty(commentTextBox.Text))
{
errorLabel.Text = "Please enter forwarding comment";
return;
}
else if (employeeNameDropDownList.SelectedIndex.Equals(0))
{
errorLabel.Text = "Please select an employee";
return;
}
SaveComment();
ForwardTask();
commentTextBox.Text = "";
Response.Redirect("AdimHomePage.aspx");
}
private void ForwardTask()
{
try
{
TaskManager taskManagerObj = new TaskManager();
Task taskObject = new Task();
taskObject.Id = taskIdTextBox.Text;
taskObject.Employee_Id = employeeNameDropDownList.SelectedItem.Value;
taskObject.Employee_AssignTo = employeeNameDropDownList.SelectedItem.Text;
taskObject.Employee_AssigenBy = taskObj.Employee_Id;
taskObject.Project_Id = projectIdTextBox.Text;
taskObject.StartDate = System.DateTime.Now;
string forwardStatus = taskManagerObj.ForwardATask(taskObject);
}
catch (SqlException sqlExceptionObj)
{
errorLabel.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
errorLabel.Text = exceptionObj.Message;
}
}
Closing Task
An admin can close any task that is assigned to him. Admin can not close a task that is not assigned to him because any other employee may be working on the task.
In admin task page, there is a link button for closing the task. If admin want to close the task, he must click on the link button and following page will appear.
After clicking on "Close Task" button, page will redirect to home page and a label appear with task close status.
Code behind closeing a task
protected void closeTaskButton_Click(object sender, EventArgs e)
{
try
{
TaskManager taskManagerObject = new TaskManager();
taskObj = taskManagerObject.SelectTask(taskId);
taskObj.TaskStatus = "Close";
message = taskManagerObject.CloseTask(taskObj);
SaveClosingComment();
Response.Redirect("AdimHomePage.aspx?" + "&message=" + Server.UrlEncode(message));
}
catch (SqlException sqlExceptionObj)
{
errorLabel.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
errorLabel.Text = exceptionObj.Message;
}
}
private void SaveClosingComment()
{
try
{
Comment commentObj = new Comment();
commentObj.CommentTaskId = taskObj.Id;
commentObj.CommentEmployeeName = taskObj.Employee_AssignTo;
commentObj.CommentEmployeeId = taskObj.Employee_Id;
commentObj.CommentDate = System.DateTime.Now;
commentObj.Comments = "This task is colsed by admin :" + taskObj.Employee_AssignTo;
CommentManager commentManagerObject = new CommentManager();
commentManagerObject.SaveComment(commentObj);
}
catch (PrimaryKeyException primaryKeyExceptionObj)
{
errorLabel.Text = primaryKeyExceptionObj.Message;
}
catch (SqlException sqlExceptionObj)
{
errorLabel.Text = sqlExceptionObj.Message;
}
catch (Exception exceptionObj)
{
errorLabel.Text = exceptionObj.Message;
}
}
All Task (View Only)
An admin can view all tasks (assigned + non-assigned)
Notice the last comment. It is added automatically during closing the task.
Crystal Reports
This project has five crystal reports and five .aspx page to view it. To view a crystal report in a .aspx page one must use a “CrystalReportViewer” in the .aspx page. In this project every page contain a “CrystalReportViewer” which load the crystal report (.rpt) page.
Crystal reports are
ReportEmployee.rpt --> view all user information
ReportProject.rpt --> view all project information
ReportTask.rpt --> view all task information
TaskHistory.rpt --> view all task history
TasksOfProject.rpt --> view all projects and its tasks
Task & Project Report
To view all projects and its tasks click on View Reports --> Tasks And Projects.
This report shows all projects and its tasks, individual task status (open / close), project status.
Task History Report
To view individual task history View Reports --> Task History
This report shows individual task history. User can understand who created the task, who forward a task to whom and when.
User Report
To view all user details View Reports --> User. This report shows employee ID, Name, Address, Email ID, Phone number, user type ans number of users.
Project Report
This report view all project information amd status
Task Report
This report views all task informations and status
In every .aspx page code behind page is
protected void Page_Load(object sender, EventArgs e)
{
string reportSourcePath = Server.MapPath("~/") + @"Reports\ReportProject.rpt";
projectCrystalReportViewer.ReportSource = reportSourcePath;
}
Notice that Server.MapPath("~/") finds the virtual path and ReportProject.rpt is the crytal report.
Exceptions
1. Exception
2. SqlException
3. NullReferenceExceptio
4. NonUserEmployeeException
5. OnlyOneAdminException
6. PrimaryKeyException
These are the exceptions I use in this project.
PrimaryKeyException
User define exception.
Exception occurs when trying to insert data into DB with existing primary key
OnlyOneAdminException
User define exception
While trying to change a admin's user type(Admin user to normal user) if admin is only admin user of a project, his user type can not be change because only admin can close task and project if OnlyOneAdmin become normal type then nobody can close task and project at this point this exception occurs.
NonUserEmployeeException
User defined exception
When trying to get a user type(Admin / Normal) of a employee if employee is not a user this exception occurs.
Note:Not all employee is a user.
NullReferenceException
Predefined Exception
SqlException
Predefined Exception
Exception
Predefined Exception