Count only the days that are workable

FEA: ItEr61OTS04PlanificacionHaciaAtras
This commit is contained in:
Óscar González Fernández 2010-11-11 01:15:55 +01:00
parent 1be1eb1714
commit 5dd3f2e70a
6 changed files with 84 additions and 35 deletions

View file

@ -682,15 +682,45 @@ public class Task extends TaskElement implements ITaskLeafConstraint {
public Integer getWorkableDays() {
if (workableDays == null) {
return getDaysBetweenDates();
return getWorkableDaysBetweenDates();
}
return workableDays;
}
public Integer getDaysBetweenDates() {
Days daysBetween = Days.daysBetween(getStartAsLocalDate(),
getIntraDayEndDate().asExclusiveEnd());
return daysBetween.getDays();
}
private Integer getWorkableDaysBetweenDates() {
int result = 0;
LocalDate start = getStartAsLocalDate();
LocalDate end = getIntraDayEndDate().asExclusiveEnd();
for (LocalDate current = start; current.compareTo(end) < 0; current = current
.plusDays(1)) {
if (isWorkable(current)) {
result++;
}
}
return result;
}
public LocalDate calculateEndGivenWorkableDays(int workableDays) {
LocalDate result = getIntraDayStartDate().getDate();
for (int i = 0; i < workableDays; result = result.plusDays(1)) {
if (isWorkable(result)) {
i++;
}
}
return result;
}
private boolean isWorkable(LocalDate day) {
ICalendar calendar = getCalendar();
assert calendar != null;
return !calendar.getCapacityOn(PartialDay.wholeDay(day)).isZero();
}
}

View file

@ -22,21 +22,27 @@ package org.navalplanner.business.test.planner.entities;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.getCurrentArguments;
import static org.easymock.EasyMock.isA;
import static org.easymock.classextension.EasyMock.createNiceMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.resetToNice;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
import static org.navalplanner.business.workingday.EffortDuration.hours;
import java.util.Arrays;
import java.util.Date;
import org.easymock.IAnswer;
import org.joda.time.LocalDate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderLine;
@ -49,6 +55,7 @@ import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueue
import org.navalplanner.business.scenarios.entities.OrderVersion;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.IntraDayDate;
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@ -74,6 +81,8 @@ public class TaskTest {
private HoursGroup hoursGroup;
private BaseCalendar calendar;
public TaskTest() {
hoursGroup = new HoursGroup();
hoursGroup.setWorkingHours(3);
@ -82,6 +91,7 @@ public class TaskTest {
order.setInitDate(new Date());
OrderLine orderLine = OrderLine.create();
order.add(orderLine);
order.setCalendar(stubCalendar());
SchedulingDataForVersion version = TaskElementTest
.mockSchedulingDataForVersion(orderLine);
TaskSource taskSource = TaskSource.create(version, Arrays
@ -89,6 +99,14 @@ public class TaskTest {
task = Task.createTask(taskSource);
}
private BaseCalendar stubCalendar() {
calendar = createNiceMock(BaseCalendar.class);
expect(calendar.getCapacityOn(isA(PartialDay.class)))
.andReturn(hours(8)).anyTimes();
replay(calendar);
return calendar;
}
@Test
public void taskIsASubclassOfTaskElement() {
assertTrue(task instanceof TaskElement);
@ -173,7 +191,7 @@ public class TaskTest {
}
@Test
public void theDaysBetweenIsCalculatedBasedOnlyOnDatesNotHours() {
public void theWorkableDaysAreCalculatedBasedOnlyOnDatesNotHours() {
task.setIntraDayStartDate(IntraDayDate.create(
new LocalDate(2010, 1, 13), EffortDuration.hours(3)));
task.setIntraDayEndDate(IntraDayDate.startOfDay(new LocalDate(2010, 1,
@ -201,6 +219,30 @@ public class TaskTest {
assertThat(task.getWorkableDays(), equalTo(2));
}
@Test
public void ifSomeDayIsNotWorkableIsNotCounted() {
final LocalDate start = new LocalDate(2010, 1, 13);
resetToNice(calendar);
expect(calendar.getCapacityOn(isA(PartialDay.class))).andAnswer(
new IAnswer<EffortDuration>() {
@Override
public EffortDuration answer() throws Throwable {
Object[] args = getCurrentArguments();
PartialDay day = (PartialDay) args[0];
return day.getDate().equals(start.plusDays(1)) ? hours(0)
: hours(8);
}
}).anyTimes();
replay(calendar);
task.setIntraDayStartDate(IntraDayDate.create(start,
EffortDuration.hours(3)));
task.setIntraDayEndDate(IntraDayDate.create(start.plusDays(1),
EffortDuration.minutes(1)));
assertThat(task.getWorkableDays(), equalTo(1));
}
/**
* @param task
* @param hours

View file

@ -308,11 +308,12 @@ public class FormBinder {
@Override
public void onEvent(Event event) throws Exception {
Date newEndDate = calculateEndDate(taskWorkableDays
.getValue());
Task task = allocationRowsHandler.getTask();
LocalDate newEndDate = task
.calculateEndGivenWorkableDays(taskWorkableDays
.getValue());
taskPropertiesController.updateTaskEndDate(newEndDate);
showValueOfDateOn(labelTaskEnd,
LocalDate.fromDateFields(newEndDate));
showValueOfDateOn(labelTaskEnd, newEndDate);
}
});
taskDurationDisabilityRule();
@ -325,18 +326,9 @@ public class FormBinder {
label.setValue(formatter.print(date));
}
private Date calculateEndDate(int duration) {
LocalDate result = new LocalDate(getPlannedTaskStart());
result = result.plusDays(duration);
return toDate(result);
}
private Date toDate(LocalDate date) {
return date.toDateTimeAtStartOfDay().toDate();
}
public Date getPlannedTaskStart() {
return resourceAllocationModel.getTaskStart();
public LocalDate getAllocationEnd() {
Task task = allocationRowsHandler.getTask();
return task.calculateEndGivenWorkableDays(taskWorkableDays.getValue());
}
public void setAllResourcesPerDay(Decimalbox allResourcesPerDay) {
@ -481,11 +473,6 @@ public class FormBinder {
return result;
}
public LocalDate getAllocationEnd() {
LocalDate result = new LocalDate(taskStartDate);
return result.plusDays(getWorkableDays().intValue());
}
public Integer getWorkableDays() {
return taskWorkableDays.getValue();
}

View file

@ -73,8 +73,6 @@ public interface IResourceAllocationModel extends INewAllocationsAdder {
ProportionalDistributor addDefaultAllocations();
Date getTaskStart();
void setStartDate(Date date);
Date getTaskEnd();

View file

@ -388,14 +388,6 @@ public class ResourceAllocationModel implements IResourceAllocationModel {
return AggregatedHoursGroup.sum(task.getAggregatedByCriterions());
}
@Override
public Date getTaskStart() {
if (task == null) {
return null;
}
return task.getStartDate();
}
@Override
public Date getTaskEnd() {
if (task == null) {

View file

@ -663,8 +663,8 @@ public class TaskPropertiesController extends GenericForwardComposer {
return false;
}
public void updateTaskEndDate(Date endDate) {
getGanttTaskDTO().endDate = endDate;
public void updateTaskEndDate(LocalDate endDate) {
getGanttTaskDTO().endDate = endDate.toDateTimeAtStartOfDay().toDate();
Util.reloadBindings(endDateBox);
}
}