FINERACT-1760: Update office by external id

- [x] Add new resource to update
- [x] Integration test
This commit is contained in:
Janos Haber
2023-08-30 09:50:56 +02:00
committed by Arnold Gálovics
parent adcdd1a224
commit 63d6cb38ab
13 changed files with 218 additions and 53 deletions
@@ -23,6 +23,7 @@ import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
import lombok.Getter;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
/**
* Immutable data object for office data.
@@ -33,7 +34,7 @@ public class OfficeData implements Serializable {
private final Long id;
private final String name;
private final String nameDecorated;
private final String externalId;
private final ExternalId externalId;
private final LocalDate openingDate;
private final String hierarchy;
private final Long parentId;
@@ -45,7 +46,8 @@ public class OfficeData implements Serializable {
private String locale;
private String dateFormat;
public static OfficeData importInstance(final String name, final Long parentId, final LocalDate openingDate, final String externalId) {
public static OfficeData importInstance(final String name, final Long parentId, final LocalDate openingDate,
final ExternalId externalId) {
return new OfficeData(null, name, null, externalId, openingDate, null, parentId, null, null);
}
@@ -72,8 +74,9 @@ public class OfficeData implements Serializable {
office.parentId, office.parentName, allowedParents);
}
public OfficeData(final Long id, final String name, final String nameDecorated, final String externalId, final LocalDate openingDate,
final String hierarchy, final Long parentId, final String parentName, final Collection<OfficeData> allowedParents) {
public OfficeData(final Long id, final String name, final String nameDecorated, final ExternalId externalId,
final LocalDate openingDate, final String hierarchy, final Long parentId, final String parentName,
final Collection<OfficeData> allowedParents) {
this.id = id;
this.name = name;
this.nameDecorated = nameDecorated;
@@ -32,15 +32,22 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
import org.apache.fineract.organisation.office.exception.CannotUpdateOfficeWithParentOfficeSameAsSelf;
import org.apache.fineract.organisation.office.exception.RootOfficeParentCannotBeUpdated;
@Entity
@Table(name = "m_office", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name_org"),
@UniqueConstraint(columnNames = { "external_id" }, name = "externalid_org") })
@Getter
@Setter
public class Office extends AbstractPersistableCustom implements Serializable {
@OneToMany(fetch = FetchType.LAZY)
@@ -60,10 +67,10 @@ public class Office extends AbstractPersistableCustom implements Serializable {
@Column(name = "opening_date", nullable = false)
private LocalDate openingDate;
@Column(name = "external_id", length = 100)
private String externalId;
@Column(name = "external_id", length = 100, unique = true)
private ExternalId externalId;
public static Office headOffice(final String name, final LocalDate openingDate, final String externalId) {
public static Office headOffice(final String name, final LocalDate openingDate, final ExternalId externalId) {
return new Office(null, name, openingDate, externalId);
}
@@ -72,7 +79,7 @@ public class Office extends AbstractPersistableCustom implements Serializable {
final String name = command.stringValueOfParameterNamed("name");
final LocalDate openingDate = command.localDateValueOfParameterNamed("openingDate");
final String externalId = command.stringValueOfParameterNamed("externalId");
return new Office(parentOffice, name, openingDate, externalId);
return new Office(parentOffice, name, openingDate, ExternalIdFactory.produce(externalId));
}
protected Office() {
@@ -82,7 +89,7 @@ public class Office extends AbstractPersistableCustom implements Serializable {
this.externalId = null;
}
private Office(final Office parent, final String name, final LocalDate openingDate, final String externalId) {
private Office(final Office parent, final String name, final LocalDate openingDate, final ExternalId externalId) {
this.parent = parent;
this.openingDate = openingDate;
if (parent != null) {
@@ -94,11 +101,7 @@ public class Office extends AbstractPersistableCustom implements Serializable {
} else {
this.name = null;
}
if (StringUtils.isNotBlank(externalId)) {
this.externalId = externalId.trim();
} else {
this.externalId = null;
}
this.externalId = externalId;
}
private void addChild(final Office office) {
@@ -141,10 +144,11 @@ public class Office extends AbstractPersistableCustom implements Serializable {
}
final String externalIdParamName = "externalId";
if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
if (command.isChangeInStringParameterNamed(externalIdParamName,
Optional.ofNullable(this.externalId).map(ExternalId::getValue).orElse(null))) {
final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
actualChanges.put(externalIdParamName, newValue);
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
this.externalId = ExternalIdFactory.produce(StringUtils.defaultIfEmpty(newValue, null));
}
return actualChanges;
@@ -193,18 +197,6 @@ public class Office extends AbstractPersistableCustom implements Serializable {
return this.hierarchy + id.toString() + ".";
}
public String getName() {
return this.name;
}
public String getHierarchy() {
return this.hierarchy;
}
public Office getParent() {
return this.parent;
}
public boolean hasParentOf(final Office office) {
if (this.parent != null) {
return this.parent.equals(office);
@@ -18,9 +18,12 @@
*/
package org.apache.fineract.organisation.office.domain;
import java.util.Optional;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface OfficeRepository extends JpaRepository<Office, Long>, JpaSpecificationExecutor<Office> {
// no added behaviour
Optional<Office> findByExternalId(ExternalId externalId);
}
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.organisation.office.exception;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
@@ -33,4 +34,8 @@ public class OfficeNotFoundException extends AbstractPlatformResourceNotFoundExc
public OfficeNotFoundException(Long id, EmptyResultDataAccessException e) {
super("error.msg.office.id.invalid", "Office with identifier " + id + " does not exist", id, e);
}
public OfficeNotFoundException(ExternalId externalId) {
super("error.msg.office.external.id.invalid", "Office with external identifier " + externalId + " does not exist", externalId);
}
}
@@ -0,0 +1,43 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.organisation.office.mapper;
import java.util.Optional;
import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
import org.apache.fineract.organisation.office.data.OfficeData;
import org.apache.fineract.organisation.office.domain.Office;
import org.mapstruct.Mapper;
@Mapper(config = MapstructMapperConfig.class)
public interface OfficeDataMapper {
default OfficeData toOfficeData(Office office) {
String hierarchy = office.getHierarchy();
String nameDecorated;
if (hierarchy == null) {
nameDecorated = "";
} else {
nameDecorated = hierarchy.substring(0, (hierarchy.length() - hierarchy.replace(".", "").length() - 1) * 4)
+ Optional.ofNullable(office.getName()).orElse("");
}
return new OfficeData(office.getId(), office.getName(), nameDecorated, office.getExternalId(), office.getOpeningDate(),
office.getHierarchy(), office.getParent() != null ? office.getParent().getId() : null,
office.getParent() != null ? office.getParent().getName() : null, null);
}
}
@@ -19,6 +19,7 @@
package org.apache.fineract.organisation.office.service;
import java.util.Collection;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.organisation.office.data.OfficeData;
import org.apache.fineract.organisation.office.data.OfficeTransactionData;
@@ -31,6 +32,8 @@ public interface OfficeReadPlatformService {
OfficeData retrieveOffice(Long officeId);
OfficeData retrieveOfficeWithExternalId(ExternalId externalId);
OfficeData retrieveNewOfficeTemplate();
Collection<OfficeData> retrieveAllowedParents(Long officeId);