0% found this document useful (0 votes)
29 views58 pages

Recruitment System Guide

The document outlines the basic concepts, assumptions, and requirements for a recruitment and course platform. It defines user roles, courses, categories, payments, and functionality for users like candidates, instructors, recruiters and administrators.

Uploaded by

Goce Lozanovski
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views58 pages

Recruitment System Guide

The document outlines the basic concepts, assumptions, and requirements for a recruitment and course platform. It defines user roles, courses, categories, payments, and functionality for users like candidates, instructors, recruiters and administrators.

Uploaded by

Goce Lozanovski
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 58

RecruitmentCH

Business Requirements

Contents
Basic Concepts.............................................................................................................................................2
Initial Assumptions..................................................................................................................................2
Commercial Terms...................................................................................................................................3
System User.............................................................................................................................................4
Company Profile......................................................................................................................................4
Course Category......................................................................................................................................4
Tag (Topic)...............................................................................................................................................4
Context....................................................................................................................................................4
Course.....................................................................................................................................................5
Course Tag...............................................................................................................................................5
Course Scores..........................................................................................................................................6
Skills and Skill Dictionary.........................................................................................................................6
Payments.................................................................................................................................................6
Course RCH Score Calculation..................................................................................................................7
Profile Tag Score Calculation (System Auto Tag Endorsement).............................................................11
Billing Process........................................................................................................................................12
Instructor Course Transaction Processing.............................................................................................12
Payment Gateway Integration...............................................................................................................13
Job Posts................................................................................................................................................14
User Interface and basic flow definitions..................................................................................................14
User Registration...................................................................................................................................14
Home (My Profile Tab)...........................................................................................................................16
Payment Gateway Accounts..................................................................................................................17
Claim Course Material Fraud.................................................................................................................19
Message Exchange among the users.....................................................................................................19
Instructor’s Functionality.......................................................................................................................22
Candidate’s Functionality......................................................................................................................24
Recruiter’s Functionality........................................................................................................................35
Administrator’s Functionality................................................................................................................48

Basic Concepts

Initial Assumptions

1. We have 4 roles: ADMIN, INSTRUCTOR, CANDIDATE and RECRUITER. Dashboard is the general default
view for each guest which does not provide access to the content, but provides general view of the
services.
2. Each participant can take any combination of the roles above.
3. Roles are defined with different tabs after user login; based on the preferences we can define the
default tab.
4. User registration and user management will be managed thru the site.
5. Candidates receive preview of the materials for free out of the box (if provided by the instructor). Also
some of the exam questions are available for free. The remaining materials as well as the full exam are
paid (or free) in the following manner:

a) Free
b) Fixed Cost (as defined by 6 –b)
c) Pay in advance for a fee of a nominal fee of X (this is related with 6-c, i.e. revenue sharing)
d) Pay upon hire for a fee of Z=Y*X which is significantly higher than X, the sum paid upon hire
is calculated as sum of all pending Z sums (related with 6-c, i.e. revenue sharing).
e) Progressive cost with each sequential exam.

6. Instructors will provide instruction materials as well exams based on the following fee structure:

a) Free

b) Fixed Cost (must be paid by each candidate with each exam)

c) Revenue sharing

7. Recruiters will provide monthly, quarterly or yearly fee. Recruiters will take a discount if they tell us
they hired a candidate.

8. The content upload process consist of:

a) Instructor creates the Course entity (name, description, category, tags, commercial term etc.).

b) Upload material and test with 2 or 3 file upload fields

c) Submit the Course (category, tags, material and test) for approval

d) The administrator will review the content for decency and validated based on the category
(smart admin)
Commercial Terms
The system shall define the following Commercial Term types:

ID=0, FREE (used by Instructors when specifying the Course’s Commercial Term and Candidates when
taking the Course)

ID=1, FIXED_COST (used by Instructors when specifying the Course’s Commercial Term and Candidates
when paying for the Course)

ID=2, REVENUE_SHARING (used by Instructors when specifying the Course’s Commercial Term)

ID=3, NOMINAL_FEE (used by Candidates when paying for a Course or additional Exam(s))

ID=4, PAY_UPON_HIRE (used by Candidates when paying for a Course or additional Exam(s))

ID=5, RECRUITER_L1_MONTHLY (used by Recruiters for 1 month subscription for Basic system access)

ID=6, RECRUITER_L1_QUARTERLY (used by Recruiters for 3 month subscription for Basic system access)

ID=7, RECRUITER_L1_YEARLY (used by Recruiters for 1 year subscription for Basic system access)

ID=8, RECRUITER_L2_MONHTLY (used by Recruiters for 1 month subscription for Intermediate system
access)

ID=9, RECRUITER_L2_QUARTERLY (used by Recruiters for 3 month subscription for Intermediate


system access)

ID=10, RECRUITER_L2_YEARLY (used by Recruiters for 1 year subscription for Intermediate system
access)

ID=11 RECRUITER_L3_MONTHLY (used by Recruiters for 1 month subscription for Advanced system
access)

ID=12, RECRUITER_L3_QUARTERLY (used by Recruiters for 3 month subscription for Advanced system
access)

ID=13, RECRUITER_L3_YEARLY (used by Recruiters for 1 year subscription for Advanced system access)

ID=14 RECRUITER_L4_MONTHLY (used by Recruiters for 1 month subscription for Complete system
access)

ID=15, RECRUITER_L4_QUARTERLY (used by Recruiters for 3 month subscription for Complete system
access)

ID=16, RECRUITER_L4_YEARLY (used by Recruiters for 1 year subscription for Complete system access)

ID=17, CANDIDATE_LOCK_PARTIAL (used by Candidates in order to revoke System rights to share exam
related information with Advanced and Complete Recruiters for Courses marked with status PARTIAL)
System User
The System has its own user that will represent the System itself whenever an identity is required
(payments System for example). This user is automatically created upon system bootstrap, has ID=0 and
can’t be deleted.

Company Profile
Company Profile is RCH entity that groups several Recruiters. Each Company Profile has the following
attributes:

 Name
 Code (UUID)
 Discount (decimal number between 0 and 1 (percent) for Recruiter level subscription cost)
 Representative email

When the Company Profile is created by the Administrator the UUID Code is generated randomly by
the RCH system. En email is sent to the Company’s representative containing the Company attributes:
Name, Code, Discount and Representative E-Mail.

The Company representative will share the Code with its Recruiters. This is verbal, i.e. out of band
communication.

Each Recruiter on his profile can claim relationship with the Company Profile by entering the following
Company Profile info that must match (case sensitive):

 The Name
 The Code

If the parameters entered match those saved in the database, the Recruiter will be associated with the
Company Profile. An Email shall be sent after that to the Company representative with notification
containing information about the Recruiter that “joined” the Company. After that moment, each cost for
Recruiter subscription shall be decreased by the Company Profile associated discount.

Course Category
The Course Category types are defined by the system. The Course Category shall be a global point of
interest like: Java, .NET, Mobile, Tibco etc.

Tag (Topic)
Each Tag is independent from the Course Category. Tags can be attached on each Course no matter of
its category (for example the XML tag can be attached on Course having category Java, as well as on
Course having Category .NET). Each tag is something that describes the content. The number of tags
defined in the system can be very large and we shall always use autocomplete fields for choosing
particular tag. When we search by Tags (Topics), the system shall consider all of them grouped by logical
AND (the Course shall have tag T1 and T2 and T3).

Context
The Context is environmental description for entities like Course, Job Post. In other words some Course
or Job Post can be related to different environmental contexts: Engineering, IT, Telecom etc. One or
multiple Contexts can be attached to each Course or Job Post. Context shall be taken into account when
searching for Courses and Candidates, as well as Job Posts.

Course
The Course is the central point in the whole system. Each Course defines metadata for its name,
description, tags, category etc.

For each Course the system collects statistical metadata defined as follows:

1. Number of Candidate Views: how many times candidates have viewed the course material
(preview or the complete material).
2. Number of Recruiter Views: how many times recruiters have viewed the course material
(preview or the complete material).
3. Candidate Favored: how many times candidates have favored the course material (preview or
the complete material) - Liking functionality
4. Recruiter Favored: how many times recruiters have favored the course material (preview or the
complete material) – Liking functionality
5. Candidate Average Rating: Average rating of the candidates that have taken the course
6. Recruiter Average Rating: Average rating of the recruiters
7. Aggregate Exam Score: Average score for the all candidates that have passed the exam
8. Total Hires: The number of the Candidate confirmed Hires
9. System Verified: This is a flag set by the system in the case the system engages third party
expert to verify the Course’s content.
10. RCH Score: The “magic” formula calculated by the system

Course Tag
Each Course can be associated with multiple tags. That way the Course can be searched by tags. For
each Course-Tag association we keep the number of endorsements for that Tag for that Course. The
Candidates that have taken the course (paid for that course) can endorse the Tag for that Course. The
system calculates the weighted endorsement for each Tag under the whole Course context (all tags).
The following rules apply:

1. All candidates can endorse courses.


2. All candidates have equal weighting in the value of their endorsement.
3. The instructor has an equal weighting as any other candidate, but the instructor endorsement is
treated as an individual endorsement well.

An Example:

Let we have a Course in the Category Java having the following tags: Spring, Web and Hibernate.

The Candidate Marjan has taken the Course and endorsed the tags Spring and Web for the Course.

The Candidate Jovica has taken the Course and endorsed the tags Web and Hibernate for the Course.

The total number of users that have endorsed the Course is 3: Instructor+Marjan+Jovica
The Tag endorsement counts and weightings for the Course are:

Tag Name Tag Endorsement Count Tag Endorsement Weighting


Spring 2 0.66 (2/3=2/N)
Web 3 1 (3/3=3/MAX)
Hibernate 2 0.66 (2/3=2/MAX)

Initially when the Course is created each Course Tag shall have weighting of 1.

Course Scores
Each Course has aggregate exam score associated. It is an average from all COMPLETED (PASSED or
FAILED) courses by ALL candidates.

Each Candidate Course has associated aggregate exam score too. It is calculated as weighted average
(exponential attenuation) from all PASSED exams by that Candidate for that Course.

Figure 1. Course Exam Average

Skills and Skill Dictionary


User on their profiles can import their Skills from LinkedIn or they can add or edit these Skills on their
edit profile page.

Each Skill shall be converted into uppercase before it is used in RCH. Each Skill shall be inserted into the
Skill table for endorsement and grading purposes described further in this document. Before saving the
Skills we shall query the Dictionary if the skills exist. The non-existent skills shall be saved into the
Dictionary.

Note: There is concurrency issues when saving the same Skills into the Dictionary from multiple threads.
The application shall handle the concurrency by catching unique name constraint exceptions.

Payments
Each payment is registered into the table Payment. User to User payments are NOT allowed. The
payments are always from SYSTEM to Profile and Profile to SYSTEM.
The payment flow has the following steps:

1. Payment record is registered into the Payment table with status INITIALIZED.
2. The User is redirected to the Payment Gateway. The Reference Id sent to the external Payment
Gateway is underscore concatenation of the following information saved into the Payment
table:
a. Reference Id Type
b. Reference Id
c. Created On (timestamp)
3. The User pays the amount specified and the Payment Gateway redirects the User to the
application.
4. The incoming external reference id string is parsed into its constituting parts that are further
used to find appropriate pending payment if any. The payment is marked as completed.

The Reference Id Type can be:

 CC (Candidate Course): Used for FIXED_COST and NOMINAL_FEE immediate payments of


Candidate Course (+the first Candidate Exam along with the course).
 CE (Candidate Exam): Used for FIXED_COST and NOMINAL_FEE immediate payments of
additional Candidate Exams.
 PUH (Pay Upon Hire): Used for Pay upon Hire payments for ALL pending Candidate Courses and
Exams.
 CLP: (Candidate Lock Partial) Used by Candidates to revoke the System right to share Exam
details for Candidate Course having visibility status of PARTIAL.
 RL_1_M, RL_2_M, RL_3_M, RL_4_M, RL_1_Q, RL_2_Q, RL_3_Q, RL_4_Q, RL_1_Y, RL_2_Y,
RL_3_Y, RL_4_Y: Used for Recruiter payments.
 IC (Instructor Course): Used when the SYSTEM pays the Instructor based on the accrued amount
in particular Instructor Course.

The Reference Id is always system generated UUID. In Candidate payments new Reference Id is
generated for each payment. For SYSTEM to Instructor payments, the Reference Id is the same for
particular Instructor Course (however the combination Reference Id Type+Reference Id+Created On is
always unique). In the case or CLP payment the Reference_Id equals to the Candidate Course
partialLockedReferenceId which is UUID too.

Course RCH Score Calculation


Each Course has associated runtime characteristics:

1. Candidate Views: (unbounded integer number)


2. Recruiter Views: (unbounded integer number)
3. Candidate Favored: (unbounded integer number)
4. Recruiter Favored: (unbounded integer number)
5. Candidate Rating Average: (double number from 0 to 5)
6. Recruiter Rating Average: (double number from 0 to 5)
7. Aggregate Exam Score: (double number from 1 to 5)
8. Total Hires: (unbounded integer number)
9. System Verified: (0 or 1)
The Course entity is not updated with each event that will change the state of the attributes above.
Rather an aggregator will collect these attributes for a specified time period and update the Course with
a single callback.

One of the key attributes in the Course table is the attribute rchScore. This factor is the key when
calculating REVENUE SHARING cost of particular Course.

The attribute rchScore is periodically calculated (once a day for example).

The rchScore can NOT be calculated only with the attributes of the Course itself. Rather, the calculation
of per Course rchScore requires scanning and gathering information from all other Courses in the
system.

The algorithm is:


min_candidate_views=0; max_candidate_views=0;

min_recruiter_views=0; max_recruiter_views=0;

min_candidate_favored=0; max_candidate_favored=0;

min_recruiter_favored=0; max_recruiter_favored=0;

min_total_hires=0; max_total_hires=0;

#The first full scan will find min-max ranges for integer valued attributes

FOR EACH Course course DO

IF course.candidate_views>max_candidate_views THEN

max_candidate_views=course.candidate_views

END_IF

IF course.candidate_views<min_candidate_views THEN

min_candidate_views=course.candidate_views

END_IF

IF course.recruiter_views>max_recruiter_views THEN

max_recruiter_views=course.recruiter_views

END_IF

IF course.recruter_views<min_recruiter_views THEN

min_recruiter_views=course.recruiter_views

END_IF

IF course.candidate_favored>max_candidate_favored THEN

max_candidate_favored=course.candidate_favored

END_IF

IF course.candidate_favored<min_candidate_favored THEN
min_candidate_favored=course.candidate_favored

END_IF

IF course.recruiter_favored>max_recruiter_favored THEN

max_recruiter_favored=course.recruiter_favored

END_IF

IF course.recruter_favored<min_recruiter_favored THEN

min_recruiter_favored=course.recruiter_favored

END_IF

IF course.total_hires>max_total_hires THEN

max_total_hires=course.total_hires

END_IF

IF course.total_hires<min_total_hires THEN

min_total_hires=course.total_hires

END_IF

END FOR

#The second full scan run calculates rchScore for each Course

FOR EACH Course course DO

norm_candidate_views=
(course.candidate_views-min_candidate_views)/
(max_candidate_views-min_candidate_views)

norm_recruiter_views=
(course.recruiter_views-min_recruiter_views)/
(max_recruiter_views-min_recruiter_views)

norm_candidate_favored=
(course.candidate_favored-min_candidate_favored)/
(max_candidate_favored-min_candidate_favored)

norm_recruiter_favored=
(course.recruiter_favored-min_recruiter_favored)/
(max_recruiter_favored-min_recruiter_favored)

norm_total_hires=
(course.total_hires-min_total_hires)/
(max_total_hires-min_total_hires)

rchScore=

k1 * norm_candidate_views +

k2 * norm_recruiter_views +
k3 * norm_candidate_favored +

k4 * norm_recruiter_favored +

k5 * course.candidateRatingAverage/5 +

k6 * course.recruiterRatingAverage/5 +

k7 * course.aggregateExamScore +

k8 * norm_total_hires +

k9 * system_verified

(k1 + k2 + k3 +k4 + k5 + k6 + k7 + k8 + k9)

END FOR

In the case of relational SQL database both scans can be sublimated on 2 SQL statements.

The coefficients k1, k2, k3, k4, k5, k6, k7, k8, k9 are system global parameters.

If we say that recruiters are more competent than candidates and their role is more important in the
system and if we agree that rating is more significant than favoring, favoring is more significant than
viewing than one possible choice of the coefficients is:
k1=1 (candidate views)

k2=2 (recruiter views)

k3=2(candidate favored)

k4=3 (recruiter favored)

k5=3 (candidate rating)

k6=4 (recruiter rating)

k7=3 (aggregate exam score)

k8=5 (total hires)

k9=5 (system verified)

Once the rchScore is calculated, the cost for Courses having REVENUE SHARING Commercial Term is set
by the system (for that day). The calculation is based on the amount and amountDelta of the
NOMINAL_FEE Commercial Term:

cost= (amount-amountDelta)+rchScore*2 * amountDelta

Example

amount=50

amountDelta=49
If rchScore=0 then cost=1

If rchScore=0.3 then cost=30.4

If rchScore=0.7 then cost=68.6

If rchScore=1 then cost=99

Profile Tag Score Calculation (System Auto Tag Endorsement)


Each Candidate takes Courses. Each Course has associated Tags. If the Candidate has passed the course,
the Course tags take contribution in the Candidate’s Tag Score.

The contribution per Tag is based on the following parameters:

1. Course rchScore
2. Course Tag endorsementWeighting
3. Candidate Course aggregateExamScore

Per Tag contribution for particular Candidate (Profile) is:


tagScoreMap=[]

tagRchNormalizatior=[]

For Each Passed CandidateCourse for Candidate

For Each Tag in Course

profileTagScore=tagScoreMap[Tag]

rchNormalizator= tagRchNormalizator[Tag]

profileTagScore = profileTagScore +

+Course.rchScore *

CourseTag.endorsementWeighting *

CandidateCource.aggregateExamScore

rchNormalizator=rchNormalizator+Course.rchScore

tagScoreMap[Tag]=profileTagScore

tagRchNormalizator[Tag]=rchNormalizator

End For Each Tag

End For Each Passed CandidateCourse

For Each Tag in rchTagMap

tagScore=rchTagMap[Tag]

rchNormalizator=rchNormalizatorMap[Tag]

tagScore=tagScore/rchNormalizator

End For Each Tag


The system shall process Candidate Course and collect them per Profile in batches of 100 (or similar
number). For each batch of profile Candidate Courses join fetch the rest of information required
(candidate course->course->course tag->tag)

Most Relevant Tags for Candidate are the first 10 tags with highest scores after the calculation. In the
table CandidateTagScore we shall keep only the Most Relevant Tags for particular user, i.e. the rest of
them shall be deleted from the database. These tags are shown on the User’s profile tabs under the
label System Graded Tags.

The calculation job shall run on a daily basis or whatever period configured in the system.

Billing Process
Once in a month the system shall execute the Billing process. The Billing process shall:

 Process all Pay Upon Hire pending payments: When the Candidate is hired with concrete hiring
date, there is an interval of 30 days for hire/dispute resolution. If the status of the hire is HIRED
or CONFIRMED after that period, the next billing process shall process for that candidate all
pending payments with date less or equal to the hiring date. For all pending payments the
system will auto deduct the total amount from the Candidate’s account and will generate the
same payment info as in the case when Candidate pays at his will. The status of the Hire after
that shall be set to BILLED which is final state (In the case of Candidate Hire Dispute, the
Administrator will resolve the issue by transition HIRED =>CONFIRMED or
HIRED=>BOOKMARKED)
 Generate credit record into the table InstructorCourseTransaction table for each
InstructorCourse having amount greater than 0. The columns amount and payment in the table
InstructorCourseTransaction initially will be null. After the transaction record is processed by
scheduled batch process, these columns will be filled with the Payment generated and the
amount transferred to the Instructor).

Each Billing process has a record in the table Billing. There is one record for each month for each year.
The status of the billing record will be INITIALIZED until all the operations, Pay Upon Hire processing and
credit record generation, has been processed for that month. If the current schedule of the billing
process has crashed, the next scheduler (after one hour for example) will find the last committed
(processed) state in the database. In particular:

 For Pay Upon Hire processing we have always information based on the Hire status (BILLED or
HIRED or CONFIRMED) and the hire date.
 For credit record generation we can always find the last instructorCourseId for
InstructorCourseTransaction credit record created that month and continue from that point
further.

When everything is processed, the billing record shall go into the state COMPLETED.

Instructor Course Transaction Processing


There is a contention if multiple actors change the InstructorCourse’s accruedAmount field
simultaneously. Read more about it in the Technical Specification document, section InstructorCourse
Updates.
We shall avoid contention by writing all the “commands” against InstructorCourse’s accruedAmount
into separate InstructorCourseTransaction table.

This table is processed periodically by scheduled process. This process will fetch unprocessed records,
ordered by id. Each record shall be processed the following way:

 For DEBIT records, the InstructorCourse’s accruedAmount shall be increased by the specified
amount
 For CREDIT records the system shall:
o Generate Payment record from SYSTEM to INSTRUCTOR with
amount==accruedAmount and status COMPLETED and execute the Payment, i.e. debit
that amount in the Instructor’s bank account. After that, we shall update the columns
amount and payment in the InstructorCourseTransaction credit record with
appropriate values found in the Payment record
o Reset InstructorCourse’s accruedAmount to zero (0).
o All of this processing must be inside database transaction where interaction with the
Payment gateway is last, i.e. in the case of remote payment system failure we can roll
back the local transaction.

Each DEBIT or CREDIT record processed shall be marked as COMPLETED and this action is part of the
database transaction that corresponds to that record processing.

Payment Gateway Integration


RecruitmentCH shall integrate with external Payment Gateway. The system shall support at least
PayPal. If the system supports several payment gateways, then user shall be allowed to create multiple
Payment Gateway Accounts if needed.

The Payment Gateway interface abstraction shall support the following operations:

 Verify User Existence: check if the user with his email, first name and last name exists in the
payment gateway external system.
 Generate Preapproval Key: the user shall be able to setup preapproval key so the system can
automatically charge the user (Pay Upon Hire scenario for hired user). The preapproval key shall
be valid for N automatic payments where each payment transaction shall not exceed the
preapproved maximum amount of M.
 Charge User: Automatic charge of the user (Candidate) in the case he was hired and there are
pending Pay Upon Hire payments.
 Pay to User: The system shall be able to transfer money to the user (Instructor). This transfer is
once in a month, i.e. for each Billing process cycle.
 Interactive Digital Goods Payment: support flow for all immediate payments by candidates and
recruiters where Payment Gateway shall provide success and cancel redirect URL as well process
and verify the returned results with the external gateway in order to ensure the payment was
successfully completed. The operations involved here are:
o Setup Digital Goods Payment
o Generate Digital Goods Payments Redirect URL
o Finish Digital Goods Payment
For more info and details regarding Pay Pal Integration, see the sample POC project located at:

https://confluence/confluence/display/Java/PayPal+Integration

Job Posts
Recruiters can submit Job Posts. Each Job Post is associated with Course Category, Tags, Contexts, City,
States etc. For Jobs in SUBMITTED state the system will associate related Courses. RCH defines use cases
where Candidates can reach the Job Posts from associated Courses, search for Job Posts etc. Candidates
can favor and rate each job post.

User Interface and basic flow definitions

User Registration
We shall allow the users to register themselves. On the application default (landing page) we shall have
a registration form (use similar look and feel as in existing Social Networks like Facebook or LinkedIn).
The form shall contain the following info:

1. Email Address
2. First Name
3. Last Name
4. Location
a. State
b. City
5. Roles: Instructor, Candidate, Recruiter
6. Password
7. Confirm Password

The User can press the button Join Now. When this button is clicked:

1. The System shall generate User record and Profile record. The User passwords in the
database must be salted and hashed. The initial status of the User is 0 (CREATED). The
system also generates random confirmation_code.
2. The System shall send account confirmation e-mail to the user (use SSL to the mail server).
The confirmation link must contain the following parameters:
a. confirmation_code
b. confirmation_timestamp (now)
c. confirmation_token: this token is HASH(confirmation_timestamp || User Id ||
Email Address || First Name || Last Name || Location State|| Location City)

When the user receives the account confirmation mail and clicks on the confirmation link, the System
shall:

1. Check if the confirmation_token received matches the info for that user in the database. The
confirmation_timestamp received shall not be older 1 day.
a. If the confirmation is ok, the User status shall set to 1: (CONFIRMED), the User’s
Security Context shall be populated as he was logged through login form and he shall be
redirected to the My Profile page.
b. If the confirmation is not ok, the user shall be redirected to the default, landing page
with appropriate error message that states that user account can’t be confirmed.
2. In both cases the confirmation_code in the User record shall be reset to null. This is extremely
important because confirmation_code MUST be used only once.

If the confirmation mail was somehow lost, we shall allow the user to ask the System for another
confirmation mail. We need another link on the default, landing page saying: Account Confirmation.
When the user presses this link we shall present him another page where he can enter his E-mail and
press the button Send Confirmation E-Mail. The system shall:

1. Find the user for that E-Mail in the user table.


2. Generate and save random confirmation_code in the User’s record.
3. Send account confirmation email to the user (the flow explained above).

LinkedIn Integration

The user shall be able to register with his LinkedIn account too. On the default landing page we shall also
have a link Join With Your LinkedIn Account. If the user clicks on that link we shall execute the flow as
described at:

https://confluence/confluence/display/Java/LinkedIn+Integration

When the user is redirected back to our application and the OAuth2 authentication has been successful
the system shall:

1. Query the user’s LinkedIn profile for attributes like: first name, last name, e-mail, picture url,
positions, skills, educations, certifications, languages, interests etc.
2. Generate User and Profile records based on that info. From the skills, educations, positions and
the rest of the LinkedIn information retrieved generate and save resume in html format (JSON-
>XML->XSLT->HTML). Note that the User account status is 1, i.e. in this case we don’t need
further account information because we trust LinkedIn that the e-mail received is a correct one.
Populate the user’s Security Context as if he was logged through the login form.
3. Redirect the user to the Create Password page where he must enter his Password for the first
time.
4. After Create Password page the user shall land on the My Profile page where we can add
(change) his Roles in the system.

Lost Password Functionality

The application shall have lost password functionality. On the default landing page we shall have link:
Forgot Password. When the user clicks on that link we shall present him a page where he can enter his
e-mail and press on the button Reset Password. If the user clicks on the Reset Password button, the
system shall:

1. Generate new confirmation_code in the User’s record


2. Generate and send reset password mail to the user (use SSL to the mail server). The reset mail
link in the mail shall have the following parameters:
a. confirmation_code
b. confirmation_timestamp
c. confirmation_token: this token is HASH(confirmation_timestamp || User Id || Email
Address || First Name || Last Name || Location State|| Location City)

When the user receives the mail and clicks on the link, the system shall:

1. Check if the confirmation_timestamp is not older than one day and confirmation_token
matches the User’s info in the table
2. If they user’s data matches, the User’s Security Context holder shall be populated as if the User
was logged thru the login form. The confirmation_code shall be reset to null (one time use, one
time password).
3. The user shall be redirected to the Change Password page (the Old password shall not be
present in this UI because the user does not know it).

Home (My Profile Tab)


My Profile is a common tab for all user roles. This tab shows the info related to the user like: name,
email, photo, skills, credentials, etc.

Change Password

The user shall be able to change his password. In order to change his password, he must enter his Old
Password too.

Other User Attributes

The user shall be able to change his:

1. First Name
2. Last Name
3. Location
4. Willing to Travel (percentage)
5. Photo
6. Roles
7. Resume
8. Video presentation
9. Password (this shall be separate screen).

The user shall be also capable to upload his photo as well as to take a photo using his Web camera.

The user can always:

 Resynchronize his resume by pressing a link Synchronize Resume with LinkedIn. The
data will be fetched and new XML resume shall be generated and stored in the storage
service. We are going to use the XML format used by LinkedIn for that purpose.
 The user shall be able to create and edit his resume and store it again in our Storage
Service.

Each user shall be able to upload his introductory self-presentation short video.

All profile related data (photo, resume, video…) shall be contained into per profile storage folder having
a unique id.
User shall be able to upload his video resume and the other users shall be able to see that video on his
profile.

The system won’t encode the uploaded video. Instead, the system shall save it in the uploaded format
and size. It must be into mp4 format ( or ???webm) format (put these formats into property file). The
system shall restrict the size of the uploaded video. The cutoff size shall be specified into properties file.
For example, we can start with restriction of 100 MB per video. It should be enough for low resolution 1
minute presentation of the user.

On the user’s profile page, the other users shall be able to watch the video (if it exists) by pressing the
link: Video Resume, below their photo. We shall present the video into lightbox popup with HTML5
video tag.

The Profile Page shall enlist all of the roles the user has. Besides the basic roles, in the case of Recruiters,
the current subscription level (dynamic role) shall be visible too. This info on the profile page shall be
visible only for the user owing that profile, not for the rest of the world.

For an example how to progressively download video from JAX-RS service, see the services located at
the following location:

https://confluence/confluence/display/Java/Common+Technologies

https://confluence/confluence/download/attachments/22478873/hdfs-file-storage.zip

For Recruiters Only:

Users having the role Recruiter associated shall be able to optionally associate themselves with a
Company Profile.

The user profile Edit page shall contain a link Associate with Company Profile. By pressing on that link, a
window shall popup where the user can enter:

 Company Name (case sensitive)


 Company Code

The entered Name and Code shall be sent to the server in order to find a match with such company
profile. If the Company Profile with that Name and Code exists, the Recruiter shall be associated with
the Company Profile and from that point further he will have subscription discounts (for the payments
after that).

Whenever a Recruiter is associated with a Company Profile a notification email shall be sent to the
Company Representative.

Important: Send the email only after the transaction was committed successfully. In order to accomplish
start from service method that is not transactional, call transactional save method and send the mail
after that through the notification service.
Payment Gateway Accounts
The user shall be able to create, edit and delete payment gateway accounts. This page shall be a sub
menu item in the Profile tab. In the first phase we are dealing only with Pay Pal, so only one payment
gateway account per user is expected. The user shall not be able to create multiple payment gateway
accounts of the same type. If the system supports multiple types of payment gateways and if the user
has created multiple payment gateway accounts, only one has to be a default one.

The user has to enter the following info for each payment gateway account:

 Gateway Account Type== PAY PAL (chose the type only when creating, when editing it is read
only).
 Email
 First Name
 Last Name
 Default ==yes

Whenever user saves the payment gateway account, it must be verified with the Payment Gateway
service. Only verified payment gateway accounts shall be used in all system transactions.

The payment gateway accounts are listed into accordions containing the following information:

 Type
 Email
 First Name
 Last Name
 Existence Verified
 Default
 Max Number of Preapproved Payments
 Max Amount per Preapproved Payment

The account related area shall contain a link: Generate Preapproval Key. When the user clicks that link a
popup will show where user can chose the following parameters:

Maximum Number of Preapproved Payments: this is drop down with options 1, 2, 3, 4, 5.

Maximum Amount per Preapproved Payment: this is drop down with options $500, $1000, $2000,
$3000, $5000.

The popup shall contain a button with name Generate. When the user clicks on this button the form
shall be submitted regularly (not Ajax) and the system will execute the following steps:

1. Generate local preaprovalKeyReferenceId.


2. The Payment Gateway shall generate preapprovalKey.
3. The fields in the database, preapprovalKeyReferenceId, prepprovalKey,
maxNumberOfPreapprovedPayments, maxAmountPerPreapprovedPayment shall be persisted
into the Payment Gateway Account and the preapprovalVerified shall be set to false.
4. The user is redirected to the external Payment Gateway where he shall confirm or deny the
payments requested.
5. The Payment Gateway will redirect the user to success or cancel URL, depending if the user has
confirmed or denied the payments.
6. In the case of cancel action, the system will find the related account by the
preapprovalKeyReferenceId returned in the URL and delete all preapproval related fields in that
account. The user is redirected to the Payment Gateway Accounts page after that.
7. In the case of success action, the system will find the related account by the
preapprovalKeyReferenceId returned in the URL and set the account’s field
preapprovalVerified to true. The user is redirected to the Payment Gateway Accounts page
after that.

The Billing process shall automatically charge users for Pay Upon Hire use case ONLY if:

 preapprovalKey is not null


 preapprovalVerified ==true
 maxNumberOfPreapprovedPayments>0
 maxAmountPerPreapprovedPayment< the sum to be charged from the user payment
gateway account

Whenever preapprovalKey is used and the transaction has successfully completed, the field
maxNumberOfPreapprovedPayments shall decrease by 1 (down to 0).

Claim Course Material Fraud


Every registered user, no matter of his role shall be able to claim that some course material is fraudulent
or it infringes someone else's IP right. The link to this page shall be the last one in each role’s menu. By
pressing on that link the user shall be redirected to a page where he can choose Course from Ajax based
lookup drop down. Besides the Course chosen, the user shall enter Claim Description. That form will be
submitted to the backend that will send an email to the configured administrator users in the system.

Note that we don’t keep persistent history for this claim notifications. The system just sends an email to
the administrators having the following information:

1. The email, first name and the last name of the user which is reporting for fraudulent courses.
2. The Id of the Course considered fraudulent
3. The Name of the Course considered fraudulent
4. The claim description

For user roles like candidate, recruiter and administrator that have possibility to search for courses we
shall provide shortcut to the Claim Course Material Fraud. When the user searches for Courses we have
a list of Courses matching the criteria. In the Course related popup we need to place a link to the Claim
Course Material Fraud page. The link shall contain the Course Id parameter that allow the system to
partially fill some of the fields in the Claim submission form.

Message Exchange among the users


In RCH only Administrator can see the emails for the other users. The rest of the system users can’t see
each other e-mails. However, they can communicate among themselves. In particular:
1. Candidate can initiate message conversation with Recruiter on the Job Post details. Next to the
Recruiter’s name we shall show an e-mail link (button).

2. Recruiter can initiate message conversation with each bookmarked Candidate. In the last, action,
column we need an e-mail link (button) for each bookmarked (or hired) candidate.

By pressing on the e-mail link a popup window with title New Message will appear where user can see
or enter the following information:

1. To: The message receiver (read-only field from the receiver’s first and last name)
2. Send me a copy: Send copy of the message to the sender
3. Subject: the subject of the message
4. Content: the text of the message

On the server side each New Message will be assigned brand new Conversation Id which is system
generated UUID. The concept of Conversation Id along with the message creation time is crucial for
maintaining and presenting conversation threads.

MessageContent
Message
+id: long
+id: long +conversationId: string
+from: Profile +subject: string
+to: Profile +content: string
+messageContent: Message
+folder: string[0..1]

Figure 2. Messaging Model

Candidates and Recruiters can access their associated messages by clicking on the e-mail link (button)
located in the top bar, on the left from the logged in user name.

This link will take the user to the My Messages page. Note: This page is not accessible thru the
dropdown menu.

The page shall contain 2 tabs: Inbox and Outbox.

The first one, Inbox, shall enlist all messages where the current user appears in the To field. The
messages shall be presented into server side paginated Ajax table. By default the messages are ordered
by the message creation time in descending order. The table will have the following columns:

1. From
2. Subject
3. Received (message creation time)

The table shall be sortable by all of the above columns. The Inbox shall be searchable by all of the
columns in the table (From, Subject, >= Received).
The second tab, Outbox, shall enlist all messages where the current user appears in the From field. The
messages shall be presented into server side paginated Ajax table. By default the messages are ordered
by the message creation time, descending. The table will have the following columns:

1. To
2. Subject
3. Sent (message creation time)

The table shall be sortable by all of the above columns. . The Outbox shall be searchable by all of the
columns in the table (From, Subject, >= Sent).

The search filter shall be common for both folders: Inbox and Outbox. The From/To and Received/Sent
labels shall change along with the active tab.

In both of the tables defined, the user can click on particular message that triggers window popup. The
content of this window does NOT consist of the clicked message only. Rather, the window shall show
the Conversation Thread that particular message is bound to. This window shall include all messages
with the same Conversation Id (that equals to the Conversation Id of the clicked message) where
current user appears in the From or To fields. The message list is sorted by the message creation time in
descending order. Despite the fact that this window shows the whole conversation thread, initially the
window shall be scrolled to the message clicked.
Figure 3. Message Conversation Thread

User can reply to the conversation thread by pressing the button Reply located on the top-right of the
window. The Reply Message window shall appear and that window is the same with the New Message
window. Application shall automatically add “Re:” to the previous message subject (the one located at
the top of the conversation thread). The user can press Send or Cancel in the Reply Message window. If
the message has been successfully sent, the Conversation Thread shall be updated accordingly (put the
last reply message at the top). The server side processing logic for reply messages shall re-use the
conversation id, i.e. new conversation id is not generated for Reply messages.

Instructor’s Functionality
The user interface tab Instructor contains the functionality related to the Instructor role.

When the instructor logs in, the tab Instructor shall be visible.

The Instructor tab shall contain the following pages:

 My Courses: the courses created by the Instructor


 Revenue: lists the payments those target is the Instructor (referenceIdType IC)
My Courses

By default we shall present the courses created in the last 3 months (date descending order). However
we will provide search criteria to find all Instructor’s courses. The search functionality shall contain the
following filter criteria:

Course Name, Course Category, State, Creation Date etc.

Each course shall be presented with expand/collapse panel (+/-). The user interface shall allow multiple
courses to be expanded at once.

The page shall provide a button or link for creating a new course, at the top and the bottom of the page.

When creating new course, the user interface shall provide two-step wizard.

In the first step the Instructor shall provide the metadata for the course and choose appropriate
Commercial Term, Course Category, Tags etc.

In the second step, the Instructor can upload the material, preview (which is optional) and the exam
itself. After the content is uploaded, the Instructor shall press the buttons: Save or Submit. After the
button is pressed, the system shall redirect the Instructor to the list of courses.

Each course can be into the following states: CREATED, EDITED, SUBMITTED, APPROVED, REJECTED,
DEPRECATED.

Each course panel shall contain buttons for specific actions: EDIT, SUBMIT, DEPRECATE.

Each Course can be edited only if it is in the states CREATED, EDITED, REJECTED, And DEPRECATED. In
the state DEPRECATED the Instructor can ONLY change the description of the course.

For each state transition the Instructor or Administrator can provide additional comment which will be
visible using lazy loading if required.

State transitions are as follows:


CREATED

INSTRUCTOR
INSTRUCTOR

INSTRUCTOR
EDITED SUBMITTED

ADMINISTRATOR
INSTRUCTOR ADMINISTRATOR

REJECTED
INSTRUCTOR APPROVED

INSTRUCTOR
SYSTEM

DEPRECATED
SYSTEM

SYSTEM_DEPRECATED

Figure 4. Course State Transitions

Note: In the state SUBMITTED, the Administrator shall not be allowed to reject the Course if the Course
has been approved at least once. This is necessary condition because once the Course goes in the public
we have no right to change the significant Course attributes like: Category, Tags, Material, Exam etc.

Create Course Details

The course creation process shall be 2 step Wizard.

In the first step, the Instructor fills the Course metadata like:

1. Name
2. Description
3. Category
4. Tags : Shall be Autocomplete list because of the large number of possible tags defined in the
system
5. Contexts: Shall be Autocomplete list because of the large number of possible contexts defined in
the system
6. Commercial Term (FREE, FIXED_COST, REVENUE_SHARING)
7. Price: for FIXED_COST the price is required, for REVENUE_SHARING the price is defined by the
system (The candidate will see NOMINAL_FEE which is calculated by the system and
PAY_UPON_HIRE which is defined and calculated by the system)
In the second step the Instructor shall be able to upload:

1. Material (pdf or video)


2. Preview Material (pdf or video): this is optional
3. Exam: An XML containing the Exam’s structure; the preview questions are marked as such in the
Exam definition

We shall have clone Course functionality.

Revenue

The Revenue page has 2 tabs: Payments and Pending Payments.

By default the Payments tab will show the realized payments for the last 3 months. Each monthly
revenue can be expanded in order to show per Course payments for that month.

We will have alternate view for the Revenue with initial list consisting of per Course payments
aggregation. Each Revenue per Course can be further expanded in order to show per month payments
for that Course. (Note: use existing control for the view swap functionality if we can find such).

The Payments tab shall contain filtering capabilities that will allow the Instructor to change the date
time interval he is filtering for.

The Pending Payments tab shall enlist all pending per Course accrued amount from the last billing cycle
up to that moment. Instead of the Month/Year, the label shall read Next Billing Cycle Payment. For this
only section we shall enlist per Course accrued amount.

The user interface shall allow multiple expanded elements in one moment.

Candidate’s Functionality
The tab Candidate contains the functionality related to the Candidate role.

When the Candidate logs in, the tab Candidate shall be visible.

The Candidate tab shall contain the following pages:

 Search for Courses


 Search for Jobs
 My Courses: courses taken by the Candidate
 My Payments: lists the payments from the Candidate

Search for Courses

Search for Courses shall offer two types of searches: Basic Search and Advanced Search.

Accordingly the screen shall consists of tabbed pane with 2 tabs: Basic Search and Advanced Search.

The Basic Search tab is default one and will have only one input field with autocomplete functionality. In
this field the candidate shall be able to enter multiple space separated words. Autocomplete
functionality shall offer term filtered list constructed from the Topic, Context and Category names.
However, Candidate can enter free form word too.
http://jqueryui.com/autocomplete/#multiple-remote

The implementation on the server side shall be implemented with Full Text Search.

The search shall be an AJAX call that will return up to 500 results in JSON format. The returned results
shall fit into table with sortable columns and in-memory (browser) pagination.

The result shall include the default set of columns like Couse Name, Category etc.

The Advanced Search shall allow filtering and ordering criteria based on:

 Course Id
 Course Category
 Creation Date
 Tags with endorsement weighting above some threshold (logical AND among the tags)
 Contexts (logical OR among the contexts)
 Name
 Number of Candidate Views
 Number of Recruiter Views
 Number of Candidate Favored (Likes)
 Number of Recruiter Favored (Likes)
 Recruiter Average Rating
 Candidate Average Rating
 Aggregate Exam Score
 Total Hires
 System Verified
 RCH Factor
 Has Job Posts

The filtering and ordering have to be dynamically constructed in the user interface.

The Candidate can choose the filtering criteria from auto complete dropdown select list (Filter Course
By). When Candidate chooses particular criteria item from this dropdown list, the criteria “balloon” shall
enter the search area bellow. All Criteria chosen are in place editable.
Figure 5. Search for Courses

For example: the user can choose the following filtering and ordering criteria:

1. Category Java
2. Tag XML with Relevance Not Applicable (Courses tagged with XML any endorsement weight)
3. Average Recruiter Rating more than 2.5

The search shall be an AJAX call that will return up to 500 results in JSON format. The returned results
shall fit into table with sortable columns and in-memory (browser) pagination.

If Course Category is NOT included in the Search Filter, then Course Category MUST be a sortable
column in the results table.

If the search filter includes at least one Course Tag, then the result table MUST include a column with
name Tags Total Endorsement Weight and the results table shall be sorted by this column in descending
order (the most relevant courses at the top).

Default sort of the results table shall be by Cost, in descending order.

The Courses that have Job Posts associated shall be marked with Job Post icon in both of the table row
and Course details popup.

The Candidate shall be able to save his Course search queries into persistent store. One of the queries is
the Default one. The default query is always loaded when the search page has been opened. The rest of
saved queries have name chosen by the user. In particular the system shall implement the following
behavior:

 When the user fetches his queries of particular type (course, candidate, job post), if no query
exists the System shall:
o Generate a query with name 'System Default'
o Mark that query as 'defaultQuery'
o Save that query
o Return that query to the user
 In the User interface:
o The current query shall be highlighted in the drop down list of available queries
o The user shall be able to add new query
o The user shall be able to save the current query
o The user shall be able to delete each query which is NOT default one. If the current
query is the default one, the delete button shall be disabled (grayed)
o The user shall be able to delete the 'System Default' query if it is not default anymore
o The user shall be able to mark each query as default. Note that the service call shall set
all queries of that type as non-default and then mark the current as default
o If the current query is deleted (and this is not a default query), the next query to be
shown on the screen shall be the default none.

The same logic shall apply for Search for Courses queries, Search for Candidates queries and Search for
Jobs queries.

The buttons for query state manipulation: ‘add’ and ‘save’ shall reside in a button group. The buttons
‘delete’ and ‘make default’ shall reside next to each query in the query drop down menu.

When the Candidate clicks on the Course link in one of the table rows returned, a popup window shall
show the Course details along with links to the preview material if any, preview exam etc. The popup
window shall also have an indicator if the Course has associated job posts or not. The Candidate can
choose to take that course (if note taken before) by pressing the link: Take the Course which is a
beginning of a flow that starts on a new page (different page from the search page). That flow consists
of the following alternative paths:

1. If the Course is FREE the system will create the Candidate-Course with marker paid=true, the
first Candidate Exam with marker paid=true, association and redirects the Candidate to the My
Courses tab where the Course taken is listed first (it is the last one, descending ordering).
2. If the Course is not FREE but with commercial term of FIXED_COST or REVENUE_SHARING the
flow proceeds the following way:
a. If the Course has FIXED_COST:
i. The system generates REFERENCE_ID, create Candidate-Course association
having that REFERENCE_ID, create Candidate-Exam having that REFERENCE_ID,
creates Payment record with that REFERENCE_ID and Candidate is redirected to
the Payment Gateway. Note: If the Candidate-Course and Candidate-Exam
exist but are never paid (something wrong happened during the payment
processes), reuse the Candidate-Course and Candidate–Exam entity and update
them with new REFERENCE_ID and cost.
ii. The Candidate pays the required amount in the Payment Gateway.
iii. The Payment Gateway redirects the Candidate to our application where the
Payment (identified by the REFERENCE_ID) is completed. The Candidate Course
and the first Course Exam are marked as paid as well.
iv. The amount paid for the Course is added to the InstructorCourse’s
accruedAmount:
accruedAmount=accruedAmount + amount * (1- commercialTerm.margin).
v. The Candidate is redirected to the My Courses tab where the Course taken is
listed as first.
b. If the Course has REVENUE_SHARING Commercial Term:
i. The Candidate must choose the Commercial Term first: NOMINAL_FEE or
PAY_UPON_HIRE.
ii. If the Candidate chooses NOMINAL_FEE, the process continues as in in the case
of FIXED_COST. The cost paid is the cost of the Course at the moment the
Course was taken. The cost of the Course per Candidate is always saved into the
Candidate-Course association.
iii. If the Candidate chooses PAY_UPON_HIRE, the system will generate Candidate-
Course association with cost calculated as the NOMINAL_FEE for that Course
multiplied by the factor defined in PAY_UPON_HIRE Commercial Term. The
first Candidate-Exam entity is created as well. In this use case we don’t care if
the Course cost increases or decreases in the future. REFERENCE_ID is NOT
generated. Payment record is NOT generated. The Candidate is redirected to
the My Courses tab where the Course taken is listed as first.

Search for Jobs

Candidates shall be able to search for Jobs. The page shall allow the candidate to search for Jobs and
filter by Category, Tags along with their associated weight, Contexts, Recruiter’s email, Job Start Date
(>=) and Job End Date (<=) as well as Location. The functionality is similar to the Search for Courses
functionality. The tables queried here are: JobPost and JobPostTag. Only Job Posts in SUBMITTED state
shall be returned. Job Posts in CREATED and COMPLETED state are not relevant for the search query.

The results shall be ordered by the Job Post start date, in descending order. The system shall return at
most 500 Job Posts and the system will present these Job Posts in the client side paginated data table.
The table row shall contain the following information:

 Recruiter’s email
 Course Category
 Start Data
 End Date
 Description (truncated)

If the search filter includes at least one Job Post Tag, then the user interface shall include one additional
sortable column: Tags Total Weight.

When some Candidate clicks on the Job Post, a popup window shall show up.

The popup window shall have 2 tabs:

 Job Post Details


 Related Courses
Whenever the popup is opened, the number of Candidate Views shall be increased (User Interaction
Service, direct or aggregated. In the case of aggregated service, the number of views is not counted from
database, but rather from file based events).

The Job Post Details tab shall present all information that relates directly to the Job Post:

 Description
 Course Category
 Start Date
 End Date
 Recruiter info (email, first name, last name and his photo)
 Job Post Contexts
 Job Post Tags along with their weights (these are created by the Recruiter)
 Job Post Tags by Candidate Feedback (these are aggregated by the system based on the
Candidates feedback)
 Job Location
 The number of Candidate Views
 The number of Candidate Favors
 Average Candidate Rating

The Job Post Details tab shall allow the candidate to favor and rate the Job Post. The favored Job Posts
shall appear under new Candidate page My Favored Job Posts.

The Related Courses tab shall enlist the associated Courses to that Job Post. This is a query to the
association entity CourseJobPost. The list shall be sorted by the Course’s rchScore, descending order.
We shall return at most 500 Courses presented in the client side paginated data table. Each table row
shall contain these Course related fields: Id, Name, Commercial Term, System Score (rchScore), and the
cost (if any). If the Candidate clicks on the Course row, the system shall redirect the Candidate to the
Search for Courses page with automatic search by the Course Id.

My Courses

By default we shall present the Courses the Candidate took in the last 3 months (date descending
order).

The courses available for listing are Candidate Courses which status paid==true or Commercial Term==
PAY_UPON_HIRE (Not that FREE courses are marked as paid=true)

However we will provide search criteria to find all Candidate courses. The search functionality shall
contain the following filter criteria:

Course Name, Course Category, Visibility, Creation Date etc.

Each Course shall be presented with expand/collapse panel (+/-).The user interface shall allow multiple
courses to be expanded in one moment.

The Course related panel shall contain links to the:

1. Course Material
2. Preview Exam
3. Course Exam(s)
4. A link (button) to buy another Course Exam. This link shall not be visible and the Add New
Course Exam action not allowed if there is a pending Course Exam which is NOT completed yet.
Note that the first Course Exam is ALWAYS paid along with Course.

If the Course has associated Job Posts at the moment, a link with name Job Posts shall be visible. If the
Candidate clicks on that link, a popup window shall enlist all associated job posts in a server side paged
accordion (query the table CourseJobPost). The Job Posts shall be ordered by their start date,
descending order and only Job Posts in SUBMITTED state shall be considered.

The accordion panel content shall show all Job Post related info:

 Description
 Course Category
 Start Date
 End Date
 Location (State and City if any, they are optional)
 Recruiter info (email, first name, last name and his photo)
 Job Post Contexts
 Job Post Tags with their weights (these are created by the Recruiter)
 Job Post Tags with their by Candidate Feedback (these are aggregated by the system based on
the Candidates feedback)

For each Job Post, Candidate shall be able to provide feedback related to the Job Post’s tags and their
weights. That functionality shall be implemented the following way:

 The tag select drop down will allow the Candidate to choose a tag. The select drop down is
prefix based Ajax filter that won’t offer tags already included in the Candidate’s feedback.
 When the user selects a tag it shall be added to the “submission” area.
 The user shall be able to adjust the weight next to the tag.
 The user shall be able to remove the Tag from the feedback (from the submission area)
 The user shall be able to click the button Save in order to persist the Feedback on the server.

Figure 6. Job Post Tag Candidate Feedback

The system shall periodically average the feedback from all of the Candidates by averaging the table
CandidateJobPostTagFeedback (group by Job Post and Tag).
Important: Only Job Posts in SUBMITTED state shall take part into this aggregation query.

The aggregated results shall be persisted into the table JobPostTagFeedback.

The Candidate must be able to change the Course Visibility (when Recruiters score Candidates). The
Course visibility can be:

 PUBLIC: All Exams for that Candidate Course are visible to the Recruiters and the Scoring
system
(Description: Your Course and Exams are always visible for Recruiters in accordance with their
level of privileges)
 PARTIAL: The Candidate Course takes part when Recruiters score the Candidates, the
aggregated Exam Score can be seen by all Recruiters of level Advanced or Complete, but the
Exams are visible only for Recruiters of level Complete.
(Description: Your Course and Exams are always visible for Recruiters, but the information for
each particular Exam is hidden from Recruiters with lower privileges)
 PARTIAL_LOCKED: The Candidate Course takes part when Recruiters score the Candidates, the
aggregated Exam Score can be seen by all Recruiters of level Advanced or Complete, but the
Exam(s) information is NOT available to the Recruiters no matter of their role. NOTE: This status
is not in the status drop down list if the flag partialLockedPaid is not true. When the partial
locked payment is finished the system automatically will set the status to PARTIAL_LOCKED.
After that the Candidate can change the status as he wish into one of 4 available statuses.
(Description: Your Course and Exams are always visible for Recruiters in accordance with their
level of privileges, but if you have paid, the information for each particular Exam is hidden from
any Recruiters)
 PRIVATE: The Candidate Course is visible only for the Candidate and it is not counted when the
Recruiters score the Candidates.
(Description: Your Course is invisible for Recruiters)

If the Candidate marks the Course as PARTIAL, the System still has the right to share the Exam
information with Recruiters of level Complete. However, the Candidate can always pay a fee
(immediately, no matter of the Candidate Course Commercial Term) and revoke the System right to
share Exam related information with Recruiters with Complete level of subscription. When the payment
is completed, the System will set the status of the Candidate Course into PARTIAL_LOCKED.

The Candidate can press the link Lock Partial Visibility which starts payment flow. The flow is:

 The system generates UUID, updates the partialLockedReferenceId in the Candidate Course
association with the generated UUID, creates Payment record with that UUID as
REFERENCE_ID and Candidate is redirected to the Payment Gateway. The amount to be
paid is defined as Commercial Term.
 The Candidate pays the required amount in the Payment Gateway.
 The Payment Gateway redirects the Candidate to our application where the Payment
(identified by the REFERENCE_ID) is completed. The Candidate Course is marked with
partialLockedPaid as true.
 The Candidate Course status is set to PARTIAL_LOCKED.
There are visibility states that are controlled by the system:

 HIDDEN_NOT_PAYED: Set by the system in the case when Candidate Course or one of its Exams
with PAY_UPON_HIRE commercial term were not paid in a predefined time period (one year)
 DEPRECATED: Set by the system automatically after predefined time period since the Course
Exam was first passed (3 years, Candidate Course aging)

The Candidate can’t change the Candidate Course status if the status is HIDDEN_NOT_PAYED or
DEPRECATED.

The Candidate can change the Candidate Course’s visibility by selecting appropriate visibility from drop
down box. Use dropdown box on change event for Ajax update call.

Clicking on Course Exam link shows the Exam into a popup window if completed or starts a page where
Candidate answers the Exam questions.

If the Course Exam is completed already, the panel shall provide the info for that Exam: Score, Time
Started, Time Completed, Passed and Score. Note that we never show to the user which questions
were correct or wrong!

If the Course Exam is NOT completed yet, the Candidate shall continue with the next Question not
answered in the Course Exam into new page (part of the question answer wizard).

During the Exam the system will send proofs to the Server that can serve as Candidate verification. For
example we can capture snapshots on random time interval by using JPEGCAM:

http://code.google.com/p/jpegcam/

We can record sounds as well.

When the last question is answered, the system will:

 Check the questions correctness


 Check the score and Candidate Exam based on that score determine if the Candidate has
passed the test or failed
 Update the info (score, passed etc.) as well as the Candidate-Course association by calculating
the aggregate exam score, exam proof weight as well updating the passingDate indicator.

For n successfully passed exams, the aggregate exam score for the whole Course is calculated as:

SCR_i: the score for the i-th exam which was passed successfully

ST_i: the Start Time for the i-th exam which was passed successfully

ST_0=INFINITY by convention
Aggregate Exam Score= SUM(SCR_i*e(-i+1)(1+1/(ST_i-ST_i-1))/SUM (e(-i+1)(1+1/(ST_i-ST_i-1))=
=(SCR_1*e(-1+1)(1+1/(ST_1-ST_0)+SCR_2*e(-2+1)(1+1/(ST_2-ST_1)+ SCR_3*e(-3+1)(1+1/(ST_3-ST_2)+…)/
(e(-1+1)(1+1/(ST_1-ST_0)+e(-2+1)(1+1/(ST_2-ST_1)+e(-3+1)(1+1/(ST_3-ST_2)+…)
The formula above represents some kind of weighted average that takes into count the following
requirements:

 Each sequential exam shall have lower contribution to the aggregated exam store
 The validity of the repeated exam increases with the time period between that exam and the
previous one passed successfully

The Start Time difference is calculated in days. If two Exams are taken in the same days set Start Time
Difference as one day.

For n successfully passed exams, the aggregate proof weight for the whole Course is calculated as the
quotient PROOFABLE_EXAMS/TOTAL_EXAMS where:

PROOFABLE_EXAMS is the number of successfully passed Candidate Exams with associated Exam
Proofs

TOTAL_EXAMS is the total number of successfully passed Candidate Exams.

If the Course Exam was not started yet, the Candidate shall press the Start Button (Link) and follow the
Exam questions as described above.

When the Candidate needs additional Course Exam (in the case when he didn’t pass the initial one or he
wants to improve his scoring) he can buy another one.

For each Commercial Term there is a factor known as Exam Percent Cost. This cost is calculated on the
accumulated cost paid (or planned to be paid).

For example:

The initial cost of Course is 100$ and Exam Percent Cost is 0.2.

The second exam (the first comes along with the materials when the course has been taken) costs
100*0.2=20$.

The accumulated cost after that is 120$.

The third exam costs (100+0.2*100)*0.2=120*0.2=24$.

The accumulated cost after that is 144$.

If the Candidate clicks on the Add New Course Exam the flow is:

 For Candidate-Course associations having FIXED_COST or NOMINAL_FEE Commercial Terms:


o System calculates the cost of the n-th Course Exam, generates new REFERENCE_ID,
creates new Course Exam Entity, creates new Payment record
o System redirects the Candidate to the Payment Gateway
o The Payment Gateway redirects the Candidate to our application, the Payment Record
and Course Exam are updated (paid=true), accruedAmount is increased in the Instructor
Course. The Candidate will land on the My Courses tab after that.
 For PAY_UPON_HIRE Commercial Term:
o System does NOT calculate any cost for the new Course Exam, does NOT generate new
REFERENCE_ID and does NOT create new Payment record.
o System generates new Course Exam Entity
o System redirects the Candidate to the My Courses tab.

Each Course taken by the Candidate can be:

1. Favored: Only Once (paid or not paid), a fancy button in the UI


2. Rated (1 to 5): With Update (paid) http://wbotelhos.com/raty/

Each Course’s Tag can be Endorsed by the Candidate (we don’t keep history of endorsements per user
per course-tag in the database, in the aggregator maybe)(or we shall discuss multiple endorsement
scenario prevention….)

My Favored Job Posts

This page shall enlist the Job Posts favored by the Candidate.

The data shall presented in server side AJAX paginated Accordion. The Job Posts shall be sorted by the
Job Post’s Start Date.

Each Accordion content shall consists of 2 tabs: Job Post Details and Related Courses. The content and
the layout of the data in these tabs shall be the same as described in the Search for Jobs section.
Whenever particular Job Post is fetched from the server the number of Candidate Views shall increase.

My Payments

These page contains 2 tabs: Candidate Payments and Pending Payments.

By default the Candidate Payments tab will show the Candidate payments in the last 3 months.

Each row is a payment for particular Course or Bulk of Courses (in the case of Pay upon Hire) or Partial
Locked Payment. For each payment the Candidate can expand the payment in order to see what Course
and (or) Exams were covered with the payment.

The user interface shall allow multiple expanded elements in one moment.

The tab shall contain filtering capabilities that will allow the Candidate to change the date time interval
he is filtering for.

Another tab named Pending Payments shall enlist per Course pending payment information as well as
the total amount to be paid by the Candidate. If there are Candidate hires with status CONFIRMED, but
not BILLED, the UI shall group pending payments per Hire. A Hire includes all pending payments from
the previous hire date +1 day (if any) up to (inclusive) this Hire date. If no previous hire date exists, the
time shall be considered as infinity in the past.

For example if have 2 Hires which are not BILLED (this can’t happen in practice if we run the Billing
process regularly), the UI shall show:

Payment Due Date: 08.15.2013


Java EE $10
.NET $5
Pay Now $15
Payment Due Date: 09.21.2013
Tibco $7
Pay Now $7
Pay Upon Hire
SharePoint $5
Hadoop 3$
Pay Now $8

Pay All $30

This tab shall have a buttons named Pay Now: One Global (for All Pending Payments) and one per Hire
Section. . By pressing that button :

 The system will generate common REFERENCE_ID for all (or per Hire Section) PAY_UPON_HIRE
Courses and Exams the Candidate has taken in the past and are not paid yet. The
REFERENCE_ID is saved into each Course and Exam determined as pending. The total sum to be
paid is calculated as well.
 The system generates Payment record with the amount and REFERENCE_ID calculated above.
 The system redirects the Candidate to the Payment Gateway
 The Candidate pays the amount required
 The Payment Gateway redirects the Candidate to our application
 The system updates all Courses and Course Exams marked with the REFERENCE_ID returned
from the Payment Gateway as paid. The Payment itself is marked as completed as well.
 The amount paid for each Course is added to the InstructorCourse’s accruedAmount:
accruedAmount=accruedAmount+amount*(1-commercialTerm.margin)
 The Candidate is redirected to the Candidate Payments tab.

Recruiter’s Functionality
Each Recruiter pays for one of the following level of service:

 Basic is the most restrictive level of visibility that a recruiter can have. This level provides only
limited candidate information which is often provided on candidate profiles, their general
skillset, experiences and some general knowledge information like most relevant tags based on
the Candidate Course information.
(Description: The most restrictive level of visibility that a recruiter can have. This level provides
only limited candidate information which is often provided on candidate profiles, their general
skillset, experiences and some general knowledge information like most relevant tags based on
the Candidate Course information)
 Intermediate is the intermediate visibility level. This level allows the recruiter to see the courses
that the candidate has taken and passed but we are not presenting the Recruiter the passing
score, i.e. just the information that the course is passed. In addition, this level will not be able to
show any courses which the candidate has not passed.
(Description: Intermediate visibility level. This level allows the recruiter to see the courses that
the candidate has taken and passed but we are not presenting you the passing score, i.e. just the
information that the course is passed. In addition, this level will not be able to show any courses
which the candidate has not passed)
 Advanced is the advanced visibility level. This level has all the visibility from the previous levels
and it also includes average candidate exam scores for all of the courses that the candidate has
taken and passed. With this level Recruiter will be able to see courses which the candidate has
passed along with each particular passed exam info (score, duration) except for Course marked
as PARTIAL. For Courses marked as PARTIAL by the candidate only average exam score is
available.
(Description: Advanced visibility level. This level has all the visibility from the previous levels and
it also includes average candidate exam scores for all of the courses that the candidate has
taken and passed. With this level you will be able to see courses which the candidate has passed
along with each particular passed exam info (score, duration) except for courses where
candidate has paid to hide exams information.)
 Complete is the most permissive level of service and gives to Recruiter a complete access into
candidate's information. Anything that the candidate wanted to use or information that is
relevant about the candidate is made visible for the Recruiter. This level of service gives the
Recruiter detailed information about each course question and the answer that the candidate
provided on every exam taken, exam proof photos…
(Complete: The most permissive level of service and gives you a complete access into candidate's
information. Anything that the candidate wanted to use or information that is relevant about
the candidate is made visible for you. This level of service gives you detailed information about
each course question and the answer that the candidate provided on every exam taken, exam
proof photos and similar details)

Each Recruiter payment can be for one Month, Quarter and Year.

The Recruiter payments are registered into the table Payment under the following referenceIdTypes:

 RL_1_M: Basic access for one Month


 RL_2_M: Intermediate access for one Month
 RL_3_M: Advanced access for one Month
 RL_4_M: Complete access for one Month
 RL_1_Q: Basic access for a Quarter
 RL_2_Q: Intermediate access for a Quarter
 RL_3_Q: Advanced access for a Quarter
 RL_4_Q: Complete access for a Quarter
 RL_1_Y: Basic access for one Year
 RL_2_Y: Intermediate access for one Year
 RL_3_Y: Advanced access for one Year
 RL_4_Y: Complete access for one Year
When the Recruiter logs in, the System must check the last Recruiter Payment if any. If the Payment
exists and the time period it is paid for is not exhausted, the Security sub-system shall grant the
Recruiter one or more of the following dynamic roles:

 RECRUITER_L_1 (Basic)
 RECRUITER_L_2 (Intermediate)
 RECRUITER_L_3 (Advanced)
 RECRUITER_L_4 (Complete)

The user interface tab Recruiter contains the functionality related to the Recruiter role.

When the Recruiter logs in, the tab Recruiter shall be visible.

The Recruiter tab shall contain the following pages:

 Search for Courses


 Search for Candidates
 Candidate Hires
 Job Posts
 My Payments

Search for Courses

Recruiters shall be able to search for Courses. This way the Recruiter can check what kind of Courses the
system offers, their quality etc.

The Search for Courses shall allow filtering and ordering criteria based on:

 Course Id
 Course Category
 Creation Date
 Tags with endorsement weighting above some threshold (logical AND)
 Contexts (logical OR)
 Name
 Number of Candidate Views
 Number of Recruiter Views
 Number of Candidate Favored (Likes)
 Number of Recruiter Favored (Likes)
 Recruiter Average Rating
 Candidate Average Rating
 Aggregate Exam Score
 Total Hires
 System Verified
 RCH Factor

The filter construction logic is the same as described before for the Candidate role.

The result of the Search operation is a table with results.


When the Recruiter clicks on the Course link in one of the table rows returned, a popup window shall
show the Course details along with links to the preview material if any, preview exam, material and
exam.

Each Course can be Favored and Rated by the Recruiter. Specifically, Recruiter can favor the Course
only once. Recruiter can rate the Course and change the rating after that.

Each Course raw contains link: Show Candidates (icon, the most left column in the row). This link will
take the Recruiter to the Search for Candidates page with prepopulated filter for Course Id and run that
query automatically.

The Course popup Windows shall have additional search for Candidate shortcuts:

 By Course Id
 By Course Context(s)
 By Course Tag(s)
 By Course Category

The Recruiter shall be able to save his Course search queries into persistent store. One of the queries is
the Default one. The default query is always loaded when the search page has been opened. The rest of
saved queries have name.

Search for Candidates

This page is the heart of the system. This is a page where Recruiter can retrieve relevant, scored list of
candidates that have passed Exams for Courses in some Category or tagged by combination of Tags.
Also the Recruiter shall be able to search for Candidates based on their profile information regardless if
they have taken Courses or not.

In the most simplistic form the system have to execute statistical query that will:

1. Filter the Courses relevant for the Recruiter: by category, by tag and its relevance (endorsement
weight), creation date, number of views and all other Course filters as defined elsewhere in the
document.
2. Based on the Courses found in step 1, find the Candidate Courses passed successfully. The
query can filter Candidate Courses by aggregateExamScore, passingDate, examProofWeight,
systemSuspected (never consider Candidate Courses with visibility set to PRIVATE,
HIDDEN_BY_SYSTEM and DEPRECATED) and Candidate Profile filter if present.
3. Group Candidate Courses found in step 2 by Candidate and SUM their exam scores as:
SCORE=SUM(COURSE_SCORE_FACTOR * EXAM_SCORE)
4. Order the list of Candidates based on the SCORE found in step 3.

= > Search

= > Filter Courses

=> Match Candidate Courses


=> SUM SCORE per Candidate

=> Order by Score

The search user interface has to provide TWO filtering dropdown select lists to the Recruiter:

 Filter Course By
 Filter Candidate By

The Recruiter must choose the Course Relevance By criteria too.

Figure 7. Search for Candidates

The dropdown filtering select lists have the following criteria items included:

 Filter Course By: This filter has identical structure and organization as in the Search for Courses
page described previously. It shall contain unique (recognizable) color in the user interface. The
criteria balloons produced from this filtering drop down shall have the same color with the drop
down list.
 Filter Candidate By: Defines filtering criteria for particular Candidate Courses by
aggregateExamScore, passingDate, examProofWeight, the flag systemSuspected and
Candidate Profile related items like: Name, Location and Mail. This filter also contains the
criteria Exclude Hired Candidates After which will provide Date Picker control in order to
specify if the Recruiter wants to filter out all of the candidates that were hired after specified
Date. For example: Take into account the candidates that were not hired in the last 6 months.
 Course Relevance By: This criteria contains multiple selection drop down list where Recruiter
can choose what Course column(s) represents the COURSE_SCORE_FACTOR in the query. The
Recruiter can choose a combination of the following relevance items: candidateViews,
recruiterViews, candidateFavored, recruiterFavored, recruiterRatingAverage,
candidateRatingAverage, totalHires and rchFactor. We shall weight each relevance item
included with coefficient in the range from 0 to 1. The left most relevance item is the most
significant one and the right most relevance item is the less significant one. So for example, if
we have 3 relevance items, the bin intervals are 1/3, the first relevance item from the left has
weight 1, the second from the left has weight 0.66 and the third one from the left has weight
0.33.
Some of the relevance items are long integers and some of them are double numbers between 0
and 1. Before summing up these relevance items, we have to scale each relevance item’s value
in the range [0,1].The search query shall use COURSE_SCORE_FACTOR which is normalized in
the range from 0 to 1.

COURSE_SCORE_FACTOR calculation example:

The Relevance Items from left to right are: recruiterFavored, recruiterRatingAverage, rchFactor.

For some course these the values are:


recruiterFavored=100

recruiterRatingAverage=4

rchFactor=0.8

For all courses we have the following information:


Min(recruiterFavored)=0

Max(recruiterFavored)=500

The normalized values of the above relevance items are:


RI_1= norm(recruiterFavored)=(recruiterFavored- Min(recruiterFavored))/
(Max(recruiterFavored)-Min(recruiterFavored))=

=(100-0)/(500-0)=0.2

RI_2=norm(recruiterRatingAverage)=4/5=0.8

RI_3=rchFactor=0.8

We have 3 relevance items with the following weighting coefficients:


RI_1: W_1=1

RI_2: W_2=0.66

RI_3: W_3=0.33

COURSE_SCORE_FACTOR=(W_1*RI_1+W_2*RI_2+W_3*RI_3)(W_1+W_2+W_3)=

=(1*0.2+0.66*0.8+0.33*0.8)/(1+0.66+0.33)=0.814/2=0.4

If only Candidate Profile related criteria (Location, Mail, Name) is present in the search, the query shall
search the Candidates directly, without considering if they have taken some Courses or not (without
considering any Course related relational joins).
If the search contains both Course and Candidate Profile related criteria, the Candidate Profile based
filtering is applied through the Candidate Course’ candidate field.

The Recruiter shall be able to his Candidate search queries into persistent store. One of the queries is
the Default one. The default query is always loaded when the search page has been opened. The rest of
saved queries have name.

When the Recruiter presses the button Search, the System will present to the Recruiter paginated list of
Candidates ordered by SCORE.

The search action is an AJAX call that returns JSON list of up to 500 results. These results shall fit into
data table with sortable columns as well as in-memory (browser) pagination.

The last column of the results table shall contain View Details link.

Recruiter can press on View Details. The system shall present the Candidate’s info into a popup
window. This popup window will show information that depends on the Recruiter’s subscription level as
defined in the section above.

The Popup window shall have title: “Candidate: <The name of the candidate>".

The Window shall have 3 tabs (the order is important):

 Relevant Courses: Only show those courses which are relevant for the search criteria; the server
shall return all the courses and we shall filter those courses against the search filter criteria using
JavaScript (this is in the browser filtering because search query is expensive operation to be repeated
if not needed).
 All Courses: Shows all the courses.
 Profile: User general info and contact information

The courses in the Relevant Courses and All Courses tabs shall be presented into accordion (expand/collapse)
bar. The courses bars should show the name (as is now), the Avg Exam Score and Candidate Exam Score.
These 3 identifiers should be in the collapsible bar.

The tabs Relevant Courses and All Courses are visible only if the Recruiter has role Intermediate and
above.

The popup window must have a button Bookmark. If the Recruiter presses the button Bookmark, an
association record is created in the table Hire with status BOOKMARKED.

We have to provide a side by side comparison for multiple candidates and a checkbox next to each candidate
in the result list as well as a Compare link or button on the lower right of the search filter.

The comparison would first need to normalize the candidate data, sort it by course first, then by exam
results, and then by question. Once we have the data we'll show it side by side and we'll allow collapsing of
the comparison by person (some personal info, location, years of experience etc.)/course (# of courses taken,
average scores)/exam results/questions. The companion document CandidateCompare.xslx shows the
comparison matrix.

The comparison matrix shall be available for recruiters having a role of Intermediate or above with the same
exam details restriction as explained before.
Candidate Hires

The Recruiter shall be able to announce to the system when some Candidate is hired by the Recruiter. If
the Candidate confirms that he was hired by the Recruiter, the System will give to the Recruiter some
Incentives.

By default we shall present the Hire records announced in the last 3 months (date descending). The
page shall also offer filtering of the Hires by:

 Date
 Status

The Hire Date can’t be set in the future.

The Status can be one of:

 BOOKMARKED
 HIRED
 CONFIRMED
 DISPUTED
 HIRED_DISPUTED
 BILLED

The state transition diagram is:

BILLED

System
System

Recruiter Candidate
BOOKMARKED HIRED CONFIRMED

Candidate

Recruiter
DISPUTED

Administrator
Administrator
Recruiter

HIRED_DISPUTED

Figure 8. Hire State Transitions


The Recruiter shall be allowed to announce a new Hire in the system by pressing a button near Hire
record with status BOOKMARKED. The status basic state transition is simple:

= > BOOKMARKED = > HIRED = > CONFIRMED=>BILLED

When the button Hire is pressed, the Recruiter shall be present a popup dialog where he will enter the
date when the Candidate was hired.

Whenever the hire status transitions to CONFIRMED (by Candidate accepting the hire or Administrator
that resolves Candidate Hire Dispute), the totalHires field shall be increased for all CandidateCourses
with passing date before the hire date.

Recruiter shall be able to endorse the skills announced on the Candidate’s profile. These are the Skills
that are not confirmed by the system, i.e. imported from LinkedIn or manually entered on the user’s edit
profile page.

In each row in the Hires display table, the Recruiter shall be able to click the link Endorse. By clicking on
this link the system shall show a popup screen where Recruiter can drag from Candidate’s existing skills
and drop the selected skills into a field that can be submitted. This is the same mechanism used when
Candidates and Recruiters endorse course tags. The result of the endorsement is saved into the table
RecruiterCandidateSkillEndorsement. The system shall not allow drag and drop for already endorsed
skills. When saving endorsement, the previous “orphaned” endorsements shall be deleted (these are
endorsements that Recruiter has revoked in the UI or the Candidate has removed them from their
profile)

Note that the Candidate’s skills are saved as part of the Profile Resume which is not kept into database
but into XML saved by the Storage Service. In order to show in the UI the Candidate’s existing Skills we
need to parse XML and extract the Skills from there. Retrieving and parsing that XML all the time is not
practical and efficient. We shall optimize the process by keeping the Candidate’s Skills into Hazelcast
memory bounded and item expire-able map. The items in that map shall be keyed by profile id. The
value is a list of Skills. We shall keep at most M entries in this map (M=100 for example). In order to
keep consistency in the system, the cache map entry shall be cleared whenever user updates his
resume.

Recruiter endorsements take part into the user interaction service which has a purpose of calculating
interactions into some kind of aggregated value (direct user interaction service for demo, real time
purposes and production aggregating user interaction service based on a scheduled execution).

The system shall process these endorsements and the aggregated values per Candidate Skill shall be
saved into the table CandidateSkillScore. The scores are calculated the same way we calculate
endorsement weights for Course Tags.

Job Posts

Recruiter shall be able to submit Job positions that are open in his company. This page enlists all Job
Posts in descending order by the Job’s start date. Each Job Post has the following attributes:

 Description
 Start Date
 End Date
 State (CREATED, SUBMITTED, COMPLETED)
 Category
 Contexts
 Tags (collection of tag name plus tag weighting)
 Location (State and City, there are optional)

The list is server side paginated data table.

The system shall allow the Recruiter to filter Job Posts by Description, Start Date, End Date, State,
Course Category, City and State.

The Recruiter shall be able to add new Job Post. When Create button is pressed, a popup dialog shall
appear where Recruiter enters the Job Post’s attributes. The tags collection is specific. Besides selecting
tags, the Recruiter shall enter the tags weight too. The user interface shall use the same Balloon type for
course tags as in the Search for Courses or Search for Candidates screens. Multiple tags with the same
name are not allowed.

Rule: The Job Post shall not span more than 3 months. This way we will prevent the system to keep and
maintain never ending Job Posts for which the system has to calculate associated courses

Once the Course has been created it is in CREATED state.

Recruiter shall be able to edit Job Post. Only Job Post in CREATED state are completely editable. For Job
Posts in SUBMITTED the Recruiter can change the End Date only. Job Posts in COMPLETED state can’t
be edited. When the Recruiter clicks on the Edit button (command buttons shall be located in the right
most “action” column), the same popup dialog as in the create use case shall appear. If the course is in
SUBMITTED state then only End Date is editable.

Recruiter shall be able to delete Job Post. Only Job Posts in CREATED state can be deleted.

Recruiter shall be able to submit the Job Post through a button in the Job Post’s table row.

After the Job is submitted, the Recruiter shall be able to add Confirmed Hires to the Job Post. If the
Recruiter clicks on the link Hires (that exists for each Job Post in SUBMITTED or COMPLETED state) a
popup window shall show up. This window enlists in a client side paginated data table at most 500 hires
associated with the job post (the latest hires ordered by hire date, descending). Recruiter shall be able
to add hire to the Job Post by selecting the Hire from select drop down list and pressing the button Add.
The list is populated with all candidates that are not associated with the Job Post already. When
recruiter adds the Job to the Post the state of the Hire will change in the following cases:

 If the state of the hire is BOOKMARKED it shall transit to HIRED. In addition the UI shall popup
window where Recruiter will choose the Hire Date.
 If the state of the hire is DISPUTED it shall transit to HIRED_DISPUTED.

Also, the Hire shall be disassociated from the Job Post automatically under the following circumstances:

 Recruiter makes hire transition HIRED=>BOOKMARKED


 Recruiter makes hire transition DISPUTED=>BOOKMARKED
 Administrator makes hire transition HIRED_DISPUTED=>BOOKMARKED

The value in the list shall be Candidate Name+[hireDate]. This drop down shall be dynamic, prefix based
Ajax filtering of hires by the Candidate’s name. The Recruiter shall be also able to disassociate the Hire
from the Job Post by pressing the delete button next to the Hire in the data table.

A scheduled background process shall periodically process the Jobs posted in SUBMITTED state and
associate or de-associate each Job Post with relevant/irrelevant Courses if any.

This scheduled process shall:

1. Maintain the state of the Job Posts those End Date has been passed:
a. Query the ids of all Job Posts in the state SUBMITTED and passed End Date (separate
transaction). These are Job Posts that will go into the COMPLETED state.
b. Process the Job Post ids in batches, single transaction (100 for example):
i. Update the state to COMPLETED for all Job Posts with id in the job post id list
currently processed.
ii. From the table CourseJobPost select grouped courses using the following
PSEUDO SQL:
SELECT courseId, COUNT(courseId) as decreaseCount from CourseJobPost
WHERE postId in (job post id list) GROUP BY courseId
iii. In memory group the courseId by their associated decreaseCount returned
above. The map shall logically represent decreaseCount to coursId list lookup.

For example if the query returned the following courseId, decreaseCount list:

1, 3

2, 1

3, 1

4, 2

5, 3

6, 2

Then the map will contain:

1 => [2, 3]

2=> [4, 6]

3=> [1, 5]

iv. Delete all entries in the CourseJobPost table with job post id in the job post id
list currently processed.
v. Update the Course table based on the decreaseCount to courseId list map the
following way:
UPDATE Course set numberOfJobPosts= numberOfJobPosts -decreaseCount
where courseId in (courseId list)

We shall run the above update query for each key in the in-memory map
constructed.

For example the queries shall be:

UPDATE Course set numberOfJobPosts = numberOfJobPosts -1 where courseId


in (2, 3)

UPDATE Course set numberOfJobPosts = numberOfJobPosts -2 where courseId


in (4, 6)

UPDATE Course set numberOfJobPosts = numberOfJobPosts -3 where courseId


in (1, 5)

Note: The purpose of the above “complex” processing is minimizing the


number of update queries.

2. For Each Job Post in SUBMITTED state (query in separate transaction that will return job post
ids):
a. Search for Courses based on the Job Post’s Category, Tags and Contexts. The weight of
the tags shall be included in the query. The query shall return the top 500 Courses
ordered by the Course’s rchScore (use separate transaction for this search, i.e. release
the Course table as fast as possible).
b. Based on the Courses returned, the CourseJobPost association shall be updated the
following way (single transaction):
i. If the Course-Job Post association already exists in the table do nothing.
ii. If the Course-Job Post association does not exist in the table, create new
association.
iii. Delete all remaining Course-Job Post associations because they are not relevant
any more.
c. Finally, after all Job Posts are processed, from the table CourseJobPost select grouped
courses using the following PSEUDO SQL (separate transaction):

SELECT courseId, COUNT(courseId) as jobPostCount from CourseJobPost


GROUP BY courseId

Similarly as explained above, create in-memory map jobPostCount=> courseId List and
for all different jobPostCount keys in the map execute the Course related update query:

UPDATE Course set numberOfJobPosts= jobPostCount where courseId in (courseId list)

Group all updates in transactions that do not include more than predefined number of
course updates (1000 for example).

For example:

jobPostCount Course Id List Length


1 500
2 1500
3 1500
4 500
5 300

The updates for the in-memory map above, shall be divided into transactions this way:

jobPostCount Course Id List Length Transaction Number


1 500 1
2 1000 2
2 500 3
3 500 3
3 1000 4
4 500 5
5 300 5
`

Recruiter Payments

This page is a simply listing of the Recruiter’s payments in the last 3 years. The page shall also offer date
filter for adjusting the time period the payments are fetched for.

The payments shall be enlisted into a table. The payment (usually the last one) that defines the
Recruiter’s subscription level at the moment shall be highlighted and we need to add word Current in
the Level column. For example:

Complete (Current)

Basic

This page shall also contain a button named Add New Payment. By pressing that button, the Recruiter
initializes a flow to pay his next subscription fee.

If the current subscription is not exhausted and the recruiter wants to pay for lower or equal level as the
current subscription level, the system shall notify the recruiter (warning popup) that he is going to pay
for something that he already has.

When the Add New Payment button is clicked a new page shall be presented where Recruiter will
choose what kind of fee he is going to pay (Commercial Terms from ID=5 to ID=16). The Recruiter
proceeds by clicking the button Pay. After that system goes through the payment cycle:

 The system generates REFERENCE_ID and a new Payment is entered into the system. The
amount to be paid depends on the Commercial Term chosen before.
 The system redirects the user to the Payment Gateway.
 The user will pay the amount required.
 The Payment Gateway will redirect the user back to our system.
 The payment is completed.
 The user’s Security Context Holder shall be renewed with a new Authentication that will reflect
the Granted Authorities (if any) available after the Recruiter has paid a new subscription fee.
 The user is redirected to the Recruiter Payments page.

Recruiter Incentives

Each Recruiter will create subscriptions in order to use the system.

The Recruiter can have more than one not exhausted subscriptions at one moment. However only one
subscription is active (prevail) at particular time instant.

En example:

At January the first, the Recruiter has paid for 1 year, L1 subscription. On March the fifteen, the same
year, the Recruiter has paid for 3 months, L4 subscription. The active subscription at particular moment
will be:

L1 L4 L1

Each CONFIRMED hire belongs to one and only subscription active at that moment. For example, hire
in April will belong to the L4 subscription period, but not to the L1 subscription period. The system will
count the number of hires per subscription period. Each Recruiter will receive some incentive at the end
of the month (money transferred on his account). The incentive depends on the number of hires made
for some subscription period.

The incentive is measured in percent and the money transferred to the Recruiter’s account is
subscription amount multiplied with that percent.

RCH shall contain an administrator page, Recruiter Incentives, where Administrator will define for each
level and subscription period combination the following parameters:

1. Min Percent

2. Max Percent

3. Max Hires

The table that holds this info is the table RecruiterIncentive and its record changes shall be audited the
same way the system audits the Commercial Term value changes.

The formula for Recruiter’s Incentive percent is linear, threshold function that depends on the number N
of hires for particular subscription period:

FOR N<=0:

INCENTIVE=0

FOR N>=1 AND N<=MAX_HIRES:

INCENTIVE = (MAX_PERCENT-MIN_PERCENT)/ (MAX_HIRES -1) * (N-1) + MIN_PERCENT

FOR N>MAX_HIRES:
INCENTIVE=MAX_PERCENT

For example, if we have MIN_PERCENT=10, MAX_PERCENT=20, MAX_HIRES=10 than the following


charts presents the Incentive/Hire dependency:

Incentive percent
25

20
Number of Hires

15

10

0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Incentive Percent

Example:

Recruiter has Complete Subscription that costs $500 an year. The Recruiter has 5 hires up to this
moment. The above formula for 5 hires gives Incentive of 14%, or in dollars=$70. The trend will increase
up to 10 hires and the maximum incentive of 20%, or in dollars=$100.

New Subscription record shall be created into the table ReruiterSubscription whenever Recruiters
makes a new subscription payment.
RecruiterSubscription

+id: long
+version: int
+recruiter: Profile
+commercialTerm: CommercialTerm
+startDate: dateTime
+endDate: dateTime
RecruiterIncentive +subscriptionAmount: double
+incentiveMinPercent: int
+id: long +incentiveMaxPercent: int
+version: int +incentiveMaxHires: int
+commercialTerm: CommercialTerm +subscriptionHires: int
+minPercent: int +amountPaid: double
+maxPercent: int +updated: boolean
+maxHires: int

RecruiterSubscriptionHireTransaction

+id: long
+version: int
+recruiterSubscription: RecruiterSubscription
+type: string (enum=debit/credit)
+payment: Payment
+billing: Billing
+status: enum

The meaning of the fields in the table are:

1. commercialTerm: the recruiter’s subscription level (one of the 4*3=12 types we have)

2. startDate: the start date of the subscription

3. endDate: the end date of the subscription

4. incentiveMinPercent: minPercent copied from the table Recruiter Incentive for the same commercial
term, i.e. the system will use incentive definition that was valid at the moment when some subscription
has been created

5. incentiveMaxPercent: maxPercent copied from the table Recruiter Incentive for the same
commercial term, i.e. the system will use incentive definition that was valid at the moment when some
subscription has been created

6. incentiveMaxHires: maxHires copied from the table Recruiter Incentive for the same commercial
term, i.e. the system will use incentive definition that was valid at the moment when some subscription
has been created

7. subscriptionHires: the number of confirmed hires bound to this subscription, i.e. confirmed hires
those date matches the time range interval(s) when this subscription was considered as active one (the
strongest subscription level).
8. amountPaid: the incentive amount paid to the Recruiter up to some moment, incentive are
transferred to Recruiters on monthly basis (see the algorithm below how to determine how much to pay
to the Recruiter each month).

9. updated: boolean flag that indicates if this record has been updated and shall be processed by the
process that transfers incentive credits to the Recruiter.

Whenever some hire has been confirmed the system shall:

1. Find Recruiter Subscription record based on the Hire’s date using the following algorithm:
a. Check if there is Recruiter Subscription rs with rs.startDate<=hireDate<=rs.endDate; if
such Recruiter Subscription exist choose the one with the highest level and return it.
b. If not, check if there exists rs with rs.startDate>=hireDate; if one or more Recruiter
Subscriptions exist, return the one with the smallest startDate; if there are multiple
records with the same smallest startDate, choose and return the record with the
highest level.
c. If not, check if there exists rs with rs.endDate<=hireDate, if one or more Recruiter
Subscriptions exist, return the one with the largest endDate; if there are multiple
records with the same largest endDate, choose and return the record with the highest
level

2. If Recruiter Subscription has been found in step 1 then create Recruiter Subscription Hire
Transaction record of type DEBIT that will reference the Recruiter Subscription found in 1). The
status shall be set to INITIALIZED and billing and payment references are null.

The system shall have cluster singleton scheduled process for processing the Recruiter Subscription Hire
Transaction ‘queue’. This process shall run on relatively small period which is configurable (1 hour for
example). The processor shall process records ordered by creation date, ascending.

For each record of type DEBIT, the processor shall:

1. Increase by one the Recruiter Subscription’s field subscriptionHires


2. Set the Recruiter Subscription’s field updated=true if subscriptionHires<=maxHires
3. Set the status of the Recruiter Subscription Hire Transaction to COMPLETED

Once in a month, the billing process shall generate Recruiter Subscription Hire Transaction record of
type CREDIT for ALL Recruiter Subscriptions with status updated=true. The status of the record is
INITIALIZED, it references appropriate billing record, but the payment is null. This record shall be
processed by the same cluster singleton scheduled process responsible for processing the Recruiter
Subscription Hire Transaction ‘queue’.

For each record of type CREDIT the processor shall:

1. Calculate the current incentive amount as:


IF subscriptionHires >=1 AND N<=maxHires:

incentive =
(maxPercent-minPercent)/ (maxHires -1) * (subscriptionHires-1) + minPercent

ELSE

incentive=maxPercent

incentiveAmount=incentive*subscriptionAmount

2. Calculate the amount to be transferred to the Recruiter account as:

paymentAmount=incentiveAmount-amountPaid

3. If paymentAmount>0
a. Transfer the paymentAmount to the Recruiter’s account.
b. Create Payment record and reference that record inside Recruiter Subscription Hire
Transaction.
c. Set Recruiter Subscription’s field amountPaid=incentiveAmount.
4. Set Recruiter Subscription’s field updated=false.
5. Set the Recruiter Subscription Hire Transaction status to COMPLETED.

Administrator’s Functionality
The Administrator tab is visible for users having the Administrator role. This tab provides access to the
following pages:

1. Submitted Courses
2. Categories
3. Tags
4. Commercial Terms
5. Hire Disputes

Submitted Courses

We shall present the courses in SUBMITTED state (date ascending order by Last Updated On). The Page
also provides filtering functionality by:

Course Name, Course Category, State, Creation Date etc.

Each course shall be presented with expand/collapse panel (+/-). When the course row is clicked, the
Course information shall be expanded. The administrator shall be able to see the Course information
and all the links related to that Course:

1. Preview Material
2. Material
3. Exam
4. Comments

For each Course, the Administrator shall be able to press one of these 2 buttons: Approve, Reject.

If the Course was never approved before, the Administrator can execute both actions. If the Course was
Approved once (it was public), the Administrator can only Approve the Course (this is the situation
when the Course was Deprecated and re-submitted after that).

With each action, the Administrator can (should) provide comment.

After pressing the button Approve or Reject, the page shall be reloaded with the next Course available
for approval.

Categories

Administrators shall be able to view, create, edit and delete categories. The number of categories in the
system is not large, so this page shall fetch and paginate the categories inside the browser.

Tags

Administrators shall be able to view, create, edit and delete tags. The number of categories in the
system is large, so this page shall fetch and paginate the categories from the server.

Commercial Terms

Administrators shall be able to update the values of the system’s commercial terms. The administrators
can’t add new commercial terms or delete existing ones through the user interface. Also not all values
for individual commercial terms are relevant. The following matrix depicts the relevant (editable) values
for each commercial term defined in the system.

Commercial Term Amount Amount Delta Exam Per. Cost Margin


FREE N/A N/A N/A N/A
FIXED_COST $10 N/A 20% 30%
REVENUE_SHARING N/A N/A N/A N/A
NOMINAL_FEE $10 $9 25% 30%
PAY_UPON_HIRE 2 N/A 30% 30%
RECRUITER_L1_MONTHLY $30 N/A N/A N/A
RECRUITER_L1_QUARTERLY $100 N/A N/A N/A
RECRUITER_L1_YEARLY $280 N/A N/A N/A
RECRUITER_L2_MONTLY $60 N/A N/A N/A
RECRUITER_L2_QUARTERLY $200 N/A N/A N/A
RECRUITER_L2_YEARLY $500 N/A N/A N/A
RECRUITER_L3_MONTHLY $100 N/A N/A N/A
RECRUITER_L3_QUARTERLY $300 N/A N/A N/A
RECRUITER_L3_YEARLY $800 N/A N/A N/A
RECRUITER_L4_MONTHLY $200 N/A N/A N/A
RECRUITER_L4_QUARTERLY $700 N/A N/A N/A
RECRUITER_L4_YEARLY $1800 N/A N/A N/A
CANDIDATE_LOCK_PARTIAL $20 N/A N/A N/A
When administrator changes values, the service shall write into auditing table an entry for each updated
field.

CommercialTermAuditLog

+id: long
+CommercialTerm: CommercialTerm
+changeUuid
+fieldName: String
+oldValue: double
+newValue: double
+changedBy: long

Only changed values are audited. If multiple values are changed into the same save action, they are
grouped under the same changeUuid.

Hire Disputes

The administrator shall query for all hires that are in the state HIRED_DISPUTED. The oldest one shall be
located on the top.

The administrator shall be able to change the status into CONFIRMED or BOOKMARKED.

Each row has information about the candidate and the recruiter, hire date etc. (i.e. all the elements
already present on the hires screen). The administrator shall be able to click on candidate and recruiter
and he shall be presented with popup window. The candidate popup shall be the same as the popup we
use in the Search for Candidates screen for L4 (Advanced) recruiter level. The recruiter popup shall have
2 tabs: Profile and Hires. The Hires tab shall present all previous confirmed hires and hires in the state
DISPUTED or HIRED_DISPUTED. The screen shall group the hires on the screen based on their status:
Confirmed, Disputed, Hired Disputed.

Search for Courses

Administrator shall be able to search for Courses. The Search for Courses functionality is the same as the
Search for Courses functionality implemented for Candidates and Recruiters. The Administrator can
bookmark some course (this is the same the same favoring button found in the UI elsewhere).

Administrator shall not be allowed to rate some course.

In addition Administrator shall be able to mark some course as System Verified. System Verified is a
mechanism to boost some Course relevance if the system has verified in a special manner that the
course is relevant (out of band check by hired educators to check the quality of the materials). The
System Verified widget shall be a checkmark with 2 facets: filled that means course is verified and empty
or grayed (just the contours) that means unverified.

Search for Candidates


Administrator shall be able to search for Candidates. The Search for Candidates functionality is the same
as the search functionality we have on the Recruiter pages. The Administrator can bookmark some
candidate (this is the same favoring button found in the UI elsewhere). However, instead of keeping the
Administrator bookmarks into the Hires table, the Candidate bookmarks will be kept into separate table.

The Administrator has the same Candidate and Candidate Exam visibility as Level 4 (Complete)
Recruiter.

The Administrator shall be able to mark some Candidate Courses (in the Candidate popup) as System
Suspected. Use some icon for visual presentation: (the suspicions icon for example). Use the grayed
icon version for Candidate Courses that are not system suspected.

Bookmarks

The Bookmarks page shall have 2 tabs: Bookmarked Courses and Bookmarked Candidates. The content
in both of these tabs shall have server side pagination.

The Bookmarked Courses tab shall have the same functionality as Recruiter’s or Candidate’s Favorite
Courses tab. Here too, Administrator shall be able to set/unset the System Verified flag on the Courses
shown.

The Administrator shall be able to remove bookmark for the Course.

The Bookmarked Candidates tab shall have data table look and feel with columns First Name, Last Name
and Email as well as the View Details trigger (the same table structure found in the Search for
Candidates without Relative Rank and Compare columns). The bookmarked Candidates shall be always
fetched initially by creation date, descending.

The administrator shall be able to remove bookmark for the Candidate.

In the popup present when the View Details link has been pressed, the Administrator shall be able to
set/unset the System Suspected flag for some Candidate Course.

Company Profiles

On the Company Profiles page Administrator shall be able to create, edit and remove Companies.

Company Profile is RCH entity that groups several Recruiters. Each Company Profile has the following
attributes:

 Name
 Code (UUID)
 Discount (decimal number between 0 and 1 (percent) for Recruiter level subscription cost)
 Representative email

On this page Administrator shall be able to create, edit and delete Company Profiles.

The Administrator shall be also able to search for Company Profiles by Name, Code, Discount (greater
than some percent) and Representative Email.
The Company Profiles shall be enlisted into table with server side pagination (unbounded number of
Companies can be created, so client side pagination is not an option).

The Company Profile create and edit functionality shall be located into a popup window (the same
window style we use in the other screens).

When the Administrator creates a Company Profile he shall be able to define Name, Discount and
Representative Email. The Code is generated UUID by the System.

There are shall be 4 links in the right most column in each Company Profile related row:

 Edit
 Delete
 Change Code
 Recruiters

In the Edit popup dialog the Administrator shall be able to change Company Name, Discount and
Representative Email. When the Company Profile is edited and new information is persisted an email
shall be sent to Representative Email and optionally to the old Representative Email if they don’t
match.

When the Company Profile is deleted, all associated Recruiters shall be disassociated first and after the
deletion an email shall be sent to the deleted Company Representative. An Email shall be sent to the all
disassociated Recruiters too.

When the Code is Changed, an email shall be associated to the Company Representative (this way the
representative will be able to share the info with his Recruiters).

Important: Send the email only after the transaction was committed successfully. In order to accomplish
start from service method that is not transactional, call transactional save method and send the mail
after that through the notification service.

The Recruiters link shall bring up popup containing all associated Recruiters with the Company Profile.
This is a table with client side pagination (we assume the number of Recruiters won’t be more than tens
to several hundreds). The right most column in the table shall contain checkbox for each Recruiter. On
the top of the popup we need a button with name Remove. By pressing this button the selected
Recruiters will be disassociated from the Company and notification email shall be sent to all of them as
well as to the Company Representative.

A typical scenario for the task above is:

 Company representative reports abuse, i.e. Company Code was somehow revealed to unwanted
persons, or the Recruiter has left the company.
 The Administrator will Change the Company Code
 The Administrator will Remove the Recruiter(s) from the Company

Past Due Payments


The Administrator shall be able to see the Candidates with unpaid payments from various reasons.

The screen shall have 2 tabs:

 Hire Past Due Payments


 System Past Due Payments

In the first tab, Hire Past Due Payments, Administrator shall be able to enlist all Candidates which were
Hired but their state is not Billed after the period of 2* payment due date (2*30 days). Note that we will
enlist the candidate only once, even if multiple Hires satisfy the searching condition (not in the Billing
state after predefined period). We are using twice of due date because when the billing starts we don’t
know when it ends (after 1, 2, 5, 10 etc. days). However we know that the Billing must occur every
month, i.e. the system guarantees that the billing process won’t last more than 30 days max.

The users shall be presented with Ajax, server side paginated Accordion. The accordion details shall
present section with 2 tabs: Profile and Payments. The Profile tab shall be the same as the Profile tab on
the other screens (in the Candidate popup windows). The Payments tab shall enlist all Payments related
to Hires those due date has been passed. This shall be the same view as on the Candidate Payments, Pay
Upon Hire related tab.

Note that some users can take Pay Upon Hire Courses and Exams, but they will never be hired. The
system MUST bill those Candidates after some predefined time period (3 years for example).

The second tab on the screen System Past Due Payments is related to this feature. This tab shall enlist
all users that have unpaid PUH payments in a period of more than 3 years (this a system configuration
that comes from a property file). The users shall be enlisted in a server side paginated Accordion. The
user having the oldest unpaid course or exam shall be on the top of the list. The content definition
inside the accordion shall be the same as explained above for the first tab.

You might also like