try {
this.savingsAccountDataValidator.validateForUpdate(command.json());
final Map<String, Object> changes = new LinkedHashMap<>(20);
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsId);
checkClientOrGroupActive(account);
account.modifyApplication(command, changes);
account.validateNewApplicationState(DateUtils.getLocalDateOfTenant(), SAVINGS_ACCOUNT_RESOURCE_NAME);
account.validateAccountValuesWithProduct();
if (!changes.isEmpty()) {
if (changes.containsKey(SavingsApiConstants.clientIdParamName)) {
final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName);
if (clientId != null) {
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client.isNotActive()) { throw new ClientNotActiveException(clientId); }
account.update(client);
} else {
final Client client = null;
account.update(client);
}
}
if (changes.containsKey(SavingsApiConstants.groupIdParamName)) {
final Long groupId = command.longValueOfParameterNamed(SavingsApiConstants.groupIdParamName);
if (groupId != null) {
final Group group = this.groupRepository.findOne(groupId);
if (group == null) { throw new GroupNotFoundException(groupId); }
if (group.isNotActive()) {
if (group.isCenter()) { throw new CenterNotActiveException(groupId); }
throw new GroupNotActiveException(groupId);
}
account.update(group);
} else {
final Group group = null;
account.update(group);
}
}
if (changes.containsKey(SavingsApiConstants.productIdParamName)) {
final Long productId = command.longValueOfParameterNamed(SavingsApiConstants.productIdParamName);
final SavingsProduct product = this.savingsProductRepository.findOne(productId);
if (product == null) { throw new SavingsProductNotFoundException(productId); }
account.update(product);
}
if (changes.containsKey(SavingsApiConstants.fieldOfficerIdParamName)) {
final Long fieldOfficerId = command.longValueOfParameterNamed(SavingsApiConstants.fieldOfficerIdParamName);
Staff fieldOfficer = null;
if (fieldOfficerId != null) {
fieldOfficer = this.staffRepository.findOneWithNotFoundDetection(fieldOfficerId);
} else {
changes.put(SavingsApiConstants.fieldOfficerIdParamName, "");
}
account.update(fieldOfficer);
}
if (changes.containsKey("charges")) {
final Set<SavingsAccountCharge> charges = this.savingsAccountChargeAssembler.fromParsedJson(command.parsedJson(),
account.getCurrency().getCode());
final boolean updated = account.update(charges);
if (!updated) {
changes.remove("charges");
}
}
this.savingAccountRepository.saveAndFlush(account);
}
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(savingsId) //
.withOfficeId(account.officeId()) //
.withClientId(account.clientId()) //
.withGroupId(account.groupId()) //
.withSavingsId(savingsId) //
.with(changes) //
.build();
} catch (final DataAccessException dve) {
handleDataIntegrityIssues(command, dve);