Overview
The Leaderboard API provides a competitive ranking system that calculates and displays top-performing salespersons based on their Performance Index (PI), which accounts for profit generated per day since signup.
LeaderBoardSalesperson
Activity that displays the leaderboard rankings and provides performance recommendations.
Package : project.avishkar.salesmanagement.Leaderboard
Key Features
Performance Index (PI) calculation
Top 10 salespersons ranking
Recommendation algorithm for target setting
Real-time Firebase integration
Circular progress indicator for goals
Properties
List of all salespersons in the system
Calculated performance index values for each salesperson
RecyclerView adapter for displaying leaderboard items
Displays the ranked list of salespersons
Triggers recommendation algorithm display
The Performance Index measures daily average profit:
Performance Index Formula
Long currTimeInSecs = System . currentTimeMillis () / 1000 ;
Long signupTimeInSecs = Long . parseLong (
leaderBoardObject . getTimestamp ()
);
Long timeDiff = ((currTimeInSecs - signupTimeInSecs) / 86400 ) + 1 ;
String performanceCurr = String . valueOf (
(totalProfit * 1.0 ) / timeDiff
);
// Format to 2 decimal places
int index = performanceCurr . lastIndexOf ( '.' );
performanceCurr = performanceCurr . substring ( 0 , index + 2 );
Performance Index = Total Profit / Days Since Signup. This provides a normalized metric that accounts for how long each salesperson has been active.
Recommendation Algorithm
The floating action button triggers a recommendation system:
Double PiTopper = Collections . max (arrayList);
Double PiCurr = Double . parseDouble (
performanceIndex . get (i)
);
// Calculate recommended target with 10% buffer
Double targetProfit = (PiCurr + (PiTopper - PiCurr)) * 1.10 ;
This calculates a target profit that bridges the gap between current performance and top performer, with a 10% stretch goal.
Methods
ListenerRunner1()
Fetches all salespersons from Firebase.
synchronized void ListenerRunner1 () {
DatabaseReference databaseReference =
FirebaseDatabase . getInstance ()
. getReference ( "Salesperson" );
databaseReference . addListenerForSingleValueEvent (
new ValueEventListener () {
@ Override
public void onDataChange (
@ NonNull DataSnapshot dataSnapshot
) {
for ( DataSnapshot dataSnapshot1 :
dataSnapshot . getChildren ()) {
SalesPerson salesPerson =
dataSnapshot1 . getValue ( SalesPerson . class );
String key = dataSnapshot1 . getKey ();
ListenerRunner2 (
key,
salesPerson . getName (),
salesPerson
);
}
}
});
}
ListenerRunner2()
Calculates total profit for each salesperson.
synchronized void ListenerRunner2 (
String key,
final String name,
final SalesPerson salesPerson
) {
DatabaseReference databaseReference =
FirebaseDatabase . getInstance ()
. getReference ( "Salesperson" );
databaseReference . child (key)
. child ( "Inventory" )
. addListenerForSingleValueEvent (
new ValueEventListener () {
@ Override
public void onDataChange (
@ NonNull DataSnapshot dataSnapshot
) {
int totalProfit = 0 ;
for ( DataSnapshot dataSnapshot2 :
dataSnapshot . getChildren ()) {
InventoryItem inventoryItem =
dataSnapshot2 . getValue (
InventoryItem . class
);
totalProfit +=
inventoryItem . getSold () *
inventoryItem . getProfit ();
}
ListenerRunner3 (
name,
salesPerson,
totalProfit
);
}
});
}
ListenerRunner3()
Calculates Performance Index and populates the leaderboard.
LeaderBoardAdapter
RecyclerView adapter for rendering leaderboard items with ranking logic.
Package : project.avishkar.salesmanagement.Leaderboard
Key Features
Sorts salespersons by Performance Index
Displays top 10 performers
Shows rank, name, PI, and profile picture
Automatic image loading with progress indicator
Properties
List of salespersons to display
Corresponding performance index values
Android context for resource access
Sorting Logic
List < Pair < String , SalesPerson >> container = new ArrayList <>();
for ( int i = 0 ; i < performanceIndex . size (); i ++ ) {
container . add ( new Pair < String , SalesPerson >(
performanceIndex . get (i),
personArrayList . get (i)
));
}
Collections . sort (container, new Comparator < Pair < String , SalesPerson >>() {
@ Override
public int compare (
Pair < String , SalesPerson > pair1 ,
Pair < String , SalesPerson > pair2
) {
// Negative for descending order
return - pair1 . first . compareTo ( pair2 . first );
}
});
// Extract top 10
ArrayList < String > PI = new ArrayList <>();
ArrayList < SalesPerson > SP = new ArrayList <>();
for ( int i = 0 ; i < Math . min ( 10 , performanceIndex . size ()); i ++ ) {
PI . add ( container . get (i). first );
SP . add ( container . get (i). second );
}
ViewHolder Binding
@ Override
public void onBindViewHolder (
@ NonNull MyViewHolder holder,
int position
) {
// Sorting logic...
SalesPerson salesPerson = SP . get (position);
holder . performanceIndex . setText ( PI . get (position));
holder . name . setText ( salesPerson . getName ());
holder . rank . setText ( String . valueOf (position + 1 ) + "." );
ImageSetter . setImage (
context,
holder . imageView ,
salesPerson . getEmailId (),
holder . progressBar
);
}
ViewHolder Structure
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView rank , name , performanceIndex ;
private ImageView imageView ;
private ProgressBar progressBar ;
public MyViewHolder ( View itemView ) {
super (itemView);
rank = itemView . findViewById ( R . id . rank );
name = itemView . findViewById ( R . id . salesperson_name );
performanceIndex = itemView . findViewById (
R . id . performance_index
);
imageView = itemView . findViewById ( R . id . salesperson_pic );
progressBar = itemView . findViewById (
R . id . leaderboard_progress
);
}
}
The adapter returns Math.min(performanceIndex.size(), 10) items, ensuring only the top 10 are displayed even if more data exists.
LeaderBoardObject
Data model for storing leaderboard-related information.
Package : project.avishkar.salesmanagement.Leaderboard
Properties
Unix timestamp of when the salesperson signed up
Constructor
public class LeaderBoardObject {
private String SalespersonName , timestamp ;
public LeaderBoardObject () {
// Default constructor for Firebase
}
public LeaderBoardObject (
String salespersonName ,
String timestamp
) {
this . SalespersonName = salespersonName;
this . timestamp = timestamp;
}
public String getSalespersonName () {
return SalespersonName;
}
public String getTimestamp () {
return timestamp;
}
public void setSalespersonName ( String salespersonName ) {
SalespersonName = salespersonName;
}
public void setTimestamp ( String timestamp ) {
this . timestamp = timestamp;
}
}
Firebase Structure
The leaderboard system uses these Firebase paths:
Salesperson/ : Salesperson profile data
Salesperson//Inventory : Inventory items with profit data
LeaderBoard : Signup timestamps for PI calculation
Key metrics calculated by the leaderboard:
Total Profit : Sum of (items sold × profit per item)
Days Active : Current time - signup timestamp (in days)
Performance Index : Total Profit / Days Active
Target Profit : Current PI + Gap to Top Performer + 10% buffer
The leaderboard uses synchronized methods (ListenerRunner1, ListenerRunner2, ListenerRunner3) to handle concurrent Firebase operations safely.