diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRiskRule.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRiskRule.java new file mode 100644 index 000000000..3c1dce647 --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRiskRule.java @@ -0,0 +1,138 @@ +/** + * 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.client.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import java.math.BigDecimal; +import org.apache.fineract.infrastructure.codes.domain.CodeValue; + +@Entity +@Table(name = "m_client_risk_rule") +public class ClientRiskRule { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "rule_name", nullable = false, length = 100) + private String ruleName; + + @Column(name = "legal_form_id") + private Integer legalFormId; + + @ManyToOne + @JoinColumn(name = "occupation_category_cv_id") + private CodeValue occupationCategory; + + @ManyToOne + @JoinColumn(name = "occupation_cv_id") + private CodeValue occupation; + + @Column(name = "min_monthly_income", precision = 19, scale = 6) + private BigDecimal minMonthlyIncome; + + @Column(name = "max_monthly_income", precision = 19, scale = 6) + private BigDecimal maxMonthlyIncome; + + @Column(name = "min_annual_income", precision = 19, scale = 6) + private BigDecimal minAnnualIncome; + + @Column(name = "max_annual_income", precision = 19, scale = 6) + private BigDecimal maxAnnualIncome; + + @Column(name = "min_annual_turnover", precision = 19, scale = 6) + private BigDecimal minAnnualTurnover; + + @Column(name = "max_annual_turnover", precision = 19, scale = 6) + private BigDecimal maxAnnualTurnover; + + @Column(name = "risk_category", nullable = false) + private Integer riskCategory; + + @Column(name = "reason", nullable = false, length = 255) + private String reason; + + @Column(name = "order_position", nullable = false) + private Integer orderPosition; + + protected ClientRiskRule() {} + + public Long getId() { + return id; + } + + public String getRuleName() { + return ruleName; + } + + public Integer getLegalFormId() { + return legalFormId; + } + + public CodeValue getOccupationCategory() { + return occupationCategory; + } + + public CodeValue getOccupation() { + return occupation; + } + + public BigDecimal getMinMonthlyIncome() { + return minMonthlyIncome; + } + + public BigDecimal getMaxMonthlyIncome() { + return maxMonthlyIncome; + } + + public BigDecimal getMinAnnualIncome() { + return minAnnualIncome; + } + + public BigDecimal getMaxAnnualIncome() { + return maxAnnualIncome; + } + + public BigDecimal getMinAnnualTurnover() { + return minAnnualTurnover; + } + + public BigDecimal getMaxAnnualTurnover() { + return maxAnnualTurnover; + } + + public Integer getRiskCategory() { + return riskCategory; + } + + public String getReason() { + return reason; + } + + public Integer getOrderPosition() { + return orderPosition; + } +} diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRiskRuleRepository.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRiskRuleRepository.java new file mode 100644 index 000000000..46eb97f48 --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRiskRuleRepository.java @@ -0,0 +1,29 @@ +/** + * 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.client.domain; + +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface ClientRiskRuleRepository extends JpaRepository { + + @Query("SELECT r FROM ClientRiskRule r ORDER BY r.orderPosition ASC") + List findAllOrderedByOrderPosition(); +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/KycRiskRulesApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/KycRiskRulesApiResource.java new file mode 100644 index 000000000..45abba10b --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/KycRiskRulesApiResource.java @@ -0,0 +1,55 @@ +/** + * 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.client.api; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.portfolio.client.data.KycRiskRuleData; +import org.apache.fineract.portfolio.client.service.KycRiskRulesReadPlatformService; +import org.springframework.stereotype.Component; + +@Path("/v1/kyc/risk-rules") +@Component +@Tag(name = "KYC Risk Rules", description = "Retrieve database-driven master rules for client AML/CFT risk rating calculation.") +@RequiredArgsConstructor +public class KycRiskRulesApiResource { + + private final PlatformSecurityContext context; + private final KycRiskRulesReadPlatformService readPlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + @Operation(summary = "Retrieve KYC risk rules", description = "Returns list of database-defined risk rules ordered by precedence.") + public String retrieveRiskRules() { + this.context.authenticatedUser(); + final List rules = this.readPlatformService.retrieveAllRules(); + return this.toApiJsonSerializer.serialize(rules); + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/KycRiskRuleData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/KycRiskRuleData.java new file mode 100644 index 000000000..61772d879 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/KycRiskRuleData.java @@ -0,0 +1,133 @@ +/** + * 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.client.data; + +import java.io.Serializable; +import java.math.BigDecimal; + +public final class KycRiskRuleData implements Serializable { + + private static final long serialVersionUID = 1L; + + private final Long id; + private final String ruleName; + private final Integer legalFormId; + private final Long occupationCategoryCvId; + private final String occupationCategoryName; + private final Long occupationCvId; + private final String occupationName; + private final BigDecimal minMonthlyIncome; + private final BigDecimal maxMonthlyIncome; + private final BigDecimal minAnnualIncome; + private final BigDecimal maxAnnualIncome; + private final BigDecimal minAnnualTurnover; + private final BigDecimal maxAnnualTurnover; + private final Integer riskCategory; + private final String reason; + private final Integer orderPosition; + + public KycRiskRuleData(final Long id, final String ruleName, final Integer legalFormId, + final Long occupationCategoryCvId, final String occupationCategoryName, + final Long occupationCvId, final String occupationName, + final BigDecimal minMonthlyIncome, final BigDecimal maxMonthlyIncome, + final BigDecimal minAnnualIncome, final BigDecimal maxAnnualIncome, + final BigDecimal minAnnualTurnover, final BigDecimal maxAnnualTurnover, + final Integer riskCategory, final String reason, final Integer orderPosition) { + this.id = id; + this.ruleName = ruleName; + this.legalFormId = legalFormId; + this.occupationCategoryCvId = occupationCategoryCvId; + this.occupationCategoryName = occupationCategoryName; + this.occupationCvId = occupationCvId; + this.occupationName = occupationName; + this.minMonthlyIncome = minMonthlyIncome; + this.maxMonthlyIncome = maxMonthlyIncome; + this.minAnnualIncome = minAnnualIncome; + this.maxAnnualIncome = maxAnnualIncome; + this.minAnnualTurnover = minAnnualTurnover; + this.maxAnnualTurnover = maxAnnualTurnover; + this.riskCategory = riskCategory; + this.reason = reason; + this.orderPosition = orderPosition; + } + + public Long getId() { + return id; + } + + public String getRuleName() { + return ruleName; + } + + public Integer getLegalFormId() { + return legalFormId; + } + + public Long getOccupationCategoryCvId() { + return occupationCategoryCvId; + } + + public String getOccupationCategoryName() { + return occupationCategoryName; + } + + public Long getOccupationCvId() { + return occupationCvId; + } + + public String getOccupationName() { + return occupationName; + } + + public BigDecimal getMinMonthlyIncome() { + return minMonthlyIncome; + } + + public BigDecimal getMaxMonthlyIncome() { + return maxMonthlyIncome; + } + + public BigDecimal getMinAnnualIncome() { + return minAnnualIncome; + } + + public BigDecimal getMaxAnnualIncome() { + return maxAnnualIncome; + } + + public BigDecimal getMinAnnualTurnover() { + return minAnnualTurnover; + } + + public BigDecimal getMaxAnnualTurnover() { + return maxAnnualTurnover; + } + + public Integer getRiskCategory() { + return riskCategory; + } + + public String getReason() { + return reason; + } + + public Integer getOrderPosition() { + return orderPosition; + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/KycRiskRulesReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/KycRiskRulesReadPlatformService.java new file mode 100644 index 000000000..8fa61d5bb --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/KycRiskRulesReadPlatformService.java @@ -0,0 +1,26 @@ +/** + * 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.client.service; + +import java.util.List; +import org.apache.fineract.portfolio.client.data.KycRiskRuleData; + +public interface KycRiskRulesReadPlatformService { + List retrieveAllRules(); +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/KycRiskRulesReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/KycRiskRulesReadPlatformServiceImpl.java new file mode 100644 index 000000000..618762d97 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/KycRiskRulesReadPlatformServiceImpl.java @@ -0,0 +1,68 @@ +/** + * 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.client.service; + +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.apache.fineract.portfolio.client.data.KycRiskRuleData; +import org.apache.fineract.portfolio.client.domain.ClientRiskRule; +import org.apache.fineract.portfolio.client.domain.ClientRiskRuleRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class KycRiskRulesReadPlatformServiceImpl implements KycRiskRulesReadPlatformService { + + private final ClientRiskRuleRepository repository; + + @Override + public List retrieveAllRules() { + final List rules = this.repository.findAllOrderedByOrderPosition(); + return rules.stream().map(this::mapToData).collect(Collectors.toList()); + } + + private KycRiskRuleData mapToData(final ClientRiskRule rule) { + final Long occCatId = rule.getOccupationCategory() != null ? rule.getOccupationCategory().getId() : null; + final String occCatName = rule.getOccupationCategory() != null ? rule.getOccupationCategory().getLabel() : null; + final Long occId = rule.getOccupation() != null ? rule.getOccupation().getId() : null; + final String occName = rule.getOccupation() != null ? rule.getOccupation().getLabel() : null; + + return new KycRiskRuleData( + rule.getId(), + rule.getRuleName(), + rule.getLegalFormId(), + occCatId, + occCatName, + occId, + occName, + rule.getMinMonthlyIncome(), + rule.getMaxMonthlyIncome(), + rule.getMinAnnualIncome(), + rule.getMaxAnnualIncome(), + rule.getMinAnnualTurnover(), + rule.getMaxAnnualTurnover(), + rule.getRiskCategory(), + rule.getReason(), + rule.getOrderPosition() + ); + } +} diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index 0c7df83d2..f58a5d6d2 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -481,4 +481,5 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0428_add_client_risk_rules.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0428_add_client_risk_rules.xml new file mode 100644 index 000000000..44db6f98c --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0428_add_client_risk_rules.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT COUNT(*) FROM m_client_risk_rule + + + INSERT INTO m_client_risk_rule (rule_name, legal_form_id, occupation_category_cv_id, occupation_cv_id, min_monthly_income, min_annual_income, min_annual_turnover, risk_category, reason, order_position) + VALUES + ('Politician / Elected Representative', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Politician / Elected Representative' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 3, 'Politically Exposed Person (PEP) / Elected Representative', 10), + ('Real Estate Dealer', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Real Estate / Property Dealer' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 3, 'High Risk Industry (Real Estate / Property Dealing)', 20), + ('Importer / Exporter', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Importer / Exporter' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 3, 'High Risk Trade (Import / Export)', 30), + ('Commission Agent', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Commission Agent' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 3, 'High Risk Business Type (Commission Agent)', 40), + ('Financial Advisor', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Financial Advisor' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 3, 'High Risk Professional (Financial Advisor)', 50), + ('High Monthly Income (> 2 Lakhs)', 1, null, null, 200000.0, null, null, 3, 'High Income threshold (> ₹2L Monthly)', 60), + ('High Annual Income (> 20 Lakhs)', 1, null, null, null, 2000000.0, null, 3, 'High Income threshold (> ₹20L Annual)', 70), + ('High Business Turnover (> 1 Crore)', 1, null, null, null, null, 10000000.0, 3, 'High Business Turnover (> ₹1 Crore Annual)', 80), + ('NRI Account Profile', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'NRI (Non-Resident Indian)' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Non-Resident Indian (NRI) account profile', 90), + ('PIO / OCI Profile', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'PIO / OCI' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Foreign/Overseas Citizen profile (PIO / OCI)', 100), + ('Business Owner / Proprietor', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Business Owner / Proprietor' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed / Business owner profile', 110), + ('Trader / Merchant', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Trader / Merchant' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed / Business owner profile', 120), + ('Manufacturer', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Manufacturer' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed / Business owner profile', 130), + ('Contractor', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Contractor' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed / Business owner profile', 140), + ('Doctor (Private Practice)', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Doctor (Private Practice)' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 150), + ('Lawyer / Advocate', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Lawyer / Advocate' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 160), + ('Chartered Accountant', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Chartered Accountant' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 170), + ('Company Secretary', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Company Secretary' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 180), + ('Architect', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Architect' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 190), + ('Consultant', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Consultant' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 200), + ('IT Professional / Freelancer', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'IT Professional / Freelancer' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 210), + ('Auditor', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Auditor' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 2, 'Self-Employed Professional profile', 220), + ('Business / Self Employed Category', 1, (SELECT id FROM m_code_value WHERE code_value = 'Business / Self Employed' AND code_id = (SELECT id FROM m_code WHERE code_name = 'OccupationCategory')), null, null, null, null, 2, 'Business / Self-Employed Category', 230), + ('Professional Category', 1, (SELECT id FROM m_code_value WHERE code_value = 'Professional' AND code_id = (SELECT id FROM m_code WHERE code_name = 'OccupationCategory')), null, null, null, null, 2, 'Professional Category', 240), + ('Medium Monthly Income (> 50K)', 1, null, null, 50000.0, null, null, 2, 'Medium Income threshold (> ₹50K Monthly)', 250), + ('Medium Annual Income (> 6 Lakhs)', 1, null, null, null, 600000.0, null, 2, 'Medium Income threshold (> ₹6L Annual)', 260), + ('Medium Business Turnover (> 20 Lakhs)', 1, null, null, null, null, 2000000.0, 2, 'Medium Business Turnover (> ₹20L Annual)', 270), + ('Student Profile', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Student' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Non-Earning profile (Student)', 280), + ('Housewife / Homemaker Profile', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Housewife / Homemaker' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Non-Earning profile (Homemaker)', 290), + ('Dependent / Minor Profile', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Dependent / Minor' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Non-Earning profile (Dependent / Minor)', 300), + ('Unemployed Profile', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Unemployed' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Non-Earning profile (Unemployed)', 310), + ('Government Employee', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Government Employee' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk employment (Government Employee)', 320), + ('PSU Employee', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Public Sector Undertaking (PSU) Employee' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk employment (PSU Employee)', 330), + ('Defence Personnel', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Defence / Armed Forces Personnel' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk employment (Defence Personnel)', 340), + ('Police / Paramilitary', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Police / Paramilitary' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk employment (Police / Paramilitary)', 350), + ('Teacher / Professor', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Teacher / Professor' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk employment (Teacher / Professor)', 360), + ('Bank Employee', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Bank Employee' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk employment (Bank Employee)', 370), + ('Railway Employee', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Railway Employee' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk employment (Railway Employee)', 380), + ('Farmer (Own Land)', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Farmer (Own Land)' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk agricultural occupation', 390), + ('Tenant Farmer', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Tenant Farmer' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk agricultural occupation', 400), + ('Agricultural Labourer', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Agricultural Labourer' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk manual/agricultural labour', 410), + ('Labourer / Daily Wage', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Labourer / Daily Wage' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk manual labour', 420), + ('Domestic Worker', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Domestic Worker' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk manual/domestic service', 430), + ('Driver / Operator', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Driver / Operator' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk manual/transport service', 440), + ('Artisan / Craftsman', 1, null, (SELECT id FROM m_code_value WHERE code_value = 'Artisan / Craftsman' AND code_id = (SELECT id FROM m_code WHERE code_name = 'Occupation')), null, null, null, 1, 'Low risk manual/artisan profile', 450), + ('Non-Individual Default Medium Risk', 2, null, null, null, null, null, 2, 'Non-Individual / Entity profile (Default Medium Risk)', 460), + ('Global Default Low Risk', null, null, null, null, null, null, 1, 'Default Low Risk profile (Salary / Service / Agriculture / Others)', 500); + + + +