diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateType.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateType.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateType.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/domain/BusinessDateType.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/ActionContext.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/ActionContext.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/ActionContext.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/ActionContext.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AuditableFieldsConstants.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AuditableFieldsConstants.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AuditableFieldsConstants.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/AuditableFieldsConstants.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractContext.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractContext.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractContext.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractContext.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenant.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenant.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenant.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenant.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/domain/FineractPlatformTenantConnection.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/DateUtils.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/DateUtils.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/DateUtils.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/DateUtils.java diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java similarity index 100% rename from fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java rename to fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/ThreadLocalContextUtil.java diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AbstractAuditableCustom.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AbstractAuditableCustom.java deleted file mode 100644 index a7b782623..000000000 --- a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AbstractAuditableCustom.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * 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.investor.domain; - -import java.time.LocalDateTime; -import java.util.Optional; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; -import org.springframework.data.domain.Auditable; - -/** - * This class is a copy paste from the fineract-provider module since EclipseLink not weaves the class properly if it's - * placed in the fineract-core module. - */ -@MappedSuperclass -public abstract class AbstractAuditableCustom extends AbstractPersistableCustom implements Auditable { - - private static final long serialVersionUID = 141481953116476081L; - - @Column(name = "createdby_id") - private Long createdBy; - - @Column(name = "created_date") - private LocalDateTime createdDate; - - @Column(name = "lastmodifiedby_id") - private Long lastModifiedBy; - - @Column(name = "lastmodified_date") - private LocalDateTime lastModifiedDate; - - @Override - public Optional getCreatedBy() { - return Optional.ofNullable(this.createdBy); - } - - @Override - public void setCreatedBy(final Long createdBy) { - this.createdBy = createdBy; - } - - @Override - public Optional getCreatedDate() { - return null == this.createdDate ? Optional.empty() : Optional.of(this.createdDate); - } - - @Override - public void setCreatedDate(final LocalDateTime createdDate) { - this.createdDate = createdDate; - } - - @Override - public Optional getLastModifiedBy() { - return Optional.ofNullable(this.lastModifiedBy); - } - - @Override - public void setLastModifiedBy(final Long lastModifiedBy) { - this.lastModifiedBy = lastModifiedBy; - } - - @Override - public Optional getLastModifiedDate() { - return null == this.lastModifiedDate ? Optional.empty() : Optional.of(this.lastModifiedDate); - } - - @Override - public void setLastModifiedDate(final LocalDateTime lastModifiedDate) { - this.lastModifiedDate = lastModifiedDate; - } -} diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AbstractAuditableWithUTCDateTimeCustom.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AbstractAuditableWithUTCDateTimeCustom.java new file mode 100644 index 000000000..cca8f6eeb --- /dev/null +++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AbstractAuditableWithUTCDateTimeCustom.java @@ -0,0 +1,99 @@ +/** + * 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.investor.domain; + +import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_BY_DB_FIELD; +import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_DATE_DB_FIELD; +import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_BY_DB_FIELD; +import static org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_DATE_DB_FIELD; + +import java.time.OffsetDateTime; +import java.util.Optional; +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.springframework.data.domain.Auditable; +import org.springframework.data.jpa.domain.AbstractAuditable; + +/** + * A custom copy of {@link AbstractAuditable} to override the column names used on database. It also uses OffsetDateTime + * for created and modified. The datetimes will be converted from tenant TZ to UTC before storing (automatically + * happens) and converted from System TZ to tenant TZ after fetching from DB + * + * Abstract base class for auditable entities. Stores the audit values in persistent fields. + */ +@MappedSuperclass +@Getter +@Setter +@NoArgsConstructor +public abstract class AbstractAuditableWithUTCDateTimeCustom extends AbstractPersistableCustom + implements Auditable { + + private static final long serialVersionUID = 141481953116476081L; + + @Column(name = CREATED_BY_DB_FIELD, nullable = false) + @Setter(onMethod = @__(@Override)) + private Long createdBy; + + @Column(name = CREATED_DATE_DB_FIELD, nullable = false) + @Setter(onMethod = @__(@Override)) + private OffsetDateTime createdDate; + + @Column(name = LAST_MODIFIED_BY_DB_FIELD, nullable = false) + @Setter(onMethod = @__(@Override)) + private Long lastModifiedBy; + + @Column(name = LAST_MODIFIED_DATE_DB_FIELD, nullable = false) + @Setter(onMethod = @__(@Override)) + private OffsetDateTime lastModifiedDate; + + @Override + public Optional getCreatedBy() { + return Optional.ofNullable(this.createdBy); + } + + @Override + public Optional getCreatedDate() { + if (this.createdDate == null) { + return Optional.empty(); + } else { + return Optional.of(this.createdDate + .withOffsetSameInstant(DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(this.createdDate.toInstant()))); + } + } + + @Override + public Optional getLastModifiedBy() { + return Optional.ofNullable(this.lastModifiedBy); + } + + @Override + public Optional getLastModifiedDate() { + if (this.lastModifiedDate == null) { + return Optional.empty(); + } else { + return Optional.of(this.lastModifiedDate + .withOffsetSameInstant(DateUtils.getDateTimeZoneOfTenant().getRules().getOffset(this.lastModifiedDate.toInstant()))); + } + } + +} diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwner.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwner.java index 9214e61a2..774018991 100644 --- a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwner.java +++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwner.java @@ -31,7 +31,7 @@ import lombok.Setter; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "m_external_asset_owner") -public class ExternalAssetOwner extends AbstractAuditableCustom { +public class ExternalAssetOwner extends AbstractAuditableWithUTCDateTimeCustom { @Column(name = "external_id", nullable = false, length = 100, unique = true) private String externalId; diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransfer.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransfer.java index 1cc9ca1cb..10108fcba 100644 --- a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransfer.java +++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransfer.java @@ -22,6 +22,8 @@ import java.math.BigDecimal; import java.time.LocalDate; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import javax.persistence.Table; import lombok.AccessLevel; import lombok.Getter; @@ -33,11 +35,15 @@ import lombok.Setter; @Table(name = "m_external_asset_owner_transfer") @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity -public class ExternalAssetOwnerTransfer extends AbstractAuditableCustom { +public class ExternalAssetOwnerTransfer extends AbstractAuditableWithUTCDateTimeCustom { @Column(name = "owner_id") private Long ownerId; + @ManyToOne + @JoinColumn(name = "owner_id", insertable = false, updatable = false) + private ExternalAssetOwner owner; + @Column(name = "external_id", length = 100) private String externalId; diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMapping.java b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMapping.java index 129e7a089..86aea1f14 100644 --- a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMapping.java +++ b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferLoanMapping.java @@ -20,6 +20,8 @@ package org.apache.fineract.investor.domain; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import javax.persistence.Table; import lombok.AccessLevel; import lombok.Getter; @@ -31,12 +33,13 @@ import lombok.Setter; @Table(name = "m_external_asset_owner_transfer_loan_mapping") @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity -public class ExternalAssetOwnerTransferLoanMapping extends AbstractAuditableCustom { +public class ExternalAssetOwnerTransferLoanMapping extends AbstractAuditableWithUTCDateTimeCustom { @Column(name = "loan_id", nullable = false) private Long loanId; - @Column(name = "owner_transfer_id") - private Long ownerTransferId; + @ManyToOne + @JoinColumn(name = "owner_transfer_id", insertable = false, updatable = false) + private ExternalAssetOwnerTransfer ownerTransfer; }