IDEMPIERE-5094 Implement validation for costing level change ( Accounting Schema and Product Category Accounting ) (#1235)

This commit is contained in:
hengsin 2022-03-11 19:43:22 +08:00 committed by GitHub
parent 3cc23af0fe
commit 9d0eea8fe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 0 deletions

View File

@ -0,0 +1,10 @@
SELECT register_migration_script('202203090311_IDEMPIERE-5094.sql') FROM dual
;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-5094 Implement validation for costing level change ( Accounting Schema and Product Category Accounting )
INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Message_UU,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,200478,'dc008155-cfe9-4394-9280-4817f3bb4f21',0,TO_DATE('2022-03-08 15:22:40','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','Costing level can''t be changed if there are product cost details created with current costing level','E',TO_DATE('2022-03-08 15:22:40','YYYY-MM-DD HH24:MI:SS'),100,'ChangeCostingLevelError')
;

View File

@ -0,0 +1,8 @@
SELECT register_migration_script('202203090311_IDEMPIERE-5094.sql') FROM dual
;
-- IDEMPIERE-5094 Implement validation for costing level change ( Accounting Schema and Product Category Accounting )
INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Message_UU,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,200478,'dc008155-cfe9-4394-9280-4817f3bb4f21',0,TO_TIMESTAMP('2022-03-08 15:22:40','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','Costing level can''t be changed if there are product cost details created with current costing level','E',TO_TIMESTAMP('2022-03-08 15:22:40','YYYY-MM-DD HH24:MI:SS'),100,'ChangeCostingLevelError')
;

View File

@ -25,8 +25,11 @@ import java.util.logging.Level;
import org.compiere.report.MReportTree; import org.compiere.report.MReportTree;
import org.compiere.util.CCache; import org.compiere.util.CCache;
import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.KeyNamePair; import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.idempiere.cache.ImmutableIntPOCache; import org.idempiere.cache.ImmutableIntPOCache;
import org.idempiere.cache.ImmutablePOSupport; import org.idempiere.cache.ImmutablePOSupport;
@ -712,9 +715,35 @@ public class MAcctSchema extends X_C_AcctSchema implements ImmutablePOSupport
if (info.getC_AcctSchema1_ID() == getC_AcctSchema_ID()) if (info.getC_AcctSchema1_ID() == getC_AcctSchema_ID())
setAD_OrgOnly_ID(0); setAD_OrgOnly_ID(0);
} }
if (!newRecord && is_ValueChanged(COLUMNNAME_CostingLevel))
{
String products = getProductsWithCost();
if (!Util.isEmpty(products)) {
log.saveError("Error", Msg.getMsg(getCtx(), "ChangeCostingLevelError") + ". Products: " + products);
return false;
}
}
return true; return true;
} // beforeSave } // beforeSave
private String getProductsWithCost() {
StringBuilder products = new StringBuilder();
StringBuilder sql = new StringBuilder("SELECT DISTINCT p.Value FROM M_Product p JOIN M_CostDetail d ON p.M_Product_ID=d.M_Product_ID");
sql.append(" JOIN M_Product_Category_Acct pc ON p.M_Product_Category_ID=pc.M_Product_Category_ID AND d.C_AcctSchema_ID=pc.C_AcctSchema_ID");
sql.append(" WHERE p.IsActive='Y' AND pc.IsActive='Y' AND pc.CostingLevel IS NULL AND d.C_AcctSchema_ID=?");
String query = DB.getDatabase().addPagingSQL(sql.toString(), 0, 50);
List<List<Object>> list = DB.getSQLArrayObjectsEx(get_TrxName(), query, getC_AcctSchema_ID());
if (list != null) {
for(List<Object> entry : list) {
String value = (String) entry.get(0);
if (products.length() > 0)
products.append(",");
products.append(value);
}
}
return products.toString();
}
@Override @Override
public MAcctSchema markImmutable() public MAcctSchema markImmutable()
{ {

View File

@ -17,9 +17,13 @@
package org.compiere.model; package org.compiere.model;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.idempiere.cache.ImmutablePOSupport; import org.idempiere.cache.ImmutablePOSupport;
import org.idempiere.cache.ImmutablePOCache; import org.idempiere.cache.ImmutablePOCache;
@ -192,4 +196,41 @@ public class MProductCategoryAcct extends X_M_Product_Category_Acct implements I
return sb.toString (); return sb.toString ();
} // toString } // toString
@Override
protected boolean beforeSave(boolean newRecord) {
if (!newRecord && is_ValueChanged(COLUMNNAME_CostingLevel)) {
String newCostingLevel = getCostingLevel();
String oldCostingLevel = (String) get_ValueOld(COLUMNNAME_CostingLevel);
I_C_AcctSchema schema = getC_AcctSchema();
if (newCostingLevel == null)
newCostingLevel = schema.getCostingLevel();
if (oldCostingLevel == null)
oldCostingLevel = schema.getCostingLevel();
if (!newCostingLevel.equals(oldCostingLevel)) {
String products = getProductsWithCost();
if (!Util.isEmpty(products)) {
log.saveError("Error", Msg.getMsg(getCtx(), "ChangeCostingLevelError") + ". Products: " + products);
return false;
}
}
}
return true;
}
private String getProductsWithCost() {
StringBuilder products = new StringBuilder();
StringBuilder sql = new StringBuilder("SELECT DISTINCT p.Value FROM M_Product p JOIN M_CostDetail d ON p.M_Product_ID=d.M_Product_ID");
sql.append(" WHERE p.IsActive='Y' AND p.M_Product_Category_ID=? AND d.C_AcctSchema_ID=?");
String query = DB.getDatabase().addPagingSQL(sql.toString(), 0, 50);
List<List<Object>> list = DB.getSQLArrayObjectsEx(get_TrxName(), query, getM_Product_Category_ID(), getC_AcctSchema_ID());
if (list != null) {
for(List<Object> entry : list) {
String value = (String) entry.get(0);
if (products.length() > 0)
products.append(",");
products.append(value);
}
}
return products.toString();
}
} // MProductCategoryAcct } // MProductCategoryAcct