oss file updated, profitl loss as per the day month and also with date select
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s

This commit is contained in:
2026-08-01 11:54:30 +05:30
parent 8622dcaf90
commit abc7eb22a2
8 changed files with 359 additions and 7 deletions
@@ -52,6 +52,14 @@ public class AmlTransactionRule {
@Column(name = "threshold_amount", precision = 19, scale = 6)
private BigDecimal thresholdAmount;
/** Risk-category-tiered overrides of {@link #thresholdAmount}. Null on both means the rule is
* not tiered; {@link #thresholdAmount} is used for every client regardless of risk category. */
@Column(name = "threshold_amount_medium_risk", precision = 19, scale = 6)
private BigDecimal thresholdAmountMediumRisk;
@Column(name = "threshold_amount_high_risk", precision = 19, scale = 6)
private BigDecimal thresholdAmountHighRisk;
@Column(name = "rule_type", nullable = false, length = 20)
private String ruleType;
@@ -86,6 +94,14 @@ public class AmlTransactionRule {
return thresholdAmount;
}
public BigDecimal getThresholdAmountMediumRisk() {
return thresholdAmountMediumRisk;
}
public BigDecimal getThresholdAmountHighRisk() {
return thresholdAmountHighRisk;
}
public AmlRuleType getRuleType() {
return AmlRuleType.valueOf(ruleType);
}
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.portfolio.aml.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
@@ -27,6 +28,8 @@ import org.apache.fineract.portfolio.aml.domain.AmlAlertRepository;
import org.apache.fineract.portfolio.aml.domain.AmlAppliesTo;
import org.apache.fineract.portfolio.aml.domain.AmlTransactionRule;
import org.apache.fineract.portfolio.aml.domain.AmlTransactionRuleRepository;
import org.apache.fineract.portfolio.client.domain.ClientKyc;
import org.apache.fineract.portfolio.client.domain.ClientKycRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -35,8 +38,12 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional
public class AmlRuleEvaluationServiceImpl implements AmlRuleEvaluationService {
private static final int MEDIUM_RISK = 2;
private static final int HIGH_RISK = 3;
private final AmlTransactionRuleRepository ruleRepository;
private final AmlAlertRepository alertRepository;
private final ClientKycRepository clientKycRepository;
@Override
public List<AmlAlert> evaluate(AmlTransactionContext context) {
@@ -56,20 +63,42 @@ public class AmlRuleEvaluationServiceImpl implements AmlRuleEvaluationService {
}
private boolean isHit(AmlTransactionRule rule, AmlTransactionContext context) {
if (rule.getThresholdAmount() == null) {
final BigDecimal threshold = resolveThreshold(rule, context);
if (threshold == null) {
// Pattern-only VELOCITY rules (e.g. same-day movement) need bespoke detection logic
// per rule and are not yet evaluated here - they exist in the catalog for future work.
return false;
}
switch (rule.getRuleType()) {
case THRESHOLD:
return context.getAmount().compareTo(rule.getThresholdAmount()) >= 0;
return context.getAmount().compareTo(threshold) >= 0;
case STRUCTURING:
case VELOCITY:
return context.getWindowAggregateAmount() != null
&& context.getWindowAggregateAmount().compareTo(rule.getThresholdAmount()) >= 0;
&& context.getWindowAggregateAmount().compareTo(threshold) >= 0;
default:
return false;
}
}
/**
* Rules with both tiered columns null use {@code thresholdAmount} for every client, unchanged
* from prior behaviour. Tiered rules look up the transacting client's current KYC risk category
* and pick the matching tier, falling back to {@code thresholdAmount} for Low-risk/unclassified
* clients.
*/
private BigDecimal resolveThreshold(AmlTransactionRule rule, AmlTransactionContext context) {
if (rule.getThresholdAmountMediumRisk() == null && rule.getThresholdAmountHighRisk() == null) {
return rule.getThresholdAmount();
}
final Integer riskCategory = clientKycRepository.findByClientId(context.getClient().getId()).map(ClientKyc::getRiskCategoryValue)
.orElse(null);
if (riskCategory != null && riskCategory == HIGH_RISK && rule.getThresholdAmountHighRisk() != null) {
return rule.getThresholdAmountHighRisk();
}
if (riskCategory != null && riskCategory == MEDIUM_RISK && rule.getThresholdAmountMediumRisk() != null) {
return rule.getThresholdAmountMediumRisk();
}
return rule.getThresholdAmount();
}
}
@@ -46,6 +46,16 @@ public final class KycRiskRuleData implements Serializable {
private final String willfulDefaulter;
private final String ecgcSalFlag;
private final String dormantFlag;
/** Populated only for rules that also have a live-transaction-monitoring counterpart in
* {@code m_aml_transaction_rule} (linked via source_client_risk_rule_id) - distinct from the
* client-onboarding income/turnover fields above, which drive KYC-time risk categorization. */
private final BigDecimal txnThresholdAmount;
private final String txnRuleType;
private final Integer txnWindowDays;
/** Risk-category-tiered overrides of {@link #txnThresholdAmount}, populated only when the
* linked {@code m_aml_transaction_rule} row has tiering configured (e.g. RTGS monitoring). */
private final BigDecimal txnThresholdAmountMediumRisk;
private final BigDecimal txnThresholdAmountHighRisk;
public KycRiskRuleData(final Long id, final String ruleName, final Integer legalFormId,
final Long occupationCategoryCvId, final String occupationCategoryName,
@@ -55,7 +65,9 @@ public final class KycRiskRuleData implements Serializable {
final BigDecimal minAnnualTurnover, final BigDecimal maxAnnualTurnover,
final Integer riskCategory, final String reason, final Integer orderPosition,
final String amlCheckStatus, final String bannedEntityMatch,
final String willfulDefaulter, final String ecgcSalFlag, final String dormantFlag) {
final String willfulDefaulter, final String ecgcSalFlag, final String dormantFlag,
final BigDecimal txnThresholdAmount, final String txnRuleType, final Integer txnWindowDays,
final BigDecimal txnThresholdAmountMediumRisk, final BigDecimal txnThresholdAmountHighRisk) {
this.id = id;
this.ruleName = ruleName;
this.legalFormId = legalFormId;
@@ -77,6 +89,11 @@ public final class KycRiskRuleData implements Serializable {
this.willfulDefaulter = willfulDefaulter;
this.ecgcSalFlag = ecgcSalFlag;
this.dormantFlag = dormantFlag;
this.txnThresholdAmount = txnThresholdAmount;
this.txnRuleType = txnRuleType;
this.txnWindowDays = txnWindowDays;
this.txnThresholdAmountMediumRisk = txnThresholdAmountMediumRisk;
this.txnThresholdAmountHighRisk = txnThresholdAmountHighRisk;
}
public Long getId() {
@@ -162,4 +179,24 @@ public final class KycRiskRuleData implements Serializable {
public String getDormantFlag() {
return dormantFlag;
}
public BigDecimal getTxnThresholdAmount() {
return txnThresholdAmount;
}
public String getTxnRuleType() {
return txnRuleType;
}
public Integer getTxnWindowDays() {
return txnWindowDays;
}
public BigDecimal getTxnThresholdAmountMediumRisk() {
return txnThresholdAmountMediumRisk;
}
public BigDecimal getTxnThresholdAmountHighRisk() {
return txnThresholdAmountHighRisk;
}
}
@@ -19,8 +19,12 @@
package org.apache.fineract.portfolio.client.service;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.portfolio.aml.domain.AmlTransactionRule;
import org.apache.fineract.portfolio.aml.domain.AmlTransactionRuleRepository;
import org.apache.fineract.portfolio.client.data.KycRiskRuleData;
import org.apache.fineract.portfolio.client.domain.ClientRiskRule;
import org.apache.fineract.portfolio.client.domain.ClientRiskRuleRepository;
@@ -33,14 +37,18 @@ import org.springframework.transaction.annotation.Transactional;
public class KycRiskRulesReadPlatformServiceImpl implements KycRiskRulesReadPlatformService {
private final ClientRiskRuleRepository repository;
private final AmlTransactionRuleRepository amlTransactionRuleRepository;
@Override
public List<KycRiskRuleData> retrieveAllRules() {
final List<ClientRiskRule> rules = this.repository.findAllOrderedByOrderPosition();
return rules.stream().map(this::mapToData).collect(Collectors.toList());
final Map<Long, AmlTransactionRule> txnRulesBySourceId = this.amlTransactionRuleRepository.findAll().stream()
.filter(txn -> txn.getSourceClientRiskRuleId() != null)
.collect(Collectors.toMap(AmlTransactionRule::getSourceClientRiskRuleId, Function.identity(), (a, b) -> a));
return rules.stream().map(rule -> mapToData(rule, txnRulesBySourceId.get(rule.getId()))).collect(Collectors.toList());
}
private KycRiskRuleData mapToData(final ClientRiskRule rule) {
private KycRiskRuleData mapToData(final ClientRiskRule rule, final AmlTransactionRule txnRule) {
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;
@@ -67,7 +75,12 @@ public class KycRiskRulesReadPlatformServiceImpl implements KycRiskRulesReadPlat
rule.getBannedEntityMatch(),
rule.getWillfulDefaulter(),
rule.getEcgcSalFlag(),
rule.getDormantFlag()
rule.getDormantFlag(),
txnRule != null ? txnRule.getThresholdAmount() : null,
txnRule != null ? txnRule.getRuleType().name() : null,
txnRule != null ? txnRule.getWindowDays() : null,
txnRule != null ? txnRule.getThresholdAmountMediumRisk() : null,
txnRule != null ? txnRule.getThresholdAmountHighRisk() : null
);
}
}
@@ -490,4 +490,7 @@
<include file="parts/0435_add_aml_officer_and_principal_officer_roles.xml" relativeToChangelogFile="true"/>
<include file="parts/0436_fix_missing_client_risk_rule_columns.xml" relativeToChangelogFile="true"/>
<include file="parts/0437_update_aml_columns_for_risk_rules.xml" relativeToChangelogFile="true"/>
<include file="parts/0438_add_tiered_thresholds_and_low_balance_rule.xml" relativeToChangelogFile="true"/>
<include file="parts/0439_fill_client_risk_rule_income_turnover_nulls.xml" relativeToChangelogFile="true"/>
<include file="parts/0440_seed_aml_test_alerts.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
@@ -0,0 +1,85 @@
<?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.13.xsd">
<!-- Optional risk-category-tiered thresholds. Null on both columns means the rule is not
tiered and threshold_amount alone is used (unchanged behaviour for every pre-existing rule). -->
<changeSet author="fineract" id="0438-1">
<preConditions onFail="MARK_RAN">
<not><columnExists tableName="m_aml_transaction_rule" columnName="threshold_amount_medium_risk"/></not>
</preConditions>
<addColumn tableName="m_aml_transaction_rule">
<column name="threshold_amount_medium_risk" type="DECIMAL(19,6)">
<constraints nullable="true"/>
</column>
</addColumn>
</changeSet>
<changeSet author="fineract" id="0438-2">
<preConditions onFail="MARK_RAN">
<not><columnExists tableName="m_aml_transaction_rule" columnName="threshold_amount_high_risk"/></not>
</preConditions>
<addColumn tableName="m_aml_transaction_rule">
<column name="threshold_amount_high_risk" type="DECIMAL(19,6)">
<constraints nullable="true"/>
</column>
</addColumn>
</changeSet>
<!-- RTGS monitoring: Medium-risk clients are flagged at INR 5,00,000, High-risk at INR 20,00,000.
threshold_amount (2,000,000) remains the fallback for Low-risk/unclassified clients. -->
<changeSet author="fineract" id="0438-3">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_aml_transaction_rule WHERE rule_code = 'RTGS_HIGH_VALUE' AND threshold_amount_medium_risk IS NOT NULL</sqlCheck>
</preConditions>
<sql>
UPDATE m_aml_transaction_rule
SET threshold_amount_medium_risk = 500000,
threshold_amount_high_risk = 2000000
WHERE rule_code = 'RTGS_HIGH_VALUE';
</sql>
</changeSet>
<!-- Rule 1 from the legacy Rules Parameter catalog: "Maintaining a low or overdrawn balance
with high activity" (order_position 1). The legacy screen reports a single INR 10,00,000
figure across three distinct parameters (average balance period, minimum balance, max
transaction count), which does not correspond to any threshold/window shape this catalog
currently evaluates (THRESHOLD/STRUCTURING/VELOCITY all key off a transaction AMOUNT, not
an account balance level). Seeded here for catalog/display parity with m_client_risk_rule,
with is_active = false so it is never picked up by AmlRuleEvaluationServiceImpl until a
balance-based rule type is built. -->
<changeSet author="fineract" id="0438-4">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_aml_transaction_rule WHERE rule_code = 'LOW_BALANCE_HIGH_ACTIVITY'</sqlCheck>
</preConditions>
<sql>
INSERT INTO m_aml_transaction_rule
(rule_code, description, applies_to, threshold_amount, rule_type, window_days, source_client_risk_rule_id, is_active)
VALUES
('LOW_BALANCE_HIGH_ACTIVITY', 'Maintaining a low or overdrawn balance with high activity', 'SAVINGS', 1000000, 'THRESHOLD', null,
(SELECT id FROM m_client_risk_rule WHERE order_position = 1 AND aml_check_status IS NOT NULL), false);
</sql>
</changeSet>
</databaseChangeLog>
@@ -0,0 +1,61 @@
<?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.13.xsd">
<changeSet author="fineract" id="0439-1">
<validCheckSum>*</validCheckSum>
<sql>
-- 1. High Risk Occupations (Real Estate, Importer/Exporter, Commission Agent, Financial Advisor)
UPDATE m_client_risk_rule
SET min_monthly_income = 200000.0,
min_annual_income = 2400000.0
WHERE order_position IN (20, 30, 40, 50);
-- 2. Medium Risk Occupations
UPDATE m_client_risk_rule
SET min_monthly_income = 50000.0,
max_monthly_income = 200000.0,
min_annual_income = 600000.0,
max_annual_income = 2400000.0
WHERE order_position BETWEEN 90 AND 240;
-- 3. Low Risk Occupations
UPDATE m_client_risk_rule
SET min_monthly_income = 0.0,
max_monthly_income = 50000.0,
min_annual_income = 0.0,
max_annual_income = 600000.0
WHERE order_position BETWEEN 280 AND 450;
-- 4. Set all remaining NULL values to 0.00
UPDATE m_client_risk_rule SET min_monthly_income = 0.0 WHERE min_monthly_income IS NULL;
UPDATE m_client_risk_rule SET max_monthly_income = 0.0 WHERE max_monthly_income IS NULL;
UPDATE m_client_risk_rule SET min_annual_income = 0.0 WHERE min_annual_income IS NULL;
UPDATE m_client_risk_rule SET max_annual_income = 0.0 WHERE max_annual_income IS NULL;
UPDATE m_client_risk_rule SET min_annual_turnover = 0.0 WHERE min_annual_turnover IS NULL;
UPDATE m_client_risk_rule SET max_annual_turnover = 0.0 WHERE max_annual_turnover IS NULL;
</sql>
</changeSet>
</databaseChangeLog>
@@ -0,0 +1,108 @@
<?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.13.xsd">
<changeSet author="fineract" id="0440-1">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM m_client WHERE external_id = 'CLIENT_RAJESH'</sqlCheck>
</preConditions>
<sql>
INSERT INTO m_client (
account_no, external_id, status_enum, office_id, display_name,
fullname, is_staff, activation_date, office_joining_date,
submittedon_date, legal_form_enum,
created_on_utc, created_by,
last_modified_on_utc, last_modified_by,
cif_number
)
VALUES
(
'ACC0000002', 'CLIENT_RAJESH', 300, 1, 'Rajesh Kumar',
'Rajesh Kumar', false, CURRENT_DATE, CURRENT_DATE,
CURRENT_DATE, 1,
NOW(), 1,
NOW(), 1,
'CIF_RAJESH'
),
(
'ACC0000003', 'CLIENT_SONIA', 300, 1, 'Sonia Sharma',
'Sonia Sharma', false, CURRENT_DATE, CURRENT_DATE,
CURRENT_DATE, 1,
NOW(), 1,
NOW(), 1,
'CIF_SONIA'
),
(
'ACC0000004', 'CLIENT_VIKRAM', 300, 1, 'Vikram Malhotra',
'Vikram Malhotra', false, CURRENT_DATE, CURRENT_DATE,
CURRENT_DATE, 1,
NOW(), 1,
NOW(), 1,
'CIF_VIKRAM'
);
</sql>
</changeSet>
<changeSet author="fineract" id="0440-2">
<preConditions onFail="MARK_RAN">
<sqlCheck expectedResult="0">
SELECT COUNT(*) FROM m_aml_alert a
JOIN m_client c ON a.client_id = c.id
WHERE c.external_id IN ('CLIENT_RAJESH', 'CLIENT_SONIA', 'CLIENT_VIKRAM')
</sqlCheck>
</preConditions>
<sql>
INSERT INTO m_aml_alert (
transaction_type, transaction_id, client_id, rule_id, amount, currency_code,
raised_on, status, created_by, created_on_utc, last_modified_by, last_modified_on_utc, version
)
VALUES
(
'SAVINGS', 1001,
(SELECT id FROM m_client WHERE external_id = 'CLIENT_RAJESH'),
(SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'LARGE_CASH_TXN_25L'),
3500000.000000, 'INR',
NOW(), 'RAISED',
1, NOW(), 1, NOW(), 0
),
(
'SAVINGS', 1002,
(SELECT id FROM m_client WHERE external_id = 'CLIENT_SONIA'),
(SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'STRUCTURING_BELOW_10L'),
995000.000000, 'INR',
NOW(), 'RAISED',
1, NOW(), 1, NOW(), 0
),
(
'SAVINGS', 1003,
(SELECT id FROM m_client WHERE external_id = 'CLIENT_VIKRAM'),
(SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'PEP_ACCOUNT_MONITORING'),
75000.000000, 'INR',
NOW(), 'RAISED',
1, NOW(), 1, NOW(), 0
);
</sql>
</changeSet>
</databaseChangeLog>