## #59 BCWP calculations

1.5.2
open
nobody
Other
Other
Other
Other
Normal
2015-02-20
2013-03-07
Julien Lamarche
No

I thought I'd re-post to the ticketing system from my blog. I thought I might have found a bug the way bcwp was calculated. But I could be wrong, perhaps I misunderstood the intention of the code.

Are there different ways to calculate BCWP?

ProjectLibre, v 1.5, calculates it the following way:

```        //[(Actual % of completion / Expected % of completion) of an activity for a given period] * Actual cost of activity
public double bcwp(long start, long end) {
if (!isInRange(start,end))
return NO_VALUE_DOUBLE;
end = Math.min(end,getStatusDate());
if (end == 0)
return 0.0D;
start = getStart(); // start from the beginning of the task and ignore the range start
double cost = actualCost(start,end);
if (cost == 0)
return 0;
return efficiency() * cost;
}
```

When I saw this, my reaction was "Why would the actual cost be part of BCWP?". Wikipedia defines BCWP, as I learned in class, as BAC * % complete.

Now its possible that I'm misinterpreting the function actualCost. When programming, variable names can be confounded with their actual meaning as the code gets bigger and bigger

But when I set % complete to 100% for a task that was due to finish in the future, my SPI is still set to 1. My understanding is that it should be higher than 1. I talk more about this in the projectlibre community forum: http://www.projectlibre.org/discussion/how-bcwp-calculated

So, while acknowledging I could be misunderstanding the output and intent of the code, here's what I think it should be:

```    // bac * percent complete -- cyclingzealot
// Changed from:
//[(Actual % of completion / Expected % of completion) of an activity for a given period] * Actual cost of activity
public double bcwp(long start, long end) {
if (!isInRange(start,end))
return NO_VALUE_DOUBLE;
end = Math.min(end,getStatusDate());
if (end == 0)
return 0.0D;
start = getStart(); // start from the beginning of the task and ignore the range start
double bac = bac(0,DateTime.getMaxDate().getTime());
double percentComplete = this.getPercentComplete();
if (bac == 0)
return 0;
return percentComplete * bac;
}
```

Again, totally possible I misunderstood the code. One thing I noticed is that start and end is used in the former calculation, whereas I'll get the bac from 0 to end. Its possible that the former code has use in calculating earned value through time.