Workflow Report
Workflow Report
Submitted by
1
Page
DECLARATION
I hereby declare that the internship project report is an authentic record of my own work
carried out as requirements of internship report submission for the award of B.Tech degree
in Computer Science Engineering from Lovely Professional University, Phagwara, under the
guidance of Mr. Sami Anand, during July to January 2018. All the information furnished in
this internship project report is based on my own intensive work and is genuine.
(Signature of Student )
Date: 05-25-2019
2
Page
CERTIFICATE
This is to certify that the declaration statement made by the student is correct to the best of
my knowledge and belief. He has completed this Internship Project Report under my
guidance and supervision. The present work is the result of their original investigation, effort
and study. No part of the work has ever been submitted for any other degree at any
University. The Internship Project Report is fit for the submission and partial fulfillment of
the conditions for the award of B.Tech degree in Computer Science Engineering from
Lovely Professional University, Phagwara.
Designation :
Date:
3
Page
Page
4
ACKNOWLEDGEMENT
I am thankful to my manager and mentor Mr. Aseem Kumar for providing me this
opportunity to work upon the projects and enhance my learning. I am also thankful to
my other colleagues for providing me support and guidance throughout my work.
I specially thanks Click Labs for providing me this wonderful opportunity to work with
the team as an intern and have wonderful learning experience.
5
Page
CONTENTS
1. Introduction
2. Problem Statement
3. Existing System
• Introduction
• Existing Software
• DFD for present system
• What’s new in the system to be developed
4. Problem Analysis
• Product definition
• Feasibility Analysis
• Project Plan
5. Software Requirement Analysis
• Introduction
• General Description
• Specific Requirements
6. Design
• System Design
• High level Design
• Low level design
• Codes/Screenshot
7. Testing
• Functional testing
• Structural testing
• Levels of testing
• Testing the project
8. Implementation
• Implementation of the project
• Conversion Plan
• Post Implementation
9. Project Legacy
6
Page
10. References
1. INTRODUCTION
7
Page
2. PROBLEM STATEMENTS
● Related to WorkFlow
3. EXISTING SYSTEM
● INTRODUCTION
Workflow app basically keep track of all the employee in an organisation , flow
of an app start from log in and sign up which receive token from API, after that
it jumps into main page where we can add our daily work routine also on which
particular task we have been working, Workflow also works as remainder for
user which allow them to remind their activity (which was my task in team to
achieve).
8
Page
● EXISTING PRODUCTS
1. XCode 11
It is a platform provided by apple which allow us to build application
for iOS. It comes with many frame work which make user to write less
code and interact more with their work
Features:
1. Card View, Map View
2. Core Data
3. Table View, Collection View
4. Widgets (slider, switch, label. Text field)
5. Notifications
2. Core Data
It is a framework of a XCode, this is own data base of the XCode, it also
saves data in the form of table and we can fetch or save data accordingly,
it is a complete copy of SQL and work as same also.
3. Swift 4
Swift is a high-level programming language developed by Apple and
made available in 2014. It is designed for writing apps for Apple
platforms, including macOS, iOS, tvOS, and watchOS
1. Object Oriented
2. Type Safe
4. REST API
Representational State Transfer (REST) is a software style that
defines a set of constraints to be used for creating web services. Web
services that conform to the REST architectural style,
called RESTful Web services (RWS), provide interoperability
between computer systems on the internet. RESTful Web services
allow the requesting systems to access and manipulate textual
representations of web resources by using a uniform and predefined
set of stateless operations. Other kinds of Web services, such a
SOAP Web services, expose their own arbitrary sets of operations
9
Page
● DATA FLOW DIAGRAM
10
Page
~ Process cycle to solve the Bug
● NEW DEVELOPMENT
New release of software is done with fixed bugs, crashes and added feature. As,
the bugs and crashes are fixed, it goes for testing to the QA team. As the code
passes all the tests by QA, finally the release goes for the deployment of new
version to live production for use.
11
Page
4. PROBLEM ANALYSIS
● INTRODUCTION
Adding new features or fixing the bugs is the most important part of a developer.
Most of the time is spent to enhance the performance of the project to make it
work better with the increase amount of customer’s suggestions and
requirements received by the company. Analyzing the requirements of clients
and the need to upgrade, are the two most important factors, which must be
taken into consideration for the releases of new version of products.
1. Add Reminder Show Notification as per data entered or value
set by the user.
2. Managing white labelling in a application.
3. Creating queries and new entity for values stored by user.
4. User Notification Framework
5. Data fetch must be of Date type.
● FEASIBILITY ANALYSIS
The need to resolve an issue, it is much necessary to realize which task i.e. to
select task from the assigned issues, to be worked upon. Thus, the priorities are
set for each task, which helps in scheduling the systematic work process. These
priorities are either set by the QA team or by the client itself, and accordingly
the developer’s team work upon them, giving preference to high priority tasks.
Push Notification:
■ To show the notification also from backend side, which is really a
big task but can be achieved by getting certificates.
There was an API already to send the notifications I used the that API to
send the notification to agent.
● PROJECT PLAN
Every two week developers and project managers have a meeting to decide the
workflow for the next sprint (tanure of two week constitutes a sprint). In the
meeting, the bugs and requirement of new feature or functionality, are decided
and a roadmap is planned to execute these fixes.
Beside this, before the release of version, a meeting is held between the QA,
developers and product management team to check whether the changes and
fixes are best to go with the release date, without effecting other data or
products.
Basically, other projects can go on release on any of the date of month. But our
project has a major concern, as it causes a downtime, so it usually goes on
release for weekends.
14
Page
5. SOFTWARE REQUIREMENT ANALYSIS
● INTRODUCTION
○ Specific Requirements
6. DESIGN
Services:
1) Training Plan Service:
This service will be responsible for managing,creating,deleting features related to Training
Plan and also Templates. The service's accessablity and CRUD privilege is limited to
only Team Lead user Type.
2. Interfaces:
User Hierarchy Chart, above shows how appropriate user will be created by assigning
appropriate user types to all user. So that they can advantage of already built-in Roles.
This diagram shows flow and tasks that a team leader can perform in our service.
16
Page
UI Mockups:
This is the mock representation of Dashboard of team lead. Which how team would be able
to create training plan or View the Progress of the employee.
Data Store:
import UIKit
import UserNotifications
self = .TaskNotifications
}
Page
}
}
// MARK :- Variables
let notificationCenter = UNUserNotificationCenter.current()
// MARK :- IBOutlets
@IBOutlet weak var notificationSettingsTableView: UITableView!
nibRegister()
notificationSettingsTableView.allowsSelection = false
self.title = "Notification"
}
notificationSettingsTableView.register(UINib(nibName: "NotificationsEnabledCell",
Page
} else {
Page
}
Page
}
}
case .ShiftNotifications:
switch NotificationTime(index: indexPath.row) {
case .notificationType:
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"NotificationsEnabledCell") as? NotificationsEnabledCell else {
fatalError("Cell Initialization failed")
}
cell.notificationEnabledSwitch.addTarget(self, action:
#selector(shiftNotificationsEnabledStateChanged(switchState:)), for: .valueChanged)
cell.notificationEnabledLabel.text = "Shift Notification"
if UserDefaults.standard.bool(forKey: UserDefaultsKey.notificationState) == false
{
cell.notificationEnabledSwitch.setOn(false, animated: true)
} else {
cell.notificationEnabledSwitch.setOn(UserDefaults.standard.bool(forKey:
UserDefaultsKey.shiftState), animated: true)
21
}
Page
return cell
case .notificationTime:
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"NotificationTimeTableViewCell") as? NotificationTimeTableViewCell else {
fatalError("Cell Initialization failed")
}
cell.notificationStartTimeLabel.text = "Shift notification start before"
cell.notificationEndTimeLabel.text = "Shift notification end before"
if UserDefaults.standard.string(forKey: UserDefaultsKey.shiftStart) == nil {
UserDefaults.standard.set("01", forKey: UserDefaultsKey.shiftStart)
UserDefaults.standard.set("01", forKey: UserDefaultsKey.shiftEnd)
}
cell.startTimeTextField.text = UserDefaults.standard.string(forKey:
UserDefaultsKey.shiftStart)! + " min"
cell.endTimeTextField.text = UserDefaults.standard.string(forKey:
UserDefaultsKey.shiftEnd)! + " min"
cell.startTimeTextField.tag = indexPath.section
cell.endTimeTextField.tag = indexPath.section
cell.timePickerDelegate = self
case .BreakNotifications:
switch NotificationTime(index: indexPath.row) {
case .notificationType:
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"NotificationsEnabledCell") as? NotificationsEnabledCell else {
fatalError("Cell Initialization failed")
22
}
Page
cell.notificationEnabledSwitch.addTarget(self, action:
#selector(breakNotificationsEnabledStateChanged(switchState:)), for: .valueChanged)
cell.notificationEnabledLabel.text = "Break Notification"
if UserDefaults.standard.bool(forKey: UserDefaultsKey.notificationState) == false
{
cell.notificationEnabledSwitch.setOn(false, animated: true)
} else {
cell.notificationEnabledSwitch.setOn(UserDefaults.standard.bool(forKey:
UserDefaultsKey.breakState), animated: true)
}
return cell
case .notificationTime:
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"NotificationTimeTableViewCell") as? NotificationTimeTableViewCell else {
fatalError("Cell Initialization failed")
}
cell.notificationStartTimeLabel.text = "Break notification start before"
cell.notificationEndTimeLabel.text = "Break notification end before"
if UserDefaults.standard.string(forKey: UserDefaultsKey.breakStart) == nil {
UserDefaults.standard.set("01", forKey: UserDefaultsKey.breakStart)
UserDefaults.standard.set("01", forKey: UserDefaultsKey.breakEnd)
}
cell.startTimeTextField.text = UserDefaults.standard.string(forKey:
UserDefaultsKey.breakStart)! + " min"
cell.endTimeTextField.text = UserDefaults.standard.string(forKey:
UserDefaultsKey.breakEnd)! + " min"
cell.startTimeTextField.tag = indexPath.section
cell.endTimeTextField.tag = indexPath.section
cell.timePickerDelegate = self
}
Page
}
return cell
}
case .TaskNotifications:
switch NotificationTime(index: indexPath.row) {
case .notificationType:
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"NotificationsEnabledCell") as? NotificationsEnabledCell else {
fatalError("Cell Initialization failed")
}
cell.notificationEnabledSwitch.addTarget(self, action:
#selector(taskNotificationsEnabledStateChanged(switchState:)), for: .valueChanged)
cell.notificationEnabledLabel.text = "Task Notification"
if UserDefaults.standard.bool(forKey: UserDefaultsKey.notificationState) == false
{
cell.notificationEnabledSwitch.setOn(false, animated: true)
} else {
cell.notificationEnabledSwitch.setOn(UserDefaults.standard.bool(forKey:
UserDefaultsKey.taskState), animated: true)
}
return cell
case .notificationTime:
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"NotificationTimeTableViewCell") as? NotificationTimeTableViewCell else {
fatalError("Cell Initialization failed")
}
cell.notificationStartTimeLabel.text = "Task notification start before"
cell.notificationEndTimeLabel.text = "Task notification end before"
cell.notificationStartTimeLabel.text = "Task notification start before"
cell.notificationEndTimeLabel.text = "Task notification end before"
if UserDefaults.standard.string(forKey: UserDefaultsKey.taskStart) == nil {
UserDefaults.standard.set("01", forKey: UserDefaultsKey.taskStart)
UserDefaults.standard.set("01", forKey: UserDefaultsKey.taskEnd)
}
cell.startTimeTextField.text = UserDefaults.standard.string(forKey:
UserDefaultsKey.taskStart)! + " min"
cell.endTimeTextField.text = UserDefaults.standard.string(forKey:
UserDefaultsKey.taskEnd)! + " min"
cell.startTimeTextField.tag = indexPath.section
cell.endTimeTextField.tag = indexPath.section
cell.timePickerDelegate = self
}
Page
}
Training Plan Services:
Interfaces
interfacimport Foundation
import UIKit
import UserNotifications
class NotificationManager {
private var taskList: [ScheduledTask] = []
private var workShifts: [WorkShiftDetails] = []
private var breakShifts: [BreakDetails] = []
private var taskTimeList: [TaskTimes] = []
private init() {
func manage() {
fetchCoreData(callback: {
})
let taskSwitchState = UserDefaults.standard.bool(forKey: UserDefaultsKey.taskState)
if UserDefaults.standard.bool(forKey: UserDefaultsKey.notificationState) == true {
if workShifts.count > 0 {
setUpShiftNotification()
if taskList.count > 0 && taskSwitchState == true {
setUpNotifications()
} else {
print("Task list is empty or task notification is off.")
}
} else {
print("Shift list is empty.")
26
}
} else {
Page
print("Notification is off.")
}
}
func updateNotificationSetting() {
fetchCoreData(callback: {
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
let taskSwitchState = UserDefaults.standard.bool(forKey:
UserDefaultsKey.taskState)
if UserDefaults.standard.bool(forKey: UserDefaultsKey.notificationState) == true {
if self.workShifts.count > 0 {
self.setUpShiftNotification()
if self.taskList.count > 0 && taskSwitchState == true {
self.setUpNotifications()
} else {
print("Task list is empty or task notification is off.")
}
} else {
print("Shift list is empty.")
}
} else {
print("Notification is off.")
}
})
}
Page
}
}
print(notificationRequest)
Page
}
private func setNotificationContent(on index: Int, for type: NotificationType) ->
UNMutableNotificationContent {
let content = UNMutableNotificationContent()
switch type {
case .TaskStart:
content.title = "Task about to start in \(UserDefaults.standard.string(forKey:
UserDefaultsKey.taskStart) ?? "") min"
content.body = taskList[index].projectDetails?.name ?? "Unknown Task"
content.sound = UNNotificationSound(named: "out.caf")
case .TaskEnd:
content.title = "Task about to end in \(UserDefaults.standard.string(forKey:
UserDefaultsKey.taskEnd) ?? "") min"
content.body = taskList[index].projectDetails?.name ?? "Unknown Task"
content.sound = UNNotificationSound(named: "out.caf")
case .ShiftStart:
content.title = "Shift about to start in \(UserDefaults.standard.string(forKey:
UserDefaultsKey.shiftStart) ?? "") min"
content.sound = UNNotificationSound(named: "out.caf")
case .ShiftEnd:
content.title = "Shift about to end in \(UserDefaults.standard.string(forKey:
UserDefaultsKey.shiftEnd) ?? "") min"
content.sound = UNNotificationSound(named: "out.caf")
case .BreakStart:
content.title = "Break about to start in \(UserDefaults.standard.string(forKey:
UserDefaultsKey.breakStart) ?? "") min"
content.sound = UNNotificationSound(named: "out.caf")
case .BreakEnd:
content.title = "Break about to end in \(UserDefaults.standard.string(forKey:
UserDefaultsKey.breakEnd) ?? "") min"
content.sound = UNNotificationSound(named: "out.caf")
}
content.badge = 1
return content
}
} else {
Page
offsetDurationInSeconds = ApplicationConstant.sixtySecond
}
case .TaskEnd:
activityTime = taskTimeList[index].endTime!
if let taskEndNotificationTime = UserDefaults.standard.string(forKey:
UserDefaultsKey.taskEnd) {
offsetDurationInSeconds = (Int(taskEndNotificationTime) ?? 0) *
ApplicationConstant.sixtySecond
} else {
offsetDurationInSeconds = ApplicationConstant.sixtySecond
}
case .ShiftStart:
activityTime = workShifts[index].startTime!
if let shiftNotificationTime = UserDefaults.standard.string(forKey:
UserDefaultsKey.shiftStart) {
offsetDurationInSeconds = (Int(shiftNotificationTime) ?? 0) *
ApplicationConstant.sixtySecond
} else {
offsetDurationInSeconds = ApplicationConstant.sixtySecond
}
case .ShiftEnd:
activityTime = workShifts[index].endTime!
if let shiftNotificationTime = UserDefaults.standard.string(forKey:
UserDefaultsKey.shiftEnd) {
offsetDurationInSeconds = (Int(shiftNotificationTime) ?? 0) *
ApplicationConstant.sixtySecond
} else {
offsetDurationInSeconds = ApplicationConstant.sixtySecond
}
case .BreakStart:
guard let breakCurrentTime = breakShifts[index].startTime else {
return nil
}
activityTime = breakCurrentTime
if let breakNotificationTime = UserDefaults.standard.string(forKey:
UserDefaultsKey.breakStart) {
offsetDurationInSeconds = (Int(breakNotificationTime) ?? 0) *
ApplicationConstant.sixtySecond
} else {
offsetDurationInSeconds = ApplicationConstant.sixtySecond
}
case .BreakEnd:
guard let breakEndTime = breakShifts[index].endTime else {
return nil
}
activityTime = breakEndTime
if let breakNotificationTime = UserDefaults.standard.string(forKey:
UserDefaultsKey.breakEnd) {
offsetDurationInSeconds = (Int(breakNotificationTime) ?? 0) *
30
ApplicationConstant.sixtySecond
Page
} else {
offsetDurationInSeconds = ApplicationConstant.sixtySecond
}
}
let triggerDateComponents = calendar.dateComponents([.hour, .minute], from:
activityTime.adjust(.second, offset: -offsetDurationInSeconds))
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDateComponents,
repeats: false)
return trigger
}
}
31
Page
Page
32
Page
33
7. TESTING
The testing for all the stories, bugs are performed in same way. The cycle repeats in the
end of every sprint ie. 15 days. For the future release. And in every 3 months team do
the thorough testing for the next deployed build.
● FUNCTIONAL TESTING
This testing ensures that the requirements are properly satisfied by the
application or not. Various inputs are passed with different values to check the
database behavior and other specifications of the application.
● UNIT TESTING
In unit testing we take a module and test it one by one and try to cover all
possiblities to check if our code is working fine or not.
● TESTING PERFORMED BY QA
Thus, it goes to the production release, and finally observed for few days, so
that it does not create any problem.
34
Page
8. IMPLEMENTATION
Each time designing the new changes or fixing the bugs, proper analyzing of
code flow is done. The need to understand the code flow is must, and then only
anything can be implemented, considering the actual model in which the
application is build.
● CONVERSION PLAN
The changes that are to be made are listed down and accordingly the coding is
done.
For fixing a bug, the whole point of error is traced by debugging the code and
finding the root cause of issue. Once the cause is known, it is fixed and sent for
testing.
For adding a new feature or functionality, prior to implementing the actual one,
a demo is prepared. Later when the demo is ready, a meeting is scheduled with
the user and displayed, to know if any changes are required. When the changes
are approved by the user, then the final implementation takes place.
● POST IMPLEMENTATION
Once everything is implemented and approved, the code is deployed for testing.
After passing the testing phase, it is finally released for users to use. Then it is
kept under surveillance for some time, to assure the proper functioning of the
application.
35
Page
9. PROJECT LEGACY
1. FUSIONCX
2. OMNI
● http://www.github.com
● http://www.stackoverflow.com
● http://www.youtube.com
● http://apple.developers.com
● http://www.swiftTutorials.com
37
Page