You are on page 1of 66

FREELANCE MANAGEMENT SYSTEM

PROJECT REPORT
Submitted
By
DIONISIO CHAVITO MASSANGA
Roll No. S19/29

In Partial Fulfillment of the Requirements


for the Award of the Degree of

BACHELOR OF SCIENCE IN APPLIED INFORMATION


TECHNOLOGY (BScAIT)

Under the guidance


of
Mr. SAMEER JHA

FACULTY OF INFORMATION AND COMMUNICATION TECHNOLOGY

INTERNATIONAL BUSINESS SCIENCE AND TECHNOLOGY UNIVERSITY


Plot 11A, Rotary Avenue, Lugogo Bypass, Kololo, Kampala, Uganda
Tel: +256 414 237 524/5/6 Email: info@isbatuniversity

SPRING 2022
FACULTY OF INFORMATION AND COMMUNICATION TECHNOLOGY
INTERNATIONAL BUSINESS, SCIENCE AND TECHNOLOGY UNIVERSITY

BONAFIDE CERTIFICATE
I certify that this project report entitled FREELANCE MANAGEMENT
SYSTEM is bonafide work of Mr/Ms. Student Name who carried out the
project work under my supervision.
Certified that the Project Entitled “FREELANCE MANAGEMENT
SYSTEM” carried out by “DIONISIO CHAVITO MASSANGA”, bearing
Roll No. “STUDENT ROLL No.S19/29” and is a bonafide student of
INTERNATIONAL BUSINESS, SCIENCE AND TECHNOLOGY
UNIVERSITY (ISBAT), is in partial fulfillment for the award of BACHELOR
OF SCIENCE IN APPLIED INFORMATION TECHNOLOGY (BScAIT) the
during Spring-2020. It is certified that all the corrections/suggestions indicated
for Internal Assessment have been incorporated in the submitted report. The
Project report has been approved as it satisfies the academic requirements in
respect of the project work prescribed for the said Degree.

DEAN, FICT SUPERVISOR

………………………………. ……………………………..

(Signature with date) (Signature with date)

External Examiner:

Name: Signature:

1|Page
ACKNOWLEDGEMENT

The satisfaction and the euphoria that accompany the successful completion of any task
would be incomplete without the mention of the people who made it possible. The constant
guidance of these persons and encouragement provide, crowned our efforts with success and
glory. Although it is not possible to thank all the members who helped for the completion of
the project individually, I take this opportunity to express my gratitude to one and all.

I am grateful to management and our university INTERNATIONAL BUSINESS, SCIENCE


AND TECHNOLOGY UNIVERSITY with its very ideals and inspiration for having
provided me with the facilities, which made this, project a success.

I wish to place on record, my grateful thanks to our honourable Vice-Chancellor, COL. DR.
K M Mathew for the constant encouragement provided to me.

I am greatly indebted to the following for their contribution to my work:


The Almighty God, who gave me the insight and perseverance to accomplish this work.
My supervisor, Mr. Nasser who’s sounding advice helped me steer this project in the right
direction, a work I will forever cherish.
I express my sincere gratitude to, Emmanuel Odonkara, who’s in-depth knowledge in
advanced Web Technologies such as Freelance Management System, was a great asset to my
project.
Last but clearly not the least, my classmates who’s technical and moral support throughout
my project was of great help.

DIONISIO CHAVITO MASSANGA,

S19/29

2|Page
FREELANCE MANAGEMENT SYSTEM

3|Page
ABSTRACT
Freelance job is where you’re a temporary contract worker, rather than a permanent
employee. Depending on your level of expertise, it could be possible to work part-time
hours, but make full-time pay. Having control over your work load, the clients you work
with, and your income is a big benefit of freelancing. Freelancing is doing a job under
contract rather than full employment. Usually, people who freelance are self-employed and
for whom they will work and they decide for how long. Freelancing offers the lot of freedom
and flexibility which regular jobs cannot. The freelancer can choose the type of the work,
time of the day can work and how long they work, a location they work and volume of work
take on. The freelancer can control work relationship and control work load. Platform
freelancing has many websites and anyone can register as freelancers or job posters. There is
a discussion forum to build up friendly environment between freelancers and clients. All
they can work without any language issue. For these solutions, the system is designed
according to four sub modules such as user validation module, file sharing module and
manage profile. Users of the system are Job poster, Freelancer (Jobseeker). Inputs of the
system are Details of the Job poster, Freelancer, Job, gig. Outputs of the system are Overall
rating. Processes of the system are collected data, analyze data and job posting, creating
gigs, discussion and complete the job. It is distributed among 20 selected users and collects
their feedback. Keywords - Freelancing, Freelancer.

4|Page
Table of Contents
1.3 Objectives....................................................................................................................................8
1.4 Scope...........................................................................................................................................8
1.6 Company Profile..........................................................................................................................9
SYSTEM ANALYSIS.........................................................................................................................11
2.1 Existing System.........................................................................................................................11
2.2 Proposed System........................................................................................................................11
2.3 Feasibility Study............................................................................................................................11
2.3.1 Technically Feasible...............................................................................................................12
2.3.2 Economically Feasible............................................................................................................12
2.4 Development Requirements.......................................................................................................12
2.6 Back-end Tool...........................................................................................................................13
2.8 Other Tools................................................................................................................................14
2.8.1 Hardware Requirements.........................................................................................................15
CHAPTER 3........................................................................................................................................16
SYSTEM DESIGN..............................................................................................................................16
3.1.2 Use Case.................................................................................................................................17
3.1.3 Data Flow Diagram (3 levels).................................................................................................18
.............................................................................................................................................................21
3.2 Database Design............................................................................................................................22
3.2.1 E-R Diagram...........................................................................................................................22
CHAPTER 4........................................................................................................................................24
System Development...........................................................................................................................24
4 Screan Shoots...............................................................................................................................24
4.1 Coding.......................................................................................................................................25
4.2 TESTING..................................................................................................................................63
CHAPTER 5........................................................................................................................................64
Conclusion...........................................................................................................................................64
5 Summary......................................................................................................................................64
5.1 Future work...............................................................................................................................64

5|Page
CHAPTER 1
INTRODUCTION
1.1 Project Overview
A freelancer is a self-employed person who offers services to clients. These services often,
though not necessarily, are offered to businesses through the proliferation of sharing
economy platforms like Task Rabbit, Mechanical Turk, or Up work. However, individuals
can offer their services directly to clients, without third-party resources that often take a cut
of the pay. Freelancing is flexible. You can often work full- or part-time on projects of your
choice, at the hours that are convenient for you. Although clients can (and usually will) set
specifications for the work they want to be done, a freelancer is still an independent
contractor, not an employee. You'd be free to control how the work is completed. However,
if your clients don't like the final product, you might find yourself out of a gig. Freelancing
allows you to set your own price for your services, which is often higher than what you'd
make as an employee doing the same work. Make sure you charge enough to cover your
overhead and to compensate you fairly for the time it will take you to do the work. You'll
probably want to take on any client who will hire you when you're starting out, but you also
have the option to not take on difficult clients, especially as you grow. You can even tell
clients you no longer wish to work for them.
Nearly every type of service needed by a business can be provided by a freelancer. Some of
the most common freelance opportunities include:
• Project Management
• Web Design/Development
• Software developer
• Writing / Editing
• Graphic Design

1.2 Name
This project has been titled Freelance Management System (FMS) as the
application names.

1.3 Objectives

Depending on what services you provide you may set goals based on outcomes. For example,
if you are a freelancer who typically works with non-profit organizations you may notice that
they aren’t as concerned about revenue as they are about making a difference. Typically, they
set goals around a specific type of outcome.

A good example of this would be if you were working with an animal shelter on improving
their social media. They may want to decrease the length of time it takes for their dogs to be
adopted by sharing more stories and pictures of Facebook. Now in order to see if they are

6|Page
achieving this goal you could track how long the average dog stays in the shelter compared
against the length of stay before increased efforts on social media.

1.4 Scope
Modules:
The system after careful analysis has been identified to be presented with the following
modules:

Main Modules:
1. Admin
2. Client
3. Freelancer

Sub Modules:
1. Registration
2. Login
3. Admin_home
Admin Module:
Administrator can edit, add, delete and update any sub modules. He can keep track of
all the information in the corresponding modules. The Admin Module includes five sub
modules. They are
1. Login
2. Freelancer
3. 3. Client
.4 Project
5. logout

Login:
Administrator have login used to login to see the information.
Freelancer Module:
Administrator can add new user and delete any existing employee if necessary.

Client Module
Administrator can add new Client and delete any existing employee if necessary.

Project:
Administrator can add new Project List and delete any existing employee if necessary2.
Requirements Specification:

Logout:
Logout is exit from your Admin account.

7|Page
1.6 Company Profile
Our presence within the proficiency service as key selection markers, as an employee in
public and private sectors, also we have experience working with professional top 4 audit
firms as part of profit service and top management. This has earned a reputation for quality,
proficiency, reliability and a tailored approach to providing our services.

We provide external audit/internal auditors, accounting and financial statements preparation,


Management and financial consultancies, systemizations and mobilizations, company
formations and project feasibility, courts financial and tax experts, liquidation and
reformation, hospitality and leisure, trade mark and patent registrations, official receivers and
payers courts custodians, due diligence and due care, feasibility studies services. MPA is
committed to provide the clients with an independent assessment of their operations and
organizational structures. MPA is founded on international standards blended with
international reconcile. We have done pro bono work for many organizations including
charitable organizations. We take time to get to know our clients and understand how they
measure success and we are dedicated to a hand on approach that is proven to build trusting
relationships, and prosperity key partner in the firm.

8|Page
CHAPTER 2

SYSTEM ANALYSIS
2.1 Existing System
The existing system is a semi-automated at where the information is stored in the form of
excel sheets in disk drives. The information sharing to the Volunteers, Group members, etc.
is through mailing feature only. The information storage and maintenance is more critical in
this system. Tracking the member‘s activities and progress of the work is a tedious job here.
This system cannot provide the information sharing by 24x7 days.

Disadvantages Of Existing System

• More manpower.
• Time consuming.
• Consumes large volume of pare work.
• Needs manual calculations.
• No direct role for the higher officials.
2.2 Proposed System
• The development of this new system objective is to provide the solution to the
problems of existing system. By using this new system, we can fully automate the
entire process of the current system. The new system would like to make as web
enabled so that the information can be shared between the members at any time using
the respective credentials. To track the status of an individual process, the status
update can be centralized using the new system. Being a web-enabled system, the
process can be accessed across the world over net.
• This system also providing the features like, Mailing between the members; updating
the process status in centralized location; generated reports can also be exporting to
the applications like MS-Excel, PDF format, etc. In this new system, the members
like Donors can give their valuable feedback to the Volunteers so that the Volunteers
can check their progress of the tasks.
• The entire process categorized as different modules like Admin module, Volunteer
module, etc. at where we can classify the functionality as an individual process.

2.3 Feasibility Study


After identifying the scope of the project, the feasibility study is needed to be carried out. It is
basically keeping the following points in mind.

9|Page
2.3.1 Technically Feasible
This software is very much technically feasible. This software is very much concerned with
specifying equipment and the software will successfully satisfy almost all the admin’s
requirements. The technical need for this system may vary considerably but might include:

a. The facility to produce output in a given time.

b. Response time under certain conditions.

c. Ability to process data at a particular speed.

Therefore, the basic input/output of data is identified. So, the project can easily be built up
and it will also be technically feasible.

2.3.2 Economically Feasible


The project is very much financially feasible. The implementation and development cost of
this software under the reach of any college.

Moreover, it requires some training for the use. So, training cost can be neglected and the
resources of this software are very much available. It also reduces the labour and extra cost to
be paid for labour. So indeed, it is financial feasible.

2.4 Development Requirements


The hardware and software specification specifies the minimum hardware and software
required to run the project. The hardware configuration specified below is not by any means
the optimal hardware requirements. The software specification given below is just the
minimum requirements, and the performance of the system may be slow on such system.

. 2.5 Software Requirement


Operating System: Windows
Back-End: Firebase
Front-End: Next.Js
Database: FireStore
Software: VScode

10 | P a g e
2.6 Back-end Tool

11 | P a g e
2.7 Front End Tool

2.8 Other Tools


Visual Studio Code is a lightweight but powerful source code editor which runs on your
desktop and is available for Windows, macOS and Linux. It comes with built-in support for
JavaScript, TypeScript and Node.js and has a rich ecosystem of extensions for other
languages.

12 | P a g e
2.8.1 Hardware Requirements
EMS should be able to work on a computer with the following minimum hardware
specifications:

OS: Windows XP/Vista/7/8 and Linux

CPU: Pentium III (700MHz) and above

Memory: 128 MB and above

Capacity: 4GB of hard drive

Others: Network interface card, mouse, keyboard, and monitor.

13 | P a g e
CHAPTER 3

SYSTEM DESIGN

14 | P a g e
3.1.2 Use Case

15 | P a g e
3.1.3 Data Flow Diagram (3 levels)

16 | P a g e
LEVEL 0

17 | P a g e
LEVEL 1

18 | P a g e
LEVEL 2

19 | P a g e
3.2 Database Design
3.2.1 E-R Diagram

3.2.2 Table Design with Constraints

20 | P a g e
21 | P a g e
CHAPTER 4
System Development
4 Screan Shoots

22 | P a g e
4.1 Coding
import React, { createContext, useEffect, useLayoutEffect } from 'react'

import { getAuth, sendPasswordResetEmail, sendEmailVerification, signInWithPopup,


signInWithEmailAndPassword, GoogleAuthProvider, signOut, RecaptchaVerifier, updateProfile,
signInWithPhoneNumber, onAuthStateChanged, createUserWithEmailAndPassword } from
"firebase/auth";

import { auth, db, firebaseFunctions } from '../firebase';

import { toast } from 'react-toastify'

import { message, notification } from 'antd'

import { httpsCallable } from "firebase/functions";

import axios from 'axios'

import { useState } from 'react';

import { useRouter } from 'next/router';

import { collection, deleteDoc, limit, increment, collectionGroup, getDocs, getDoc, doc, setDoc,
updateDoc, onSnapshot, serverTimestamp, query, where, addDoc, orderBy } from
'firebase/firestore';

export const GlobalContext = createContext()

export default function GlobalContextProvider({ children }) {

  const [isUpadating, setIsUpdating] = useState(false)

23 | P a g e
  const router = useRouter()

  const [user, setUser] = useState(null)

  const [jobDetails, setJobDetails] = useState(null)

  const [workInfo, setWorkInfo] = useState([])

  const [jobs, setJobs] = useState([])

  // Profile

  // Work

  const [workTitle, setWorkTitle] = useState("")

  const [workCompany, setWorkCompany] = useState("")

  const [workCity, setWorkCity] = useState("")

  const [workCountry, setWorkCountry] = useState("")

  const [workDate, setWorkDate] = useState(null)

  const [stopDate,setStopDate] =useState(null)

  const [workDescription, setWorkDescription] = useState("")

  // Education

  const [field, setField] = useState("")

  const [level, setLevel] = useState("")

  const [school, setSchool] = useState("")

  const [date, setDate] = useState(null)

  const [endDate,setEndDate] = useState(null)

  const [description, setDescription] = useState("")

  const [educationInfo, setEducationInfo] = useState([])

  // Profile

  const [about, setAbout] = useState("")

  const [userPic, setUserPic] = useState("")

  const [applicantsId, setApplicantsId] = useState([])

  const [confirmLoading, setConfirmLoading] = React.useState(false);

  const [openModal, setOpenModal] = useState(false)

  const [totalJobsCount, setTotalJobsCount] = useState(0)

24 | P a g e
  const [totalUsersCount, setTotalUsersCount] = useState(0)

  const [totalClients, setTotalClients] = useState(0)

  const [hires, setHires] = useState([])

  const [topFreelancers, setTopFreelancers] = useState([])

  const [jobInvites, setJobInvites] = useState([])

  const [active, setActive] = useState(0)

  const [username, setUsername] = useState(user === null ? '' : user.displayName)

  const [contact, setContact] = useState("")

  const [freelancerDetails, setFreelancerDetails] = useState(null)

  const [clientId, setClientId] = useState("")

  const [profileStatus, setProfileStatus] = useState(false)

  const [title, setTitle] = useState("")

  const [chatRooms, setChatRooms] = useState([])

  const [showUserModal, setShowUserModal] = useState(false)

  const [skills, setSkills] = useState([])

  const [skillsAdded, setSkillsAdded] = useState(false)

  const [experience, setExperience] = useState("")

  const [loading, setLoading] = useState(false)

  const [accountType, setAccountType] = useState("")

  const [authenticating, setAuthenticating] = useState(false)

  const [savedJobs, setSavedJobs] = useState([])

  const [myProposals, setMyProposals] = useState([])

  // const [showDismissModal,setShowDismissModal] = useState(false)

  const [dismissing, setDismissing] = useState(false);

  const [skillz, setSkillz] = useState(

  [

      'React Native',

      'Next.js',

      'React',

      'Java',

      'Python',

25 | P a g e
      'Julia',

      'Scala',

      'MATLAB',

      'Tensorflow',

      'Mathematics',

      'Statistical Analysis and computing',

      'Machine Learning',

      'Deep Learning ',

      'Data Visualization ',

      'Data Wrangling',

      'Programming',

      'Big Data',

      'Analytics and Modeling',

      'Communication',

      'Cloud Computing',

      'Microsoft Excel',

  ]

 )

  useEffect(() => {

    getChats()

    getTotalJobsPosted()

  }, [])

  useLayoutEffect(() => {

    isloggedIn()

  }, [user])

  const currentDate = new Date()

  const hours = currentDate.getHours();

26 | P a g e
  const minutes = currentDate.getMinutes();

  const seconds = currentDate.getSeconds();

  const timeString = hours + ":" + minutes

  const DayOfMonth = currentDate.getDate();

  const Month = currentDate.getMonth();

  const Year = currentDate.getFullYear();

  const dateString = (Month + 1) + "/" + DayOfMonth + "/" + Year;

  const now = dateString

  const isloggedIn = () => {

    onAuthStateChanged(auth, async (authuser) => {

      if (authuser) {

        // setUser(user)

        // const acc = localStorage.getItem('account')

        // if (acc === 'client') {

        //   setProfileStatus(true)

        // } else {

        //   const docRef = doc(db, 'Users', authuser.uid)

        //   const snapshot = await getDoc(query(docRef))

        //   if (snapshot.data()?.accountType === 'freelancer') {

        //     localStorage.setItem('account', 'freelancer')

        //     if (snapshot.data().profileCompleted === false) {

        //       setProfileStatus(false)

        //       router.push('/complete-profile')

        //     } else {

        //       setProfileStatus(true)

        //     }

        //   }

27 | P a g e
        // }

        authoriseUser(authuser)

        // setUser(authuser)

   }

    });

 }

  const loginWithGoogle = async () => {

    const provider = new GoogleAuthProvider();

    signInWithPopup(auth, provider)

      .then((result) => {

        // This gives you a Google Access Token. You can use it to access the Google API.

        //   const credential = GoogleAuthProvider.credentialFromResult(result);

        //   const token = credential.accessToken;

        // The signed-in user info.

        setUser(result.user)

        console.log("Google Data", result.user)

        if (result.user.emailVerified) {

          // router.push('/complete-profile')

          authoriseUser(result.user)

        } else {

          router.push('/verify-email')

    }

        // localStorage.setItem('@user', JSON.stringify(user))

28 | P a g e
        // ...

      }).catch((error) => {

        // Handle Errors here.

        // const errorCode = error.code;

        // const errorMessage = error.code;

        // The email of the user's account used.

        // const email = error.email;

        // The AuthCredential type that was used.

        // const credential = GoogleAuthProvider.credentialFromError(error);

        // ...

      });

 }

  const getTotalJobsPosted = async () => {

    onSnapshot(collectionGroup(db, 'Jobs'), snapshot => {

      let jobs = []

      snapshot.forEach(doc => {

        jobs.push(doc.data())

      })

      setTotalJobsCount(jobs.length)

    })

    onSnapshot(collection(db, 'Users'), snapshot => {

      let users = []

      snapshot.forEach(doc => {

        users.push(doc.data())

      })

      setTotalUsersCount(users.length)

    })

    onSnapshot(collection(db, 'Clients'), snapshot => {

      let clients = []

      snapshot.forEach(doc => {

29 | P a g e
        clients.push(doc.data())

      })

      setTotalClients(clients.length)

    })

    getTopFreelancers()

 }

  const sendVerificationLink = async () => {

    sendEmailVerification(auth.currentUser)

      .then(res => {

        const hide = message.loading('Redirecting to Login', 1200);

        // Dismiss manually and asynchronously

        toast.success("Verification Link has sent to your email.")

        setTimeout(hide, 9000);

        setTimeout(() => {

          logout()

        }, 9000)

      })

 }

  const getChats = async () => {

    onSnapshot(collection(db, 'ChatRooms'), snapshot => {

      let data = []

      snapshot.forEach(doc => {

        data.push(doc.data())

      })

      setChatRooms(data)

    })

 }

30 | P a g e
  const createChat = (chatName, freelancer, jobTitle, jobId, message) => {

    const docRef = doc(db, 'ChatRooms', freelancer?.userId)

    setDoc(docRef, {

      clientId: user?.uid,

      name: chatName,

      chatId: freelancer?.userId,

      clientEmail: user?.email,

      freelancerEmail: freelancer?.email,

      chatImage: user?.photoURL,

      freelancerId: freelancer.userId,

      freelancerName: freelancer.displayName,

      jobTitle: jobTitle,

      jobId: jobId,

      createdAt: serverTimestamp(),

    }).then(res => {

      // updateDoc(doc(db, 'ChatRooms', res.id), {

      //   chatId: res.id

      // })

      setDoc(doc(db, 'Clients', user?.uid, 'Jobs', jobId, 'Invites', freelancer?.userId), {

        inviteId: freelancer?.userId,

        freelancerId: freelancer?.userId,

        clientId: user?.uid,

        freelancerDetails: freelancer,

        chatId: freelancer?.userId,

        invitedOn: serverTimestamp()

      }).then(response => {

        sendMessage(freelancer?.userId, message)

      }).catch(error => {

        toast.error(error.code)

31 | P a g e
      })

    }).catch(error => {

      toast.error(error.code)

    })

 }

  const getJobInvites = async (jobId) => {

    if (user) {

      let data = []

      onSnapshot(collection(db, 'Clients', user.uid, 'Jobs', jobId, 'Invites'), snapshot => {

        snapshot.forEach(res => {

          data.push(res.data())

        })

      })

      setJobInvites(data)

      console.log("Invites", data)

  }

 }

  const getJobs = async () => {

    const ref = query(collectionGroup(db, 'Jobs'), orderBy('createdOn', 'desc'))

    onSnapshot(query(ref), snapshot => {

        let data = []

        snapshot.forEach(results => {

            data.push(results.data())

        })

        setJobs(data)

        console.log(data)

        // if (data.length === 0) {

32 | P a g e
        //     setLoad(true)

        //     setTimeout(() => {

        //         setLoad(false)

        //         setIsEmpty(true)

        //     }, 5000)

        // }

    })

  const sendMessage = (chatId, input) => {

    const collRef = collection(db, 'ChatRooms', chatId, 'Messages')

    addDoc(collRef, {

      message: input,

      name: user?.displayName,

      photoURL: user?.photoURL,

      clientEmail: user?.email,

      createdAt: serverTimestamp(),

    })

      .then(res => {

        router.push(`/messages?id=${chatId}`)

        toast.success("Your invite was sent successfully")

      })

      .catch(error => {

      })

 }

  const resetPassword = async (email) => {

    if (email) {

33 | P a g e
      sendPasswordResetEmail(auth, email)

        .then(() => {

          message.success("Reset link has been sent to your email")

        })

        .catch(error => {

          message.error(error.code)

        })

    } else {

      message.error("Enter email")

  }

 }

  const logout = () => {

    // localStorage.removeItem('@user')

    signOut(auth).then(res => {

      setUser(null)

      toast.success("You have logged out")

      localStorage.removeItem('account')

      router.push('/auth')

    })

 }

  const addJob = async (userId, jobTitle, description, currency, jobtype, price, estimate, duration,
skills, experience) => {

    updateDoc(doc(db, 'Clients', userId), {

      totalJobs: increment(1),

    })

    addDoc(collection(db, 'Clients', userId, 'Jobs'), {

      clientId: userId,

      clientEmail: user.email,

34 | P a g e
      title: jobTitle,

      description: description,

      price: price,

      currency: currency,

      jobtype: jobtype,

      estimate: estimate,

      duration: duration,

      skills: skills,

      experience: experience,

      createdOn: serverTimestamp(),

      status: 'initiated'

    })

      .then(res => {

        updateDoc(doc(db, 'Clients', userId, 'Jobs', res.id), {

          jobId: res.id

        }).then(result => {

          router.push(`/post-job/review/${res.id}`)

          message.success("Job posted sucessfully")

        }).catch(error => {

          message.error(error.code)

        })

      }).catch(error => {

        message.error(error.code)

      })

 }

  const getFreelancerDetails = (userId) => {

    if (userId) {

      getDoc(doc(db, 'Users', userId))

        .then(res => {

35 | P a g e
          setFreelancerDetails(res.data())

        }).catch(error => toast.error(error.code))

  }

 }

  const completeProfile = async () => {

    const docRef = doc(db, 'Users', user.uid)

    updateDoc(docRef, {

      experienceLevel: experience,

      skills: skills,

      title: title,

      profileCompleted: true,

      photoURL: userPic,

      workHistory: workInfo,

      educationBackground: educationInfo,

      about: about

    })

      .then(res => {

        if (user.emailVerified) {

          message.success('Profile complete')

          setIsUpdating(false)

          router.push('/dashboard')

          setProfileStatus(true)

        } else {

          setIsUpdating(false)

          router.push('/verify-email')

    }

      })

      .catch(error => {

        message.error(error.code)

36 | P a g e
        setIsUpdating(false)

      })

 }

  // username, userPic,contact,title,experience

  const updateUserProfile = () => {

    setIsUpdating(true)

    updateProfile(auth.currentUser, {

      photoURL: userPic ===""?'default':userPic,

    }).then(res => {

      updateDoc(doc(db, 'Users', user.uid), {

        photoURL: userPic

      }).then(res => {

        message.success('Profile updated successfully')

        completeProfile()

      }).catch(error => toast.error(error.code))

      // setShowUserModal(!showUserModal)

    }).catch(error => {

      toast.error(error.code)

      setIsUpdating(false)

    })

 }

  const createEmployerAccount = async (userDetails) => {

    setAuthenticating(true)

    createUserWithEmailAndPassword(auth, userDetails.userEmail, userDetails.userPassword)

      .then(userCredentials => {

        setUser(userCredentials.user)

        updateProfile(auth.currentUser, {

          displayName: userDetails?.firstName + ' ' + userDetails?.secondName,

          photoURL: 'default'

        })

37 | P a g e
        const collRef = doc(db, 'Clients', userCredentials.user.uid)

        setDoc(collRef, {

          userId: userCredentials.user.uid,

          businessName: userDetails?.businessName,

          firstName: userDetails?.firstName,

          secondName: userDetails?.secondName,

          displayName: userDetails?.firstName + ' ' + userDetails?.secondName,

          email: userCredentials.user.email,

          country: userDetails.userCountry,

          joinedDate: now,

          status: 'not verified',

          accountType: userDetails.accountType.toLowerCase(),

          photoURL: 'default',

          profileCompleted: false,

          // skills: [],

          about: `Hey am ${userDetails?.firstName + ' ' + userDetails?.secondName}`,

        }).then(res => {

          setAuthenticating(false)

          router.push('/verify-email')

        })

          .catch(error => {

            setAuthenticating(false)

            message.error(error.code)

          })

      })

      .catch(error => {

        setAuthenticating(false)

        message.error(error.code)

38 | P a g e
      })

 }

  const signupWithEmail = async (userDetails) => {

    setAuthenticating(true)

    createUserWithEmailAndPassword(auth, userDetails.userEmail, userDetails.userPassword)

      .then(userCredentials => {

        setUser(userCredentials.user)

        updateProfile(auth.currentUser, {

          displayName: userDetails?.firstName + ' ' + userDetails?.secondName,

          photoURL: 'default'

        })

        // localStorage.setItem('@user', JSON.stringify(userCredentials.user))

        const collRef = doc(db, 'Users', userCredentials.user.uid)

        setDoc(collRef, {

          userId: userCredentials.user.uid,

          firstName: userDetails?.firstName,

          secondName: userDetails?.secondName,

          displayName: userDetails?.firstName + ' ' + userDetails?.secondName,

          email: userCredentials.user.email,

          country: userDetails.userCountry,

          joinedDate: now,

          status: 'not verified',

          accountType: userDetails.accountType.toLowerCase(),

          photoURL: 'default',

          profileCompleted: false,

          skills: [],

          about: `Hey am ${userDetails?.firstName + ' ' + userDetails?.secondName}`,

        })

          .then(res => {

39 | P a g e
            authoriseUser(userCredentials.user)

            // router.push('/verify-email')

          }).catch(error => {

            setAuthenticating(false)

            toast.error(error.code)

          })

      })

      .catch(error => {

        setAuthenticating(false)

        message.error(error.code)

      })

 }

  const signinWithEmail = async (email, password) => {

    setAuthenticating(true)

    signInWithEmailAndPassword(auth, email, password)

      .then(userCredentials => {

        const user = userCredentials.user;

        authoriseUser(user)  //  const snapshot = await getDoc(docRef)

        // router.push('/find-work')

        // localStorage.setItem('@user', JSON.stringify(user))

      }).catch(error => {

        setAuthenticating(false)

        toast.error(error.code)

      })

 }

  const authoriseUser = async (user) => {

40 | P a g e
    // setUser(user)

    const docRef = doc(db, 'Users', user.uid)

    const ref = doc(db, 'Clients', user.uid)

    const freelancerSnapshot = await getDoc(docRef)

    const clientSnapshot = await getDoc(ref)

    if (user.emailVerified) {

      if (freelancerSnapshot.id === user.uid) {

        if (freelancerSnapshot.data()?.accountType === 'freelancer') {

          localStorage.setItem('account', 'freelancer')

          setUser(user)

          if (freelancerSnapshot.data()?.profileCompleted === false) {

            setAuthenticating(false)

            setUser(user)

            router.push('/complete-profile')

          } else {

            setProfileStatus(true)

            setUser(user)

            router.push('/dashboard')

            setAuthenticating(false)

     }

          setAuthenticating(false)

    }

   }

      if(clientSnapshot.id === user.uid){

        if(clientSnapshot.data()?.accountType ==='client'){

          localStorage.setItem('account','client')

          setUser(user)

          setAuthenticating(false)

          router.push('/post-job')

    }

41 | P a g e
   }

    } else {

      router.push('/verify-email')

      setAuthenticating(false)

  }

    // if (clientSnapshot.exists) {

    //   localStorage.setItem('account', 'client')

    //   setUser(user)

    //   router.push('/post-job')

    //   setAuthenticating(false)

    // }

    // getDoc(query(docRef))

    //   .then(snapshot => {

    //     if (snapshot.data()?.accountType === 'freelancer') {

    //       localStorage.setItem('account', 'freelancer')

    //       if (snapshot.data().profileCompleted === false) {

    //         setAuthenticating(false)

    //         router.push('/complete-profile')

    //       } else {

    //         setProfileStatus(true)

    //         setUser(user)

    //         router.push('/find-work')

    //       }

    //       setAuthenticating(false)

    //     } else {

42 | P a g e
    //       localStorage.setItem('account', 'client')

    //       setUser(user)

    //       router.push('/post-job')

    //       setAuthenticating(false)

    //     }

    //   })

 }

  const openNotificationWithIcon = type => {

    notification[type]({

      message: 'Sucess',

      description: "Your proposal has been submitted sucessfully"

    });

  };

  const submitApplication = (application) => {

    setConfirmLoading(true)

    const ref = doc(db, 'Clients', application.clientId, 'Jobs', application.jobDetails.jobId, 'Applicants',


application.freelancer.userId)

    setDoc(ref, {

      freelancerId: application?.freelancer.userId,

      freelancerDetails: application?.freelancer,

      jobDetails: application?.jobDetails,

      attachment: application?.attachment,

      resume: application?.resume,

      submittedOn: serverTimestamp()

    }).then(res => {

      // updateDoc(doc(db, 'Clients', application.clientId, 'Jobs', application.jobDetails.jobId,


'Applicants', application.freelancer.userId), {

      //   applicationId: application.freelancer.userId

      // })

43 | P a g e
      setDoc(doc(db, 'Users', application.freelancer.userId, 'MyProposals', application.jobDetails.jobId),
{

        jobId: application?.jobDetails.jobId,

        jobDetails: application?.jobDetails,

        attachment: application?.attachment,

        resume: application?.resume,

        submittedOn: serverTimestamp()

      }).then(response => {

        setConfirmLoading(false)

        openNotificationWithIcon('success')

        setOpenModal(false)

        router.push('/find-work')

      }).catch(error => {

        message.error(error.code)

        setConfirmLoading(false)

      })

    }).catch(err => {

      message.error(err.message)

      setConfirmLoading(false)

    })

 }

  // setDoc(doc(db, 'Users', application.freelancer.userId, 'MyProposals',


application.jobDetails.jobId), {

  //   jobId: application?.jobDetails.jobId,

  //   jobDetails: application?.jobDetails,

  //   attachment: application?.attachment,

  //   resume: application?.resume,

44 | P a g e
  //   submittedOn: serverTimestamp()

  // }).then(response => {

  //   setConfirmLoading(false)

  //   openNotificationWithIcon('success')

  //   setOpenModal(false)

  //   router.push('/find-work')

  // }).catch(error => {

  //   message.error(error.code)

  //   setConfirmLoading(false)

  // })

  const hireFreelancer = async (freelancer, jobDetails, attachment, resume, transaction) => {

    const ref = doc(db, 'Clients', user?.uid, 'Jobs', jobDetails?.jobId, 'Hires', freelancer?.userId)

    if (transaction?.status === "successful") {

      const colRef = collection(db, 'Clients', user?.uid, 'Jobs', jobDetails?.jobId, 'Transactions')

      addDoc(colRef, {

        transactionDetails: {

          amount: transaction?.amount,

          currency: transaction?.currency,

          customer:

     {

            name: transaction?.customer?.name,

            email: transaction?.customer?.email,

            phone_number: transaction?.customer?.phone_number

          },

          flw_ref: transaction?.flw_ref,

          redirectstatus: `www.vasights.com/payments/${transaction?.id}`,

45 | P a g e
          status: transaction?.status,

          transaction_id: transaction?.transaction_id,

          tx_ref: transaction?.tx_ref,

        },

        transactionReference: transaction?.tx_ref,

        freelancer: freelancer

      }).then((res) => {

        setDoc(ref, {

          freelancerDetails: freelancer,

          // email:freelancer.email,

          freelancerId: freelancer.userId,

          clientId: user?.uid,

          resume: resume,

          attachment: attachment,

          hiredOn: serverTimestamp(),

          jobId: jobDetails?.jobId,

          jobTitle: jobDetails?.title,

          status: "hired",

          paymentStatus: transaction.status

        }).then(() => {

          //Client should be notified

        }).catch(error => {

          message.error(error.code)

        })

        setDoc(doc(db, 'Users', freelancer.userId, 'MyHires', jobDetails?.jobId), {

          freelancerDetails: freelancer,

          freelancerId: freelancer.userId,

          clientId: user?.uid,

          resume: resume,

46 | P a g e
          attachment: attachment,

          hiredOn: serverTimestamp(),

          jobId: jobDetails?.jobId,

          jobTitle: jobDetails?.title,

          status: "hired",

          paymentStatus: transaction.status,

        }).then(response => {

          message.success(`You hired ${freelancer?.firstName + ' ' + freelancer?.secondName}`)

        }).catch(error => {

          message.error(error.code)

        })

      }).catch(error => {

        message.error(error.code)

      })

      updateDoc(doc(db, 'Clients', user?.uid, 'Jobs', jobDetails?.jobId), {

        paymentStatus: transaction.status

      })

      message.success("We picked your payments sucessfully")

      router.push(`/post-job/review/${jobDetails?.jobId}`)

  }

 }

  const dismissFreelancer = async (freelancer, jobId, clientFeedback, rating) => {

    // setShowDismissModal(true)

    // dismissing,setDismissing

    // setDismissing(true)

    const ref = doc(db, 'Clients', user?.uid, 'Jobs', jobId, 'Hires', freelancer?.userId)

    //Deleting from Client Side

    updateDoc(ref, {

      jobId: jobId,

47 | P a g e
      status: 'dismissed',

      dismissedOn: serverTimestamp(),

      clientFeedback: clientFeedback,

      rating: rating

    })

      .then(response => {

        updateDoc(doc(db, 'Users', freelancer.userId, 'MyHires', jobId), {

          jobId: jobId,

          status: 'dismissed',

          clientFeedback: clientFeedback,

          rating: rating

        })

          .then(response => {

            message.success(`You dismissed ${freelancer?.displayName}`)

            // setShowDismissModal(false)

            setDismissing(false)

          })

          .catch(error => {

            message.error(error.code)

            // setShowDismissModal(false)

            setDismissing(false)

          })

      }).catch(error => {

        message.error(error.code)

        // setShowDismissModal(false)

        setDismissing(false)

      })

 }

48 | P a g e
  const removeJob = async (jobId) => {

    if (user && jobId) {

      deleteDoc(doc(db, 'Clients', user.uid, 'Jobs', jobId))

        .then(res => {

          message.success("Job was deleted successfully")

        })

        .catch(e => {

          message.error(e.message)

        })

  }

 }

  const removeSavedJob = async (jobDetails) => {

    if (user && jobDetails.jobId) {

      deleteDoc(doc(db, 'Users', user.uid, 'SavedJobs', jobDetails.jobId))

        .then(() => {

        }).catch(e => {

          message.error(e.message)

        })

  }

 }

  const getTopFreelancers = async () => {

    let data = []

    onSnapshot(query(collection(db, 'Users')), snapshot => {

      snapshot.forEach(doc => {

        data.push(doc.data())

49 | P a g e
      })

    })

    setTopFreelancers(data)

 }

  const saveJob = (jobDetails) => {

    console.log("Add job", jobDetails)

    if (user && jobDetails.jobId) {

      setDoc(doc(db, 'Users', user.uid, 'SavedJobs', jobDetails.jobId), {

        jobDetails: {

          clientId: jobDetails.clientId,

          title: jobDetails.title,

          description: jobDetails.description,

          price: jobDetails.price,

          jobId: jobDetails.jobId,

          currency: jobDetails.currency,

          jobtype: jobDetails.jobtype,

          estimate: jobDetails.estimate,

          duration: jobDetails.duration,

          skills: jobDetails.skills,

          experience: jobDetails.experience,

          createdOn: jobDetails.createdOn

        },

        savedOn: serverTimestamp()

      })

  }

 }

  const getSavedJobs = () => {

50 | P a g e
    if (user) {

      if (localStorage.getItem('account') === 'freelancer') {

        onSnapshot(query(collection(db, 'Users', user.uid, 'SavedJobs')),

          snapshot => {

            let data = []

            snapshot.forEach(res => {

              data.push(res.data())

            })

            console.log("Saved Jobs", data)

            setSavedJobs(data)

     }

    )

   }

  }

 }

  // const getHires = async (jobId) => {

  //   if (jobId && user !== null) {

  //     const ref = query(collection(db, 'Clients', user?.uid, 'Jobs', jobId, 'Hires'), where('status', '==',
'hired'))

  //     onSnapshot(ref, snapshot => {

  //       let data = []

  //       snapshot.forEach(doc => {

  //         data.push(doc.data())

  //       })

  //       setHires(data)

  //     })

  //   }

  // }

  const getHires = (jobId) => {

51 | P a g e
    if (user) {

      if (localStorage.getItem('account') === 'client') {

        onSnapshot(query(collection(db, 'Clients', user.uid, 'Jobs', jobId, 'Hires'), where('status', '==',


'hired')),

          snapshot => {

            let data = []

            snapshot.forEach(res => {

              data.push(res.data())

            })

            console.log("Tires", data)

            setHires(data)

     }

    )

   }

  }

 }

  const startJob = async (jobId) => {

    const ref = doc(db, 'Clients', user.uid, 'Jobs', jobId)

    if (hires.length > 0) {

      updateDoc(ref, {

        status: 'started',

        startedOn: serverTimestamp()

      })

        .then(res => {

          message.success("Job Started")

        })

        .catch(error => {

          message.error("Something went wrong")

        })

    } else {

52 | P a g e
      message.warn("No hires found yet!")

  }

 }

  const endJob = async (jobId) => {

    const ref = doc(db, 'Clients', user.uid, 'Jobs', jobId)

    updateDoc(ref, {

      status: 'completed',

      endedOn: serverTimestamp()

    })

      .then(res => {

        message.success("Job Completed")

      })

      .catch(error => {

        message.error("Something went wrong")

      })

 }

  const getMyProposals = () => {

    if (user) {

      if (localStorage.getItem('account') === 'freelancer') {

        onSnapshot(query(collection(db, 'Users', user.uid, 'MyProposals'), orderBy('submittedOn',


'asc')),

          snapshot => {

            let data = []

            snapshot.forEach(res => {

              data.push(res.data())

            })

            console.log("My proposals", data)

53 | P a g e
            setMyProposals(data)

     }

    )

   }

  }

 }

  const addToSkills = (text) => {

    const tempItem = skills.find(item => item.toLowerCase() === text.toLowerCase())

    if (!tempItem) {

      if (skills.length < 5) {

        setSkills([...skills, text])

      } else {

        message.warning("Only 5 skills are required", 2.5)

   }

  }

 }

  const addMultipleSkills = (text) => {

    const tempItem = skills.find(item => item.toLowerCase() === text.toLowerCase())

    if (!tempItem) {

      setSkills([...skills, text])

  }

 }

  const removeFromSkills = (text) => {

    const exist = skills.find(item => item === text)

    if (exist) {

54 | P a g e
      setSkills(skills.filter(item => item !== text))

  }

 }

  //  Send Notications email

  const notifyUser = () => {

    console.log("Clicked ")

    const sendMessageNotication = httpsCallable(firebaseFunctions, 'sendMessageNotication')

    // const email = data.email

    //     const message = data.message

    //     const jobTitle =data.jobTitle

    //     const clientName = data.clientName

    const data = {

      email: 'waiswadonnie@gmail.com',

      message: 'You have a new client',

      jobTitle: 'React Native Developer needed',

      clientName: 'Donnie Drin'

  }

    sendMessageNotication(data)

      .then(res => {

        console.log(res)

      })

      .catch(error => {

        message.error(error.code)

      })

 }

  // Collect Payments

  // const config = {

55 | P a g e
  //   headers: { Authorization: `Bearer ${ZPYPUBK -
a5d1a6a1674ea577ac01b4b2d52b18760691e830dbc04a08ce17c96bde0c502f}` }

  // };

  const mobileMoney = async () => {

    let userId = user.uid;

    let phoneNumber = '256759723980';

    let amount = 200;

    let appointmentId = '1213213';

    let narration = 'Being Paid for Waiswa Donnie';

    console.log(`UserId: ${userId}, Amount: ${amount}, Phone number: ${phoneNumber} with Job ID:
${narration}`);

    const endpoint = 'https://api.zengapay.com/v1/collections';

    const config = {

      'Authorization': 'ZPYPUBK-
a5d1a6a1674ea577ac01b4b2d52b18760691e830dbc04a08ce17c96bde0c502f',

      'Content-Type': 'application/json'

  }

    const obj = JSON.stringify({

      "msisdn": phoneNumber,

      "amount": amount,

      "external_reference": appointmentId,

      "narration": `${narration}`

    })

    // axios({ method: 'post', url: endpoint, headers: config, data: obj })

    // .then(result=>{

    //   console.log(result.data);

    // })

    // .catch(error=>{

    //   throw error

56 | P a g e
    // })

    try {

      const result = await axios({ method: 'post', url: endpoint, headers: config, data: obj });

      // Check OneNote for sample response object. By default axios callback returns res.data

    } catch (error) {

      console.log("Error initiating payment: " + JSON.stringify(error));

      // return error;

  }

  };

  return (

    <GlobalContext.Provider

      value={{

        logout,

        signinWithEmail,

        signupWithEmail,

        updateUserProfile,

        user,

        loginWithGoogle,

        skillz,

        getChats,

        chatRooms,

        removeSavedJob,

        savedJobs,

        setShowUserModal,

        showUserModal,

        sendMessage,

57 | P a g e
        sendVerificationLink,

        skills,

        createChat,

        clientId,

        active,

        setActive,

        setClientId,

        totalJobsCount,

        removeFromSkills,

        addToSkills,

        createEmployerAccount,

        skillsAdded,

        openModal,

        setOpenModal,

        setSkillsAdded,

        getSavedJobs,

        setExperience,

        confirmLoading,

        setConfirmLoading,

        removeJob,

        experience,

        totalUsersCount,

        completeProfile,

        addMultipleSkills,

        getFreelancerDetails,

        totalClients,

        topFreelancers,

        freelancerDetails,

        title,

        setTitle,

        jobDetails,

58 | P a g e
        setJobDetails,

        username,

        setUsername,

        userPic,

        setUserPic,

        authenticating,

        dismissing,

        setDismissing,

        contact,

        setContact,

        addJob,

        hireFreelancer,

        myProposals,

        getMyProposals,

        applicantsId,

        setApplicantsId,

        profileStatus,

        setProfileStatus,

        notifyUser,

        submitApplication,

        saveJob,

        dismissFreelancer,

        // showDismissModal,

        getJobInvites,

        startJob,

        endJob,

        jobInvites,

        getHires,

        resetPassword,

        savedJobs,

        hires,

59 | P a g e
        mobileMoney,

        // completing profile

        field,

        setField,

        level,

        setLevel,

        school,

        setSchool,

        date,

        setDate,

        description,

        setDescription,

        workTitle,

        setWorkTitle,

        workCompany,

        setWorkCompany,

        workCity,

        setWorkCity,

        workCountry,

        setWorkCountry,

        workDate,

        setWorkDate,

        workDescription,

        setAbout,

        endDate,

        setEndDate,

        about,

        workInfo,

        isUpadating,

        setWorkInfo,

        setEducationInfo,

60 | P a g e
        educationInfo,

        setWorkDescription,

        getJobs,

        stopDate,

        setStopDate,

        jobs,

      }}

  >

      {children}

    </GlobalContext.Provider>

 )

4.2 TESTING
The Test Plan is derived from the Requirements, Functional Specifications, and detailed
Design Specifications. To ensure that a new user is added to the system successfully.

61 | P a g e
CHAPTER 5

Conclusion
Freelance Management System Fixed-price projects are automatically marked complete
once your bid amount is paid in full. Hourly projects have to be ended manually by your
employer before they are marked complete. Feel free to ask your employer for the project’s
completion after your submitted work is reviewed and paid for. The Jobs Completed is the
percentage of the projects you have successfully completed versus the total number of
awarded projects you accepted. The On Budget and On Time percentages reflect your
previous employers’ feedback on whether or not you completed their projects for the agreed
price and on the agreed deadline. The Preferred Freelancer Program pools the best
talent ,creating a community of elite freelancers whom we call Preferred Freelancers. If you
get accepted into the program, you will receive exclusive invitations to work on high-value
projects, and you will get the Preferred Freelancer badge to make your profile stand out,
among other perks.

5 Summary
This chapter has outlined how the employee management system. The method selected for
systems change-over has been highlighted and justified, lastly the chapter concludes by
showing how the system can be deployed. The next chapter is on Testing, it focuses on the
tests carried out to ensure the system functions according to its specifications.

5.1 Future work


Leave Management
The leave management module can be improved by having all leave requests approved by the
head of department before submission rather than going straight to the HR manager. This
feature is important because the HOD /Supervisor should know which of his/her employees
which to go on leave.
Integration with payroll system
In order for the system to be more comprehensive, I’d recommend an integration of the
system to a payroll system that will enable employees view and download their pay slips on
demand.
Employee Performance

62 | P a g e
The designed system provides the HOD with the ability to assign tasks to project members. If
further worked on, this functionality can assist in determining the performance of employees
based on their ability to finish tasks on time.

63 | P a g e
5.2 References / Bibliography
[1] OrangeHRM Open Source, Retrieved: November 4, 2013. From:
http://www.orangehrm.com/open-source-product-features-pim.shtml
[2] A.S.SyedNavaz, A.S.SyedFiaz, C.Prabhadevi, V.Sangeetha, S.Gopalakrishnan, “Human
Resource Management System”, IOSR Journal of Computer Engineering (IOSR-JCE),
Volume 8, Issue 4 (Jan. – Feb. 2013) Page 62-71.
[3] Julie Bulmash, “Human Resource Management and Technology”, Chapter 3
[4] TECH HRM (Human Resource Management System), Retrieved: November 4, 2013.
From: http://www.techjetsolutions.com/brochure/TECHHRM.pdf
[5] Renae Broderick, John W. Boudreau, “Human resource management, information
technology, and the competitive edge”, Academy of Management Executive, 1992 Vol. 6 No.
2
[6] Centralized Employee Information, Retrieved: July 8th, 2014. From:
https://www.zoho.com/people/employee-management-system.html
[7] HR and Employee Mnagement Software, Retrieved: July 8th, 2014. From:
http://www.getapp.com/hr-employee-management-software
[8] Ian Sommerville, “Software Engineering”, 9th Edition, Addison-Wesley, 2011.
[9] What is Enterprise Resource Planning (ERP)? Webopedia. Retrieved: January 17, 2014,
from: http://www.webopedia.com
[10] Avison, D. and Fitzgerald, G. (2003).Information systems Development Methodologies,
Techniques and Tools.3rd Edition. McGraw-Hill Education Limited Bershire
[11] Zhiming, L, July 2002 ,Object-Oriented Software Development with UML Retrieved:
July 16th 2010. From: http://www.iist.unu.edu/www/docs/techreports/reports/report259.pdf
67 | P a g e

64 | P a g e
[12] Juan Manuel Munoz Palacio, Information systems development methodologies for Data-
driven Decision Support Systems, 2010,
[13] Deitel, PJ & Deitel, HM, 2008, Internet & World Wide Web How To Program,
Dorling Kindersley, India
[14] Web design best practices checklist 2009. Retrieved: October 17, 2009, from:
http://terrymorris.net/bestpractices/
[16] Connolly, T, Begg, C, 2005, Database Systems A Practical Approach to Design
Implementation and Management, 4th Edition, Dorling Kindersley, India
[17] Avison, D. and Fitzgerald, G, 2003. Information systems Development Methodologies,
Techniques and Tools, 3rd Edition, McGraw-Hill Education Limited, Berkshir

65 | P a g e

You might also like