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.util.*;
|
||||
import java.util.logging.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.table.*;
|
||||
|
@ -616,9 +617,12 @@ public final class Find extends CDialog
|
|||
// globalqss - Carlos Ruiz - 20060711
|
||||
// fix a bug with virtualColumn + isSelectionColumn not yielding results
|
||||
GridField field = getTargetMField(ColumnName);
|
||||
boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
|
||||
String ColumnSQL = field.getColumnSQL(false);
|
||||
if (value.toString().indexOf('%') != -1)
|
||||
m_query.addRestriction(ColumnSQL, MQuery.LIKE, value, ColumnName, ved.getDisplay());
|
||||
else if (isProductCategoryField && value instanceof Integer)
|
||||
m_query.addRestriction(getSubCategoryWhereClause(((Integer) value).intValue()));
|
||||
else
|
||||
m_query.addRestriction(ColumnSQL, MQuery.EQUAL, value, ColumnName, ved.getDisplay());
|
||||
/*
|
||||
|
@ -698,6 +702,7 @@ public final class Find extends CDialog
|
|||
String infoName = column.toString();
|
||||
//
|
||||
GridField field = getTargetMField(ColumnName);
|
||||
boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
|
||||
String ColumnSQL = field.getColumnSQL(false);
|
||||
// Op
|
||||
Object op = advancedTable.getValueAt(row, INDEX_OPERATOR);
|
||||
|
@ -730,12 +735,118 @@ public final class Find extends CDialog
|
|||
m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2,
|
||||
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
|
||||
m_query.addRestriction(ColumnSQL, Operator, parsedValue,
|
||||
infoName, infoDisplay);
|
||||
}
|
||||
} // 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
|
||||
* @param field column
|
||||
|
|
|
@ -232,6 +232,27 @@ return ii.intValue();
|
|||
}
|
||||
/** Column name 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.
|
||||
@param Name Alphanumeric identifier of the entity */
|
||||
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