@Transactional
  @Override
  public CommandProcessingResult createEventOrder(JsonCommand command) {

    try {

      this.context.authenticatedUser();
      Long clientId = command.longValueOfParameterNamed("clientId");

      // Check Client Custome Validation
      this.eventValidationReadPlatformService.checkForCustomValidations(
          clientId, EventActionConstants.EVENT_EVENT_ORDER, command.json(), getUserId());
      EventOrder eventOrder = assembleEventOrderDetails(command, clientId);
      Configuration walletConfiguration =
          this.configurationRepository.findOneByName(
              ConfigurationConstants.CONFIG_PROPERTY_WALLET_ENABLE);
      boolean isBalanceAvailable =
          this.checkClientBalance(
              eventOrder.getBookedPrice(), clientId, walletConfiguration.isEnabled());
      if (!isBalanceAvailable) {
        throw new InsufficientAmountException("bookevent");
      }
      this.eventOrderRepository.save(eventOrder);

      List<OneTimeSaleData> oneTimeSaleDatas =
          eventOrderReadplatformServie.retrieveEventOrderData(eventOrder.getClientId());
      for (OneTimeSaleData oneTimeSaleData : oneTimeSaleDatas) {
        CommandProcessingResult commandProcessingResult =
            this.invoiceOneTimeSale.invoiceOneTimeSale(
                eventOrder.getClientId(), oneTimeSaleData, walletConfiguration.isEnabled());
        this.updateOneTimeSale(oneTimeSaleData);
        if (walletConfiguration.isEnabled()) {
          JournalVoucher journalVoucher =
              new JournalVoucher(
                  commandProcessingResult.resourceId(),
                  DateUtils.getDateOfTenant(),
                  "Event Sale",
                  null,
                  eventOrder.getBookedPrice(),
                  eventOrder.getClientId());
          this.journalvoucherRepository.save(journalVoucher);
        }
      }

      // Add New Action
      List<ActionDetaislData> actionDetaislDatas =
          this.actionDetailsReadPlatformService.retrieveActionDetails(
              EventActionConstants.EVENT_EVENT_ORDER);
      if (!actionDetaislDatas.isEmpty()) {
        this.actiondetailsWritePlatformService.AddNewActions(
            actionDetaislDatas, clientId, eventOrder.getId().toString(), null);
      }
      return new CommandProcessingResult(
          eventOrder.getEventOrderdetials().get(0).getMovieLink(), eventOrder.getClientId());

    } catch (DataIntegrityViolationException dve) {
      handleCodeDataIntegrityIssues(command, dve);
      return new CommandProcessingResult(Long.valueOf(-1));
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult createHoliday(final JsonCommand command) {

    try {
      this.context.authenticatedUser();
      this.fromApiJsonDeserializer.validateForCreate(command.json());

      validateInputDates(command);

      final Set<Office> offices = getSelectedOffices(command);

      final Holiday holiday = Holiday.createNew(offices, command);

      this.holidayRepository.save(holiday);

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withEntityId(holiday.getId())
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult submitApplication(final JsonCommand command) {
    try {
      this.savingsAccountDataValidator.validateForSubmit(command.json());
      final AppUser submittedBy = this.context.authenticatedUser();

      final SavingsAccount account = this.savingAccountAssembler.assembleFrom(command, submittedBy);
      this.savingAccountRepository.save(account);

      if (account.isAccountNumberRequiresAutoGeneration()) {
        final AccountNumberGenerator accountNoGenerator =
            this.accountIdentifierGeneratorFactory.determineSavingsAccountNoGenerator(
                account.getId());
        account.updateAccountNo(accountNoGenerator.generate());

        this.savingAccountRepository.save(account);
      }

      final Long savingsId = account.getId();
      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(savingsId) //
          .withOfficeId(account.officeId()) //
          .withClientId(account.clientId()) //
          .withGroupId(account.groupId()) //
          .withSavingsId(savingsId) //
          .build();
    } catch (final DataAccessException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult updateCharge(final Long chargeId, final JsonCommand command) {

    try {
      this.context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForUpdate(command.json());

      final Charge chargeForUpdate = this.chargeRepository.findOne(chargeId);
      if (chargeForUpdate == null) {
        throw new ChargeNotFoundException(chargeId);
      }

      final Map<String, Object> changes = chargeForUpdate.update(command);

      if (!changes.isEmpty()) {
        this.chargeRepository.save(chargeForUpdate);
      }

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withEntityId(chargeId)
          .with(changes)
          .build();
    } catch (DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult createOffice(final JsonCommand command) {

    try {
      final AppUser currentUser = context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForCreate(command.json());

      Long parentId = null;
      if (command.parameterExists("parentId")) {
        parentId = command.longValueOfParameterNamed("parentId");
      }

      final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, parentId);
      final Office office = Office.fromJson(parent, command);

      // pre save to generate id for use in office hierarchy
      this.officeRepository.save(office);

      office.generateHierarchy();

      this.officeRepository.save(office);

      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(office.getId()) //
          .withOfficeId(office.getId()) //
          .build();
    } catch (DataIntegrityViolationException dve) {
      handleOfficeDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult followUpProspect(
      final JsonCommand command, final Long prospectId) {
    try {
      context.authenticatedUser();
      this.clientProspectCommandFromApiJsonDeserializer.validateForUpdate(command.json());

      final ProspectDetail prospectDetail = ProspectDetail.fromJson(command, prospectId);
      prospectDetailJpaRepository.save(prospectDetail);

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withEntityId(prospectDetail.getProspectId())
          .build();

    } catch (DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    } catch (ParseException e) {
      throw new PlatformDataIntegrityException(
          "invalid.date.and.time.format",
          "invalid.date.and.time.format",
          "invalid.date.and.time.format");
    }
  }
  /**
   * This method <code>onlinePayment</code> is used for the Both M-pesa & Tigo-pesa PaymentGateways
   * to Pay the Money.
   *
   * @param requestData Containg input data in the Form of Xml/Soap .
   * @return
   */
  @POST
  @Consumes({MediaType.WILDCARD})
  @Produces({MediaType.APPLICATION_XML})
  public String onlinePayment(final String requestData) {

    try {
      final JSONObject xmlJSONObj = XML.toJSONObject(requestData);
      jsonData = this.returnJsonFromXml(xmlJSONObj);
      final CommandWrapper commandRequest =
          new CommandWrapperBuilder().createPaymentGateway().withJson(jsonData.toString()).build();
      result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
      success = "SUCCESS";
      errorDesc = "";
      errorCode = Long.valueOf(0);
      contentData = "OBSTRANSACTIONID=" + result.resourceId();
      return this.returnToServer();
    } catch (ReceiptNoDuplicateException e) {
      success = "DUPLICATE_TXN";
      errorDesc = "DUPLICATE";
      errorCode = Long.valueOf(1);
      contentData = "TXNID ALREADY EXIST";
      return this.returnToServer();
    } catch (JSONException e) {
      return e.getCause().toString();
    } catch (PlatformDataIntegrityException e) {
      return null;
    }
  }
  @POST
  @Path("/documents")
  @Consumes({MediaType.MULTIPART_FORM_DATA})
  @Produces({MediaType.APPLICATION_JSON})
  public Response createUploadFile(
      @HeaderParam("Content-Length") final Long fileSize,
      @FormDataParam("file") final InputStream inputStream,
      @FormDataParam("file") final FormDataContentDisposition fileDetails,
      @FormDataParam("file") final FormDataBodyPart bodyPart,
      @FormDataParam("status") final String name,
      @FormDataParam("description") final String description) {

    FileUtils.validateFileSizeWithinPermissibleRange(
        fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
    inputStreamObject = inputStream;
    DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
    final Date date = DateUtils.getDateOfTenant();
    final DateTimeFormatter dtf = DateTimeFormat.forPattern("dd MMMM yyyy");
    final LocalDate localdate = dtf.parseLocalDate(dateFormat.format(date));
    final String fileUploadLocation = FileUtils.generateXlsFileDirectory();
    final String fileName = fileDetails.getFileName();
    if (!new File(fileUploadLocation).isDirectory()) {
      new File(fileUploadLocation).mkdirs();
    }
    final DataUploadCommand uploadStatusCommand =
        new DataUploadCommand(
            name,
            null,
            localdate,
            "",
            null,
            null,
            null,
            description,
            fileName,
            inputStream,
            fileUploadLocation);
    CommandProcessingResult id = this.dataUploadWritePlatformService.addItem(uploadStatusCommand);
    return Response.ok().entity(id.toString()).build();
    // return null;
  }
  @Transactional
  @Override
  @Caching(
      evict = {
        @CacheEvict(
            value = "offices",
            key =
                "T(org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#root.target.context.authenticatedUser().getOffice().getHierarchy()+'of')"),
        @CacheEvict(
            value = "officesForDropdown",
            key =
                "T(org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#root.target.context.authenticatedUser().getOffice().getHierarchy()+'ofd')"),
        @CacheEvict(
            value = "officesById",
            key =
                "T(org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#officeId)")
      })
  public CommandProcessingResult updateOffice(final Long officeId, final JsonCommand command) {

    try {
      final AppUser currentUser = context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForUpdate(command.json());

      Long parentId = null;
      if (command.parameterExists("parentId")) {
        parentId = command.longValueOfParameterNamed("parentId");
      }

      final Office office = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId);

      final Map<String, Object> changes = office.update(command);

      if (changes.containsKey("parentId")) {
        final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, parentId);
        office.update(parent);
      }

      if (!changes.isEmpty()) {
        this.officeRepository.saveAndFlush(office);
      }

      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(office.getId()) //
          .withOfficeId(office.getId()) //
          .with(changes) //
          .build();
    } catch (DataIntegrityViolationException dve) {
      handleOfficeDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  @CacheEvict(value = "usersByUsername", allEntries = true)
  public CommandProcessingResult updateUser(final Long userId, final JsonCommand command) {

    try {
      this.context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForUpdate(command.json());

      final AppUser userToUpdate = this.appUserRepository.findOne(userId);
      if (userToUpdate == null) {
        throw new UserNotFoundException(userId);
      }

      final Map<String, Object> changes =
          userToUpdate.update(command, this.platformPasswordEncoder);

      if (changes.containsKey("officeId")) {
        final Long officeId = (Long) changes.get("officeId");
        final Office office = this.officeRepository.findOne(officeId);
        if (office == null) {
          throw new OfficeNotFoundException(officeId);
        }

        userToUpdate.changeOffice(office);
      }

      if (changes.containsKey("roles")) {
        final String[] roleIds = (String[]) changes.get("roles");
        final Set<Role> allRoles = assembleSetOfRoles(roleIds);

        userToUpdate.updateRoles(allRoles);
      }

      if (!changes.isEmpty()) {
        this.appUserRepository.saveAndFlush(userToUpdate);
      }

      return new CommandProcessingResultBuilder() //
          .withEntityId(userId) //
          .withOfficeId(userToUpdate.getOffice().getId()) //
          .with(changes) //
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  @CacheEvict(value = "usersByUsername", allEntries = true)
  public CommandProcessingResult createUser(final JsonCommand command) {

    try {
      this.context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForCreate(command.json());

      final String officeIdParamName = "officeId";
      final Long officeId = command.longValueOfParameterNamed(officeIdParamName);

      final Office userOffice = this.officeRepository.findOne(officeId);
      if (userOffice == null) {
        throw new OfficeNotFoundException(officeId);
      }

      final String[] roles = command.arrayValueOfParameterNamed("roles");
      final Set<Role> allRoles = assembleSetOfRoles(roles);

      final AppUser appUser = AppUser.fromJson(userOffice, allRoles, command);
      final Boolean sendPasswordToEmail =
          command.booleanObjectValueOfParameterNamed("sendPasswordToEmail");
      this.userDomainService.create(appUser, sendPasswordToEmail);

      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(appUser.getId()) //
          .withOfficeId(userOffice.getId()) //
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    } catch (final PlatformEmailSendException e) {
      final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();

      final String email = command.stringValueOfParameterNamed("email");
      final ApiParameterError error =
          ApiParameterError.parameterError(
              "error.msg.user.email.invalid", "The parameter email is invalid.", "email", email);
      dataValidationErrors.add(error);

      throw new PlatformApiDataValidationException(
          "validation.msg.validation.errors.exist",
          "Validation errors exist.",
          dataValidationErrors);
    }
  }
 @Transactional
 @Override
 public CommandProcessingResult deleteEventPricing(JsonCommand command) {
   try {
     EventPricing eventPricing = this.eventPricingRepository.findOne(command.entityId());
     eventPricing.setClientType(null);
     eventPricing.setOptType(null);
     eventPricing.setFormatType(null);
     eventPricing.setIsDeleted('y');
     this.eventPricingRepository.save(eventPricing);
     return new CommandProcessingResultBuilder().withEntityId(eventPricing.getId()).build();
   } catch (DataIntegrityViolationException dev) {
     return CommandProcessingResult.empty();
   }
 }
 public CommandProcessingResult updateEventPricing(JsonCommand command) {
   try {
     this.apiJsonDeserializer.validateForCreate(command.json());
     EventPricing eventPrice = this.eventPricingRepository.findOne(command.entityId());
     EventMaster eventMaster = eventPrice.getEventId();
     EventPricing newEventPricing = EventPricing.fromJson(command, eventMaster);
     eventPrice = (EventPricing) UpdateCompareUtil.compare(eventPrice, newEventPricing);
     this.eventPricingRepository.save(eventPrice);
     return new CommandProcessingResultBuilder()
         .withEntityId(eventPrice.getId())
         .withCommandId(command.commandId())
         .build();
   } catch (DataIntegrityViolationException dev) {
     return CommandProcessingResult.empty();
   }
 }
  @Transactional
  @Override
  public CommandProcessingResult createGLClosure(final JsonCommand command) {
    try {
      final GLClosureCommand closureCommand =
          this.fromApiJsonDeserializer.commandFromApiJson(command.json());
      closureCommand.validateForCreate();

      // check office is valid
      final Long officeId =
          command.longValueOfParameterNamed(GLClosureJsonInputParams.OFFICE_ID.getValue());
      final Office office = this.officeRepository.findOne(officeId);
      if (office == null) {
        throw new OfficeNotFoundException(officeId);
      }

      // TODO: Get Tenant specific date
      // ensure closure date is not in the future
      final Date todaysDate = DateUtils.getDateOfTenant();
      final Date closureDate =
          command.DateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue());
      if (closureDate.after(todaysDate)) {
        throw new GLClosureInvalidException(GL_CLOSURE_INVALID_REASON.FUTURE_DATE, closureDate);
      }
      // shouldn't be before an existing accounting closure
      final GLClosure latestGLClosure =
          this.glClosureRepository.getLatestGLClosureByBranch(officeId);
      if (latestGLClosure != null) {
        if (latestGLClosure.getClosingDate().after(closureDate)) {
          throw new GLClosureInvalidException(
              GL_CLOSURE_INVALID_REASON.ACCOUNTING_CLOSED, latestGLClosure.getClosingDate());
        }
      }
      final GLClosure glClosure = GLClosure.fromJson(office, command);

      this.glClosureRepository.saveAndFlush(glClosure);

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withOfficeId(officeId)
          .withEntityId(glClosure.getId())
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleGLClosureIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult createCharge(final JsonCommand command) {
    try {
      this.context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForCreate(command.json());

      final Charge charge = Charge.fromJson(command);
      this.chargeRepository.save(charge);

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withEntityId(charge.getId())
          .build();
    } catch (DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @POST
  @Consumes({MediaType.MULTIPART_FORM_DATA})
  @Produces({MediaType.APPLICATION_JSON})
  public String createDocument(
      @PathParam("entityType") final String entityType,
      @PathParam("entityId") final Long entityId,
      @HeaderParam("Content-Length") final Long fileSize,
      @FormDataParam("file") final InputStream inputStream,
      @FormDataParam("file") final FormDataContentDisposition fileDetails,
      @FormDataParam("file") final FormDataBodyPart bodyPart,
      @FormDataParam("name") final String name,
      @FormDataParam("description") final String description) {

    FileUtils.validateFileSizeWithinPermissibleRange(
        fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);

    /**
     * TODO: also need to have a backup and stop reading from stream after max size is reached to
     * protect against malicious clients
     */

    /** TODO: need to extract the actual file type and determine if they are permissable */
    final DocumentCommand documentCommand =
        new DocumentCommand(
            null,
            null,
            entityType,
            entityId,
            name,
            fileDetails.getFileName(),
            fileSize,
            bodyPart.getMediaType().toString(),
            description,
            null);

    final Long documentId =
        this.documentWritePlatformService.createDocument(documentCommand, inputStream);

    return this.toApiJsonSerializer.serialize(
        CommandProcessingResult.resourceResult(documentId, null));
  }
  @Transactional
  @Override
  @CacheEvict(value = "hooks", allEntries = true)
  public CommandProcessingResult createHook(final JsonCommand command) {

    try {
      this.context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForCreate(command.json());

      final HookTemplate template =
          retrieveHookTemplateBy(command.stringValueOfParameterNamed(nameParamName));
      final String configJson = command.jsonFragment(configParamName);
      final Set<HookConfiguration> config =
          assembleConfig(command.mapValueOfParameterNamed(configJson), template);
      final JsonArray events = command.arrayOfParameterNamed(eventsParamName);
      final Set<HookResource> allEvents = assembleSetOfEvents(events);
      Template ugdTemplate = null;
      if (command.hasParameter(templateIdParamName)) {
        final Long ugdTemplateId = command.longValueOfParameterNamed(templateIdParamName);
        ugdTemplate = this.ugdTemplateRepository.findOne(ugdTemplateId);
        if (ugdTemplate == null) {
          throw new TemplateNotFoundException(ugdTemplateId);
        }
      }
      final Hook hook = Hook.fromJson(command, template, config, allEvents, ugdTemplate);

      validateHookRules(template, config, allEvents);

      this.hookRepository.save(hook);

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withEntityId(hook.getId())
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleHookDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult updateOffice(final Long officeId, final JsonCommand command) {

    try {
      final AppUser currentUser = context.authenticatedUser();

      this.fromApiJsonDeserializer.validateForUpdate(command.json());

      Long parentId = null;
      if (command.parameterExists("parentId")) {
        parentId = command.longValueOfParameterNamed("parentId");
      }

      final Office office = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId);

      final Map<String, Object> changes = office.update(command);

      if (changes.containsKey("parentId")) {
        final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, parentId);
        office.update(parent);
      }

      if (!changes.isEmpty()) {
        this.officeRepository.saveAndFlush(office);
      }

      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(office.getId()) //
          .withOfficeId(office.getId()) //
          .with(changes) //
          .build();
    } catch (DataIntegrityViolationException dve) {
      handleOfficeDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult createSavingAccount(final JsonCommand command) {
    try {
      this.context.authenticatedUser();
      this.savingsAccountDataValidator.validateForCreate(command.json());

      final List<Long> existingTransactionIds = new ArrayList<Long>();
      final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
      final SavingsAccount account =
          this.savingAccountAssembler.assembleFrom(
              command, existingTransactionIds, existingReversedTransactionIds);
      this.savingAccountRepository.save(account);

      if (account.isAccountNumberRequiresAutoGeneration()) {
        final AccountNumberGenerator accountNoGenerator =
            this.accountIdentifierGeneratorFactory.determineLoanAccountNoGenerator(account.getId());
        account.updateAccountNo(accountNoGenerator.generate());

        this.savingAccountRepository.save(account);
      }

      postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);

      final Long savingsId = account.getId();
      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(savingsId) //
          .withOfficeId(account.officeId()) //
          .withClientId(account.clientId()) //
          .withGroupId(account.groupId()) //
          .withSavingsId(savingsId) //
          .build();
    } catch (DataAccessException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult updateHoliday(final JsonCommand command) {

    try {
      this.context.authenticatedUser();
      this.fromApiJsonDeserializer.validateForUpdate(command.json());

      final Holiday holiday =
          this.holidayRepository.findOneWithNotFoundDetection(command.entityId());
      Map<String, Object> changes = holiday.update(command);

      validateInputDates(
          holiday.getFromDateLocalDate(),
          holiday.getToDateLocalDate(),
          holiday.getRepaymentsRescheduledToLocalDate());

      if (changes.containsKey(officesParamName)) {
        final Set<Office> offices = getSelectedOffices(command);
        final boolean updated = holiday.update(offices);
        if (!updated) {
          changes.remove(officesParamName);
        }
      }

      this.holidayRepository.saveAndFlush(holiday);

      return new CommandProcessingResultBuilder()
          .withEntityId(holiday.getId())
          .with(changes)
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return CommandProcessingResult.empty();
    }
  }
  /**
   * This method is using for Handling Paypal IPN Requests.
   *
   * <p>i) We have to Verify the Paypal IPN Request by Re-Sending the Received Parameters to Paypal
   * IPN Server.
   *
   * <p>ii) Paypal IPN Server Checks Whether IPN Server Sending Request Parameters and Received
   * Parameters(Which are Sending by OBS on (i)).
   *
   * <p>iii) If Both Request Parameters are Match, Then Only Paypal Server Send "VERIFIED" as
   * Response
   *
   * <p>iv) If Both are mis-match, Then Send "INVALID" as Response.
   */
  @POST
  @Path("ipnhandler")
  @Consumes({MediaType.APPLICATION_FORM_URLENCODED})
  @Produces({MediaType.TEXT_HTML})
  public void paypalRecurringPayment(final @Context HttpServletRequest request) {

    RecurringBillingHistory recurringBillingHistory = new RecurringBillingHistory();

    try {
      String verifiyMessage =
          this.paymentGatewayRecurringWritePlatformService.paypalRecurringVerification(request);
      String txnType =
          request.getParameter(RecurringPaymentTransactionTypeConstants.RECURRING_TXNTYPE);

      System.out.println("Transaction Type :" + txnType + " , Result:" + verifiyMessage);

      String requestParameters =
          this.paymentGatewayRecurringWritePlatformService.getRequestParameters(request);

      recurringBillingHistory.setTransactionData(requestParameters);
      recurringBillingHistory.setTransactionDate(DateUtils.getDateOfTenant());
      recurringBillingHistory.setSource(RecurringPaymentTransactionTypeConstants.PAYPAL);
      recurringBillingHistory.setTransactionStatus(verifiyMessage);
      recurringBillingHistory.setTransactionCategory(txnType);

      if (request.getParameterMap().containsKey("txn_id")) {
        recurringBillingHistory.setTransactionId(request.getParameter("txn_id"));
      }

      if (RecurringPaymentTransactionTypeConstants.RECURRING_VERIFIED.equals(verifiyMessage)) {

        switch (txnType) {
          case RecurringPaymentTransactionTypeConstants.SUBSCR_SIGNUP:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_PROFILE_CREATED:
            this.paymentGatewayRecurringWritePlatformService.recurringSubscriberSignUp(
                request, recurringBillingHistory);

            break;

          case RecurringPaymentTransactionTypeConstants.SUBSCR_PAYMENT:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT:
            PaypalRecurringBilling paypalRecurringBilling =
                this.paymentGatewayRecurringWritePlatformService.recurringSubscriberSignUp(
                    request, recurringBillingHistory);

            if (null != paypalRecurringBilling) {

              String jsonObject =
                  this.paymentGatewayRecurringWritePlatformService.createJsonForOnlineMethod(
                      request);

              String data = OnlinePaymentMethod(jsonObject);

              JSONObject resultJsonObject = new JSONObject(data);

              String result = resultJsonObject.getString("Result");
              String description = resultJsonObject.getString("Description");

              if (result.equalsIgnoreCase(RecurringPaymentTransactionTypeConstants.SUCCESS)) {

                this.paymentGatewayRecurringWritePlatformService.recurringEventUpdate(
                    request, recurringBillingHistory);

              } else {
                recurringBillingHistory.setClientId(paypalRecurringBilling.getClientId());
                recurringBillingHistory.setObsStatus(
                    RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
                recurringBillingHistory.setObsDescription(
                    "Payment Failed in OBS, Reason: " + description);
                this.recurringBillingHistoryRepository.save(recurringBillingHistory);
              }
            }

            break;

          case RecurringPaymentTransactionTypeConstants.SUBSCR_EOT:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_EXPIRED:
          case RecurringPaymentTransactionTypeConstants.SUBSCR_CANCELLED:
            String profileId =
                request.getParameter(RecurringPaymentTransactionTypeConstants.SUBSCRID);
            PaypalRecurringBilling billing =
                this.paymentGatewayRecurringWritePlatformService.getRecurringBillingObject(
                    profileId);

            if (null == billing || null == billing.getOrderId()) {

              recurringBillingHistory.setClientId(0L);
              recurringBillingHistory.setObsStatus(
                  RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
              recurringBillingHistory.setObsDescription(
                  "OrderId Not Found with this SubscriberId:" + profileId);

            } else {

              String status =
                  this.paymentGatewayRecurringWritePlatformService.getOrderStatus(
                      billing.getOrderId());

              this.paymentGatewayRecurringWritePlatformService.updateRecurringBillingTable(
                  profileId);

              if (null != status && status.equalsIgnoreCase(StatusTypeEnum.ACTIVE.toString())) {
                final CommandWrapper commandRequest =
                    new CommandWrapperBuilder().terminateOrder(billing.getOrderId()).build();
                CommandProcessingResult result =
                    this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
                recurringBillingHistory.setClientId(billing.getClientId());

                if (null == result || result.resourceId() <= 0) {
                  recurringBillingHistory.setObsStatus(
                      RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
                  recurringBillingHistory.setObsDescription("order Terminate Action Failed...");
                } else {
                  recurringBillingHistory.setObsStatus(
                      RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_SUCCESS);
                  recurringBillingHistory.setObsDescription("Order Termination Completed...");
                }
              }
            }

            this.recurringBillingHistoryRepository.save(recurringBillingHistory);

            break;

          case RecurringPaymentTransactionTypeConstants.SUBSCR_FAILED:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILED:
          case RecurringPaymentTransactionTypeConstants.SUBSCR_MODIFY:
          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_SKIPPED:
            recurringBillingHistory.setClientId(0L);
            recurringBillingHistory.setObsStatus(
                RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_UNKNOWN);
            recurringBillingHistory.setObsDescription("UnDeveloped Request types");
            this.recurringBillingHistoryRepository.save(recurringBillingHistory);
            break;

          case RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_SUSPENDED:
          case RecurringPaymentTransactionTypeConstants
              .RECURRING_PAYMENT_SUSPENDED_DUE_TO_MAX_FAILED_PAYMENT:
            String profileId1 =
                request.getParameter(RecurringPaymentTransactionTypeConstants.SUBSCRID);
            this.paymentGatewayRecurringWritePlatformService.disConnectOrder(
                profileId1, recurringBillingHistory);

            break;
          default:
            break;
        }

      } else {
        recurringBillingHistory.setClientId(0L);
        recurringBillingHistory.setObsStatus(
            RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
        recurringBillingHistory.setObsDescription("Paypal Verification Failed...");
        this.recurringBillingHistoryRepository.save(recurringBillingHistory);
      }

    } catch (JSONException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription("JSONException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (UnsupportedEncodingException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription(
          "UnsupportedEncodingException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (IllegalStateException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription(
          "IllegalStateException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (ClientProtocolException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription(
          "ClientProtocolException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    } catch (IOException e) {
      recurringBillingHistory.setClientId(0L);
      recurringBillingHistory.setObsStatus(
          RecurringPaymentTransactionTypeConstants.RECURRING_PAYMENT_FAILURE);
      recurringBillingHistory.setObsDescription("IOException throwing.." + stackTraceToString(e));
      this.recurringBillingHistoryRepository.save(recurringBillingHistory);
    }
  }
  /**
   * This method is used for Online Payment Systems like Paypal,Dalpay,Korta etc...
   *
   * <p>Storing these payment details in 2 tables. 1) b_paymentgateway and 2) b_payment.
   */
  @PUT
  @Path("onlinepayment")
  @Consumes({MediaType.APPLICATION_JSON})
  @Produces({MediaType.TEXT_HTML})
  public String OnlinePaymentMethod(final String apiRequestBodyAsJson) {

    try {

      final CommandWrapper commandRequest =
          new CommandWrapperBuilder().OnlinePaymentGateway().withJson(apiRequestBodyAsJson).build();
      final CommandProcessingResult result =
          this.commandsSourceWritePlatformService.logCommandSource(commandRequest);

      Map<String, Object> output = result.getChanges();

      String status = String.valueOf(output.get("status"));
      String client = String.valueOf(output.get("clientId"));
      String txnId = String.valueOf(output.get("txnId"));
      String amount = String.valueOf(output.get("amount"));
      String currency = String.valueOf(output.get("currency"));

      String error = String.valueOf(output.get("error"));
      String cardType = null;
      String cardNumber = null;

      JSONObject apiObject = new JSONObject(apiRequestBodyAsJson);

      if (apiObject.has("cardType")) {
        cardType = apiObject.getString("cardType");
      }

      if (apiObject.has("cardNumber")) {
        cardNumber = apiObject.getString("cardNumber");
      }

      String totalAmount = amount + " " + currency;

      Long clientId = Long.valueOf(client);

      if (status.equalsIgnoreCase("Success") || status.equalsIgnoreCase("Pending")) {

        Long pgId = Long.valueOf(String.valueOf(output.get("pgId")));
        String OutputData =
            this.paymentGatewayWritePlatformService.payment(clientId, pgId, txnId, amount, error);

        JSONObject object = new JSONObject(OutputData);

        this.paymentGatewayWritePlatformService.emailSending(
            clientId,
            object.getString("Result"),
            object.getString("Description"),
            txnId,
            totalAmount,
            cardType,
            cardNumber);

        return object.toString();

      } else {

        JSONObject object = new JSONObject();
        object.put("Result", status.toUpperCase());
        object.put("Description", error);
        object.put("Amount", totalAmount);
        object.put("ObsPaymentId", "");
        object.put("TransactionId", txnId);

        this.paymentGatewayWritePlatformService.emailSending(
            clientId, status, error, txnId, totalAmount, cardType, cardNumber);

        return object.toString();
      }

    } catch (JSONException e) {
      String output =
          "{\"Result\":\"FAILURE\", \"Description\":\"JSONException = \"" + e.getMessage() + "}";
      return output;
    }
  }
  @Override
  public CommandProcessingResult convertToClient(final Long entityId) {

    final AppUser currentUser = context.authenticatedUser();
    final ClientProspect clientProspect = retrieveCodeBy(entityId);

    Long clientId = null;

    final JSONObject newClientJsonObject = new JSONObject();

    try {
      SimpleDateFormat formatter = new SimpleDateFormat("dd MMMM yyyy");
      String activationDate = formatter.format(DateUtils.getDateOfTenant());

      final Long officeId = currentUser.getOffice().getId();
      newClientJsonObject.put("dateFormat", "dd MMMM yyyy");
      newClientJsonObject.put("locale", "en");
      newClientJsonObject.put("officeId", officeId);
      newClientJsonObject.put("firstname", clientProspect.getFirstName());
      newClientJsonObject.put("middlename", clientProspect.getMiddleName());
      newClientJsonObject.put("lastname", clientProspect.getLastName());
      newClientJsonObject.put("fullname", "");
      newClientJsonObject.put("externalId", "");
      newClientJsonObject.put("clientCategory", "20");
      // newClientJsonObject.put("active","300");
      newClientJsonObject.put("activationDate", activationDate);
      newClientJsonObject.put("active", "true");
      newClientJsonObject.put("email", clientProspect.getEmail());
      newClientJsonObject.put("phone", clientProspect.getMobileNumber());
      newClientJsonObject.put("flag", false);
      /*
       * newClientJsonObject.put("login","");
       * newClientJsonObject.put("password","");
       */

      newClientJsonObject.put("addressNo", clientProspect.getAddress());
      newClientJsonObject.put("street", clientProspect.getStreetArea());
      newClientJsonObject.put("city", clientProspect.getCityDistrict());
      newClientJsonObject.put("zipCode", clientProspect.getZipCode());
      newClientJsonObject.put("state", clientProspect.getState());
      newClientJsonObject.put("country", clientProspect.getCountry());
      newClientJsonObject.put("flag", "false");

      final CommandWrapper commandNewClient =
          new CommandWrapperBuilder()
              .createClient()
              .withJson(newClientJsonObject.toString().toString())
              .build(); //

      final CommandProcessingResult clientResult =
          this.commandsSourceWritePlatformService.logCommandSource(commandNewClient);
      /*
       * final CommandWrapper commandRequest = new
       * CommandWrapperBuilder().
       * createAddress(clientResult.getClientId()).
       * withJson(newClientAddressObject.toString().toString()).build();
       * final CommandProcessingResult addressResult =
       * this.commandsSourceWritePlatformService
       * .logCommandSource(commandRequest);
       */

      clientProspect.setStatusRemark(clientResult.getClientId().toString());
      clientId = clientResult.getClientId();

    } catch (JSONException e) {
      e.printStackTrace();
    }

    clientProspect.setStatus("Closed");
    // clientProspect.setIsDeleted('Y');

    // clientProspect.setStatusRemark(command.stringValueOfParameterNamed("statusRemark"));

    this.clientProspectJpaRepository.saveAndFlush(clientProspect);

    return new CommandProcessingResultBuilder().withEntityId(clientId).build();
  }
  @Override
  public CommandProcessingResult updateBillMaster(
      final List<BillDetail> billDetails,
      final BillMaster billMaster,
      final BigDecimal clientBalance) {

    try {
      BigDecimal chargeAmount = BigDecimal.ZERO;
      BigDecimal adjustmentAmount = BigDecimal.ZERO;
      BigDecimal paymentAmount = BigDecimal.ZERO;
      BigDecimal dueAmount = BigDecimal.ZERO;
      BigDecimal taxAmount = BigDecimal.ZERO;
      BigDecimal oneTimeSaleAmount = BigDecimal.ZERO;
      BigDecimal serviceTransferAmount = BigDecimal.ZERO;
      BigDecimal depositRefundAmount = BigDecimal.ZERO;

      for (final BillDetail billDetail : billDetails) {
        if ("SERVICE_CHARGES".equalsIgnoreCase(billDetail.getTransactionType())) {
          if (billDetail.getAmount() != null)
            chargeAmount = chargeAmount.add(billDetail.getAmount());

        } else if ("TAXES".equalsIgnoreCase(billDetail.getTransactionType())) {
          if (billDetail.getAmount() != null) taxAmount = taxAmount.add(billDetail.getAmount());

        } else if ("ADJUSTMENT".equalsIgnoreCase(billDetail.getTransactionType())) {
          if (billDetail.getAmount() != null)
            adjustmentAmount = adjustmentAmount.add(billDetail.getAmount());

        } else if (billDetail.getTransactionType().contains("PAYMENT")) {
          if (billDetail.getAmount() != null)
            paymentAmount = paymentAmount.add(billDetail.getAmount());

        } else if ("ONETIME_CHARGES".equalsIgnoreCase(billDetail.getTransactionType())) {
          if (billDetail.getAmount() != null)
            oneTimeSaleAmount = oneTimeSaleAmount.add(billDetail.getAmount());

        } else if ("SERVICE_TRANSFER".equalsIgnoreCase(billDetail.getTransactionType())) {
          if (billDetail.getAmount() != null)
            serviceTransferAmount = serviceTransferAmount.add(billDetail.getAmount());

        } else if ("DEPOSIT&REFUND".equalsIgnoreCase(billDetail.getTransactionType())) {
          if (billDetail.getAmount() != null)
            depositRefundAmount = depositRefundAmount.add(billDetail.getAmount());
        }
      }
      dueAmount =
          chargeAmount
              .add(taxAmount)
              .add(oneTimeSaleAmount)
              .add(clientBalance)
              .add(depositRefundAmount)
              .add(serviceTransferAmount)
              .subtract(paymentAmount)
              .subtract(adjustmentAmount);
      billMaster.setChargeAmount(chargeAmount.add(oneTimeSaleAmount).add(serviceTransferAmount));
      billMaster.setAdjustmentAmount(adjustmentAmount);
      billMaster.setTaxAmount(taxAmount);
      billMaster.setPaidAmount(paymentAmount);
      billMaster.setDueAmount(dueAmount);
      billMaster.setPreviousBalance(clientBalance);
      billMaster.setDepositRefundAmount(depositRefundAmount);
      this.billMasterRepository.save(billMaster);
      return new CommandProcessingResult(billMaster.getId(), billMaster.getClientId());
    } catch (DataIntegrityViolationException dve) {
      LOGGER.error("unable to retrieve data" + dve.getLocalizedMessage());
      return CommandProcessingResult.empty();
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult activationProcess(final JsonCommand command) {

    try {
      context.authenticatedUser();
      CommandProcessingResult resultClient = null;
      CommandProcessingResult resultSale = null;
      ///  CommandProcessingResult resultAllocate=null;
      CommandProcessingResult resultOrder = null;
      final JsonElement element = fromJsonHelper.parse(command.json());
      JsonArray clientData = fromJsonHelper.extractJsonArrayNamed("client", element);
      JsonArray saleData = fromJsonHelper.extractJsonArrayNamed("sale", element);
      JsonArray owndevices = fromJsonHelper.extractJsonArrayNamed("owndevice", element);
      // JsonArray allocateData = fromJsonHelper.extractJsonArrayNamed("allocate", element);
      JsonArray bookOrder = fromJsonHelper.extractJsonArrayNamed("bookorder", element);

      for (JsonElement j : clientData) {

        JsonCommand comm =
            new JsonCommand(
                null,
                j.toString(),
                j,
                fromJsonHelper,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null);
        resultClient = this.clientWritePlatformService.createClient(comm);
      }

      //  Configuration
      // configuration=configurationRepository.findOneByName(ConfigurationConstants.CONFIG_PROPERTY_DEVICE_AGREMENT_TYPE);
      // if(configuration.getValue().equalsIgnoreCase(ConfigurationConstants.CONFIR_PROPERTY_SALE)){
      if (saleData.size() != 0) {
        for (JsonElement sale : saleData) {
          JsonCommand comm =
              new JsonCommand(
                  null,
                  sale.toString(),
                  sale,
                  fromJsonHelper,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null);
          resultSale =
              this.oneTimeSaleWritePlatformService.createOneTimeSale(
                  comm, resultClient.getClientId());
        }
      } // else
      // if(configuration.getValue().equalsIgnoreCase(ConfigurationConstants.CONFIR_PROPERTY_OWN)){
      else if (owndevices.size() != 0) {
        for (JsonElement ownDevice : owndevices) {

          JsonCommand comm =
              new JsonCommand(
                  null,
                  ownDevice.toString(),
                  ownDevice,
                  fromJsonHelper,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null);
          resultSale =
              this.ownedHardwareWritePlatformService.createOwnedHardware(
                  comm, resultClient.getClientId());
        }
      }

      for (JsonElement order : bookOrder) {

        JsonCommand comm =
            new JsonCommand(
                null,
                order.toString(),
                order,
                fromJsonHelper,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null);
        resultOrder = this.orderWritePlatformService.createOrder(resultClient.getClientId(), comm);
      }
      return resultClient;

    } catch (DataIntegrityViolationException dve) {

      handleDataIntegrityIssues(command, dve);
      return new CommandProcessingResult(Long.valueOf(-1));
    }
  }
  // @SuppressWarnings("unused")
  @Override
  public CommandProcessingResult selfRegistrationProcess(JsonCommand command) {

    try {

      context.authenticatedUser();
      Configuration deviceStatusConfiguration =
          configurationRepository.findOneByName(
              ConfigurationConstants.CONFIR_PROPERTY_REGISTRATION_DEVICE);

      commandFromApiJsonDeserializer.validateForCreate(
          command.json(), deviceStatusConfiguration.isEnabled());
      Long id = new Long(1);
      CommandProcessingResult resultClient = null;
      CommandProcessingResult resultSale = null;
      CommandProcessingResult resultOrder = null;
      String device = null;
      String dateFormat = "dd MMMM yyyy";
      String activationDate = new SimpleDateFormat(dateFormat).format(DateUtils.getDateOfTenant());

      String fullname = command.stringValueOfParameterNamed("fullname");
      String firstName = command.stringValueOfParameterNamed("firstname");
      String city = command.stringValueOfParameterNamed("city");
      String address = command.stringValueOfParameterNamed("address");
      Long phone = command.longValueOfParameterNamed("phone");
      Long homePhoneNumber = command.longValueOfParameterNamed("homePhoneNumber");
      String email = command.stringValueOfParameterNamed("email");
      String nationalId = command.stringValueOfParameterNamed("nationalId");
      String deviceId = command.stringValueOfParameterNamed("device");
      String deviceAgreementType = command.stringValueOfParameterNamed("deviceAgreementType");
      String password = command.stringValueOfParameterNamed("password");
      String isMailCheck = command.stringValueOfParameterNamed("isMailCheck");
      String passport = command.stringValueOfParameterNamed("passport");
      SelfCareTemporary temporary = null;

      if (isMailCheck == null || isMailCheck.isEmpty()) {
        temporary = selfCareTemporaryRepository.findOneByEmailId(email);

        if (temporary == null) {
          throw new SelfCareTemporaryEmailIdNotFoundException(email);

        } else if (temporary.getStatus().equalsIgnoreCase("ACTIVE")) {
          throw new ClientAlreadyCreatedException();

        } else if (temporary.getStatus().equalsIgnoreCase("INACTIVE")) {
          throw new SelfCareNotVerifiedException(email);
        }
      }

      //	if (temporary.getStatus().equalsIgnoreCase("PENDING")){

      String zipCode = command.stringValueOfParameterNamed("zipCode");
      // client creation
      AddressData addressData = this.addressReadPlatformService.retrieveAdressBy(city);
      CodeValue codeValue = this.codeValueRepository.findOneByCodeValue("Normal");
      JSONObject clientcreation = new JSONObject();
      clientcreation.put("officeId", new Long(1));
      clientcreation.put("clientCategory", codeValue.getId());
      clientcreation.put("firstname", firstName);
      clientcreation.put("lastname", fullname);
      clientcreation.put("phone", phone);
      clientcreation.put("homePhoneNumber", homePhoneNumber);
      clientcreation.put("entryType", "IND"); // new Long(1));
      clientcreation.put("addressNo", address);
      clientcreation.put("city", addressData.getCity());
      clientcreation.put("state", addressData.getState());
      clientcreation.put("country", addressData.getCountry());
      clientcreation.put("email", email);
      clientcreation.put("locale", "en");
      clientcreation.put("active", true);
      clientcreation.put("dateFormat", dateFormat);
      clientcreation.put("activationDate", activationDate);
      clientcreation.put("flag", false);
      clientcreation.put("zipCode", zipCode);
      clientcreation.put("device", deviceId);
      clientcreation.put("password", password);

      if (nationalId != null && !nationalId.equalsIgnoreCase("")) {
        clientcreation.put("externalId", nationalId);
      }

      final JsonElement element = fromJsonHelper.parse(clientcreation.toString());
      JsonCommand clientCommand =
          new JsonCommand(
              null,
              clientcreation.toString(),
              element,
              fromJsonHelper,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null,
              null);
      resultClient = this.clientWritePlatformService.createClient(clientCommand);

      if (resultClient == null) {
        throw new PlatformDataIntegrityException(
            "error.msg.client.creation.failed", "Client Creation Failed", "Client Creation Failed");
      }

      if (passport != null && !passport.equalsIgnoreCase("")) {
        CodeValue passportcodeValue = this.codeValueRepository.findOneByCodeValue("Passport");
        JSONObject clientIdentifierJson = new JSONObject();
        clientIdentifierJson.put("documentTypeId", passportcodeValue.getId());
        clientIdentifierJson.put("documentKey", passport);
        final JsonElement idenfierJsonEement =
            fromJsonHelper.parse(clientIdentifierJson.toString());
        JsonCommand idenfierJsonCommand =
            new JsonCommand(
                null,
                clientIdentifierJson.toString(),
                idenfierJsonEement,
                fromJsonHelper,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null);
        this.clientIdentifierWritePlatformService.addClientIdentifier(
            resultClient.getClientId(), idenfierJsonCommand);
      }

      if (temporary != null) {
        temporary.setStatus("ACTIVE");
        this.selfCareTemporaryRepository.saveAndFlush(temporary);
      }

      // book device
      if (deviceStatusConfiguration != null) {

        if (deviceStatusConfiguration.isEnabled()) {

          JSONObject bookDevice = new JSONObject();
          /*deviceStatusConfiguration = configurationRepository
          .findOneByName(ConfigurationConstants.CONFIG_PROPERTY_DEVICE_AGREMENT_TYPE);*/

          /*if (deviceStatusConfiguration != null&& deviceStatusConfiguration.isEnabled()
          && deviceStatusConfiguration.getValue().equalsIgnoreCase(ConfigurationConstants.CONFIR_PROPERTY_SALE)) {*/
          if (deviceAgreementType.equalsIgnoreCase(ConfigurationConstants.CONFIR_PROPERTY_SALE)) {

            device = command.stringValueOfParameterNamed("device");
            ItemDetails detail = itemDetailsRepository.getInventoryItemDetailBySerialNum(device);

            if (detail == null) {
              throw new SerialNumberNotFoundException(device);
            }

            ItemMaster itemMaster = this.itemRepository.findOne(detail.getItemMasterId());

            if (itemMaster == null) {
              throw new ItemNotFoundException(deviceId);
            }

            if (detail != null && detail.getStatus().equalsIgnoreCase("Used")) {
              throw new SerialNumberAlreadyExistException(device);
            }

            JSONObject serialNumberObject = new JSONObject();
            serialNumberObject.put("serialNumber", device);
            serialNumberObject.put("clientId", resultClient.getClientId());
            serialNumberObject.put("status", "allocated");
            serialNumberObject.put("itemMasterId", detail.getItemMasterId());
            serialNumberObject.put("isNewHw", "Y");
            JSONArray serialNumber = new JSONArray();
            serialNumber.put(0, serialNumberObject);

            bookDevice.put("chargeCode", itemMaster.getChargeCode());
            bookDevice.put("unitPrice", itemMaster.getUnitPrice());
            bookDevice.put("itemId", itemMaster.getId());
            bookDevice.put("discountId", id);
            bookDevice.put("officeId", detail.getOfficeId());
            bookDevice.put("totalPrice", itemMaster.getUnitPrice());

            bookDevice.put("quantity", id);
            bookDevice.put("locale", "en");
            bookDevice.put("dateFormat", dateFormat);
            bookDevice.put("saleType", "NEWSALE");
            bookDevice.put("saleDate", activationDate);
            bookDevice.put("serialNumber", serialNumber);

            final JsonElement deviceElement = fromJsonHelper.parse(bookDevice.toString());
            JsonCommand comm =
                new JsonCommand(
                    null,
                    bookDevice.toString(),
                    deviceElement,
                    fromJsonHelper,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null);

            resultSale =
                this.oneTimeSaleWritePlatformService.createOneTimeSale(
                    comm, resultClient.getClientId());

            if (resultSale == null) {
              throw new PlatformDataIntegrityException(
                  "error.msg.client.device.assign.failed",
                  "Device Assign Failed for ClientId :" + resultClient.getClientId(),
                  "Device Assign Failed");
            }

          } else if (deviceAgreementType.equalsIgnoreCase(
              ConfigurationConstants.CONFIR_PROPERTY_OWN)) {

            List<ItemMaster> itemMaster = this.itemRepository.findAll();
            bookDevice.put("locale", "en");
            bookDevice.put("dateFormat", dateFormat);
            bookDevice.put("allocationDate", activationDate);
            bookDevice.put("provisioningSerialNumber", deviceId);
            bookDevice.put("itemType", itemMaster.get(0).getId());
            bookDevice.put("serialNumber", deviceId);
            bookDevice.put("status", "ACTIVE");
            CommandWrapper commandWrapper =
                new CommandWrapperBuilder()
                    .createOwnedHardware(resultClient.getClientId())
                    .withJson(bookDevice.toString())
                    .build();
            final CommandProcessingResult result =
                portfolioCommandSourceWritePlatformService.logCommandSource(commandWrapper);

            if (result == null) {
              throw new PlatformDataIntegrityException(
                  "error.msg.client.device.assign.failed",
                  "Device Assign Failed for ClientId :" + resultClient.getClientId(),
                  "Device Assign Failed");
            }
          } else {

          }
        }
      }

      // book order
      Configuration selfregistrationconfiguration =
          configurationRepository.findOneByName(
              ConfigurationConstants.CONFIR_PROPERTY_SELF_REGISTRATION);

      if (selfregistrationconfiguration != null && selfregistrationconfiguration.isEnabled()) {

        if (selfregistrationconfiguration.getValue() != null) {

          JSONObject ordeJson = new JSONObject(selfregistrationconfiguration.getValue());
          ordeJson.put("locale", "en");
          ordeJson.put("isNewplan", true);
          ordeJson.put("dateFormat", dateFormat);
          ordeJson.put("start_date", activationDate);

          CommandWrapper commandRequest =
              new CommandWrapperBuilder()
                  .createOrder(resultClient.getClientId())
                  .withJson(ordeJson.toString())
                  .build();
          resultOrder =
              this.portfolioCommandSourceWritePlatformService.logCommandSource(commandRequest);

          if (resultOrder == null) {
            throw new PlatformDataIntegrityException(
                "error.msg.client.order.creation",
                "Book Order Failed for ClientId:" + resultClient.getClientId(),
                "Book Order Failed");
          }

        } else {

          String paytermCode = command.stringValueOfParameterNamed("paytermCode");
          Long contractPeriod = command.longValueOfParameterNamed("contractPeriod");
          Long planCode = command.longValueOfParameterNamed("planCode");

          JSONObject ordeJson = new JSONObject();

          ordeJson.put("planCode", planCode);
          ordeJson.put("contractPeriod", contractPeriod);
          ordeJson.put("paytermCode", paytermCode);
          ordeJson.put("billAlign", false);
          ordeJson.put("locale", "en");
          ordeJson.put("isNewplan", true);
          ordeJson.put("dateFormat", dateFormat);
          ordeJson.put("start_date", activationDate);

          CommandWrapper commandRequest =
              new CommandWrapperBuilder()
                  .createOrder(resultClient.getClientId())
                  .withJson(ordeJson.toString())
                  .build();
          resultOrder =
              this.portfolioCommandSourceWritePlatformService.logCommandSource(commandRequest);

          if (resultOrder == null) {
            throw new PlatformDataIntegrityException(
                "error.msg.client.order.creation",
                "Book Order Failed for ClientId:" + resultClient.getClientId(),
                "Book Order Failed");
          }
        }
      }

      return resultClient;

      /*}  else {
      	return new CommandProcessingResult(Long.valueOf(-1));
      }*/

    } catch (DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return new CommandProcessingResult(Long.valueOf(-1));
    } catch (JSONException e) {
      return new CommandProcessingResult(Long.valueOf(-1));
    }
  }