@Test
  public void testUpdateDOBAndCompleteActiveSubscription() throws Exception {
    createLocationData();

    Long msisdn = subscriptionHelper.makeNumber();
    String childId = "0123456789";
    DateTime originalDOB = DateTime.now().minusDays(100);
    DateTime updatedDOB = originalDOB.minusDays(400);

    MctsChild child = new MctsChild(childId);
    child.setState(stateDataService.findByCode(21L));
    child.setDistrict(districtService.findByStateAndCode(child.getState(), 3L));
    makeMctsSubscription(child, originalDOB, SubscriptionPackType.CHILD, msisdn);

    // verify that the subscription is active
    Subscriber subscriber = subscriberDataService.findByCallingNumber(msisdn);
    Subscription subscription = subscriber.getAllSubscriptions().iterator().next();
    assertEquals(SubscriptionStatus.ACTIVE, subscription.getStatus());

    // now, via CSV update, change the DOB to a past subscription date; subscription should be
    // marked completed
    Reader reader =
        createUpdateReaderWithHeaders(
            "1," + childId + ",," + getDateString(updatedDOB) + ",,,,,,,,,,,");
    mctsBeneficiaryUpdateService.updateBeneficiaryData(reader);

    Subscriber updatedSubscriber = subscriberDataService.findByCallingNumber(msisdn);
    assertEquals(getDateString(updatedDOB), getDateString(updatedSubscriber.getDateOfBirth()));
    Subscription updatedSubscription = updatedSubscriber.getAllSubscriptions().iterator().next();
    assertEquals(getDateString(updatedDOB), getDateString(updatedSubscription.getStartDate()));
    assertEquals(SubscriptionStatus.COMPLETED, updatedSubscription.getStatus());
  }
  /*
   * To verify that NMS is not able to change the location of
   * beneficiary using MCTS ID when location information is wrong.
   *
   * https://applab.atlassian.net/browse/NMS-231
   */
  @Test
  public void verifyFT325() throws Exception {
    createLocationData();

    Long msisdn = subscriptionHelper.makeNumber();
    String childId = "0123456789";

    MctsChild child = new MctsChild(childId);
    child.setState(stateDataService.findByCode(21L));
    child.setDistrict(districtService.findByStateAndCode(child.getState(), 2L));
    makeMctsSubscription(child, DateTime.now().minusDays(100), SubscriptionPackType.CHILD, msisdn);

    // district provided in request doesn't exist in nms-db
    Reader reader = createUpdateReaderWithHeaders("1," + childId + ",,,,21,8,0026,453,,,,,,");
    mctsBeneficiaryUpdateService.updateBeneficiaryData(reader);

    Subscriber subscriber = subscriberDataService.findByCallingNumber(msisdn);
    assertNotNull(subscriber);
    assertNotEquals(subscriber.getChild().getDistrict().getCode(), new Long(7));

    List<SubscriptionError> susbErrors = subscriptionErrorDataService.findByBeneficiaryId(childId);
    SubscriptionError susbError = susbErrors.iterator().next();
    assertNotNull(susbError);
    assertEquals(SubscriptionRejectionReason.INVALID_LOCATION, susbError.getRejectionReason());
  }
  @Test
  public void testUpdateLMP() throws Exception {
    createLocationData();

    Long msisdn = subscriptionHelper.makeNumber();
    String motherId = "0123456789";
    DateTime originalLMP = DateTime.now().minusDays(100);
    DateTime updatedLMP = originalLMP.minusDays(200);

    subscriptionHelper.mksub(
        SubscriptionOrigin.MCTS_IMPORT, originalLMP, SubscriptionPackType.PREGNANCY, msisdn);
    Subscriber subscriber = subscriberDataService.findByCallingNumber(msisdn);
    subscriber.setLastMenstrualPeriod(originalLMP);
    MctsMother mother = new MctsMother(motherId);
    mother.setState(stateDataService.findByCode(21L));
    mother.setDistrict(districtService.findByStateAndCode(mother.getState(), 3L));
    subscriber.setMother(mother);
    subscriberDataService.update(subscriber);

    Reader reader =
        createUpdateReaderWithHeaders(
            "1," + motherId + ",,," + getDateString(updatedLMP) + ",,,,,,,,,,");
    mctsBeneficiaryUpdateService.updateBeneficiaryData(reader);

    Subscriber updatedSubscriber = subscriberDataService.findByCallingNumber(msisdn);
    assertEquals(
        getDateString(updatedLMP), getDateString(updatedSubscriber.getLastMenstrualPeriod()));
    Subscription updatedSubscription =
        updatedSubscriber.getActiveAndPendingSubscriptions().iterator().next();
    assertEquals(
        getDateString(updatedLMP.plusDays(90)), getDateString(updatedSubscription.getStartDate()));
    assertEquals(SubscriptionStatus.ACTIVE, updatedSubscription.getStatus());
  }
  @Test
  public void testUpdateDOB() throws Exception {
    createLocationData();

    Long msisdn = subscriptionHelper.makeNumber();
    String childId = "0123456789";
    DateTime originalDOB = DateTime.now();
    DateTime updatedDOB = originalDOB.minusDays(100);

    subscriptionHelper.mksub(
        SubscriptionOrigin.MCTS_IMPORT, originalDOB, SubscriptionPackType.CHILD, msisdn);
    Subscriber subscriber = subscriberDataService.findByCallingNumber(msisdn);
    subscriber.setDateOfBirth(originalDOB);
    MctsChild child = new MctsChild(childId);
    child.setState(stateDataService.findByCode(21L));
    child.setDistrict(districtService.findByStateAndCode(child.getState(), 3L));
    subscriber.setChild(child);
    subscriberDataService.update(subscriber);

    // this updates the db with the new data (DOB)
    Reader reader =
        createUpdateReaderWithHeaders(
            "1," + childId + ",," + getDateString(updatedDOB) + ",,,,,,,,,,,");
    mctsBeneficiaryUpdateService.updateBeneficiaryData(reader);

    // This query should return the updated subscriber information (but it doesn't...causing the
    // assert to fail)
    Subscriber updatedSubscriber = subscriberDataService.findByCallingNumber(msisdn);
    assertEquals(getDateString(updatedDOB), getDateString(updatedSubscriber.getDateOfBirth()));
    Subscription updatedSubscription =
        updatedSubscriber.getActiveAndPendingSubscriptions().iterator().next();
    assertEquals(getDateString(updatedDOB), getDateString(updatedSubscription.getStartDate()));
    assertEquals(SubscriptionStatus.ACTIVE, updatedSubscription.getStatus());
  }
 private State importHeader(BufferedReader bufferedReader) throws IOException {
   String line = readLineWhileBlank(bufferedReader);
   // expect state name in the first line
   if (line.matches("^State Name : .*$")) {
     String stateName = line.substring(line.indexOf(':') + 1).trim();
     State state = stateDataService.findByName(stateName);
     verify(null != state, "State does not exists");
     readLineWhileNotBlank(bufferedReader);
     return state;
   } else {
     throw new IllegalArgumentException("Invalid file format");
   }
 }
  @Test
  public void testUpdateLocation() throws Exception {
    createLocationData();

    Long msisdn = subscriptionHelper.makeNumber();
    String childId = "0123456789";

    MctsChild child = new MctsChild(childId);
    child.setState(stateDataService.findByCode(21L));
    child.setDistrict(districtService.findByStateAndCode(child.getState(), 2L));
    makeMctsSubscription(child, DateTime.now().minusDays(100), SubscriptionPackType.CHILD, msisdn);

    Reader reader = createUpdateReaderWithHeaders("1," + childId + ",,,,21,3,0026,453,,,,,,");
    mctsBeneficiaryUpdateService.updateBeneficiaryData(reader);

    MctsChild updatedChild = mctsChildDataService.findByBeneficiaryId(childId);
    assertEquals(21L, (long) updatedChild.getState().getCode());
    assertEquals(3L, (long) updatedChild.getDistrict().getCode());
    assertEquals("0026", updatedChild.getTaluka().getCode());
    assertEquals(453L, (long) updatedChild.getHealthBlock().getCode());
  }
  @Test
  public void testUpdateBeneficiariesFromFile() throws Exception {
    createLocationData();

    // ----Create 4 beneficiaries:----

    String child1id = "1234567890";
    MctsChild child1 = new MctsChild(child1id);
    child1.setState(stateDataService.findByCode(21L));
    child1.setDistrict(districtService.findByStateAndCode(child1.getState(), 3L));
    Long child1msisdn = subscriptionHelper.makeNumber();
    makeMctsSubscription(
        child1, DateTime.now().minusDays(100), SubscriptionPackType.CHILD, child1msisdn);

    String mother2id = "1234567899";
    MctsMother mother2 = new MctsMother(mother2id);
    mother2.setState(stateDataService.findByCode(21L));
    mother2.setDistrict(districtService.findByStateAndCode(mother2.getState(), 3L));
    Long mother2msisdn = subscriptionHelper.makeNumber();
    makeMctsSubscription(
        mother2, DateTime.now().minusDays(100), SubscriptionPackType.PREGNANCY, mother2msisdn);

    String mother3id = "9876543210";
    MctsMother mother3 = new MctsMother(mother3id);
    mother3.setState(stateDataService.findByCode(21L));
    mother3.setDistrict(districtService.findByStateAndCode(mother3.getState(), 3L));
    makeMctsSubscription(
        mother3,
        DateTime.now().minusDays(100),
        SubscriptionPackType.PREGNANCY,
        subscriptionHelper.makeNumber());

    Long child4msisdn = subscriptionHelper.makeNumber();
    MctsChild child4 = new MctsChild("9876543211");
    child4.setState(stateDataService.findByCode(21L));
    child4.setDistrict(districtService.findByStateAndCode(child4.getState(), 3L));
    makeMctsSubscription(
        child4, DateTime.now().minusDays(100), SubscriptionPackType.CHILD, child4msisdn);

    // ----Update all 4 via CSV:----

    mctsBeneficiaryUpdateService.updateBeneficiaryData(read("csv/mcts_beneficiary_update.csv"));

    // ----Validate updates to each:----

    // MSISDN update:
    Subscriber oldSubscriber1 = subscriberDataService.findByCallingNumber(child1msisdn);
    assertNull(oldSubscriber1.getChild());
    assertEquals(0, oldSubscriber1.getAllSubscriptions().size());

    Subscriber subscriber1 = subscriberDataService.findByCallingNumber(9439986187L);
    assertNotNull(subscriber1);
    assertEquals(child1id, subscriber1.getChild().getBeneficiaryId());

    // MSISDN update:
    Subscriber oldSubscriber2 = subscriberDataService.findByCallingNumber(mother2msisdn);
    assertNull(oldSubscriber2.getMother());
    assertEquals(0, oldSubscriber2.getAllSubscriptions().size());

    Subscriber subscriber2 = subscriberDataService.findByCallingNumber(9439986188L);
    assertNotNull(subscriber2);
    assertEquals(mother2id, subscriber2.getMother().getBeneficiaryId());

    // Location update:
    MctsMother updatedMother3 = mctsMotherDataService.findByBeneficiaryId(mother3id);
    assertEquals(21L, (long) updatedMother3.getState().getCode());
    assertEquals(3L, (long) updatedMother3.getDistrict().getCode());
    assertEquals("0026", updatedMother3.getTaluka().getCode());
    assertEquals(453L, (long) updatedMother3.getHealthBlock().getCode());

    // DOB update:
    String updatedDOB = "01-07-2015";
    Subscriber subscriber4 = subscriberDataService.findByCallingNumber(child4msisdn);
    assertEquals(updatedDOB, getDateString(subscriber4.getDateOfBirth()));
    Subscription updatedSubscription =
        subscriber4.getActiveAndPendingSubscriptions().iterator().next();
    assertEquals(updatedDOB, getDateString(updatedSubscription.getStartDate()));
    assertEquals(SubscriptionStatus.ACTIVE, updatedSubscription.getStatus());
  }
  private void createLocationData() {
    // specific locations from the mother and child data files:

    State state21 = createState(21L, "State 21");
    District district2 = createDistrict(state21, 2L, "Jharsuguda", new Language("21", "English"));
    District district3 = createDistrict(state21, 3L, "Sambalpur");
    District district4 = createDistrict(state21, 4L, "Debagarh");
    state21.getDistricts().addAll(Arrays.asList(district2, district3, district4));

    Taluka taluka24 = createTaluka(district2, "0024", "Laikera P.S.", 24);
    district2.getTalukas().add(taluka24);

    Taluka taluka26 = createTaluka(district3, "0026", "Govindpur P.S.", 26);
    district3.getTalukas().add(taluka26);

    Taluka taluka46 = createTaluka(district4, "0046", "Debagarh P.S.", 46);
    district4.getTalukas().add(taluka46);

    HealthBlock healthBlock259 = createHealthBlock(taluka24, 259L, "Laikera", "hq");
    taluka24.getHealthBlocks().add(healthBlock259);

    HealthBlock healthBlock453 = createHealthBlock(taluka26, 453L, "Bamara", "hq");
    taluka26.getHealthBlocks().add(healthBlock453);

    HealthBlock healthBlock153 = createHealthBlock(taluka46, 153L, "Tileibani", "hq");
    taluka46.getHealthBlocks().add(healthBlock153);

    HealthFacilityType facilityType635 = createHealthFacilityType("Mundrajore CHC", 635L);
    HealthFacility healthFacility635 =
        createHealthFacility(healthBlock259, 635L, "Mundrajore CHC", facilityType635);
    healthBlock259.getHealthFacilities().add(healthFacility635);

    HealthFacilityType facilityType41 = createHealthFacilityType("Garposh CHC", 41L);
    HealthFacility healthFacility41 =
        createHealthFacility(healthBlock453, 41L, "Garposh CHC", facilityType41);
    healthBlock453.getHealthFacilities().add(healthFacility41);

    HealthFacilityType facilityType114 = createHealthFacilityType("CHC Tileibani", 114L);
    HealthFacility healthFacility114 =
        createHealthFacility(healthBlock153, 114L, "CHC Tileibani", facilityType114);
    healthBlock153.getHealthFacilities().add(healthFacility114);

    HealthSubFacility subFacilityType7389 =
        createHealthSubFacility("Babuniktimal", 7389L, healthFacility41);
    healthFacility41.getHealthSubFacilities().add(subFacilityType7389);

    HealthSubFacility subFacilityType7393 =
        createHealthSubFacility("Jarabaga", 7393L, healthFacility41);
    healthFacility41.getHealthSubFacilities().add(subFacilityType7393);

    HealthSubFacility subFacilityType2104 =
        createHealthSubFacility("Chupacabra", 2104L, healthFacility635);
    healthFacility635.getHealthSubFacilities().add(subFacilityType2104);

    HealthSubFacility subFacilityType342 =
        createHealthSubFacility("El Dorado", 342L, healthFacility114);
    healthFacility114.getHealthSubFacilities().add(subFacilityType342);

    Village village10004693 = createVillage(taluka24, 10004693L, 0, "Khairdihi");
    Village village10004691 = createVillage(taluka24, 10004691L, 0, "Gambhariguda");
    Village village1509 = createVillage(taluka24, 0, 1509L, "Mundrajore");
    Village village1505 = createVillage(taluka24, 0, 1505L, "Kulemura");
    Village village10004690 = createVillage(taluka24, 10004690L, 0, "Ampada");
    Village village10004697 = createVillage(taluka24, 10004697L, 0, "Saletikra");

    taluka24
        .getVillages()
        .addAll(
            Arrays.asList(
                village10004693,
                village10004691,
                village1509,
                village1505,
                village10004690,
                village10004697));

    Village village3089 = createVillage(taluka46, 0, 3089L, "Podapara");
    taluka46.getVillages().add(village3089);

    stateDataService.create(state21);
  }