IDEMPIERE-1370 Circular Reference in Product Info when a bom product is referenced to itself and its price-lists prices are set to zero
Thorough review of the BOM verification process: 1 - changed the three BOMprice functions to not take into account unverified BOMs 2 - fixed four BOMQty functions to point to correct BOM structures 3 - dropped from DB unused BOMQty*ASI functions and deprecated M_Product_BOM_Check.java class 4 - Verify BOMs process inactivated (pointing to unused structures) 5 - set default and displaylogic for process parameters of Verify BOM Structure 6 - set product verified flag as readonly to allow modification just via process verify BOM 7 - BOM products are marked as not verified when lines are changed or last line deleted
This commit is contained in:
parent
c210b5e571
commit
5bc1dae184
|
@ -1,53 +1,51 @@
|
||||||
CREATE OR REPLACE FUNCTION Bompricelimit
|
CREATE OR REPLACE FUNCTION BOMPRICELIMIT
|
||||||
(
|
(
|
||||||
Product_ID IN NUMBER,
|
Product_ID IN NUMBER,
|
||||||
PriceList_Version_ID IN NUMBER
|
PriceList_Version_ID IN NUMBER
|
||||||
)
|
)
|
||||||
RETURN NUMBER
|
RETURN NUMBER
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* The contents of this file are subject to the Compiere License. You may
|
* 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
|
* 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
|
* 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
|
* express or implied. See the License for details. Code: Compiere ERP+CRM
|
||||||
* Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved.
|
* 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 $
|
* $Id: BOM_PriceLimit.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $
|
||||||
***
|
***
|
||||||
* Title: Return Limit Price of Product/BOM
|
* Title: Return Limit Price of Product/BOM
|
||||||
* Description:
|
* Description:
|
||||||
* if not found: 0
|
* if not found: 0
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
AS
|
AS
|
||||||
v_Price NUMBER;
|
v_Price NUMBER;
|
||||||
v_ProductPrice NUMBER;
|
v_ProductPrice NUMBER;
|
||||||
-- Get BOM Product info
|
-- Get BOM Product info
|
||||||
CURSOR CUR_BOM IS
|
CURSOR CUR_BOM IS
|
||||||
/*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
||||||
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
AND b.M_Product_ID=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
|
AND p.IsBOM='Y'
|
||||||
FROM PP_PRODUCT_BOM b
|
AND p.IsVerified='Y';
|
||||||
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)
|
BEGIN
|
||||||
WHERE b.M_Product_ID = Product_ID;
|
-- Try to get price from PriceList directly
|
||||||
--
|
SELECT COALESCE (SUM(PriceLimit), 0)
|
||||||
BEGIN
|
INTO v_Price
|
||||||
-- Try to get price from PriceList directly
|
FROM M_PRODUCTPRICE
|
||||||
SELECT COALESCE (SUM(PriceLimit), 0)
|
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
||||||
INTO v_Price
|
-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price);
|
||||||
FROM M_PRODUCTPRICE
|
|
||||||
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
-- No Price - Check if BOM
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price);
|
IF (v_Price = 0) THEN
|
||||||
|
FOR bom IN CUR_BOM LOOP
|
||||||
-- No Price - Check if BOM
|
v_ProductPrice := Bompricelimit (bom.M_ProductBOM_ID, PriceList_Version_ID);
|
||||||
IF (v_Price = 0) THEN
|
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
||||||
FOR bom IN CUR_BOM LOOP
|
END LOOP;
|
||||||
v_ProductPrice := Bompricelimit (bom.M_ProductBOM_ID, PriceList_Version_ID);
|
END IF;
|
||||||
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
--
|
||||||
END LOOP;
|
RETURN v_Price;
|
||||||
END IF;
|
END Bompricelimit;
|
||||||
--
|
/
|
||||||
RETURN v_Price;
|
|
||||||
END Bompricelimit;
|
|
||||||
/
|
|
||||||
|
|
|
@ -1,54 +1,52 @@
|
||||||
CREATE OR REPLACE FUNCTION Bompricelist
|
CREATE OR REPLACE FUNCTION BOMPRICELIST
|
||||||
(
|
(
|
||||||
Product_ID IN NUMBER,
|
Product_ID IN NUMBER,
|
||||||
PriceList_Version_ID IN NUMBER
|
PriceList_Version_ID IN NUMBER
|
||||||
)
|
)
|
||||||
RETURN NUMBER
|
RETURN NUMBER
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* The contents of this file are subject to the Compiere License. You may
|
* 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
|
* 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
|
* 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
|
* express or implied. See the License for details. Code: Compiere ERP+CRM
|
||||||
* Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved.
|
* 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 $
|
* $Id: BOM_PriceList.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $
|
||||||
***
|
***
|
||||||
* Title: Return List Price of Product/BOM
|
* Title: Return List Price of Product/BOM
|
||||||
* Description:
|
* Description:
|
||||||
* if not found: 0
|
* if not found: 0
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
AS
|
AS
|
||||||
v_Price NUMBER;
|
v_Price NUMBER;
|
||||||
v_ProductPrice NUMBER;
|
v_ProductPrice NUMBER;
|
||||||
-- Get BOM Product info
|
-- Get BOM Product info
|
||||||
CURSOR CUR_BOM IS
|
CURSOR CUR_BOM IS
|
||||||
/*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
||||||
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
AND b.M_Product_ID=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
|
AND p.IsBOM='Y'
|
||||||
FROM PP_PRODUCT_BOM b
|
AND p.IsVerified='Y';
|
||||||
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)
|
BEGIN
|
||||||
WHERE b.M_Product_ID = Product_ID;
|
-- Try to get price from pricelist directly
|
||||||
--
|
SELECT COALESCE (SUM(PriceList), 0)
|
||||||
BEGIN
|
INTO v_Price
|
||||||
-- Try to get price from pricelist directly
|
FROM M_PRODUCTPRICE
|
||||||
SELECT COALESCE (SUM(PriceList), 0)
|
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
||||||
INTO v_Price
|
-- DBMS_OUTPUT.PUT_LINE('Price=' || Price);
|
||||||
FROM M_PRODUCTPRICE
|
|
||||||
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
-- No Price - Check if BOM
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Price=' || Price);
|
IF (v_Price = 0) THEN
|
||||||
|
FOR bom IN CUR_BOM LOOP
|
||||||
-- No Price - Check if BOM
|
v_ProductPrice := Bompricelist (bom.M_ProductBOM_ID, PriceList_Version_ID);
|
||||||
IF (v_Price = 0) THEN
|
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
||||||
FOR bom IN CUR_BOM LOOP
|
-- DBMS_OUTPUT.PUT_LINE('Qry=' || bom.BOMQty || ' @ ' || v_ProductPrice || ', Price=' || v_Price);
|
||||||
v_ProductPrice := Bompricelist (bom.M_ProductBOM_ID, PriceList_Version_ID);
|
END LOOP; -- BOM
|
||||||
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
END IF;
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Qry=' || bom.BOMQty || ' @ ' || v_ProductPrice || ', Price=' || v_Price);
|
--
|
||||||
END LOOP; -- BOM
|
RETURN v_Price;
|
||||||
END IF;
|
END Bompricelist;
|
||||||
--
|
/
|
||||||
RETURN v_Price;
|
|
||||||
END Bompricelist;
|
|
||||||
/
|
|
||||||
|
|
|
@ -1,54 +1,52 @@
|
||||||
CREATE OR REPLACE FUNCTION Bompricestd
|
CREATE OR REPLACE FUNCTION BOMPRICESTD
|
||||||
(
|
(
|
||||||
Product_ID IN NUMBER,
|
Product_ID IN NUMBER,
|
||||||
PriceList_Version_ID IN NUMBER
|
PriceList_Version_ID IN NUMBER
|
||||||
)
|
)
|
||||||
RETURN NUMBER
|
RETURN NUMBER
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* The contents of this file are subject to the Compiere License. You may
|
* 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
|
* 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
|
* 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
|
* express or implied. See the License for details. Code: Compiere ERP+CRM
|
||||||
* Copyright (C) 1999-2002 Jorg Janke, ComPiere, Inc. All Rights Reserved.
|
* 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 $
|
* $Id: BOM_PriceStd.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $
|
||||||
***
|
***
|
||||||
* Title: Return Standard Price of Product/BOM
|
* Title: Return Standard Price of Product/BOM
|
||||||
* Description:
|
* Description:
|
||||||
* if not found: 0
|
* if not found: 0
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
AS
|
AS
|
||||||
v_Price NUMBER;
|
v_Price NUMBER;
|
||||||
v_ProductPrice NUMBER;
|
v_ProductPrice NUMBER;
|
||||||
-- Get BOM Product info
|
-- Get BOM Product info
|
||||||
CURSOR CUR_BOM IS
|
CURSOR CUR_BOM IS
|
||||||
/*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
||||||
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
AND b.M_Product_ID=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
|
AND p.IsBOM='Y'
|
||||||
FROM PP_PRODUCT_BOM b
|
AND p.IsVerified='Y';
|
||||||
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)
|
BEGIN
|
||||||
WHERE b.M_Product_ID = Product_ID;
|
-- Try to get price from pricelist directly
|
||||||
--
|
SELECT COALESCE(SUM(PriceStd), 0)
|
||||||
BEGIN
|
INTO v_Price
|
||||||
-- Try to get price from pricelist directly
|
FROM M_PRODUCTPRICE
|
||||||
SELECT COALESCE(SUM(PriceStd), 0)
|
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
||||||
INTO v_Price
|
-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price);
|
||||||
FROM M_PRODUCTPRICE
|
|
||||||
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
-- No Price - Check if BOM
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price);
|
IF (v_Price = 0) THEN
|
||||||
|
FOR bom IN CUR_BOM LOOP
|
||||||
-- No Price - Check if BOM
|
v_ProductPrice := Bompricestd (bom.M_ProductBOM_ID, PriceList_Version_ID);
|
||||||
IF (v_Price = 0) THEN
|
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
||||||
FOR bom IN CUR_BOM LOOP
|
-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price);
|
||||||
v_ProductPrice := Bompricestd (bom.M_ProductBOM_ID, PriceList_Version_ID);
|
END LOOP; -- BOM
|
||||||
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
END IF;
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price);
|
--
|
||||||
END LOOP; -- BOM
|
RETURN v_Price;
|
||||||
END IF;
|
END Bompricestd;
|
||||||
--
|
/
|
||||||
RETURN v_Price;
|
|
||||||
END Bompricestd;
|
|
||||||
/
|
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
CREATE OR REPLACE FUNCTION bomQtyAvailable
|
CREATE OR REPLACE FUNCTION BOMQTYAVAILABLE
|
||||||
(
|
(
|
||||||
Product_ID IN NUMBER,
|
Product_ID IN NUMBER,
|
||||||
Warehouse_ID IN NUMBER,
|
Warehouse_ID IN NUMBER,
|
||||||
Locator_ID IN NUMBER -- Only used, if warehouse is null
|
Locator_ID IN NUMBER -- Only used, if warehouse is null
|
||||||
)
|
)
|
||||||
RETURN NUMBER
|
RETURN NUMBER
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
||||||
* Open Source Software Provided "AS IS" without warranty or liability
|
* Open Source Software Provided "AS IS" without warranty or liability
|
||||||
* When you use any parts (changed or unchanged), add "Powered by Compiere" to
|
* 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
|
* your product name; See license details http://www.compiere.org/license.html
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Return quantity available for BOM
|
* Return quantity available for BOM
|
||||||
*/
|
*/
|
||||||
AS
|
AS
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID)
|
RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID)
|
||||||
- bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID);
|
- bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID);
|
||||||
END bomQtyAvailable;
|
END bomQtyAvailable;
|
||||||
/
|
/
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
/
|
|
|
@ -1,125 +1,123 @@
|
||||||
CREATE OR REPLACE FUNCTION Bomqtyonhand
|
CREATE OR REPLACE FUNCTION BOMQTYONHAND
|
||||||
(
|
(
|
||||||
Product_ID IN NUMBER,
|
Product_ID IN NUMBER,
|
||||||
Warehouse_ID IN NUMBER,
|
Warehouse_ID IN NUMBER,
|
||||||
Locator_ID IN NUMBER -- Only used, if warehouse is null
|
Locator_ID IN NUMBER -- Only used, if warehouse is null
|
||||||
)
|
)
|
||||||
RETURN NUMBER
|
RETURN NUMBER
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
||||||
* Open Source Software Provided "AS IS" without warranty or liability
|
* Open Source Software Provided "AS IS" without warranty or liability
|
||||||
* When you use any parts (changed or unchanged), add "Powered by Compiere" to
|
* 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
|
* your product name; See license details http://www.compiere.org/license.html
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Return quantity on hand for BOM
|
* Return quantity on hand for BOM
|
||||||
*/
|
*/
|
||||||
AS
|
AS
|
||||||
myWarehouse_ID NUMBER;
|
myWarehouse_ID NUMBER;
|
||||||
Quantity NUMBER := 99999; -- unlimited
|
Quantity NUMBER := 99999; -- unlimited
|
||||||
IsBOM CHAR(1);
|
IsBOM CHAR(1);
|
||||||
IsStocked CHAR(1);
|
IsStocked CHAR(1);
|
||||||
ProductType CHAR(1);
|
ProductType CHAR(1);
|
||||||
ProductQty NUMBER;
|
ProductQty NUMBER;
|
||||||
StdPrecision NUMBER;
|
StdPrecision NUMBER;
|
||||||
-- Get BOM Product info
|
-- Get BOM Product info
|
||||||
CURSOR CUR_BOM IS
|
CURSOR CUR_BOM IS
|
||||||
/*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
||||||
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
AND b.M_Product_ID=p_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 , p.IsStocked, p.ProductType
|
AND p.IsBOM='Y'
|
||||||
FROM PP_PRODUCT_BOM b
|
AND p.IsVerified='Y';
|
||||||
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)
|
BEGIN
|
||||||
WHERE b.M_Product_ID = Product_ID;
|
-- Check Parameters
|
||||||
--
|
myWarehouse_ID := Warehouse_ID;
|
||||||
BEGIN
|
IF (myWarehouse_ID IS NULL) THEN
|
||||||
-- Check Parameters
|
IF (Locator_ID IS NULL) THEN
|
||||||
myWarehouse_ID := Warehouse_ID;
|
RETURN 0;
|
||||||
IF (myWarehouse_ID IS NULL) THEN
|
ELSE
|
||||||
IF (Locator_ID IS NULL) THEN
|
SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID
|
||||||
RETURN 0;
|
FROM M_LOCATOR
|
||||||
ELSE
|
WHERE M_Locator_ID=Locator_ID;
|
||||||
SELECT SUM(M_Warehouse_ID) INTO myWarehouse_ID
|
END IF;
|
||||||
FROM M_LOCATOR
|
END IF;
|
||||||
WHERE M_Locator_ID=Locator_ID;
|
IF (myWarehouse_ID IS NULL) THEN
|
||||||
END IF;
|
RETURN 0;
|
||||||
END IF;
|
END IF;
|
||||||
IF (myWarehouse_ID IS NULL) THEN
|
-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID);
|
||||||
RETURN 0;
|
|
||||||
END IF;
|
-- Check, if product exists and if it is stocked
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || myWarehouse_ID);
|
BEGIN
|
||||||
|
SELECT IsBOM, ProductType, IsStocked
|
||||||
-- Check, if product exists and if it is stocked
|
INTO IsBOM, ProductType, IsStocked
|
||||||
BEGIN
|
FROM M_PRODUCT
|
||||||
SELECT IsBOM, ProductType, IsStocked
|
WHERE M_Product_ID=Product_ID;
|
||||||
INTO IsBOM, ProductType, IsStocked
|
--
|
||||||
FROM M_PRODUCT
|
EXCEPTION -- not found
|
||||||
WHERE M_Product_ID=Product_ID;
|
WHEN OTHERS THEN
|
||||||
--
|
RETURN 0;
|
||||||
EXCEPTION -- not found
|
END;
|
||||||
WHEN OTHERS THEN
|
-- Unimited capacity if no item
|
||||||
RETURN 0;
|
IF (IsBOM='N' AND (ProductType<>'I' OR IsStocked='N')) THEN
|
||||||
END;
|
RETURN Quantity;
|
||||||
-- Unimited capacity if no item
|
-- Stocked item
|
||||||
IF (IsBOM='N' AND (ProductType<>'I' OR IsStocked='N')) THEN
|
ELSIF (IsStocked='Y') THEN
|
||||||
RETURN Quantity;
|
-- Get ProductQty
|
||||||
-- Stocked item
|
SELECT NVL(SUM(QtyOnHand), 0)
|
||||||
ELSIF (IsStocked='Y') THEN
|
INTO ProductQty
|
||||||
-- Get ProductQty
|
FROM M_STORAGE s
|
||||||
SELECT NVL(SUM(QtyOnHand), 0)
|
WHERE M_Product_ID=Product_ID
|
||||||
INTO ProductQty
|
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
||||||
FROM M_STORAGE s
|
AND l.M_Warehouse_ID=myWarehouse_ID);
|
||||||
WHERE M_Product_ID=Product_ID
|
--
|
||||||
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
-- DBMS_OUTPUT.PUT_LINE('Qty=' || ProductQty);
|
||||||
AND l.M_Warehouse_ID=myWarehouse_ID);
|
RETURN ProductQty;
|
||||||
--
|
END IF;
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Qty=' || ProductQty);
|
|
||||||
RETURN ProductQty;
|
-- Go though BOM
|
||||||
END IF;
|
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
||||||
|
FOR bom IN CUR_BOM LOOP
|
||||||
-- Go though BOM
|
-- Stocked Items "leaf node"
|
||||||
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
||||||
FOR bom IN CUR_BOM LOOP
|
-- Get ProductQty
|
||||||
-- Stocked Items "leaf node"
|
SELECT NVL(SUM(QtyOnHand), 0)
|
||||||
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
INTO ProductQty
|
||||||
-- Get ProductQty
|
FROM M_STORAGE s
|
||||||
SELECT NVL(SUM(QtyOnHand), 0)
|
WHERE M_Product_ID=bom.M_ProductBOM_ID
|
||||||
INTO ProductQty
|
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
||||||
FROM M_STORAGE s
|
AND l.M_Warehouse_ID=myWarehouse_ID);
|
||||||
WHERE M_Product_ID=bom.M_ProductBOM_ID
|
-- Get Rounding Precision
|
||||||
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
SELECT NVL(MAX(u.StdPrecision), 0)
|
||||||
AND l.M_Warehouse_ID=myWarehouse_ID);
|
INTO StdPrecision
|
||||||
-- Get Rounding Precision
|
FROM C_UOM u, M_PRODUCT p
|
||||||
SELECT NVL(MAX(u.StdPrecision), 0)
|
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID;
|
||||||
INTO StdPrecision
|
-- How much can we make with this product
|
||||||
FROM C_UOM u, M_PRODUCT p
|
ProductQty := ROUND (ProductQty/bom.BOMQty, StdPrecision);
|
||||||
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID;
|
-- How much can we make overall
|
||||||
-- How much can we make with this product
|
IF (ProductQty < Quantity) THEN
|
||||||
ProductQty := ROUND (ProductQty/bom.BOMQty, StdPrecision);
|
Quantity := ProductQty;
|
||||||
-- How much can we make overall
|
END IF;
|
||||||
IF (ProductQty < Quantity) THEN
|
-- Another BOM
|
||||||
Quantity := ProductQty;
|
ELSIF (bom.IsBOM = 'Y') THEN
|
||||||
END IF;
|
ProductQty := Bomqtyonhand (bom.M_ProductBOM_ID, myWarehouse_ID, Locator_ID);
|
||||||
-- Another BOM
|
-- How much can we make overall
|
||||||
ELSIF (bom.IsBOM = 'Y') THEN
|
IF (ProductQty < Quantity) THEN
|
||||||
ProductQty := Bomqtyonhand (bom.M_ProductBOM_ID, myWarehouse_ID, Locator_ID);
|
Quantity := ProductQty;
|
||||||
-- How much can we make overall
|
END IF;
|
||||||
IF (ProductQty < Quantity) THEN
|
END IF;
|
||||||
Quantity := ProductQty;
|
END LOOP; -- BOM
|
||||||
END IF;
|
|
||||||
END IF;
|
IF (Quantity > 0) THEN
|
||||||
END LOOP; -- BOM
|
-- Get Rounding Precision for Product
|
||||||
|
SELECT NVL(MAX(u.StdPrecision), 0)
|
||||||
IF (Quantity > 0) THEN
|
INTO StdPrecision
|
||||||
-- Get Rounding Precision for Product
|
FROM C_UOM u, M_PRODUCT p
|
||||||
SELECT NVL(MAX(u.StdPrecision), 0)
|
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID;
|
||||||
INTO StdPrecision
|
--
|
||||||
FROM C_UOM u, M_PRODUCT p
|
RETURN ROUND (Quantity, StdPrecision);
|
||||||
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=Product_ID;
|
END IF;
|
||||||
--
|
RETURN 0;
|
||||||
RETURN ROUND (Quantity, StdPrecision);
|
END Bomqtyonhand;
|
||||||
END IF;
|
/
|
||||||
RETURN 0;
|
|
||||||
END Bomqtyonhand;
|
|
||||||
/
|
|
||||||
|
|
|
@ -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;
|
|
||||||
/
|
|
|
@ -1,131 +1,129 @@
|
||||||
CREATE OR REPLACE FUNCTION Bomqtyordered
|
CREATE OR REPLACE FUNCTION BOMQTYORDERED
|
||||||
(
|
(
|
||||||
p_Product_ID IN NUMBER,
|
p_Product_ID IN NUMBER,
|
||||||
p_Warehouse_ID IN NUMBER,
|
p_Warehouse_ID IN NUMBER,
|
||||||
p_Locator_ID IN NUMBER -- Only used, if warehouse is null
|
p_Locator_ID IN NUMBER -- Only used, if warehouse is null
|
||||||
)
|
)
|
||||||
RETURN NUMBER
|
RETURN NUMBER
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
||||||
* Open Source Software Provided "AS IS" without warranty or liability
|
* Open Source Software Provided "AS IS" without warranty or liability
|
||||||
* When you use any parts (changed or unchanged), add "Powered by Compiere" to
|
* 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
|
* your product name; See license details http://www.compiere.org/license.html
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Return quantity ordered for BOM
|
* Return quantity ordered for BOM
|
||||||
*/
|
*/
|
||||||
AS
|
AS
|
||||||
v_Warehouse_ID NUMBER;
|
v_Warehouse_ID NUMBER;
|
||||||
v_Quantity NUMBER := 99999; -- unlimited
|
v_Quantity NUMBER := 99999; -- unlimited
|
||||||
v_IsBOM CHAR(1);
|
v_IsBOM CHAR(1);
|
||||||
v_IsStocked CHAR(1);
|
v_IsStocked CHAR(1);
|
||||||
v_ProductType CHAR(1);
|
v_ProductType CHAR(1);
|
||||||
v_ProductQty NUMBER;
|
v_ProductQty NUMBER;
|
||||||
v_StdPrecision NUMBER;
|
v_StdPrecision NUMBER;
|
||||||
-- Get BOM Product info
|
-- Get BOM Product info
|
||||||
CURSOR CUR_BOM IS
|
CURSOR CUR_BOM IS
|
||||||
/*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
||||||
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
AND b.M_Product_ID=p_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
|
AND p.IsBOM='Y'
|
||||||
FROM PP_PRODUCT_BOM b
|
AND p.IsVerified='Y';
|
||||||
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)
|
BEGIN
|
||||||
WHERE b.M_Product_ID = p_Product_ID;
|
-- Check Parameters
|
||||||
--
|
v_Warehouse_ID := p_Warehouse_ID;
|
||||||
BEGIN
|
IF (v_Warehouse_ID IS NULL) THEN
|
||||||
-- Check Parameters
|
IF (p_Locator_ID IS NULL) THEN
|
||||||
v_Warehouse_ID := p_Warehouse_ID;
|
RETURN 0;
|
||||||
IF (v_Warehouse_ID IS NULL) THEN
|
ELSE
|
||||||
IF (p_Locator_ID IS NULL) THEN
|
SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID
|
||||||
RETURN 0;
|
FROM M_LOCATOR
|
||||||
ELSE
|
WHERE M_Locator_ID=p_Locator_ID;
|
||||||
SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID
|
END IF;
|
||||||
FROM M_LOCATOR
|
END IF;
|
||||||
WHERE M_Locator_ID=p_Locator_ID;
|
IF (v_Warehouse_ID IS NULL) THEN
|
||||||
END IF;
|
RETURN 0;
|
||||||
END IF;
|
END IF;
|
||||||
IF (v_Warehouse_ID IS NULL) THEN
|
-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID);
|
||||||
RETURN 0;
|
|
||||||
END IF;
|
-- Check, if product exists and if it is stocked
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID);
|
BEGIN
|
||||||
|
SELECT IsBOM, ProductType, IsStocked
|
||||||
-- Check, if product exists and if it is stocked
|
INTO v_IsBOM, v_ProductType, v_IsStocked
|
||||||
BEGIN
|
FROM M_PRODUCT
|
||||||
SELECT IsBOM, ProductType, IsStocked
|
WHERE M_Product_ID=p_Product_ID;
|
||||||
INTO v_IsBOM, v_ProductType, v_IsStocked
|
--
|
||||||
FROM M_PRODUCT
|
EXCEPTION -- not found
|
||||||
WHERE M_Product_ID=p_Product_ID;
|
WHEN OTHERS THEN
|
||||||
--
|
RETURN 0;
|
||||||
EXCEPTION -- not found
|
END;
|
||||||
WHEN OTHERS THEN
|
|
||||||
RETURN 0;
|
-- No reservation for non-stocked
|
||||||
END;
|
IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN
|
||||||
|
RETURN 0;
|
||||||
-- No reservation for non-stocked
|
-- Stocked item
|
||||||
IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN
|
ELSIF (v_IsStocked='Y') THEN
|
||||||
RETURN 0;
|
-- Get ProductQty
|
||||||
-- Stocked item
|
SELECT NVL(SUM(QtyOrdered), 0)
|
||||||
ELSIF (v_IsStocked='Y') THEN
|
INTO v_ProductQty
|
||||||
-- Get ProductQty
|
FROM M_STORAGE s
|
||||||
SELECT NVL(SUM(QtyOrdered), 0)
|
WHERE M_Product_ID=p_Product_ID
|
||||||
INTO v_ProductQty
|
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
||||||
FROM M_STORAGE s
|
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
||||||
WHERE M_Product_ID=p_Product_ID
|
--
|
||||||
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
RETURN v_ProductQty;
|
||||||
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
END IF;
|
||||||
--
|
|
||||||
RETURN v_ProductQty;
|
-- Go though BOM
|
||||||
END IF;
|
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
||||||
|
FOR bom IN CUR_BOM LOOP
|
||||||
-- Go though BOM
|
-- Stocked Items "leaf node"
|
||||||
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
||||||
FOR bom IN CUR_BOM LOOP
|
-- Get ProductQty
|
||||||
-- Stocked Items "leaf node"
|
SELECT NVL(SUM(QtyOrdered), 0)
|
||||||
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
INTO v_ProductQty
|
||||||
-- Get ProductQty
|
FROM M_STORAGE s
|
||||||
SELECT NVL(SUM(QtyOrdered), 0)
|
WHERE M_Product_ID=bom.M_ProductBOM_ID
|
||||||
INTO v_ProductQty
|
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
||||||
FROM M_STORAGE s
|
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
||||||
WHERE M_Product_ID=bom.M_ProductBOM_ID
|
-- Get Rounding Precision
|
||||||
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
SELECT NVL(MAX(u.StdPrecision), 0)
|
||||||
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
INTO v_StdPrecision
|
||||||
-- Get Rounding Precision
|
FROM C_UOM u, M_PRODUCT p
|
||||||
SELECT NVL(MAX(u.StdPrecision), 0)
|
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID;
|
||||||
INTO v_StdPrecision
|
-- How much can we make with this product
|
||||||
FROM C_UOM u, M_PRODUCT p
|
v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision);
|
||||||
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID;
|
-- How much can we make overall
|
||||||
-- How much can we make with this product
|
IF (v_ProductQty < v_Quantity) THEN
|
||||||
v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision);
|
v_Quantity := v_ProductQty;
|
||||||
-- How much can we make overall
|
END IF;
|
||||||
IF (v_ProductQty < v_Quantity) THEN
|
-- Another BOM
|
||||||
v_Quantity := v_ProductQty;
|
ELSIF (bom.IsBOM = 'Y') THEN
|
||||||
END IF;
|
v_ProductQty := Bomqtyordered (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID);
|
||||||
-- Another BOM
|
-- How much can we make overall
|
||||||
ELSIF (bom.IsBOM = 'Y') THEN
|
IF (v_ProductQty < v_Quantity) THEN
|
||||||
v_ProductQty := Bomqtyordered (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID);
|
v_Quantity := v_ProductQty;
|
||||||
-- How much can we make overall
|
END IF;
|
||||||
IF (v_ProductQty < v_Quantity) THEN
|
END IF;
|
||||||
v_Quantity := v_ProductQty;
|
END LOOP; -- BOM
|
||||||
END IF;
|
|
||||||
END IF;
|
-- Unlimited (e.g. only services)
|
||||||
END LOOP; -- BOM
|
IF (v_Quantity = 99999) THEN
|
||||||
|
RETURN 0;
|
||||||
-- Unlimited (e.g. only services)
|
END IF;
|
||||||
IF (v_Quantity = 99999) THEN
|
|
||||||
RETURN 0;
|
IF (v_Quantity > 0) THEN
|
||||||
END IF;
|
-- Get Rounding Precision for Product
|
||||||
|
SELECT NVL(MAX(u.StdPrecision), 0)
|
||||||
IF (v_Quantity > 0) THEN
|
INTO v_StdPrecision
|
||||||
-- Get Rounding Precision for Product
|
FROM C_UOM u, M_PRODUCT p
|
||||||
SELECT NVL(MAX(u.StdPrecision), 0)
|
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID;
|
||||||
INTO v_StdPrecision
|
--
|
||||||
FROM C_UOM u, M_PRODUCT p
|
RETURN ROUND (v_Quantity, v_StdPrecision);
|
||||||
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID;
|
END IF;
|
||||||
--
|
--
|
||||||
RETURN ROUND (v_Quantity, v_StdPrecision);
|
RETURN 0;
|
||||||
END IF;
|
END Bomqtyordered;
|
||||||
--
|
/
|
||||||
RETURN 0;
|
|
||||||
END Bomqtyordered;
|
|
||||||
/
|
|
||||||
|
|
|
@ -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;
|
|
||||||
/
|
|
|
@ -1,130 +1,128 @@
|
||||||
CREATE OR REPLACE FUNCTION Bomqtyreserved
|
CREATE OR REPLACE FUNCTION BOMQTYRESERVED
|
||||||
(
|
(
|
||||||
p_Product_ID IN NUMBER,
|
p_Product_ID IN NUMBER,
|
||||||
p_Warehouse_ID IN NUMBER,
|
p_Warehouse_ID IN NUMBER,
|
||||||
p_Locator_ID IN NUMBER -- Only used, if warehouse is null
|
p_Locator_ID IN NUMBER -- Only used, if warehouse is null
|
||||||
)
|
)
|
||||||
RETURN NUMBER
|
RETURN NUMBER
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
* ** Compiere Product ** Copyright (c) 1999-2001 Accorto, Inc. USA
|
||||||
* Open Source Software Provided "AS IS" without warranty or liability
|
* Open Source Software Provided "AS IS" without warranty or liability
|
||||||
* When you use any parts (changed or unchanged), add "Powered by Compiere" to
|
* 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
|
* your product name; See license details http://www.compiere.org/license.html
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Return quantity reserved for BOM
|
* Return quantity reserved for BOM
|
||||||
*/
|
*/
|
||||||
AS
|
AS
|
||||||
v_Warehouse_ID NUMBER;
|
v_Warehouse_ID NUMBER;
|
||||||
v_Quantity NUMBER := 99999; -- unlimited
|
v_Quantity NUMBER := 99999; -- unlimited
|
||||||
v_IsBOM CHAR(1);
|
v_IsBOM CHAR(1);
|
||||||
v_IsStocked CHAR(1);
|
v_IsStocked CHAR(1);
|
||||||
v_ProductType CHAR(1);
|
v_ProductType CHAR(1);
|
||||||
v_ProductQty NUMBER;
|
v_ProductQty NUMBER;
|
||||||
v_StdPrecision NUMBER;
|
v_StdPrecision NUMBER;
|
||||||
-- Get BOM Product info
|
-- Get BOM Product info
|
||||||
CURSOR CUR_BOM IS
|
CURSOR CUR_BOM IS
|
||||||
/*SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
||||||
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
AND b.M_Product_ID=p_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
|
AND p.IsBOM='Y'
|
||||||
FROM PP_PRODUCT_BOM b
|
AND p.IsVerified='Y';
|
||||||
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)
|
BEGIN
|
||||||
WHERE b.M_Product_ID = p_Product_ID;
|
-- Check Parameters
|
||||||
--
|
v_Warehouse_ID := p_Warehouse_ID;
|
||||||
BEGIN
|
IF (v_Warehouse_ID IS NULL) THEN
|
||||||
-- Check Parameters
|
IF (p_Locator_ID IS NULL) THEN
|
||||||
v_Warehouse_ID := p_Warehouse_ID;
|
RETURN 0;
|
||||||
IF (v_Warehouse_ID IS NULL) THEN
|
ELSE
|
||||||
IF (p_Locator_ID IS NULL) THEN
|
SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID
|
||||||
RETURN 0;
|
FROM M_LOCATOR
|
||||||
ELSE
|
WHERE M_Locator_ID=p_Locator_ID;
|
||||||
SELECT MAX(M_Warehouse_ID) INTO v_Warehouse_ID
|
END IF;
|
||||||
FROM M_LOCATOR
|
END IF;
|
||||||
WHERE M_Locator_ID=p_Locator_ID;
|
IF (v_Warehouse_ID IS NULL) THEN
|
||||||
END IF;
|
RETURN 0;
|
||||||
END IF;
|
END IF;
|
||||||
IF (v_Warehouse_ID IS NULL) THEN
|
-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID);
|
||||||
RETURN 0;
|
|
||||||
END IF;
|
-- Check, if product exists and if it is stocked
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Warehouse=' || v_Warehouse_ID);
|
BEGIN
|
||||||
|
SELECT IsBOM, ProductType, IsStocked
|
||||||
-- Check, if product exists and if it is stocked
|
INTO v_IsBOM, v_ProductType, v_IsStocked
|
||||||
BEGIN
|
FROM M_PRODUCT
|
||||||
SELECT IsBOM, ProductType, IsStocked
|
WHERE M_Product_ID=p_Product_ID;
|
||||||
INTO v_IsBOM, v_ProductType, v_IsStocked
|
--
|
||||||
FROM M_PRODUCT
|
EXCEPTION -- not found
|
||||||
WHERE M_Product_ID=p_Product_ID;
|
WHEN OTHERS THEN
|
||||||
--
|
RETURN 0;
|
||||||
EXCEPTION -- not found
|
END;
|
||||||
WHEN OTHERS THEN
|
|
||||||
RETURN 0;
|
-- No reservation for non-stocked
|
||||||
END;
|
IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN
|
||||||
|
RETURN 0;
|
||||||
-- No reservation for non-stocked
|
-- Stocked item
|
||||||
IF (v_IsBOM='N' AND (v_ProductType<>'I' OR v_IsStocked='N')) THEN
|
ELSIF (v_IsStocked='Y') THEN
|
||||||
RETURN 0;
|
-- Get ProductQty
|
||||||
-- Stocked item
|
SELECT NVL(SUM(QtyReserved), 0)
|
||||||
ELSIF (v_IsStocked='Y') THEN
|
INTO v_ProductQty
|
||||||
-- Get ProductQty
|
FROM M_STORAGE s
|
||||||
SELECT NVL(SUM(QtyReserved), 0)
|
WHERE M_Product_ID=p_Product_ID
|
||||||
INTO v_ProductQty
|
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
||||||
FROM M_STORAGE s
|
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
||||||
WHERE M_Product_ID=p_Product_ID
|
--
|
||||||
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
RETURN v_ProductQty;
|
||||||
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
END IF;
|
||||||
--
|
|
||||||
RETURN v_ProductQty;
|
-- Go though BOM
|
||||||
END IF;
|
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
||||||
|
FOR bom IN CUR_BOM LOOP
|
||||||
-- Go though BOM
|
-- Stocked Items "leaf node"
|
||||||
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
||||||
FOR bom IN CUR_BOM LOOP
|
-- Get ProductQty
|
||||||
-- Stocked Items "leaf node"
|
SELECT NVL(SUM(QtyReserved), 0)
|
||||||
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
INTO v_ProductQty
|
||||||
-- Get ProductQty
|
FROM M_STORAGE s
|
||||||
SELECT NVL(SUM(QtyReserved), 0)
|
WHERE M_Product_ID=bom.M_ProductBOM_ID
|
||||||
INTO v_ProductQty
|
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
||||||
FROM M_STORAGE s
|
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
||||||
WHERE M_Product_ID=bom.M_ProductBOM_ID
|
-- Get Rounding Precision
|
||||||
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_ID
|
SELECT NVL(MAX(u.StdPrecision), 0)
|
||||||
AND l.M_Warehouse_ID=v_Warehouse_ID);
|
INTO v_StdPrecision
|
||||||
-- Get Rounding Precision
|
FROM C_UOM u, M_PRODUCT p
|
||||||
SELECT NVL(MAX(u.StdPrecision), 0)
|
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID;
|
||||||
INTO v_StdPrecision
|
-- How much can we make with this product
|
||||||
FROM C_UOM u, M_PRODUCT p
|
v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision);
|
||||||
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=bom.M_ProductBOM_ID;
|
-- How much can we make overall
|
||||||
-- How much can we make with this product
|
IF (v_ProductQty < v_Quantity) THEN
|
||||||
v_ProductQty := ROUND (v_ProductQty/bom.BOMQty, v_StdPrecision);
|
v_Quantity := v_ProductQty;
|
||||||
-- How much can we make overall
|
END IF;
|
||||||
IF (v_ProductQty < v_Quantity) THEN
|
-- Another BOM
|
||||||
v_Quantity := v_ProductQty;
|
ELSIF (bom.IsBOM = 'Y') THEN
|
||||||
END IF;
|
v_ProductQty := Bomqtyreserved (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID);
|
||||||
-- Another BOM
|
-- How much can we make overall
|
||||||
ELSIF (bom.IsBOM = 'Y') THEN
|
IF (v_ProductQty < v_Quantity) THEN
|
||||||
v_ProductQty := Bomqtyreserved (bom.M_ProductBOM_ID, v_Warehouse_ID, p_Locator_ID);
|
v_Quantity := v_ProductQty;
|
||||||
-- How much can we make overall
|
END IF;
|
||||||
IF (v_ProductQty < v_Quantity) THEN
|
END IF;
|
||||||
v_Quantity := v_ProductQty;
|
END LOOP; -- BOM
|
||||||
END IF;
|
|
||||||
END IF;
|
-- Unlimited (e.g. only services)
|
||||||
END LOOP; -- BOM
|
IF (v_Quantity = 99999) THEN
|
||||||
|
RETURN 0;
|
||||||
-- Unlimited (e.g. only services)
|
END IF;
|
||||||
IF (v_Quantity = 99999) THEN
|
|
||||||
RETURN 0;
|
IF (v_Quantity > 0) THEN
|
||||||
END IF;
|
-- Get Rounding Precision for Product
|
||||||
|
SELECT NVL(MAX(u.StdPrecision), 0)
|
||||||
IF (v_Quantity > 0) THEN
|
INTO v_StdPrecision
|
||||||
-- Get Rounding Precision for Product
|
FROM C_UOM u, M_PRODUCT p
|
||||||
SELECT NVL(MAX(u.StdPrecision), 0)
|
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID;
|
||||||
INTO v_StdPrecision
|
--
|
||||||
FROM C_UOM u, M_PRODUCT p
|
RETURN ROUND (v_Quantity, v_StdPrecision);
|
||||||
WHERE u.C_UOM_ID=p.C_UOM_ID AND p.M_Product_ID=p_Product_ID;
|
END IF;
|
||||||
--
|
RETURN 0;
|
||||||
RETURN ROUND (v_Quantity, v_StdPrecision);
|
END Bomqtyreserved;
|
||||||
END IF;
|
/
|
||||||
RETURN 0;
|
|
||||||
END Bomqtyreserved;
|
|
||||||
/
|
|
||||||
|
|
|
@ -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;
|
|
||||||
/
|
|
|
@ -1,50 +1,37 @@
|
||||||
/*
|
CREATE OR REPLACE FUNCTION bompricelimit (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS
|
||||||
*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
|
|
||||||
$BODY$
|
$BODY$
|
||||||
DECLARE
|
DECLARE
|
||||||
v_Price numeric;
|
v_Price NUMERIC;
|
||||||
v_ProductPrice numeric;
|
v_ProductPrice NUMERIC;
|
||||||
bom record;
|
bom RECORD;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Try to get price from PriceList directly
|
-- Try to get price from PriceList directly
|
||||||
SELECT COALESCE (SUM(PriceLimit), 0)
|
SELECT COALESCE (SUM(PriceLimit), 0)
|
||||||
INTO v_Price
|
INTO v_Price
|
||||||
FROM M_PRODUCTPRICE
|
FROM M_ProductPrice
|
||||||
WHERE M_PriceList_Version_ID=p_PriceList_Version_ID AND M_Product_ID=p_Product_ID;
|
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
||||||
|
|
||||||
|
-- No Price - Check if BOM
|
||||||
IF (v_Price = 0) THEN
|
IF (v_Price = 0) THEN
|
||||||
FOR bom in SELECT bl.M_Product_ID AS M_ProductBOM_ID,
|
FOR bom IN
|
||||||
CASE WHEN bl.IsQtyPercentage = 'N' THEN bl.QtyBOM ELSE bl.QtyBatch / 100 END AS BomQty , p.IsBOM
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
||||||
FROM PP_PRODUCT_BOM b
|
FROM M_Product_BOM b, M_Product p
|
||||||
INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID)
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID)
|
AND b.M_Product_ID=Product_ID
|
||||||
WHERE b.M_Product_ID = p_Product_ID
|
AND p.IsBOM='Y'
|
||||||
|
AND p.IsVerified='Y'
|
||||||
LOOP
|
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);
|
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
--
|
--
|
||||||
RETURN v_Price;
|
RETURN v_Price;
|
||||||
|
|
||||||
END;
|
END;
|
||||||
|
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE 'plpgsql' ;
|
LANGUAGE 'plpgsql'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -1,60 +1,37 @@
|
||||||
/*
|
CREATE OR REPLACE FUNCTION bompricelist (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS
|
||||||
*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
|
|
||||||
$BODY$
|
$BODY$
|
||||||
DECLARE
|
DECLARE
|
||||||
v_Price numeric;
|
v_Price NUMERIC;
|
||||||
v_ProductPrice numeric;
|
v_ProductPrice NUMERIC;
|
||||||
bom record;
|
bom RECORD;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Try to get price from pricelist directly
|
-- Try to get price from pricelist directly
|
||||||
SELECT COALESCE (SUM(PriceList), 0)
|
SELECT COALESCE (SUM(PriceList), 0)
|
||||||
INTO v_Price
|
INTO v_Price
|
||||||
FROM M_PRODUCTPRICE
|
FROM M_ProductPrice
|
||||||
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
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
|
-- No Price - Check if BOM
|
||||||
IF (v_Price = 0) THEN
|
IF (v_Price = 0) THEN
|
||||||
FOR bom IN
|
FOR bom IN
|
||||||
--Get BOM Product info
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
||||||
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 M_Product_BOM b, M_Product p
|
||||||
FROM PP_PRODUCT_BOM b
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID)
|
AND b.M_Product_ID=Product_ID
|
||||||
INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID)
|
AND p.IsBOM='Y'
|
||||||
WHERE b.M_Product_ID = Product_ID
|
AND p.IsVerified='Y'
|
||||||
LOOP
|
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);
|
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Qry=' || bom.BOMQty || ' @ ' || v_ProductPrice || ', Price=' || v_Price);
|
END LOOP;
|
||||||
END LOOP; -- BOM
|
|
||||||
END IF;
|
END IF;
|
||||||
--
|
--
|
||||||
RETURN v_Price;
|
RETURN v_Price;
|
||||||
|
|
||||||
END;
|
END;
|
||||||
|
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE 'plpgsql' ;
|
LANGUAGE 'plpgsql'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -1,59 +1,37 @@
|
||||||
/*
|
CREATE OR REPLACE FUNCTION bompricestd (in product_id numeric, in pricelist_version_id numeric) RETURNS numeric AS
|
||||||
*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
|
|
||||||
$BODY$
|
$BODY$
|
||||||
DECLARE
|
DECLARE
|
||||||
v_Price numeric;
|
v_Price NUMERIC;
|
||||||
v_ProductPrice numeric;
|
v_ProductPrice NUMERIC;
|
||||||
bom record;
|
bom RECORD;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Try to get price from pricelist directly
|
-- Try to get price from PriceList directly
|
||||||
SELECT COALESCE(SUM(PriceStd), 0)
|
SELECT COALESCE(SUM(PriceStd), 0)
|
||||||
INTO v_Price
|
INTO v_Price
|
||||||
FROM M_PRODUCTPRICE
|
FROM M_ProductPrice
|
||||||
WHERE M_PriceList_Version_ID=PriceList_Version_ID AND M_Product_ID=Product_ID;
|
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
|
-- No Price - Check if BOM
|
||||||
IF (v_Price = 0) THEN
|
IF (v_Price = 0) THEN
|
||||||
FOR bom IN -- Get BOM Product info
|
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
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM
|
||||||
FROM PP_PRODUCT_BOM b
|
FROM M_Product_BOM b, M_Product p
|
||||||
INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID)
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID)
|
AND b.M_Product_ID=Product_ID
|
||||||
WHERE b.M_Product_ID = Product_ID
|
AND p.IsBOM='Y'
|
||||||
|
AND p.IsVerified='Y'
|
||||||
LOOP
|
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);
|
v_Price := v_Price + (bom.BOMQty * v_ProductPrice);
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Price=' || v_Price);
|
END LOOP;
|
||||||
END LOOP; -- BOM
|
|
||||||
END IF;
|
END IF;
|
||||||
--
|
--
|
||||||
RETURN v_Price;
|
RETURN v_Price;
|
||||||
|
|
||||||
END;
|
END;
|
||||||
|
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE 'plpgsql' ;
|
LANGUAGE 'plpgsql'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,9 @@
|
||||||
/*
|
CREATE OR REPLACE FUNCTION bomqtyavailable (in product_id numeric, in warehouse_id numeric, in locator_id numeric) RETURNS numeric AS
|
||||||
*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
|
|
||||||
$BODY$
|
$BODY$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID) - bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID);
|
RETURN bomQtyOnHand(Product_ID, Warehouse_ID, Locator_ID) - bomQtyReserved(Product_ID, Warehouse_ID, Locator_ID);
|
||||||
END;
|
END;
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE 'plpgsql' ;
|
LANGUAGE 'plpgsql'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -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' ;
|
|
|
@ -1,29 +1,4 @@
|
||||||
/*
|
CREATE OR REPLACE FUNCTION bomqtyonhand (in product_id numeric, in warehouse_id numeric, in locator_id numeric) RETURNS numeric AS
|
||||||
*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
|
|
||||||
$BODY$
|
$BODY$
|
||||||
DECLARE
|
DECLARE
|
||||||
myWarehouse_ID numeric;
|
myWarehouse_ID numeric;
|
||||||
|
@ -50,7 +25,7 @@ BEGIN
|
||||||
IF (myWarehouse_ID IS NULL) THEN
|
IF (myWarehouse_ID IS NULL) THEN
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
END IF;
|
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
|
-- Check, if product exists and if it is stocked
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -76,18 +51,19 @@ BEGIN
|
||||||
AND EXISTS (SELECT * FROM M_LOCATOR l WHERE s.M_Locator_ID=l.M_Locator_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 l.M_Warehouse_ID=myWarehouse_ID);
|
||||||
--
|
--
|
||||||
-- DBMS_OUTPUT.PUT_LINE('Qty=' || v_ProductQty);
|
-- DBMS_OUTPUT.PUT_LINE(''Qty='' || v_ProductQty);
|
||||||
RETURN v_ProductQty;
|
RETURN v_ProductQty;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Go though BOM
|
-- Go though BOM
|
||||||
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
-- DBMS_OUTPUT.PUT_LINE(''BOM'');
|
||||||
FOR bom IN -- Get BOM Product info
|
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
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
||||||
FROM PP_PRODUCT_BOM b
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID)
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID)
|
AND b.M_Product_ID=product_ID
|
||||||
WHERE b.M_Product_ID = Product_ID
|
AND p.IsBOM='Y'
|
||||||
|
AND p.IsVerified='Y'
|
||||||
LOOP
|
LOOP
|
||||||
-- Stocked Items "leaf node"
|
-- Stocked Items "leaf node"
|
||||||
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
||||||
|
@ -131,4 +107,6 @@ BEGIN
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
END;
|
END;
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE 'plpgsql' ;
|
LANGUAGE 'plpgsql'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -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' ;
|
|
|
@ -1,30 +1,4 @@
|
||||||
/*
|
CREATE OR REPLACE FUNCTION bomqtyordered (in p_product_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) RETURNS numeric AS
|
||||||
*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
|
|
||||||
$BODY$
|
$BODY$
|
||||||
DECLARE
|
DECLARE
|
||||||
v_Warehouse_ID numeric;
|
v_Warehouse_ID numeric;
|
||||||
|
@ -50,7 +24,7 @@ BEGIN
|
||||||
IF (v_Warehouse_ID IS NULL) THEN
|
IF (v_Warehouse_ID IS NULL) THEN
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
END IF;
|
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
|
-- Check, if product exists and if it is stocked
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -81,14 +55,15 @@ BEGIN
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Go though BOM
|
-- Go though BOM
|
||||||
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
-- DBMS_OUTPUT.PUT_LINE(''BOM'');
|
||||||
FOR bom IN
|
FOR bom IN
|
||||||
-- Get BOM Product info
|
-- 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
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
||||||
FROM PP_PRODUCT_BOM b
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID)
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID)
|
AND b.M_Product_ID=p_Product_ID
|
||||||
WHERE b.M_Product_ID = p_Product_ID
|
AND p.IsBOM='Y'
|
||||||
|
AND p.IsVerified='Y'
|
||||||
LOOP
|
LOOP
|
||||||
-- Stocked Items "leaf node"
|
-- Stocked Items "leaf node"
|
||||||
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
||||||
|
@ -139,4 +114,6 @@ BEGIN
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
END;
|
END;
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE 'plpgsql' ;
|
LANGUAGE 'plpgsql'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -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' ;
|
|
|
@ -1,30 +1,4 @@
|
||||||
/*
|
CREATE OR REPLACE FUNCTION bomqtyreserved (in p_product_id numeric, in p_warehouse_id numeric, in p_locator_id numeric) RETURNS numeric AS
|
||||||
*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
|
|
||||||
$BODY$
|
$BODY$
|
||||||
DECLARE
|
DECLARE
|
||||||
v_Warehouse_ID numeric;
|
v_Warehouse_ID numeric;
|
||||||
|
@ -50,7 +24,7 @@ BEGIN
|
||||||
IF (v_Warehouse_ID IS NULL) THEN
|
IF (v_Warehouse_ID IS NULL) THEN
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
END IF;
|
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
|
-- Check, if product exists and if it is stocked
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -81,14 +55,15 @@ BEGIN
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Go though BOM
|
-- Go though BOM
|
||||||
-- DBMS_OUTPUT.PUT_LINE('BOM');
|
-- DBMS_OUTPUT.PUT_LINE(''BOM'');
|
||||||
FOR bom IN
|
FOR bom IN
|
||||||
-- Get BOM Product info
|
-- 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
|
SELECT b.M_ProductBOM_ID, b.BOMQty, p.IsBOM, p.IsStocked, p.ProductType
|
||||||
FROM PP_PRODUCT_BOM b
|
FROM M_PRODUCT_BOM b, M_PRODUCT p
|
||||||
INNER JOIN M_PRODUCT p ON (p.M_Product_ID=b.M_Product_ID)
|
WHERE b.M_ProductBOM_ID=p.M_Product_ID
|
||||||
INNER JOIN PP_PRODUCT_BOMLINE bl ON (bl.PP_Product_BOM_ID=b.PP_Product_BOM_ID)
|
AND b.M_Product_ID=p_Product_ID
|
||||||
WHERE b.M_Product_ID = p_Product_ID
|
AND p.IsBOM='Y'
|
||||||
|
AND p.IsVerified='Y'
|
||||||
LOOP
|
LOOP
|
||||||
-- Stocked Items "leaf node"
|
-- Stocked Items "leaf node"
|
||||||
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
IF (bom.ProductType = 'I' AND bom.IsStocked = 'Y') THEN
|
||||||
|
@ -137,4 +112,6 @@ BEGIN
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
END;
|
END;
|
||||||
$BODY$
|
$BODY$
|
||||||
LANGUAGE 'plpgsql' ;
|
LANGUAGE 'plpgsql'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -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' ;
|
|
|
@ -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
|
||||||
|
;
|
||||||
|
|
|
@ -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
|
||||||
|
;
|
||||||
|
|
|
@ -38,6 +38,8 @@ public class BOMVerify extends SvrProcess
|
||||||
private int p_M_Product_Category_ID = 0;
|
private int p_M_Product_Category_ID = 0;
|
||||||
/** Re-Validate */
|
/** Re-Validate */
|
||||||
private boolean p_IsReValidate = false;
|
private boolean p_IsReValidate = false;
|
||||||
|
|
||||||
|
private boolean p_fromButton = false;
|
||||||
|
|
||||||
/** List of Products */
|
/** List of Products */
|
||||||
private ArrayList<MProduct> foundproducts = new ArrayList<MProduct>();
|
private ArrayList<MProduct> foundproducts = new ArrayList<MProduct>();
|
||||||
|
@ -68,6 +70,7 @@ public class BOMVerify extends SvrProcess
|
||||||
}
|
}
|
||||||
if ( p_M_Product_ID == 0 )
|
if ( p_M_Product_ID == 0 )
|
||||||
p_M_Product_ID = getRecord_ID();
|
p_M_Product_ID = getRecord_ID();
|
||||||
|
p_fromButton = (getRecord_ID() > 0);
|
||||||
} // prepare
|
} // prepare
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,9 +158,12 @@ public class BOMVerify extends SvrProcess
|
||||||
MProductBOM[] productsBOMs = MProductBOM.getBOMLines(product);
|
MProductBOM[] productsBOMs = MProductBOM.getBOMLines(product);
|
||||||
boolean containsinvalid = false;
|
boolean containsinvalid = false;
|
||||||
boolean invalid = 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());
|
MProduct pp = new MProduct(getCtx(), productsBOM.getM_ProductBOM_ID(), get_TrxName());
|
||||||
if (!pp.isBOM()) {
|
if (!pp.isBOM()) {
|
||||||
if (log.isLoggable(Level.FINER)) log.finer(pp.getName());
|
if (log.isLoggable(Level.FINER)) log.finer(pp.getName());
|
||||||
|
@ -173,7 +179,10 @@ public class BOMVerify extends SvrProcess
|
||||||
else if (foundproducts.contains(pp))
|
else if (foundproducts.contains(pp))
|
||||||
{
|
{
|
||||||
invalid = true;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -181,14 +190,19 @@ public class BOMVerify extends SvrProcess
|
||||||
{
|
{
|
||||||
containsinvalid = true;
|
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);
|
checkedproducts.add(product);
|
||||||
foundproducts.remove(product);
|
foundproducts.remove(product);
|
||||||
if (invalid)
|
if (invalid)
|
||||||
|
|
|
@ -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
|
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
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
|
* Get BOM Lines for Product
|
||||||
|
@ -96,7 +96,7 @@ public class MProductBOM extends X_M_Product_BOM
|
||||||
} // MProductBOM
|
} // MProductBOM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Construvtor
|
* Load Constructor
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
* @param rs result set
|
* @param rs result set
|
||||||
* @param trxName transaction
|
* @param trxName transaction
|
||||||
|
@ -159,22 +159,51 @@ public class MProductBOM extends X_M_Product_BOM
|
||||||
{
|
{
|
||||||
if (!success)
|
if (!success)
|
||||||
return success;
|
return success;
|
||||||
// Product Line was changed
|
MProduct product = new MProduct (getCtx(), getM_Product_ID(), get_TrxName());
|
||||||
if (newRecord || is_ValueChanged("M_ProductBOM_ID"))
|
if (get_TrxName() != null)
|
||||||
|
product.load(get_TrxName());
|
||||||
|
if (product.isVerified())
|
||||||
{
|
{
|
||||||
// Invalidate BOM
|
if ( newRecord
|
||||||
MProduct product = new MProduct (getCtx(), getM_Product_ID(), get_TrxName());
|
|| is_ValueChanged("M_ProductBOM_ID") // Product Line was changed
|
||||||
if (get_TrxName() != null)
|
|| (is_ValueChanged("IsActive") && isActive())) // line was activated
|
||||||
product.load(get_TrxName());
|
|
||||||
if (product.isVerified())
|
|
||||||
{
|
{
|
||||||
|
// Invalidate BOM
|
||||||
product.setIsVerified(false);
|
product.setIsVerified(false);
|
||||||
product.saveEx(get_TrxName());
|
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;
|
return success;
|
||||||
} // afterSave
|
} // 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
|
} // MProductBOM
|
||||||
|
|
Loading…
Reference in New Issue