Skip to content

Commit d8f483a

Browse files
adamsaghygalovics
authored andcommitted
Refactor Client to support auditable fields
1 parent b8f8217 commit d8f483a

9 files changed

Lines changed: 424 additions & 26 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.infrastructure.core.api;
20+
21+
import com.google.gson.JsonElement;
22+
import com.google.gson.JsonPrimitive;
23+
import com.google.gson.JsonSerializationContext;
24+
import com.google.gson.JsonSerializer;
25+
import java.lang.reflect.Type;
26+
import java.time.OffsetDateTime;
27+
import java.time.format.DateTimeFormatter;
28+
29+
/**
30+
* Serializer for Java Offset Date Time {@link OffsetDateTime} that returns the date in ISO-8601 Offset date time format
31+
*/
32+
public class OffsetDateTimeAdapter implements JsonSerializer<OffsetDateTime> {
33+
34+
@Override
35+
@SuppressWarnings("unused")
36+
public JsonElement serialize(final OffsetDateTime dateTime, final Type typeOfSrc, final JsonSerializationContext context) {
37+
JsonElement object = null;
38+
if (dateTime != null) {
39+
object = new JsonPrimitive(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(dateTime));
40+
}
41+
return object;
42+
}
43+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.portfolio.client.api;
20+
21+
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_BY;
22+
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_DATE;
23+
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_BY;
24+
import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_DATE;
25+
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
import javax.ws.rs.Consumes;
29+
import javax.ws.rs.GET;
30+
import javax.ws.rs.Path;
31+
import javax.ws.rs.PathParam;
32+
import javax.ws.rs.Produces;
33+
import javax.ws.rs.core.Context;
34+
import javax.ws.rs.core.MediaType;
35+
import javax.ws.rs.core.UriInfo;
36+
import lombok.RequiredArgsConstructor;
37+
import lombok.extern.slf4j.Slf4j;
38+
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
39+
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
40+
import org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
41+
import org.apache.fineract.portfolio.client.domain.Client;
42+
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
43+
import org.springframework.beans.factory.InitializingBean;
44+
import org.springframework.stereotype.Component;
45+
46+
//@Profile("test")
47+
@Component
48+
@Path("/internal/client")
49+
@RequiredArgsConstructor
50+
@Slf4j
51+
public class InternalClientInformationApiResource implements InitializingBean {
52+
53+
private final ClientRepositoryWrapper clientRepositoryWrapper;
54+
private final ToApiJsonSerializer<Map> toApiJsonSerializer;
55+
private final ApiRequestParameterHelper apiRequestParameterHelper;
56+
57+
@Override
58+
public void afterPropertiesSet() {
59+
log.warn("------------------------------------------------------------");
60+
log.warn(" ");
61+
log.warn("DO NOT USE THIS IN PRODUCTION!");
62+
log.warn("Internal client services mode is enabled");
63+
log.warn("DO NOT USE THIS IN PRODUCTION!");
64+
log.warn(" ");
65+
log.warn("------------------------------------------------------------");
66+
67+
}
68+
69+
@GET
70+
@Path("{clientId}/audit")
71+
@Consumes({ MediaType.APPLICATION_JSON })
72+
@Produces({ MediaType.APPLICATION_JSON })
73+
public String getClientAuditFields(@Context final UriInfo uriInfo, @PathParam("clientId") Long clientId) {
74+
log.warn("------------------------------------------------------------");
75+
log.warn(" ");
76+
log.warn("Fetching client with {}", clientId);
77+
log.warn(" ");
78+
log.warn("------------------------------------------------------------");
79+
80+
final Client client = clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
81+
Map<String, Object> auditFields = new HashMap<>(
82+
Map.of(CREATED_BY, client.getCreatedBy().orElse(null), CREATED_DATE, client.getCreatedDate().orElse(null), LAST_MODIFIED_BY,
83+
client.getLastModifiedBy().orElse(null), LAST_MODIFIED_DATE, client.getLastModifiedDate().orElse(null)));
84+
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
85+
return this.toApiJsonSerializer.serialize(settings, auditFields);
86+
}
87+
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import org.apache.fineract.infrastructure.core.api.JsonCommand;
4545
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
4646
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
47-
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
47+
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
4848
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
4949
import org.apache.fineract.infrastructure.core.service.DateUtils;
5050
import org.apache.fineract.infrastructure.documentmanagement.domain.Image;
@@ -59,7 +59,7 @@
5959
@Entity
6060
@Table(name = "m_client", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "account_no_UNIQUE"), //
6161
@UniqueConstraint(columnNames = { "mobile_no" }, name = "mobile_no_UNIQUE") })
62-
public final class Client extends AbstractPersistableCustom {
62+
public class Client extends AbstractAuditableWithUTCDateTimeCustom {
6363

6464
@Column(name = "account_no", length = 20, unique = true, nullable = false)
6565
private String accountNumber;
@@ -180,16 +180,14 @@ public final class Client extends AbstractPersistableCustom {
180180
@Column(name = "submittedon_date", nullable = true)
181181
private LocalDate submittedOnDate;
182182

183-
@ManyToOne(optional = true, fetch = FetchType.LAZY)
184-
@JoinColumn(name = "submittedon_userid", nullable = true)
185-
private AppUser submittedBy;
183+
// Deprecated since common Auditable fields were introduced. Columns and data left untouched to help migration.
186184

187-
@Column(name = "updated_on", nullable = true)
188-
private LocalDate updatedOnDate;
185+
// @Column(name = "updated_on", nullable = true)
186+
// private LocalDate updatedOnDate;
189187

190-
@ManyToOne(optional = true, fetch = FetchType.LAZY)
191-
@JoinColumn(name = "updated_by", nullable = true)
192-
private AppUser updatedBy;
188+
// @ManyToOne(optional = true, fetch = FetchType.LAZY)
189+
// @JoinColumn(name = "updated_by", nullable = true)
190+
// private AppUser updatedBy;
193191

194192
@ManyToOne(optional = true, fetch = FetchType.LAZY)
195193
@JoinColumn(name = "activatedon_userid", nullable = true)
@@ -270,9 +268,7 @@ public static Client createNew(final AppUser currentUser, final Office clientOff
270268
savingsAccountId, dataOfBirth, gender, clientType, clientClassification, legalForm, isStaff);
271269
}
272270

273-
Client() {
274-
this.setLegalForm(null);
275-
}
271+
protected Client() {}
276272

277273
private Client(final AppUser currentUser, final ClientStatus status, final Office office, final Group clientParentGroup,
278274
final String accountNo, final String firstname, final String middlename, final String lastname, final String fullname,
@@ -289,7 +285,6 @@ private Client(final AppUser currentUser, final ClientStatus status, final Offic
289285
}
290286

291287
this.submittedOnDate = submittedOnDate;
292-
this.submittedBy = currentUser;
293288

294289
this.status = status.getValue();
295290
this.office = office;
@@ -969,8 +964,6 @@ public void reject(AppUser currentUser, CodeValue rejectionReason, LocalDate rej
969964
this.rejectionReason = rejectionReason;
970965
this.rejectionDate = rejectionDate;
971966
this.rejectedBy = currentUser;
972-
this.updatedBy = currentUser;
973-
this.updatedOnDate = rejectionDate;
974967
this.status = ClientStatus.REJECTED.getValue();
975968

976969
}
@@ -979,8 +972,6 @@ public void withdraw(AppUser currentUser, CodeValue withdrawalReason, LocalDate
979972
this.withdrawalReason = withdrawalReason;
980973
this.withdrawalDate = withdrawalDate;
981974
this.withdrawnBy = currentUser;
982-
this.updatedBy = currentUser;
983-
this.updatedOnDate = withdrawalDate;
984975
this.status = ClientStatus.WITHDRAWN.getValue();
985976

986977
}
@@ -990,17 +981,13 @@ public void reActivate(AppUser currentUser, LocalDate reactivateDate) {
990981
this.closureReason = null;
991982
this.reactivateDate = reactivateDate;
992983
this.reactivatedBy = currentUser;
993-
this.updatedBy = currentUser;
994-
this.updatedOnDate = reactivateDate;
995984
this.status = ClientStatus.PENDING.getValue();
996985

997986
}
998987

999988
public void reOpened(AppUser currentUser, LocalDate reopenedDate) {
1000989
this.reopenedDate = reopenedDate;
1001990
this.reopenedBy = currentUser;
1002-
this.updatedBy = currentUser;
1003-
this.updatedOnDate = reopenedDate;
1004991
this.status = ClientStatus.PENDING.getValue();
1005992

1006993
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ private static final class ClientMembersOfGroupMapper implements RowMapper<Clien
430430
sqlBuilder.append("left join m_savings_product sp on sp.id = c.default_savings_product ");
431431
sqlBuilder.append("left join m_office transferToOffice on transferToOffice.id = c.transfer_to_office_id ");
432432

433-
sqlBuilder.append("left join m_appuser sbu on sbu.id = c.submittedon_userid ");
433+
sqlBuilder.append("left join m_appuser sbu on sbu.id = c.created_by ");
434434
sqlBuilder.append("left join m_appuser acu on acu.id = c.activatedon_userid ");
435435
sqlBuilder.append("left join m_appuser clu on clu.id = c.closedon_userid ");
436436
sqlBuilder.append("left join m_code_value cv on cv.id = c.gender_cv_id ");
@@ -618,7 +618,7 @@ private static final class ClientMapper implements RowMapper<ClientData> {
618618
builder.append("left join m_staff s on s.id = c.staff_id ");
619619
builder.append("left join m_savings_product sp on sp.id = c.default_savings_product ");
620620
builder.append("left join m_office transferToOffice on transferToOffice.id = c.transfer_to_office_id ");
621-
builder.append("left join m_appuser sbu on sbu.id = c.submittedon_userid ");
621+
builder.append("left join m_appuser sbu on sbu.id = c.created_by ");
622622
builder.append("left join m_appuser acu on acu.id = c.activatedon_userid ");
623623
builder.append("left join m_appuser clu on clu.id = c.closedon_userid ");
624624
builder.append("left join m_code_value cv on cv.id = c.gender_cv_id ");

fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@
3939
<include file="parts/0017_fix_stretchy_reports.xml" relativeToChangelogFile="true"/>
4040
<include file="parts/0018_pentaho_reports_to_table.xml" relativeToChangelogFile="true"/>
4141
<include file="parts/0019_refactor_loan_transaction.xml" relativeToChangelogFile="true"/>
42+
<include file="parts/0020_add_audit_entries.xml" relativeToChangelogFile="true"/>
4243
</databaseChangeLog>

0 commit comments

Comments
 (0)