/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2013 VillageReach
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses. For additional information contact info@OpenLMIS.org.
*/
package org.openlmis.rnr.service;
import org.apache.commons.lang3.time.DateUtils;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.openlmis.core.domain.Money;
import org.openlmis.core.domain.ProcessingPeriod;
import org.openlmis.core.service.ProcessingScheduleService;
import org.openlmis.db.categories.UnitTests;
import org.openlmis.rnr.builder.RnrLineItemBuilder;
import org.openlmis.rnr.domain.*;
import org.openlmis.rnr.repository.RequisitionRepository;
import java.util.*;
import static com.natpryce.makeiteasy.MakeItEasy.*;
import static java.util.Arrays.asList;
import static java.util.Collections.EMPTY_LIST;
import static junit.framework.Assert.assertNull;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.openlmis.core.builder.ProcessingPeriodBuilder.defaultProcessingPeriod;
import static org.openlmis.core.builder.ProcessingPeriodBuilder.numberOfMonths;
import static org.openlmis.rnr.builder.RequisitionBuilder.defaultRequisition;
import static org.openlmis.rnr.builder.RequisitionBuilder.period;
import static org.openlmis.rnr.builder.RnrLineItemBuilder.defaultRnrLineItem;
import static org.openlmis.rnr.domain.RnrStatus.SUBMITTED;
@Category(UnitTests.class)
public class CalculationServiceTest {
private Rnr rnr;
private Integer M;
@Mock
List<LossesAndAdjustmentsType> lossesAndAdjustmentsTypes;
@Mock
RequisitionRepository requisitionRepository;
@Mock
ProcessingScheduleService processingScheduleService;
@InjectMocks
CalculationService calculationService;
private List<ProcessingPeriod> emptyPeriodList;
@Before
public void setUp() throws Exception {
initMocks(this);
rnr = make(a(defaultRequisition));
M = 3;
when(requisitionRepository.getLossesAndAdjustmentsTypes()).thenReturn(lossesAndAdjustmentsTypes);
when(processingScheduleService.findM(rnr.getPeriod())).thenReturn(M);
emptyPeriodList = Collections.emptyList();
}
@Test
public void shouldCallValidateOnEachLineItem() throws Exception {
final RnrLineItem rnrLineItem1 = mock(RnrLineItem.class);
final RnrLineItem rnrLineItem2 = mock(RnrLineItem.class);
when(rnrLineItem1.calculateCost()).thenReturn(new Money("10"));
when(rnrLineItem2.calculateCost()).thenReturn(new Money("10"));
rnr.setFullSupplyLineItems(asList(rnrLineItem1));
rnr.setNonFullSupplyLineItems(asList(rnrLineItem2));
List<RnrColumn> programRnrColumns = new ArrayList<>();
ProgramRnrTemplate template = new ProgramRnrTemplate(programRnrColumns);
calculationService.perform(rnr, template);
verify(rnrLineItem1).validateMandatoryFields(template);
verify(rnrLineItem1).validateCalculatedFields(template);
verify(rnrLineItem2).validateNonFullSupply();
}
@Test
public void shouldCalculateCalculatedFieldsAccordingToProgramTemplate() throws Exception {
ArrayList<RnrColumn> programRequisitionColumns = new ArrayList<>();
ProcessingPeriod period = new ProcessingPeriod();
RnrLineItem firstLineItem = mock(RnrLineItem.class);
RnrLineItem secondLineItem = mock(RnrLineItem.class);
rnr.setFullSupplyLineItems(asList(firstLineItem));
rnr.setNonFullSupplyLineItems(asList(secondLineItem));
rnr.setPeriod(period);
rnr.setStatus(SUBMITTED);
when(firstLineItem.calculateCost()).thenReturn(new Money("10"));
when(secondLineItem.calculateCost()).thenReturn(new Money("20"));
ProgramRnrTemplate template = new ProgramRnrTemplate(programRequisitionColumns);
when(processingScheduleService.findM(period)).thenReturn(M);
calculationService.perform(rnr, template);
verify(firstLineItem).calculateForFullSupply(eq(template), eq(SUBMITTED), eq(lossesAndAdjustmentsTypes), eq(M));
verify(firstLineItem).calculateCost();
verify(secondLineItem).calculateCost();
verify(secondLineItem).calculatePacksToShip();
assertThat(rnr.getFullSupplyItemsSubmittedCost(), is(new Money("10")));
assertThat(rnr.getNonFullSupplyItemsSubmittedCost(), is(new Money("20")));
}
@Test
public void shouldCalculateForVirtualRequisitionUsingDefaultStrategy() throws Exception {
rnr.getFacility().setVirtualFacility(true);
final RnrLineItem rnrLineItem1 = mock(RnrLineItem.class);
ProgramRnrTemplate template = new ProgramRnrTemplate(Collections.<Column>emptyList());
when(rnrLineItem1.calculateCost()).thenReturn(new Money("10"));
rnr.setFullSupplyLineItems(asList(rnrLineItem1));
calculationService.perform(rnr, template);
verify(rnrLineItem1).calculateForFullSupply(eq(template), eq(rnr.getStatus()), eq(lossesAndAdjustmentsTypes), eq(M));
verify(rnrLineItem1).validateMandatoryFields(template);
verify(rnrLineItem1).validateCalculatedFields(template);
}
@Test
public void shouldAvoidCalculationForSkippedFullSupplyLineItems() throws Exception {
ProcessingPeriod period = new ProcessingPeriod();
RnrLineItem skippedLineItem = mock(RnrLineItem.class);
when(skippedLineItem.getSkipped()).thenReturn(true);
RnrLineItem nonSkippedLineItem = mock(RnrLineItem.class);
rnr.setFullSupplyLineItems(asList(skippedLineItem, nonSkippedLineItem));
rnr.setPeriod(period);
rnr.setStatus(SUBMITTED);
when(nonSkippedLineItem.calculateCost()).thenReturn(new Money("20"));
ProgramRnrTemplate template = new ProgramRnrTemplate(new ArrayList<RnrColumn>());
calculationService.perform(rnr, template);
verify(skippedLineItem, never()).calculateForFullSupply(any(ProgramRnrTemplate.class),
any(RnrStatus.class),
anyListOf(LossesAndAdjustmentsType.class), any(Integer.class));
verify(skippedLineItem, never()).calculateCost();
verify(nonSkippedLineItem).calculateCost();
assertThat(rnr.getFullSupplyItemsSubmittedCost(), is(new Money("20")));
}
@Test
public void shouldCalculateDaysDifferenceUsingCurrentPeriodIfPreviousPeriodNotPresent() throws Exception {
Date authorizedDateOfPreviousLineItem = setLineItemDatesAndReturnDate();
Rnr rnr = getVirtualFacilityRnr();
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(emptyPeriodList);
when(requisitionRepository.getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), rnr.getPeriod().getStartDate())).thenReturn(authorizedDateOfPreviousLineItem);
calculationService.fillReportingDays(rnr);
assertThat(lineItem.getReportingDays(), is(5));
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), rnr.getPeriod().getStartDate());
}
@Test
public void shouldCalculateDaysDifferenceUsingPreviousPeriodIfPreviousPeriodPresentButSecondPreviousPeriodIsNotPresent() throws Exception {
Date authorizedDateOfPreviousLineItem = setLineItemDatesAndReturnDate();
Rnr rnr = getVirtualFacilityRnr();
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 2, "previousPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod));
when(requisitionRepository.getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), previousPeriod.getStartDate())).thenReturn(authorizedDateOfPreviousLineItem);
calculationService.fillReportingDays(rnr);
assertThat(lineItem.getReportingDays(), is(5));
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), previousPeriod.getStartDate());
}
@Test
public void shouldCalculateDaysDifferenceUsingSecondPreviousPeriodIfPreviousPeriodAndSecondPreviousPeriodPresent() throws Exception {
Date authorizedDateOfPreviousLineItem = setLineItemDatesAndReturnDate();
Rnr rnr = getVirtualFacilityRnr();
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 2, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, new Date(), new Date(), 2, "secondLastPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod, secondLastPeriod));
when(requisitionRepository.getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), secondLastPeriod.getStartDate())).thenReturn(authorizedDateOfPreviousLineItem);
calculationService.fillReportingDays(rnr);
assertThat(lineItem.getReportingDays(), is(5));
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), secondLastPeriod.getStartDate());
}
@Test
public void shouldCalculateDaysDifferenceUsingPreviousPeriodIfPreviousPeriodPresentAndNumberOfMonthsIsGreaterThanOrEqualToThree() throws Exception {
Date authorizedDateOfPreviousLineItem = setLineItemDatesAndReturnDate();
Rnr rnr = getVirtualFacilityRnr();
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 4, "previousPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod));
when(requisitionRepository.getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), previousPeriod.getStartDate())).thenReturn(authorizedDateOfPreviousLineItem);
calculationService.fillReportingDays(rnr);
assertThat(lineItem.getReportingDays(), is(5));
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), previousPeriod.getStartDate());
}
@Test
public void shouldCalculateDaysDifferenceUsingSecondPreviousPeriodIfMIsSmallerThanThree() throws Exception {
Date authorizedDateOfPreviousLineItem = setLineItemDatesAndReturnDate();
Rnr rnr = getVirtualFacilityRnr();
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 2, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, new Date(), new Date(), 2, "secondLastPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod, secondLastPeriod));
when(requisitionRepository.getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), secondLastPeriod.getStartDate())).thenReturn(authorizedDateOfPreviousLineItem);
calculationService.fillReportingDays(rnr);
assertThat(lineItem.getReportingDays(), is(5));
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), secondLastPeriod.getStartDate());
}
@Test
public void shouldNotCalculateDaysDifferenceIfPreviousAuthorizedLineItemIsNotPresent() throws Exception {
Rnr rnr = getVirtualFacilityRnr();
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 4, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, new Date(), new Date(), 2, "secondLastPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod, secondLastPeriod));
when(requisitionRepository.getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), secondLastPeriod.getStartDate())).thenReturn(null);
calculationService.fillReportingDays(rnr);
assertNull(lineItem.getReportingDays());
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), secondLastPeriod.getStartDate());
}
@Test
public void shouldNotCalculateDaysDifferenceIfCurrentLineItemIsSkipped() throws Exception {
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
lineItem.setSkipped(true);
rnr.setFullSupplyLineItems(asList(lineItem));
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 4, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, new Date(), new Date(), 2, "secondLastPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod, secondLastPeriod));
calculationService.fillReportingDays(rnr);
assertNull(lineItem.getReportingDays());
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository, never()).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), secondLastPeriod.getStartDate());
}
@Test
public void shouldGetPreviousOneNormalizedConsumptionFor3MonthsInCurrentPeriodIfPreviousPeriodNotExists() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
requisition.setPeriod(make(a(defaultProcessingPeriod, with(numberOfMonths, 3))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(null, programTemplate, regimenTemplate);
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(emptyPeriodList);
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, requisition.getPeriod().getStartDate())).thenReturn(rnrLineItems);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, requisition.getPeriod().getStartDate());
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4)));
}
@Test
public void shouldGetPreviousOneNormalizedConsumptionFor2MonthsInCurrentPeriodIfPreviousPeriodNotExists() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
requisition.setPeriod(make(a(defaultProcessingPeriod, with(numberOfMonths, 2))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(null, programTemplate, regimenTemplate);
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(emptyPeriodList);
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, requisition.getPeriod().getStartDate())).thenReturn(rnrLineItems);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, requisition.getPeriod().getStartDate());
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4)));
}
@Test
public void shouldGetPreviousTwoNormalizedConsumptionFor1MonthInCurrentPeriodIfPreviousPeriodDoesNotExist() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
requisition.setPeriod(make(a(defaultProcessingPeriod, with(numberOfMonths, 1))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(null, programTemplate, regimenTemplate);
when(processingScheduleService.findM(requisition.getPeriod())).thenReturn(1);
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(emptyPeriodList);
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
RnrLineItem rnrLineItem2 = new RnrLineItem();
rnrLineItem2.setNormalizedConsumption(9);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem, rnrLineItem2);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 2, requisition.getPeriod().getStartDate())).thenReturn(rnrLineItems);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 2, requisition.getPeriod().getStartDate());
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4, 9)));
}
@Test
public void shouldGetPreviousOneNormalizedConsumptionFor3MonthsInPreviousPeriod() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
Date trackingStartDate = new Date();
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, trackingStartDate, new Date(), 3, "previousPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(asList(previousPeriod));
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, previousPeriod.getStartDate())).thenReturn(rnrLineItems);
Rnr previousRnr = make(a(defaultRequisition, with(period, make(a(defaultProcessingPeriod, with(numberOfMonths, 3))))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
when(requisitionRepository.getLastRegularRequisitionToEnterThePostSubmitFlow( requisition.getFacility().getId(), requisition.getProgram().getId() )).thenReturn(previousRnr);
when(requisitionRepository.getById(previousRnr.getId())).thenReturn(previousRnr);
when(requisitionRepository.getRegularRequisitionWithLineItems(requisition.getFacility(), requisition.getProgram(), previousPeriod)).thenReturn(previousRnr);
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(previousRnr, programTemplate, regimenTemplate);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, previousPeriod.getStartDate());
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4)));
}
@Test
public void shouldGetPreviousOneNormalizedConsumptionFor2MonthsInPreviousPeriod() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
Date trackingStartDate = DateTime.now().minusMonths(2).toDate();
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 2, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, trackingStartDate, new Date(), 2, "secondLastPeriod");
when(processingScheduleService.findM(requisition.getPeriod())).thenReturn(2);
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(asList(previousPeriod, secondLastPeriod));
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, trackingStartDate)).thenReturn(rnrLineItems);
Rnr previousRnr = make(a(defaultRequisition, with(period, make(a(defaultProcessingPeriod, with(numberOfMonths, 3))))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
when(requisitionRepository.getRegularRequisitionWithLineItems(requisition.getFacility(), requisition.getProgram(), previousPeriod)).thenReturn(previousRnr);
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(previousRnr, programTemplate, regimenTemplate);
when(requisitionRepository.getLastRegularRequisitionToEnterThePostSubmitFlow( requisition.getFacility().getId(), requisition.getProgram().getId() )).thenReturn(previousRnr);
when(requisitionRepository.getById(previousRnr.getId())).thenReturn(previousRnr);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, trackingStartDate);
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4)));
}
@Test
public void shouldGetPreviousOneNormalizedConsumptionFor2MonthsInPreviousPeriodAndTrackFromPreviousPeriodStartDateIfOnly1PreviousPeriodExists() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
Date trackingStartDate = DateTime.now().minusMonths(2).toDate();
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, trackingStartDate, new Date(), 2, "previousPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(asList(previousPeriod));
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, trackingStartDate)).thenReturn(rnrLineItems);
Rnr previousRnr = make(a(defaultRequisition, with(period, make(a(defaultProcessingPeriod, with(numberOfMonths, 3))))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
when(requisitionRepository.getRegularRequisitionWithLineItems(requisition.getFacility(), requisition.getProgram(), previousPeriod)).thenReturn(previousRnr);
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(previousRnr, programTemplate, regimenTemplate);
when(requisitionRepository.getLastRegularRequisitionToEnterThePostSubmitFlow( requisition.getFacility().getId(), requisition.getProgram().getId() )).thenReturn(previousRnr);
when(requisitionRepository.getById(previousRnr.getId())).thenReturn(previousRnr);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, trackingStartDate);
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4)));
}
@Test
public void shouldGetPreviousOneNormalizedConsumptionFor2MonthsInPreviousPeriodAndShouldTrackFromLast2Periods() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
Date trackingStartDate = DateTime.now().minusMonths(2).toDate();
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 2, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, trackingStartDate, new Date(), 2, "secondLastPeriod");
ProcessingPeriod thirdLastPeriod = new ProcessingPeriod(4l, new Date(), new Date(), 1, "thirdLastPeriod");
when(processingScheduleService.findM(requisition.getPeriod())).thenReturn(2);
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(asList(previousPeriod, secondLastPeriod, thirdLastPeriod));
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, trackingStartDate)).thenReturn(rnrLineItems);
Rnr previousRnr = make(a(defaultRequisition, with(period, make(a(defaultProcessingPeriod, with(numberOfMonths, 3))))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
when(requisitionRepository.getLastRegularRequisitionToEnterThePostSubmitFlow( requisition.getFacility().getId(), requisition.getProgram().getId() )).thenReturn(previousRnr);
when(requisitionRepository.getById(previousRnr.getId())).thenReturn(previousRnr);
when(requisitionRepository.getRegularRequisitionWithLineItems(requisition.getFacility(), requisition.getProgram(), previousPeriod)).thenReturn(previousRnr);
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(previousRnr, programTemplate, regimenTemplate);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 1, trackingStartDate);
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4)));
}
@Test
public void shouldGetPreviousTwoNormalizedConsumptionsFor1MonthInPreviousPeriodAndShouldTrackFromLast5Periods() throws Exception {
Rnr requisition = getVirtualFacilityRnr();
String productCode = "Code1";
requisition.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
Date trackingStartDate = DateTime.now().minusMonths(2).toDate();
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 1, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, new Date(), new Date(), 1, "secondLastPeriod");
ProcessingPeriod thirdLastPeriod = new ProcessingPeriod(4l, new Date(), new Date(), 1, "thirdLastPeriod");
ProcessingPeriod fourthLastPeriod = new ProcessingPeriod(5l, new Date(), new Date(), 1, "fourthLastPeriod");
ProcessingPeriod fifthLastPeriod = new ProcessingPeriod(6l, trackingStartDate, new Date(), 1, "fifthLastPeriod");
when(processingScheduleService.findM(requisition.getPeriod())).thenReturn(1);
when(processingScheduleService.getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5)).thenReturn(asList(previousPeriod, secondLastPeriod, thirdLastPeriod, fourthLastPeriod, fifthLastPeriod));
RnrLineItem rnrLineItem = new RnrLineItem();
rnrLineItem.setNormalizedConsumption(4);
RnrLineItem rnrLineItem2 = new RnrLineItem();
rnrLineItem2.setNormalizedConsumption(5);
List<RnrLineItem> rnrLineItems = asList(rnrLineItem, rnrLineItem2);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 2, trackingStartDate)).thenReturn(rnrLineItems);
Rnr previousRnr = make(a(defaultRequisition, with(period, make(a(defaultProcessingPeriod, with(numberOfMonths, 3))))));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
when(requisitionRepository.getRegularRequisitionWithLineItems(requisition.getFacility(), requisition.getProgram(), previousPeriod)).thenReturn(previousRnr);
when(requisitionRepository.getLastRegularRequisitionToEnterThePostSubmitFlow( requisition.getFacility().getId(), requisition.getProgram().getId() )).thenReturn(previousRnr);
when(requisitionRepository.getById(previousRnr.getId())).thenReturn(previousRnr);
doNothing().when(requisition).setFieldsAccordingToTemplateFrom(previousRnr, programTemplate, regimenTemplate);
calculationService.fillFieldsForInitiatedRequisition(requisition, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(requisition.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, requisition, 2, trackingStartDate);
assertThat(requisition.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(4, 5)));
}
@Test
public void shouldNotTrackPreviousRequisitionsIfRegularRnrAndMIs3() throws Exception {
Rnr spyRnr = spy(rnr);
String productCode = "Code1";
spyRnr.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 3, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, new Date(), new Date(), 3, "secondLastPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(spyRnr.getPeriod(), 5)).thenReturn(asList(previousPeriod, secondLastPeriod));
Rnr previousRnr = make(a(defaultRequisition, with(period, previousPeriod)));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
when(requisitionRepository.getRegularRequisitionWithLineItems(spyRnr.getFacility(), spyRnr.getProgram(), previousPeriod)).thenReturn(previousRnr);
doNothing().when(spyRnr).setFieldsAccordingToTemplateFrom(previousRnr, programTemplate, regimenTemplate);
when(requisitionRepository.getLastRegularRequisitionToEnterThePostSubmitFlow( rnr.getFacility().getId(), rnr.getProgram().getId() )).thenReturn(previousRnr);
when(requisitionRepository.getById(previousRnr.getId())).thenReturn(previousRnr);
calculationService.fillFieldsForInitiatedRequisition(spyRnr, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(spyRnr.getPeriod(), 5);
verify(requisitionRepository, never()).getAuthorizedRegularUnSkippedLineItems(anyString(), any(Rnr.class), anyInt(), any(Date.class));
assertThat(rnr.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(EMPTY_LIST));
}
@Test
public void shouldTrackPreviousRequisitionsIfRegularRnrAndMIs1() throws Exception {
Rnr spyRnr = spy(rnr);
String productCode = "Code1";
spyRnr.setFullSupplyLineItems(asList(make(a(defaultRnrLineItem, with(RnrLineItemBuilder.productCode, productCode)))));
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 1, "previousPeriod");
ProcessingPeriod secondLastPeriod = new ProcessingPeriod(3l, new Date(), new Date(), 1, "secondLastPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(spyRnr.getPeriod(), 5)).thenReturn(asList(previousPeriod, secondLastPeriod));
RnrLineItem previousLineItem1 = new RnrLineItem();
previousLineItem1.setNormalizedConsumption(5);
RnrLineItem previousLineItem2 = new RnrLineItem();
previousLineItem2.setNormalizedConsumption(50);
when(requisitionRepository.getAuthorizedRegularUnSkippedLineItems(productCode, spyRnr, 2, secondLastPeriod.getStartDate())).thenReturn(asList(previousLineItem1, previousLineItem2));
Rnr previousRnr = make(a(defaultRequisition, with(period, previousPeriod)));
ProgramRnrTemplate programTemplate = new ProgramRnrTemplate();
RegimenTemplate regimenTemplate = new RegimenTemplate();
when(requisitionRepository.getRegularRequisitionWithLineItems(spyRnr.getFacility(), spyRnr.getProgram(), previousPeriod)).thenReturn(previousRnr);
doNothing().when(spyRnr).setFieldsAccordingToTemplateFrom(previousRnr, programTemplate, regimenTemplate);
when(requisitionRepository.getLastRegularRequisitionToEnterThePostSubmitFlow( rnr.getFacility().getId(), rnr.getProgram().getId() )).thenReturn(previousRnr);
when(requisitionRepository.getById(previousRnr.getId())).thenReturn(previousRnr);
calculationService.fillFieldsForInitiatedRequisition(spyRnr, programTemplate, regimenTemplate);
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(spyRnr.getPeriod(), 5);
verify(requisitionRepository).getAuthorizedRegularUnSkippedLineItems(productCode, spyRnr, 2, secondLastPeriod.getStartDate());
assertThat(spyRnr.getFullSupplyLineItems().get(0).getPreviousNormalizedConsumptions(), is(asList(5, 50)));
}
@Test
public void shouldSetDto90daysForRegularRnrWithMEqualTo3() throws Exception {
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
Integer numberOfMonths = 3;
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), numberOfMonths, "previousPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod));
calculationService.fillReportingDays(rnr);
Integer expectedNumberOfDays = 90;
assertThat(lineItem.getReportingDays(), is(expectedNumberOfDays));
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository, never()).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), previousPeriod.getStartDate());
}
@Test
public void shouldUseCurrentPeriodStartDateToCalculateDForEmergencyRnr() throws Exception {
rnr.setEmergency(true);
rnr.setCreatedDate(DateUtils.parseDate("01-02-12", "dd-MM-yy"));
RnrLineItem lineItem = rnr.getFullSupplyLineItems().get(0);
ProcessingPeriod previousPeriod = new ProcessingPeriod(2l, new Date(), new Date(), 3, "previousPeriod");
when(processingScheduleService.getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2)).thenReturn(asList(previousPeriod));
calculationService.fillReportingDays(rnr);
Integer expectedNumberOfDays = 31;
assertThat(lineItem.getReportingDays(), is(expectedNumberOfDays));
verify(processingScheduleService).getNPreviousPeriodsInDescOrder(rnr.getPeriod(), 2);
verify(requisitionRepository, never()).getAuthorizedDateForPreviousLineItem(rnr, lineItem.getProductCode(), previousPeriod.getStartDate());
}
private Rnr getVirtualFacilityRnr() {
//TODO: Inline method when calculating for regular
Rnr spy = spy(rnr);
spy.getFacility().setVirtualFacility(true);
return spy;
}
private Date setLineItemDatesAndReturnDate() {
Calendar currentDate = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Calendar previousDate = (Calendar) currentDate.clone();
previousDate.add(Calendar.DATE, -5);
Date authorizedDateOfPreviousLineItem = new Date(previousDate.getTimeInMillis());
Date createdDateOfCurrentLineItem = new Date(currentDate.getTimeInMillis());
rnr.setCreatedDate(createdDateOfCurrentLineItem);
return authorizedDateOfPreviousLineItem;
}
}