Product Category Tree enhancement - as discussed here:
http://sourceforge.net/forum/forum.php?thread_id=1721178&forum_id=611158
This commit is contained in:
parent
4edc8f6676
commit
a4da34825a
|
@ -0,0 +1,146 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
* For the text or an alternative of this public license, you may reach us *
|
||||||
|
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||||
|
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.compiere.model;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Product Category Callouts
|
||||||
|
*
|
||||||
|
* @author Karsten Thiemann kthiemann@adempiere.org
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CalloutProductCategory extends CalloutEngine
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Loop detection of product category tree.
|
||||||
|
*
|
||||||
|
* @param ctx context
|
||||||
|
* @param WindowNo current Window No
|
||||||
|
* @param mTab Grid Tab
|
||||||
|
* @param mField Grid Field
|
||||||
|
* @param value New Value
|
||||||
|
* @return "" or error message
|
||||||
|
*/
|
||||||
|
public String testForLoop (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
|
||||||
|
{
|
||||||
|
if (isCalloutActive() || value == null)
|
||||||
|
return "";
|
||||||
|
setCalloutActive(true);
|
||||||
|
|
||||||
|
// get values
|
||||||
|
Integer newParentCategoryId = (Integer) mTab.getValue(MProductCategory.COLUMNNAME_M_Product_Category_Parent_ID);
|
||||||
|
Integer productCategoryId = (Integer) mTab.getValue(MProductCategory.COLUMNNAME_M_Product_Category_ID);
|
||||||
|
|
||||||
|
String sql = " SELECT M_Product_Category_ID, M_Product_Category_Parent_ID FROM M_Product_Category";
|
||||||
|
final Vector<SimpleTreeNode> categories = new Vector<SimpleTreeNode>(100);
|
||||||
|
try {
|
||||||
|
Statement stmt = DB.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery(sql);
|
||||||
|
while (rs.next()) {
|
||||||
|
if(rs.getInt(1)==productCategoryId.intValue()) {
|
||||||
|
categories.add(new SimpleTreeNode(rs.getInt(1), newParentCategoryId));
|
||||||
|
}
|
||||||
|
categories.add(new SimpleTreeNode(rs.getInt(1), rs.getInt(2)));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
stmt.close();
|
||||||
|
if(hasLoop(newParentCategoryId, categories, productCategoryId)) {
|
||||||
|
mField.setValue(0, false);
|
||||||
|
|
||||||
|
setCalloutActive(false);
|
||||||
|
return "ProductCategoryLoopDetected";
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
setCalloutActive(false);
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
setCalloutActive(false);
|
||||||
|
return "";
|
||||||
|
} // testForLoop
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive search for parent nodes - climbes the to the root.
|
||||||
|
* If there is a circle there is no root but it comes back to the start node.
|
||||||
|
* @param parentCategoryId
|
||||||
|
* @param categories
|
||||||
|
* @param loopIndicatorId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean hasLoop(int parentCategoryId, Vector<SimpleTreeNode> categories, int loopIndicatorId) {
|
||||||
|
final Iterator iter = categories.iterator();
|
||||||
|
boolean ret = false;
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
SimpleTreeNode node = (SimpleTreeNode) iter.next();
|
||||||
|
if(node.getNodeId()==parentCategoryId){
|
||||||
|
if (node.getParentId()==0) {
|
||||||
|
//root node, all fine
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(node.getNodeId()==loopIndicatorId){
|
||||||
|
//loop found
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ret = hasLoop(node.getParentId(), categories, loopIndicatorId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} //hasLoop
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple class for tree nodes.
|
||||||
|
* @author Karsten Thiemann, kthiemann@adempiere.org
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class SimpleTreeNode {
|
||||||
|
/** id of the node */
|
||||||
|
private int nodeId;
|
||||||
|
/** id of the nodes parent */
|
||||||
|
private int parentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* @param nodeId
|
||||||
|
* @param parentId
|
||||||
|
*/
|
||||||
|
public SimpleTreeNode(int nodeId, int parentId) {
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
this.parentId = parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNodeId() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParentId() {
|
||||||
|
return parentId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // CalloutProductCategory
|
|
@ -22,6 +22,7 @@ import java.math.*;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.*;
|
import javax.swing.event.*;
|
||||||
import javax.swing.table.*;
|
import javax.swing.table.*;
|
||||||
|
@ -616,9 +617,12 @@ public final class Find extends CDialog
|
||||||
// globalqss - Carlos Ruiz - 20060711
|
// globalqss - Carlos Ruiz - 20060711
|
||||||
// fix a bug with virtualColumn + isSelectionColumn not yielding results
|
// fix a bug with virtualColumn + isSelectionColumn not yielding results
|
||||||
GridField field = getTargetMField(ColumnName);
|
GridField field = getTargetMField(ColumnName);
|
||||||
|
boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
|
||||||
String ColumnSQL = field.getColumnSQL(false);
|
String ColumnSQL = field.getColumnSQL(false);
|
||||||
if (value.toString().indexOf('%') != -1)
|
if (value.toString().indexOf('%') != -1)
|
||||||
m_query.addRestriction(ColumnSQL, MQuery.LIKE, value, ColumnName, ved.getDisplay());
|
m_query.addRestriction(ColumnSQL, MQuery.LIKE, value, ColumnName, ved.getDisplay());
|
||||||
|
else if (isProductCategoryField && value instanceof Integer)
|
||||||
|
m_query.addRestriction(getSubCategoryWhereClause(((Integer) value).intValue()));
|
||||||
else
|
else
|
||||||
m_query.addRestriction(ColumnSQL, MQuery.EQUAL, value, ColumnName, ved.getDisplay());
|
m_query.addRestriction(ColumnSQL, MQuery.EQUAL, value, ColumnName, ved.getDisplay());
|
||||||
/*
|
/*
|
||||||
|
@ -698,6 +702,7 @@ public final class Find extends CDialog
|
||||||
String infoName = column.toString();
|
String infoName = column.toString();
|
||||||
//
|
//
|
||||||
GridField field = getTargetMField(ColumnName);
|
GridField field = getTargetMField(ColumnName);
|
||||||
|
boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
|
||||||
String ColumnSQL = field.getColumnSQL(false);
|
String ColumnSQL = field.getColumnSQL(false);
|
||||||
// Op
|
// Op
|
||||||
Object op = advancedTable.getValueAt(row, INDEX_OPERATOR);
|
Object op = advancedTable.getValueAt(row, INDEX_OPERATOR);
|
||||||
|
@ -730,12 +735,118 @@ public final class Find extends CDialog
|
||||||
m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2,
|
m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2,
|
||||||
infoName, infoDisplay, infoDisplay_to);
|
infoName, infoDisplay, infoDisplay_to);
|
||||||
}
|
}
|
||||||
|
else if (isProductCategoryField && MQuery.OPERATORS[MQuery.EQUAL_INDEX].equals(op)) {
|
||||||
|
if (!(parsedValue instanceof Integer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_query
|
||||||
|
|
||||||
|
.addRestriction(getSubCategoryWhereClause(((Integer) parsedValue).intValue()));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_query.addRestriction(ColumnSQL, Operator, parsedValue,
|
m_query.addRestriction(ColumnSQL, Operator, parsedValue,
|
||||||
infoName, infoDisplay);
|
infoName, infoDisplay);
|
||||||
}
|
}
|
||||||
} // cmd_save
|
} // cmd_save
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the given column.
|
||||||
|
* @param columnId
|
||||||
|
* @return true if the column is a product category column
|
||||||
|
*/
|
||||||
|
private boolean isProductCategoryField(int columnId) {
|
||||||
|
X_AD_Column col = new X_AD_Column(Env.getCtx(), columnId, null);
|
||||||
|
if (col.get_ID() == 0) {
|
||||||
|
return false; // column not found...
|
||||||
|
}
|
||||||
|
return MProduct.COLUMNNAME_M_Product_Category_ID.equals(col.getColumnName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a sql where string with the given category id and all of its subcategory ids.
|
||||||
|
* It is used as restriction in MQuery.
|
||||||
|
* @param productCategoryId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getSubCategoryWhereClause(int productCategoryId) {
|
||||||
|
//if a node with this id is found later in the search we have a loop in the tree
|
||||||
|
int subTreeRootParentId = 0;
|
||||||
|
String retString = " M_Product_Category_ID IN (";
|
||||||
|
String sql = " SELECT M_Product_Category_ID, M_Product_Category_Parent_ID FROM M_Product_Category";
|
||||||
|
final Vector<SimpleTreeNode> categories = new Vector<SimpleTreeNode>(100);
|
||||||
|
try {
|
||||||
|
Statement stmt = DB.createStatement();
|
||||||
|
ResultSet rs = stmt.executeQuery(sql);
|
||||||
|
while (rs.next()) {
|
||||||
|
if(rs.getInt(1)==productCategoryId) {
|
||||||
|
subTreeRootParentId = rs.getInt(2);
|
||||||
|
}
|
||||||
|
categories.add(new SimpleTreeNode(rs.getInt(1), rs.getInt(2)));
|
||||||
|
}
|
||||||
|
retString += getSubCategoriesString(productCategoryId, categories, subTreeRootParentId);
|
||||||
|
retString += ") ";
|
||||||
|
rs.close();
|
||||||
|
stmt.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
retString = "";
|
||||||
|
} catch (AdempiereSystemError e) {
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
retString = "";
|
||||||
|
}
|
||||||
|
return retString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive search for subcategories with loop detection.
|
||||||
|
* @param productCategoryId
|
||||||
|
* @param categories
|
||||||
|
* @param loopIndicatorId
|
||||||
|
* @return comma seperated list of category ids
|
||||||
|
* @throws AdempiereSystemError if a loop is detected
|
||||||
|
*/
|
||||||
|
private String getSubCategoriesString(int productCategoryId, Vector<SimpleTreeNode> categories, int loopIndicatorId) throws AdempiereSystemError {
|
||||||
|
String ret = "";
|
||||||
|
final Iterator iter = categories.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
SimpleTreeNode node = (SimpleTreeNode) iter.next();
|
||||||
|
if (node.getParentId() == productCategoryId) {
|
||||||
|
if (node.getNodeId() == loopIndicatorId) {
|
||||||
|
throw new AdempiereSystemError("The product category tree contains a loop on categoryId: " + loopIndicatorId);
|
||||||
|
}
|
||||||
|
ret = ret + getSubCategoriesString(node.getNodeId(), categories, loopIndicatorId) + ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.fine(ret);
|
||||||
|
return ret + productCategoryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple tree node class for product category tree search.
|
||||||
|
* @author Karsten Thiemann, kthiemann@adempiere.org
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class SimpleTreeNode {
|
||||||
|
|
||||||
|
private int nodeId;
|
||||||
|
|
||||||
|
private int parentId;
|
||||||
|
|
||||||
|
public SimpleTreeNode(int nodeId, int parentId) {
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
this.parentId = parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNodeId() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParentId() {
|
||||||
|
return parentId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse Value
|
* Parse Value
|
||||||
* @param field column
|
* @param field column
|
||||||
|
|
|
@ -232,6 +232,27 @@ return ii.intValue();
|
||||||
}
|
}
|
||||||
/** Column name M_Product_Category_ID */
|
/** Column name M_Product_Category_ID */
|
||||||
public static final String COLUMNNAME_M_Product_Category_ID = "M_Product_Category_ID";
|
public static final String COLUMNNAME_M_Product_Category_ID = "M_Product_Category_ID";
|
||||||
|
|
||||||
|
/** M_Product_Category_Parent_ID AD_Reference_ID=163 */
|
||||||
|
public static final int M_PRODUCT_CATEGORY_PARENT_ID_AD_Reference_ID=163;
|
||||||
|
/** Set Parent Product Category.
|
||||||
|
@param M_Product_Category_Parent_ID Parent Product Category */
|
||||||
|
public void setM_Product_Category_Parent_ID (int M_Product_Category_Parent_ID)
|
||||||
|
{
|
||||||
|
if (M_Product_Category_Parent_ID <= 0) set_Value ("M_Product_Category_Parent_ID", null);
|
||||||
|
else
|
||||||
|
set_Value ("M_Product_Category_Parent_ID", Integer.valueOf(M_Product_Category_Parent_ID));
|
||||||
|
}
|
||||||
|
/** Get Parent Product Category.
|
||||||
|
@return Parent Product Category */
|
||||||
|
public int getM_Product_Category_Parent_ID()
|
||||||
|
{
|
||||||
|
Integer ii = (Integer)get_Value("M_Product_Category_Parent_ID");
|
||||||
|
if (ii == null) return 0;
|
||||||
|
return ii.intValue();
|
||||||
|
}
|
||||||
|
/** Column name M_Product_Category_Parent_ID */
|
||||||
|
public static final String COLUMNNAME_M_Product_Category_Parent_ID = "M_Product_Category_Parent_ID";
|
||||||
/** Set Name.
|
/** Set Name.
|
||||||
@param Name Alphanumeric identifier of the entity */
|
@param Name Alphanumeric identifier of the entity */
|
||||||
public void setName (String Name)
|
public void setName (String Name)
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
INSERT INTO ad_element
|
||||||
|
(ad_element_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created, createdby,
|
||||||
|
updated, updatedby,
|
||||||
|
columnname, entitytype, NAME,
|
||||||
|
printname
|
||||||
|
)
|
||||||
|
VALUES (50070, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
'M_Product_Category_Parent_ID', 'D', 'Parent Product Category',
|
||||||
|
'Parent Product Category'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO ad_column
|
||||||
|
(ad_column_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created,
|
||||||
|
updated, createdby,
|
||||||
|
updatedby, name, description, help, version,
|
||||||
|
entitytype, columnname, ad_table_id, ad_reference_id,
|
||||||
|
ad_reference_value_id,
|
||||||
|
fieldlength, iskey, isparent, ismandatory, isupdateable,
|
||||||
|
isidentifier, seqno, istranslated, isencrypted,
|
||||||
|
isselectioncolumn, ad_element_id, callout, issyncdatabase,
|
||||||
|
isalwaysupdateable
|
||||||
|
)
|
||||||
|
VALUES (50211, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'),
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
100, 'Parent Product Category', 'Parent Product Category', 'The parent product category is used to build a category tree.', 1,
|
||||||
|
'D', 'M_Product_Category_Parent_ID', 209, 18,
|
||||||
|
163,
|
||||||
|
22, 'N', 'N', 'N', 'Y',
|
||||||
|
'N', 0, 'N', 'N',
|
||||||
|
'N', 50070, 'org.compiere.model.CalloutProductCategory.testForLoop', 'N',
|
||||||
|
'N'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO ad_field
|
||||||
|
(ad_field_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created, createdby,
|
||||||
|
updated, updatedby,
|
||||||
|
name, description, iscentrallymaintained, seqno, ad_tab_id,
|
||||||
|
ad_column_id, isdisplayed, displaylength, isreadonly,
|
||||||
|
issameline, isheading, isfieldonly, isencrypted, entitytype
|
||||||
|
)
|
||||||
|
VALUES (50181, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
'Parent Product Category', 'Parent Product Category', 'Y', 60, 189,
|
||||||
|
50211, 'Y', 22, 'N',
|
||||||
|
'N', 'N', 'N', 'N', 'D'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO ad_message
|
||||||
|
(ad_message_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created, createdby,
|
||||||
|
updated, updatedby,
|
||||||
|
value, msgtext, msgtype
|
||||||
|
)
|
||||||
|
VALUES (50014, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
'ProductCategoryLoopDetected',
|
||||||
|
'A loop in the product category tree has been detected - the old value will be restored','E'
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMIT ;
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_element_id) + 1
|
||||||
|
FROM ad_element
|
||||||
|
WHERE ad_element_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Element';
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_column_id) + 1
|
||||||
|
FROM ad_column
|
||||||
|
WHERE ad_column_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Column';
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_field_id) + 1
|
||||||
|
FROM ad_field
|
||||||
|
WHERE ad_field_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Field';
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_message_id) + 1
|
||||||
|
FROM ad_message
|
||||||
|
WHERE ad_message_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Message';
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE M_Product_Category ADD M_Product_Category_Parent_ID NUMBER(10,0);
|
||||||
|
ALTER TABLE M_Product_Category ADD CONSTRAINT MProductCat_ParentCat FOREIGN KEY (M_Product_Category_Parent_ID)
|
||||||
|
REFERENCES M_Product_Category (M_Product_Category_ID);
|
||||||
|
UPDATE AD_Column SET IsSelectionColumn='Y' WHERE AD_Column_ID=2012;
|
||||||
|
|
||||||
|
COMMIT ;
|
|
@ -0,0 +1,102 @@
|
||||||
|
INSERT INTO ad_element
|
||||||
|
(ad_element_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created, createdby,
|
||||||
|
updated, updatedby,
|
||||||
|
columnname, entitytype, NAME,
|
||||||
|
printname
|
||||||
|
)
|
||||||
|
VALUES (50070, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
'M_Product_Category_Parent_ID', 'D', 'Parent Product Category',
|
||||||
|
'Parent Product Category'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO ad_column
|
||||||
|
(ad_column_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created,
|
||||||
|
updated, createdby,
|
||||||
|
updatedby, name, description, help, version,
|
||||||
|
entitytype, columnname, ad_table_id, ad_reference_id,
|
||||||
|
ad_reference_value_id,
|
||||||
|
fieldlength, iskey, isparent, ismandatory, isupdateable,
|
||||||
|
isidentifier, seqno, istranslated, isencrypted,
|
||||||
|
isselectioncolumn, ad_element_id, callout, issyncdatabase,
|
||||||
|
isalwaysupdateable
|
||||||
|
)
|
||||||
|
VALUES (50211, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'),
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
100, 'Parent Product Category', 'Parent Product Category', 'The parent product category is used to build a category tree.', 1,
|
||||||
|
'D', 'M_Product_Category_Parent_ID', 209, 18,
|
||||||
|
163,
|
||||||
|
22, 'N', 'N', 'N', 'Y',
|
||||||
|
'N', 0, 'N', 'N',
|
||||||
|
'N', 50070, 'org.compiere.model.CalloutProductCategory.testForLoop', 'N',
|
||||||
|
'N'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO ad_field
|
||||||
|
(ad_field_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created, createdby,
|
||||||
|
updated, updatedby,
|
||||||
|
name, description, iscentrallymaintained, seqno, ad_tab_id,
|
||||||
|
ad_column_id, isdisplayed, displaylength, isreadonly,
|
||||||
|
issameline, isheading, isfieldonly, isencrypted, entitytype
|
||||||
|
)
|
||||||
|
VALUES (50181, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
'Parent Product Category', 'Parent Product Category', 'Y', 60, 189,
|
||||||
|
50211, 'Y', 22, 'N',
|
||||||
|
'N', 'N', 'N', 'N', 'D'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO ad_message
|
||||||
|
(ad_message_id, ad_client_id, ad_org_id, isactive,
|
||||||
|
created, createdby,
|
||||||
|
updated, updatedby,
|
||||||
|
value, msgtext, msgtype
|
||||||
|
)
|
||||||
|
VALUES (50014, 0, 0, 'Y',
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
TO_DATE ('04/24/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
|
||||||
|
'ProductCategoryLoopDetected',
|
||||||
|
'A loop in the product category tree has been detected - the old value will be restored','E'
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMIT ;
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_element_id) + 1
|
||||||
|
FROM ad_element
|
||||||
|
WHERE ad_element_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Element';
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_column_id) + 1
|
||||||
|
FROM ad_column
|
||||||
|
WHERE ad_column_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Column';
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_field_id) + 1
|
||||||
|
FROM ad_field
|
||||||
|
WHERE ad_field_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Field';
|
||||||
|
|
||||||
|
UPDATE ad_sequence
|
||||||
|
SET currentnextsys = (SELECT MAX (ad_message_id) + 1
|
||||||
|
FROM ad_message
|
||||||
|
WHERE ad_message_id < 1000000)
|
||||||
|
WHERE NAME = 'AD_Message';
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE M_Product_Category ADD M_Product_Category_Parent_ID NUMERIC(10);
|
||||||
|
ALTER TABLE M_Product_Category ADD CONSTRAINT MProductCat_ParentCat FOREIGN KEY (M_Product_Category_Parent_ID)
|
||||||
|
REFERENCES M_Product_Category (M_Product_Category_ID);
|
||||||
|
UPDATE AD_Column SET IsSelectionColumn='Y' WHERE AD_Column_ID=2012;
|
||||||
|
|
||||||
|
COMMIT ;
|
Loading…
Reference in New Issue