@Transactional
  @Override
  public EntityIdentifier submitLoanApplication(final JsonCommand command) {

    context.authenticatedUser();

    LoanApplicationCommand loanApplicationCommand =
        this.fromApiJsonDeserializer.commandFromApiJson(command.json());
    loanApplicationCommand.validate();

    CalculateLoanScheduleQuery calculateLoanScheduleQuery =
        this.calculateLoanScheduleQueryFromApiJsonDeserializer.commandFromApiJson(command.json());
    calculateLoanScheduleQuery.validate();

    final Loan newLoanApplication = loanAssembler.assembleFrom(command);

    this.loanRepository.save(newLoanApplication);

    final String submittedOnNote = command.stringValueOfParameterNamed("submittedOnNote");
    if (StringUtils.isNotBlank(submittedOnNote)) {
      Note note = Note.loanNote(newLoanApplication, submittedOnNote);
      this.noteRepository.save(note);
    }

    return EntityIdentifier.resourceResult(newLoanApplication.getId(), command.commandId());
  }
  @Override
  public CommandProcessingResult createLoanTaxMapping(Long entityId, JsonCommand command) {

    final JsonElement parsedQuery = this.fromJsonHelper.parse(command.json());
    final JsonQuery query = JsonQuery.from(command.json(), parsedQuery, this.fromJsonHelper);
    boolean flag = false;

    if (entityId == 1L) {
      flag = true;
    }
    String data = this.calculationPlatformService.calculateTaxLoanSchedule(query, flag);
    return new CommandProcessingResultBuilder().withResourceIdAsString(data).build();
  }
  @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");
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult createProspect(JsonCommand command) {

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

      final ClientProspect entity = ClientProspect.fromJson(fromApiJsonHelper, command);
      this.clientProspectJpaRepository.save(entity);

      return new CommandProcessingResultBuilder()
          .withCommandId(command.commandId())
          .withEntityId(entity.getId())
          .build();

    } catch (DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
      return new CommandProcessingResult(Long.valueOf(-1));
    } catch (ParseException pe) {
      throw new PlatformDataIntegrityException(
          "invalid.date.and.time.format",
          "invalid.date.and.time.format",
          "invalid.date.and.time.format");
    }
  }
  @Override
  public CommandProcessingResult updateProspect(JsonCommand command) {

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

      final ClientProspect pros = retrieveCodeBy(command.entityId());
      final Map<String, Object> changes = pros.update(command);

      if (!changes.isEmpty()) {
        this.clientProspectJpaRepository.save(pros);
      }

      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(pros.getId()) //
          .with(changes) //
          .build();

    } catch (DataIntegrityViolationException dve) {
      handleDataIntegrityIssues(command, dve);
    }
    return new CommandProcessingResultBuilder().withEntityId(-1L).build();
  }
  @Transactional
  @Override
  public EntityIdentifier disburseLoan(final Long loanId, final JsonCommand command) {

    final AppUser currentUser = context.authenticatedUser();

    final LoanStateTransitionCommand disburseLoan =
        this.loanStateTransitionCommandFromApiJsonDeserializer.commandFromApiJson(command.json());
    disburseLoan.validate();

    final Loan loan = retrieveLoanBy(loanId);

    final String noteText = command.stringValueOfParameterNamed("note");
    final LocalDate actualDisbursementDate = disburseLoan.getDisbursedOnDate();
    if (this.isBeforeToday(actualDisbursementDate) && currentUser.canNotDisburseLoanInPast()) {
      throw new NoAuthorizationException(
          "User has no authority to disburse loan with a date in the past.");
    }

    final ApplicationCurrency currency =
        this.applicationCurrencyRepository.findOneByCode(loan.getPrincpal().getCurrencyCode());

    final Map<String, Object> changes =
        loan.disburse(command, defaultLoanLifecycleStateMachine(), currency);
    this.loanRepository.save(loan);

    if (StringUtils.isNotBlank(noteText)) {
      Note note = Note.loanNote(loan, noteText);
      this.noteRepository.save(note);
    }

    return EntityIdentifier.resourceResult(loanId, command.commandId(), changes);
  }
  @Transactional
  @Override
  public EntityIdentifier applicantWithdrawsFromLoanApplication(
      final Long loanId, final JsonCommand command) {

    final AppUser currentUser = context.authenticatedUser();

    final LoanStateTransitionCommand applicantWithdrawsFromLoanApplication =
        this.loanStateTransitionCommandFromApiJsonDeserializer.commandFromApiJson(command.json());
    applicantWithdrawsFromLoanApplication.validate();

    final Loan loan = retrieveLoanBy(loanId);

    final LocalDate eventDate = applicantWithdrawsFromLoanApplication.getWithdrawnOnDate();
    if (this.isBeforeToday(eventDate) && currentUser.canNotWithdrawByClientLoanInPast()) {
      throw new NoAuthorizationException(
          "User has no authority to mark loan as withdrawn by applicant with a date in the past.");
    }

    final Map<String, Object> changes =
        loan.loanApplicationWithdrawnByApplicant(command, defaultLoanLifecycleStateMachine());
    this.loanRepository.save(loan);

    String noteText = command.stringValueOfParameterNamed("note");
    if (StringUtils.isNotBlank(noteText)) {
      Note note = Note.loanNote(loan, noteText);
      this.noteRepository.save(note);
    }

    return EntityIdentifier.resourceResult(loanId, command.commandId(), changes);
  }
  @Override
  public CommandProcessingResult deleteAllLoanTaxMapId(JsonCommand command) {

    final JsonElement parsedJson = this.fromJsonHelper.parse(command.json());

    if (parsedJson.isJsonObject()) {

      final JsonObject topLevelJsonElement = parsedJson.getAsJsonObject();

      if (topLevelJsonElement.has("taxMapArray")
          && topLevelJsonElement.get("taxMapArray").isJsonArray()) {

        final JsonArray array = topLevelJsonElement.get("taxMapArray").getAsJsonArray();

        for (int i = 0; i < array.size(); i++) {
          final JsonObject loanChargeElement = array.get(i).getAsJsonObject();
          final Long taxMapId = this.fromJsonHelper.extractLongNamed("taxMapId", loanChargeElement);
          this.loanTaxMapRepository.delete(taxMapId);
        }
      }

      return new CommandProcessingResultBuilder().withEntityId(0L).build();
    }
    return null;
  }
  @Transactional
  @Override
  public Map<String, Object> updateDatatableEntryOneToMany(
      final String datatable,
      final Long appTableId,
      final Long datatableId,
      final JsonCommand command) {

    final GenericResultsetData grs =
        retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);

    if (grs.getData().size() == 0) throw new DatatableNotFoundException(datatable, appTableId);

    final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
    final Map<String, String> dataParams =
        this.fromJsonHelper.extractDataMap(typeOfMap, command.json());

    final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, "id");

    if (changes.size() == 0) return changes;

    final String sql = getUpdateSql(datatable, "id", datatableId, changes);

    if (StringUtils.isNotBlank(sql)) {
      this.jdbcTemplate.update(sql);
    } else {
      logger.info("No Changes");
    }

    return changes;
  }
  @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 createEventPricing(JsonCommand command) {
   try {
     this.context.authenticatedUser();
     this.apiJsonDeserializer.validateForCreate(command.json());
     Long eventId = command.longValueOfParameterNamed("eventId");
     EventMaster eventMaster = this.eventMasterRepository.findOne(eventId);
     final EventPricing eventPricing = EventPricing.fromJson(command, eventMaster);
     List<EventPricingData> eventDetails =
         this.eventPricingReadPlatformService.retrieventPriceData(command.entityId());
     for (EventPricingData eventDetail : eventDetails) {
       if (eventPricing.getFormatType().equalsIgnoreCase(eventDetail.getFormatType())
           && eventPricing.getClientType() == eventDetail.getClientType()
           && eventPricing.getOptType().equalsIgnoreCase(eventDetail.getOptType())) {
         throw new DuplicatEventPrice(eventPricing.getFormatType());
       }
     }
     this.eventPricingRepository.save(eventPricing);
     return new CommandProcessingResultBuilder()
         .withCommandId(command.commandId())
         .withEntityId(eventPricing.getId())
         .build();
   } catch (DataIntegrityViolationException dve) {
     handleDataIntegrityIssues(command, dve);
     return new CommandProcessingResult(Long.valueOf(-1));
   }
 }
  @Transactional
  @Override
  public void createNewDatatableEntry(
      final String dataTableName, final Long appTableId, final JsonCommand command) {

    try {
      final String appTable = getWithinScopeApplicationTableName(dataTableName, appTableId);

      final List<ResultsetColumnHeaderData> columnHeaders =
          this.genericDataService.fillResultsetColumnHeaders(dataTableName);

      final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
      final Map<String, String> dataParams =
          this.fromJsonHelper.extractDataMap(typeOfMap, command.json());

      final String sql =
          getAddSql(columnHeaders, dataTableName, getFKField(appTable), appTableId, dataParams);

      this.jdbcTemplate.update(sql);
    } catch (ConstraintViolationException dve) {
      // NOTE: jdbctemplate throws a
      // org.hibernate.exception.ConstraintViolationException even though
      // it should be a DataAccessException?
      Throwable realCause = dve.getCause();
      if (realCause.getMessage().contains("Duplicate entry")) {
        throw new PlatformDataIntegrityException(
            "error.msg.datatable.entry.duplicate",
            "An entry already exists for datatable `"
                + dataTableName
                + "` and application table with identifier `"
                + appTableId
                + "`.",
            "dataTableName",
            dataTableName,
            appTableId);
      }

      logAsErrorUnexpectedDataIntegrityException(dve);
      throw new PlatformDataIntegrityException(
          "error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource.");
    } catch (DataAccessException dve) {
      Throwable realCause = dve.getMostSpecificCause();
      if (realCause.getMessage().contains("Duplicate entry")) {
        throw new PlatformDataIntegrityException(
            "error.msg.datatable.entry.duplicate",
            "An entry already exists for datatable `"
                + dataTableName
                + "` and application table with identifier `"
                + appTableId
                + "`.",
            "dataTableName",
            dataTableName,
            appTableId);
      }

      logAsErrorUnexpectedDataIntegrityException(dve);
      throw new PlatformDataIntegrityException(
          "error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource.");
    }
  }
  @Transactional
  @Override
  public CommandProcessingResult rejectApplication(
      final Long savingsId, final JsonCommand command) {

    final AppUser currentUser = this.context.authenticatedUser();

    this.savingsAccountApplicationTransitionApiJsonValidator.validateRejection(command.json());

    final SavingsAccount savingsAccount = this.savingAccountAssembler.assembleFrom(savingsId);
    checkClientOrGroupActive(savingsAccount);

    final Map<String, Object> changes =
        savingsAccount.rejectApplication(currentUser, command, DateUtils.getLocalDateOfTenant());
    if (!changes.isEmpty()) {
      this.savingAccountRepository.save(savingsAccount);

      final String noteText = command.stringValueOfParameterNamed("note");
      if (StringUtils.isNotBlank(noteText)) {
        final Note note = Note.savingNote(savingsAccount, noteText);
        changes.put("note", noteText);
        this.noteRepository.save(note);
      }
    }

    return new CommandProcessingResultBuilder() //
        .withCommandId(command.commandId()) //
        .withEntityId(savingsId) //
        .withOfficeId(savingsAccount.officeId()) //
        .withClientId(savingsAccount.clientId()) //
        .withGroupId(savingsAccount.groupId()) //
        .withSavingsId(savingsId) //
        .with(changes) //
        .build();
  }
  @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 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 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 updateGLClosure(
      final Long glClosureId, final JsonCommand command) {
    final GLClosureCommand closureCommand =
        this.fromApiJsonDeserializer.commandFromApiJson(command.json());
    closureCommand.validateForUpdate();

    // is the glClosure valid
    final GLClosure glClosure = this.glClosureRepository.findOne(glClosureId);
    if (glClosure == null) {
      throw new GLClosureNotFoundException(glClosureId);
    }

    final Map<String, Object> changesOnly = glClosure.update(command);

    if (!changesOnly.isEmpty()) {
      this.glClosureRepository.saveAndFlush(glClosure);
    }

    return new CommandProcessingResultBuilder()
        .withCommandId(command.commandId())
        .withOfficeId(glClosure.getOffice().getId())
        .withEntityId(glClosure.getId())
        .with(changesOnly)
        .build();
  }
  @Transactional
  @Override
  public EntityIdentifier updateRolePermissions(final Long roleId, final JsonCommand command) {
    context.authenticatedUser();

    final Role role = this.roleRepository.findOne(roleId);
    if (role == null) {
      throw new RoleNotFoundException(roleId);
    }

    final Collection<Permission> allPermissions = this.permissionRepository.findAll();

    final PermissionsCommand permissionsCommand =
        this.permissionsFromApiJsonDeserializer.commandFromApiJson(command.json());

    final Map<String, Boolean> commandPermissions = permissionsCommand.getPermissions();
    final Map<String, Object> changes = new HashMap<String, Object>();
    final Map<String, Boolean> changedPermissions = new HashMap<String, Boolean>();
    for (final String permissionCode : commandPermissions.keySet()) {
      final boolean isSelected = commandPermissions.get(permissionCode).booleanValue();

      final Permission permission = findPermissionByCode(allPermissions, permissionCode);
      boolean changed = role.updatePermission(permission, isSelected);
      if (changed) {
        changedPermissions.put(permissionCode, isSelected);
      }
    }

    if (!changedPermissions.isEmpty()) {
      changes.put("permissions", changedPermissions);
      this.roleRepository.save(role);
    }

    return EntityIdentifier.withChanges(role.getId(), changes);
  }
  @Transactional
  @Override
  @CacheEvict(value = "hooks", allEntries = true)
  public CommandProcessingResult updateHook(final Long hookId, final JsonCommand command) {

    try {
      this.context.authenticatedUser();

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

      final Hook hook = retrieveHookBy(hookId);
      final HookTemplate template = hook.getHookTemplate();
      final Map<String, Object> changes = hook.update(command);

      if (!changes.isEmpty()) {

        if (changes.containsKey(templateIdParamName)) {
          final Long ugdTemplateId = command.longValueOfParameterNamed(templateIdParamName);
          final Template ugdTemplate = this.ugdTemplateRepository.findOne(ugdTemplateId);
          if (ugdTemplate == null) {
            changes.remove(templateIdParamName);
            throw new TemplateNotFoundException(ugdTemplateId);
          }
          hook.updateUgdTemplate(ugdTemplate);
        }

        if (changes.containsKey(eventsParamName)) {
          final Set<HookResource> events =
              assembleSetOfEvents(command.arrayOfParameterNamed(eventsParamName));
          final boolean updated = hook.updateEvents(events);
          if (!updated) {
            changes.remove(eventsParamName);
          }
        }

        if (changes.containsKey(configParamName)) {
          final String configJson = command.jsonFragment(configParamName);
          final Set<HookConfiguration> config =
              assembleConfig(command.mapValueOfParameterNamed(configJson), template);
          final boolean updated = hook.updateConfig(config);
          if (!updated) {
            changes.remove(configParamName);
          }
        }

        this.hookRepository.saveAndFlush(hook);
      }

      return new CommandProcessingResultBuilder() //
          .withCommandId(command.commandId()) //
          .withEntityId(hookId) //
          .with(changes) //
          .build();
    } catch (final DataIntegrityViolationException dve) {
      handleHookDataIntegrityIssues(command, dve);
      return null;
    }
  }
  @Override
  public CommandProcessingResult createGameMediaAsset(JsonCommand command) {

    MediaAsset mediaAsset = null;
    try {
      this.context.authenticatedUser();
      fromApiJsonDeserializer.validateForCreateGame(command.json());
      mediaAsset = MediaAsset.fromGameMediaJsonForm(command);

      PartnerAccountData contentProvider =
          mediaSettlementReadPlatformService.retrieveContentProviderPartnerId(
              mediaAsset.getContentProvider());
      if (!command.stringValueOfParameterNamed("mediaCategory").equalsIgnoreCase("Games")) {
        throw new NotaContentProviderException(
            "This game category is not available", "this game category is not available");
      }
      if (contentProvider == null) {
        throw new NotaContentProviderException();
      } else if (contentProvider != null) {
        if (!contentProvider.getPartnerName().equalsIgnoreCase("Content Provider")) {
          throw new NotaContentProviderException();
        }
      }
      mediaAsset.setContentProvider(contentProvider.getId().toString());
      assetRepository.save(mediaAsset);

      /*final JsonArray gameData = command.arrayOfParameterNamed("gameMediaData").getAsJsonArray();
      for(int i=0; i<gameData.size();i++){
      	String currentData = gameData.get(i).toString();
      	final JsonElement element = fromApiJsonHelper.parse(currentData);

      	 final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element);
        final String category = fromApiJsonHelper.extractStringNamed("category", element);
        final String mediaContentProvider = fromApiJsonHelper.extractStringNamed("mediaContentProvider", element);
        final String mt = fromApiJsonHelper.extractStringNamed("mediaType", element);
        final Character mediaType = mt.equals("Flat")?'F':'P';
        final Long sequence = fromApiJsonHelper.extractLongNamed("sequence", element);
        final String source = fromApiJsonHelper.extractStringNamed("source", element);


        Settlement settlement = Settlement.fromJson(mediaAsset.getId(),amount,category,mediaContentProvider,mediaType,sequence,source);
        settlementJpaRepository.save(settlement);
      }*/

    } catch (EmptyResultDataAccessException e) {
      throw new PlatformDataIntegrityException(
          "not.a.valid.content.provider", "not.a.valid.content.provider", "ContentProvider");
    } catch (DataIntegrityViolationException dve) {
      handleCodeDataIntegrityIssues(command, dve);
      throw new DataIntegrityViolationException(dve.toString());
    } catch (Exception e) {
      throw new DataIntegrityViolationException(e.toString());
    }
    return new CommandProcessingResult(mediaAsset.getId());
  }
  @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();
    }
  }
  private EventOrder assembleEventOrderDetails(JsonCommand command, Long clientId) {

    Configuration configuration =
        this.configurationRepository.findOneByName(
            ConfigurationConstants.CONFIR_PROPERTY_REGISTRATION_DEVICE);
    this.apiJsonDeserializer.validateForCreate(command.json(), configuration.isEnabled());
    final Long eventId = command.longValueOfParameterNamed("eventId");
    final String deviceId = command.stringValueOfParameterNamed("deviceId");
    Long clientType = Long.valueOf(0);

    if (configuration != null && configuration.isEnabled()) {
      MediaDeviceData deviceData = this.deviceReadPlatformService.retrieveDeviceDetails(deviceId);
      if (deviceData == null) {
        throw new NoMediaDeviceFoundException();
      }
      clientId = deviceData.getClientId();
      clientType = deviceData.getClientTypeId();

    } else if (clientId != null) {
      Client client = this.clientRepository.findOne(clientId);
      clientType = client.getCategoryType();
    }

    final String formatType = command.stringValueOfParameterNamed("formatType");
    final String optType = command.stringValueOfParameterNamed("optType");
    EventMaster eventMaster = this.eventMasterRepository.findOne(eventId);
    if (eventMaster == null) {
      throw new NoEventMasterFoundException();
    }
    List<EventDetails> eventDetails = eventMaster.getEventDetails();
    EventOrder eventOrder = EventOrder.fromJson(command, eventMaster, clientType);
    for (EventDetails detail : eventDetails) {
      EventDetails eventDetail = this.eventDetailsRepository.findOne(detail.getId());
      MediaAsset mediaAsset = this.mediaAssetRepository.findOne(eventDetail.getMediaId());
      List<MediaassetLocation> mediaassetLocations = mediaAsset.getMediaassetLocations();
      String movieLink = "";
      for (MediaassetLocation location : mediaassetLocations) {
        if (location.getFormatType().equalsIgnoreCase(formatType)) {
          movieLink = location.getLocation();
        }
      }
      EventOrderdetials eventOrderdetials =
          new EventOrderdetials(eventDetail, movieLink, formatType, optType);
      eventOrder.addEventOrderDetails(eventOrderdetials);
      if (movieLink.isEmpty()) {
        throw new NoMoviesFoundException();
      }
    }
    return eventOrder;
  }
  @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
  @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
  public CommandProcessingResult officeTransaction(final JsonCommand command) {

    context.authenticatedUser();

    this.moneyTransferCommandFromApiJsonDeserializer.validateOfficeTransfer(command.json());

    Long officeId = null;
    Office fromOffice = null;
    final Long fromOfficeId = command.longValueOfParameterNamed("fromOfficeId");
    if (fromOfficeId != null) {
      fromOffice = this.officeRepository.findOne(fromOfficeId);
      officeId = fromOffice.getId();
    }
    Office toOffice = null;
    final Long toOfficeId = command.longValueOfParameterNamed("toOfficeId");
    if (toOfficeId != null) {
      toOffice = this.officeRepository.findOne(toOfficeId);
      officeId = toOffice.getId();
    }

    if (fromOffice == null && toOffice == null) {
      throw new OfficeNotFoundException(toOfficeId);
    }

    final String currencyCode = command.stringValueOfParameterNamed("currencyCode");
    final ApplicationCurrency appCurrency =
        this.applicationCurrencyRepository.findOneByCode(currencyCode);
    if (appCurrency == null) {
      throw new CurrencyNotFoundException(currencyCode);
    }

    final MonetaryCurrency currency =
        new MonetaryCurrency(appCurrency.getCode(), appCurrency.getDecimalPlaces());
    final Money amount =
        Money.of(currency, command.bigDecimalValueOfParameterNamed("transactionAmount"));

    final OfficeTransaction entity =
        OfficeTransaction.fromJson(fromOffice, toOffice, amount, command);

    this.officeTransactionRepository.save(entity);

    return new CommandProcessingResultBuilder() //
        .withCommandId(command.commandId()) //
        .withEntityId(entity.getId()) //
        .withOfficeId(officeId) //
        .build();
  }
  @Transactional
  @Override
  public EntityIdentifier createRole(final JsonCommand command) {

    context.authenticatedUser();

    final RoleCommand roleCommand =
        this.roleCommandFromApiJsonDeserializer.commandFromApiJson(command.json());
    roleCommand.validateForCreate();

    final Role entity = Role.fromJson(command);
    this.roleRepository.save(entity);

    return EntityIdentifier.resourceResult(entity.getId(), null);
  }
 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();
    }
  }