rymghosn commented on code in PR #6235:
URL: https://github.com/apache/fineract/pull/6235#discussion_r4181350392


##########
fineract-provider/src/main/resources/db/changelog/tenant/parts/0245_delete_trailing_space_standinginstruction_permissions.xml:
##########
@@ -0,0 +1,75 @@
+<?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.
+
+-->
+<!--
+    Liquibase changeSet to safely delete duplicate m_permission rows
+    for Standing Instruction permissions WITHOUT trailing spaces,
+    keeping the legacy trailing-space versions.
+
+    Deletes ONLY:
+      - 'CREATE_STANDINGINSTRUCTION'
+      - 'UPDATE_STANDINGINSTRUCTION'
+      - 'DELETE_STANDINGINSTRUCTION'
+
+    Safety rules:
+    - Delete ONLY if a trailing-space version already exists.
+    - Do NOT modify or insert any permissions.
+    - Do NOT touch m_role_permission.
+    - Idempotent and safe to re-run.
+    - PostgreSQL only.
+-->
+<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";>
+
+    <changeSet id="0245_delete_non_spaced_standinginstruction_permissions"

Review Comment:
   
   You were right, and my earlier reply had it backwards: the application 
checks the trimmed codes (`CommandWrapper` builds `CREATE_STANDINGINSTRUCTION`, 
and `Permission.hasCode` doesn't ignore the trailing space). The changeset now 
keeps the trimmed rows and deletes the trailing-space ones. Before deleting, it 
moves their role assignments to the trimmed rows, so the `RESTRICT` foreign key 
can't stop the migration and no role loses access.
   



##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java:
##########
@@ -299,8 +299,21 @@ public Page<StandingInstructionData> retrieveAll(final 
StandingInstructionDTO st
                 sqlBuilder.append(" fromsavacc.id=? ");
                 paramObj.add(standingInstructionDTO.fromAccount());
             } else if (PortfolioAccountType.LOAN.equals(accountType)) {
-                sqlBuilder.append(" fromloanacc.id=? ");
-                paramObj.add(standingInstructionDTO.fromAccount());
+                // For LOAN_REPAYMENT transfers, loan is stored in 
to_loan_account_id (FROM=SAVINGS, TO=LOAN)

Review Comment:
   
   Agreed: the result depended on the transfer type, which is fragile. A loan 
account filter now always matches `(toloanacc.id=? or fromloanacc.id=?)`, so 
the transfer type no longer decides which column is checked.
   



##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java:
##########
@@ -299,8 +299,21 @@ public Page<StandingInstructionData> retrieveAll(final 
StandingInstructionDTO st
                 sqlBuilder.append(" fromsavacc.id=? ");
                 paramObj.add(standingInstructionDTO.fromAccount());
             } else if (PortfolioAccountType.LOAN.equals(accountType)) {
-                sqlBuilder.append(" fromloanacc.id=? ");
-                paramObj.add(standingInstructionDTO.fromAccount());
+                // For LOAN_REPAYMENT transfers, loan is stored in 
to_loan_account_id (FROM=SAVINGS, TO=LOAN)
+                // For other transfer types, loan is stored in 
from_loan_account_id
+                // Defensive fallback: if transferType is null, check both 
columns to handle UI inconsistencies
+                Integer transferTypeValue = 
standingInstructionDTO.transferType();
+                if (transferTypeValue != null && 
transferTypeValue.equals(AccountTransferType.LOAN_REPAYMENT.getValue())) {
+                    sqlBuilder.append(" toloanacc.id=? ");

Review Comment:
   
   That branch is gone. `fromAccountId` is the account the caller filters by, 
so for a loan it is now matched against both loan columns.
   



##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java:
##########
@@ -299,8 +299,21 @@ public Page<StandingInstructionData> retrieveAll(final 
StandingInstructionDTO st
                 sqlBuilder.append(" fromsavacc.id=? ");
                 paramObj.add(standingInstructionDTO.fromAccount());
             } else if (PortfolioAccountType.LOAN.equals(accountType)) {
-                sqlBuilder.append(" fromloanacc.id=? ");
-                paramObj.add(standingInstructionDTO.fromAccount());
+                // For LOAN_REPAYMENT transfers, loan is stored in 
to_loan_account_id (FROM=SAVINGS, TO=LOAN)
+                // For other transfer types, loan is stored in 
from_loan_account_id
+                // Defensive fallback: if transferType is null, check both 
columns to handle UI inconsistencies
+                Integer transferTypeValue = 
standingInstructionDTO.transferType();
+                if (transferTypeValue != null && 
transferTypeValue.equals(AccountTransferType.LOAN_REPAYMENT.getValue())) {
+                    sqlBuilder.append(" toloanacc.id=? ");
+                    paramObj.add(standingInstructionDTO.fromAccount());
+                } else if (transferTypeValue == null) {
+                    sqlBuilder.append(" (toloanacc.id=? OR fromloanacc.id=?) 
");

Review Comment:
   
   The fallback is now the only loan filter: both columns are checked whether 
or not `transferType` is given. That also covers `LOAN_DOWN_PAYMENT` and the 
other non-`LOAN_REPAYMENT` types you mentioned.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to