diff --git a/migration/i2.1/oracle/201501111840_IDEMPIERE-1425.sql b/migration/i2.1/oracle/201501111840_IDEMPIERE-1425.sql new file mode 100644 index 0000000000..c70dc7f7c4 --- /dev/null +++ b/migration/i2.1/oracle/201501111840_IDEMPIERE-1425.sql @@ -0,0 +1,67 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jan 11, 2015 6:38:54 PM COT +-- IDEMPIERE-1425 Account element improvements +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (202809,0,0,'Y',TO_DATE('2015-01-11 18:38:53','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2015-01-11 18:38:53','YYYY-MM-DD HH24:MI:SS'),100,'IsTreeDrivenByValue','Driven By Search Key','Defines if the tree is driven by the Search Key column','D','9ff38eb0-bbe7-4584-8682-f82f5cf9152b') +; + +-- Jan 11, 2015 6:39:16 PM COT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure) VALUES (211812,0,'Driven By Search Key',288,'IsTreeDrivenByValue','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_DATE('2015-01-11 18:39:16','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2015-01-11 18:39:16','YYYY-MM-DD HH24:MI:SS'),100,202809,'Y','N','U','N','N','N','Y','a55184b0-1acc-433e-8df2-cd00b8aa77a3','Y',0,'N','N') +; + +-- Jan 11, 2015 6:39:17 PM COT +ALTER TABLE AD_Tree ADD IsTreeDrivenByValue CHAR(1) DEFAULT 'N' CHECK (IsTreeDrivenByValue IN ('Y','N')) NOT NULL +; + +-- Jan 11, 2015 6:39:32 PM COT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (203480,'Driven By Search Key',243,211812,'Y',1,100,'N','N','N','N',0,0,'Y',TO_DATE('2015-01-11 18:39:31','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2015-01-11 18:39:31','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','ac15015d-0eef-4e66-b2fb-6a2fa0f60a1f','Y',100,2,2) +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=70, XPosition=5,Updated=TO_DATE('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203480 +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET SeqNo=80,Updated=TO_DATE('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5228 +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET SeqNo=90,Updated=TO_DATE('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=12421 +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET SeqNo=100,Updated=TO_DATE('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8371 +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Element SET Name='Driven by Search Key',Updated=TO_DATE('2015-01-11 18:39:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=202809 +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Column SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Element_ID=202809 +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Process_Para SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL, AD_Element_ID=202809 WHERE UPPER(ColumnName)='ISTREEDRIVENBYVALUE' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Process_Para SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Element_ID=202809 AND IsCentrallyMaintained='Y' +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_InfoColumn SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Element_ID=202809 AND IsCentrallyMaintained='Y' +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Field SET Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=202809) AND IsCentrallyMaintained='Y' +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_PrintFormatItem SET PrintName='Defines if the tree is driven by the Search Key column', Name='Driven by Search Key' WHERE IsCentrallyMaintained='Y' AND EXISTS (SELECT * FROM AD_Column c WHERE c.AD_Column_ID=AD_PrintFormatItem.AD_Column_ID AND c.AD_Element_ID=202809) +; + +SELECT register_migration_script('201501111840_IDEMPIERE-1425.sql') FROM dual +; + diff --git a/migration/i2.1/postgresql/201501111840_IDEMPIERE-1425.sql b/migration/i2.1/postgresql/201501111840_IDEMPIERE-1425.sql new file mode 100644 index 0000000000..0a3f63a42c --- /dev/null +++ b/migration/i2.1/postgresql/201501111840_IDEMPIERE-1425.sql @@ -0,0 +1,64 @@ +-- Jan 11, 2015 6:38:54 PM COT +-- IDEMPIERE-1425 Account element improvements +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (202809,0,0,'Y',TO_TIMESTAMP('2015-01-11 18:38:53','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2015-01-11 18:38:53','YYYY-MM-DD HH24:MI:SS'),100,'IsTreeDrivenByValue','Driven By Search Key','Defines if the tree is driven by the Search Key column','D','9ff38eb0-bbe7-4584-8682-f82f5cf9152b') +; + +-- Jan 11, 2015 6:39:16 PM COT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure) VALUES (211812,0,'Driven By Search Key',288,'IsTreeDrivenByValue','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2015-01-11 18:39:16','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2015-01-11 18:39:16','YYYY-MM-DD HH24:MI:SS'),100,202809,'Y','N','U','N','N','N','Y','a55184b0-1acc-433e-8df2-cd00b8aa77a3','Y',0,'N','N') +; + +-- Jan 11, 2015 6:39:17 PM COT +ALTER TABLE AD_Tree ADD COLUMN IsTreeDrivenByValue CHAR(1) DEFAULT 'N' CHECK (IsTreeDrivenByValue IN ('Y','N')) NOT NULL +; + +-- Jan 11, 2015 6:39:32 PM COT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (203480,'Driven By Search Key',243,211812,'Y',1,100,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2015-01-11 18:39:31','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2015-01-11 18:39:31','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','ac15015d-0eef-4e66-b2fb-6a2fa0f60a1f','Y',100,2,2) +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=70, XPosition=5,Updated=TO_TIMESTAMP('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203480 +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET SeqNo=80,Updated=TO_TIMESTAMP('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5228 +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET SeqNo=90,Updated=TO_TIMESTAMP('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=12421 +; + +-- Jan 11, 2015 6:39:47 PM COT +UPDATE AD_Field SET SeqNo=100,Updated=TO_TIMESTAMP('2015-01-11 18:39:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8371 +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Element SET Name='Driven by Search Key',Updated=TO_TIMESTAMP('2015-01-11 18:39:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=202809 +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Column SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Element_ID=202809 +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Process_Para SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL, AD_Element_ID=202809 WHERE UPPER(ColumnName)='ISTREEDRIVENBYVALUE' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Process_Para SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Element_ID=202809 AND IsCentrallyMaintained='Y' +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_InfoColumn SET ColumnName='IsTreeDrivenByValue', Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Element_ID=202809 AND IsCentrallyMaintained='Y' +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_Field SET Name='Driven by Search Key', Description=NULL, Help=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=202809) AND IsCentrallyMaintained='Y' +; + +-- Jan 11, 2015 6:39:56 PM COT +UPDATE AD_PrintFormatItem SET PrintName='Defines if the tree is driven by the Search Key column', Name='Driven by Search Key' WHERE IsCentrallyMaintained='Y' AND EXISTS (SELECT * FROM AD_Column c WHERE c.AD_Column_ID=AD_PrintFormatItem.AD_Column_ID AND c.AD_Element_ID=202809) +; + +SELECT register_migration_script('201501111840_IDEMPIERE-1425.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Tree.java b/org.adempiere.base/src/org/compiere/model/I_AD_Tree.java index bb4fe607eb..d03a294ab6 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Tree.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Tree.java @@ -152,6 +152,15 @@ public interface I_AD_Tree */ public boolean isDefault(); + /** Column name IsTreeDrivenByValue */ + public static final String COLUMNNAME_IsTreeDrivenByValue = "IsTreeDrivenByValue"; + + /** Set Driven by Search Key */ + public void setIsTreeDrivenByValue (boolean IsTreeDrivenByValue); + + /** Get Driven by Search Key */ + public boolean isTreeDrivenByValue(); + /** Column name Name */ public static final String COLUMNNAME_Name = "Name"; diff --git a/org.adempiere.base/src/org/compiere/model/MActivity.java b/org.adempiere.base/src/org/compiere/model/MActivity.java index d7a87b6560..0cfa7e8af8 100644 --- a/org.adempiere.base/src/org/compiere/model/MActivity.java +++ b/org.adempiere.base/src/org/compiere/model/MActivity.java @@ -109,6 +109,8 @@ public class MActivity extends X_C_Activity return success; if (newRecord) insert_Tree(MTree_Base.TREETYPE_Activity); + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) + update_Tree(MTree_Base.TREETYPE_Activity); // Value/Name change if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))){ StringBuilder msguvd = new StringBuilder("C_Activity_ID=").append(getC_Activity_ID()); diff --git a/org.adempiere.base/src/org/compiere/model/MBPartner.java b/org.adempiere.base/src/org/compiere/model/MBPartner.java index c6eea18f51..28adf4c002 100644 --- a/org.adempiere.base/src/org/compiere/model/MBPartner.java +++ b/org.adempiere.base/src/org/compiere/model/MBPartner.java @@ -925,7 +925,9 @@ public class MBPartner extends X_C_BPartner */ protected boolean afterSave (boolean newRecord, boolean success) { - if (newRecord && success) + if (!success) + return success; + if (newRecord) { // Trees insert_Tree(MTree_Base.TREETYPE_BPartner); @@ -935,9 +937,11 @@ public class MBPartner extends X_C_BPartner insert_Accounting("C_BP_Vendor_Acct", "C_BP_Group_Acct",msgacc.toString()); // insert_Accounting("C_BP_Employee_Acct", "C_AcctSchema_Default", null); } + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) + update_Tree(MTree_Base.TREETYPE_BPartner); // Value/Name change - if (success && !newRecord + if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))){ StringBuilder msgacc = new StringBuilder("C_BPartner_ID=").append(getC_BPartner_ID()); MAccount.updateValueDescription(getCtx(), msgacc.toString(), get_TrxName()); diff --git a/org.adempiere.base/src/org/compiere/model/MCampaign.java b/org.adempiere.base/src/org/compiere/model/MCampaign.java index 208332642a..af05b9eded 100644 --- a/org.adempiere.base/src/org/compiere/model/MCampaign.java +++ b/org.adempiere.base/src/org/compiere/model/MCampaign.java @@ -70,6 +70,8 @@ public class MCampaign extends X_C_Campaign return success; if (newRecord) insert_Tree(MTree_Base.TREETYPE_Campaign); + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) + update_Tree(MTree_Base.TREETYPE_Campaign); // Value/Name change if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))) MAccount.updateValueDescription(getCtx(), "C_Campaign_ID=" + getC_Campaign_ID(), get_TrxName()); diff --git a/org.adempiere.base/src/org/compiere/model/MElementValue.java b/org.adempiere.base/src/org/compiere/model/MElementValue.java index ef12535d3e..7c880550ab 100644 --- a/org.adempiere.base/src/org/compiere/model/MElementValue.java +++ b/org.adempiere.base/src/org/compiere/model/MElementValue.java @@ -246,14 +246,16 @@ public class MElementValue extends X_C_ElementValue { if (!success) return success; - if (newRecord) + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) { // afalcone [Bugs #1837219] int ad_Tree_ID= (new MElement(getCtx(), getC_Element_ID(), get_TrxName())).getAD_Tree_ID(); String treeType= (new MTree(getCtx(),ad_Tree_ID,get_TrxName())).getTreeType(); - insert_Tree(treeType, getC_Element_ID()); - // insert_Tree(MTree_Base.TREETYPE_ElementValue, getC_Element_ID()); Old - + + if (newRecord) + insert_Tree(treeType, getC_Element_ID()); + + update_Tree(treeType); } // Value/Name change diff --git a/org.adempiere.base/src/org/compiere/model/MOrg.java b/org.adempiere.base/src/org/compiere/model/MOrg.java index b1d6dd9da3..f0ed6d80a2 100644 --- a/org.adempiere.base/src/org/compiere/model/MOrg.java +++ b/org.adempiere.base/src/org/compiere/model/MOrg.java @@ -156,6 +156,8 @@ public class MOrg extends X_AD_Org // TreeNode insert_Tree(MTree_Base.TREETYPE_Organization); } + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) + update_Tree(MTree_Base.TREETYPE_Organization); // Value/Name change if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))) { diff --git a/org.adempiere.base/src/org/compiere/model/MProduct.java b/org.adempiere.base/src/org/compiere/model/MProduct.java index 8abfdcc2b2..d6c9ef5fb9 100644 --- a/org.adempiere.base/src/org/compiere/model/MProduct.java +++ b/org.adempiere.base/src/org/compiere/model/MProduct.java @@ -704,6 +704,8 @@ public class MProduct extends X_M_Product "p.M_Product_Category_ID=" + getM_Product_Category_ID()); insert_Tree(X_AD_Tree.TREETYPE_Product); } + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) + update_Tree(MTree_Base.TREETYPE_Product); // New Costing if (newRecord || is_ValueChanged("M_Product_Category_ID")) diff --git a/org.adempiere.base/src/org/compiere/model/MProject.java b/org.adempiere.base/src/org/compiere/model/MProject.java index 271caa4438..19d33def5b 100644 --- a/org.adempiere.base/src/org/compiere/model/MProject.java +++ b/org.adempiere.base/src/org/compiere/model/MProject.java @@ -428,14 +428,18 @@ public class MProject extends X_C_Project */ protected boolean afterSave (boolean newRecord, boolean success) { - if (newRecord && success) + if (!success) + return success; + if (newRecord) { insert_Accounting("C_Project_Acct", "C_AcctSchema_Default", null); insert_Tree(MTree_Base.TREETYPE_Project); } + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) + update_Tree(MTree_Base.TREETYPE_Project); // Value/Name change - if (success && !newRecord + if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))) MAccount.updateValueDescription(getCtx(), "C_Project_ID=" + getC_Project_ID(), get_TrxName()); diff --git a/org.adempiere.base/src/org/compiere/model/MSalesRegion.java b/org.adempiere.base/src/org/compiere/model/MSalesRegion.java index b537701167..e94add42a9 100644 --- a/org.adempiere.base/src/org/compiere/model/MSalesRegion.java +++ b/org.adempiere.base/src/org/compiere/model/MSalesRegion.java @@ -106,6 +106,8 @@ public class MSalesRegion extends X_C_SalesRegion return success; if (newRecord) insert_Tree(MTree_Base.TREETYPE_SalesRegion); + if (newRecord || is_ValueChanged(COLUMNNAME_Value)) + update_Tree(MTree_Base.TREETYPE_SalesRegion); // Value/Name change if (!newRecord && (is_ValueChanged("Value") || is_ValueChanged("Name"))) MAccount.updateValueDescription(getCtx(), "C_SalesRegion_ID=" + getC_SalesRegion_ID(), get_TrxName()); diff --git a/org.adempiere.base/src/org/compiere/model/MTree.java b/org.adempiere.base/src/org/compiere/model/MTree.java index b96f0bdb1e..1478285c45 100644 --- a/org.adempiere.base/src/org/compiere/model/MTree.java +++ b/org.adempiere.base/src/org/compiere/model/MTree.java @@ -408,8 +408,7 @@ public class MTree extends MTree_Base String fromClause = getSourceTableName(false); // fully qualified String columnNameX = getSourceTableName(true); String color = getActionColorName(); - if (getTreeType().equals(TREETYPE_Menu)) - { + if (getTreeType().equals(TREETYPE_Menu)) { boolean base = Env.isBaseLanguage(p_ctx, "AD_Menu"); sourceTable = "m"; if (base) @@ -450,9 +449,13 @@ public class MTree extends MTree_Base sqlNode.append("f.JSPURL"); sqlNode.append(" IS NOT NULL))"); } - } - else - { + } else if (getTreeType().equals(TREETYPE_ElementValue)) { + sqlNode.append("SELECT t.").append(columnNameX) + .append("_ID, t.Value || ' - ' || t.Name, t.Description, t.IsSummary,").append(color) + .append(" FROM ").append(fromClause); + if (!m_editable) + sqlNode.append(" WHERE t.IsActive='Y'"); + } else { if (columnNameX == null) throw new IllegalArgumentException("Unknown TreeType=" + getTreeType()); sqlNode.append("SELECT t.").append(columnNameX) diff --git a/org.adempiere.base/src/org/compiere/model/MTree_Base.java b/org.adempiere.base/src/org/compiere/model/MTree_Base.java index c9c4be663c..f0497df8bd 100644 --- a/org.adempiere.base/src/org/compiere/model/MTree_Base.java +++ b/org.adempiere.base/src/org/compiere/model/MTree_Base.java @@ -342,6 +342,17 @@ public class MTree_Base extends X_AD_Tree { if (!isActive() || !isAllNodes()) setIsDefault(false); + + if (isTreeDrivenByValue()) { + String tableName = getSourceTableName(true); + MTable table = MTable.get(getCtx(), tableName); + // Value and IsSummary are mandatory columns to have a tree driven by Value + if ( table.getColumn("Value") == null + || table.getColumn("IsSummary") == null) { + setIsTreeDrivenByValue(false); + } + } + return true; } // beforeSabe diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index 635501bd7e..50c8af2a14 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -106,7 +106,7 @@ public abstract class PO /** * */ - private static final long serialVersionUID = -591429462738850345L; + private static final long serialVersionUID = -2731993630208549493L; public static final String LOCAL_TRX_PREFIX = "POSave"; @@ -3869,6 +3869,63 @@ public abstract class PO return no > 0; } // insert_Tree + /** + * Update parent key and seqno based on value if the tree is driven by value + * @param treeType MTree TREETYPE_* + * @return true if inserted + */ + protected void update_Tree (String treeType) + { + int idxValueCol = get_ColumnIndex("Value"); + if (idxValueCol < 0) + return; + int idxValueIsSummary = get_ColumnIndex("IsSummary"); + if (idxValueIsSummary < 0) + return; + String value = get_Value(idxValueCol).toString(); + if (value == null) + return; + + String tableName = MTree_Base.getNodeTableName(treeType); + String sourceTableName = MTree_Base.getSourceTableName(treeType); + String updateSeqNo = "UPDATE " + tableName + " SET SeqNo=SeqNo+1 WHERE Parent_ID=? AND SeqNo>=? AND AD_Tree_ID=?"; + String update = "UPDATE " + tableName + " SET SeqNo=?, Parent_ID=? WHERE Node_ID=? AND AD_Tree_ID=?"; + String selMinSeqNo = "SELECT COALESCE(MIN(tn.SeqNo),-1) FROM AD_TreeNode tn JOIN " + sourceTableName + " n ON (tn.Node_ID=n." + sourceTableName + "_ID) WHERE tn.Parent_ID=? AND tn.AD_Tree_ID=? AND n.Value>?"; + String selMaxSeqNo = "SELECT COALESCE(MAX(tn.SeqNo)+1,999) FROM AD_TreeNode tn JOIN " + sourceTableName + " n ON (tn.Node_ID=n." + sourceTableName + "_ID) WHERE tn.Parent_ID=? AND tn.AD_Tree_ID=? AND n.Value<?"; + + List<MTree_Base> trees = new Query(getCtx(), MTree_Base.Table_Name, "TreeType=?", get_TrxName()) + .setClient_ID() + .setOnlyActiveRecords(true) + .setParameters(treeType) + .list(); + + for (MTree_Base tree : trees) { + if (tree.isTreeDrivenByValue()) { + int newParentID = retrieveIdOfParentValue(value, sourceTableName, getAD_Client_ID(), get_TrxName()); + int seqNo = DB.getSQLValueEx(get_TrxName(), selMinSeqNo, newParentID, tree.getAD_Tree_ID(), value); + if (seqNo == -1) + seqNo = DB.getSQLValueEx(get_TrxName(), selMaxSeqNo, newParentID, tree.getAD_Tree_ID(), value); + DB.executeUpdateEx(updateSeqNo, new Object[] {newParentID, seqNo, tree.getAD_Tree_ID()}, get_TrxName()); + DB.executeUpdateEx(update, new Object[] {seqNo, newParentID, get_ID(), tree.getAD_Tree_ID()}, get_TrxName()); + } + } + } // update_Tree + + /** Returns the summary node with the corresponding value */ + public static int retrieveIdOfParentValue(String value, String tableName, int clientID, String trxName) + { + String sql = "SELECT " + tableName + "_ID FROM " + tableName + " WHERE IsSummary='Y' AND AD_Client_ID=? AND Value=?"; + int pos = value.length()-1; + while (pos > 0) { + String testParentValue = value.substring(0, pos); + int parentID = DB.getSQLValueEx(trxName, sql, clientID, testParentValue); + if (parentID > 0) + return parentID; + pos--; + } + return 0; // rootID + } + /** * Delete ID Tree Nodes * @param treeType MTree TREETYPE_* diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Tree.java b/org.adempiere.base/src/org/compiere/model/X_AD_Tree.java index a5cfaacd2c..79a0bc6fb8 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Tree.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Tree.java @@ -30,7 +30,7 @@ public class X_AD_Tree extends PO implements I_AD_Tree, I_Persistent /** * */ - private static final long serialVersionUID = 20141030L; + private static final long serialVersionUID = 20150111L; /** Standard Constructor */ public X_AD_Tree (Properties ctx, int AD_Tree_ID, String trxName) @@ -41,6 +41,8 @@ public class X_AD_Tree extends PO implements I_AD_Tree, I_Persistent setAD_Tree_ID (0); setIsAllNodes (false); setIsDefault (false); +// N + setIsTreeDrivenByValue (false); // N setName (null); setTreeType (null); @@ -177,6 +179,27 @@ public class X_AD_Tree extends PO implements I_AD_Tree, I_Persistent return false; } + /** Set Driven by Search Key. + @param IsTreeDrivenByValue Driven by Search Key */ + public void setIsTreeDrivenByValue (boolean IsTreeDrivenByValue) + { + set_Value (COLUMNNAME_IsTreeDrivenByValue, Boolean.valueOf(IsTreeDrivenByValue)); + } + + /** Get Driven by Search Key. + @return Driven by Search Key */ + public boolean isTreeDrivenByValue () + { + Object oo = get_Value(COLUMNNAME_IsTreeDrivenByValue); + if (oo != null) + { + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + return "Y".equals(oo); + } + return false; + } + /** Set Name. @param Name Alphanumeric identifier of the entity diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java index 19a29d9fd6..a58743fdab 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java @@ -69,6 +69,7 @@ import org.compiere.model.MToolBarButton; import org.compiere.model.MToolBarButtonRestrict; import org.compiere.model.MTree; import org.compiere.model.MTreeNode; +import org.compiere.model.PO; import org.compiere.model.Query; import org.compiere.model.X_AD_FieldGroup; import org.compiere.model.X_AD_ToolBarButton; @@ -1247,9 +1248,14 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer refresh = false; } } + // Remove the node if driven by value; will be re-added right after + if ("Saved".equals(e.getAD_Message()) && model.find(null, gridTab.getRecord_ID())!=null && isTreeDrivenByValue()) + model.removeNode(model.find(null, gridTab.getRecord_ID())); if ("Saved".equals(e.getAD_Message()) && model.find(null, gridTab.getRecord_ID())==null) { addNewNode(); + if (isTreeDrivenByValue()) + treePanel.prepareForRefresh(); } if (refresh) { @@ -1313,10 +1319,25 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer SimpleTreeModel model = (SimpleTreeModel)(TreeModel<?>) treePanel.getTree().getModel(); DefaultTreeNode<Object> treeNode = model.getRoot(); MTreeNode root = (MTreeNode) treeNode.getData(); + + int parentID = root.getNode_ID(); + DefaultTreeNode<Object> parentNode = null; + if (isTreeDrivenByValue()) { + String value = gridTab.getValue("Value").toString(); + parentID = PO.retrieveIdOfParentValue(value, getTableName(), Env.getAD_Client_ID(Env.getCtx()), null); + parentNode = model.find(treeNode, parentID); + name = value + " - " + name; + } MTreeNode node = new MTreeNode (gridTab.getRecord_ID(), 0, name, description, - root.getNode_ID(), summary, imageIndicator, false, null); + parentID, summary, imageIndicator, false, null); DefaultTreeNode<Object> newNode = new DefaultTreeNode<Object>(node); - model.addNode(newNode); + + if (isTreeDrivenByValue() && parentNode != null) { + model.addNode(parentNode, newNode, 0); + } else { + model.addNode(newNode); + } + int[] path = model.getPath(newNode); Treeitem ti = treePanel.getTree().renderItemByPath(path); treePanel.getTree().setSelectedItem(ti); @@ -1344,7 +1365,16 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } boolean changed = false; - if (Env.isBaseLanguage(Env.getCtx(), "AD_Menu")) { + if (isTreeDrivenByValue()) { + String value = (String) gridTab.getValue("Value"); + String name = (String) gridTab.getValue("Name"); + String full = value + " - " + name; + + if (full != null && !full.equals(data.getName())) { + data.setName(full); + changed = true; + } + } else if (Env.isBaseLanguage(Env.getCtx(), "AD_Menu")) { String name = (String) gridTab.getValue("Name"); if (name != null && !name.equals(data.getName())) { data.setName(name); @@ -1662,5 +1692,12 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer listPanel.onADTabPanelParentChanged(); } } -} + private boolean isTreeDrivenByValue() { + SimpleTreeModel model = (SimpleTreeModel)(TreeModel<?>) treePanel.getTree().getModel(); + boolean retValue = false; + retValue = model.isTreeDrivenByValue(); + return retValue; + } + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTreePanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTreePanel.java index afccfd5cc8..035ee11515 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTreePanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTreePanel.java @@ -41,7 +41,8 @@ public class ADTreePanel extends Panel implements EventListener<Event> /** * */ - private static final long serialVersionUID = -3046550099597437942L; + private static final long serialVersionUID = -6868506934553777046L; + private static final String ON_EXPAND_MENU_EVENT = "onExpandMenu"; private TreeSearchPanel pnlSearch; private Tree tree; @@ -180,4 +181,9 @@ public class ADTreePanel extends Panel implements EventListener<Event> collapseAll(); } // + + public void prepareForRefresh() { + this.AD_Tree_ID = -1; + } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java index 582938ab0c..a477f557a2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java @@ -43,11 +43,10 @@ import org.zkoss.zul.event.TreeDataEvent; * */ public class SimpleTreeModel extends org.zkoss.zul.DefaultTreeModel<Object> implements TreeitemRenderer<Object>, EventListener<Event> { - /** * */ - private static final long serialVersionUID = -4649471521757131755L; + private static final long serialVersionUID = -2689107390272278321L; private static final CLogger logger = CLogger.getCLogger(SimpleTreeModel.class); @@ -81,6 +80,7 @@ public class SimpleTreeModel extends org.zkoss.zul.DefaultTreeModel<Object> impl MTreeNode root = vTree.getRoot(); SimpleTreeModel treeModel = SimpleTreeModel.createFrom(root); treeModel.setItemDraggable(true); + treeModel.setTreeDrivenByValue(vTree.isTreeDrivenByValue()); treeModel.addOnDropEventListener(new ADTreeOnDropListener(tree, treeModel, vTree, windowNo)); if (tree.getTreecols() == null) @@ -102,7 +102,17 @@ public class SimpleTreeModel extends org.zkoss.zul.DefaultTreeModel<Object> impl return treeModel; } - + + private boolean isTreeDrivenByValue = false; + + public boolean isTreeDrivenByValue() { + return isTreeDrivenByValue; + } + + public void setTreeDrivenByValue(boolean isTreeDrivenByValue) { + this.isTreeDrivenByValue = isTreeDrivenByValue; + } + /** * * @param root @@ -168,6 +178,8 @@ public class SimpleTreeModel extends org.zkoss.zul.DefaultTreeModel<Object> impl ZkCssHelper.appendStyle(tc, "color: #" + hex); } ti.setTooltiptext(mNode.getDescription()); + if (mNode.isSummary()) + ZkCssHelper.appendStyle(tc, "font-weight: bold"); } // End color }else{