This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 8663c054a FINERACT-2152: API update and delete interest pause
8663c054a is described below

commit 8663c054a076ca52e49b8df3987f8da46c929e51
Author: Andrii Kulminskyi <[email protected]>
AuthorDate: Mon Dec 23 19:26:33 2024 +0200

    FINERACT-2152: API update and delete interest pause
---
 .../fineract/commands/domain/CommandSource.java    |   3 +-
 .../fineract/commands/domain/CommandWrapper.java   |  12 +-
 .../commands/service/CommandWrapperBuilder.java    |  18 ++
 .../SynchronousCommandProcessingService.java       |  12 +-
 .../api/LoanInterestPauseApiResource.java          |  42 ++-
 ...java => CreateInterestPauseCommandHandler.java} |  12 +-
 ...java => DeleteInterestPauseCommandHandler.java} |  27 +-
 ...java => UpdateInterestPauseCommandHandler.java} |  23 +-
 .../service/InterestPauseWritePlatformService.java |  50 ++++
 .../InterestPauseWritePlatformServiceImpl.java     |  91 +++++-
 .../loanaccount/domain/LoanTermVariations.java     |  48 +++
 .../domain/LoanTermVariationsRepository.java       |   9 +
 .../starter/LoanAccountConfiguration.java          |   4 +-
 .../db/changelog/tenant/changelog-tenant.xml       |   1 +
 ..._additional_audit_fields_to_term_variations.xml |  51 ++++
 .../integrationtests/LoanInterestPauseApiTest.java | 328 ++++++++++++++-------
 .../common/loans/LoanProductTestBuilder.java       |   1 +
 .../common/loans/LoanTransactionHelper.java        |  38 ++-
 18 files changed, 599 insertions(+), 171 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSource.java
 
b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSource.java
index ad28f696c..e468e4a17 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSource.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandSource.java
@@ -159,8 +159,7 @@ public class CommandSource extends 
AbstractPersistableCustom<Long> {
                 .transactionId(command.getTransactionId()) //
                 .creditBureauId(command.getCreditBureauId()) //
                 
.organisationCreditBureauId(command.getOrganisationCreditBureauId()) //
-                .loanExternalId(command.getLoanExternalId()) //
-                .build(); //
+                .loanExternalId(command.getLoanExternalId()).build(); //
     }
 
     public String getPermissionCode() {
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapper.java
 
b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapper.java
index 5b51f40de..fd73b43b9 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapper.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapper.java
@@ -251,8 +251,16 @@ public class CommandWrapper {
         return this.entityName.equalsIgnoreCase("INTEREST_PAUSE");
     }
 
-    public boolean isInterestPauseExternalIdResource() {
-        return this.entityName.equalsIgnoreCase("INTEREST_PAUSE") && 
this.href.contains("/external-id/");
+    public boolean isInterestPauseCreateResource() {
+        return this.entityName.equalsIgnoreCase("INTEREST_PAUSE") && 
"CREATE".equalsIgnoreCase(this.actionName);
+    }
+
+    public boolean isInterestPauseUpdateResource() {
+        return this.entityName.equalsIgnoreCase("INTEREST_PAUSE") && 
"UPDATE".equalsIgnoreCase(this.actionName);
+    }
+
+    public boolean isInterestPauseDeleteResource() {
+        return this.entityName.equalsIgnoreCase("INTEREST_PAUSE") && 
"DELETE".equalsIgnoreCase(this.actionName);
     }
 
     public Long commandId() {
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
 
b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
index 497862cbf..740fbbbc6 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
@@ -3732,4 +3732,22 @@ public class CommandWrapperBuilder {
         this.href = "/v1/loans/external-id/" + loanExternalId + 
"/interest-pauses";
         return this;
     }
+
+    public CommandWrapperBuilder deleteInterestPause(final long loanId, final 
long variationId) {
+        this.actionName = "DELETE";
+        this.entityName = "INTEREST_PAUSE";
+        this.loanId = loanId;
+        this.entityId = variationId;
+        this.href = "/v1/loans/" + loanId + "/interest-pauses/" + variationId;
+        return this;
+    }
+
+    public CommandWrapperBuilder updateInterestPause(final long loanId, final 
long variationId) {
+        this.actionName = "UPDATE";
+        this.entityName = "INTEREST_PAUSE";
+        this.loanId = loanId;
+        this.entityId = variationId;
+        this.href = "/v1/loans/" + loanId + "/interest-pauses/" + variationId;
+        return this;
+    }
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
 
b/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
index 9b525d5cd..f021cb23c 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
@@ -249,8 +249,16 @@ public class SynchronousCommandProcessingService 
implements CommandProcessingSer
             } else {
                 throw new UnsupportedCommandException(wrapper.commandName());
             }
-        } else if (wrapper.isInterestPauseResource() || 
wrapper.isInterestPauseExternalIdResource()) {
-            handler = 
applicationContext.getBean("interestPauseCommandHandler", 
NewCommandSourceHandler.class);
+        } else if (wrapper.isInterestPauseResource()) {
+            if (wrapper.isInterestPauseCreateResource()) {
+                handler = 
applicationContext.getBean("createInterestPauseCommandHandler", 
NewCommandSourceHandler.class);
+            } else if (wrapper.isInterestPauseUpdateResource()) {
+                handler = 
applicationContext.getBean("updateInterestPauseCommandHandler", 
NewCommandSourceHandler.class);
+            } else if (wrapper.isInterestPauseDeleteResource()) {
+                handler = 
applicationContext.getBean("deleteInterestPauseCommandHandler", 
NewCommandSourceHandler.class);
+            } else {
+                throw new UnsupportedCommandException(wrapper.commandName());
+            }
         } else {
             handler = commandHandlerProvider.getHandler(wrapper.entityName(), 
wrapper.actionName());
         }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/api/LoanInterestPauseApiResource.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/api/LoanInterestPauseApiResource.java
index 1b08ad6d8..253727547 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/api/LoanInterestPauseApiResource.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/api/LoanInterestPauseApiResource.java
@@ -25,12 +25,15 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
 import jakarta.ws.rs.Path;
 import jakarta.ws.rs.PathParam;
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
 import java.util.List;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.commands.domain.CommandWrapper;
@@ -50,6 +53,7 @@ import org.springframework.stereotype.Component;
 public class LoanInterestPauseApiResource {
 
     private static final String RESOURCE_NAME_FOR_PERMISSIONS = "LOAN";
+    private static final String MODIFY_RESOURCE_NAME_FOR_PERMISSIONS = "UPDATE 
LOAN";
 
     private final PlatformSecurityContext context;
     private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
@@ -64,7 +68,7 @@ public class LoanInterestPauseApiResource {
     public CommandProcessingResult createInterestPause(@PathParam("loanId") 
@Parameter(description = "loanId") final Long loanId,
             @RequestBody(required = true) final InterestPauseRequestDto 
request) {
 
-        
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
+        
this.context.authenticatedUser().validateHasReadPermission(MODIFY_RESOURCE_NAME_FOR_PERMISSIONS);
 
         final CommandWrapper commandRequest = new 
CommandWrapperBuilder().createInterestPause(loanId).withJson(request.toJson()).build();
 
@@ -81,7 +85,7 @@ public class LoanInterestPauseApiResource {
             @PathParam("loanExternalId") @Parameter(description = 
"loanExternalId") final String loanExternalId,
             @RequestBody(required = true) final InterestPauseRequestDto 
request) {
 
-        
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
+        
this.context.authenticatedUser().validateHasReadPermission(MODIFY_RESOURCE_NAME_FOR_PERMISSIONS);
 
         final CommandWrapper commandRequest = new 
CommandWrapperBuilder().createInterestPauseByExternalId(loanExternalId)
                 .withJson(request.toJson()).build();
@@ -114,4 +118,38 @@ public class LoanInterestPauseApiResource {
 
         return 
this.interestPauseReadPlatformService.retrieveInterestPauses(loanExternalId);
     }
+
+    @DELETE
+    @Path("/{loanId}/interest-pauses/{variationId}")
+    @Operation(summary = "Delete an interest pause period", description = 
"Deletes a specific interest pause period by its variation ID.")
+    @ApiResponses({ @ApiResponse(responseCode = "204", description = "No 
Content") })
+    public Response deleteInterestPause(@PathParam("loanId") 
@Parameter(description = "loanId") final Long loanId,
+            @PathParam("variationId") @Parameter(description = "variationId") 
final Long variationId) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(MODIFY_RESOURCE_NAME_FOR_PERMISSIONS);
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().deleteInterestPause(loanId, variationId).build();
+
+        
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+        return Response.noContent().build();
+    }
+
+    @PUT
+    @Path("/{loanId}/interest-pauses/{variationId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Update an interest pause period", description = 
"Updates a specific interest pause period by its variation ID.")
+    @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK") })
+    public CommandProcessingResult updateInterestPause(@PathParam("loanId") 
@Parameter(description = "loanId") final Long loanId,
+            @PathParam("variationId") @Parameter(description = "variationId") 
final Long variationId,
+            @RequestBody(required = true) final InterestPauseRequestDto 
request) {
+
+        
this.context.authenticatedUser().validateHasReadPermission(MODIFY_RESOURCE_NAME_FOR_PERMISSIONS);
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().updateInterestPause(loanId, variationId)
+                .withJson(request.toJson()).build();
+
+        return 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+    }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/CreateInterestPauseCommandHandler.java
similarity index 85%
copy from 
fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
copy to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/CreateInterestPauseCommandHandler.java
index 5747625dd..6246f278c 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/CreateInterestPauseCommandHandler.java
@@ -27,16 +27,14 @@ import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
 import 
org.apache.fineract.portfolio.interestpauses.service.InterestPauseWritePlatformService;
 import org.springframework.stereotype.Component;
 
-@Component("interestPauseCommandHandler")
+@Component("createInterestPauseCommandHandler")
 @RequiredArgsConstructor
-public class InterestPauseCommandHandler implements NewCommandSourceHandler {
+public class CreateInterestPauseCommandHandler implements 
NewCommandSourceHandler {
 
     private final InterestPauseWritePlatformService interestPauseService;
 
     @Override
     public CommandProcessingResult processCommand(final JsonCommand command) {
-        CommandProcessingResult result;
-
         final String startDate = 
command.stringValueOfParameterNamed("startDate");
         final String endDate = command.stringValueOfParameterNamed("endDate");
         final String dateFormat = 
command.stringValueOfParameterNamed("dateFormat");
@@ -44,15 +42,13 @@ public class InterestPauseCommandHandler implements 
NewCommandSourceHandler {
 
         if (command.getLoanId() != null) {
             final Long loanId = command.getLoanId();
-            result = interestPauseService.createInterestPause(loanId, 
startDate, endDate, dateFormat, locale);
+            return interestPauseService.createInterestPause(loanId, startDate, 
endDate, dateFormat, locale);
         } else if (command.getLoanExternalId() != null) {
             final ExternalId loanExternalId = command.getLoanExternalId();
-            result = interestPauseService.createInterestPause(loanExternalId, 
startDate, endDate, dateFormat, locale);
+            return interestPauseService.createInterestPause(loanExternalId, 
startDate, endDate, dateFormat, locale);
         } else {
             throw new 
PlatformApiDataValidationException("validation.msg.missing.loan.id.or.external.id",
                     "Either loanId or loanExternalId must be provided.", 
"loanId");
         }
-
-        return result;
     }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/DeleteInterestPauseCommandHandler.java
similarity index 52%
copy from 
fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
copy to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/DeleteInterestPauseCommandHandler.java
index 5747625dd..8068c8c5a 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/DeleteInterestPauseCommandHandler.java
@@ -22,37 +22,20 @@ import lombok.RequiredArgsConstructor;
 import org.apache.fineract.commands.handler.NewCommandSourceHandler;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
-import org.apache.fineract.infrastructure.core.domain.ExternalId;
-import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import 
org.apache.fineract.portfolio.interestpauses.service.InterestPauseWritePlatformService;
 import org.springframework.stereotype.Component;
 
-@Component("interestPauseCommandHandler")
+@Component("deleteInterestPauseCommandHandler")
 @RequiredArgsConstructor
-public class InterestPauseCommandHandler implements NewCommandSourceHandler {
+public class DeleteInterestPauseCommandHandler implements 
NewCommandSourceHandler {
 
     private final InterestPauseWritePlatformService interestPauseService;
 
     @Override
     public CommandProcessingResult processCommand(final JsonCommand command) {
-        CommandProcessingResult result;
+        final Long loanId = command.getLoanId();
+        final Long termVariationId = command.getResourceId();
 
-        final String startDate = 
command.stringValueOfParameterNamed("startDate");
-        final String endDate = command.stringValueOfParameterNamed("endDate");
-        final String dateFormat = 
command.stringValueOfParameterNamed("dateFormat");
-        final String locale = command.stringValueOfParameterNamed("locale");
-
-        if (command.getLoanId() != null) {
-            final Long loanId = command.getLoanId();
-            result = interestPauseService.createInterestPause(loanId, 
startDate, endDate, dateFormat, locale);
-        } else if (command.getLoanExternalId() != null) {
-            final ExternalId loanExternalId = command.getLoanExternalId();
-            result = interestPauseService.createInterestPause(loanExternalId, 
startDate, endDate, dateFormat, locale);
-        } else {
-            throw new 
PlatformApiDataValidationException("validation.msg.missing.loan.id.or.external.id",
-                    "Either loanId or loanExternalId must be provided.", 
"loanId");
-        }
-
-        return result;
+        return interestPauseService.deleteInterestPause(loanId, 
termVariationId);
     }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/UpdateInterestPauseCommandHandler.java
similarity index 63%
rename from 
fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
rename to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/UpdateInterestPauseCommandHandler.java
index 5747625dd..04a9b2f03 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/InterestPauseCommandHandler.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/handler/UpdateInterestPauseCommandHandler.java
@@ -22,37 +22,24 @@ import lombok.RequiredArgsConstructor;
 import org.apache.fineract.commands.handler.NewCommandSourceHandler;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
-import org.apache.fineract.infrastructure.core.domain.ExternalId;
-import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import 
org.apache.fineract.portfolio.interestpauses.service.InterestPauseWritePlatformService;
 import org.springframework.stereotype.Component;
 
-@Component("interestPauseCommandHandler")
+@Component("updateInterestPauseCommandHandler")
 @RequiredArgsConstructor
-public class InterestPauseCommandHandler implements NewCommandSourceHandler {
+public class UpdateInterestPauseCommandHandler implements 
NewCommandSourceHandler {
 
     private final InterestPauseWritePlatformService interestPauseService;
 
     @Override
     public CommandProcessingResult processCommand(final JsonCommand command) {
-        CommandProcessingResult result;
-
+        final Long loanId = command.getLoanId();
+        final Long termVariationId = command.getResourceId();
         final String startDate = 
command.stringValueOfParameterNamed("startDate");
         final String endDate = command.stringValueOfParameterNamed("endDate");
         final String dateFormat = 
command.stringValueOfParameterNamed("dateFormat");
         final String locale = command.stringValueOfParameterNamed("locale");
 
-        if (command.getLoanId() != null) {
-            final Long loanId = command.getLoanId();
-            result = interestPauseService.createInterestPause(loanId, 
startDate, endDate, dateFormat, locale);
-        } else if (command.getLoanExternalId() != null) {
-            final ExternalId loanExternalId = command.getLoanExternalId();
-            result = interestPauseService.createInterestPause(loanExternalId, 
startDate, endDate, dateFormat, locale);
-        } else {
-            throw new 
PlatformApiDataValidationException("validation.msg.missing.loan.id.or.external.id",
-                    "Either loanId or loanExternalId must be provided.", 
"loanId");
-        }
-
-        return result;
+        return interestPauseService.updateInterestPause(loanId, 
termVariationId, startDate, endDate, dateFormat, locale);
     }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformService.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformService.java
index e3b8c397a..491a45171 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformService.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformService.java
@@ -23,6 +23,21 @@ import 
org.apache.fineract.infrastructure.core.domain.ExternalId;
 
 public interface InterestPauseWritePlatformService {
 
+    /**
+     * Create a new interest pause period for a loan identified by its 
external ID.
+     *
+     * @param loanExternalId
+     *            the external ID of the loan
+     * @param startDate
+     *            the start date of the interest pause period (inclusive)
+     * @param endDate
+     *            the end date of the interest pause period (inclusive)
+     * @param dateFormat
+     *            the format of the provided dates
+     * @param locale
+     *            the locale used for date parsing
+     * @return the ID of the created loan term variation representing the 
interest pause
+     */
     CommandProcessingResult createInterestPause(ExternalId loanExternalId, 
String startDate, String endDate, String dateFormat,
             String locale);
 
@@ -35,7 +50,42 @@ public interface InterestPauseWritePlatformService {
      *            the start date of the interest pause period (inclusive)
      * @param endDate
      *            the end date of the interest pause period (inclusive)
+     * @param dateFormat
+     *            the format of the provided dates
+     * @param locale
+     *            the locale used for date parsing
      * @return the ID of the created loan term variation representing the 
interest pause
      */
     CommandProcessingResult createInterestPause(Long loanId, String startDate, 
String endDate, String dateFormat, String locale);
+
+    /**
+     * Delete an existing interest pause period for a loan.
+     *
+     * @param loanId
+     *            the ID of the loan
+     * @param variationId
+     *            the ID of the loan term variation representing the interest 
pause
+     * @return the result of the delete operation
+     */
+    CommandProcessingResult deleteInterestPause(Long loanId, Long variationId);
+
+    /**
+     * Update an existing interest pause period for a loan identified by its 
internal ID.
+     *
+     * @param loanId
+     *            the ID of the loan
+     * @param variationId
+     *            the ID of the loan term variation representing the interest 
pause to be updated
+     * @param startDateString
+     *            the new start date of the interest pause period (inclusive) 
as a string
+     * @param endDateString
+     *            the new end date of the interest pause period (inclusive) as 
a string
+     * @param dateFormat
+     *            the format of the provided dates (e.g., "yyyy-MM-dd")
+     * @param locale
+     *            the locale used for parsing the provided dates
+     * @return the updated loan term variation ID along with the updated fields
+     */
+    CommandProcessingResult updateInterestPause(Long loanId, Long variationId, 
String startDateString, String endDateString,
+            String dateFormat, String locale);
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformServiceImpl.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformServiceImpl.java
index 272ba3f9f..095ec4024 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformServiceImpl.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/interestpauses/service/InterestPauseWritePlatformServiceImpl.java
@@ -18,12 +18,19 @@
  */
 package org.apache.fineract.portfolio.interestpauses.service;
 
+import static 
org.apache.fineract.portfolio.loanaccount.domain.LoanStatus.ACTIVE;
+import static 
org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType.INTEREST_PAUSE;
+import static 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType.PROGRESSIVE;
+
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 import lombok.AllArgsConstructor;
@@ -34,11 +41,13 @@ import 
org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
 import org.apache.fineract.infrastructure.core.domain.ExternalId;
 import 
org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
 import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.service.DateUtils;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariations;
 import 
org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanTermVariationsRepository;
+import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.transaction.annotation.Transactional;
 
 @AllArgsConstructor
@@ -47,6 +56,7 @@ public class InterestPauseWritePlatformServiceImpl implements 
InterestPauseWrite
 
     private final LoanTermVariationsRepository loanTermVariationsRepository;
     private final LoanRepositoryWrapper loanRepositoryWrapper;
+    private final PlatformSecurityContext context;
 
     @Override
     public CommandProcessingResult createInterestPause(ExternalId 
loanExternalId, String startDateString, String endDateString,
@@ -68,14 +78,59 @@ public class InterestPauseWritePlatformServiceImpl 
implements InterestPauseWrite
                 locale);
     }
 
+    @Override
+    public CommandProcessingResult deleteInterestPause(Long loanId, Long 
variationId) {
+        LoanTermVariations variation = loanTermVariationsRepository
+                .findByIdAndLoanIdAndTermType(variationId, loanId, 
INTEREST_PAUSE.getValue())
+                .orElseThrow(() -> new 
GeneralPlatformDomainRuleException("error.msg.variation.not.found",
+                        "Variation not found for the given loan ID"));
+
+        loanTermVariationsRepository.delete(variation);
+
+        return new 
CommandProcessingResultBuilder().withEntityId(variationId).build();
+    }
+
+    @Override
+    public CommandProcessingResult updateInterestPause(Long loanId, Long 
variationId, String startDateString, String endDateString,
+            String dateFormat, String locale) {
+        Loan loan = loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
+
+        LocalDate startDate = parseDate(startDateString, dateFormat, locale);
+        LocalDate endDate = parseDate(endDateString, dateFormat, locale);
+
+        validateInterestPauseDates(loan, startDate, endDate, dateFormat, 
locale);
+
+        LoanTermVariations variation = loanTermVariationsRepository
+                .findByIdAndLoanIdAndTermType(variationId, loanId, 
INTEREST_PAUSE.getValue())
+                .orElseThrow(() -> new 
GeneralPlatformDomainRuleException("error.msg.variation.not.found",
+                        "Variation not found for the given loan ID"));
+
+        validateVariations(loan, variation);
+
+        variation.setTermApplicableFrom(startDate);
+        variation.setDateValue(endDate);
+
+        AppUser currentUser = context.authenticatedUser();
+        variation.setUpdatedBy(currentUser != null ? currentUser.getId() : 
null);
+        
variation.setUpdatedOnDate(LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant()));
+
+        LoanTermVariations updatedVariation = 
loanTermVariationsRepository.save(variation);
+
+        return new 
CommandProcessingResultBuilder().withEntityId(updatedVariation.getId())
+                .with(Map.of("startDate", startDate.toString(), "endDate", 
endDate.toString())).build();
+    }
+
     private CommandProcessingResult processInterestPause(Supplier<Loan> 
loanSupplier, LocalDate startDate, LocalDate endDate,
             String dateFormat, String locale) {
         final Loan loan = loanSupplier.get();
 
         validateInterestPauseDates(loan, startDate, endDate, dateFormat, 
locale);
 
-        LoanTermVariations variation = new 
LoanTermVariations(LoanTermVariationType.INTEREST_PAUSE.getValue(), startDate, 
null, endDate,
-                false, loan);
+        LoanTermVariations variation = new 
LoanTermVariations(INTEREST_PAUSE.getValue(), startDate, null, endDate, false, 
loan);
+
+        AppUser currentUser = context.authenticatedUser();
+        variation.setCreatedBy(currentUser != null ? currentUser.getId() : 
null);
+        
variation.setCreatedOnDate(LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant()));
 
         LoanTermVariations savedVariation = 
loanTermVariationsRepository.saveAndFlush(variation);
 
@@ -109,6 +164,36 @@ public class InterestPauseWritePlatformServiceImpl 
implements InterestPauseWrite
                     .format("Interest pause end date (%s) must not be before 
the interest pause start date (%s).", endDate, startDate),
                     endDate, startDate);
         }
+
+        if (!Objects.equals(loan.getLoanStatus(), ACTIVE.getValue())) {
+            throw new GeneralPlatformDomainRuleException("loan.must.be.active",
+                    "Operations on interest pauses are restricted to active 
loans.");
+        }
+
+        if 
(!PROGRESSIVE.equals(loan.getLoanRepaymentScheduleDetail().getLoanScheduleType()))
 {
+            throw new 
GeneralPlatformDomainRuleException("loan.must.be.progressive",
+                    "Interest pause is only supported for progressive loans.");
+        }
+
+        if 
(!loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) {
+            throw new 
GeneralPlatformDomainRuleException("loan.must.have.recalculate.interest.enabled",
+                    "Interest pause is only supported for loans with 
recalculate interest enabled.");
+        }
+    }
+
+    private void validateVariations(Loan loan, LoanTermVariations variation) {
+        if (variation == null) {
+            throw new 
GeneralPlatformDomainRuleException("interest.pause.not.found",
+                    "The specified interest pause does not exist for the given 
loan.");
+        }
+
+        List<LoanTermVariations> existingVariations = 
loan.getLoanTermVariations();
+        for (LoanTermVariations existingVariation : existingVariations) {
+            if (!existingVariation.equals(variation) && 
variation.getTermApplicableFrom().isBefore(existingVariation.getDateValue())
+                    && 
variation.getDateValue().isAfter(existingVariation.getTermApplicableFrom())) {
+                throw new 
GeneralPlatformDomainRuleException("interest.pause.overlapping", "Overlapping 
interest pauses are not allowed.");
+            }
+        }
     }
 
     private LocalDate parseDate(String date, String dateFormat, String locale) 
{
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
index d5f41828d..891dde0e2 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java
@@ -27,6 +27,7 @@ import jakarta.persistence.OneToOne;
 import jakarta.persistence.Table;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import 
org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
@@ -61,6 +62,18 @@ public class LoanTermVariations extends 
AbstractPersistableCustom<Long> {
     @Column(name = "is_active", nullable = false)
     private Boolean isActive;
 
+    @Column(name = "created_by")
+    private Long createdBy;
+
+    @Column(name = "created_on_date")
+    private LocalDateTime createdOnDate;
+
+    @Column(name = "updated_by")
+    private Long updatedBy;
+
+    @Column(name = "updated_on_date")
+    private LocalDateTime updatedOnDate;
+
     @OneToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "parent_id")
     private LoanTermVariations parent;
@@ -139,6 +152,10 @@ public class LoanTermVariations extends 
AbstractPersistableCustom<Long> {
         return this.dateValue;
     }
 
+    public void setDateValue(LocalDate dateValue) {
+        this.dateValue = dateValue;
+    }
+
     public void setTermApplicableFrom(LocalDate termApplicableFrom) {
         this.termApplicableFrom = termApplicableFrom;
     }
@@ -167,4 +184,35 @@ public class LoanTermVariations extends 
AbstractPersistableCustom<Long> {
         this.isActive = false;
     }
 
+    public Long getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(Long createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public LocalDateTime getCreatedOnDate() {
+        return createdOnDate;
+    }
+
+    public void setCreatedOnDate(LocalDateTime createdOnDate) {
+        this.createdOnDate = createdOnDate;
+    }
+
+    public Long getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(Long updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public LocalDateTime getUpdatedOnDate() {
+        return updatedOnDate;
+    }
+
+    public void setUpdatedOnDate(LocalDateTime updatedOnDate) {
+        this.updatedOnDate = updatedOnDate;
+    }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanTermVariationsRepository.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanTermVariationsRepository.java
index 0bf7209ff..57993fe05 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanTermVariationsRepository.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanTermVariationsRepository.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain;
 
 import java.util.List;
+import java.util.Optional;
 import org.apache.fineract.infrastructure.core.domain.ExternalId;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariations;
@@ -60,4 +61,12 @@ public interface LoanTermVariationsRepository
             """)
     List<LoanTermVariationsData> 
findLoanTermVariationsByExternalLoanIdAndTermType(@Param("loanExternalId") 
ExternalId loanExternalId,
             @Param("termType") int termType);
+
+    @Query("""
+            select ltv
+            from LoanTermVariations ltv
+            where ltv.id = :variationId and ltv.loan.id = :loanId and 
ltv.termType = :termType
+            """)
+    Optional<LoanTermVariations> 
findByIdAndLoanIdAndTermType(@Param("variationId") long variationId, 
@Param("loanId") long loanId,
+            @Param("termType") int termType);
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
index b7b9a955d..a1a1fddbb 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
@@ -471,7 +471,7 @@ public class LoanAccountConfiguration {
     @Bean
     @ConditionalOnMissingBean(InterestPauseWritePlatformService.class)
     public InterestPauseWritePlatformService 
interestPauseWritePlatformService(LoanTermVariationsRepository 
loanTermVariationsRepository,
-            LoanRepositoryWrapper loanRepositoryWrapper) {
-        return new 
InterestPauseWritePlatformServiceImpl(loanTermVariationsRepository, 
loanRepositoryWrapper);
+            LoanRepositoryWrapper loanRepositoryWrapper, 
PlatformSecurityContext context) {
+        return new 
InterestPauseWritePlatformServiceImpl(loanTermVariationsRepository, 
loanRepositoryWrapper, context);
     }
 }
diff --git 
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml 
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
index 673a92f1f..b058f2a2a 100644
--- 
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
+++ 
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
@@ -180,4 +180,5 @@
     <include 
file="parts/0159_trial_balance_summary_with_asset_owner_year_end_summary.xml" 
relativeToChangelogFile="true" />
     <include file="parts/0160_add_acc_product_mapping_product_id_index.xml" 
relativeToChangelogFile="true" />
     <include file="parts/0161_add_loan_external_id_to_commands.xml" 
relativeToChangelogFile="true" />
+    <include 
file="parts/0162_add_additional_audit_fields_to_term_variations.xml" 
relativeToChangelogFile="true" />
 </databaseChangeLog>
diff --git 
a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0162_add_additional_audit_fields_to_term_variations.xml
 
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0162_add_additional_audit_fields_to_term_variations.xml
new file mode 100644
index 000000000..fbb1ef2bf
--- /dev/null
+++ 
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0162_add_additional_audit_fields_to_term_variations.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog";
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+                   
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog 
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd";>
+
+    <changeSet id="1" author="fineract">
+        <addColumn tableName="m_loan_term_variations">
+            <column name="created_by" type="BIGINT">
+                <constraints nullable="true"/>
+            </column>
+        </addColumn>
+
+        <addColumn tableName="m_loan_term_variations">
+            <column name="created_on_date" type="TIMESTAMP">
+                <constraints nullable="true"/>
+            </column>
+        </addColumn>
+
+        <addColumn tableName="m_loan_term_variations">
+            <column name="updated_by" type="BIGINT">
+                <constraints nullable="true"/>
+            </column>
+        </addColumn>
+
+        <addColumn tableName="m_loan_term_variations">
+            <column name="updated_on_date" type="TIMESTAMP">
+                <constraints nullable="true"/>
+            </column>
+        </addColumn>
+    </changeSet>
+</databaseChangeLog>
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
index 347b72f23..d4f5d0dc0 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
@@ -24,38 +24,30 @@ import io.restassured.http.ContentType;
 import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.List;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.client.models.AdvancedPaymentData;
-import org.apache.fineract.client.models.PaymentAllocationOrder;
-import org.apache.fineract.client.models.PostClientsResponse;
+import org.apache.fineract.client.models.PostLoansLoanIdRequest;
 import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
-import org.apache.fineract.client.models.PostLoansRequest;
-import org.apache.fineract.client.models.PostLoansResponse;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.accounting.Account;
 import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
+import 
org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
-import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
 import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
 import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
-import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Slf4j
-@ExtendWith({ LoanTestLifecycleExtension.class })
+@ExtendWith(LoanTestLifecycleExtension.class)
 public class LoanInterestPauseApiTest extends BaseLoanIntegrationTest {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(LoanInterestPauseApiTest.class);
@@ -63,52 +55,56 @@ public class LoanInterestPauseApiTest extends 
BaseLoanIntegrationTest {
     private static RequestSpecification REQUEST_SPEC;
     private static ResponseSpecification RESPONSE_SPEC;
     private static ResponseSpecification RESPONSE_SPEC_403;
+    private static ResponseSpecification RESPONSE_SPEC_204;
     private static LoanTransactionHelper LOAN_TRANSACTIONAL_HELPER;
+    private static LoanTransactionHelper LOAN_TRANSACTIONAL_HELPER_204;
     private static LoanTransactionHelper LOAN_TRANSACTION_HELPER_403;
-    private static AccountHelper accountHelper;
-    private static PostClientsResponse client;
-    private static Integer loanProductId;
-    private static Long loanId;
-    private static Long nonExistLoanId = 99999L;
+    private static AccountHelper ACCOUNT_HELPER;
+    private static final Integer nonExistLoanId = 99999;
     private static String externalId;
-    private static String nonExistExternalId = 
"7c4fb86f-a778-4d02-b7a8-ec3ec98941fa";
-
-    @BeforeAll
-    public static void setupTests() {
+    private static final String nonExistExternalId = 
"7c4fb86f-a778-4d02-b7a8-ec3ec98941fa";
+    private Integer clientId;
+    private Integer loanProductId;
+    private Integer loanId;
+    private final String loanPrincipalAmount = "10000.00";
+    private final String numberOfRepayments = "12";
+    private final String interestRatePerPeriod = "18";
+    private final String dateString = "01 January 2023";
+
+    @BeforeEach
+    public void initialize() {
         Utils.initializeRESTAssured();
         REQUEST_SPEC = new 
RequestSpecBuilder().setContentType(ContentType.JSON).build();
         REQUEST_SPEC.header("Authorization", "Basic " + 
Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
         RESPONSE_SPEC = new 
ResponseSpecBuilder().expectStatusCode(200).build();
         RESPONSE_SPEC_403 = new 
ResponseSpecBuilder().expectStatusCode(403).build();
+        RESPONSE_SPEC_204 = new 
ResponseSpecBuilder().expectStatusCode(204).build();
         LOAN_TRANSACTIONAL_HELPER = new LoanTransactionHelper(REQUEST_SPEC, 
RESPONSE_SPEC);
         LOAN_TRANSACTION_HELPER_403 = new LoanTransactionHelper(REQUEST_SPEC, 
RESPONSE_SPEC_403);
-        accountHelper = new AccountHelper(REQUEST_SPEC, RESPONSE_SPEC);
-        ClientHelper clientHelper = new ClientHelper(REQUEST_SPEC, 
RESPONSE_SPEC);
-        client = 
clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
-
-        final Account assetAccount = accountHelper.createAssetAccount();
-        final Account incomeAccount = accountHelper.createIncomeAccount();
-        final Account expenseAccount = accountHelper.createExpenseAccount();
-        final Account overpaymentAccount = 
accountHelper.createLiabilityAccount();
+        LOAN_TRANSACTIONAL_HELPER_204 = new 
LoanTransactionHelper(REQUEST_SPEC, RESPONSE_SPEC_204);
+        ACCOUNT_HELPER = new AccountHelper(REQUEST_SPEC, RESPONSE_SPEC);
 
         externalId = UUID.randomUUID().toString();
 
-        loanProductId = createLoanProduct("500", "15", "4", true, "25", true, 
LoanScheduleType.PROGRESSIVE,
-                LoanScheduleProcessingType.HORIZONTAL, assetAccount, 
incomeAccount, expenseAccount, overpaymentAccount);
-
-        final PostLoansResponse loanResponse = 
applyForLoanApplication(client.getClientId(), loanProductId, 
BigDecimal.valueOf(500.0), 45,
-                15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023", 
externalId);
-
-        loanId = loanResponse.getLoanId();
+        createRequiredEntities();
 
         Assertions.assertNotNull(loanProductId, "Loan Product ID should not be 
null after creation");
         Assertions.assertNotNull(loanId, "Loan ID should not be null after 
creation");
         Assertions.assertNotNull(externalId, "External Loan ID should not be 
null after creation");
     }
 
+    /**
+     * Creates the client, loan product, and loan entities
+     **/
+    private void createRequiredEntities() {
+        this.createClientEntity();
+        this.createLoanProductEntity();
+        this.createLoanEntity();
+    }
+
     @Test
     public void testCreateInterestPauseByLoanId_validRequest_shouldSucceed() {
-        PostLoansLoanIdTransactionsResponse response = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01", 
"2023-02-05",
+        PostLoansLoanIdTransactionsResponse response = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01", 
"2023-01-12",
                 "yyyy-MM-dd", "en", loanId);
 
         Assertions.assertNotNull(response);
@@ -118,7 +114,7 @@ public class LoanInterestPauseApiTest extends 
BaseLoanIntegrationTest {
     @Test
     public void 
testCreateInterestPauseByLoanId_endDateBeforeStartDate_shouldFail() {
         try {
-            
LOAN_TRANSACTION_HELPER_403.createInterestPauseByLoanId("2024-12-05", 
"2024-12-01", "yyyy-MM-dd", "en", loanId);
+            
LOAN_TRANSACTION_HELPER_403.createInterestPauseByLoanId("2024-12-05", 
"2023-01-12", "yyyy-MM-dd", "en", loanId);
         } catch (Exception e) {
             String responseBody = e.getMessage();
             Assertions.assertNotNull(responseBody, "Response body should not 
be null");
@@ -130,7 +126,7 @@ public class LoanInterestPauseApiTest extends 
BaseLoanIntegrationTest {
     @Test
     public void 
testCreateInterestPauseByLoanId_startDateBeforeLoanStart_shouldFail() {
         try {
-            
LOAN_TRANSACTION_HELPER_403.createInterestPauseByLoanId("2022-12-01", 
"2024-12-05", "yyyy-MM-dd", "en", loanId);
+            
LOAN_TRANSACTION_HELPER_403.createInterestPauseByLoanId("2022-12-01", 
"2023-01-12", "yyyy-MM-dd", "en", loanId);
         } catch (Exception e) {
             String responseBody = e.getMessage();
             Assertions.assertNotNull(responseBody, "Response body should not 
be null");
@@ -163,18 +159,18 @@ public class LoanInterestPauseApiTest extends 
BaseLoanIntegrationTest {
 
     @Test
     public void testRetrieveInterestPausesByLoanId_shouldReturnData() {
-        LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01", 
"2023-02-05", "yyyy-MM-dd", "en", loanId);
+        LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01", 
"2023-01-12", "yyyy-MM-dd", "en", loanId);
 
         String response = 
LOAN_TRANSACTIONAL_HELPER.retrieveInterestPauseByLoanId(loanId);
 
         Assertions.assertNotNull(response, "Response should not be null");
         Assertions.assertTrue(response.contains("2023-01-01"));
-        Assertions.assertTrue(response.contains("2023-02-05"));
+        Assertions.assertTrue(response.contains("2023-01-12"));
     }
 
     @Test
     public void 
testCreateInterestPauseByExternalLoanId_validRequest_shouldSucceed() {
-        PostLoansLoanIdTransactionsResponse response = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByExternalId("2023-01-01", 
"2023-02-05",
+        PostLoansLoanIdTransactionsResponse response = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByExternalId("2023-01-01", 
"2023-01-12",
                 "yyyy-MM-dd", "en", externalId);
 
         Assertions.assertNotNull(response);
@@ -184,7 +180,7 @@ public class LoanInterestPauseApiTest extends 
BaseLoanIntegrationTest {
     @Test
     public void 
testCreateInterestPauseByExternalLoanId_endDateBeforeStartDate_shouldFail() {
         try {
-            
LOAN_TRANSACTION_HELPER_403.createInterestPauseByExternalId("2024-12-05", 
"2024-12-01", "yyyy-MM-dd", "en", externalId);
+            
LOAN_TRANSACTION_HELPER_403.createInterestPauseByExternalId("2023-01-01", 
"2022-01-12", "yyyy-MM-dd", "en", externalId);
         } catch (Exception e) {
             String responseBody = e.getMessage();
             Assertions.assertNotNull(responseBody, "Response body should not 
be null");
@@ -229,87 +225,207 @@ public class LoanInterestPauseApiTest extends 
BaseLoanIntegrationTest {
 
     @Test
     public void testRetrieveInterestPausesByExternalLoanId_shouldReturnData() {
-        
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByExternalId("2023-01-01", 
"2023-02-05", "yyyy-MM-dd", "en", externalId);
+        
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByExternalId("2023-01-01", 
"2023-01-12", "yyyy-MM-dd", "en", externalId);
 
         String response = 
LOAN_TRANSACTIONAL_HELPER.retrieveInterestPauseByExternalId(externalId);
 
         Assertions.assertNotNull(response, "Response should not be null");
         Assertions.assertTrue(response.contains("2023-01-01"));
-        Assertions.assertTrue(response.contains("2023-02-05"));
+        Assertions.assertTrue(response.contains("2023-01-12"));
+    }
+
+    @Test
+    public void testUpdateInterestPauseByLoanId_validRequest_shouldSucceed() {
+        PostLoansLoanIdTransactionsResponse createResponse = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01",
+                "2023-01-12", "yyyy-MM-dd", "en", loanId);
+
+        Assertions.assertNotNull(createResponse);
+        Assertions.assertNotNull(createResponse.getResourceId());
+
+        Long variationId = createResponse.getResourceId();
+
+        PostLoansLoanIdTransactionsResponse updateResponse = 
LOAN_TRANSACTIONAL_HELPER.updateInterestPauseByLoanId(variationId,
+                "2023-01-01", "2023-01-12", "yyyy-MM-dd", "en", loanId);
+
+        Assertions.assertNotNull(updateResponse);
+        Assertions.assertNotNull(updateResponse.getResourceId());
+        Assertions.assertEquals(variationId, updateResponse.getResourceId());
+    }
+
+    @Test
+    public void 
testUpdateInterestPauseByLoanId_endDateBeforeStartDate_shouldFail() {
+        PostLoansLoanIdTransactionsResponse createResponse = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01",
+                "2023-01-12", "yyyy-MM-dd", "en", loanId);
+
+        Assertions.assertNotNull(createResponse);
+        Assertions.assertNotNull(createResponse.getResourceId());
+
+        Long variationId = createResponse.getResourceId();
+
+        try {
+            
LOAN_TRANSACTION_HELPER_403.updateInterestPauseByLoanId(variationId, 
"2023-03-01", "2023-01-12", "yyyy-MM-dd", "en", loanId);
+        } catch (Exception e) {
+            String responseBody = e.getMessage();
+            Assertions.assertNotNull(responseBody, "Response body should not 
be null");
+            
Assertions.assertTrue(responseBody.contains("interest.pause.end.date.before.start.date"),
+                    "Response should contain the validation error message for 
end date before start date");
+        }
+    }
+
+    @Test
+    public void 
testUpdateInterestPauseByLoanId_startDateBeforeLoanStart_shouldFail() {
+        PostLoansLoanIdTransactionsResponse createResponse = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01",
+                "2023-01-12", "yyyy-MM-dd", "en", loanId);
+
+        Assertions.assertNotNull(createResponse);
+        Assertions.assertNotNull(createResponse.getResourceId());
+
+        Long variationId = createResponse.getResourceId();
+
+        try {
+            
LOAN_TRANSACTION_HELPER_403.updateInterestPauseByLoanId(variationId, 
"2022-12-01", "2023-01-12", "yyyy-MM-dd", "en", loanId);
+        } catch (Exception e) {
+            String responseBody = e.getMessage();
+            Assertions.assertNotNull(responseBody, "Response body should not 
be null");
+            
Assertions.assertTrue(responseBody.contains("interest.pause.start.date.before.loan.start.date"),
+                    "Response should contain the validation error message for 
start date before loan start date");
+        }
     }
 
-    private static Integer createLoanProduct(final String principal, final 
String repaymentAfterEvery, final String numberOfRepayments,
-            boolean downPaymentEnabled, String downPaymentPercentage, boolean 
autoPayForDownPayment, LoanScheduleType loanScheduleType,
-            LoanScheduleProcessingType loanScheduleProcessingType, final 
Account... accounts) {
-        AdvancedPaymentData defaultAllocation = 
createDefaultPaymentAllocation();
-        final String loanProductJSON = new 
LoanProductTestBuilder().withMinPrincipal(principal).withPrincipal(principal)
-                
.withRepaymentTypeAsDays().withRepaymentAfterEvery(repaymentAfterEvery).withNumberOfRepayments(numberOfRepayments)
-                .withEnableDownPayment(downPaymentEnabled, 
downPaymentPercentage, autoPayForDownPayment).withinterestRatePerPeriod("0")
-                .withInterestRateFrequencyTypeAsMonths()
-                
.withRepaymentStrategy(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
-                
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
-                
.addAdvancedPaymentAllocation(defaultAllocation).withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
-                
.withInterestTypeAsDecliningBalance().withMultiDisburse().withDisallowExpectedDisbursements(true)
-                
.withLoanScheduleType(loanScheduleType).withLoanScheduleProcessingType(loanScheduleProcessingType).withDaysInMonth("30")
-                .withDaysInYear("365").withMoratorium("0", "0").build(null);
-        return LOAN_TRANSACTIONAL_HELPER.getLoanProductId(loanProductJSON);
+    @Test
+    public void testDeleteInterestPauseByLoanId_validRequest_shouldSucceed() {
+        PostLoansLoanIdTransactionsResponse createResponse = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01",
+                "2023-01-12", "yyyy-MM-dd", "en", loanId);
+
+        Assertions.assertNotNull(createResponse, "Create response should not 
be null");
+        Assertions.assertNotNull(createResponse.getResourceId(), "Resource ID 
should not be null");
+
+        Long variationId = createResponse.getResourceId();
+
+        try {
+            
LOAN_TRANSACTIONAL_HELPER_204.deleteInterestPauseByLoanId(variationId, loanId);
+        } catch (Exception e) {
+            Assertions.fail("Delete operation failed: " + e.getMessage());
+        }
+
+        String response = 
LOAN_TRANSACTIONAL_HELPER.retrieveInterestPauseByLoanId(loanId);
+        Assertions.assertFalse(response.contains(String.valueOf(variationId)), 
"Response should not contain the deleted variation ID");
     }
 
-    private static AdvancedPaymentData createDefaultPaymentAllocation() {
-        AdvancedPaymentData advancedPaymentData = new AdvancedPaymentData();
-        advancedPaymentData.setTransactionType("DEFAULT");
-        
advancedPaymentData.setFutureInstallmentAllocationRule("NEXT_INSTALLMENT");
+    @Test
+    public void 
testDeleteInterestPauseByLoanId_nonExistentVariation_shouldFail() {
+        try {
+            LOAN_TRANSACTION_HELPER_403.deleteInterestPauseByLoanId(99999L, 
loanId);
+        } catch (Exception e) {
+            String responseBody = e.getMessage();
+            Assertions.assertNotNull(responseBody, "Response body should not 
be null");
+            
Assertions.assertTrue(responseBody.contains("error.msg.variation.not.found"),
+                    "Response should contain the validation error message for 
variation not found");
+        }
+    }
 
-        List<PaymentAllocationOrder> paymentAllocationOrders = 
getPaymentAllocationOrder(PaymentAllocationType.PAST_DUE_PENALTY,
-                PaymentAllocationType.PAST_DUE_FEE, 
PaymentAllocationType.PAST_DUE_PRINCIPAL, 
PaymentAllocationType.PAST_DUE_INTEREST,
-                PaymentAllocationType.DUE_PENALTY, 
PaymentAllocationType.DUE_FEE, PaymentAllocationType.DUE_PRINCIPAL,
-                PaymentAllocationType.DUE_INTEREST, 
PaymentAllocationType.IN_ADVANCE_PENALTY, PaymentAllocationType.IN_ADVANCE_FEE,
-                PaymentAllocationType.IN_ADVANCE_PRINCIPAL, 
PaymentAllocationType.IN_ADVANCE_INTEREST);
+    @Test
+    public void testDeleteInterestPauseByLoanId_invalidLoanId_shouldFail() {
+        PostLoansLoanIdTransactionsResponse createResponse = 
LOAN_TRANSACTIONAL_HELPER.createInterestPauseByLoanId("2023-01-01",
+                "2023-01-12", "yyyy-MM-dd", "en", loanId);
 
-        advancedPaymentData.setPaymentAllocationOrder(paymentAllocationOrders);
-        return advancedPaymentData;
+        Assertions.assertNotNull(createResponse);
+        Assertions.assertNotNull(createResponse.getResourceId());
+
+        Long variationId = createResponse.getResourceId();
+
+        try {
+            
LOAN_TRANSACTION_HELPER_403.deleteInterestPauseByLoanId(variationId, 
nonExistLoanId);
+        } catch (Exception e) {
+            String responseBody = e.getMessage();
+            Assertions.assertNotNull(responseBody, "Response body should not 
be null");
+            
Assertions.assertTrue(responseBody.contains("error.msg.variation.not.found"),
+                    "Response should contain the validation error message for 
variation not found");
+        }
+    }
+
+    /**
+     * create a new client
+     **/
+    private void createClientEntity() {
+        this.clientId = ClientHelper.createClient(REQUEST_SPEC, RESPONSE_SPEC);
+
+        ClientHelper.verifyClientCreatedOnServer(REQUEST_SPEC, RESPONSE_SPEC, 
clientId);
     }
 
-    private static List<PaymentAllocationOrder> 
getPaymentAllocationOrder(PaymentAllocationType... paymentAllocationTypes) {
-        AtomicInteger integer = new AtomicInteger(1);
-        return Arrays.stream(paymentAllocationTypes).map(pat -> {
-            PaymentAllocationOrder paymentAllocationOrder = new 
PaymentAllocationOrder();
-            paymentAllocationOrder.setPaymentAllocationRule(pat.name());
-            paymentAllocationOrder.setOrder(integer.getAndIncrement());
-            return paymentAllocationOrder;
-        }).collect(Collectors.toList());
+    /**
+     * create a new loan product
+     **/
+    private void createLoanProductEntity() {
+        LOG.info("---------------------------------CREATING LOAN 
PRODUCT------------------------------------------");
+
+        final String interestRecalculationCompoundingMethod = 
LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE;
+        final String rescheduleStrategyMethod = 
LoanProductTestBuilder.RECALCULATION_STRATEGY_ADJUST_LAST_UNPAID_PERIOD;
+        final String preCloseInterestCalculationStrategy = 
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE;
+
+        final Account assetAccount = ACCOUNT_HELPER.createAssetAccount();
+        final Account incomeAccount = ACCOUNT_HELPER.createIncomeAccount();
+        final Account expenseAccount = ACCOUNT_HELPER.createExpenseAccount();
+        final Account overpaymentAccount = 
ACCOUNT_HELPER.createLiabilityAccount();
+
+        String futureInstallmentAllocationRule = "NEXT_INSTALLMENT";
+        AdvancedPaymentData defaultAllocation = 
createDefaultPaymentAllocation(futureInstallmentAllocationRule);
+        String loanProductJSON = new 
LoanProductTestBuilder().withPrincipal(loanPrincipalAmount).withNumberOfRepayments(numberOfRepayments)
+                
.withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod(interestRatePerPeriod)
+                
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
+                .withAccountingRulePeriodicAccrual(new Account[] { 
assetAccount, incomeAccount, expenseAccount, overpaymentAccount })
+                
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true).addAdvancedPaymentAllocation(defaultAllocation)
+                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL)
+                
.withMultiDisburse().withDisallowExpectedDisbursements(true).withInterestRecalculationDetails(
+                        interestRecalculationCompoundingMethod, 
rescheduleStrategyMethod, preCloseInterestCalculationStrategy)
+                .build();
+
+        loanProductId = 
LOAN_TRANSACTIONAL_HELPER.getLoanProductId(loanProductJSON);
+        LOG.info("Successfully created loan product  (ID:{}) ", loanProductId);
     }
 
-    private static PostLoansResponse applyForLoanApplication(final Long 
clientId, final Integer loanProductId, final BigDecimal principal,
-            final int loanTermFrequency, final int repaymentAfterEvery, final 
int numberOfRepayments, final BigDecimal interestRate,
-            final String expectedDisbursementDate, final String 
submittedOnDate, final String externalId) {
-        return applyForLoanApplication(clientId, loanProductId, principal, 
loanTermFrequency, repaymentAfterEvery, numberOfRepayments,
-                interestRate, expectedDisbursementDate, submittedOnDate, 
LoanScheduleProcessingType.HORIZONTAL, externalId);
+    /**
+     * submit a new loan application, approve and disburse the loan
+     **/
+    private void createLoanEntity() {
+        LOG.info("---------------------------------NEW LOAN 
APPLICATION------------------------------------------");
+
+        String loanApplicationJSON = new 
LoanApplicationTestBuilder().withPrincipal(loanPrincipalAmount)
+                
.withLoanTermFrequency(numberOfRepayments).withLoanTermFrequencyAsDays().withNumberOfRepayments(numberOfRepayments)
+                
.withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsDays().withInterestRatePerPeriod(interestRatePerPeriod)
+                
.withInterestTypeAsFlatBalance().withAmortizationTypeAsEqualPrincipalPayments()
+                
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withExpectedDisbursementDate(dateString)
+                
.withSubmittedOnDate(dateString).withLoanType("individual").withExternalId(externalId)
+                
.withRepaymentStrategy("advanced-payment-allocation-strategy").build(clientId.toString(),
 loanProductId.toString(), null);
+
+        loanId = LOAN_TRANSACTIONAL_HELPER.getLoanId(loanApplicationJSON);
+
+        LOG.info("Sucessfully created loan (ID: {} )", loanId);
+
+        approveLoanApplication();
+        disburseLoan();
     }
 
-    private static PostLoansResponse applyForLoanApplication(final Long 
clientId, final Integer loanProductId, final BigDecimal principal,
-            final int loanTermFrequency, final int repaymentAfterEvery, final 
int numberOfRepayments, final BigDecimal interestRate,
-            final String expectedDisbursementDate, final String 
submittedOnDate, LoanScheduleProcessingType loanScheduleProcessingType,
-            final String externalId) {
-        LOG.info("--------------------------------APPLYING FOR LOAN 
APPLICATION--------------------------------");
-        return applyForLoanApplication(clientId, loanProductId, principal, 
loanTermFrequency, repaymentAfterEvery, numberOfRepayments,
-                interestRate, expectedDisbursementDate, submittedOnDate,
-                
AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY,
 loanScheduleProcessingType.name(),
-                externalId);
+    /**
+     * approve the loan application
+     **/
+    private void approveLoanApplication() {
+
+        if (loanId != null) {
+            LOAN_TRANSACTIONAL_HELPER.approveLoan(dateString, loanId);
+            LOG.info("Successfully approved loan (ID: {} )", loanId);
+        }
     }
 
-    private static PostLoansResponse applyForLoanApplication(final Long 
clientId, final Integer loanProductId, final BigDecimal principal,
-            final int loanTermFrequency, final int repaymentAfterEvery, final 
int numberOfRepayments, final BigDecimal interestRate,
-            final String expectedDisbursementDate, final String 
submittedOnDate, String transactionProcessorCode,
-            String loanScheduleProcessingType, final String externalId) {
-        LOG.info("--------------------------------APPLYING FOR LOAN 
APPLICATION--------------------------------");
-        return LOAN_TRANSACTIONAL_HELPER.applyLoan(new 
PostLoansRequest().clientId(clientId).productId(loanProductId.longValue())
-                
.expectedDisbursementDate(expectedDisbursementDate).dateFormat(DATETIME_PATTERN)
-                
.transactionProcessingStrategyCode(transactionProcessorCode).locale("en").submittedOnDate(submittedOnDate)
-                
.amortizationType(1).interestRatePerPeriod(interestRate).interestCalculationPeriodType(1).interestType(0)
-                
.repaymentFrequencyType(0).repaymentEvery(repaymentAfterEvery).repaymentFrequencyType(0)
-                
.numberOfRepayments(numberOfRepayments).loanTermFrequency(loanTermFrequency).loanTermFrequencyType(0).principal(principal)
-                
.loanType("individual").loanScheduleProcessingType(loanScheduleProcessingType).externalId(externalId)
-                .maxOutstandingLoanBalance(BigDecimal.valueOf(35000)));
+    /**
+     * disburse the newly created loan
+     **/
+    private void disburseLoan() {
+
+        if (loanId != null) {
+            LOAN_TRANSACTIONAL_HELPER.disburseLoan(externalId, new 
PostLoansLoanIdRequest().actualDisbursementDate(dateString)
+                    .transactionAmount(new 
BigDecimal(loanPrincipalAmount)).locale("en").dateFormat("dd MMMM yyyy"));
+            LOG.info("Successfully disbursed loan (ID: {} )", loanId);
+        }
     }
 }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index 40116b9ae..507d789fe 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -66,6 +66,7 @@ public class LoanProductTestBuilder {
     public static final String 
RECALCULATION_STRATEGY_RESCHEDULE_NEXT_REPAYMENTS = "1";
     public static final String 
RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS = "2";
     public static final String RECALCULATION_STRATEGY_REDUCE_EMI_AMOUN = "3";
+    public static final String 
RECALCULATION_STRATEGY_ADJUST_LAST_UNPAID_PERIOD = "4";
 
     public static final String RECALCULATION_COMPOUNDING_METHOD_NONE = "0";
     public static final String RECALCULATION_COMPOUNDING_METHOD_INTEREST = "1";
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
index 8785ec626..52e222d65 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
@@ -609,7 +609,7 @@ public class LoanTransactionHelper extends IntegrationTest {
     }
 
     public PostLoansLoanIdTransactionsResponse 
createInterestPauseByLoanId(final String startDate, final String endDate,
-            final String dateFormat, final String locale, final Long loanID) {
+            final String dateFormat, final String locale, final Integer 
loanID) {
         log.info("Creating interest pause for Loan {} from {} to {} with 
dateFormat {} and locale {}", loanID, startDate, endDate,
                 dateFormat, locale);
         String body = getInterestPauseBodyAsJSON(startDate, endDate, 
dateFormat, locale);
@@ -624,7 +624,20 @@ public class LoanTransactionHelper extends IntegrationTest 
{
         return postLoanTransaction(createInterestPause(INTEREST_PAUSE_COMMAND, 
externalId), body);
     }
 
-    public String retrieveInterestPauseByLoanId(final Long loanID) {
+    public PostLoansLoanIdTransactionsResponse 
updateInterestPauseByLoanId(final Long termVariationId, final String startDate,
+            final String endDate, final String dateFormat, final String 
locale, final Integer loanID) {
+        log.info("Updating interest pause for Loan {} with Term Variation ID 
{}: startDate={} endDate={} dateFormat={} locale={}", loanID,
+                termVariationId, startDate, endDate, dateFormat, locale);
+        String body = getInterestPauseBodyAsJSON(startDate, endDate, 
dateFormat, locale);
+        return putLoanTransaction(updateInterestPause(termVariationId, 
loanID), body);
+    }
+
+    public void deleteInterestPauseByLoanId(final Long termVariationId, final 
Integer loanID) {
+        log.info("Deleting interest pause for Loan ID {} with Term Variation 
ID {}", loanID, termVariationId);
+        deleteLoanTransaction(deleteInterestPause(termVariationId, loanID));
+    }
+
+    public String retrieveInterestPauseByLoanId(final Integer loanID) {
         log.info("Retrieving interest pauses for Loan ID {}", loanID);
         String url = retrieveInterestPause(loanID);
         return Utils.performServerGet(requestSpec, responseSpec, url);
@@ -1450,7 +1463,7 @@ public class LoanTransactionHelper extends 
IntegrationTest {
         return "/fineract-provider/api/v1/loans/" + loanID + 
"/transactions?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
     }
 
-    private String createInterestPause(final String command, final Long 
loanID) {
+    private String createInterestPause(final String command, final Integer 
loanID) {
         return "/fineract-provider/api/v1/loans/" + loanID + 
"/interest-pauses?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
     }
 
@@ -1459,7 +1472,7 @@ public class LoanTransactionHelper extends 
IntegrationTest {
                 + Utils.TENANT_IDENTIFIER;
     }
 
-    private String retrieveInterestPause(final Long loanID) {
+    private String retrieveInterestPause(final Integer loanID) {
         return "/fineract-provider/api/v1/loans/" + loanID + 
"/interest-pauses?" + Utils.TENANT_IDENTIFIER;
     }
 
@@ -1467,6 +1480,14 @@ public class LoanTransactionHelper extends 
IntegrationTest {
         return "/fineract-provider/api/v1/loans/external-id/" + externalId + 
"/interest-pauses?" + Utils.TENANT_IDENTIFIER;
     }
 
+    private String updateInterestPause(final Long termVariationId, final 
Integer loanID) {
+        return "/fineract-provider/api/v1/loans/" + loanID + 
"/interest-pauses/" + termVariationId + "?" + Utils.TENANT_IDENTIFIER;
+    }
+
+    private String deleteInterestPause(final Long termVariationId, final 
Integer loanID) {
+        return "/fineract-provider/api/v1/loans/" + loanID + 
"/interest-pauses/" + termVariationId + "?" + Utils.TENANT_IDENTIFIER;
+    }
+
     private String createInteroperationLoanTransactionURL(final String 
accountNo) {
         return "/fineract-provider/api/v1/interoperation/transactions/" + 
accountNo + "/loanrepayment";
     }
@@ -1513,6 +1534,15 @@ public class LoanTransactionHelper extends 
IntegrationTest {
         return GSON.fromJson(response, 
PostLoansLoanIdTransactionsResponse.class);
     }
 
+    private PostLoansLoanIdTransactionsResponse putLoanTransaction(final 
String putURLForLoanTransaction, final String jsonToBeSent) {
+        final String response = Utils.performServerPut(this.requestSpec, 
this.responseSpec, putURLForLoanTransaction, jsonToBeSent);
+        return GSON.fromJson(response, 
PostLoansLoanIdTransactionsResponse.class);
+    }
+
+    private void deleteLoanTransaction(final String 
deleteURLForLoanTransaction) {
+        Utils.performServerDelete(this.requestSpec, this.responseSpec, 
deleteURLForLoanTransaction, null);
+    }
+
     private Object performLoanTransaction(final String 
postURLForLoanTransaction, final String jsonToBeSent,
             ResponseSpecification responseValidationError) {
 

Reply via email to