diff --git a/db/ddlutils/oracle/functions/BOM_PriceLimit.sql b/db/ddlutils/oracle/functions/BOM_PriceLimit.sql index 4294c57bbc..fa1996fd77 100644 --- a/db/ddlutils/oracle/functions/BOM_PriceLimit.sql +++ b/db/ddlutils/oracle/functions/BOM_PriceLimit.sql @@ -1,53 +1,51 @@ -CREATE OR REPLACE FUNCTION Bompricelimit -( - Product_ID IN NUMBER, - PriceList_Version_ID IN NUMBER -) -RETURN NUMBER -/************************************************************************* - * The contents of this file are subject to the Compiere License. You may - * obtain a copy of the License at http://www.compiere.org/license.html - * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for details. Code: Compiere ERP+CRM - * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. - ************************************************************************* - * $Id: BOM_PriceLimit.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ - *** - * Title: Return Limit Price of Product/BOM - * Description: - * if not found: 0 - ************************************************************************/ -AS - v_Price NUMBER; - v_ProductPrice NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID; - -- -BEGIN - -- Try to get price from PriceList directly - SELECT COALESCE (SUM(PriceLimit), 0) - INTO v_Price - FROM M_PRODUCTPRICE - WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; --- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); - - -- No Price - Check if BOM - IF (v_Price = 0) THEN - FOR bom IN CUR_BOM LOOP - v_ProductPrice := Bompricelimit (bom.M_ProductBOM_ID, PriceList_Version_ID); - v_Price := v_Price + (bom.BOMQty * v_ProductPrice); - END LOOP; - END IF; - -- - RETURN v_Price; -END Bompricelimit; -/ +CREATE OR REPLACE FUNCTION BOMPRICELIMIT +( + Product_ID IN NUMBER, + PriceList_Version_ID IN NUMBER +) +RETURN NUMBER +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: BOM_PriceLimit.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Return Limit Price of Product/BOM + * Description: + * if not found: 0 + ************************************************************************/ +AS + v_Price NUMBER; + v_ProductPrice NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Try to get price from PriceList directly + SELECT COALESCE (SUM(PriceLimit), 0) + INTO v_Price + FROM M_PRODUCTPRICE + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; +-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN CUR_BOM LOOP + v_ProductPrice := Bompricelimit (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + END LOOP; + END IF; + -- + RETURN v_Price; +END Bompricelimit; +/ + diff --git a/db/ddlutils/oracle/functions/BOM_PriceList.sql b/db/ddlutils/oracle/functions/BOM_PriceList.sql index 0de404cc7e..0be86221b8 100644 --- a/db/ddlutils/oracle/functions/BOM_PriceList.sql +++ b/db/ddlutils/oracle/functions/BOM_PriceList.sql @@ -1,54 +1,52 @@ -CREATE OR REPLACE FUNCTION Bompricelist -( - Product_ID IN NUMBER, - PriceList_Version_ID IN NUMBER -) -RETURN NUMBER -/************************************************************************* - * The contents of this file are subject to the Compiere License. You may - * obtain a copy of the License at http://www.compiere.org/license.html - * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for details. Code: Compiere ERP+CRM - * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. - ************************************************************************* - * $Id: BOM_PriceList.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ - *** - * Title: Return List Price of Product/BOM - * Description: - * if not found: 0 - ************************************************************************/ -AS - v_Price NUMBER; - v_ProductPrice NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID; - -- -BEGIN - -- Try to get price from pricelist directly - SELECT COALESCE (SUM(PriceList), 0) - INTO v_Price - FROM M_PRODUCTPRICE - WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; --- DBMS_OUTPUT.PUT_LINE('Price=' || Price); - - -- No Price - Check if BOM - IF (v_Price = 0) THEN - FOR bom IN CUR_BOM LOOP - v_ProductPrice := Bompricelist (bom.M_ProductBOM_ID, PriceList_Version_ID); - v_Price := v_Price + (bom.BOMQty * v_ProductPrice); - -- DBMS_OUTPUT.PUT_LINE('Qry=' || bom.BOMQty || ' @ ' || v_ProductPrice || ', Price=' || v_Price); - END LOOP; -- BOM - END IF; - -- - RETURN v_Price; -END Bompricelist; -/ +CREATE OR REPLACE FUNCTION BOMPRICELIST +( + Product_ID IN NUMBER, + PriceList_Version_ID IN NUMBER +) +RETURN NUMBER +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: BOM_PriceList.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Return List Price of Product/BOM + * Description: + * if not found: 0 + ************************************************************************/ +AS + v_Price NUMBER; + v_ProductPrice NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Try to get price from pricelist directly + SELECT COALESCE (SUM(PriceList), 0) + INTO v_Price + FROM M_PRODUCTPRICE + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; +-- DBMS_OUTPUT.PUT_LINE('Price=' || Price); + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN CUR_BOM LOOP + v_ProductPrice := Bompricelist (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + -- DBMS_OUTPUT.PUT_LINE('Qry=' || bom.BOMQty || ' @ ' || v_ProductPrice || ', Price=' || v_Price); + END LOOP; -- BOM + END IF; + -- + RETURN v_Price; +END Bompricelist; +/ + diff --git a/db/ddlutils/oracle/functions/BOM_PriceStd.sql b/db/ddlutils/oracle/functions/BOM_PriceStd.sql index adf8662b68..e946334252 100644 --- a/db/ddlutils/oracle/functions/BOM_PriceStd.sql +++ b/db/ddlutils/oracle/functions/BOM_PriceStd.sql @@ -1,54 +1,52 @@ -CREATE OR REPLACE FUNCTION Bompricestd -( - Product_ID IN NUMBER, - PriceList_Version_ID IN NUMBER -) -RETURN NUMBER -/************************************************************************* - * The contents of this file are subject to the Compiere License. You may - * obtain a copy of the License at http://www.compiere.org/license.html - * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for details. Code: Compiere ERP+CRM - * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. - ************************************************************************* - * $Id: BOM_PriceStd.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ - *** - * Title: Return Standard Price of Product/BOM - * Description: - * if not found: 0 - ************************************************************************/ -AS - v_Price NUMBER; - v_ProductPrice NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID; - -- -BEGIN - -- Try to get price from pricelist directly - SELECT COALESCE(SUM(PriceStd), 0) - INTO v_Price - FROM M_PRODUCTPRICE - WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; --- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); - - -- No Price - Check if BOM - IF (v_Price = 0) THEN - FOR bom IN CUR_BOM LOOP - v_ProductPrice := Bompricestd (bom.M_ProductBOM_ID, PriceList_Version_ID); - v_Price := v_Price + (bom.BOMQty * v_ProductPrice); - -- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); - END LOOP; -- BOM - END IF; - -- - RETURN v_Price; -END Bompricestd; -/ +CREATE OR REPLACE FUNCTION BOMPRICESTD +( + Product_ID IN NUMBER, + PriceList_Version_ID IN NUMBER +) +RETURN NUMBER +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: BOM_PriceStd.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Return Standard Price of Product/BOM + * Description: + * if not found: 0 + ************************************************************************/ +AS + v_Price NUMBER; + v_ProductPrice NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Try to get price from pricelist directly + SELECT COALESCE(SUM(PriceStd), 0) + INTO v_Price + FROM M_PRODUCTPRICE + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; +-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN CUR_BOM LOOP + v_ProductPrice := Bompricestd (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + -- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); + END LOOP; -- BOM + END IF; + -- + RETURN v_Price; +END Bompricestd; +/ + diff --git a/db/ddlutils/oracle/functions/BOM_Qty_Available.sql b/db/ddlutils/oracle/functions/BOM_Qty_Available.sql index 3d7d50eefd..a396069be3 100644 --- a/db/ddlutils/oracle/functions/BOM_Qty_Available.sql +++ b/db/ddlutils/oracle/functions/BOM_Qty_Available.sql @@ -1,21 +1,22 @@ -CREATE OR REPLACE FUNCTION bomQtyAvailable -( - Product_ID IN NUMBER, - Warehouse_ID IN NUMBER, - Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity available for BOM - */ -AS -BEGIN - RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID) - - bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID); -END bomQtyAvailable; -/ \ No newline at end of file +CREATE OR REPLACE FUNCTION BOMQTYAVAILABLE +( + Product_ID IN NUMBER, + Warehouse_ID IN NUMBER, + Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity available for BOM + */ +AS +BEGIN + RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID) + - bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID); +END bomQtyAvailable; +/ + diff --git a/db/ddlutils/oracle/functions/BOM_Qty_AvailableASI.sql b/db/ddlutils/oracle/functions/BOM_Qty_AvailableASI.sql deleted file mode 100644 index f7de6896a3..0000000000 --- a/db/ddlutils/oracle/functions/BOM_Qty_AvailableASI.sql +++ /dev/null @@ -1,22 +0,0 @@ -CREATE OR REPLACE FUNCTION BomqtyavailableASI -( - Product_ID IN NUMBER, - AttributeSetInstance_ID IN NUMBER, - Warehouse_ID IN NUMBER, - Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity available for BOM ASI - */ -AS -BEGIN - RETURN BomqtyonhandASI(Product_ID, AttributeSetInstance_ID, Warehouse_ID, Locator_ID) - - BomqtyreservedASI(Product_ID, AttributeSetInstance_ID, Warehouse_ID, Locator_ID); -END BomqtyavailableASI; -/ diff --git a/db/ddlutils/oracle/functions/BOM_Qty_OnHand.sql b/db/ddlutils/oracle/functions/BOM_Qty_OnHand.sql index 9c3fe43b69..aee834d042 100644 --- a/db/ddlutils/oracle/functions/BOM_Qty_OnHand.sql +++ b/db/ddlutils/oracle/functions/BOM_Qty_OnHand.sql @@ -1,125 +1,123 @@ -CREATE OR REPLACE FUNCTION Bomqtyonhand -( - Product_ID IN NUMBER, - Warehouse_ID IN NUMBER, - Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity on hand for BOM - */ -AS - myWarehouse_ID NUMBER; - Quantity NUMBER := 99999; -- unlimited - IsBOM CHAR(1); - IsStocked CHAR(1); - ProductType CHAR(1); - ProductQty NUMBER; - StdPrecision NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=p_Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID; - -- -BEGIN - -- Check Parameters - myWarehouse_ID := Warehouse_ID; - IF (myWarehouse_ID IS NULL) THEN - IF (Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=Locator_ID; - END IF; - END IF; - IF (myWarehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO IsBOM, ProductType, IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - -- Unimited capacity if no item - IF (IsBOM='N' AND (ProductType<>'I' OR IsStocked='N')) THEN - RETURN Quantity; - -- Stocked item - ELSIF (IsStocked='Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOnHand), 0) - INTO ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=myWarehouse_ID); - -- - -- DBMS_OUTPUT.PUT_LINE('Qty=' || ProductQty); - RETURN ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN CUR_BOM LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOnHand), 0) - INTO ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=myWarehouse_ID); - -- Get Rounding Precision - SELECT NVL(MAX(u.StdPrecision), 0) - INTO StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - ProductQty := ROUND (ProductQty/bom.BOMQty, StdPrecision); - -- How much can we make overall - IF (ProductQty < Quantity) THEN - Quantity := ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - ProductQty := Bomqtyonhand (bom.M_ProductBOM_ID, myWarehouse_ID, Locator_ID); - -- How much can we make overall - IF (ProductQty < Quantity) THEN - Quantity := ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - IF (Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT NVL(MAX(u.StdPrecision), 0) - INTO StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID; - -- - RETURN ROUND (Quantity, StdPrecision); - END IF; - RETURN 0; -END Bomqtyonhand; -/ +CREATE OR REPLACE FUNCTION BOMQTYONHAND +( + Product_ID IN NUMBER, + Warehouse_ID IN NUMBER, + Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity on hand for BOM + */ +AS + myWarehouse_ID NUMBER; + Quantity NUMBER := 99999; -- unlimited + IsBOM CHAR(1); + IsStocked CHAR(1); + ProductType CHAR(1); + ProductQty NUMBER; + StdPrecision NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Check Parameters + myWarehouse_ID := Warehouse_ID; + IF (myWarehouse_ID IS NULL) THEN + IF (Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=Locator_ID; + END IF; + END IF; + IF (myWarehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO IsBOM, ProductType, IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + -- Unimited capacity if no item + IF (IsBOM='N' AND (ProductType<>'I' OR IsStocked='N')) THEN + RETURN Quantity; + -- Stocked item + ELSIF (IsStocked='Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOnHand), 0) + INTO ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=myWarehouse_ID); + -- + -- DBMS_OUTPUT.PUT_LINE('Qty=' || ProductQty); + RETURN ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE('BOM'); + FOR bom IN CUR_BOM LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOnHand), 0) + INTO ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=myWarehouse_ID); + -- Get Rounding Precision + SELECT NVL(MAX(u.StdPrecision), 0) + INTO StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + ProductQty := ROUND (ProductQty/bom.BOMQty, StdPrecision); + -- How much can we make overall + IF (ProductQty < Quantity) THEN + Quantity := ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + ProductQty := Bomqtyonhand (bom.M_ProductBOM_ID, myWarehouse_ID, Locator_ID); + -- How much can we make overall + IF (ProductQty < Quantity) THEN + Quantity := ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + IF (Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT NVL(MAX(u.StdPrecision), 0) + INTO StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID; + -- + RETURN ROUND (Quantity, StdPrecision); + END IF; + RETURN 0; +END Bomqtyonhand; +/ + diff --git a/db/ddlutils/oracle/functions/BOM_Qty_OnHandASI.sql b/db/ddlutils/oracle/functions/BOM_Qty_OnHandASI.sql deleted file mode 100644 index 948631da7b..0000000000 --- a/db/ddlutils/oracle/functions/BOM_Qty_OnHandASI.sql +++ /dev/null @@ -1,128 +0,0 @@ -CREATE OR REPLACE FUNCTION BomqtyonhandASI -( - Product_ID IN NUMBER, - AttributeSetInstance_ID IN NUMBER, - Warehouse_ID IN NUMBER, - Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity on hand for BOM - */ -AS - myWarehouse_ID NUMBER; - Quantity NUMBER := 99999; -- unlimited - IsBOM CHAR(1); - IsStocked CHAR(1); - ProductType CHAR(1); - ProductQty NUMBER; - StdPrecision NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=p_Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID; - -- -BEGIN - -- Check Parameters - myWarehouse_ID := Warehouse_ID; - IF (myWarehouse_ID IS NULL) THEN - IF (Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=Locator_ID; - END IF; - END IF; - IF (myWarehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO IsBOM, ProductType, IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - -- Unimited capacity if no item - IF (IsBOM='N' AND (ProductType<>'I' OR IsStocked='N')) THEN - RETURN Quantity; - -- Stocked item - ELSIF (IsStocked='Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOnHand), 0) - INTO ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=myWarehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR NVL(AttributeSetInstance_ID,0) = 0); - -- - -- DBMS_OUTPUT.PUT_LINE('Qty=' || ProductQty); - RETURN ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN CUR_BOM LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOnHand), 0) - INTO ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=myWarehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR NVL(AttributeSetInstance_ID,0) = 0); - -- Get Rounding Precision - SELECT NVL(MAX(u.StdPrecision), 0) - INTO StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - ProductQty := ROUND (ProductQty/bom.BOMQty, StdPrecision); - -- How much can we make overall - IF (ProductQty < Quantity) THEN - Quantity := ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - ProductQty := BomqtyonhandASI (bom.M_ProductBOM_ID, AttributeSetInstance_ID, myWarehouse_ID, Locator_ID); - -- How much can we make overall - IF (ProductQty < Quantity) THEN - Quantity := ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - IF (Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT NVL(MAX(u.StdPrecision), 0) - INTO StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID; - -- - RETURN ROUND (Quantity, StdPrecision); - END IF; - RETURN 0; -END BomqtyonhandASI; -/ diff --git a/db/ddlutils/oracle/functions/BOM_Qty_Ordered.sql b/db/ddlutils/oracle/functions/BOM_Qty_Ordered.sql index 540aea2535..c34b6434be 100644 --- a/db/ddlutils/oracle/functions/BOM_Qty_Ordered.sql +++ b/db/ddlutils/oracle/functions/BOM_Qty_Ordered.sql @@ -1,131 +1,129 @@ -CREATE OR REPLACE FUNCTION Bomqtyordered -( - p_Product_ID IN NUMBER, - p_Warehouse_ID IN NUMBER, - p_Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity ordered for BOM - */ -AS - v_Warehouse_ID NUMBER; - v_Quantity NUMBER := 99999; -- unlimited - v_IsBOM CHAR(1); - v_IsStocked CHAR(1); - v_ProductType CHAR(1); - v_ProductQty NUMBER; - v_StdPrecision NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=p_Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID; - -- -BEGIN - -- Check Parameters - v_Warehouse_ID := p_Warehouse_ID; - IF (v_Warehouse_ID IS NULL) THEN - IF (p_Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=p_Locator_ID; - END IF; - END IF; - IF (v_Warehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO v_IsBOM, v_ProductType, v_IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=p_Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - - -- No reservation for non-stocked - IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN - RETURN 0; - -- Stocked item - ELSIF (v_IsStocked='Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOrdered), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=p_Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID); - -- - RETURN v_ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN CUR_BOM LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOrdered), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID); - -- Get Rounding Precision - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - v_ProductQty := Bomqtyordered (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - -- Unlimited (e.g. only services) - IF (v_Quantity = 99999) THEN - RETURN 0; - END IF; - - IF (v_Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; - -- - RETURN ROUND (v_Quantity, v_StdPrecision); - END IF; - -- - RETURN 0; -END Bomqtyordered; -/ +CREATE OR REPLACE FUNCTION BOMQTYORDERED +( + p_Product_ID IN NUMBER, + p_Warehouse_ID IN NUMBER, + p_Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity ordered for BOM + */ +AS + v_Warehouse_ID NUMBER; + v_Quantity NUMBER := 99999; -- unlimited + v_IsBOM CHAR(1); + v_IsStocked CHAR(1); + v_ProductType CHAR(1); + v_ProductQty NUMBER; + v_StdPrecision NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Check Parameters + v_Warehouse_ID := p_Warehouse_ID; + IF (v_Warehouse_ID IS NULL) THEN + IF (p_Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=p_Locator_ID; + END IF; + END IF; + IF (v_Warehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO v_IsBOM, v_ProductType, v_IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=p_Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + + -- No reservation for non-stocked + IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN + RETURN 0; + -- Stocked item + ELSIF (v_IsStocked='Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOrdered), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=p_Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- + RETURN v_ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE('BOM'); + FOR bom IN CUR_BOM LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOrdered), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- Get Rounding Precision + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + v_ProductQty := Bomqtyordered (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + -- Unlimited (e.g. only services) + IF (v_Quantity = 99999) THEN + RETURN 0; + END IF; + + IF (v_Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; + -- + RETURN ROUND (v_Quantity, v_StdPrecision); + END IF; + -- + RETURN 0; +END Bomqtyordered; +/ + diff --git a/db/ddlutils/oracle/functions/BOM_Qty_OrderedASI.sql b/db/ddlutils/oracle/functions/BOM_Qty_OrderedASI.sql deleted file mode 100644 index a727661762..0000000000 --- a/db/ddlutils/oracle/functions/BOM_Qty_OrderedASI.sql +++ /dev/null @@ -1,134 +0,0 @@ -CREATE OR REPLACE FUNCTION BomqtyorderedASI -( - p_Product_ID IN NUMBER, - AttributeSetInstance_ID IN NUMBER, - p_Warehouse_ID IN NUMBER, - p_Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity ordered for BOM - */ -AS - v_Warehouse_ID NUMBER; - v_Quantity NUMBER := 99999; -- unlimited - v_IsBOM CHAR(1); - v_IsStocked CHAR(1); - v_ProductType CHAR(1); - v_ProductQty NUMBER; - v_StdPrecision NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=p_Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID; - -- -BEGIN - -- Check Parameters - v_Warehouse_ID := p_Warehouse_ID; - IF (v_Warehouse_ID IS NULL) THEN - IF (p_Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=p_Locator_ID; - END IF; - END IF; - IF (v_Warehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO v_IsBOM, v_ProductType, v_IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=p_Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - - -- No reservation for non-stocked - IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN - RETURN 0; - -- Stocked item - ELSIF (v_IsStocked='Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOrdered), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=p_Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR NVL(AttributeSetInstance_ID,0) = 0); - -- - RETURN v_ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN CUR_BOM LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyOrdered), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR NVL(AttributeSetInstance_ID,0) = 0); - -- Get Rounding Precision - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - v_ProductQty := BomqtyorderedASI (bom.M_ProductBOM_ID, AttributeSetInstance_ID, v_Warehouse_ID, p_Locator_ID); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - -- Unlimited (e.g. only services) - IF (v_Quantity = 99999) THEN - RETURN 0; - END IF; - - IF (v_Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; - -- - RETURN ROUND (v_Quantity, v_StdPrecision); - END IF; - -- - RETURN 0; -END BomqtyorderedASI; -/ diff --git a/db/ddlutils/oracle/functions/BOM_Qty_Reserved.sql b/db/ddlutils/oracle/functions/BOM_Qty_Reserved.sql index 8b50796a28..6921fc37ac 100644 --- a/db/ddlutils/oracle/functions/BOM_Qty_Reserved.sql +++ b/db/ddlutils/oracle/functions/BOM_Qty_Reserved.sql @@ -1,130 +1,128 @@ -CREATE OR REPLACE FUNCTION Bomqtyreserved -( - p_Product_ID IN NUMBER, - p_Warehouse_ID IN NUMBER, - p_Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity reserved for BOM - */ -AS - v_Warehouse_ID NUMBER; - v_Quantity NUMBER := 99999; -- unlimited - v_IsBOM CHAR(1); - v_IsStocked CHAR(1); - v_ProductType CHAR(1); - v_ProductQty NUMBER; - v_StdPrecision NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=p_Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID; - -- -BEGIN - -- Check Parameters - v_Warehouse_ID := p_Warehouse_ID; - IF (v_Warehouse_ID IS NULL) THEN - IF (p_Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=p_Locator_ID; - END IF; - END IF; - IF (v_Warehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO v_IsBOM, v_ProductType, v_IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=p_Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - - -- No reservation for non-stocked - IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN - RETURN 0; - -- Stocked item - ELSIF (v_IsStocked='Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyReserved), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=p_Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID); - -- - RETURN v_ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN CUR_BOM LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyReserved), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID); - -- Get Rounding Precision - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - v_ProductQty := Bomqtyreserved (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - -- Unlimited (e.g. only services) - IF (v_Quantity = 99999) THEN - RETURN 0; - END IF; - - IF (v_Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; - -- - RETURN ROUND (v_Quantity, v_StdPrecision); - END IF; - RETURN 0; -END Bomqtyreserved; -/ +CREATE OR REPLACE FUNCTION BOMQTYRESERVED +( + p_Product_ID IN NUMBER, + p_Warehouse_ID IN NUMBER, + p_Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity reserved for BOM + */ +AS + v_Warehouse_ID NUMBER; + v_Quantity NUMBER := 99999; -- unlimited + v_IsBOM CHAR(1); + v_IsStocked CHAR(1); + v_ProductType CHAR(1); + v_ProductQty NUMBER; + v_StdPrecision NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Check Parameters + v_Warehouse_ID := p_Warehouse_ID; + IF (v_Warehouse_ID IS NULL) THEN + IF (p_Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=p_Locator_ID; + END IF; + END IF; + IF (v_Warehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO v_IsBOM, v_ProductType, v_IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=p_Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + + -- No reservation for non-stocked + IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN + RETURN 0; + -- Stocked item + ELSIF (v_IsStocked='Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyReserved), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=p_Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- + RETURN v_ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE('BOM'); + FOR bom IN CUR_BOM LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyReserved), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- Get Rounding Precision + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + v_ProductQty := Bomqtyreserved (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + -- Unlimited (e.g. only services) + IF (v_Quantity = 99999) THEN + RETURN 0; + END IF; + + IF (v_Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; + -- + RETURN ROUND (v_Quantity, v_StdPrecision); + END IF; + RETURN 0; +END Bomqtyreserved; +/ + diff --git a/db/ddlutils/oracle/functions/BOM_Qty_ReservedASI.sql b/db/ddlutils/oracle/functions/BOM_Qty_ReservedASI.sql deleted file mode 100644 index 425f0a3b10..0000000000 --- a/db/ddlutils/oracle/functions/BOM_Qty_ReservedASI.sql +++ /dev/null @@ -1,133 +0,0 @@ -CREATE OR REPLACE FUNCTION BomqtyreservedASI -( - p_Product_ID IN NUMBER, - AttributeSetInstance_ID IN NUMBER, - p_Warehouse_ID IN NUMBER, - p_Locator_ID IN NUMBER -- Only used, if warehouse is null -) -RETURN NUMBER -/****************************************************************************** - * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA - * Open Source Software Provided "AS IS" without warranty or liability - * When you use any parts (changed or unchanged), add "Powered by Compiere" to - * your product name; See license details http://www.compiere.org/license.html - ****************************************************************************** - * Return quantity reserved for BOM - */ -AS - v_Warehouse_ID NUMBER; - v_Quantity NUMBER := 99999; -- unlimited - v_IsBOM CHAR(1); - v_IsStocked CHAR(1); - v_ProductType CHAR(1); - v_ProductQty NUMBER; - v_StdPrecision NUMBER; - -- Get BOM Product info - CURSOR CUR_BOM IS - /*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType - FROM M_PRODUCT_BOM b, M_PRODUCT p - WHERE b.M_ProductBOM_ID=p.M_Product_ID - AND b.M_Product_ID=p_Product_ID;*/ - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID; - -- -BEGIN - -- Check Parameters - v_Warehouse_ID := p_Warehouse_ID; - IF (v_Warehouse_ID IS NULL) THEN - IF (p_Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=p_Locator_ID; - END IF; - END IF; - IF (v_Warehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO v_IsBOM, v_ProductType, v_IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=p_Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - - -- No reservation for non-stocked - IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN - RETURN 0; - -- Stocked item - ELSIF (v_IsStocked='Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyReserved), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=p_Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR NVL(AttributeSetInstance_ID,0) = 0); - -- - RETURN v_ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN CUR_BOM LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT NVL(SUM(QtyReserved), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR NVL(AttributeSetInstance_ID,0) = 0); - -- Get Rounding Precision - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - v_ProductQty := BomqtyreservedASI (bom.M_ProductBOM_ID, AttributeSetInstance_ID, v_Warehouse_ID, p_Locator_ID); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - -- Unlimited (e.g. only services) - IF (v_Quantity = 99999) THEN - RETURN 0; - END IF; - - IF (v_Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT NVL(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; - -- - RETURN ROUND (v_Quantity, v_StdPrecision); - END IF; - RETURN 0; -END BomqtyreservedASI; -/ \ No newline at end of file diff --git a/db/ddlutils/postgresql/functions/BOM_PriceLimit.sql b/db/ddlutils/postgresql/functions/BOM_PriceLimit.sql index a49f019780..f32ba35945 100644 --- a/db/ddlutils/postgresql/functions/BOM_PriceLimit.sql +++ b/db/ddlutils/postgresql/functions/BOM_PriceLimit.sql @@ -1,50 +1,37 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - * - *Copyright (C) 2006-2008 Antonio CaƱaveral, e-Evolution - * - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - */ -CREATE OR REPLACE FUNCTION bompricelimit(p_product_id numeric, p_pricelist_version_id numeric) - RETURNS numeric AS +CREATE OR REPLACE FUNCTION bompricelimit (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS $BODY$ DECLARE - v_Price numeric; - v_ProductPrice numeric; - bom record; + v_Price NUMERIC; + v_ProductPrice NUMERIC; + bom RECORD; + BEGIN -- Try to get price from PriceList directly SELECT COALESCE (SUM(PriceLimit), 0) - INTO v_Price - FROM M_PRODUCTPRICE - WHERE M_PriceList_Version_ID=p_PriceList_Version_ID AND M_Product_ID=p_Product_ID; + INTO v_Price + FROM M_ProductPrice + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; + + -- No Price - Check if BOM IF (v_Price = 0) THEN - FOR bom in SELECT bl.M_Product_ID AS M_ProductBOM_ID, - CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID + FOR bom IN + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_Product_BOM b, M_Product p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' LOOP - v_ProductPrice := Bompricelimit (bom.M_ProductBOM_ID, p_PriceList_Version_ID); + v_ProductPrice := bomPriceLimit (bom.M_ProductBOM_ID, PriceList_Version_ID); v_Price := v_Price + (bom.BOMQty * v_ProductPrice); END LOOP; END IF; -- RETURN v_Price; + END; + $BODY$ - LANGUAGE 'plpgsql' ; +LANGUAGE 'plpgsql' +; + diff --git a/db/ddlutils/postgresql/functions/BOM_PriceList.sql b/db/ddlutils/postgresql/functions/BOM_PriceList.sql index 5d77430daa..58aaef8ec6 100644 --- a/db/ddlutils/postgresql/functions/BOM_PriceList.sql +++ b/db/ddlutils/postgresql/functions/BOM_PriceList.sql @@ -1,60 +1,37 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - * Title: Return List Price of Product/BOM - * Description: - */ -CREATE OR REPLACE FUNCTION Bompricelist -( - Product_ID numeric, - PriceList_Version_ID numeric -) -RETURNS numeric -AS +CREATE OR REPLACE FUNCTION bompricelist (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS $BODY$ DECLARE - v_Price numeric; - v_ProductPrice numeric; - bom record; + v_Price NUMERIC; + v_ProductPrice NUMERIC; + bom RECORD; + BEGIN -- Try to get price from pricelist directly SELECT COALESCE (SUM(PriceList), 0) INTO v_Price - FROM M_PRODUCTPRICE + FROM M_ProductPrice WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; --- DBMS_OUTPUT.PUT_LINE('Price=' || Price); -- No Price - Check if BOM IF (v_Price = 0) THEN - FOR bom IN - --Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID + FOR bom IN + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_Product_BOM b, M_Product p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' LOOP - v_ProductPrice := Bompricelist (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_ProductPrice := bomPriceList (bom.M_ProductBOM_ID, PriceList_Version_ID); v_Price := v_Price + (bom.BOMQty * v_ProductPrice); - -- DBMS_OUTPUT.PUT_LINE('Qry=' || bom.BOMQty || ' @ ' || v_ProductPrice || ', Price=' || v_Price); - END LOOP; -- BOM + END LOOP; END IF; -- RETURN v_Price; + END; + $BODY$ - LANGUAGE 'plpgsql' ; +LANGUAGE 'plpgsql' +; + diff --git a/db/ddlutils/postgresql/functions/BOM_PriceStd.sql b/db/ddlutils/postgresql/functions/BOM_PriceStd.sql index cac669b3d5..a259dccefc 100644 --- a/db/ddlutils/postgresql/functions/BOM_PriceStd.sql +++ b/db/ddlutils/postgresql/functions/BOM_PriceStd.sql @@ -1,59 +1,37 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - * Title: Return Standard Price of Product/BOM - * Description: - */ -CREATE OR REPLACE FUNCTION Bompricestd -( - Product_ID numeric, - PriceList_Version_ID numeric -) -RETURNS numeric -AS +CREATE OR REPLACE FUNCTION bompricestd (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS $BODY$ DECLARE - v_Price numeric; - v_ProductPrice numeric; - bom record; + v_Price NUMERIC; + v_ProductPrice NUMERIC; + bom RECORD; + BEGIN - -- Try to get price from pricelist directly + -- Try to get price from PriceList directly SELECT COALESCE(SUM(PriceStd), 0) INTO v_Price - FROM M_PRODUCTPRICE + FROM M_ProductPrice WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; --- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); -- No Price - Check if BOM IF (v_Price = 0) THEN - FOR bom IN -- Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID + FOR bom IN + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_Product_BOM b, M_Product p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' LOOP - v_ProductPrice := Bompricestd (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_ProductPrice := bomPriceStd (bom.M_ProductBOM_ID, PriceList_Version_ID); v_Price := v_Price + (bom.BOMQty * v_ProductPrice); - -- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); - END LOOP; -- BOM + END LOOP; END IF; -- RETURN v_Price; + END; + $BODY$ - LANGUAGE 'plpgsql' ; +LANGUAGE 'plpgsql' +; + diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_Available.sql b/db/ddlutils/postgresql/functions/BOM_Qty_Available.sql index 936c03d9d3..19662e14b2 100644 --- a/db/ddlutils/postgresql/functions/BOM_Qty_Available.sql +++ b/db/ddlutils/postgresql/functions/BOM_Qty_Available.sql @@ -1,26 +1,9 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - */ -CREATE OR REPLACE FUNCTION bomQtyAvailable(Product_ID numeric, Warehouse_ID numeric ,Locator_ID numeric) - RETURNS numeric AS +CREATE OR REPLACE FUNCTION bomqtyavailable (in product_id numeric, in warehouse_id numeric, in locator_id numeric) RETURNS numeric AS $BODY$ BEGIN RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID) - bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID); END; $BODY$ - LANGUAGE 'plpgsql' ; \ No newline at end of file +LANGUAGE 'plpgsql' +; + diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_AvailableASI.sql b/db/ddlutils/postgresql/functions/BOM_Qty_AvailableASI.sql deleted file mode 100644 index 696c52bec5..0000000000 --- a/db/ddlutils/postgresql/functions/BOM_Qty_AvailableASI.sql +++ /dev/null @@ -1,27 +0,0 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 carlos.ruiz@globalqss.com, GlobalQSS - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - */ -CREATE OR REPLACE FUNCTION bomQtyAvailableASI(Product_ID numeric, AttributeSetInstance_ID numeric, Warehouse_ID numeric ,Locator_ID numeric) - RETURNS numeric AS -$BODY$ -BEGIN - RETURN bomQtyOnHandASI(Product_ID, AttributeSetInstance_ID, Warehouse_ID, Locator_ID) - - bomQtyReservedASI(Product_ID, AttributeSetInstance_ID, Warehouse_ID, Locator_ID); -END; -$BODY$ - LANGUAGE 'plpgsql' ; diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_OnHand.sql b/db/ddlutils/postgresql/functions/BOM_Qty_OnHand.sql index 343b323707..9518f30ebe 100644 --- a/db/ddlutils/postgresql/functions/BOM_Qty_OnHand.sql +++ b/db/ddlutils/postgresql/functions/BOM_Qty_OnHand.sql @@ -1,29 +1,4 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - */ -CREATE OR REPLACE FUNCTION Bomqtyonhand -( - Product_ID numeric, - Warehouse_ID numeric, - Locator_ID numeric -- Only used, if warehouse is null -) -RETURNS numeric -AS +CREATE OR REPLACE FUNCTION bomqtyonhand (in product_id numeric, in warehouse_id numeric, in locator_id numeric) RETURNS numeric AS $BODY$ DECLARE myWarehouse_ID numeric; @@ -50,7 +25,7 @@ BEGIN IF (myWarehouse_ID IS NULL) THEN RETURN 0; END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID); +-- DBMS_OUTPUT.PUT_LINE(''Warehouse='' || myWarehouse_ID); -- Check, if product exists and if it is stocked BEGIN @@ -76,18 +51,19 @@ BEGIN AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID AND l.M_Warehouse_ID=myWarehouse_ID); -- - -- DBMS_OUTPUT.PUT_LINE('Qty=' || v_ProductQty); + -- DBMS_OUTPUT.PUT_LINE(''Qty='' || v_ProductQty); RETURN v_ProductQty; END IF; -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); +-- DBMS_OUTPUT.PUT_LINE(''BOM''); FOR bom IN -- Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' LOOP -- Stocked Items "leaf node" IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN @@ -131,4 +107,6 @@ BEGIN RETURN 0; END; $BODY$ - LANGUAGE 'plpgsql' ; +LANGUAGE 'plpgsql' +; + diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_OnHandASI.sql b/db/ddlutils/postgresql/functions/BOM_Qty_OnHandASI.sql deleted file mode 100644 index 3bfbd247ec..0000000000 --- a/db/ddlutils/postgresql/functions/BOM_Qty_OnHandASI.sql +++ /dev/null @@ -1,138 +0,0 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - * Return quantity on hand for BOM ASI - */ -CREATE OR REPLACE FUNCTION BomqtyonhandASI -( - Product_ID numeric, - AttributeSetInstance_ID numeric, - Warehouse_ID numeric, - Locator_ID numeric -- Only used, if warehouse is null -) -RETURNS numeric -AS -$BODY$ -DECLARE - myWarehouse_ID numeric; - v_Quantity numeric := 99999; -- unlimited - v_IsBOM CHAR(1); - v_IsStocked CHAR(1); - v_ProductType CHAR(1); - v_ProductQty numeric; - v_StdPrecision numeric; - bom record; -BEGIN - -- Check Parameters - myWarehouse_ID := Warehouse_ID; - IF (myWarehouse_ID IS NULL) THEN - IF (Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=Locator_ID; - END IF; - END IF; - IF (myWarehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO v_IsBOM, v_ProductType, v_IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - -- Unimited capacity if no item - IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN - RETURN v_Quantity; - -- Stocked item - ELSIF (v_IsStocked='Y') THEN - -- Get v_ProductQty - SELECT COALESCE(SUM(QtyOnHand), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=myWarehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR COALESCE(AttributeSetInstance_ID,0) = 0); - -- - -- DBMS_OUTPUT.PUT_LINE('Qty=' || v_ProductQty); - RETURN v_ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN - -- Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = Product_ID - LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get v_ProductQty - SELECT COALESCE(SUM(QtyOnHand), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=myWarehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR COALESCE(AttributeSetInstance_ID,0) = 0); - -- Get Rounding Precision - SELECT COALESCE(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - v_ProductQty := BomqtyonhandASI (bom.M_ProductBOM_ID, AttributeSetInstance_ID, myWarehouse_ID, Locator_ID); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - IF (v_Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT COALESCE(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID; - -- - RETURN ROUND (v_Quantity, v_StdPrecision ); - END IF; - RETURN 0; -END; -$BODY$ - LANGUAGE 'plpgsql' ; diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_Ordered.sql b/db/ddlutils/postgresql/functions/BOM_Qty_Ordered.sql index 4d033f7b26..d9f8fe49a2 100644 --- a/db/ddlutils/postgresql/functions/BOM_Qty_Ordered.sql +++ b/db/ddlutils/postgresql/functions/BOM_Qty_Ordered.sql @@ -1,30 +1,4 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - * Return quantity ordered for BOM - */ -CREATE OR REPLACE FUNCTION Bomqtyordered -( - p_Product_ID numeric, - p_Warehouse_ID numeric, - p_Locator_ID numeric -- Only used, if warehouse is null -) -RETURNS numeric -AS +CREATE OR REPLACE FUNCTION bomqtyordered (in p_product_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) RETURNS numeric AS $BODY$ DECLARE v_Warehouse_ID numeric; @@ -50,7 +24,7 @@ BEGIN IF (v_Warehouse_ID IS NULL) THEN RETURN 0; END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); +-- DBMS_OUTPUT.PUT_LINE(''Warehouse='' || v_Warehouse_ID); -- Check, if product exists and if it is stocked BEGIN @@ -81,14 +55,15 @@ BEGIN END IF; -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); +-- DBMS_OUTPUT.PUT_LINE(''BOM''); FOR bom IN -- Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' LOOP -- Stocked Items "leaf node" IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN @@ -139,4 +114,6 @@ BEGIN RETURN 0; END; $BODY$ - LANGUAGE 'plpgsql' ; +LANGUAGE 'plpgsql' +; + diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_OrderedASI.sql b/db/ddlutils/postgresql/functions/BOM_Qty_OrderedASI.sql deleted file mode 100644 index d3e6f5c54a..0000000000 --- a/db/ddlutils/postgresql/functions/BOM_Qty_OrderedASI.sql +++ /dev/null @@ -1,144 +0,0 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - * Return quantity ordered for BOM ASI - */ -CREATE OR REPLACE FUNCTION BomqtyorderedASI -( - p_Product_ID numeric, - AttributeSetInstance_ID numeric, - p_Warehouse_ID numeric, - p_Locator_ID numeric -- Only used, if warehouse is null -) -RETURNS numeric -AS -$BODY$ -DECLARE - v_Warehouse_ID numeric; - v_Quantity numeric := 99999; -- unlimited - v_IsBOM CHAR(1); - v_IsStocked CHAR(1); - v_ProductType CHAR(1); - v_ProductQty numeric; - v_StdPrecision int; - bom record; -BEGIN - -- Check Parameters - v_Warehouse_ID := p_Warehouse_ID; - IF (v_Warehouse_ID IS NULL) THEN - IF (p_Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=p_Locator_ID; - END IF; - END IF; - IF (v_Warehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO v_IsBOM, v_ProductType, v_IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=p_Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - - -- No reservation for non-stocked - IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN - RETURN 0; - -- Stocked item - ELSIF (v_IsStocked='Y') THEN - -- Get ProductQty - SELECT COALESCE(SUM(QtyOrdered), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=p_Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR COALESCE(AttributeSetInstance_ID,0) = 0); - -- - RETURN v_ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN - -- Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID - LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT COALESCE(SUM(QtyOrdered), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR COALESCE(AttributeSetInstance_ID,0) = 0); - -- Get Rounding Precision - SELECT COALESCE(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - v_ProductQty := BomqtyorderedASI (bom.M_ProductBOM_ID, AttributeSetInstance_ID, v_Warehouse_ID, p_Locator_ID); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - -- Unlimited (e.g. only services) - IF (v_Quantity = 99999) THEN - RETURN 0; - END IF; - - IF (v_Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT COALESCE(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; - -- - RETURN ROUND (v_Quantity, v_StdPrecision); - END IF; - -- - RETURN 0; -END; -$BODY$ - LANGUAGE 'plpgsql' ; diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_Reserved.sql b/db/ddlutils/postgresql/functions/BOM_Qty_Reserved.sql index 938e59084f..c4ea21df31 100644 --- a/db/ddlutils/postgresql/functions/BOM_Qty_Reserved.sql +++ b/db/ddlutils/postgresql/functions/BOM_Qty_Reserved.sql @@ -1,30 +1,4 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - * Return quantity reserved for BOM - */ -CREATE OR REPLACE FUNCTION Bomqtyreserved -( - p_Product_ID numeric, - p_Warehouse_ID numeric, - p_Locator_ID numeric -- Only used, if warehouse is null -) -RETURNS numeric -AS +CREATE OR REPLACE FUNCTION bomqtyreserved (in p_product_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) RETURNS numeric AS $BODY$ DECLARE v_Warehouse_ID numeric; @@ -50,7 +24,7 @@ BEGIN IF (v_Warehouse_ID IS NULL) THEN RETURN 0; END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); +-- DBMS_OUTPUT.PUT_LINE(''Warehouse='' || v_Warehouse_ID); -- Check, if product exists and if it is stocked BEGIN @@ -81,14 +55,15 @@ BEGIN END IF; -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); +-- DBMS_OUTPUT.PUT_LINE(''BOM''); FOR bom IN -- Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' LOOP -- Stocked Items "leaf node" IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN @@ -137,4 +112,6 @@ BEGIN RETURN 0; END; $BODY$ - LANGUAGE 'plpgsql' ; +LANGUAGE 'plpgsql' +; + diff --git a/db/ddlutils/postgresql/functions/BOM_Qty_ReservedASI.sql b/db/ddlutils/postgresql/functions/BOM_Qty_ReservedASI.sql deleted file mode 100644 index d2d14ceee3..0000000000 --- a/db/ddlutils/postgresql/functions/BOM_Qty_ReservedASI.sql +++ /dev/null @@ -1,144 +0,0 @@ -/* - *This file is part of Adempiere ERP Bazaar - *http://www.adempiere.org - *Copyright (C) 2006-2008 victor.perez@e-evolution.com, e-Evolution - *This program is free software; you can redistribute it and/or - *modify it under the terms of the GNU General Public License - *as published by the Free Software Foundation; either version 2 - *of the License, or (at your option) any later version. - * - *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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of - * Return quantity reserved for BOM ASI - */ -CREATE OR REPLACE FUNCTION BomqtyreservedASI -( - p_Product_ID numeric, - AttributeSetInstance_ID numeric, - p_Warehouse_ID numeric, - p_Locator_ID numeric -- Only used, if warehouse is null -) -RETURNS numeric -AS -$BODY$ -DECLARE - v_Warehouse_ID numeric; - v_Quantity numeric := 99999; -- unlimited - v_IsBOM CHAR(1); - v_IsStocked CHAR(1); - v_ProductType CHAR(1); - v_ProductQty numeric; - v_StdPrecision int; - bom record; - -- -BEGIN - -- Check Parameters - v_Warehouse_ID := p_Warehouse_ID; - IF (v_Warehouse_ID IS NULL) THEN - IF (p_Locator_ID IS NULL) THEN - RETURN 0; - ELSE - SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID - FROM M_LOCATOR - WHERE M_Locator_ID=p_Locator_ID; - END IF; - END IF; - IF (v_Warehouse_ID IS NULL) THEN - RETURN 0; - END IF; --- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); - - -- Check, if product exists and if it is stocked - BEGIN - SELECT IsBOM, ProductType, IsStocked - INTO v_IsBOM, v_ProductType, v_IsStocked - FROM M_PRODUCT - WHERE M_Product_ID=p_Product_ID; - -- - EXCEPTION -- not found - WHEN OTHERS THEN - RETURN 0; - END; - - -- No reservation for non-stocked - IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN - RETURN 0; - -- Stocked item - ELSIF (v_IsStocked='Y') THEN - -- Get ProductQty - SELECT COALESCE(SUM(QtyReserved), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=p_Product_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR COALESCE(AttributeSetInstance_ID,0) = 0); - -- - RETURN v_ProductQty; - END IF; - - -- Go though BOM --- DBMS_OUTPUT.PUT_LINE('BOM'); - FOR bom IN - --Get BOM Product info - SELECT bl.M_Product_ID AS M_ProductBOM_ID, CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM , p.IsStocked, p.ProductType - FROM PP_PRODUCT_BOM b - INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID) - INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID) - WHERE b.M_Product_ID = p_Product_ID - LOOP - -- Stocked Items "leaf node" - IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN - -- Get ProductQty - SELECT COALESCE(SUM(QtyReserved), 0) - INTO v_ProductQty - FROM M_STORAGE s - WHERE M_Product_ID=bom.M_ProductBOM_ID - AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID - AND l.M_Warehouse_ID=v_Warehouse_ID) - AND (s.M_AttributeSetInstance_ID = AttributeSetInstance_ID OR COALESCE(AttributeSetInstance_ID,0) = 0); - -- Get Rounding Precision - SELECT COALESCE(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; - -- How much can we make with this product - v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - -- Another BOM - ELSIF (bom.IsBOM = 'Y') THEN - v_ProductQty := BomqtyreservedASI (bom.M_ProductBOM_ID, AttributeSetInstance_ID, v_Warehouse_ID, p_Locator_ID); - -- How much can we make overall - IF (v_ProductQty < v_Quantity) THEN - v_Quantity := v_ProductQty; - END IF; - END IF; - END LOOP; -- BOM - - -- Unlimited (e.g. only services) - IF (v_Quantity = 99999) THEN - RETURN 0; - END IF; - - IF (v_Quantity > 0) THEN - -- Get Rounding Precision for Product - SELECT COALESCE(MAX(u.StdPrecision), 0) - INTO v_StdPrecision - FROM C_UOM u, M_PRODUCT p - WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; - -- - RETURN ROUND (v_Quantity, v_StdPrecision ); - END IF; - RETURN 0; -END; -$BODY$ - LANGUAGE 'plpgsql' ; diff --git a/migration/i1.0c-release/oracle/201308260558_IDEMPIERE-1298.sql b/migration/i1.0c-release/oracle/201308260558_IDEMPIERE-1298.sql index fd3286f373..adff461b5b 100644 --- a/migration/i1.0c-release/oracle/201308260558_IDEMPIERE-1298.sql +++ b/migration/i1.0c-release/oracle/201308260558_IDEMPIERE-1298.sql @@ -1,8 +1,3 @@ --- Aug 23, 2013 6:08:39 PM MYT --- IDEMPIERE-1297 2Pack: Remove code for the lookup of record and reference using business key -UPDATE AD_SysConfig SET Value='IDEMPIERE-1298 2Pack: Support copying of data from one client to another',Updated=TO_DATE('2013-08-23 18:08:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=50003 -; - -- Aug 23, 2013 6:09:08 PM MYT -- IDEMPIERE-1298 2Pack: Support copying of data from one client to another INSERT INTO AD_Table (ImportTable,CopyColumnsFromTable,IsSecurityEnabled,AccessLevel,LoadSeq,AD_Table_ID,IsHighVolume,IsView,IsChangeLog,EntityType,ReplicationType,AD_Table_UU,IsCentrallyMaintained,IsDeleteable,TableName,Description,Name,IsActive,AD_Org_ID,CreatedBy,Updated,UpdatedBy,Created,AD_Client_ID) VALUES ('N','N','N','2',0,200105,'Y','N','N','D','L','af0292e5-c824-47c2-b0cd-99ec92b9fc02','Y','Y','AD_Package_UUID_Map','UUID Mapping between client','UUID Mapping','Y',0,100,TO_DATE('2013-08-23 18:09:02','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2013-08-23 18:09:02','YYYY-MM-DD HH24:MI:SS'),0) diff --git a/migration/i1.0c-release/oracle/201309192024_IDEMPIERE-1370.sql b/migration/i1.0c-release/oracle/201309192024_IDEMPIERE-1370.sql new file mode 100644 index 0000000000..1b23970233 --- /dev/null +++ b/migration/i1.0c-release/oracle/201309192024_IDEMPIERE-1370.sql @@ -0,0 +1,625 @@ +CREATE OR REPLACE FUNCTION BOMPRICELIMIT +( + Product_ID IN NUMBER, + PriceList_Version_ID IN NUMBER +) +RETURN NUMBER +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: BOM_PriceLimit.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Return Limit Price of Product/BOM + * Description: + * if not found: 0 + ************************************************************************/ +AS + v_Price NUMBER; + v_ProductPrice NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Try to get price from PriceList directly + SELECT COALESCE (SUM(PriceLimit), 0) + INTO v_Price + FROM M_PRODUCTPRICE + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; +-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN CUR_BOM LOOP + v_ProductPrice := Bompricelimit (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + END LOOP; + END IF; + -- + RETURN v_Price; +END Bompricelimit; +/ + +CREATE OR REPLACE FUNCTION BOMPRICELIST +( + Product_ID IN NUMBER, + PriceList_Version_ID IN NUMBER +) +RETURN NUMBER +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: BOM_PriceList.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Return List Price of Product/BOM + * Description: + * if not found: 0 + ************************************************************************/ +AS + v_Price NUMBER; + v_ProductPrice NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Try to get price from pricelist directly + SELECT COALESCE (SUM(PriceList), 0) + INTO v_Price + FROM M_PRODUCTPRICE + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; +-- DBMS_OUTPUT.PUT_LINE('Price=' || Price); + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN CUR_BOM LOOP + v_ProductPrice := Bompricelist (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + -- DBMS_OUTPUT.PUT_LINE('Qry=' || bom.BOMQty || ' @ ' || v_ProductPrice || ', Price=' || v_Price); + END LOOP; -- BOM + END IF; + -- + RETURN v_Price; +END Bompricelist; +/ + +CREATE OR REPLACE FUNCTION BOMPRICESTD +( + Product_ID IN NUMBER, + PriceList_Version_ID IN NUMBER +) +RETURN NUMBER +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: BOM_PriceStd.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Return Standard Price of Product/BOM + * Description: + * if not found: 0 + ************************************************************************/ +AS + v_Price NUMBER; + v_ProductPrice NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Try to get price from pricelist directly + SELECT COALESCE(SUM(PriceStd), 0) + INTO v_Price + FROM M_PRODUCTPRICE + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; +-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN CUR_BOM LOOP + v_ProductPrice := Bompricestd (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + -- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price); + END LOOP; -- BOM + END IF; + -- + RETURN v_Price; +END Bompricestd; +/ + +CREATE OR REPLACE FUNCTION BOMQTYONHAND +( + Product_ID IN NUMBER, + Warehouse_ID IN NUMBER, + Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity on hand for BOM + */ +AS + myWarehouse_ID NUMBER; + Quantity NUMBER := 99999; -- unlimited + IsBOM CHAR(1); + IsStocked CHAR(1); + ProductType CHAR(1); + ProductQty NUMBER; + StdPrecision NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Check Parameters + myWarehouse_ID := Warehouse_ID; + IF (myWarehouse_ID IS NULL) THEN + IF (Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=Locator_ID; + END IF; + END IF; + IF (myWarehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO IsBOM, ProductType, IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + -- Unimited capacity if no item + IF (IsBOM='N' AND (ProductType<>'I' OR IsStocked='N')) THEN + RETURN Quantity; + -- Stocked item + ELSIF (IsStocked='Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOnHand), 0) + INTO ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=myWarehouse_ID); + -- + -- DBMS_OUTPUT.PUT_LINE('Qty=' || ProductQty); + RETURN ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE('BOM'); + FOR bom IN CUR_BOM LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOnHand), 0) + INTO ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=myWarehouse_ID); + -- Get Rounding Precision + SELECT NVL(MAX(u.StdPrecision), 0) + INTO StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + ProductQty := ROUND (ProductQty/bom.BOMQty, StdPrecision); + -- How much can we make overall + IF (ProductQty < Quantity) THEN + Quantity := ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + ProductQty := Bomqtyonhand (bom.M_ProductBOM_ID, myWarehouse_ID, Locator_ID); + -- How much can we make overall + IF (ProductQty < Quantity) THEN + Quantity := ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + IF (Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT NVL(MAX(u.StdPrecision), 0) + INTO StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID; + -- + RETURN ROUND (Quantity, StdPrecision); + END IF; + RETURN 0; +END Bomqtyonhand; +/ + +CREATE OR REPLACE FUNCTION BOMQTYORDERED +( + p_Product_ID IN NUMBER, + p_Warehouse_ID IN NUMBER, + p_Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity ordered for BOM + */ +AS + v_Warehouse_ID NUMBER; + v_Quantity NUMBER := 99999; -- unlimited + v_IsBOM CHAR(1); + v_IsStocked CHAR(1); + v_ProductType CHAR(1); + v_ProductQty NUMBER; + v_StdPrecision NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Check Parameters + v_Warehouse_ID := p_Warehouse_ID; + IF (v_Warehouse_ID IS NULL) THEN + IF (p_Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=p_Locator_ID; + END IF; + END IF; + IF (v_Warehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO v_IsBOM, v_ProductType, v_IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=p_Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + + -- No reservation for non-stocked + IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN + RETURN 0; + -- Stocked item + ELSIF (v_IsStocked='Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOrdered), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=p_Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- + RETURN v_ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE('BOM'); + FOR bom IN CUR_BOM LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyOrdered), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- Get Rounding Precision + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + v_ProductQty := Bomqtyordered (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + -- Unlimited (e.g. only services) + IF (v_Quantity = 99999) THEN + RETURN 0; + END IF; + + IF (v_Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; + -- + RETURN ROUND (v_Quantity, v_StdPrecision); + END IF; + -- + RETURN 0; +END Bomqtyordered; +/ + +CREATE OR REPLACE FUNCTION BOMQTYRESERVED +( + p_Product_ID IN NUMBER, + p_Warehouse_ID IN NUMBER, + p_Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity reserved for BOM + */ +AS + v_Warehouse_ID NUMBER; + v_Quantity NUMBER := 99999; -- unlimited + v_IsBOM CHAR(1); + v_IsStocked CHAR(1); + v_ProductType CHAR(1); + v_ProductQty NUMBER; + v_StdPrecision NUMBER; + -- Get BOM Product info + CURSOR CUR_BOM IS + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y'; + -- +BEGIN + -- Check Parameters + v_Warehouse_ID := p_Warehouse_ID; + IF (v_Warehouse_ID IS NULL) THEN + IF (p_Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=p_Locator_ID; + END IF; + END IF; + IF (v_Warehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO v_IsBOM, v_ProductType, v_IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=p_Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + + -- No reservation for non-stocked + IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN + RETURN 0; + -- Stocked item + ELSIF (v_IsStocked='Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyReserved), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=p_Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- + RETURN v_ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE('BOM'); + FOR bom IN CUR_BOM LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT NVL(SUM(QtyReserved), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- Get Rounding Precision + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + v_ProductQty := Bomqtyreserved (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + -- Unlimited (e.g. only services) + IF (v_Quantity = 99999) THEN + RETURN 0; + END IF; + + IF (v_Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT NVL(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; + -- + RETURN ROUND (v_Quantity, v_StdPrecision); + END IF; + RETURN 0; +END Bomqtyreserved; +/ + +CREATE OR REPLACE FUNCTION BOMQTYAVAILABLE +( + Product_ID IN NUMBER, + Warehouse_ID IN NUMBER, + Locator_ID IN NUMBER -- Only used, if warehouse is null +) +RETURN NUMBER +/****************************************************************************** + * ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA + * Open Source Software Provided "AS IS" without warranty or liability + * When you use any parts (changed or unchanged), add "Powered by Compiere" to + * your product name; See license details http://www.compiere.org/license.html + ****************************************************************************** + * Return quantity available for BOM + */ +AS +BEGIN + RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID) + - bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID); +END bomQtyAvailable; +/ + +DROP FUNCTION BOMQTYAVAILABLEASI +; + +DROP FUNCTION BOMQTYONHANDASI +; + +DROP FUNCTION BOMQTYORDEREDASI +; + +DROP FUNCTION BOMQTYRESERVEDASI +; + +-- Sep 19, 2013 8:34:08 PM COT +-- IDEMPIERE-1370 Circular Reference in Product Info when a bom product is referenced to itself and its price-lists prices are set to zero +UPDATE AD_Process SET IsActive='N',Updated=TO_DATE('2013-09-19 20:34:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=346 +; + +-- Sep 19, 2013 8:34:08 PM COT +UPDATE AD_Menu SET Name='Verify BOMs', Description='Verify BOM Structures', IsActive='N',Updated=TO_DATE('2013-09-19 20:34:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=585 +; + +-- Sep 19, 2013 8:36:42 PM COT +UPDATE AD_Process_Para SET IsMandatory='Y', DefaultValue='Y',Updated=TO_DATE('2013-09-19 20:36:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53463 +; + +-- Sep 19, 2013 8:55:22 PM COT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_DATE('2013-09-19 20:55:22','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3746 +; + +-- Sep 19, 2013 8:55:55 PM COT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_DATE('2013-09-19 20:55:55','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=59805 +; + +-- Sep 19, 2013 8:59:20 PM COT +UPDATE AD_Process_Para SET DefaultValue='@M_Product_ID@',Updated=TO_DATE('2013-09-19 20:59:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53461 +; + +-- Sep 19, 2013 8:59:36 PM COT +UPDATE AD_Process_Para SET ReadOnlyLogic='@M_Product_ID@>0',Updated=TO_DATE('2013-09-19 20:59:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53461 +; + +-- Sep 19, 2013 8:59:50 PM COT +UPDATE AD_Process_Para SET DisplayLogic='@M_Product_ID@=0',Updated=TO_DATE('2013-09-19 20:59:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53462 +; + +-- Sep 19, 2013 9:12:59 PM COT +UPDATE AD_Process_Para SET DisplayLogic='@M_Product_ID@=0',Updated=TO_DATE('2013-09-19 21:12:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53463 +; + +-- Sep 19, 2013 9:21:47 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_DATE('2013-09-19 21:21:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=133 +; + +-- Sep 19, 2013 9:21:47 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_DATE('2013-09-19 21:21:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=145 +; + +-- Sep 19, 2013 9:22:10 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_DATE('2013-09-19 21:22:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=50001 +; + +-- Sep 19, 2013 9:44:39 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_DATE('2013-09-19 21:44:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=50000 +; + +SELECT register_migration_script('201309192024_IDEMPIERE-1370.sql') FROM dual +; + diff --git a/migration/i1.0c-release/postgresql/201308260558_IDEMPIERE-1298.sql b/migration/i1.0c-release/postgresql/201308260558_IDEMPIERE-1298.sql index ce2632bbba..7b6a0432e7 100644 --- a/migration/i1.0c-release/postgresql/201308260558_IDEMPIERE-1298.sql +++ b/migration/i1.0c-release/postgresql/201308260558_IDEMPIERE-1298.sql @@ -1,8 +1,3 @@ --- Aug 23, 2013 6:08:39 PM MYT --- IDEMPIERE-1297 2Pack: Remove code for the lookup of record and reference using business key -UPDATE AD_SysConfig SET Value='IDEMPIERE-1298 2Pack: Support copying of data from one client to another',Updated=TO_TIMESTAMP('2013-08-23 18:08:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=50003 -; - -- Aug 23, 2013 6:09:08 PM MYT -- IDEMPIERE-1298 2Pack: Support copying of data from one client to another INSERT INTO AD_Table (ImportTable,CopyColumnsFromTable,IsSecurityEnabled,AccessLevel,LoadSeq,AD_Table_ID,IsHighVolume,IsView,IsChangeLog,EntityType,ReplicationType,AD_Table_UU,IsCentrallyMaintained,IsDeleteable,TableName,Description,Name,IsActive,AD_Org_ID,CreatedBy,Updated,UpdatedBy,Created,AD_Client_ID) VALUES ('N','N','N','2',0,200105,'Y','N','N','D','L','af0292e5-c824-47c2-b0cd-99ec92b9fc02','Y','Y','AD_Package_UUID_Map','UUID Mapping between client','UUID Mapping','Y',0,100,TO_TIMESTAMP('2013-08-23 18:09:02','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2013-08-23 18:09:02','YYYY-MM-DD HH24:MI:SS'),0) diff --git a/migration/i1.0c-release/postgresql/201309192024_IDEMPIERE-1370.sql b/migration/i1.0c-release/postgresql/201309192024_IDEMPIERE-1370.sql new file mode 100644 index 0000000000..8774a68adb --- /dev/null +++ b/migration/i1.0c-release/postgresql/201309192024_IDEMPIERE-1370.sql @@ -0,0 +1,539 @@ +CREATE OR REPLACE FUNCTION bompricelimit (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS +$BODY$ +DECLARE + v_Price NUMERIC; + v_ProductPrice NUMERIC; + bom RECORD; + +BEGIN + -- Try to get price from PriceList directly + SELECT COALESCE (SUM(PriceLimit), 0) + INTO v_Price + FROM M_ProductPrice + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_Product_BOM b, M_Product p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' + LOOP + v_ProductPrice := bomPriceLimit (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + END LOOP; + END IF; + -- + RETURN v_Price; + +END; + +$BODY$ +LANGUAGE 'plpgsql' +; + +CREATE OR REPLACE FUNCTION bompricelist (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS +$BODY$ +DECLARE + v_Price NUMERIC; + v_ProductPrice NUMERIC; + bom RECORD; + +BEGIN + -- Try to get price from pricelist directly + SELECT COALESCE (SUM(PriceList), 0) + INTO v_Price + FROM M_ProductPrice + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_Product_BOM b, M_Product p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' + LOOP + v_ProductPrice := bomPriceList (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + END LOOP; + END IF; + -- + RETURN v_Price; + +END; + +$BODY$ +LANGUAGE 'plpgsql' +; + +CREATE OR REPLACE FUNCTION bompricestd (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS +$BODY$ +DECLARE + v_Price NUMERIC; + v_ProductPrice NUMERIC; + bom RECORD; + +BEGIN + -- Try to get price from PriceList directly + SELECT COALESCE(SUM(PriceStd), 0) + INTO v_Price + FROM M_ProductPrice + WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID; + + -- No Price - Check if BOM + IF (v_Price = 0) THEN + FOR bom IN + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM + FROM M_Product_BOM b, M_Product p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' + LOOP + v_ProductPrice := bomPriceStd (bom.M_ProductBOM_ID, PriceList_Version_ID); + v_Price := v_Price + (bom.BOMQty * v_ProductPrice); + END LOOP; + END IF; + -- + RETURN v_Price; + +END; + +$BODY$ +LANGUAGE 'plpgsql' +; + +CREATE OR REPLACE FUNCTION bomqtyonhand (in product_id numeric, in warehouse_id numeric, in locator_id numeric) RETURNS numeric AS +$BODY$ +DECLARE + myWarehouse_ID numeric; + v_Quantity numeric := 99999; -- unlimited + v_IsBOM CHAR(1); + v_IsStocked CHAR(1); + v_ProductType CHAR(1); + v_ProductQty numeric; + v_StdPrecision int; + bom record; + +BEGIN + -- Check Parameters + myWarehouse_ID := Warehouse_ID; + IF (myWarehouse_ID IS NULL) THEN + IF (Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=Locator_ID; + END IF; + END IF; + IF (myWarehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE(''Warehouse='' || myWarehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO v_IsBOM, v_ProductType, v_IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + -- Unimited capacity if no item + IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN + RETURN v_Quantity; + -- Stocked item + ELSIF (v_IsStocked='Y') THEN + -- Get ProductQty + SELECT COALESCE(SUM(QtyOnHand), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=myWarehouse_ID); + -- + -- DBMS_OUTPUT.PUT_LINE(''Qty='' || v_ProductQty); + RETURN v_ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE(''BOM''); + FOR bom IN -- Get BOM Product info + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' + LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get v_ProductQty + SELECT COALESCE(SUM(QtyOnHand), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=myWarehouse_ID); + -- Get Rounding Precision + SELECT COALESCE(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + v_ProductQty := Bomqtyonhand (bom.M_ProductBOM_ID, myWarehouse_ID, Locator_ID); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + IF (v_Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT COALESCE(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID; + -- + RETURN ROUND (v_Quantity, v_StdPrecision); + END IF; + RETURN 0; +END; +$BODY$ +LANGUAGE 'plpgsql' +; + +CREATE OR REPLACE FUNCTION bomqtyordered (in p_product_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) RETURNS numeric AS +$BODY$ +DECLARE + v_Warehouse_ID numeric; + v_Quantity numeric := 99999; -- unlimited + v_IsBOM CHAR(1); + v_IsStocked CHAR(1); + v_ProductType CHAR(1); + v_ProductQty numeric; + v_StdPrecision int; + bom record; +BEGIN + -- Check Parameters + v_Warehouse_ID := p_Warehouse_ID; + IF (v_Warehouse_ID IS NULL) THEN + IF (p_Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=p_Locator_ID; + END IF; + END IF; + IF (v_Warehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE(''Warehouse='' || v_Warehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO v_IsBOM, v_ProductType, v_IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=p_Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + + -- No reservation for non-stocked + IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN + RETURN 0; + -- Stocked item + ELSIF (v_IsStocked='Y') THEN + -- Get ProductQty + SELECT COALESCE(SUM(QtyOrdered), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=p_Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- + RETURN v_ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE(''BOM''); + FOR bom IN + -- Get BOM Product info + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' + LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT COALESCE(SUM(QtyOrdered), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- Get Rounding Precision + SELECT COALESCE(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision ); + + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + v_ProductQty := Bomqtyordered (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + -- Unlimited (e.g. only services) + IF (v_Quantity = 99999) THEN + RETURN 0; + END IF; + + IF (v_Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT COALESCE(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; + -- + RETURN ROUND (v_Quantity, v_StdPrecision ); + END IF; + -- + RETURN 0; +END; +$BODY$ +LANGUAGE 'plpgsql' +; + +CREATE OR REPLACE FUNCTION bomqtyreserved (in p_product_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) RETURNS numeric AS +$BODY$ +DECLARE + v_Warehouse_ID numeric; + v_Quantity numeric := 99999; -- unlimited + v_IsBOM CHAR(1); + v_IsStocked CHAR(1); + v_ProductType CHAR(1); + v_ProductQty numeric; + v_StdPrecision int; + bom record; +BEGIN + -- Check Parameters + v_Warehouse_ID := p_Warehouse_ID; + IF (v_Warehouse_ID IS NULL) THEN + IF (p_Locator_ID IS NULL) THEN + RETURN 0; + ELSE + SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID + FROM M_LOCATOR + WHERE M_Locator_ID=p_Locator_ID; + END IF; + END IF; + IF (v_Warehouse_ID IS NULL) THEN + RETURN 0; + END IF; +-- DBMS_OUTPUT.PUT_LINE(''Warehouse='' || v_Warehouse_ID); + + -- Check, if product exists and if it is stocked + BEGIN + SELECT IsBOM, ProductType, IsStocked + INTO v_IsBOM, v_ProductType, v_IsStocked + FROM M_PRODUCT + WHERE M_Product_ID=p_Product_ID; + -- + EXCEPTION -- not found + WHEN OTHERS THEN + RETURN 0; + END; + + -- No reservation for non-stocked + IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN + RETURN 0; + -- Stocked item + ELSIF (v_IsStocked='Y') THEN + -- Get ProductQty + SELECT COALESCE(SUM(QtyReserved), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=p_Product_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- + RETURN v_ProductQty; + END IF; + + -- Go though BOM +-- DBMS_OUTPUT.PUT_LINE(''BOM''); + FOR bom IN + -- Get BOM Product info + SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType + FROM M_PRODUCT_BOM b, M_PRODUCT p + WHERE b.M_ProductBOM_ID=p.M_Product_ID + AND b.M_Product_ID=p_Product_ID + AND p.IsBOM='Y' + AND p.IsVerified='Y' + LOOP + -- Stocked Items "leaf node" + IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN + -- Get ProductQty + SELECT COALESCE(SUM(QtyReserved), 0) + INTO v_ProductQty + FROM M_STORAGE s + WHERE M_Product_ID=bom.M_ProductBOM_ID + AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID + AND l.M_Warehouse_ID=v_Warehouse_ID); + -- Get Rounding Precision + SELECT COALESCE(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID; + -- How much can we make with this product + v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + -- Another BOM + ELSIF (bom.IsBOM = 'Y') THEN + v_ProductQty := Bomqtyreserved (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID); + -- How much can we make overall + IF (v_ProductQty < v_Quantity) THEN + v_Quantity := v_ProductQty; + END IF; + END IF; + END LOOP; -- BOM + + -- Unlimited (e.g. only services) + IF (v_Quantity = 99999) THEN + RETURN 0; + END IF; + + IF (v_Quantity > 0) THEN + -- Get Rounding Precision for Product + SELECT COALESCE(MAX(u.StdPrecision), 0) + INTO v_StdPrecision + FROM C_UOM u, M_PRODUCT p + WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID; + -- + RETURN ROUND (v_Quantity, v_StdPrecision); + END IF; + RETURN 0; +END; +$BODY$ +LANGUAGE 'plpgsql' +; + +CREATE OR REPLACE FUNCTION bomqtyavailable (in product_id numeric, in warehouse_id numeric, in locator_id numeric) RETURNS numeric AS +$BODY$ +BEGIN + RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID) - bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID); +END; +$BODY$ +LANGUAGE 'plpgsql' +; + +DROP FUNCTION bomqtyavailable (in product_id numeric, in attributesetinstance_id numeric, in warehouse_id numeric, in locator_id numeric) +; + +DROP FUNCTION bomqtyavailableasi (in product_id numeric, in attributesetinstance_id numeric, in warehouse_id numeric, in locator_id numeric) +; + +DROP FUNCTION bomqtyonhandasi (in product_id numeric, in attributesetinstance_id numeric, in warehouse_id numeric, in locator_id numeric) +; + +DROP FUNCTION bomqtyorderedasi (in p_product_id numeric, in attributesetinstance_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) +; + +DROP FUNCTION bomqtyreservedasi (in p_product_id numeric, in attributesetinstance_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) +; + +-- Sep 19, 2013 8:34:08 PM COT +-- IDEMPIERE-1370 Circular Reference in Product Info when a bom product is referenced to itself and its price-lists prices are set to zero +UPDATE AD_Process SET IsActive='N',Updated=TO_TIMESTAMP('2013-09-19 20:34:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=346 +; + +-- Sep 19, 2013 8:34:08 PM COT +UPDATE AD_Menu SET Name='Verify BOMs', Description='Verify BOM Structures', IsActive='N',Updated=TO_TIMESTAMP('2013-09-19 20:34:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=585 +; + +-- Sep 19, 2013 8:36:42 PM COT +UPDATE AD_Process_Para SET IsMandatory='Y', DefaultValue='Y',Updated=TO_TIMESTAMP('2013-09-19 20:36:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53463 +; + +-- Sep 19, 2013 8:55:22 PM COT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_TIMESTAMP('2013-09-19 20:55:22','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3746 +; + +-- Sep 19, 2013 8:55:55 PM COT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_TIMESTAMP('2013-09-19 20:55:55','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=59805 +; + +-- Sep 19, 2013 8:59:20 PM COT +UPDATE AD_Process_Para SET DefaultValue='@M_Product_ID@',Updated=TO_TIMESTAMP('2013-09-19 20:59:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53461 +; + +-- Sep 19, 2013 8:59:36 PM COT +UPDATE AD_Process_Para SET ReadOnlyLogic='@M_Product_ID@>0',Updated=TO_TIMESTAMP('2013-09-19 20:59:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53461 +; + +-- Sep 19, 2013 8:59:50 PM COT +UPDATE AD_Process_Para SET DisplayLogic='@M_Product_ID@=0',Updated=TO_TIMESTAMP('2013-09-19 20:59:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53462 +; + +-- Sep 19, 2013 9:12:59 PM COT +UPDATE AD_Process_Para SET DisplayLogic='@M_Product_ID@=0',Updated=TO_TIMESTAMP('2013-09-19 21:12:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53463 +; + +-- Sep 19, 2013 9:21:47 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_TIMESTAMP('2013-09-19 21:21:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=133 +; + +-- Sep 19, 2013 9:21:47 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_TIMESTAMP('2013-09-19 21:21:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=145 +; + +-- Sep 19, 2013 9:22:10 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_TIMESTAMP('2013-09-19 21:22:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=50001 +; + +-- Sep 19, 2013 9:44:39 PM COT +UPDATE M_Product SET IsVerified='Y',Updated=TO_TIMESTAMP('2013-09-19 21:44:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE M_Product_ID=50000 +; + +SELECT register_migration_script('201309192024_IDEMPIERE-1370.sql') FROM dual +; + diff --git a/org.adempiere.base.process/src/org/compiere/process/BOMVerify.java b/org.adempiere.base.process/src/org/compiere/process/BOMVerify.java index 0204f0b83e..230ce83d69 100644 --- a/org.adempiere.base.process/src/org/compiere/process/BOMVerify.java +++ b/org.adempiere.base.process/src/org/compiere/process/BOMVerify.java @@ -38,6 +38,8 @@ public class BOMVerify extends SvrProcess private int p_M_Product_Category_ID = 0; /** Re-Validate */ private boolean p_IsReValidate = false; + + private boolean p_fromButton = false; /** List of Products */ private ArrayList foundproducts = new ArrayList(); @@ -68,6 +70,7 @@ public class BOMVerify extends SvrProcess } if ( p_M_Product_ID == 0 ) p_M_Product_ID = getRecord_ID(); + p_fromButton = (getRecord_ID() > 0); } // prepare /** @@ -155,9 +158,12 @@ public class BOMVerify extends SvrProcess MProductBOM[] productsBOMs = MProductBOM.getBOMLines(product); boolean containsinvalid = false; boolean invalid = false; - for (int i = 0; i < productsBOMs.length; i++) + int lines = 0; + for (MProductBOM productsBOM : productsBOMs) { - MProductBOM productsBOM = productsBOMs[i]; + if (! productsBOM.isActive()) + continue; + lines++; MProduct pp = new MProduct(getCtx(), productsBOM.getM_ProductBOM_ID(), get_TrxName()); if (!pp.isBOM()) { if (log.isLoggable(Level.FINER)) log.finer(pp.getName()); @@ -173,7 +179,10 @@ public class BOMVerify extends SvrProcess else if (foundproducts.contains(pp)) { invalid = true; - addLog(0, null, null, product.getValue() + " recursively contains " + pp.getValue(), MProduct.Table_ID, product.getM_Product_ID()); + if (p_fromButton) + addLog(0, null, null, product.getValue() + " recursively contains " + pp.getValue()); + else + addLog(0, null, null, product.getValue() + " recursively contains " + pp.getValue(), MProduct.Table_ID, product.getM_Product_ID()); } else { @@ -181,14 +190,19 @@ public class BOMVerify extends SvrProcess { containsinvalid = true; } - + } } - - - } - + + if (lines == 0) { + invalid = true; + if (p_fromButton) + addLog(0, null, null, product.getValue() + " does not have lines"); + else + addLog(0, null, null, product.getValue() + " does not have lines", MProduct.Table_ID, product.getM_Product_ID()); + } + checkedproducts.add(product); foundproducts.remove(product); if (invalid) diff --git a/org.adempiere.base.process/src/org/compiere/process/M_Product_BOM_Check.java b/org.adempiere.base.process/src/org/compiere/process/M_Product_BOM_Check.java deleted file mode 100644 index 657b621df7..0000000000 --- a/org.adempiere.base.process/src/org/compiere/process/M_Product_BOM_Check.java +++ /dev/null @@ -1,193 +0,0 @@ -/****************************************************************************** - * 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 * - * Portions created by Carlos Ruiz are Copyright (C) 2005 QSS Ltda. - * Contributor(s): Carlos Ruiz (globalqss) - *****************************************************************************/ -package org.compiere.process; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.logging.Level; - -import org.compiere.model.X_M_Product; -import org.compiere.util.AdempiereUserError; -import org.compiere.util.CLogger; -import org.compiere.util.DB; -import org.compiere.util.Env; -import org.compiere.util.ValueNamePair; - -/** - * Title: Check BOM Structure (free of cycles) - * Description: - * Tree cannot contain BOMs which are already referenced - * - * @author Carlos Ruiz (globalqss) - * @version $Id: M_Product_BOM_Check.java,v 1.0 2005/09/17 13:32:00 globalqss Exp $ - * @author Carlos Ruiz (globalqss) - * Make T_Selection tables permanent - */ -public class M_Product_BOM_Check extends SvrProcess -{ - - /** The Record */ - private int p_Record_ID = 0; - - private int m_AD_PInstance_ID = 0; - - /** - * Prepare - e.g., get Parameters. - */ - protected void prepare() - { - ProcessInfoParameter[] para = getParameter(); - for (int i = 0; i < para.length; i++) - { - String name = para[i].getParameterName(); - if (para[i].getParameter() == null) - ; - else - log.log(Level.SEVERE, "Unknown Parameter: " + name); - } - p_Record_ID = getRecord_ID(); - m_AD_PInstance_ID = getAD_PInstance_ID(); - } // prepare - - /** - * Process - * @return message - * @throws Exception - */ - protected String doIt() throws Exception - { - StringBuilder sql1 = null; - int no = 0; - - log.info("Check BOM Structure"); - - // Record ID is M_Product_ID of product to be tested - X_M_Product xp = new X_M_Product(Env.getCtx(), p_Record_ID, get_TrxName()); - - if (! xp.isBOM()) { - log.info("NOT BOM Product"); - // No BOM - should not happen, but no problem - xp.setIsVerified(true); - xp.saveEx(get_TrxName()); - return "OK"; - } - - // Table to put all BOMs - duplicate will cause exception - sql1 = new StringBuilder("DELETE FROM T_Selection2 WHERE Query_ID = 0 AND AD_PInstance_ID=").append(m_AD_PInstance_ID); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - sql1 = new StringBuilder("INSERT INTO T_Selection2 (AD_PInstance_ID, Query_ID, T_Selection_ID) VALUES (") - .append(m_AD_PInstance_ID) - .append(", 0, ") - .append(p_Record_ID).append(")"); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - // Table of root modes - sql1 = new StringBuilder("DELETE FROM T_Selection WHERE AD_PInstance_ID=").append(m_AD_PInstance_ID); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - sql1 = new StringBuilder("INSERT INTO T_Selection (AD_PInstance_ID, T_Selection_ID) VALUES (") - .append(m_AD_PInstance_ID) - .append(", ") - .append(p_Record_ID).append(")"); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - - while (true) { - - // Get count remaining on t_selection - int countno = 0; - PreparedStatement pstmt = null; - ResultSet rs = null; - try - { - StringBuilder dbpst = new StringBuilder("SELECT COUNT(*) FROM T_Selection WHERE AD_PInstance_ID=").append(m_AD_PInstance_ID); - pstmt = DB.prepareStatement(dbpst.toString(), get_TrxName()); - rs = pstmt.executeQuery(); - if (rs.next()) - countno = rs.getInt(1); - } - catch (SQLException e) - { - throw new Exception ("count t_selection", e); - } - finally - { - DB.close(rs, pstmt); - rs = null; - pstmt = null; - } - if (log.isLoggable(Level.FINE)) log.fine("Count T_Selection =" + countno); - - if (countno == 0) - break; - - try - { - // if any command fails (no==-1) break and inform failure - // Insert BOM Nodes into "All" table - sql1 = new StringBuilder("INSERT INTO T_Selection2 (AD_PInstance_ID, Query_ID, T_Selection_ID) ") - .append("SELECT ").append(m_AD_PInstance_ID).append(", 0, p.M_Product_ID FROM M_Product p WHERE IsBOM='Y' AND EXISTS ") - //+ "(SELECT * FROM M_Product_BOM b WHERE p.M_Product_ID=b.M_ProductBOM_ID AND b.M_Product_ID IN " - .append("(SELECT * FROM PP_Product_BOM b WHERE p.M_Product_ID=b.M_Product_ID AND b.M_Product_ID IN ") - .append("(SELECT T_Selection_ID FROM T_Selection WHERE AD_PInstance_ID=").append(m_AD_PInstance_ID).append("))"); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString()); - // Insert BOM Nodes into temporary table - sql1 = new StringBuilder("DELETE FROM T_Selection2 WHERE Query_ID = 1 AND AD_PInstance_ID=").append(m_AD_PInstance_ID); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString()); - sql1 = new StringBuilder("INSERT INTO T_Selection2 (AD_PInstance_ID, Query_ID, T_Selection_ID) ") - .append("SELECT ").append(m_AD_PInstance_ID).append(", 1, p.M_Product_ID FROM M_Product p WHERE IsBOM='Y' AND EXISTS ") - //+ "(SELECT * FROM M_Product_BOM b WHERE p.M_Product_ID=b.M_ProductBOM_ID AND b.M_Product_ID IN " - .append("(SELECT * FROM PP_Product_BOM b WHERE p.M_Product_ID=b.M_Product_ID AND b.M_Product_ID IN ") - .append("(SELECT T_Selection_ID FROM T_Selection WHERE AD_PInstance_ID=").append(m_AD_PInstance_ID).append("))"); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString()); - // Copy into root table - sql1 = new StringBuilder("DELETE FROM T_Selection WHERE AD_PInstance_ID=").append(m_AD_PInstance_ID); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString()); - sql1 = new StringBuilder("INSERT INTO T_Selection (AD_PInstance_ID, T_Selection_ID) ") - .append("SELECT ").append(m_AD_PInstance_ID).append(", T_Selection_ID ") - .append("FROM T_Selection2 WHERE Query_ID = 1 AND AD_PInstance_ID=").append(m_AD_PInstance_ID); - no = DB.executeUpdate(sql1.toString(), get_TrxName()); - if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString()); - } - catch (Exception e) - { - throw new Exception ("root insert", e); - } - - } - - // Finish process - xp.setIsVerified(true); - xp.saveEx(get_TrxName()); - return "OK"; - } // doIt - - private void raiseError(String string, String sql) throws Exception { - DB.rollback(false, get_TrxName()); - StringBuilder msg = new StringBuilder(string); - ValueNamePair pp = CLogger.retrieveError(); - if (pp != null) - msg = new StringBuilder(pp.getName()).append(" - "); - msg.append(sql); - throw new AdempiereUserError (msg.toString()); - } - -} // M_Product_BOM_Check diff --git a/org.adempiere.base/src/org/compiere/model/MProductBOM.java b/org.adempiere.base/src/org/compiere/model/MProductBOM.java index 1533d5946f..c9cfdae077 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductBOM.java +++ b/org.adempiere.base/src/org/compiere/model/MProductBOM.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Properties; import org.compiere.util.CLogger; +import org.compiere.util.DB; import org.compiere.util.Env; /** @@ -37,8 +38,7 @@ public class MProductBOM extends X_M_Product_BOM /** * */ - private static final long serialVersionUID = 6029128559467083124L; - + private static final long serialVersionUID = 2615029184168566124L; /** * Get BOM Lines for Product @@ -96,7 +96,7 @@ public class MProductBOM extends X_M_Product_BOM } // MProductBOM /** - * Load Construvtor + * Load Constructor * @param ctx context * @param rs result set * @param trxName transaction @@ -159,22 +159,51 @@ public class MProductBOM extends X_M_Product_BOM { if (!success) return success; - // Product Line was changed - if (newRecord || is_ValueChanged("M_ProductBOM_ID")) + MProduct product = new MProduct (getCtx(), getM_Product_ID(), get_TrxName()); + if (get_TrxName() != null) + product.load(get_TrxName()); + if (product.isVerified()) { - // Invalidate BOM - MProduct product = new MProduct (getCtx(), getM_Product_ID(), get_TrxName()); - if (get_TrxName() != null) - product.load(get_TrxName()); - if (product.isVerified()) + if ( newRecord + || is_ValueChanged("M_ProductBOM_ID") // Product Line was changed + || (is_ValueChanged("IsActive") && isActive())) // line was activated { + // Invalidate BOM product.setIsVerified(false); product.saveEx(get_TrxName()); } - // Invalidate Products where BOM is used - + if (product.isVerified() && is_ValueChanged("IsActive") && !isActive()) { // line was inactivated + if (! hasActiveComponents(getM_Product_ID())) { + product.setIsVerified(false); + product.saveEx(get_TrxName()); + } + } } return success; } // afterSave + + @Override + protected boolean afterDelete(boolean success) { + if (!success) + return success; + MProduct product = new MProduct (getCtx(), getM_Product_ID(), get_TrxName()); + if (get_TrxName() != null) + product.load(get_TrxName()); + if (product.isVerified()) + { + if (! hasActiveComponents(getM_Product_ID())) { + product.setIsVerified(false); + product.saveEx(get_TrxName()); + } + } + return success; + } + private boolean hasActiveComponents(int productID) { + int cnt = DB.getSQLValue(get_TrxName(), + "SELECT COUNT(*) FROM M_Product_BOM WHERE IsActive='Y' AND M_Product_ID=? AND M_Product_BOM_ID!=?", + productID, getM_Product_BOM_ID()); + return cnt > 0; + } + } // MProductBOM diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java index 735de0e6dc..31543d8d3e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java @@ -65,6 +65,7 @@ import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.MaximizeEvent; import org.zkoss.zul.Anchorchildren; import org.zkoss.zul.Anchorlayout; +import org.zkoss.zul.Caption; import org.zkoss.zul.Html; import org.zkoss.zul.Iframe; import org.zkoss.zul.Include; @@ -174,12 +175,13 @@ public class DashboardController implements EventListener { } Panel panel = new Panel(); + Caption caption = new Caption(dc.get_Translation(MDashboardContent.COLUMNNAME_Name)); + panel.appendChild(caption); panel.setAttribute("PA_DashboardContent_ID", dp.getPA_DashboardContent_ID()); panel.setAttribute("PA_DashboardPreference_ID", dp.getPA_DashboardPreference_ID()); panelList.add(panel); panel.addEventListener(Events.ON_MAXIMIZE, this); panel.setSclass("dashboard-widget"); - panel.setTitle(dc.get_Translation(MDashboardContent.COLUMNNAME_Name)); panel.setMaximizable(true); String description = dc.get_Translation(MDashboardContent.COLUMNNAME_Description); @@ -191,7 +193,7 @@ public class DashboardController implements EventListener { panel.addEventListener(Events.ON_OPEN, this); panel.setDroppable("true"); - panel.setDraggable("true"); + panel.getCaption().setDraggable("true"); panel.addEventListener(Events.ON_DROP, this); panel.setBorder("normal"); @@ -471,11 +473,16 @@ public class DashboardController implements EventListener { DropEvent de = (DropEvent) event; Component dragged = de.getDragged(); - if(dragged instanceof Panel) + if(dragged instanceof Caption) { - Panel panel = (Panel) dragged; - - if(comp instanceof Panel) + Caption caption = (Caption) dragged; + Panel panel = null; + if (caption.getParent() instanceof Panel) + panel = (Panel) caption.getParent(); + + if (panel == null) + ; + else if(comp instanceof Panel) { Panel target = (Panel) comp; diff --git a/org.adempiere.ui.zk/theme/default/css/theme.css.dsp b/org.adempiere.ui.zk/theme/default/css/theme.css.dsp index ad97af5834..625c91e190 100644 --- a/org.adempiere.ui.zk/theme/default/css/theme.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/theme.css.dsp @@ -592,10 +592,19 @@ div.wc-modal, div.wc-modal-none, div.wc-highlighted, div.wc-highlighted-none { .z-panel-hl .z-panel-header { padding: 0 0 2px 0; color: #262626; + background: #F4F4F4; font-weight: 300; font-size: 13px; } +.z-caption .z-caption-l, .z-caption .z-caption-r { + padding: 0 0 2px 0; + color: #262626; + font-weight: 300; + font-size: 13px; + cursor: move; +} + .desktop-home-tabpanel .z-panel-tl, .desktop-home-tabpanel .z-panel-tr, .desktop-home-tabpanel .z-panel-hr, .desktop-home-tabpanel .z-panel-hl, .desktop-home-tabpanel .z-panel-hm {