@RequestMapping(method = RequestMethod.GET)
  public String showPatientInfo(
      @RequestParam("patientId") Integer patientId,
      @RequestParam(value = "encounterId", required = false) Integer encounterId,
      @RequestParam(value = "reprint", required = false) Boolean reprint,
      Model model)
      throws IOException, ParseException {

    Patient patient = Context.getPatientService().getPatient(patientId);
    PatientModel patientModel = new PatientModel(patient);
    model.addAttribute("patient", patientModel);
    model.addAttribute(
        "OPDs", RegistrationWebUtils.getSubConcepts(RegistrationConstants.CONCEPT_NAME_OPD_WARD));

    // Get current date
    SimpleDateFormat sdf = new SimpleDateFormat("EEE dd/MM/yyyy kk:mm");
    model.addAttribute("currentDateTime", sdf.format(new Date()));

    // Get patient registration fee
    if (GlobalPropertyUtil.getInteger(RegistrationConstants.PROPERTY_NUMBER_OF_DATE_VALIDATION, 0)
        > 0) {
      List<RegistrationFee> fees =
          Context.getService(RegistrationService.class)
              .getRegistrationFees(
                  patient,
                  GlobalPropertyUtil.getInteger(
                      RegistrationConstants.PROPERTY_NUMBER_OF_DATE_VALIDATION, 0));
      if (!CollectionUtils.isEmpty(fees)) {
        RegistrationFee fee = fees.get(0);
        Calendar dueDate = Calendar.getInstance();
        dueDate.setTime(fee.getCreatedOn());
        dueDate.add(Calendar.DATE, 30);
        model.addAttribute("dueDate", RegistrationUtils.formatDate(dueDate.getTime()));
        model.addAttribute("daysLeft", dateDiff(dueDate.getTime(), new Date()));
      }
    }

    // Get selected OPD room if this is the first time of visit
    if (encounterId != null) {
      Encounter encounter = Context.getEncounterService().getEncounter(encounterId);
      for (Obs obs : encounter.getObs()) {
        if (obs.getConcept()
            .getName()
            .getName()
            .equalsIgnoreCase(RegistrationConstants.CONCEPT_NAME_OPD_WARD)) {
          model.addAttribute("selectedOPD", obs.getValueCoded().getConceptId());
        }
      }
    }

    // If reprint, get the latest registration encounter
    if ((reprint != null) && reprint) {

      /** June 7th 2012 - Supported #250 - Registration 2.2.14 (Mohali): Date on Reprint */
      HospitalCoreService hcs = Context.getService(HospitalCoreService.class);
      model.addAttribute("currentDateTime", sdf.format(hcs.getLastVisitTime(patientId)));

      Encounter encounter = Context.getService(RegistrationService.class).getLastEncounter(patient);
      if (encounter != null) {
        Map<Integer, String> observations = new HashMap<Integer, String>();

        for (Obs obs : encounter.getAllObs()) {
          if (obs.getConcept()
              .getDisplayString()
              .equalsIgnoreCase(RegistrationConstants.CONCEPT_NAME_TEMPORARY_CATEGORY)) {
            model.addAttribute("tempCategoryId", obs.getConcept().getConceptId());
          } else if (obs.getConcept()
              .getDisplayString()
              .equalsIgnoreCase(RegistrationConstants.CONCEPT_NAME_OPD_WARD)) {
            model.addAttribute("opdWardId", obs.getConcept().getConceptId());
          }
          observations.put(obs.getConcept().getConceptId(), ObsUtils.getValueAsString(obs));
        }
        model.addAttribute("observations", observations);
      }
    }

    return "/module/registration/patient/showPatientInfo";
  }
  @RequestMapping(method = RequestMethod.POST)
  public void savePatientInfo(
      @RequestParam("patientId") Integer patientId,
      @RequestParam(value = "encounterId", required = false) Integer encounterId,
      HttpServletRequest request,
      HttpServletResponse response)
      throws ParseException, IOException {

    Map<String, String> parameters = RegistrationWebUtils.optimizeParameters(request);

    // get patient
    Patient patient = Context.getPatientService().getPatient(patientId);

    /*
     * SAVE ENCOUNTER
     */
    Encounter encounter = null;
    if (encounterId != null) {
      encounter = Context.getEncounterService().getEncounter(encounterId);
    } else {
      encounter = RegistrationWebUtils.createEncounter(patient, true);

      // create OPD obs
      Concept opdWardConcept =
          Context.getConceptService().getConcept(RegistrationConstants.CONCEPT_NAME_OPD_WARD);
      Concept selectedOPDConcept =
          Context.getConceptService()
              .getConcept(
                  Integer.parseInt(
                      parameters.get(RegistrationConstants.FORM_FIELD_PATIENT_OPD_WARD)));
      Obs opd = new Obs();
      opd.setConcept(opdWardConcept);
      opd.setValueCoded(selectedOPDConcept);
      encounter.addObs(opd);

      // send patient to opd room/bloodbank

      // harsh 5/10/2012 changed the way to get blood bank concept->shifted hardcoded dependency
      // from id to name
      //			Concept bloodbankConcept = Context.getConceptService().getConcept(
      //			    GlobalPropertyUtil.getInteger(RegistrationConstants.PROPERTY_BLOODBANK_CONCEPT_ID,
      // 6425));
      String bloodBankWardName =
          GlobalPropertyUtil.getString(
              RegistrationConstants.PROPERTY_BLOODBANK_OPDWARD_NAME, "Blood Bank Room");

      // ghanshyam 03-sept-2013 Bug #394 [Blood bank]queue
      String socn = new String(selectedOPDConcept.getName().toString());
      String substringofsocn = socn.substring(0, 15);

      if (!substringofsocn.equalsIgnoreCase(bloodBankWardName)) {
        RegistrationWebUtils.sendPatientToOPDQueue(patient, selectedOPDConcept, true);
      } else {
        OrderType orderType = null;
        String orderTypeName =
            Context.getAdministrationService().getGlobalProperty("bloodbank.orderTypeName");
        orderType = OrderUtil.getOrderTypeByName(orderTypeName);

        Order order = new Order();
        order.setConcept(selectedOPDConcept);
        order.setCreator(Context.getAuthenticatedUser());
        order.setDateCreated(new Date());
        order.setOrderer(Context.getAuthenticatedUser());
        order.setPatient(patient);
        order.setStartDate(new Date());
        order.setAccessionNumber("0");
        order.setOrderType(orderType);
        order.setEncounter(encounter);
        encounter.addOrder(order);
      }
    }

    // create temporary attributes
    for (String name : parameters.keySet()) {
      if ((name.contains(".attribute.")) && (!StringUtils.isBlank(parameters.get(name)))) {
        String[] parts = name.split("\\.");
        String idText = parts[parts.length - 1];
        Integer id = Integer.parseInt(idText);
        Concept tempCatConcept = Context.getConceptService().getConceptByName("TEMPORARY CATEGORY");

        Concept temporaryAttributeConcept =
            Context.getConceptService().getConcept(tempCatConcept.getConceptId());
        Obs temporaryAttribute = new Obs();
        temporaryAttribute.setConcept(temporaryAttributeConcept);
        logger.info("concept: " + temporaryAttributeConcept);
        logger.info("value: " + parameters.get(name));
        temporaryAttribute.setValueAsString(parameters.get(name));
        encounter.addObs(temporaryAttribute);
      }
    }

    // save encounter
    Context.getEncounterService().saveEncounter(encounter);
    logger.info(
        String.format(
            "Save encounter for the visit of patient [encounterId=%s, patientId=%s]",
            encounter.getId(), patient.getId()));

    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.print("success");
  }