HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Calculating total sales from each member

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
totaleachcalculatingmembersalesfrom

Problem

I am building a new system that is using some tables from an old system.

For each user on this new system, I need to go to the old system and total up their sales. Currently it takes between 2-5 minutes to load.

public static List GetListDailyTeamGoals(int teamId)
{
    string teamGoal = "";
    List lstProPit_User = new List();
    using (ProsPitEntities db = new ProsPitEntities())
    {
        // Find the team
        Team team = db.Teams.Where(x => x.teamID == teamId).FirstOrDefault();

        if (team != null)
        {
            // Grab team goal
            teamGoal = Convert.ToString(team.goal);
        }
        // Make a list of all users who are on the team
        lstProPit_User = db.ProPit_User.Where(x => x.teamID == teamId).ToList();
    }

    List lstDailyTeamGoal = new List();
    using (TEntities db = new TEntities())
    {
        //have to get every day of the month
        DateTime dt = DateTime.Now;
        int days = DateTime.DaysInMonth(dt.Year, dt.Month);
        decimal orderTotal = 0m;
        for (int day = 1; day = dtStartDate
                                    where o.DateCompleted <= dtEndDate
                                    where (o.Status == 1 || o.Status == 2)
                                    where o.Kiosk != 0
                                    where o.SalesRepID == propit_User.SalesRepID
                                    orderby o.OrderTotal descending
                                    select o.OrderTotal).ToList();

                foreach (var item in lstorderTotalRep)
                {
                    //orderTotalRep =+ item;
                    orderTotalRep += item;
                }
            }

            orderTotal += orderTotalRep;
            dtg.DailyTotal = orderTotal;

            lstDailyTeamGoal.Add(dtg);
        }
    }

    return lstDailyTeamGoal;
}


The above code will use my site to find the teamID the logged in person is on. It will then find all members who are on that tea

Solution

I won't comment about the fact that this is a static method in what's possibly a static "helper" class and that it would be much prettier in a service class instance... but I just did.

The method is doing way too many things.

Thing one:

// Make a list of all users who are on the team


That's one method. But there's a twist: you not only need all users on the team, but also the teamGoal figure. I'd encapsulate that in its own class:

public class TeamGoalAndUsersResult // todo: rename this class
{
    public IEnumerable Users { get; private set; }
    public string Goal { get; private set; }

    public TeamGoalAndUsersResult(string goal, IEnumerable users)
    {
        Users = users;
        Goal = goal;
    }
}


And then you can write a method/function that will return that type:

private TeamGoalAndUsersResult GetTeamGoalAndUsers(int teamId)
{
    using (ProsPitEntities db = new ProsPitEntities())
    {
        var goal = string.Empty;
        var team = db.Teams.SingleOrDefault(x => x.teamID == teamId);
        if (team != null)
        {
            goal = Convert.ToString(team.goal);
        }

        var users = db.ProPit_User.Where(x => x.teamID == teamId).ToList();
        return new TeamGoalAndUsersResult(goal, users);
    }
}


Performance Issue:

var lstorderTotalRep = (from o in db.Orders
                                where o.DateCompleted >= dtStartDate
                                where o.DateCompleted <= dtEndDate
                                where (o.Status == 1 || o.Status == 2)
                                where o.Kiosk != 0
                                where o.SalesRepID == propit_User.SalesRepID
                                orderby o.OrderTotal descending
                                select o.OrderTotal).ToList();

            foreach (var item in lstorderTotalRep)
            {
                //orderTotalRep =+ item;
                orderTotalRep += item;
            }


You're doing all the computation on the client. I'd take a wild guess and say that this is where your bottleneck is. Do you really need to select, sort and materialize all orders just to sum up OrderTotal?

var total = db.Orders.Where(o => o.DateCompleted >= dtStartDate
                              && o.DateCompleted  o.OrderTotal);

orderTotal += total;
dtg.DailyTotal = orderTotal;
dailyTeamGoals.Add(dtg);


The above doesn't sort anything, has the same criterion and performs everything on the server side, without materializing every order in the way. Also I believe if the table has all the fields used in the WHERE, in an index (guts tell me "especially DateCompleted"), that would further help the server-side processing, but that's something you're probably better off finding out with a profiler.

Code Snippets

// Make a list of all users who are on the team
public class TeamGoalAndUsersResult // todo: rename this class
{
    public IEnumerable<ProPit_User> Users { get; private set; }
    public string Goal { get; private set; }

    public TeamGoalAndUsersResult(string goal, IEnumerable<ProPit_User> users)
    {
        Users = users;
        Goal = goal;
    }
}
private TeamGoalAndUsersResult GetTeamGoalAndUsers(int teamId)
{
    using (ProsPitEntities db = new ProsPitEntities())
    {
        var goal = string.Empty;
        var team = db.Teams.SingleOrDefault(x => x.teamID == teamId);
        if (team != null)
        {
            goal = Convert.ToString(team.goal);
        }

        var users = db.ProPit_User.Where(x => x.teamID == teamId).ToList();
        return new TeamGoalAndUsersResult(goal, users);
    }
}
var lstorderTotalRep = (from o in db.Orders
                                where o.DateCompleted >= dtStartDate
                                where o.DateCompleted <= dtEndDate
                                where (o.Status == 1 || o.Status == 2)
                                where o.Kiosk != 0
                                where o.SalesRepID == propit_User.SalesRepID
                                orderby o.OrderTotal descending
                                select o.OrderTotal).ToList();

            foreach (var item in lstorderTotalRep)
            {
                //orderTotalRep =+ item;
                orderTotalRep += item;
            }
var total = db.Orders.Where(o => o.DateCompleted >= dtStartDate
                              && o.DateCompleted <= dtEndDate
                              && (o.Status == 1 || o.Status == 2)
                              && o.Kiosk != 0
                              && o.SalesRepID == user.SalesRepID)
                     .Sum(o => o.OrderTotal);

orderTotal += total;
dtg.DailyTotal = orderTotal;
dailyTeamGoals.Add(dtg);

Context

StackExchange Code Review Q#48002, answer score: 3

Revisions (0)

No revisions yet.