@RequestMapping(method = RequestMethod.GET)
  public String edit(final Model model, @PathVariable final String crnNo) {
    final Complaint complaint = complaintService.getComplaintByCRN(crnNo);
    model.addAttribute("complaintHistory", complaintService.getHistory(complaint));
    model.addAttribute(
        "status",
        complaintStatusMappingService.getStatusByRoleAndCurrentStatus(
            securityUtils.getCurrentUser().getRoles(), complaint.getStatus()));
    model.addAttribute("complaint", complaint);

    if (securityUtils.currentUserType().equals(UserType.CITIZEN)) return COMPLAINT_CITIZEN_EDIT;
    else {
      model.addAttribute("approvalDepartmentList", departmentService.getAllDepartments());
      model.addAttribute("complaintType", complaintTypeService.findAll());
      model.addAttribute("ward", Collections.EMPTY_LIST);
      if (complaint.getLocation() != null && complaint.getLocation().getParent() != null)
        model.addAttribute(
            "ward",
            boundaryService.getBoundariesByBndryTypeNameAndHierarchyTypeName(
                "Ward", "Administration"));
      if (complaint.getLocation() != null && complaint.getLocation().getParent() != null)
        model.addAttribute(
            "location",
            crossHierarchyService.getChildBoundariesNameAndBndryTypeAndHierarchyType(
                "Locality", "Ward", "Location"));
      model.addAttribute(
          "mailSubject", "Grievance regarding " + complaint.getComplaintType().getName());

      model.addAttribute("mailBody", complaintService.getEmailBody(complaint));
      return COMPLAINT_EDIT;
    }
  }
  @RequestMapping(method = RequestMethod.POST)
  public String update(
      @ModelAttribute Complaint complaint,
      final BindingResult errors,
      final RedirectAttributes redirectAttrs,
      final Model model,
      final HttpServletRequest request,
      @RequestParam("files") final MultipartFile[] files) {
    // this validation is common for citizen and official. Any more
    // specific
    // validation required for official then write different method
    validateUpdate(complaint, errors, request);

    Long approvalPosition = 0l;
    String approvalComent = "";
    String result = "";

    if (request.getParameter("approvalComent") != null
        && !request.getParameter("approvalComent").trim().isEmpty())
      approvalComent = request.getParameter("approvalComent");

    if (request.getParameter("approvalPosition") != null
        && !request.getParameter("approvalPosition").isEmpty())
      approvalPosition = Long.valueOf(request.getParameter("approvalPosition"));
    if (!securityUtils.currentUserType().equals(UserType.CITIZEN))
      if (files != null) complaint.getSupportDocs().addAll(addToFileStore(files));
    if (!errors.hasErrors()) {
      complaint = complaintService.update(complaint, approvalPosition, approvalComent);
      redirectAttrs.addFlashAttribute("complaint", complaint);
      result = "redirect:" + complaint.getCrn() + COMPLAINT_UPDATE_SUCCESS;
    } else {
      final List<Hashtable<String, Object>> historyTable = complaintService.getHistory(complaint);
      model.addAttribute("complaintHistory", historyTable);
      model.addAttribute("complaintType", complaintTypeService.findAll());
      model.addAttribute("approvalDepartmentList", departmentService.getAllDepartments());
      model.addAttribute(
          "zone",
          boundaryService.getBoundariesByBndryTypeNameAndHierarchyTypeName(
              "ZONE", "ADMINISTRATION"));
      model.addAttribute("ward", Collections.EMPTY_LIST);
      if (complaint.getLocation() != null && complaint.getLocation().getParent() != null)
        model.addAttribute(
            "ward",
            boundaryService.getActiveChildBoundariesByBoundaryId(
                complaint.getLocation().getParent().getId()));
      if (securityUtils.currentUserType().equals(UserType.CITIZEN)) result = COMPLAINT_CITIZEN_EDIT;
      else result = COMPLAINT_EDIT;
    }
    return result;
  }
 private void loadBasicDetails(
     final WaterConnectionDetails addConnection,
     final Model model,
     final WaterConnectionDetails parentConnectionDetails) {
   addConnection.setConnectionStatus(ConnectionStatus.INPROGRESS);
   model.addAttribute("parentConnection", parentConnectionDetails.getConnection());
   model.addAttribute("waterConnectionDetails", parentConnectionDetails);
   model.addAttribute(
       "connectionType",
       waterConnectionDetailsService
           .getConnectionTypesMap()
           .get(parentConnectionDetails.getConnectionType().name()));
   model.addAttribute("addConnection", addConnection);
   model.addAttribute("stateType", parentConnectionDetails.getClass().getSimpleName());
   model.addAttribute(
       "currentUser", waterTaxUtils.getCurrentUserRole(securityUtils.getCurrentUser()));
   model.addAttribute("additionalRule", addConnection.getApplicationType().getCode());
   model.addAttribute("mode", "addconnection");
   model.addAttribute(
       "validationMessage",
       additionalConnectionService.validateAdditionalConnection(parentConnectionDetails));
   BigDecimal waterTaxDueforParent =
       waterConnectionDetailsService.getTotalAmount(parentConnectionDetails);
   model.addAttribute("waterTaxDueforParent", waterTaxDueforParent);
   model.addAttribute("typeOfConnection", WaterTaxConstants.ADDNLCONNECTION);
 }
  @RequestMapping(value = "/addconnection/addConnection-create", method = RequestMethod.POST)
  public String create(
      @Valid @ModelAttribute final WaterConnectionDetails addConnection,
      final BindingResult resultBinder,
      final RedirectAttributes redirectAttributes,
      final Model model,
      @RequestParam String workFlowAction,
      final HttpServletRequest request,
      final BindingResult errors) {

    final WaterConnectionDetails parent =
        waterConnectionDetailsService.findByConnection(
            addConnection.getConnection().getParentConnection());
    final String message = additionalConnectionService.validateAdditionalConnection(parent);
    if (!message.isEmpty() && !"".equals(message))
      return "redirect:/application/addconnection/"
          + addConnection.getConnection().getParentConnection().getConsumerCode();

    final List<ApplicationDocuments> applicationDocs = new ArrayList<ApplicationDocuments>();
    int i = 0;
    if (!addConnection.getApplicationDocs().isEmpty())
      for (final ApplicationDocuments applicationDocument : addConnection.getApplicationDocs()) {
        if (applicationDocument.getDocumentNumber() == null
            && applicationDocument.getDocumentDate() != null) {
          final String fieldError = "applicationDocs[" + i + "].documentNumber";
          resultBinder.rejectValue(fieldError, "documentNumber.required");
        }
        if (applicationDocument.getDocumentNumber() != null
            && applicationDocument.getDocumentDate() == null) {
          final String fieldError = "applicationDocs[" + i + "].documentDate";
          resultBinder.rejectValue(fieldError, "documentDate.required");
        } else if (validApplicationDocument(applicationDocument))
          applicationDocs.add(applicationDocument);
        i++;
      }

    if (addConnection.getState() == null)
      addConnection.setStatus(
          waterTaxUtils.getStatusByCodeAndModuleType(
              WaterTaxConstants.APPLICATION_STATUS_CREATED, WaterTaxConstants.MODULETYPE));

    if (resultBinder.hasErrors()) {
      final WaterConnectionDetails parentConnectionDetails =
          waterConnectionDetailsService.getActiveConnectionDetailsByConnection(
              addConnection.getConnection());
      loadBasicDetails(addConnection, model, parentConnectionDetails);
      prepareWorkflow(model, addConnection, new WorkflowContainer());
      model.addAttribute("additionalRule", addConnection.getApplicationType().getCode());
      model.addAttribute("stateType", addConnection.getClass().getSimpleName());
      model.addAttribute(
          "currentUser", waterTaxUtils.getCurrentUserRole(securityUtils.getCurrentUser()));
      return "addconnection-form";
    }
    addConnection.setApplicationDate(new Date());
    addConnection.getApplicationDocs().clear();
    addConnection.setApplicationDocs(applicationDocs);

    processAndStoreApplicationDocuments(addConnection);

    Long approvalPosition = 0l;
    String approvalComent = "";

    if (request.getParameter("approvalComent") != null)
      approvalComent = request.getParameter("approvalComent");

    if (request.getParameter("workFlowAction") != null)
      workFlowAction = request.getParameter("workFlowAction");

    if (request.getParameter("approvalPosition") != null
        && !request.getParameter("approvalPosition").isEmpty())
      approvalPosition = Long.valueOf(request.getParameter("approvalPosition"));

    final Boolean applicationByOthers =
        waterTaxUtils.getCurrentUserRole(securityUtils.getCurrentUser());

    if (applicationByOthers != null && applicationByOthers.equals(true)) {
      final Position userPosition =
          waterTaxUtils.getZonalLevelClerkForLoggedInUser(
              addConnection.getConnection().getPropertyIdentifier());
      if (userPosition == null) {
        final WaterConnectionDetails parentConnectionDetails =
            waterConnectionDetailsService.getActiveConnectionDetailsByConnection(
                addConnection.getConnection());
        loadBasicDetails(addConnection, model, parentConnectionDetails);
        prepareWorkflow(model, addConnection, new WorkflowContainer());
        model.addAttribute("additionalRule", addConnection.getApplicationType().getCode());
        model.addAttribute("stateType", addConnection.getClass().getSimpleName());
        model.addAttribute(
            "currentUser", waterTaxUtils.getCurrentUserRole(securityUtils.getCurrentUser()));
        errors.rejectValue(
            "connection.propertyIdentifier",
            "err.validate.connection.user.mapping",
            "err.validate.connection.user.mapping");
        return "addconnection-form";
      } else {
        approvalPosition = userPosition.getId();
      }
    }

    waterConnectionDetailsService.createNewWaterConnection(
        addConnection,
        approvalPosition,
        approvalComent,
        addConnection.getApplicationType().getCode(),
        workFlowAction);
    final String pathVars =
        addConnection.getApplicationNumber()
            + ","
            + waterTaxUtils.getApproverUserName(approvalPosition);
    return "redirect:/application/application-success?pathVars=" + pathVars;
  }