public CommandProcessingResult updateClient()

in fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java [406:704]


    public CommandProcessingResult updateClient(final Long clientId, final JsonCommand command) {

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

            final Client clientForUpdate = this.clientRepository.findOneWithNotFoundDetection(clientId);
            final String clientHierarchy = clientForUpdate.getOffice().getHierarchy();

            this.context.validateAccessRights(clientHierarchy);

            final Map<String, Object> changes = new LinkedHashMap<>(9);

            if (command.isChangeInIntegerParameterNamed(ClientApiConstants.statusParamName, clientForUpdate.getStatus())) {
                final Integer newValue = command.integerValueOfParameterNamed(ClientApiConstants.statusParamName);
                changes.put(ClientApiConstants.statusParamName, ClientEnumerations.status(newValue));
                clientForUpdate.setStatus(ClientStatus.fromInt(newValue).getValue());
            }

            if (command.isChangeInStringParameterNamed(ClientApiConstants.accountNoParamName, clientForUpdate.getAccountNumber())) {
                final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName);
                changes.put(ClientApiConstants.accountNoParamName, newValue);
                clientForUpdate.setAccountNumber(StringUtils.defaultIfEmpty(newValue, null));
            }

            final ExternalId externalId = externalIdFactory.createFromCommand(command, ClientApiConstants.externalIdParamName);
            if (command.isChangeInStringParameterNamed(ClientApiConstants.externalIdParamName,
                    clientForUpdate.getExternalId().getValue())) {
                changes.put(ClientApiConstants.externalIdParamName, externalId.getValue());
                clientForUpdate.setExternalId(externalId);
            }

            if (command.isChangeInStringParameterNamed(ClientApiConstants.mobileNoParamName, clientForUpdate.getMobileNo())) {
                final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.mobileNoParamName);
                changes.put(ClientApiConstants.mobileNoParamName, newValue);
                clientForUpdate.setMobileNo(StringUtils.defaultIfEmpty(newValue, null));
            }

            if (command.isChangeInStringParameterNamed(ClientApiConstants.emailAddressParamName, clientForUpdate.getEmailAddress())) {
                final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.emailAddressParamName);
                changes.put(ClientApiConstants.emailAddressParamName, newValue);
                clientForUpdate.setEmailAddress(StringUtils.defaultIfEmpty(newValue, null));
            }

            if (command.isChangeInStringParameterNamed(ClientApiConstants.firstnameParamName, clientForUpdate.getFirstname())) {
                final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.firstnameParamName);
                changes.put(ClientApiConstants.firstnameParamName, newValue);
                clientForUpdate.setFirstname(StringUtils.defaultIfEmpty(newValue, null));
            }

            if (command.isChangeInStringParameterNamed(ClientApiConstants.middlenameParamName, clientForUpdate.getMiddlename())) {
                final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.middlenameParamName);
                changes.put(ClientApiConstants.middlenameParamName, newValue);
                clientForUpdate.setMiddlename(StringUtils.defaultIfEmpty(newValue, null));
            }

            if (command.isChangeInStringParameterNamed(ClientApiConstants.lastnameParamName, clientForUpdate.getLastname())) {
                final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName);
                changes.put(ClientApiConstants.lastnameParamName, newValue);
                clientForUpdate.setLastname(StringUtils.defaultIfEmpty(newValue, null));
            }

            if (command.isChangeInStringParameterNamed(ClientApiConstants.fullnameParamName, clientForUpdate.getFullname())) {
                final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName);
                changes.put(ClientApiConstants.fullnameParamName, newValue);
                clientForUpdate.setFullname(newValue);
            }

            if (command.isChangeInLongParameterNamed(ClientApiConstants.staffIdParamName, clientForUpdate.staffId())) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.staffIdParamName);
                changes.put(ClientApiConstants.staffIdParamName, newValue);
            }

            if (command.isChangeInLongParameterNamed(ClientApiConstants.genderIdParamName, clientForUpdate.genderId())) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName);
                changes.put(ClientApiConstants.genderIdParamName, newValue);
            }

            if (command.isChangeInLongParameterNamed(ClientApiConstants.savingsProductIdParamName, clientForUpdate.savingsProductId())) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.savingsProductIdParamName);
                changes.put(ClientApiConstants.savingsProductIdParamName, newValue);
            }

            if (command.isChangeInLongParameterNamed(ClientApiConstants.clientTypeIdParamName, clientForUpdate.clientTypeId())) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientTypeIdParamName);
                changes.put(ClientApiConstants.clientTypeIdParamName, newValue);
            }

            if (command.isChangeInLongParameterNamed(ClientApiConstants.clientClassificationIdParamName,
                    clientForUpdate.clientClassificationId())) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientClassificationIdParamName);
                changes.put(ClientApiConstants.clientClassificationIdParamName, newValue);
            }

            if (command.isChangeInIntegerParameterNamed(ClientApiConstants.legalFormIdParamName, clientForUpdate.getLegalForm())) {
                final Integer newValue = command.integerValueOfParameterNamed(ClientApiConstants.legalFormIdParamName);
                if (newValue != null) {
                    LegalForm legalForm = LegalForm.fromInt(newValue);
                    if (legalForm != null) {
                        changes.put(ClientApiConstants.legalFormIdParamName, ClientEnumerations.legalForm(newValue));
                        clientForUpdate.setLegalForm(legalForm.getValue());
                        clientForUpdate.resetDerivedNames(legalForm);
                    } else {
                        changes.put(ClientApiConstants.legalFormIdParamName, null);
                        clientForUpdate.setLegalForm(null);
                    }
                } else {
                    changes.put(ClientApiConstants.legalFormIdParamName, null);
                    clientForUpdate.setLegalForm(null);
                }
            }

            final String dateFormatAsInput = command.dateFormat();
            final String localeAsInput = command.locale();

            if (command.isChangeInLocalDateParameterNamed(ClientApiConstants.activationDateParamName,
                    clientForUpdate.getActivationDate())) {
                final String valueAsInput = command.stringValueOfParameterNamed(ClientApiConstants.activationDateParamName);
                changes.put(ClientApiConstants.activationDateParamName, valueAsInput);
                changes.put(ClientApiConstants.dateFormatParamName, dateFormatAsInput);
                changes.put(ClientApiConstants.localeParamName, localeAsInput);

                clientForUpdate.setActivationDate(command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName));
                clientForUpdate.setOfficeJoiningDate(clientForUpdate.getActivationDate());
            }

            if (command.isChangeInLocalDateParameterNamed(ClientApiConstants.dateOfBirthParamName, clientForUpdate.getDateOfBirth())) {
                final String valueAsInput = command.stringValueOfParameterNamed(ClientApiConstants.dateOfBirthParamName);
                changes.put(ClientApiConstants.dateOfBirthParamName, valueAsInput);
                changes.put(ClientApiConstants.dateFormatParamName, dateFormatAsInput);
                changes.put(ClientApiConstants.localeParamName, localeAsInput);

                clientForUpdate.setDateOfBirth(command.localDateValueOfParameterNamed(ClientApiConstants.dateOfBirthParamName));
            }

            if (command.isChangeInLocalDateParameterNamed(ClientApiConstants.submittedOnDateParamName,
                    clientForUpdate.getSubmittedOnDate())) {
                final String valueAsInput = command.stringValueOfParameterNamed(ClientApiConstants.submittedOnDateParamName);
                changes.put(ClientApiConstants.submittedOnDateParamName, valueAsInput);
                changes.put(ClientApiConstants.dateFormatParamName, dateFormatAsInput);
                changes.put(ClientApiConstants.localeParamName, localeAsInput);

                clientForUpdate.setSubmittedOnDate(command.localDateValueOfParameterNamed(ClientApiConstants.submittedOnDateParamName));
            }

            clientForUpdate.validateUpdate();

            clientForUpdate.deriveDisplayName();

            if (changes.containsKey(ClientApiConstants.staffIdParamName)) {

                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.staffIdParamName);
                Staff newStaff = null;
                if (newValue != null) {
                    newStaff = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(newValue,
                            clientForUpdate.getOffice().getHierarchy());
                }
                clientForUpdate.updateStaff(newStaff);
            }

            if (changes.containsKey(ClientApiConstants.genderIdParamName)) {

                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName);
                CodeValue gender = null;
                if (newValue != null) {
                    gender = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.GENDER, newValue);
                }
                clientForUpdate.updateGender(gender);
            }

            if (changes.containsKey(ClientApiConstants.savingsProductIdParamName)) {
                if (clientForUpdate.isActive()) {
                    throw new ClientActiveForUpdateException(clientId, ClientApiConstants.savingsProductIdParamName);
                }
                final Long savingsProductId = command.longValueOfParameterNamed(ClientApiConstants.savingsProductIdParamName);
                if (savingsProductId != null) {
                    this.savingsProductRepository.findById(savingsProductId)
                            .orElseThrow(() -> new SavingsProductNotFoundException(savingsProductId));
                }
                clientForUpdate.updateSavingsProduct(savingsProductId);
            }

            if (changes.containsKey(ClientApiConstants.genderIdParamName)) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName);
                CodeValue newCodeVal = null;
                if (newValue != null) {
                    newCodeVal = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.GENDER, newValue);
                }
                clientForUpdate.updateGender(newCodeVal);
            }

            if (changes.containsKey(ClientApiConstants.clientTypeIdParamName)) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientTypeIdParamName);
                CodeValue newCodeVal = null;
                if (newValue != null) {
                    newCodeVal = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.CLIENT_TYPE,
                            newValue);
                }
                clientForUpdate.updateClientType(newCodeVal);
            }

            if (changes.containsKey(ClientApiConstants.clientClassificationIdParamName)) {
                final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.clientClassificationIdParamName);
                CodeValue newCodeVal = null;
                if (newValue != null) {
                    newCodeVal = this.codeValueRepository
                            .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.CLIENT_CLASSIFICATION, newValue);
                }
                clientForUpdate.updateClientClassification(newCodeVal);
            }

            if (!changes.isEmpty()) {
                this.clientRepository.saveAndFlush(clientForUpdate);
            }

            if (changes.containsKey(ClientApiConstants.legalFormIdParamName)) {
                Integer legalFormValue = clientForUpdate.getLegalForm();
                boolean isChangedToEntity = false;
                if (legalFormValue != null) {
                    LegalForm legalForm = LegalForm.fromInt(legalFormValue);
                    if (legalForm != null) {
                        isChangedToEntity = legalForm.isEntity();
                    }
                }

                if (isChangedToEntity) {
                    extractAndCreateClientNonPerson(clientForUpdate, command);
                } else {
                    final ClientNonPerson clientNonPerson = this.clientNonPersonRepository.findOneByClientId(clientForUpdate.getId());
                    if (clientNonPerson != null) {
                        this.clientNonPersonRepository.delete(clientNonPerson);
                    }
                }
            }

            final ClientNonPerson clientNonPersonForUpdate = this.clientNonPersonRepository.findOneByClientId(clientId);
            if (clientNonPersonForUpdate != null) {
                final JsonElement clientNonPersonElement = command.jsonElement(ClientApiConstants.clientNonPersonDetailsParamName);
                final Map<String, Object> clientNonPersonChanges = clientNonPersonForUpdate
                        .update(JsonCommand.fromExistingCommand(command, clientNonPersonElement));

                if (clientNonPersonChanges.containsKey(ClientApiConstants.constitutionIdParamName)) {

                    final Long newValue = this.fromApiJsonHelper.extractLongNamed(ClientApiConstants.constitutionIdParamName,
                            clientNonPersonElement);
                    CodeValue constitution = null;
                    if (newValue != null) {
                        constitution = this.codeValueRepository
                                .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.CLIENT_NON_PERSON_CONSTITUTION, newValue);
                    }
                    clientNonPersonForUpdate.updateConstitution(constitution);
                }

                if (clientNonPersonChanges.containsKey(ClientApiConstants.mainBusinessLineIdParamName)) {

                    final Long newValue = this.fromApiJsonHelper.extractLongNamed(ClientApiConstants.mainBusinessLineIdParamName,
                            clientNonPersonElement);
                    CodeValue mainBusinessLine = null;
                    if (newValue != null) {
                        mainBusinessLine = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(
                                ClientApiConstants.CLIENT_NON_PERSON_MAIN_BUSINESS_LINE, newValue);
                    }
                    clientNonPersonForUpdate.updateMainBusinessLine(mainBusinessLine);
                }

                if (!clientNonPersonChanges.isEmpty()) {
                    this.clientNonPersonRepository.saveAndFlush(clientNonPersonForUpdate);
                }

                changes.putAll(clientNonPersonChanges);
            } else {
                final Integer legalFormParamValue = command.integerValueOfParameterNamed(ClientApiConstants.legalFormIdParamName);
                boolean isEntity = false;
                if (legalFormParamValue != null) {
                    final LegalForm legalForm = LegalForm.fromInt(legalFormParamValue);
                    if (legalForm != null) {
                        isEntity = legalForm.isEntity();
                    }
                }
                if (isEntity) {
                    extractAndCreateClientNonPerson(clientForUpdate, command);
                }
            }
            return new CommandProcessingResultBuilder() //
                    .withCommandId(command.commandId()) //
                    .withEntityExternalId(clientForUpdate.getExternalId()) //
                    .withOfficeId(clientForUpdate.officeId()) //
                    .withClientId(clientId) //
                    .withEntityId(clientId) //
                    .with(changes) //
                    .build();
        } catch (final JpaSystemException | DataIntegrityViolationException dve) {
            handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
            return CommandProcessingResult.empty();
        } catch (final PersistenceException dve) {
            Throwable throwable = ExceptionUtils.getRootCause(dve.getCause());
            handleDataIntegrityIssues(command, throwable, dve);
            return CommandProcessingResult.empty();
        }
    }