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 f83ea7ea15 FINERACT-2418: create the loan origination module
f83ea7ea15 is described below

commit f83ea7ea15a51821fc401fa7739f61e64244df90
Author: Attila Budai <[email protected]>
AuthorDate: Tue Jan 13 21:12:20 2026 +0100

    FINERACT-2418: create the loan origination module
---
 build.gradle                                       |   2 +
 .../core/config/FineractProperties.java            |   7 +
 fineract-loan-origination/build.gradle             |  81 ++++
 fineract-loan-origination/dependencies.gradle      |  74 ++++
 .../LoanOriginationModuleIsEnabledCondition.java   |  30 ++
 .../loanorigination/domain/LoanOriginator.java     |  78 ++++
 .../domain/LoanOriginatorMapping.java              |  52 +++
 .../domain/LoanOriginatorMappingRepository.java    |  42 ++
 .../domain/LoanOriginatorRepository.java           |  34 ++
 .../domain/LoanOriginatorStatus.java               |  43 ++
 .../loanorigination/module-changelog-master.xml    |  26 ++
 .../loanorigination/parts/0001_initial_schema.xml  | 436 +++++++++++++++++++++
 .../fineract-loan-origination/persistence.xml      |  47 +++
 fineract-provider/dependencies.gradle              |   1 +
 .../src/main/resources/application.properties      |   1 +
 .../resources/db/changelog/db.changelog-master.xml |   1 +
 .../src/test/resources/application-test.properties |   2 +
 fineract-war/build.gradle                          |   1 +
 settings.gradle                                    |   1 +
 19 files changed, 959 insertions(+)

diff --git a/build.gradle b/build.gradle
index 17cee30737..e38d5dce1f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -37,6 +37,7 @@ buildscript {
                 'fineract-charge',
                 'fineract-rates',
                 'fineract-tax',
+                'fineract-loan-origination',
                 'fineract-loan',
                 'fineract-savings',
                 'fineract-report',
@@ -67,6 +68,7 @@ buildscript {
                 'fineract-charge',
                 'fineract-rates',
                 'fineract-tax',
+                'fineract-loan-origination',
                 'fineract-loan',
                 'fineract-savings',
                 'fineract-report',
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
index 44139b26e7..9730467be0 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
@@ -600,6 +600,7 @@ public class FineractProperties {
 
         private FineractInvestorModuleProperties investor;
         private FineractSelfServiceModuleProperties selfService;
+        private FineractLoanOriginationModuleProperties loanOrigination;
     }
 
     @Getter
@@ -614,6 +615,12 @@ public class FineractProperties {
 
     }
 
+    @Getter
+    @Setter
+    public static class FineractLoanOriginationModuleProperties extends 
AbstractFineractModuleProperties {
+
+    }
+
     @Getter
     @Setter
     public static class FineractSqlValidationProperties {
diff --git a/fineract-loan-origination/build.gradle 
b/fineract-loan-origination/build.gradle
new file mode 100644
index 0000000000..278bed82fe
--- /dev/null
+++ b/fineract-loan-origination/build.gradle
@@ -0,0 +1,81 @@
+/**
+ * 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.
+ */
+description = 'Fineract Loan Origination'
+
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+compileJava {
+    dependsOn ':fineract-avro-schemas:buildJavaSdk'
+}
+
+configurations {
+    providedRuntime // needed for Spring Boot executable WAR
+    providedCompile
+    compile() {
+        exclude module: 'hibernate-entitymanager'
+        exclude module: 'hibernate-validator'
+        exclude module: 'activation'
+        exclude module: 'bcmail-jdk14'
+        exclude module: 'bcprov-jdk14'
+        exclude module: 'bctsp-jdk14'
+        exclude module: 'c3p0'
+        exclude module: 'stax-api'
+        exclude module: 'jaxb-api'
+        exclude module: 'jaxb-impl'
+        exclude module: 'jboss-logging'
+        exclude module: 'itext-rtf'
+        exclude module: 'classworlds'
+    }
+    runtime
+}
+
+apply from: 'dependencies.gradle'
+
+// Configuration for the modernizer plugin
+// https://github.com/andygoossens/gradle-modernizer-plugin
+modernizer {
+    ignoreClassNamePatterns = [
+        '.*AbstractPersistableCustom',
+        '.*EntityTables',
+        '.*domain.*'
+    ]
+}
+
+// If we are running Gradle within Eclipse to enhance classes with OpenJPA,
+// set the classes directory to point to Eclipse's default build directory
+if (project.hasProperty('env') && project.getProperty('env') == 'eclipse') {
+    sourceSets.main.java.outputDir = new File(rootProject.projectDir, 
"fineract-loan-origination/bin/main")
+}
+
+eclipse {
+    project {
+        buildCommand([ LaunchConfigHandle: 
"<project>/.externalToolBuilders/OpenJPA Enhance Builder.launch" ],  
'org.eclipse.ui.externaltools.ExternalToolBuilder')
+    }
+}
+
+if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) {
+    sourceSets {
+        test {
+            java {
+                exclude '**/core/boot/tests/**'
+            }
+        }
+    }
+}
diff --git a/fineract-loan-origination/dependencies.gradle 
b/fineract-loan-origination/dependencies.gradle
new file mode 100644
index 0000000000..bd2a15867e
--- /dev/null
+++ b/fineract-loan-origination/dependencies.gradle
@@ -0,0 +1,74 @@
+/**
+ * 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.
+ */
+
+dependencies {
+    // Never use "compile" scope, but make all dependencies either 
'implementation', 'runtimeOnly' or 'testCompile'.
+    // Note that we never use 'api', because Fineract at least currently is a 
simple monolithic application ("WAR"), not a library.
+    // We also (normally should have) no need to ever use 'compileOnly'.
+
+    // implementation dependencies are directly used (compiled against) in 
src/main (and src/test)
+    //
+    implementation(project(path: ':fineract-core'))
+
+    implementation(
+            'org.springframework.boot:spring-boot-starter-web',
+            'org.springframework.boot:spring-boot-starter-security',
+            'jakarta.ws.rs:jakarta.ws.rs-api',
+            'org.glassfish.jersey.media:jersey-media-multipart',
+
+            'com.google.guava:guava',
+            'com.google.code.gson:gson',
+
+            'org.apache.commons:commons-lang3',
+
+            'com.jayway.jsonpath:json-path',
+
+            'com.github.spotbugs:spotbugs-annotations',
+            'io.swagger.core.v3:swagger-annotations-jakarta',
+
+            'com.squareup.retrofit2:converter-gson',
+
+            'org.springdoc:springdoc-openapi-starter-webmvc-ui',
+            'org.mapstruct:mapstruct',
+
+            'io.github.resilience4j:resilience4j-spring-boot3',
+            'org.apache.httpcomponents:httpcore',
+            )
+    compileOnly 'org.projectlombok:lombok'
+    annotationProcessor 'org.projectlombok:lombok'
+    annotationProcessor 'org.mapstruct:mapstruct-processor'
+    implementation ('org.springframework.boot:spring-boot-starter-data-jpa') {
+        exclude group: 'org.hibernate'
+    }
+    implementation('org.eclipse.persistence:org.eclipse.persistence.jpa') {
+        exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence'
+    }
+    // testCompile dependencies are ONLY used in src/test, not src/main.
+    // Do NOT repeat dependencies which are ALREADY in implementation or 
runtimeOnly!
+    //
+    testImplementation( 'io.github.classgraph:classgraph' )
+    testImplementation ('org.springframework.boot:spring-boot-starter-test') {
+        exclude group: 'com.jayway.jsonpath', module: 'json-path'
+        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
+        exclude group: 'jakarta.activation'
+        exclude group: 'javax.activation'
+        exclude group: 'org.skyscreamer'
+    }
+    testImplementation ('org.mockito:mockito-inline')
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/config/LoanOriginationModuleIsEnabledCondition.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/config/LoanOriginationModuleIsEnabledCondition.java
new file mode 100644
index 0000000000..cab4484565
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/config/LoanOriginationModuleIsEnabledCondition.java
@@ -0,0 +1,30 @@
+/**
+ * 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.config;
+
+import org.apache.fineract.infrastructure.core.condition.PropertiesCondition;
+import org.apache.fineract.infrastructure.core.config.FineractProperties;
+
+public class LoanOriginationModuleIsEnabledCondition extends 
PropertiesCondition {
+
+    @Override
+    protected boolean matches(FineractProperties properties) {
+        return properties.getModule().getLoanOrigination().isEnabled();
+    }
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginator.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginator.java
new file mode 100644
index 0000000000..1bcb31d8e2
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginator.java
@@ -0,0 +1,78 @@
+/**
+ * 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.domain;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.apache.fineract.infrastructure.codes.domain.CodeValue;
+import 
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
+import org.apache.fineract.infrastructure.core.domain.ExternalId;
+
+@Getter
+@Setter
+@Entity
+@NoArgsConstructor
+@Table(name = "m_loan_originator")
+public class LoanOriginator extends 
AbstractAuditableWithUTCDateTimeCustom<Long> {
+
+    @Column(name = "external_id", nullable = false, length = 100, unique = 
true)
+    private ExternalId externalId;
+
+    @Column(name = "name", length = 255)
+    private String name;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "status", nullable = false, length = 20)
+    private LoanOriginatorStatus status;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "originator_type_cv_id")
+    private CodeValue originatorType;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "channel_type_cv_id")
+    private CodeValue channelType;
+
+    public static LoanOriginator create(ExternalId externalId, String name, 
LoanOriginatorStatus status, CodeValue originatorType,
+            CodeValue channelType) {
+        LoanOriginator originator = new LoanOriginator();
+        originator.setExternalId(externalId);
+        originator.setName(name);
+        originator.setStatus(status);
+        originator.setOriginatorType(originatorType);
+        originator.setChannelType(channelType);
+        return originator;
+    }
+
+    public void update(String name, LoanOriginatorStatus status, CodeValue 
originatorType, CodeValue channelType) {
+        this.name = name;
+        this.status = status;
+        this.originatorType = originatorType;
+        this.channelType = channelType;
+    }
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorMapping.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorMapping.java
new file mode 100644
index 0000000000..79f29bf19b
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorMapping.java
@@ -0,0 +1,52 @@
+/**
+ * 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.domain;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import 
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
+
+@Getter
+@Setter
+@Entity
+@NoArgsConstructor
+@Table(name = "m_loan_originator_mapping")
+public class LoanOriginatorMapping extends 
AbstractAuditableWithUTCDateTimeCustom<Long> {
+
+    @Column(name = "loan_id", nullable = false)
+    private Long loanId;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "originator_id", nullable = false)
+    private LoanOriginator originator;
+
+    public static LoanOriginatorMapping create(Long loanId, LoanOriginator 
originator) {
+        LoanOriginatorMapping mapping = new LoanOriginatorMapping();
+        mapping.setLoanId(loanId);
+        mapping.setOriginator(originator);
+        return mapping;
+    }
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorMappingRepository.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorMappingRepository.java
new file mode 100644
index 0000000000..c3e6e1af3b
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorMappingRepository.java
@@ -0,0 +1,42 @@
+/**
+ * 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.domain;
+
+import java.util.List;
+import java.util.Optional;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+public interface LoanOriginatorMappingRepository
+        extends JpaRepository<LoanOriginatorMapping, Long>, 
JpaSpecificationExecutor<LoanOriginatorMapping> {
+
+    List<LoanOriginatorMapping> findByLoanId(Long loanId);
+
+    boolean existsByLoanId(Long loanId);
+
+    boolean existsByOriginatorId(Long originatorId);
+
+    List<LoanOriginatorMapping> findByOriginatorId(Long originatorId);
+
+    Optional<LoanOriginatorMapping> findByLoanIdAndOriginatorId(Long loanId, 
Long originatorId);
+
+    boolean existsByLoanIdAndOriginatorId(Long loanId, Long originatorId);
+
+    void deleteByLoanIdAndOriginatorId(Long loanId, Long originatorId);
+}
diff --git 
a/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorRepository.java
 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorRepository.java
new file mode 100644
index 0000000000..09c2969240
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorRepository.java
@@ -0,0 +1,34 @@
+/**
+ * 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.domain;
+
+import java.util.List;
+import java.util.Optional;
+import org.apache.fineract.infrastructure.core.domain.ExternalId;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+public interface LoanOriginatorRepository extends 
JpaRepository<LoanOriginator, Long>, JpaSpecificationExecutor<LoanOriginator> {
+
+    Optional<LoanOriginator> findByExternalId(ExternalId externalId);
+
+    boolean existsByExternalId(ExternalId externalId);
+
+    List<LoanOriginator> findByStatus(LoanOriginatorStatus status);
+}
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
new file mode 100644
index 0000000000..45eaba37d9
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/java/org/apache/fineract/portfolio/loanorigination/domain/LoanOriginatorStatus.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.loanorigination.domain;
+
+public enum LoanOriginatorStatus {
+
+    ACTIVE("ACTIVE"), PENDING("PENDING");
+
+    private final String value;
+
+    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);
+    }
+}
diff --git 
a/fineract-loan-origination/src/main/resources/db/changelog/tenant/module/loanorigination/module-changelog-master.xml
 
b/fineract-loan-origination/src/main/resources/db/changelog/tenant/module/loanorigination/module-changelog-master.xml
new file mode 100644
index 0000000000..6bc107ecab
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/resources/db/changelog/tenant/module/loanorigination/module-changelog-master.xml
@@ -0,0 +1,26 @@
+<?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.1.xsd";>
+  <include relativeToChangelogFile="true" 
file="parts/0001_initial_schema.xml"/>
+</databaseChangeLog>
diff --git 
a/fineract-loan-origination/src/main/resources/db/changelog/tenant/module/loanorigination/parts/0001_initial_schema.xml
 
b/fineract-loan-origination/src/main/resources/db/changelog/tenant/module/loanorigination/parts/0001_initial_schema.xml
new file mode 100644
index 0000000000..049de8506d
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/resources/db/changelog/tenant/module/loanorigination/parts/0001_initial_schema.xml
@@ -0,0 +1,436 @@
+<?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.1.xsd";>
+
+    <!-- Create Codes for Originator Type -->
+    <changeSet id="loan-origination-001" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code WHERE code_name = 
'LoanOriginatorType'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code">
+            <column name="code_name" value="LoanOriginatorType"/>
+            <column name="is_system_defined" valueBoolean="true"/>
+        </insert>
+    </changeSet>
+
+    <!-- Create Code Values for Originator Type -->
+    <changeSet id="loan-origination-002" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginatorType' AND cv.code_value = 
'MERCHANT'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginatorType')"/>
+            <column name="code_value" value="MERCHANT"/>
+            <column name="order_position" valueNumeric="1"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <changeSet id="loan-origination-003" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginatorType' AND cv.code_value = 
'BROKER'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginatorType')"/>
+            <column name="code_value" value="BROKER"/>
+            <column name="order_position" valueNumeric="2"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <changeSet id="loan-origination-004" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginatorType' AND cv.code_value = 
'AFFILIATE'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginatorType')"/>
+            <column name="code_value" value="AFFILIATE"/>
+            <column name="order_position" valueNumeric="3"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <changeSet id="loan-origination-005" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginatorType' AND cv.code_value = 
'PLATFORM'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginatorType')"/>
+            <column name="code_value" value="PLATFORM"/>
+            <column name="order_position" valueNumeric="4"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <!-- Create Codes for Channel Type -->
+    <changeSet id="loan-origination-006" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code WHERE code_name = 
'LoanOriginationChannelType'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code">
+            <column name="code_name" value="LoanOriginationChannelType"/>
+            <column name="is_system_defined" valueBoolean="true"/>
+        </insert>
+    </changeSet>
+
+    <!-- Create Code Values for Channel Type -->
+    <changeSet id="loan-origination-007" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginationChannelType' AND 
cv.code_value = 'ONLINE'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginationChannelType')"/>
+            <column name="code_value" value="ONLINE"/>
+            <column name="order_position" valueNumeric="1"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <changeSet id="loan-origination-008" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginationChannelType' AND 
cv.code_value = 'IN_STORE'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginationChannelType')"/>
+            <column name="code_value" value="IN_STORE"/>
+            <column name="order_position" valueNumeric="2"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <changeSet id="loan-origination-009" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginationChannelType' AND 
cv.code_value = 'API'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginationChannelType')"/>
+            <column name="code_value" value="API"/>
+            <column name="order_position" valueNumeric="3"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <changeSet id="loan-origination-010" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <sqlCheck expectedResult="0">
+                SELECT COUNT(1) FROM m_code_value cv
+                JOIN m_code c ON cv.code_id = c.id
+                WHERE c.code_name = 'LoanOriginationChannelType' AND 
cv.code_value = 'AGGREGATOR'
+            </sqlCheck>
+        </preConditions>
+        <insert tableName="m_code_value">
+            <column name="code_id" valueComputed="(SELECT id FROM m_code WHERE 
code_name = 'LoanOriginationChannelType')"/>
+            <column name="code_value" value="AGGREGATOR"/>
+            <column name="order_position" valueNumeric="4"/>
+            <column name="is_active" valueBoolean="true"/>
+            <column name="is_mandatory" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+
+    <!-- Create m_loan_originator table - MySQL -->
+    <changeSet id="loan-origination-011" author="fineract" context="mysql">
+        <preConditions onFail="MARK_RAN">
+            <not>
+                <tableExists tableName="m_loan_originator"/>
+            </not>
+        </preConditions>
+        <createTable tableName="m_loan_originator">
+            <column name="id" type="BIGINT" autoIncrement="true">
+                <constraints primaryKey="true" nullable="false"/>
+            </column>
+            <column name="external_id" type="VARCHAR(100)">
+                <constraints nullable="false" unique="true" 
uniqueConstraintName="UQ_loan_originator_external_id"/>
+            </column>
+            <column name="name" type="VARCHAR(255)">
+                <constraints nullable="true"/>
+            </column>
+            <column name="status" type="VARCHAR(20)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="originator_type_cv_id" type="INT">
+                <constraints nullable="true"/>
+            </column>
+            <column name="channel_type_cv_id" type="INT">
+                <constraints nullable="true"/>
+            </column>
+            <column name="created_on_utc" type="DATETIME">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_on_utc" type="DATETIME">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+
+    <!-- Create m_loan_originator table - PostgreSQL -->
+    <changeSet id="loan-origination-011" author="fineract" 
context="postgresql">
+        <preConditions onFail="MARK_RAN">
+            <not>
+                <tableExists tableName="m_loan_originator"/>
+            </not>
+        </preConditions>
+        <createTable tableName="m_loan_originator">
+            <column name="id" type="BIGINT" autoIncrement="true">
+                <constraints primaryKey="true" nullable="false"/>
+            </column>
+            <column name="external_id" type="VARCHAR(100)">
+                <constraints nullable="false" unique="true" 
uniqueConstraintName="UQ_loan_originator_external_id"/>
+            </column>
+            <column name="name" type="VARCHAR(255)">
+                <constraints nullable="true"/>
+            </column>
+            <column name="status" type="VARCHAR(20)">
+                <constraints nullable="false"/>
+            </column>
+            <column name="originator_type_cv_id" type="INT">
+                <constraints nullable="true"/>
+            </column>
+            <column name="channel_type_cv_id" type="INT">
+                <constraints nullable="true"/>
+            </column>
+            <column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_on_utc" type="TIMESTAMP WITH TIME 
ZONE">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+
+    <!-- Add foreign keys for m_loan_originator -->
+    <changeSet id="loan-origination-012" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator"/>
+            <columnExists tableName="m_loan_originator" 
columnName="originator_type_cv_id"/>
+        </preConditions>
+        <addForeignKeyConstraint baseTableName="m_loan_originator" 
baseColumnNames="originator_type_cv_id"
+                                 referencedTableName="m_code_value" 
referencedColumnNames="id"
+                                 constraintName="FK_loan_originator_type_cv" 
onDelete="RESTRICT" onUpdate="RESTRICT"/>
+    </changeSet>
+
+    <changeSet id="loan-origination-013" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator"/>
+            <columnExists tableName="m_loan_originator" 
columnName="channel_type_cv_id"/>
+        </preConditions>
+        <addForeignKeyConstraint baseTableName="m_loan_originator" 
baseColumnNames="channel_type_cv_id"
+                                 referencedTableName="m_code_value" 
referencedColumnNames="id"
+                                 
constraintName="FK_loan_originator_channel_cv" onDelete="RESTRICT" 
onUpdate="RESTRICT"/>
+    </changeSet>
+
+    <!-- Add FK for audit columns on m_loan_originator -->
+    <changeSet id="loan-origination-014" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator"/>
+        </preConditions>
+        <addForeignKeyConstraint baseColumnNames="created_by" 
baseTableName="m_loan_originator"
+                                 
constraintName="FK_loan_originator_created_by" deferrable="false" 
initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT"
+                                 referencedColumnNames="id" 
referencedTableName="m_appuser" validate="true"/>
+        <addForeignKeyConstraint baseColumnNames="last_modified_by" 
baseTableName="m_loan_originator"
+                                 
constraintName="FK_loan_originator_modified_by" deferrable="false" 
initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT"
+                                 referencedColumnNames="id" 
referencedTableName="m_appuser" validate="true"/>
+    </changeSet>
+
+    <!-- Create m_loan_originator_mapping table - MySQL -->
+    <changeSet id="loan-origination-015" author="fineract" context="mysql">
+        <preConditions onFail="MARK_RAN">
+            <not>
+                <tableExists tableName="m_loan_originator_mapping"/>
+            </not>
+            <tableExists tableName="m_loan"/>
+        </preConditions>
+        <createTable tableName="m_loan_originator_mapping">
+            <column name="id" type="BIGINT" autoIncrement="true">
+                <constraints primaryKey="true" nullable="false"/>
+            </column>
+            <column name="loan_id" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="originator_id" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_on_utc" type="DATETIME">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_on_utc" type="DATETIME">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+
+    <!-- Create m_loan_originator_mapping table - PostgreSQL -->
+    <changeSet id="loan-origination-015" author="fineract" 
context="postgresql">
+        <preConditions onFail="MARK_RAN">
+            <not>
+                <tableExists tableName="m_loan_originator_mapping"/>
+            </not>
+            <tableExists tableName="m_loan"/>
+        </preConditions>
+        <createTable tableName="m_loan_originator_mapping">
+            <column name="id" type="BIGINT" autoIncrement="true">
+                <constraints primaryKey="true" nullable="false"/>
+            </column>
+            <column name="loan_id" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="originator_id" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_on_utc" type="TIMESTAMP WITH TIME ZONE">
+                <constraints nullable="false"/>
+            </column>
+            <column name="created_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_on_utc" type="TIMESTAMP WITH TIME 
ZONE">
+                <constraints nullable="false"/>
+            </column>
+            <column name="last_modified_by" type="BIGINT">
+                <constraints nullable="false"/>
+            </column>
+        </createTable>
+    </changeSet>
+
+    <!-- Add foreign keys for m_loan_originator_mapping -->
+    <changeSet id="loan-origination-016" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator_mapping"/>
+        </preConditions>
+        <addForeignKeyConstraint baseTableName="m_loan_originator_mapping" 
baseColumnNames="loan_id"
+                                 referencedTableName="m_loan" 
referencedColumnNames="id"
+                                 
constraintName="FK_loan_originator_mapping_loan" onDelete="RESTRICT" 
onUpdate="RESTRICT"/>
+    </changeSet>
+
+    <changeSet id="loan-origination-017" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator_mapping"/>
+        </preConditions>
+        <addForeignKeyConstraint baseTableName="m_loan_originator_mapping" 
baseColumnNames="originator_id"
+                                 referencedTableName="m_loan_originator" 
referencedColumnNames="id"
+                                 
constraintName="FK_loan_originator_mapping_originator" onDelete="RESTRICT" 
onUpdate="RESTRICT"/>
+    </changeSet>
+
+    <!-- Add FK for audit columns on m_loan_originator_mapping -->
+    <changeSet id="loan-origination-018" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator_mapping"/>
+        </preConditions>
+        <addForeignKeyConstraint baseColumnNames="created_by" 
baseTableName="m_loan_originator_mapping"
+                                 
constraintName="FK_loan_originator_mapping_created_by" deferrable="false" 
initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT"
+                                 referencedColumnNames="id" 
referencedTableName="m_appuser" validate="true"/>
+        <addForeignKeyConstraint baseColumnNames="last_modified_by" 
baseTableName="m_loan_originator_mapping"
+                                 
constraintName="FK_loan_originator_mapping_modified_by" deferrable="false" 
initiallyDeferred="false"
+                                 onDelete="RESTRICT" onUpdate="RESTRICT"
+                                 referencedColumnNames="id" 
referencedTableName="m_appuser" validate="true"/>
+    </changeSet>
+
+    <!-- Add unique constraint for loan-originator mapping (prevent duplicate 
assignments) -->
+    <changeSet id="loan-origination-019" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator_mapping"/>
+        </preConditions>
+        <addUniqueConstraint tableName="m_loan_originator_mapping" 
columnNames="loan_id, originator_id"
+                             
constraintName="UQ_loan_originator_mapping_loan_originator"/>
+    </changeSet>
+
+    <!-- Add indexes -->
+    <changeSet id="loan-origination-020" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator"/>
+        </preConditions>
+        <createIndex tableName="m_loan_originator" 
indexName="idx_loan_originator_status">
+            <column name="status"/>
+        </createIndex>
+    </changeSet>
+
+    <changeSet id="loan-origination-021" author="fineract">
+        <preConditions onFail="MARK_RAN">
+            <tableExists tableName="m_loan_originator_mapping"/>
+        </preConditions>
+        <createIndex tableName="m_loan_originator_mapping" 
indexName="idx_loan_originator_mapping_originator">
+            <column name="originator_id"/>
+        </createIndex>
+    </changeSet>
+
+</databaseChangeLog>
diff --git 
a/fineract-loan-origination/src/main/resources/jpa/static-weaving/module/fineract-loan-origination/persistence.xml
 
b/fineract-loan-origination/src/main/resources/jpa/static-weaving/module/fineract-loan-origination/persistence.xml
new file mode 100644
index 0000000000..61e9d53144
--- /dev/null
+++ 
b/fineract-loan-origination/src/main/resources/jpa/static-weaving/module/fineract-loan-origination/persistence.xml
@@ -0,0 +1,47 @@
+<?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.
+
+-->
+
+
+<persistence version="2.0"
+             xmlns="http://java.sun.com/xml/ns/persistence";
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd";>
+
+    <!--  This file is only used for static weaving, nothing more.  -->
+    <!--  You can find the runtime configuration in the JPAConfig class  -->
+    <persistence-unit name="jpa-pu" transaction-type="RESOURCE_LOCAL">
+        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+        <!-- Core entities needed for weaving -->
+        <class>org.apache.fineract.infrastructure.codes.domain.Code</class>
+        
<class>org.apache.fineract.infrastructure.codes.domain.CodeValue</class>
+
+        <!-- Loan Origination Module Entities -->
+        
<class>org.apache.fineract.portfolio.loanorigination.domain.LoanOriginator</class>
+        
<class>org.apache.fineract.portfolio.loanorigination.domain.LoanOriginatorMapping</class>
+
+        <exclude-unlisted-classes>false</exclude-unlisted-classes>
+        <properties>
+            <property name="eclipselink.weaving" value="static" />
+        </properties>
+    </persistence-unit>
+</persistence>
diff --git a/fineract-provider/dependencies.gradle 
b/fineract-provider/dependencies.gradle
index 4b889af935..ebf9d375cd 100644
--- a/fineract-provider/dependencies.gradle
+++ b/fineract-provider/dependencies.gradle
@@ -39,6 +39,7 @@ dependencies {
     implementation(project(path: ':fineract-progressive-loan'))
     implementation(project(path: ':fineract-report'))
     implementation(project(path: ':fineract-tax'))
+    implementation(project(path: ':fineract-loan-origination'))
 
     providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
 
diff --git a/fineract-provider/src/main/resources/application.properties 
b/fineract-provider/src/main/resources/application.properties
index d002dfbb72..93130efaeb 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -212,6 +212,7 @@ 
fineract.sampling.resetPeriodSec=${FINERACT_SAMPLING_RESET_PERIOD_IN_SEC:60}
 #Modules
 
fineract.module.self-service.enabled=${FINERACT_MODULE_SELF_SERVICE_ENABLED:false}
 fineract.module.investor.enabled=${FINERACT_MODULE_INVESTOR_ENABLED:true}
+fineract.module.loan-origination.enabled=${FINERACT_MODULE_LOAN_ORIGINATION_ENABLED:false}
 
 fineract.insecure-http-client=${FINERACT_INSECURE_HTTP_CLIENT:true}
 fineract.client-connect-timeout=${FINERACT_CLIENT_CONNECT_TIMEOUT:30}
diff --git 
a/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml 
b/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml
index f5c4e60ef3..fa2b25a088 100644
--- a/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml
+++ b/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml
@@ -37,6 +37,7 @@
     <include 
file="db/changelog/tenant/module/savings/parts/module-changelog-master.xml" 
context="tenant_db AND !initial_switch"/>
     <includeAll path="db/custom-changelog" errorIfMissingOrEmpty="false" 
context="tenant_db AND !initial_switch AND custom_changelog"/>
     <include 
file="/db/changelog/tenant/module/progressiveloan/module-changelog-master.xml" 
context="tenant_db AND !initial_switch"/>
+    <include 
file="db/changelog/tenant/module/loanorigination/module-changelog-master.xml" 
context="tenant_db AND !initial_switch"/>
     <!-- Scripts to run after the modules were initialized  -->
     <include file="tenant/final-changelog-tenant.xml" 
relativeToChangelogFile="true" context="tenant_db AND !initial_switch"/>
 </databaseChangeLog>
diff --git a/fineract-provider/src/test/resources/application-test.properties 
b/fineract-provider/src/test/resources/application-test.properties
index 1530e7cdfa..e5142d8468 100644
--- a/fineract-provider/src/test/resources/application-test.properties
+++ b/fineract-provider/src/test/resources/application-test.properties
@@ -125,6 +125,8 @@ fineract.sampling.sampledClasses=
 
 fineract.module.investor.enabled=true
 fineract.module.self-service.enabled=true
+# TODO: activate this module when the implementation is ready
+fineract.module.loan-origination.enabled=false
 
 # sql validation
 
diff --git a/fineract-war/build.gradle b/fineract-war/build.gradle
index 2540300c31..da34c147c2 100644
--- a/fineract-war/build.gradle
+++ b/fineract-war/build.gradle
@@ -86,6 +86,7 @@ dependencies {
     implementation project(':fineract-charge')
     implementation project(':fineract-rates')
     implementation project(':fineract-loan')
+    implementation project(':fineract-loan-origination')
     implementation project(':fineract-progressive-loan')
     implementation project(':fineract-savings')
     implementation project(':fineract-provider')
diff --git a/settings.gradle b/settings.gradle
index c8cf0e47ae..1b6ac8d978 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -59,6 +59,7 @@ include ':fineract-investor'
 include ':fineract-rates'
 include ':fineract-charge'
 include ':fineract-tax'
+include ':fineract-loan-origination'
 include ':fineract-loan'
 include ':fineract-savings'
 include ':fineract-report'

Reply via email to