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

commit 87cad91aa857e6f6b402f1991562c54c12e63aad
Author: Attila Budai <[email protected]>
AuthorDate: Tue Jan 20 01:42:17 2026 +0100

    FINERACT-2418: add origination-api-skeleton
---
 .../src/main/avro/loan/v1/LoanAccountDataV1.avsc   |  11 ++
 .../main/avro/loan/v1/LoanTransactionDataV1.avsc   |  12 ++
 .../src/main/avro/loan/v1/OriginatorDetailsV1.avsc |  62 +++++++
 .../commands/service/CommandWrapperBuilder.java    |  23 +++
 .../test/stepdef/common/BatchApiStepDef.java       |   2 +-
 .../fineract/test/stepdef/common/UserStepDef.java  |   2 +-
 .../test/stepdef/loan/LoanRepaymentStepDef.java    |   4 +-
 .../api/LoanOriginatorApiConstants.java            |  51 ++++++
 .../api/LoanOriginatorApiResource.java             | 190 +++++++++++++++++++++
 .../LoanOriginatorData.java}                       |  40 ++---
 .../data/LoanOriginatorRequestData.java            |  53 ++++++
 .../domain/LoanOriginatorStatus.java               |   2 +-
 .../LoanOriginatorReadPlatformService.java}        |  26 +--
 .../LoanOriginatorReadPlatformServiceImpl.java     |  51 ++++++
 .../LoanOriginatorWritePlatformService.java}       |  26 +--
 .../loanaccount/api/LoanApiConstants.java          |   2 +
 .../mapper/loan/LoanAccountDataMapper.java         |   1 +
 .../mapper/loan/LoanTransactionDataMapper.java     |   1 +
 .../loanaccount/api/LoansApiResourceSwagger.java   |  53 ++++++
 .../serialization/LoanApplicationValidator.java    |   2 +-
 .../integrationtests/BaseLoanIntegrationTest.java  |   2 +-
 .../SavingsAccountsExternalIdTest.java             |  10 +-
 .../integrationtests/UserAdministrationTest.java   |  12 +-
 .../savings/SavingsTestLifecycleExtension.java     |   2 +-
 .../savings/base/BaseSavingsIntegrationTest.java   |   8 +-
 25 files changed, 568 insertions(+), 80 deletions(-)

diff --git a/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc 
b/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc
index 8966f19a01..de0455b0f1 100644
--- a/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc
+++ b/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc
@@ -842,6 +842,17 @@
                     "type": "map"
                 }
             ]
+        },
+        {
+            "default": null,
+            "name": "originators",
+            "type": [
+                "null",
+                {
+                    "type": "array",
+                    "items": 
"org.apache.fineract.avro.loan.v1.OriginatorDetailsV1"
+                }
+            ]
         }
     ]
 }
diff --git 
a/fineract-avro-schemas/src/main/avro/loan/v1/LoanTransactionDataV1.avsc 
b/fineract-avro-schemas/src/main/avro/loan/v1/LoanTransactionDataV1.avsc
index 2b59fd23a9..f02d6e090a 100644
--- a/fineract-avro-schemas/src/main/avro/loan/v1/LoanTransactionDataV1.avsc
+++ b/fineract-avro-schemas/src/main/avro/loan/v1/LoanTransactionDataV1.avsc
@@ -271,6 +271,18 @@
                 "null",
                 "org.apache.fineract.avro.generic.v1.CodeValueDataV1"
             ]
+        },
+        {
+            "default": null,
+            "name": "originators",
+            "doc": "List of originators attached to the parent loan for 
revenue sharing",
+            "type": [
+                "null",
+                {
+                    "type": "array",
+                    "items": 
"org.apache.fineract.avro.loan.v1.OriginatorDetailsV1"
+                }
+            ]
         }
     ]
 }
diff --git 
a/fineract-avro-schemas/src/main/avro/loan/v1/OriginatorDetailsV1.avsc 
b/fineract-avro-schemas/src/main/avro/loan/v1/OriginatorDetailsV1.avsc
new file mode 100644
index 0000000000..37d406b7d9
--- /dev/null
+++ b/fineract-avro-schemas/src/main/avro/loan/v1/OriginatorDetailsV1.avsc
@@ -0,0 +1,62 @@
+{
+    "name": "OriginatorDetailsV1",
+    "namespace": "org.apache.fineract.avro.loan.v1",
+    "doc": "Loan originator details for revenue sharing and reporting",
+    "type": "record",
+    "fields": [
+        {
+            "default": null,
+            "name": "id",
+            "doc": "Internal originator ID",
+            "type": [
+                "null",
+                "long"
+            ]
+        },
+        {
+            "default": null,
+            "name": "externalId",
+            "doc": "Unique external identifier (Revenue Share ID)",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "name",
+            "doc": "Originator name",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "status",
+            "doc": "Originator status: ACTIVE, PENDING, or INACTIVE",
+            "type": [
+                "null",
+                "string"
+            ]
+        },
+        {
+            "default": null,
+            "name": "originatorType",
+            "doc": "Code value for originator type (MERCHANT, BROKER, 
AFFILIATE, PLATFORM)",
+            "type": [
+                "null",
+                "org.apache.fineract.avro.generic.v1.CodeValueDataV1"
+            ]
+        },
+        {
+            "default": null,
+            "name": "channelType",
+            "doc": "Code value for channel type (ONLINE, IN_STORE, API, 
AGGREGATOR)",
+            "type": [
+                "null",
+                "org.apache.fineract.avro.generic.v1.CodeValueDataV1"
+            ]
+        }
+    ]
+}
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 d2453dd9c5..ff96583fb5 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
@@ -3929,4 +3929,27 @@ public class CommandWrapperBuilder {
         this.href = "/loans/" + loanId;
         return this;
     }
+
+    public CommandWrapperBuilder createLoanOriginator() {
+        this.actionName = "CREATE";
+        this.entityName = "LOAN_ORIGINATOR";
+        this.href = "/loan-originators";
+        return this;
+    }
+
+    public CommandWrapperBuilder updateLoanOriginator(final Long originatorId) 
{
+        this.actionName = "UPDATE";
+        this.entityName = "LOAN_ORIGINATOR";
+        this.entityId = originatorId;
+        this.href = "/loan-originators/" + originatorId;
+        return this;
+    }
+
+    public CommandWrapperBuilder deleteLoanOriginator(final Long originatorId) 
{
+        this.actionName = "DELETE";
+        this.entityName = "LOAN_ORIGINATOR";
+        this.entityId = originatorId;
+        this.href = "/loan-originators/" + originatorId;
+        return this;
+    }
 }
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/BatchApiStepDef.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/BatchApiStepDef.java
index 00a9064667..b389dd1909 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/BatchApiStepDef.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/BatchApiStepDef.java
@@ -552,7 +552,7 @@ public class BatchApiStepDef extends AbstractStepDef {
         // Create new user which cannot bypass loan COB execution
         PostUsersResponse createUserResponse = 
testContext().get(TestContextKey.CREATED_SIMPLE_USER_RESPONSE);
         Long createdUserId = createUserResponse.getResourceId();
-        GetUsersUserIdResponse user = 
fineractFeignClient.users().retrieveOne31(createdUserId);
+        GetUsersUserIdResponse user = 
fineractFeignClient.users().retrieveOne32(createdUserId);
         String authorizationString = user.getUsername() + ":" + 
PWD_USER_WITH_ROLE;
         Base64 base64 = new Base64();
         headerMap.put("Authorization",
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/UserStepDef.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/UserStepDef.java
index 534f624e4c..261ddf2c04 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/UserStepDef.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/UserStepDef.java
@@ -68,7 +68,7 @@ public class UserStepDef extends AbstractStepDef {
                 .repeatPassword(PWD_USER_WITH_ROLE) //
                 .roles(List.of(roleId));
 
-        PostUsersResponse createUserResponse = ok(() -> 
fineractClient.users().create15(postUsersRequest));
+        PostUsersResponse createUserResponse = ok(() -> 
fineractClient.users().create16(postUsersRequest));
         testContext().set(TestContextKey.CREATED_SIMPLE_USER_RESPONSE, 
createUserResponse);
         testContext().set(TestContextKey.CREATED_SIMPLE_USER_USERNAME, 
generatedUsername);
         testContext().set(TestContextKey.CREATED_SIMPLE_USER_PASSWORD, 
PWD_USER_WITH_ROLE);
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanRepaymentStepDef.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanRepaymentStepDef.java
index d42734a6f4..25ec08a9b3 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanRepaymentStepDef.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanRepaymentStepDef.java
@@ -145,7 +145,7 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
 
         PostUsersResponse createUserResponse = 
testContext().get(TestContextKey.CREATED_SIMPLE_USER_RESPONSE);
         Long createdUserId = createUserResponse.getResourceId();
-        GetUsersUserIdResponse user = ok(() -> 
fineractClient.users().retrieveOne31(createdUserId));
+        GetUsersUserIdResponse user = ok(() -> 
fineractClient.users().retrieveOne32(createdUserId));
 
         String apiBaseUrl = apiProperties.getBaseUrl() + 
"/fineract-provider/api/";
         FineractFeignClient userClient = 
FineractFeignClient.builder().baseUrl(apiBaseUrl)
@@ -200,7 +200,7 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
 
         PostUsersResponse createUserResponse = 
testContext().get(TestContextKey.CREATED_SIMPLE_USER_RESPONSE);
         Long createdUserId = createUserResponse.getResourceId();
-        GetUsersUserIdResponse user = ok(() -> 
fineractClient.users().retrieveOne31(createdUserId));
+        GetUsersUserIdResponse user = ok(() -> 
fineractClient.users().retrieveOne32(createdUserId));
 
         String apiBaseUrl = apiProperties.getBaseUrl() + 
"/fineract-provider/api/";
         FineractFeignClient userClient = 
FineractFeignClient.builder().baseUrl(apiBaseUrl)
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/api/LoanOriginatorApiConstants.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/api/LoanOriginatorApiConstants.java
new file mode 100644
index 0000000000..52d81ffd56
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/api/LoanOriginatorApiConstants.java
@@ -0,0 +1,51 @@
+/**
+ * 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.portfolio.loanorigination.api;
+
+import java.util.Set;
+
+public final class LoanOriginatorApiConstants {
+
+    private LoanOriginatorApiConstants() {}
+
+    public static final String RESOURCE_NAME = "LOAN_ORIGINATOR";
+    public static final String RESOURCE_PATH = "/loan-originators";
+
+    public static final String ACTION_CREATE = "CREATE";
+    public static final String ACTION_UPDATE = "UPDATE";
+    public static final String ACTION_DELETE = "DELETE";
+
+    public static final String ORIGINATOR_TYPE_CODE_NAME = 
"LoanOriginatorType";
+    public static final String CHANNEL_TYPE_CODE_NAME = 
"LoanOriginationChannelType";
+
+    public static final String EXTERNAL_ID_PARAM = "externalId";
+    public static final String NAME_PARAM = "name";
+    public static final String STATUS_PARAM = "status";
+    public static final String ORIGINATOR_TYPE_ID_PARAM = "originatorTypeId";
+    public static final String CHANNEL_TYPE_ID_PARAM = "channelTypeId";
+
+    public static final Set<String> CREATE_REQUEST_PARAMS = 
Set.of(EXTERNAL_ID_PARAM, NAME_PARAM, STATUS_PARAM, ORIGINATOR_TYPE_ID_PARAM,
+            CHANNEL_TYPE_ID_PARAM);
+
+    public static final Set<String> UPDATE_REQUEST_PARAMS = Set.of(NAME_PARAM, 
STATUS_PARAM, ORIGINATOR_TYPE_ID_PARAM,
+            CHANNEL_TYPE_ID_PARAM);
+
+    public static final Set<String> RESPONSE_PARAMS = Set.of("id", 
EXTERNAL_ID_PARAM, NAME_PARAM, STATUS_PARAM, ORIGINATOR_TYPE_ID_PARAM,
+            CHANNEL_TYPE_ID_PARAM);
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/api/LoanOriginatorApiResource.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/api/LoanOriginatorApiResource.java
new file mode 100644
index 0000000000..4122eef6ef
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/api/LoanOriginatorApiResource.java
@@ -0,0 +1,190 @@
+/**
+ * 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.portfolio.loanorigination.api;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+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.Context;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.UriInfo;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import 
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import 
org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import 
org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.apache.fineract.portfolio.loanorigination.data.LoanOriginatorData;
+import 
org.apache.fineract.portfolio.loanorigination.service.LoanOriginatorReadPlatformService;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+@Path("/v1/loan-originators")
+@Component
+@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", 
havingValue = "true")
+@Tag(name = "Loan Originators", description = "Manage loan originator details 
for revenue sharing and reporting")
+@RequiredArgsConstructor
+public class LoanOriginatorApiResource {
+
+    private final PlatformSecurityContext context;
+    private final LoanOriginatorReadPlatformService 
loanOriginatorReadPlatformService;
+    private final DefaultToApiJsonSerializer<LoanOriginatorData> 
toApiJsonSerializer;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
+
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Create a new loan originator", description = 
"Creates a new loan originator record. Requires CREATE_LOAN_ORIGINATOR 
permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "400", description = "Required parameter is 
missing or incorrect format")
+    @ApiResponse(responseCode = "403", description = "Duplicate external ID or 
insufficient permissions")
+    public String create(@Parameter(hidden = true) final String 
apiRequestBodyAsJson) {
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().createLoanOriginator().withJson(apiRequestBodyAsJson).build();
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @GET
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "List all loan originators", description = "Retrieves 
all loan originator records. Requires READ_LOAN_ORIGINATOR permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "403", description = "Insufficient 
permissions")
+    public String retrieveAll(@Context final UriInfo uriInfo) {
+        
this.context.authenticatedUser().validateHasReadPermission(LoanOriginatorApiConstants.RESOURCE_NAME);
+
+        final List<LoanOriginatorData> originators = 
this.loanOriginatorReadPlatformService.retrieveAll();
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, originators, 
LoanOriginatorApiConstants.RESPONSE_PARAMS);
+    }
+
+    @GET
+    @Path("{originatorId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Retrieve a loan originator by ID", description = 
"Retrieves a loan originator by its internal ID. Requires READ_LOAN_ORIGINATOR 
permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "403", description = "Insufficient 
permissions")
+    @ApiResponse(responseCode = "404", description = "Originator not found")
+    public String retrieveOne(@PathParam("originatorId") 
@Parameter(description = "originatorId") final Long originatorId,
+            @Context final UriInfo uriInfo) {
+        
this.context.authenticatedUser().validateHasReadPermission(LoanOriginatorApiConstants.RESOURCE_NAME);
+
+        final LoanOriginatorData originator = 
this.loanOriginatorReadPlatformService.retrieveById(originatorId);
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, originator, 
LoanOriginatorApiConstants.RESPONSE_PARAMS);
+    }
+
+    @GET
+    @Path("external-id/{externalId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Retrieve a loan originator by external ID", 
description = "Retrieves a loan originator by its external ID. Requires 
READ_LOAN_ORIGINATOR permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "403", description = "Insufficient 
permissions")
+    @ApiResponse(responseCode = "404", description = "Originator not found")
+    public String retrieveByExternalId(@PathParam("externalId") 
@Parameter(description = "externalId") final String externalId,
+            @Context final UriInfo uriInfo) {
+        
this.context.authenticatedUser().validateHasReadPermission(LoanOriginatorApiConstants.RESOURCE_NAME);
+
+        final LoanOriginatorData originator = 
this.loanOriginatorReadPlatformService.retrieveByExternalId(externalId);
+        final ApiRequestJsonSerializationSettings settings = 
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, originator, 
LoanOriginatorApiConstants.RESPONSE_PARAMS);
+    }
+
+    @PUT
+    @Path("{originatorId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Update a loan originator by ID", description = 
"Updates a loan originator by its internal ID. Requires UPDATE_LOAN_ORIGINATOR 
permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "400", description = "Incorrect format")
+    @ApiResponse(responseCode = "403", description = "Insufficient 
permissions")
+    @ApiResponse(responseCode = "404", description = "Originator not found")
+    public String update(@PathParam("originatorId") @Parameter(description = 
"originatorId") final Long originatorId,
+            @Parameter(hidden = true) final String apiRequestBodyAsJson) {
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().updateLoanOriginator(originatorId).withJson(apiRequestBodyAsJson)
+                .build();
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @PUT
+    @Path("external-id/{externalId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Update a loan originator by external ID", 
description = "Updates a loan originator by its external ID. Requires 
UPDATE_LOAN_ORIGINATOR permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "400", description = "Incorrect format")
+    @ApiResponse(responseCode = "403", description = "Insufficient 
permissions")
+    @ApiResponse(responseCode = "404", description = "Originator not found")
+    public String updateByExternalId(@PathParam("externalId") 
@Parameter(description = "externalId") final String externalId,
+            @Parameter(hidden = true) final String apiRequestBodyAsJson) {
+        final Long originatorId = 
this.loanOriginatorReadPlatformService.resolveIdByExternalId(externalId);
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().updateLoanOriginator(originatorId).withJson(apiRequestBodyAsJson)
+                .build();
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @DELETE
+    @Path("{originatorId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Delete a loan originator by ID", description = 
"Deletes a loan originator by its internal ID. Requires DELETE_LOAN_ORIGINATOR 
permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "403", description = "Originator is mapped to 
loans and cannot be deleted, or insufficient permissions")
+    @ApiResponse(responseCode = "404", description = "Originator not found")
+    public String delete(@PathParam("originatorId") @Parameter(description = 
"originatorId") final Long originatorId) {
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().deleteLoanOriginator(originatorId).build();
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+
+    @DELETE
+    @Path("external-id/{externalId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Delete a loan originator by external ID", 
description = "Deletes a loan originator by its external ID. Requires 
DELETE_LOAN_ORIGINATOR permission.")
+    @ApiResponse(responseCode = "200", description = "OK")
+    @ApiResponse(responseCode = "403", description = "Originator is mapped to 
loans and cannot be deleted, or insufficient permissions")
+    @ApiResponse(responseCode = "404", description = "Originator not found")
+    public String deleteByExternalId(@PathParam("externalId") 
@Parameter(description = "externalId") final String externalId) {
+        final Long originatorId = 
this.loanOriginatorReadPlatformService.resolveIdByExternalId(externalId);
+
+        final CommandWrapper commandRequest = new 
CommandWrapperBuilder().deleteLoanOriginator(originatorId).build();
+        final CommandProcessingResult result = 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toApiJsonSerializer.serialize(result);
+    }
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/data/LoanOriginatorData.java
similarity index 55%
copy from 
fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
copy to 
fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/data/LoanOriginatorData.java
index 45eaba37d9..35fbfc55a4 100644
--- 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/data/LoanOriginatorData.java
@@ -16,28 +16,28 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.loanorigination.domain;
+package org.apache.fineract.portfolio.loanorigination.data;
 
-public enum LoanOriginatorStatus {
+import java.io.Serial;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-    ACTIVE("ACTIVE"), PENDING("PENDING");
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class LoanOriginatorData implements Serializable {
 
-    private final String value;
+    @Serial
+    private static final long serialVersionUID = 1L;
 
-    LoanOriginatorStatus(String value) {
-        this.value = value;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public static LoanOriginatorStatus fromString(String text) {
-        for (LoanOriginatorStatus status : LoanOriginatorStatus.values()) {
-            if (status.value.equalsIgnoreCase(text)) {
-                return status;
-            }
-        }
-        throw new IllegalArgumentException("Unknown LoanOriginatorStatus: " + 
text);
-    }
+    private Long id;
+    private String externalId;
+    private String name;
+    private String status;
+    private Long originatorTypeId;
+    private Long channelTypeId;
 }
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/data/LoanOriginatorRequestData.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/data/LoanOriginatorRequestData.java
new file mode 100644
index 0000000000..9fd6cb6c7c
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/data/LoanOriginatorRequestData.java
@@ -0,0 +1,53 @@
+/**
+ * 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.portfolio.loanorigination.data;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.io.Serial;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Schema(description = "Loan Originator request payload")
+public class LoanOriginatorRequestData implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "Unique external identifier (Revenue Share ID)", 
example = "REV-SHARE-001", required = true)
+    private String externalId;
+
+    @Schema(description = "Originator name", example = "Acme Merchant")
+    private String name;
+
+    @Schema(description = "Originator status", example = "ACTIVE", 
allowableValues = { "ACTIVE", "PENDING", "INACTIVE" })
+    private String status;
+
+    @Schema(description = "Code value ID for originator type (from 
LoanOriginatorType code)", example = "1")
+    private Long originatorTypeId;
+
+    @Schema(description = "Code value ID for channel type (from 
LoanOriginationChannelType code)", example = "2")
+    private Long channelTypeId;
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
index 45eaba37d9..9a97a741ee 100644
--- 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
@@ -20,7 +20,7 @@ package org.apache.fineract.portfolio.loanorigination.domain;
 
 public enum LoanOriginatorStatus {
 
-    ACTIVE("ACTIVE"), PENDING("PENDING");
+    ACTIVE("ACTIVE"), PENDING("PENDING"), INACTIVE("INACTIVE");
 
     private final String value;
 
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorReadPlatformService.java
similarity index 55%
copy from 
fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
copy to 
fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorReadPlatformService.java
index 45eaba37d9..e7a169bf85 100644
--- 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorReadPlatformService.java
@@ -16,28 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.loanorigination.domain;
+package org.apache.fineract.portfolio.loanorigination.service;
 
-public enum LoanOriginatorStatus {
+import java.util.List;
+import org.apache.fineract.portfolio.loanorigination.data.LoanOriginatorData;
 
-    ACTIVE("ACTIVE"), PENDING("PENDING");
+public interface LoanOriginatorReadPlatformService {
 
-    private final String value;
+    List<LoanOriginatorData> retrieveAll();
 
-    LoanOriginatorStatus(String value) {
-        this.value = value;
-    }
+    LoanOriginatorData retrieveById(Long id);
 
-    public String getValue() {
-        return value;
-    }
+    LoanOriginatorData retrieveByExternalId(String externalId);
 
-    public static LoanOriginatorStatus fromString(String text) {
-        for (LoanOriginatorStatus status : LoanOriginatorStatus.values()) {
-            if (status.value.equalsIgnoreCase(text)) {
-                return status;
-            }
-        }
-        throw new IllegalArgumentException("Unknown LoanOriginatorStatus: " + 
text);
-    }
+    Long resolveIdByExternalId(String externalId);
 }
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorReadPlatformServiceImpl.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorReadPlatformServiceImpl.java
new file mode 100644
index 0000000000..dd9f84c3c6
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorReadPlatformServiceImpl.java
@@ -0,0 +1,51 @@
+/**
+ * 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.portfolio.loanorigination.service;
+
+import java.util.List;
+import org.apache.fineract.portfolio.loanorigination.data.LoanOriginatorData;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+@Service
+@ConditionalOnProperty(value = "fineract.module.loan-origination.enabled", 
havingValue = "true")
+public class LoanOriginatorReadPlatformServiceImpl implements 
LoanOriginatorReadPlatformService {
+
+    private static final String NOT_IMPLEMENTED_MESSAGE = "Not implemented 
yet";
+
+    @Override
+    public List<LoanOriginatorData> retrieveAll() {
+        throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE);
+    }
+
+    @Override
+    public LoanOriginatorData retrieveById(Long id) {
+        throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE);
+    }
+
+    @Override
+    public LoanOriginatorData retrieveByExternalId(String externalId) {
+        throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE);
+    }
+
+    @Override
+    public Long resolveIdByExternalId(String externalId) {
+        throw new UnsupportedOperationException(NOT_IMPLEMENTED_MESSAGE);
+    }
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorWritePlatformService.java
similarity index 55%
copy from 
fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
copy to 
fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorWritePlatformService.java
index 45eaba37d9..7bd3f182fe 100644
--- 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/service/LoanOriginatorWritePlatformService.java
@@ -16,28 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.loanorigination.domain;
+package org.apache.fineract.portfolio.loanorigination.service;
 
-public enum LoanOriginatorStatus {
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 
-    ACTIVE("ACTIVE"), PENDING("PENDING");
+public interface LoanOriginatorWritePlatformService {
 
-    private final String value;
+    CommandProcessingResult create(JsonCommand command);
 
-    LoanOriginatorStatus(String value) {
-        this.value = value;
-    }
+    CommandProcessingResult update(Long id, JsonCommand command);
 
-    public String getValue() {
-        return value;
-    }
-
-    public static LoanOriginatorStatus fromString(String text) {
-        for (LoanOriginatorStatus status : LoanOriginatorStatus.values()) {
-            if (status.value.equalsIgnoreCase(text)) {
-                return status;
-            }
-        }
-        throw new IllegalArgumentException("Unknown LoanOriginatorStatus: " + 
text);
-    }
+    CommandProcessingResult delete(Long id);
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java
index ace70a9b59..367dd5b969 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java
@@ -210,4 +210,6 @@ public interface LoanApiConstants {
             LoanTransactionType.REPAYMENT //
     );
 
+    String ORIGINATORS_PARAM = "originators";
+
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
index 73990337d2..9e2b3480a0 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
@@ -39,6 +39,7 @@ public interface LoanAccountDataMapper {
     @Mapping(target = "delinquent.installmentDelinquencyBuckets", ignore = 
true)
     @Mapping(target = "customData", ignore = true)
     @Mapping(target = "product.customData", ignore = true)
+    @Mapping(target = "originators", ignore = true)
     LoanAccountDataV1 map(LoanAccountData source);
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanTransactionDataMapper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanTransactionDataMapper.java
index cf84e0e635..3b0b906ea8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanTransactionDataMapper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanTransactionDataMapper.java
@@ -32,6 +32,7 @@ public interface LoanTransactionDataMapper {
     @Mapping(target = "externalOwnerId", ignore = true)
     @Mapping(target = "customData", ignore = true)
     @Mapping(target = "reversed", expression = "java(isReversed(source))")
+    @Mapping(target = "originators", ignore = true)
     LoanTransactionDataV1 map(LoanTransactionData source);
 
     default boolean isReversed(LoanTransactionData source) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
index 8d97966ca6..1ef9b7ce9b 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
@@ -1128,6 +1128,29 @@ final class LoansApiResourceSwagger {
             public boolean isProcessed;
         }
 
+        @Schema(description = "Originator data associated with the loan")
+        static final class GetLoansLoanIdOriginatorData {
+
+            private GetLoansLoanIdOriginatorData() {}
+
+            @Schema(example = "1")
+            public Long id;
+            @Schema(example = "REV-SHARE-001")
+            public String externalId;
+            @Schema(example = "PP Merchant")
+            public String name;
+            @Schema(example = "ACTIVE")
+            public String status;
+            @Schema(example = "1")
+            public Long originatorTypeId;
+            @Schema(example = "MERCHANT")
+            public String originatorTypeName;
+            @Schema(example = "2")
+            public Long channelTypeId;
+            @Schema(example = "ONLINE")
+            public String channelTypeName;
+        }
+
         @Schema(example = "1")
         public Long id;
         @Schema(example = "95174ff9-1a75-4d72-a413-6f9b1cb988b7")
@@ -1206,6 +1229,8 @@ final class LoansApiResourceSwagger {
         public GetLoansLoanIdDelinquencySummary delinquent;
         @Schema(description = "Set of charges")
         public List<GetLoansLoanIdLoanChargeData> charges;
+        @Schema(description = "List of originators associated with this loan")
+        public List<GetLoansLoanIdOriginatorData> originators;
         public DelinquencyRangeData delinquencyRange;
         @Schema(example = "false")
         public Boolean fraud;
@@ -1399,6 +1424,13 @@ final class LoansApiResourceSwagger {
 
         public List<PostLoansRequestChargeData> charges;
 
+        @Schema(description = """
+                Optional array of originators to associate with this loan. \
+                Each entry can reference an existing originator by 'id' or 
'externalId'. \
+                If the global config 
'enable_originator_creation_during_loan_application' is enabled, \
+                non-existing originators will be auto-created using the 
provided details (name, typeId, channelTypeId).""")
+        public List<PostLoansOriginatorData> originators;
+
         static final class PostLoansRequestChargeData {
 
             private PostLoansRequestChargeData() {}
@@ -1409,6 +1441,27 @@ final class LoansApiResourceSwagger {
             @Schema(example = "1.0")
             public BigDecimal amount;
         }
+
+        @Schema(description = "Originator data for loan creation request")
+        public static final class PostLoansOriginatorData {
+
+            private PostLoansOriginatorData() {}
+
+            @Schema(description = "Originator internal ID (use this OR 
externalId, not both)", example = "1")
+            public Long id;
+
+            @Schema(description = "Originator external ID (use this OR id, not 
both)", example = "REV-SHARE-001")
+            public String externalId;
+
+            @Schema(description = "Originator name (used when creating new 
originator if config enabled)", example = "PP Merchant")
+            public String name;
+
+            @Schema(description = "Code value ID for originator type (from 
LoanOriginatorType code)", example = "1")
+            public Long typeId;
+
+            @Schema(description = "Code value ID for channel type (from 
LoanOriginationChannelType code)", example = "2")
+            public Long channelTypeId;
+        }
     }
 
     @Schema(description = "PostLoansResponse")
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationValidator.java
index 6401f9957f..4ee48f71bf 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationValidator.java
@@ -176,7 +176,7 @@ public final class LoanApplicationValidator {
             LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, 
LoanProductConstants.ENABLE_DOWN_PAYMENT,
             LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, 
LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT,
             LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, 
LoanApiConstants.daysInYearCustomStrategyParameterName,
-            LoanApiConstants.ALLOW_FULL_TERM_FOR_TRANCHE));
+            LoanApiConstants.ALLOW_FULL_TERM_FOR_TRANCHE, 
LoanApiConstants.ORIGINATORS_PARAM));
     public static final String LOANAPPLICATION_UNDO = "loanapplication.undo";
 
     private final FromJsonHelper fromApiJsonHelper;
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
index 25cc3ea5ed..6d3f5aab96 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
@@ -374,7 +374,7 @@ public abstract class BaseLoanIntegrationTest extends 
IntegrationTest {
         String password = "AKleRbDhK421$";
         String email = firstname + "." + lastname + "@whatever.mifos.org";
         Calls.ok(fineractClient().users
-                .create15(new 
PostUsersRequest().addRolesItem(roleId).email(email).firstname(firstname).lastname(lastname)
+                .create16(new 
PostUsersRequest().addRolesItem(roleId).email(email).firstname(firstname).lastname(lastname)
                         
.repeatPassword(password).sendPasswordToEmail(false).officeId(1L).username(userName).password(password)));
 
         // login user
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsAccountsExternalIdTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsAccountsExternalIdTest.java
index e16b3883d0..5f9e827740 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsAccountsExternalIdTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsAccountsExternalIdTest.java
@@ -75,7 +75,7 @@ public class SavingsAccountsExternalIdTest extends 
IntegrationTest {
         PutSavingsAccountsAccountIdRequest request = new 
PutSavingsAccountsAccountIdRequest();
         request.setLocale(locale);
         request.setNominalAnnualInterestRate(5.999);
-        Response<PutSavingsAccountsAccountIdResponse> response = 
okR(fineractClient().savingsAccounts.update21(EXTERNAL_ID, request, ""));
+        Response<PutSavingsAccountsAccountIdResponse> response = 
okR(fineractClient().savingsAccounts.update22(EXTERNAL_ID, request, ""));
 
         assertThat(response.isSuccessful()).isTrue();
         assertThat(response.body()).isNotNull();
@@ -104,7 +104,7 @@ public class SavingsAccountsExternalIdTest extends 
IntegrationTest {
         request.dateFormat(dateFormat);
         request.setLocale(locale);
         request.setActivatedOnDate(formattedDate);
-        Response<SavingsAccountData> response = 
okR(fineractClient().savingsAccounts.retrieveOne26(EXTERNAL_ID, false, null, 
"all"));
+        Response<SavingsAccountData> response = 
okR(fineractClient().savingsAccounts.retrieveOne27(EXTERNAL_ID, false, null, 
"all"));
 
         assertThat(response.isSuccessful()).isTrue();
         assertThat(response.body()).isNotNull();
@@ -132,7 +132,7 @@ public class SavingsAccountsExternalIdTest extends 
IntegrationTest {
         request.dateFormat(dateFormat);
         request.setLocale(locale);
         request.setActivatedOnDate(formattedDate);
-        Response<SavingsAccountData> response = 
okR(fineractClient().savingsAccounts.retrieveOne26(EXTERNAL_ID, false, null, 
"all"));
+        Response<SavingsAccountData> response = 
okR(fineractClient().savingsAccounts.retrieveOne27(EXTERNAL_ID, false, null, 
"all"));
 
         assertThat(response.isSuccessful()).isTrue();
         assertThat(response.body()).isNotNull();
@@ -147,7 +147,7 @@ public class SavingsAccountsExternalIdTest extends 
IntegrationTest {
         request.dateFormat(dateFormat);
         request.setLocale(locale);
         request.setActivatedOnDate(formattedDate);
-        Response<DeleteSavingsAccountsAccountIdResponse> response = 
okR(fineractClient().savingsAccounts.delete19(EXTERNAL_ID));
+        Response<DeleteSavingsAccountsAccountIdResponse> response = 
okR(fineractClient().savingsAccounts.delete20(EXTERNAL_ID));
 
         assertThat(response.isSuccessful()).isTrue();
         assertThat(response.body()).isNotNull();
@@ -162,7 +162,7 @@ public class SavingsAccountsExternalIdTest extends 
IntegrationTest {
         request.setLocale(locale);
         request.setActivatedOnDate(formattedDate);
         Response<SavingsAccountData> response = Calls
-                
.executeU(fineractClient().savingsAccounts.retrieveOne26(EXTERNAL_ID, false, 
null, "all"));
+                
.executeU(fineractClient().savingsAccounts.retrieveOne27(EXTERNAL_ID, false, 
null, "all"));
 
         assertThat(response.raw().code()).isEqualTo(404);
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UserAdministrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UserAdministrationTest.java
index 2db29dcf2c..0c2b61e4ab 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UserAdministrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UserAdministrationTest.java
@@ -202,19 +202,19 @@ public class UserAdministrationTest extends 
IntegrationTest {
 
         // User updates its own password
         String updatedPassword = "QwE!5rTy#9uP0u";
-        PutUsersUserIdResponse putUsersUserIdResponse = 
ok(newFineractClient(simpleUsername, originalPassword).users.update26(userId,
+        PutUsersUserIdResponse putUsersUserIdResponse = 
ok(newFineractClient(simpleUsername, originalPassword).users.update27(userId,
                 new 
PutUsersUserIdRequest().password(updatedPassword).repeatPassword(updatedPassword)));
         Assertions.assertNotNull(putUsersUserIdResponse.getResourceId());
 
         // From then on the originalPassword is not working anymore
         CallFailedRuntimeException callFailedRuntimeException = 
Assertions.assertThrows(CallFailedRuntimeException.class, () -> {
-            ok(newFineractClient(simpleUsername, 
originalPassword).users.retrieveOne31(userId));
+            ok(newFineractClient(simpleUsername, 
originalPassword).users.retrieveOne32(userId));
         });
         Assertions.assertEquals(401, 
callFailedRuntimeException.getResponse().raw().code());
         
Assertions.assertTrue(callFailedRuntimeException.getMessage().contains("Unauthorized"));
 
         // The update password is still working perfectly
-        GetUsersUserIdResponse ok = ok(newFineractClient(simpleUsername, 
updatedPassword).users.retrieveOne31(userId));
+        GetUsersUserIdResponse ok = ok(newFineractClient(simpleUsername, 
updatedPassword).users.retrieveOne32(userId));
     }
 
     @Test
@@ -242,13 +242,13 @@ public class UserAdministrationTest extends 
IntegrationTest {
 
         // From then on the originalPassword is not working anymore
         CallFailedRuntimeException callFailedRuntimeException = 
Assertions.assertThrows(CallFailedRuntimeException.class, () -> {
-            ok(newFineractClient(simpleUsername, 
originalPassword).users.retrieveOne31(userId));
+            ok(newFineractClient(simpleUsername, 
originalPassword).users.retrieveOne32(userId));
         });
         Assertions.assertEquals(401, 
callFailedRuntimeException.getResponse().raw().code());
         
Assertions.assertTrue(callFailedRuntimeException.getMessage().contains("Unauthorized"));
 
         // The update password is still working perfectly
-        GetUsersUserIdResponse ok = ok(newFineractClient(simpleUsername, 
updatedPassword).users.retrieveOne31(userId));
+        GetUsersUserIdResponse ok = ok(newFineractClient(simpleUsername, 
updatedPassword).users.retrieveOne32(userId));
     }
 
     @Test
@@ -272,7 +272,7 @@ public class UserAdministrationTest extends IntegrationTest 
{
 
         // User tries to update it's own roles
         CallFailedRuntimeException callFailedRuntimeException = 
Assertions.assertThrows(CallFailedRuntimeException.class, () -> {
-            ok(newFineractClient(simpleUsername, 
password).users.update26(userId,
+            ok(newFineractClient(simpleUsername, 
password).users.update27(userId,
                     new 
PutUsersUserIdRequest().roles(List.of(Long.valueOf(roleId2)))));
         });
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsTestLifecycleExtension.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsTestLifecycleExtension.java
index 38458df811..11bd89e288 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsTestLifecycleExtension.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsTestLifecycleExtension.java
@@ -65,7 +65,7 @@ public class SavingsTestLifecycleExtension implements 
AfterAllCallback {
                 try {
                     
this.savingsAccountHelper.postInterestForSavings(savingsId.intValue());
                     SavingsAccountData savingsAccountData = Calls
-                            
.ok(FineractClientHelper.getFineractClient().savingsAccounts.retrieveOne25(savingsId,
 false, null, "all"));
+                            
.ok(FineractClientHelper.getFineractClient().savingsAccounts.retrieveOne26(savingsId,
 false, null, "all"));
                     BigDecimal accountBalance = 
MathUtil.subtract(savingsAccountData.getSummary().getAvailableBalance(),
                             savingsAccountData.getMinRequiredBalance(), 
MathContext.DECIMAL64);
                     if (accountBalance.compareTo(BigDecimal.ZERO) > 0) {
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/savings/base/BaseSavingsIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/savings/base/BaseSavingsIntegrationTest.java
index 9de4dbbea9..421eed05c6 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/savings/base/BaseSavingsIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/savings/base/BaseSavingsIntegrationTest.java
@@ -128,7 +128,7 @@ public class BaseSavingsIntegrationTest extends 
IntegrationTest {
     }
 
     protected PostSavingsProductsResponse 
createProduct(PostSavingsProductsRequest productsRequest) {
-        return ok(fineractClient().savingsProducts.create13(productsRequest));
+        return ok(fineractClient().savingsProducts.create14(productsRequest));
     }
 
     protected PostSavingsAccountsRequest applySavingsRequest(Long clientId, 
Long productId, String submittedDate) {
@@ -162,11 +162,11 @@ public class BaseSavingsIntegrationTest extends 
IntegrationTest {
     }
 
     protected SavingsAccountData getSavingsAccount(Long savingsId) {
-        return ok(fineractClient().savingsAccounts.retrieveOne25(savingsId, 
false, null, "transactions"));
+        return ok(fineractClient().savingsAccounts.retrieveOne26(savingsId, 
false, null, "transactions"));
     }
 
     protected List<SavingsAccountTransactionData> getTransactions(Long 
savingsId) {
-        return ok(fineractClient().savingsAccounts.retrieveOne25(savingsId, 
false, null, "transactions")).getTransactions();
+        return ok(fineractClient().savingsAccounts.retrieveOne26(savingsId, 
false, null, "transactions")).getTransactions();
     }
 
     protected void verifyNoTransactions(Long savingsId) {
@@ -174,7 +174,7 @@ public class BaseSavingsIntegrationTest extends 
IntegrationTest {
     }
 
     protected void verifyTransactions(Long savingsId, Transaction... 
transactions) {
-        SavingsAccountData savingsDetails = 
ok(fineractClient().savingsAccounts.retrieveOne25(savingsId, false, null, 
"transactions"));
+        SavingsAccountData savingsDetails = 
ok(fineractClient().savingsAccounts.retrieveOne26(savingsId, false, null, 
"transactions"));
         if (transactions == null || transactions.length == 0) {
             Assertions.assertTrue(savingsDetails.getTransactions().isEmpty(), 
"No transaction is expected on savings account " + savingsId);
         } else {

Reply via email to