/** public void updateVaccinesCodesAndDriver(StageConfigurationVoCollection value) */
  public void updateVaccinesCodesAndDriver(ims.pci.vo.StageConfigurationVoCollection value)
      throws ims.domain.exceptions.DomainInterfaceException {
    if (value == null) return;

    if (this.stages.size() != value.size())
      throw new ims.domain.exceptions.DomainInterfaceException(
          "Stage configutation provided not matching the current stage configuration");

    for (int i = 0; i < this.stages.size(); i++) {
      if (this.stages.get(i) == null)
        throw new ims.domain.exceptions.DomainInterfaceException(
            "Stage configuration provided not matching the current stage configuration");

      if (this.stages.get(i).getStage() == null)
        throw new ims.domain.exceptions.DomainInterfaceException(
            "Stage configuration provided not matching the current stage configuration");

      if (!this.stages.get(i).getStage().equals(value.get(i).getStage())) {
        throw new ims.domain.exceptions.DomainInterfaceException(
            "Stage configuration provided not matching the current stage configuration");
      }

      if (!ims.pci.vo.lookups.ScheduleType.OUTBREAKSCHEDULE.equals(this.scheduletype)) {
        if (this.stages.get(i).getAgeInMonths() == null)
          throw new ims.domain.exceptions.DomainInterfaceException(
              "Stage configuration provided not matching the current stage configuration");

        if (!this.stages.get(i).getAgeInMonths().equals(value.get(i).getAgeInMonths())) {
          throw new ims.domain.exceptions.DomainInterfaceException(
              "Stage configuration provided not matching the current stage configuration");
        }
      }

      if (this.stages.get(i).getStageVaccines() == null) {
        if (value.get(i).getStageVaccines() == null) continue;
        else
          throw new ims.domain.exceptions.DomainInterfaceException(
              "Stage configuration provided not matching the current stage configuration");
      }

      if (this.stages.get(i).getStageVaccines().size() != value.get(i).getStageVaccines().size()) {
        throw new ims.domain.exceptions.DomainInterfaceException(
            "Stage configuration provided not matching the current stage configuration");
      }

      for (int k = 0; k < this.stages.get(i).getStageVaccines().size(); k++) {
        if (!this.stages
            .get(i)
            .getStageVaccines()
            .get(k)
            .getVaccine()
            .equals(value.get(i).getStageVaccines().get(k).getVaccine()))
          throw new ims.domain.exceptions.DomainInterfaceException(
              "Stage configuration provided not matching the current stage configuration");
      }
    }

    for (int i = 0; i < this.stages.size(); i++) {
      if (this.stages.get(i) == null) continue;

      for (int k = 0; k < this.stages.get(i).getStageVaccines().size(); k++) {
        if (this.stages.get(i).getStageVaccines().get(k) == null) continue;

        this.stages
            .get(i)
            .getStageVaccines()
            .get(k)
            .setPcrsCode(value.get(i).getStageVaccines().get(k).getPcrsCode());

        // wdev-7566
        this.stages
            .get(i)
            .getStageVaccines()
            .get(k)
            .setDriver(value.get(i).getStageVaccines().get(k).getDriver());
        this.stages
            .get(i)
            .getStageVaccines()
            .get(k)
            .setIntervalMonths(value.get(i).getStageVaccines().get(k).getIntervalMonths());

        // WDEV-9612
        this.stages
            .get(i)
            .getStageVaccines()
            .get(k)
            .setCanBeRescheduled(value.get(i).getStageVaccines().get(k).getCanBeRescheduled());

        // WDEV-8654
        this.stages
            .get(i)
            .getStageVaccines()
            .get(k)
            .setIsLastShotForVaccine(
                value.get(i).getStageVaccines().get(k).getIsLastShotForVaccine());
      }
    }
  }
  /**
   * Custom validate method - checks for startDOB < endDOB and if default is set only when the
   * schedule is active. Checks for duplicate stages. Checks if the same vaccine has the same shot
   * number.
   */
  public String[] validateCustomRules(String[] existingErrors) {
    existingErrors = this.validate(existingErrors);

    if (this.isBusy) return null;

    this.isBusy = true;

    java.util.ArrayList<String> listOfErrors = new java.util.ArrayList<String>();
    if (existingErrors != null) {
      for (int x = 0; x < existingErrors.length; x++) {
        listOfErrors.add(existingErrors[x]);
      }
    }

    if (ims.pci.vo.lookups.ScheduleType.OUTBREAKSCHEDULE.equals(this.scheduletype)) {
      if (this.campaignstartdate == null) listOfErrors.add("Campaign start date is mandatory");
    } else if (ims.pci.vo.lookups.ScheduleType.INVALIDVACCINESCHEDULE.equals(this.scheduletype)
        || ims.pci.vo.lookups.ScheduleType.PCISCHEDULE.equals(this.scheduletype)) {
      if (this.startdob == null) listOfErrors.add("Start DOB is mandatory");
    }

    if ((this.startdob != null)
        && (this.enddob != null && this.startdob.isGreaterThan(this.enddob)))
      listOfErrors.add("StartDob can not be set after EndDob");

    if (ims.core.vo.lookups.PreActiveActiveInactiveStatus.PREACTIVE.equals(this.status)
        && this.isdefaultschedule)
      listOfErrors.add("Schedule can be set as default only if it is active");

    if (this.stages == null || this.stages.size() == 0) listOfErrors.add("Stages are mandatory");
    else {
      // Check for duplicate stages
      for (int i = 0; i < this.stages.size() - 1; i++) {
        StageConfigurationVo markStage = this.stages.get(i);
        if (markStage == null || markStage.stage == null) continue;

        for (int j = i + 1; j < this.stages.size(); j++) {
          StageConfigurationVo stageCompare = this.stages.get(j);
          if (stageCompare == null) continue;

          if (markStage.stage.equals(stageCompare.stage))
            listOfErrors.add(
                "This schedule contains duplicates stages. "
                    + markStage.stage.getText()
                    + " is present more than once.");
        }
      }

      // Check for vaccines with the same shot number
      for (int i = 0; i < this.stages.size() - 1; i++) {
        StageConfigurationVo markStage = this.stages.get(i);
        if (markStage == null || markStage.stagevaccines == null) continue;

        for (int k = 0; k < markStage.stagevaccines.size(); k++) {
          StageVaccineVo markVaccine = markStage.stagevaccines.get(k);
          if (markVaccine == null || markVaccine.shotno == null || markVaccine.vaccine == null)
            continue;

          for (int j = i + 1; j < this.stages.size(); j++) {
            StageConfigurationVo stageCompare = this.stages.get(j);
            if (stageCompare == null || stageCompare.stagevaccines == null) continue;

            for (int index = 0; index < stageCompare.stagevaccines.size(); index++) {
              StageVaccineVo vaccineCompare = stageCompare.stagevaccines.get(index);
              if (vaccineCompare == null) continue;

              if (markVaccine.equals(vaccineCompare)
                  && markVaccine.shotno.equals(vaccineCompare.shotno))
                listOfErrors.add(
                    "This schedule contains vaccines with the same shot number. "
                        + markVaccine.vaccine.getVaccineName()
                        + " has the same shot number in more than one stage:"
                        + markVaccine.shotno.toString());
            }
          }
        }
      }

      // Check for driver and minimum interval value in months
      for (int i = 0; i < this.stages.size(); i++) {
        StageConfigurationVo stage = this.stages.get(i);
        if (stage == null || stage.stagevaccines == null) continue;

        Boolean hasNoInterval = false;

        for (int j = 0; j < stage.stagevaccines.size(); j++) {
          StageVaccineVo vaccine = stage.stagevaccines.get(j);
          if (vaccine == null) continue;

          if (vaccine.driver != null && vaccine.driver) {
            if (vaccine.intervalmonths == null) {
              listOfErrors.add("Interval(Months) is mandatory");
              hasNoInterval = true;
              break;
            }
          }
        }

        if (hasNoInterval) break;
      }
    }

    int errorCount = listOfErrors.size();
    if (errorCount == 0) {
      this.isBusy = false;
      this.isValidated = true;
      return null;
    }

    String[] result = new String[errorCount];

    for (int x = 0; x < errorCount; x++) result[x] = (String) listOfErrors.get(x);

    this.isBusy = false;
    this.isValidated = false;

    return result;
  }