Advertisement
tko_pb

m_production_run 10 september add exception

Sep 11th, 2018
409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. CREATE OR REPLACE FUNCTION public.m_production_run(pinstance_id character varying)
  2.  RETURNS void
  3.  LANGUAGE plpgsql
  4.  SET search_path TO '$user', 'public'
  5. AS $function$ DECLARE
  6. /*************************************************************************
  7.   * The contents of this file are subject to the Compiere Public
  8.   * License 1.1 ("License"); You may not use this file except in
  9.   * compliance with the License. You may obtain a copy of the License in
  10.   * the legal folder of your Openbravo installation.
  11.   * Software distributed under the License is distributed on an
  12.   * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  13.   * implied. See the License for the specific language governing rights
  14.   * and limitations under the License.
  15.   * The Original Code is  Compiere  ERP &  Business Solution
  16.   * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
  17.   * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke,
  18.   * parts created by ComPiere are Copyright (C) ComPiere, Inc.;
  19.   * All Rights Reserved.
  20.   * Contributor(s): Openbravo SLU
  21.   * Contributions are Copyright (C) 2001-2017 Openbravo, S.L.U.
  22.   *
  23.   * Specifically, this derivative work is based upon the following Compiere
  24.   * file and version.
  25.   *************************************************************************
  26.   * $Id: M_Production_Run.sql,v 1.4 2003/09/05 04:58:06 jjanke Exp $
  27.   ***
  28.   * Title: Production of BOMs
  29.   * Description:
  30.   *  1) Creating ProductionLines when IsCreated = 'N'
  31.   *  2) Posting the Lines (optionally only when fully stocked)
  32.   ************************************************************************/
  33.   -- Logistice
  34.   v_ResultStr VARCHAR(2000):=''; --OBTG:VARCHAR2--
  35.   v_Message VARCHAR(2000):=''; --OBTG:VARCHAR2--
  36.   v_Record_ID VARCHAR(32); --OBTG:VARCHAR2--
  37.   v_Result NUMERIC:=1;
  38.   v_is_included NUMERIC:=0;
  39.   v_MovementDate TIMESTAMP;
  40.   v_available_period NUMERIC:=0;
  41.   v_is_ready AD_Org.IsReady%TYPE;
  42.   v_is_tr_allow AD_OrgType.IsTransactionsAllowed%TYPE;
  43.   v_isacctle AD_OrgType.IsAcctLegalEntity%TYPE;
  44.   -- Parameter
  45.   --TYPE RECORD IS REFCURSOR;
  46.     Cur_Parameter RECORD;
  47.     CUR_ProductionPlan RECORD;
  48.     CUR_PP RECORD;
  49.     CUR_PLineBOM RECORD;
  50.     CUR_BOM_PRODUCT RECORD;
  51.     CUR_PL_Post RECORD;
  52.   -- Parameter Variables
  53.   MustBeStocked CHAR(1) ;
  54.   v_IsCreated CHAR(1) ;
  55.   v_Processed VARCHAR(60) ; --OBTG:VARCHAR2--
  56.   v_Client_ID VARCHAR(32); --OBTG:VARCHAR2--
  57.   v_Org_ID VARCHAR(32); --OBTG:VARCHAR2--
  58.   --
  59.   v_Line NUMERIC;
  60.   v_Count NUMERIC;
  61.   p_User VARCHAR(32); --OBTG:VARCHAR2--
  62.   v_NegStockLocator VARCHAR(32); --OBTG:VARCHAR2--
  63.   v_NegStockWarehosue VARCHAR(32); --OBTG:VARCHAR2--
  64.   v_Product_Name m_product.name%TYPE;
  65.   -- Stocked BOMs
  66.   -- Proposed stock from given warehouse is priorized.
  67.   DECLARE CUR_STOCK CURSOR (v_ad_pinstance_id VARCHAR)  FOR
  68.       SELECT sd.m_product_id, sd.m_locator_id, sd.m_attributesetinstance_id,
  69.           sd.c_uom_id, sd.m_product_uom_id, u.stdprecision,
  70.           ms.quantity AS qty, ms.qtyorder AS qtyorder,
  71.           ms.priority, invs.overissue
  72.       FROM m_stock_proposed ms
  73.             LEFT JOIN m_storage_detail sd ON ms.m_storage_detail_id = sd.m_storage_detail_id
  74.             LEFT JOIN m_product_uom pu ON sd.m_product_uom_id = pu.m_product_uom_id
  75.             LEFT JOIN c_uom u ON pu.c_uom_id = u.c_uom_id
  76.             LEFT JOIN m_locator l ON sd.m_locator_id = l.m_locator_id
  77.             JOIN m_inventorystatus invs ON invs.m_inventorystatus_id = l.m_inventorystatus_id
  78.       WHERE ms.ad_pinstance_id = v_ad_pinstance_id
  79.       ORDER BY ms.priority;
  80.   v_storage RECORD; --OBTG:CUR_STOCK--
  81.   NEXT_PRODUCT BOOLEAN:=false;
  82.   CUR_STOCK_ISOPEN BOOLEAN:=false;
  83. BEGIN
  84.   --  Update AD_PInstance
  85.   RAISE NOTICE '%','Updating PInstance - Processing ' || PInstance_ID ;
  86.   v_ResultStr:='PInstanceNotFound';
  87.   PERFORM AD_UPDATE_PINSTANCE(PInstance_ID, NULL, 'Y', NULL, NULL) ;
  88. BEGIN --BODY
  89.   -- Get Parameters
  90.   v_ResultStr:='ReadingParameters';
  91.   FOR Cur_Parameter IN (
  92.       SELECT i.Record_ID, i.AD_User_ID, p.ParameterName,
  93.           p.P_String, p.P_Number, p.P_Date
  94.       FROM AD_ClientInfo ci JOIN AD_PInstance i ON ci.ad_client_id=i.ad_client_id
  95.             LEFT JOIN AD_PInstance_Para p ON i.AD_PInstance_ID=p.AD_PInstance_ID
  96.       WHERE i.AD_PInstance_ID=PInstance_ID
  97.       ORDER BY p.SeqNo
  98.   ) LOOP
  99.     v_Record_ID := Cur_Parameter.Record_ID;
  100.     p_User := Cur_Parameter.AD_User_ID;
  101.     IF (Cur_Parameter.ParameterName = 'MustBeStocked') THEN
  102.       MustBeStocked:=Cur_Parameter.P_String;
  103.       RAISE NOTICE '%','  MustBeStocked=' || MustBeStocked ;
  104.     ELSE
  105.       RAISE NOTICE '%','*** Unknown Parameter=' || Cur_Parameter.ParameterName ;
  106.     END IF;
  107.   END LOOP; -- Get Parameter
  108.   RAISE NOTICE '%','  Record_ID=' || v_Record_ID ;
  109.   -- Processing:1:2:3 Lock :4:5:6:7
  110.   -- TODO
  111.   /**
  112.   * Get Info + Lock
  113.   */
  114.   v_ResultStr:='ReadingRecord';
  115.   SELECT IsCreated, Processed, AD_Client_ID, AD_Org_ID, MovementDate
  116.     INTO v_IsCreated, v_Processed, v_Client_ID, v_Org_ID, v_MovementDate
  117.   FROM M_PRODUCTION
  118.   WHERE M_Production_ID=v_Record_ID  FOR UPDATE;
  119.   /**
  120.   * No Action
  121.   */
  122.   RAISE EXCEPTION '%', "TIKO TEST ERORR 1 "; --OBTG:-20000--
  123.   IF (v_Processed <> 'N') THEN
  124.     v_Message:='@AlreadyPosted@';
  125.   END IF;
  126.   /**************************************************************************
  127.   * Create Lines
  128.   */
  129.   /***************************************************************************/
  130.  
  131.   RAISE EXCEPTION '%', v_Message; --OBTG:-20000--tiko
  132.  
  133.   -- Check the header belongs to a organization where transactions are posible and ready to use
  134.   SELECT AD_Org.IsReady, Ad_OrgType.IsTransactionsAllowed
  135.     INTO v_is_ready, v_is_tr_allow
  136.   FROM M_PRODUCTION, AD_Org, AD_OrgType
  137.   WHERE AD_Org.AD_Org_ID=M_PRODUCTION.AD_Org_ID
  138.     AND AD_Org.AD_OrgType_ID=AD_OrgType.AD_OrgType_ID
  139.     AND M_PRODUCTION.M_PRODUCTION_ID=v_Record_ID;
  140.   IF (v_is_ready='N') THEN
  141.     RAISE EXCEPTION '%', '@OrgHeaderNotReady@'; --OBTG:-20000--
  142.   END IF;
  143.   IF (v_is_tr_allow='N') THEN
  144.     RAISE EXCEPTION '%', '@OrgHeaderNotTransAllowed@'; --OBTG:-20000--
  145.   END IF;
  146.  
  147.   -- Check the lines belong to the same business unit or legal entity as the header    
  148.   SELECT AD_ORG_CHK_DOCUMENTS('M_PRODUCTION', 'M_PRODUCTIONPLAN', v_Record_ID, 'M_PRODUCTION_ID', 'M_PRODUCTION_ID') INTO v_is_included FROM dual;
  149.   IF (v_is_included = -1) THEN
  150.     RAISE EXCEPTION '%', '@LinesAndHeaderDifferentLEorBU@'; --OBTG:-20000--
  151.   END IF;
  152.   FOR CUR_PP IN (
  153.       SELECT M_PRODUCTIONPLAN_ID
  154.       FROM M_PRODUCTIONPLAN
  155.       WHERE M_PRODUCTION_ID = v_Record_ID
  156.   ) LOOP
  157.     SELECT AD_ORG_CHK_DOCUMENTS('M_PRODUCTIONPLAN', 'M_PRODUCTIONLINE', CUR_PP.M_PRODUCTIONPLAN_ID, 'M_PRODUCTIONPLAN_ID', 'M_PRODUCTIONPLAN_ID') INTO v_is_included FROM dual;
  158.     IF (v_is_included = -1) THEN
  159.       RAISE EXCEPTION '%', '@LinesAndHeaderDifferentLEorBU@'; --OBTG:-20000--
  160.     END IF;
  161.   END LOOP;
  162.  
  163.   -- Check the period control is opened (only if it is legal entity with accounting)
  164.   -- Gets the BU or LE of the document
  165.   SELECT AD_OrgType.IsAcctLegalEntity INTO v_isacctle
  166.   FROM AD_OrgType, AD_Org
  167.   WHERE AD_Org.AD_OrgType_ID = AD_OrgType.AD_OrgType_ID
  168.     AND AD_Org.AD_Org_ID = AD_GET_DOC_LE_BU('M_PRODUCTION', v_Record_ID, 'M_PRODUCTION_ID', 'LE');
  169.  
  170.   IF (v_isacctle='Y') THEN
  171.     SELECT C_CHK_OPEN_PERIOD(v_Org_ID, v_MovementDate, 'MMP', NULL)  INTO v_available_period FROM DUAL;
  172.  
  173.     IF (v_available_period<>1) THEN
  174.       RAISE EXCEPTION '%', '@PeriodNotAvailable@'; --OBTG:-20000--
  175.     END IF;
  176.   END IF;
  177.  
  178.   IF (v_IsCreated <> 'Y') THEN
  179.     -- For every Production Plan
  180.     FOR CUR_PP IN (
  181.         SELECT M_PRODUCTIONPLAN.*, M_PRODUCT.C_UOM_ID,
  182.             (CASE WHEN M_PRODUCT.ATTRSETVALUETYPE='D' THEN M_PRODUCT.M_AttributeSetInstance_ID ELSE NULL END) AS M_AttributeSetInstance_ID
  183.         FROM M_PRODUCTIONPLAN, M_PRODUCT
  184.         WHERE M_PRODUCTIONPLAN.M_Product_ID=M_PRODUCT.M_Product_ID
  185.           AND M_PRODUCTIONPLAN.M_Production_ID=v_Record_ID
  186.         ORDER BY M_PRODUCTIONPLAN.Line, M_PRODUCTIONPLAN.M_Product_ID
  187.     ) LOOP
  188.       IF (CUR_PP.M_Locator_ID IS NULL) THEN
  189.         RAISE EXCEPTION '%', '@ProductionPlanLocatorNeeded@'; --OBTG:-20000--
  190.       END IF;
  191.       -- Delete prior lines
  192.       DELETE
  193.       FROM M_PRODUCTIONLINE
  194.       WHERE M_ProductionPlan_ID=CUR_PP.M_ProductionPlan_ID;
  195.       -- Create BOM Line
  196.       v_ResultStr:='CreatingLine BOM';
  197.       v_Line:=10; -- OriginLine
  198.       INSERT INTO M_PRODUCTIONLINE (
  199.           M_ProductionLine_ID, M_ProductionPlan_ID, Line, AD_Client_ID,
  200.           AD_Org_ID, IsActive, Created, CreatedBy,
  201.           Updated, UpdatedBy, M_Product_ID, MovementQty,
  202.           M_Locator_ID, Description, C_UOM_ID,
  203.           M_AttributeSetInstance_ID
  204.       ) VALUES (
  205.           get_uuid(), CUR_PP.M_ProductionPlan_ID, v_Line, CUR_PP.AD_Client_ID,
  206.           CUR_PP.AD_Org_ID, 'Y', TO_DATE(NOW()), p_User,
  207.           TO_DATE(NOW()), p_User, CUR_PP.M_Product_ID, CUR_PP.ProductionQty,
  208.           CUR_PP.M_Locator_ID, CUR_PP.Description, CUR_PP.C_UOM_ID,
  209.           CUR_PP.M_AttributeSetInstance_ID
  210.       );
  211.     END LOOP;
  212.     --Creating BOM Lines
  213.     DECLARE
  214.       v_Product_old VARCHAR(32); --OBTG:VARCHAR2--
  215.       v_Warehouse_old VARCHAR(32); --OBTG:VARCHAR2--
  216.       v_UOM_old VARCHAR(32); --OBTG:VARCHAR2--
  217.       v_Qty NUMERIC;
  218.       v_QtyStorage NUMERIC:=0;
  219.       v_QtyAcumulated NUMERIC;
  220.       v_QtyOrder NUMERIC;
  221.       v_QtyOrderRate NUMERIC;
  222.       v_ProductionLineCount NUMERIC;
  223.       v_pinstance_id VARCHAR(32); --OBTG:VARCHAR2--
  224.       CUR_BOM RECORD;
  225.     BEGIN
  226.       FOR CUR_BOM IN (
  227.           SELECT pb.*,
  228.               p.C_UOM_ID, p.IsStocked, pp.M_LOCATOR_ID, pp.AD_Org_ID AS ORG_ID,
  229.               pp.ProductionQty, pp.M_ProductionPlan_ID, pp.AD_Client_ID AS Client_ID, p.name as pname,
  230.               l.m_warehouse_id
  231.           FROM M_PRODUCT_BOM pb
  232.               JOIN M_PRODUCT p ON pb.M_ProductBOM_ID=p.M_Product_ID
  233.               JOIN M_PRODUCTIONPLAN pp ON pb.M_Product_ID=pp.M_PRODUCT_ID
  234.               JOIN M_LOCATOR l ON pp.m_locator_id = l.m_locator_id
  235.         WHERE pp.M_PRODUCTION_ID=v_Record_ID
  236.           AND pb.isactive='Y'
  237.         ORDER BY pb.M_PRODUCTBOM_ID, pb.Line
  238.       ) LOOP
  239.         v_ResultStr:='CreatingLine Products';
  240.         IF (CUR_BOM.IsStocked = 'Y') THEN
  241.           v_QtyAcumulated:=0;
  242.           IF ((NOT CUR_STOCK_ISOPEN)
  243.               OR (v_Product_old <> CUR_BOM.M_ProductBOM_ID OR v_Warehouse_old <> cur_bom.m_warehouse_id OR v_UOM_old <> CUR_BOM.C_UOM_ID)) THEN
  244.             NEXT_PRODUCT:=false;
  245.             v_product_old := cur_bom.m_productbom_id;
  246.             v_warehouse_old := cur_bom.m_warehouse_id;
  247.             v_uom_old := cur_bom.c_uom_id;
  248.             IF (CUR_STOCK_ISOPEN) THEN
  249.               CLOSE CUR_STOCK;
  250.               CUR_STOCK_ISOPEN:=false;
  251.             END IF;
  252.            
  253.             -- Call M_GET_STOCK
  254.             DECLARE
  255.               v_pinstance_result AD_PInstance.result%TYPE;
  256.               v_pinstance_msg AD_PInstance.errormsg%TYPE;
  257.             BEGIN
  258.               v_pinstance_id := get_uuid();
  259.              SELECT * INTO  v_pinstance_result, v_pinstance_msg FROM M_GET_STOCK_PARAM(v_pinstance_id, v_record_id, null, v_Product_old, null, null, v_Warehouse_old, cur_bom.org_id, null, p_user, v_client_id, null, v_UOM_old, null, null, null, 10, '137', null, 'N', 'Y', null, null);
  260.               -- Check result
  261.               IF (v_pinstance_result = 0) THEN
  262.                 -- Error on m_get_stock
  263.                 RAISE EXCEPTION '%', v_pinstance_msg; --OBTG:-20000--
  264.               END IF;
  265.             END; -- End Call M_GET_STOCK
  266.            
  267.             OPEN CUR_STOCK(v_pinstance_id);
  268.             CUR_STOCK_ISOPEN:=true;
  269.             FETCH CUR_STOCK INTO v_storage;
  270.             IF ( NOT FOUND ) THEN --OBTG:CUR_STOCK--
  271.               NEXT_PRODUCT:=true;
  272.             END IF;
  273.             v_qtystorage:=v_storage.qty;
  274.           END IF;
  275.           IF (NOT NEXT_PRODUCT) THEN
  276.             LOOP          
  277.               IF (v_storage.OVERISSUE = 'Y' AND v_NegStockLocator IS NULL) THEN
  278.                 v_NegStockLocator:= v_storage.m_locator_id;
  279.               END IF;
  280.  
  281.               v_Qty := LEAST(v_QtyStorage, CUR_BOM.ProductionQty * CUR_BOM.BOMQty - v_QtyAcumulated) ;
  282.               v_QtyStorage := v_QtyStorage - v_Qty;
  283.               v_QtyAcumulated := v_QtyAcumulated + v_Qty;
  284.               v_QtyOrder := ROUND(v_storage.QtyOrder*(v_Qty/v_storage.Qty), v_storage.stdprecision);
  285.               SELECT COALESCE(MAX(Line), 0) + 10 INTO v_Line
  286.               FROM M_PRODUCTIONLINE
  287.               WHERE M_ProductionPlan_ID=CUR_BOM.M_ProductionPlan_ID;
  288.               INSERT INTO M_PRODUCTIONLINE (
  289.                   M_ProductionLine_ID, M_ProductionPlan_ID, Line, AD_Client_ID,
  290.                   AD_Org_ID, IsActive, Created, CreatedBy,
  291.                   Updated, UpdatedBy, M_Product_ID, C_UOM_ID,
  292.                   MovementQty, M_Locator_ID,
  293.                   M_AttributeSetInstance_ID,
  294.                   M_Product_UOM_ID,
  295.                   QuantityOrder
  296.               ) VALUES (
  297.                   get_uuid(), CUR_BOM.M_ProductionPlan_ID, v_Line, CUR_BOM.Client_ID,
  298.                   CUR_BOM.Org_ID, 'Y', TO_DATE(NOW()), p_User,
  299.                   TO_DATE(NOW()), p_User, CUR_BOM.M_ProductBOM_ID, CUR_BOM.C_UOM_ID,
  300.                   -v_Qty, v_storage.M_Locator_ID,
  301.                   (CASE WHEN (SELECT ATTRSETVALUETYPE FROM M_PRODUCT WHERE M_PRODUCT_ID=CUR_BOM.M_ProductBOM_ID)='F' THEN NULL ELSE v_storage.M_AttributeSetInstance_ID END),
  302.                   v_storage.M_Product_UOM_ID,
  303.                   -v_QtyOrder
  304.               );
  305.               IF (v_QtyAcumulated >= CUR_BOM.ProductionQty*CUR_BOM.BOMQty) THEN
  306.                 EXIT;
  307.               END IF;
  308.               v_QtyStorage:=0;
  309.               v_ResultStr:='FetchingData';
  310.               FETCH CUR_STOCK INTO v_storage;
  311.               IF ( NOT FOUND ) THEN --OBTG:CUR_STOCK--
  312.                 CLOSE CUR_STOCK;
  313.                 CUR_STOCK_ISOPEN:=false;
  314.                 EXIT;
  315.               END IF;
  316.               EXIT WHEN  NOT FOUND ; --OBTG:CUR_STOCK--
  317.               v_QtyStorage:=v_storage.Qty;
  318.             END LOOP;
  319.           END IF; --NEXT_PRODUCT
  320.         ELSE
  321.           SELECT COALESCE(MAX(Line), 0) + 10
  322.           INTO v_Line
  323.           FROM M_PRODUCTIONLINE
  324.           WHERE M_ProductionPlan_ID=CUR_BOM.M_ProductionPlan_ID;
  325.           INSERT INTO M_PRODUCTIONLINE (
  326.               M_ProductionLine_ID, M_ProductionPlan_ID, Line, AD_Client_ID,
  327.               AD_Org_ID, IsActive, Created, CreatedBy,
  328.               Updated, UpdatedBy, M_Product_ID, MovementQty,
  329.               M_Locator_ID, C_UOM_ID
  330.           ) VALUES (
  331.               get_uuid(), CUR_BOM.M_ProductionPlan_ID, v_Line, CUR_BOM.Client_ID,
  332.               CUR_BOM.Org_ID, 'Y', TO_DATE(NOW()), p_User,
  333.               TO_DATE(NOW()), p_User, CUR_BOM.M_ProductBOM_ID, -CUR_BOM.ProductionQty*CUR_BOM.BOMQty,
  334.               CUR_BOM.M_Locator_ID, CUR_BOM.C_UOM_ID
  335.           );
  336.         END IF;
  337.         v_Line:=v_Line;
  338.         IF (v_QtyAcumulated < CUR_BOM.BOMQTY*CUR_BOM.ProductionQty) THEN
  339.           IF (MustBeStocked='Y') THEN
  340.             v_Message := '@NotEnoughStocked@: ' || CUR_BOM.pname || ' ' || v_QtyAcumulated || ' / '|| CUR_BOM.BOMQTY*CUR_BOM.ProductionQty;
  341.             RAISE EXCEPTION '%', v_Message; --OBTG:-20000--
  342.           ELSE
  343.             IF (v_NegStockLocator IS NULL) THEN
  344.               -- Get Locator with negative Stock that belongs to the same Warehosue
  345.               SELECT m_warehouse_id
  346.               INTO v_NegStockWarehosue
  347.               FROM m_locator
  348.              WHERE m_locator_id = (SELECT m_locator_id
  349.                                    FROM M_PRODUCTIONPLAN
  350.                                    WHERE M_ProductionPlan_ID=CUR_BOM.M_ProductionPlan_ID);
  351.        
  352.               SELECT MIN(l.m_locator_id)
  353.               INTO v_NegStockLocator
  354.               FROM m_locator l
  355.               JOIN m_inventorystatus invs ON l.m_inventorystatus_id = invs.m_inventorystatus_id
  356.               WHERE l.m_warehouse_id = v_NegStockWarehosue
  357.               AND invs.overissue = 'Y'
  358.               AND l.isactive= 'Y'
  359.               AND priorityno = (SELECT MIN(priorityno)
  360.                                 FROM m_locator l
  361.                                 JOIN m_inventorystatus invs ON l.m_inventorystatus_id = invs.m_inventorystatus_id
  362.                                 WHERE l.m_warehouse_id = v_NegStockWarehosue
  363.                                 AND invs.overissue = 'Y'
  364.                                 AND l.isactive='Y');
  365.             END IF;        
  366.            
  367.             -- If there is a Storage Bin that allows negative stock and MustBeStocked is disabled and there is not enough stock,
  368.             -- pending quantity will be created for the same locator as production plan product, keeping a negative stock
  369.             IF (v_NegStockLocator IS NOT NULL) THEN  
  370.            
  371.               -- Check if exists a production line for this product with the same locator
  372.               SELECT count(M_ProductionLine_ID)
  373.               INTO v_ProductionLineCount
  374.               FROM M_PRODUCTIONLINE
  375.               WHERE M_ProductionPlan_ID=CUR_BOM.M_ProductionPlan_ID
  376.               AND M_Product_ID=CUR_BOM.M_ProductBOM_ID
  377.               AND M_Locator_ID=v_NegStockLocator;
  378.  
  379.               -- If exists update it            
  380.               IF (v_ProductionLineCount <> 0) THEN
  381.                
  382.                 SELECT QuantityOrder / CASE WHEN (MovementQty <> 0) THEN MovementQty ELSE 1 END
  383.                 INTO v_QtyOrderRate
  384.                 FROM M_PRODUCTIONLINE
  385.                 WHERE M_ProductionPlan_ID=CUR_BOM.M_ProductionPlan_ID
  386.                 AND M_Product_ID=CUR_BOM.M_ProductBOM_ID
  387.                 AND M_Locator_ID=v_NegStockLocator;              
  388.                
  389.                 UPDATE M_PRODUCTIONLINE
  390.                 SET MovementQty = MovementQty - (CUR_BOM.BOMQTY*CUR_BOM.ProductionQty - v_QtyAcumulated),
  391.                 QuantityOrder = v_QtyOrderRate * (MovementQty - (CUR_BOM.BOMQTY*CUR_BOM.ProductionQty - v_QtyAcumulated))
  392.                 WHERE M_ProductionPlan_ID=CUR_BOM.M_ProductionPlan_ID
  393.                 AND M_Product_ID=CUR_BOM.M_ProductBOM_ID
  394.                 AND M_Locator_ID=v_NegStockLocator;
  395.  
  396.               -- If not exists, insert a new production line
  397.               ELSE
  398.                    
  399.                 SELECT COALESCE(MAX(Line), 0) + 10 INTO v_Line
  400.                 FROM M_PRODUCTIONLINE
  401.                 WHERE M_ProductionPlan_ID=CUR_BOM.M_ProductionPlan_ID;        
  402.                
  403.                 INSERT INTO M_PRODUCTIONLINE (
  404.                   M_ProductionLine_ID, M_ProductionPlan_ID, Line, AD_Client_ID,
  405.                   AD_Org_ID, IsActive, Created, CreatedBy,
  406.                   Updated, UpdatedBy, M_Product_ID, C_UOM_ID,
  407.                   MovementQty, M_Locator_ID
  408.               ) VALUES (
  409.                   get_uuid(), CUR_BOM.M_ProductionPlan_ID, v_Line, CUR_BOM.Client_ID,
  410.                   CUR_BOM.Org_ID, 'Y', TO_DATE(NOW()), p_User,
  411.                   TO_DATE(NOW()), p_User, CUR_BOM.M_ProductBOM_ID, CUR_BOM.C_UOM_ID,
  412.                   - (CUR_BOM.BOMQTY*CUR_BOM.ProductionQty - v_QtyAcumulated), v_NegStockLocator                  
  413.               );
  414.              
  415.               END IF;          
  416.             END IF;
  417.           END IF;  
  418.         END IF;
  419.         IF (CUR_BOM.ProductionQty <= 0) THEN
  420.           v_Message := '@NegativeBOMProductionQty@';
  421.           RAISE EXCEPTION '%', v_Message; --OBTG:-20000--
  422.         END IF;
  423.       END LOOP;
  424.       IF (CUR_STOCK_ISOPEN) THEN
  425.         CLOSE CUR_STOCK;
  426.         CUR_STOCK_ISOPEN := false;
  427.       END IF;
  428.     END; --END OF DECLARE FOR BOM PRODUCTS INSERTION
  429.     -- While we have BOMs
  430.     LOOP
  431.       -- Are there non-stored BOMs to list details:8
  432.       v_ResultStr:='CreatingLine CheckBOM';
  433.       SELECT COUNT(*) INTO v_count
  434.       FROM M_PRODUCTIONLINE pl,
  435.         M_PRODUCT p,
  436.         M_PRODUCTIONPLAN pp
  437.       WHERE pl.M_Product_ID=p.M_Product_ID
  438.         AND pl.M_ProductionPlan_ID=pp.M_ProductionPlan_ID
  439.         AND pp.M_PRODUCTION_ID=v_Record_ID
  440.         AND pl.Line<>10 -- Origin Line
  441.         AND p.IsBOM='Y'
  442.         AND p.IsStocked='N';
  443.       -- Nothing to do
  444.       EXIT WHEN(v_count=0) ;
  445.       --
  446.       -- Resolve BOMs in ProductLine which are not stocked
  447.       FOR CUR_PLineBOM IN (
  448.           SELECT pl.M_ProductionLine_ID, pl.Line, pl.M_Product_ID, pl.MovementQty,
  449.               pp.M_LOCATOR_ID, pp.AD_Org_ID AS ORG_ID, pp.ProductionQty, pp.M_ProductionPlan_ID,
  450.               pp.AD_Client_ID AS Client_ID
  451.           FROM M_PRODUCTIONLINE pl, M_PRODUCT p, M_PRODUCTIONPLAN pp
  452.         WHERE pl.M_ProductionPlan_ID=pp.M_ProductionPlan_ID
  453.           AND pp.M_Production_ID=v_Record_ID
  454.           AND pl.M_Product_ID=p.M_Product_ID
  455.           AND pl.Line<>10 -- Origin Line
  456.           AND p.IsBOM='Y'
  457.           AND p.IsStocked='N'
  458.       ) LOOP
  459.         v_ResultStr:='CreatingLineBOM Resolution';
  460.         v_Line:=CUR_PLineBOM.Line;
  461.         -- Resolve BOM Line in product line
  462.         FOR CUR_BOM_PRODUCT IN (
  463.             SELECT pb.*, p.C_UOM_ID, p.IsStocked
  464.             FROM M_PRODUCT_BOM pb, M_PRODUCT p
  465.             WHERE pb.M_ProductBOM_ID=p.M_Product_ID
  466.               AND pb.M_Product_ID=CUR_PLineBOM.M_Product_ID
  467.               AND pb.isactive='Y'
  468.             ORDER BY pb.M_PRODUCTBOM_ID, pb.Line
  469.         ) LOOP
  470.           v_ResultStr:='CreatingLine Products2';
  471.           SELECT COALESCE(MAX(Line), 0) + 10 INTO v_Line
  472.           FROM M_PRODUCTIONLINE
  473.           WHERE M_ProductionPlan_ID=CUR_PLineBOM.M_ProductionPlan_ID;
  474.           INSERT INTO M_PRODUCTIONLINE (
  475.               M_ProductionLine_ID, M_ProductionPlan_ID, Line, AD_Client_ID,
  476.               AD_Org_ID, IsActive, Created, CreatedBy,
  477.               Updated, UpdatedBy, M_Product_ID, MovementQty,
  478.               M_Locator_ID, C_UOM_ID
  479.           ) VALUES (
  480.               get_uuid(), CUR_PLineBOM.M_ProductionPlan_ID, v_Line, CUR_PLineBOM.Client_ID,
  481.               CUR_PLineBOM.Org_ID, 'Y', TO_DATE(NOW()), p_User,
  482.               TO_DATE(NOW()), p_User, CUR_BOM_PRODUCT.M_ProductBOM_ID, CUR_PLineBOM.MovementQty*CUR_BOM_PRODUCT.BOMQty,
  483.               CUR_PLineBOM.M_Locator_ID, CUR_BOM_PRODUCT.C_UOM_ID
  484.           );
  485.         END LOOP;
  486.         -- Delete BOM line
  487.         DELETE
  488.         FROM M_PRODUCTIONLINE
  489.         WHERE M_ProductionLine_ID=CUR_PLineBOM.M_ProductionLine_ID;
  490.       END LOOP;
  491.     END LOOP; -- While we have BOMs
  492.     -- Modifying locator to have sufficient stock
  493.     -- Indicate that it is Created
  494.     UPDATE M_PRODUCTION  SET IsCreated='Y',Updated=TO_DATE(NOW()),UpdatedBy=p_User  WHERE M_Production_ID=v_Record_ID;
  495.   /**************************************************************************
  496.   * Post Lines
  497.   */
  498.   ELSE
  499.     v_ResultStr:='CheckingRestrictions';
  500.     SELECT COUNT(*) INTO v_Count
  501.     FROM M_PRODUCTIONPLAN PP, M_PRODUCTIONLINE PL, M_PRODUCT P
  502.     WHERE PL.M_PRODUCT_ID=P.M_PRODUCT_ID
  503.       AND P.M_ATTRIBUTESET_ID IS NOT NULL
  504.       AND (P.ATTRSETVALUETYPE IS NULL OR P.ATTRSETVALUETYPE <> 'F')
  505.       AND (SELECT ISONEATTRSETVALREQUIRED FROM M_ATTRIBUTESET WHERE M_ATTRIBUTESET_ID = P.M_ATTRIBUTESET_ID) = 'Y'
  506.       AND COALESCE(PL.M_ATTRIBUTESETINSTANCE_ID, '0') = '0'
  507.       AND PL.M_ProductionPlan_ID=pp.M_ProductionPlan_ID
  508.       AND pp.M_Production_ID=v_Record_ID;
  509.     IF (v_Count <> 0) THEN
  510.       SELECT max(P.name) INTO v_Product_Name
  511.       FROM M_PRODUCTIONPLAN PP, M_PRODUCTIONLINE PL, M_PRODUCT P
  512.       WHERE PL.M_PRODUCT_ID=P.M_PRODUCT_ID
  513.         AND P.M_ATTRIBUTESET_ID IS NOT NULL
  514.         AND (P.ATTRSETVALUETYPE IS NULL OR P.ATTRSETVALUETYPE <> 'F')
  515.         AND (SELECT ISONEATTRSETVALREQUIRED FROM M_ATTRIBUTESET WHERE M_ATTRIBUTESET_ID = P.M_ATTRIBUTESET_ID) = 'Y'
  516.         AND COALESCE(PL.M_ATTRIBUTESETINSTANCE_ID, '0') = '0'
  517.         AND PL.M_ProductionPlan_ID=pp.M_ProductionPlan_ID
  518.         AND pp.M_Production_ID=v_Record_ID;
  519.       v_Message:='@Product@'||' "' ||v_Product_Name ||'" ' || '@ProductWithoutAttributeSet@';
  520.       RAISE EXCEPTION '%', v_Message; --OBTG:-20000--
  521.     END IF;
  522.  
  523.     SELECT COUNT(M_ProductionPlan_ID)
  524.     INTO v_count
  525.     FROM M_ProductionPlan pp
  526.     WHERE pp.M_Production_ID = v_Record_ID
  527.     AND NOT EXISTS (SELECT 1 FROM M_ProductionLine WHERE M_ProductionPlan_ID = pp.M_ProductionPlan_ID AND MovementQty > 0);
  528.  
  529.     v_Message := NULL;      
  530.     IF(v_count <> 0) THEN
  531.       FOR CUR_ProductionPlan IN (
  532.     SELECT DISTINCT(pp.line)
  533.     FROM M_ProductionPlan pp
  534.     WHERE pp.M_Production_ID = v_Record_ID
  535.     AND NOT EXISTS (SELECT 1 FROM M_ProductionLine WHERE M_ProductionPlan_ID = pp.M_ProductionPlan_ID AND MovementQty > 0)
  536.     ORDER BY Line
  537.         )
  538.       LOOP
  539.         IF v_Message IS NULL THEN
  540.           v_Message := CUR_ProductionPlan.line;
  541.         ELSE
  542.       v_Message := v_Message || ', ' || CUR_ProductionPlan.line;
  543.     END IF;
  544.       END LOOP;
  545.       v_Message := '@ProducedProductWithNegativeQty@' || ' @ReferProductionPlanLines@' || ': ' || v_Message;
  546.       RAISE EXCEPTION '%', v_Message; --OBTG:-20000--
  547.     END IF;  
  548.  
  549.     SELECT COUNT(M_ProductionPlan_ID)
  550.     INTO v_count
  551.     FROM M_ProductionPlan pp
  552.     WHERE pp.M_Production_ID = v_Record_ID
  553.     AND (SELECT COUNT(M_ProductionLine_ID) FROM M_ProductionLine WHERE M_ProductionPlan_ID = pp.M_ProductionPlan_ID AND movementQty > 0) > 1;
  554.    
  555.     IF (v_count <> 0) THEN
  556.       FOR CUR_ProductionPlan IN (
  557.     SELECT DISTINCT(pp.line)
  558.     FROM M_ProductionPlan pp
  559.     WHERE pp.M_Production_ID = v_Record_ID
  560.     AND (SELECT COUNT(M_ProductionLine_ID) FROM M_ProductionLine WHERE M_ProductionPlan_ID = pp.M_ProductionPlan_ID AND movementQty > 0) > 1
  561.     ORDER BY Line
  562.       )
  563.       LOOP
  564.         IF v_Message IS NULL THEN
  565.           v_Message := CUR_ProductionPlan.line;
  566.         ELSE
  567.       v_Message := v_Message || ', ' || CUR_ProductionPlan.line;
  568.     END IF;
  569.       END LOOP;
  570.       v_Message:= '@ConsumedProductWithPostiveQty@' || ' @ReferProductionPlanLines@' || ': ' || v_Message;
  571.       RAISE EXCEPTION '%', v_Message; --OBTG:-20000--
  572.     END IF;
  573.  
  574.     DECLARE
  575.         v_Message_ProductionRun VARCHAR(2000);
  576.         v_Message_ProductLine VARCHAR(2000);
  577.         BEGIN
  578.           FOR CUR_ProductionPlan IN
  579.             (SELECT pp.Line, pp.M_PRODUCTIONPLAN_ID
  580.             FROM M_PRODUCTION p, M_PRODUCTIONPLAN pp
  581.             WHERE p.M_Production_ID=pp.M_Production_ID
  582.             AND pp.M_Production_ID=v_Record_ID
  583.             ORDER BY pp.Line)
  584.           LOOP
  585.             FOR CUR_PL_Post IN
  586.               (SELECT pl.Line
  587.               FROM M_PRODUCTIONLINE pl, M_PRODUCT pr
  588.               WHERE Cur_ProductionPlan.M_ProductionPlan_ID=pl.M_ProductionPlan_ID
  589.               AND pl.M_PRODUCT_ID=pr.M_PRODUCT_ID
  590.               AND pr.ISACTIVE='N'
  591.               ORDER BY pl.Line)
  592.             LOOP
  593.               v_Message_ProductLine := COALESCE(v_Message_ProductLine, '') || CUR_PL_Post.line || ', ';
  594.             END LOOP;
  595.             IF (v_Message_ProductLine IS NOT NULL) THEN
  596.               v_Message_ProductionRun := COALESCE(v_Message_ProductionRun, '') || '@ProductionRunLine@' || Cur_ProductionPlan.line || ' @ProductLine@' || v_Message_ProductLine;
  597.               v_Message_ProductLine := NULL;
  598.             END IF;
  599.           END LOOP;
  600.           IF (v_Message_ProductionRun IS NOT NULL) THEN
  601.             RAISE EXCEPTION '%', v_Message_ProductionRun||'@InActiveProducts@'; --OBTG:-20000--
  602.           END IF;
  603.         END;
  604.    
  605.     SELECT count(*) INTO v_count
  606.     FROM dual
  607.     WHERE EXISTS (
  608.         SELECT 1
  609.         FROM m_productionplan pp
  610.             JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
  611.             JOIN m_product p ON pl.m_product_id = p.m_product_id
  612.         WHERE pp.m_production_id = v_record_id
  613.           AND p.isgeneric = 'Y');
  614.     IF (v_count > 0) THEN
  615.       SELECT max(p.name) INTO v_product_name
  616.       FROM m_productionplan pp
  617.           JOIN m_productionline pl ON pp.m_productionplan_id = pl.m_productionplan_id
  618.           JOIN m_product p ON pl.m_product_id = p.m_product_id
  619.       WHERE pp.m_production_id = v_record_id
  620.         AND p.isgeneric = 'Y';
  621.       RAISE EXCEPTION '%', '@CannotUseGenericProduct@ ' || v_product_Name; --OBTG:-20000--
  622.     END IF;
  623.  
  624.     -- All Production Lines
  625.     FOR CUR_PL_Post IN (
  626.         SELECT pl.M_ProductionLine_ID, pl.AD_Client_ID, pl.AD_Org_ID, p.MovementDate,
  627.             pl.M_Product_ID, pl.M_AttributeSetInstance_ID, pl.MovementQty, pl.M_Locator_ID,
  628.             pl.M_Product_UOM_ID, pl.QuantityOrder, pl.C_UOM_ID, pl.LINE
  629.         FROM M_PRODUCTION p, M_PRODUCTIONLINE pl, M_PRODUCTIONPLAN pp, M_PRODUCT pro
  630.         WHERE p.M_Production_ID=pp.M_Production_ID
  631.           AND pp.M_ProductionPlan_ID=pl.M_ProductionPlan_ID
  632.           AND pl.M_PRODUCT_ID = pro.M_PRODUCT_ID
  633.           AND pro.ISSTOCKED = 'Y'
  634.           AND pp.M_Production_ID=v_Record_ID
  635.         ORDER BY pp.Line, pl.Line
  636.     ) LOOP
  637.       -- M_ProductionLine_ID, AD_Client_ID, AD_Org_ID, MovementDate, M_Product_ID, MovementQty, M_Locator_ID
  638.       -- DBMS_OUTPUT.PUT_LINE('ProductionLine=' || pl.M_ProductionLine_ID);
  639.       -- DBMS_OUTPUT.PUT_LINE('  Qty=' || pl.MovementQty || ', OnHand=' || M_BOM_Qty_OnHand(pl.M_Product_ID, NULL, pl.M_Locator_ID));
  640.       -- Check Stock levels for reductions
  641.       IF (CUR_PL_Post.MovementQty<0 AND MustBeStocked<>'N' AND M_BOM_Qty_OnHand(CUR_PL_Post.M_Product_ID, NULL, CUR_PL_Post.M_Locator_ID) +CUR_PL_Post.MovementQty<0) THEN
  642.         SELECT '@NotEnoughStocked@: ' || Name INTO v_Message
  643.         FROM M_PRODUCT
  644.         WHERE M_Product_ID=CUR_PL_Post.M_Product_ID;
  645.         RAISE EXCEPTION '%', v_Message; --OBTG:-20000--
  646.       END IF;
  647.       -- Create Transaction Entry
  648.       v_ResultStr:='CreateTransaction';
  649.       INSERT INTO M_TRANSACTION (
  650.           M_Transaction_ID, M_ProductionLine_ID, AD_Client_ID, AD_Org_ID,
  651.           IsActive, Created, CreatedBy, Updated,
  652.           UpdatedBy, MovementType, M_Locator_ID, M_Product_ID,
  653.           M_AttributeSetInstance_ID,
  654.           MovementDate, MovementQty, M_Product_UOM_ID, QuantityOrder,
  655.           C_UOM_ID
  656.       ) VALUES (
  657.           get_uuid(), CUR_PL_Post.M_ProductionLine_ID, CUR_PL_Post.AD_Client_ID, CUR_PL_Post.AD_Org_ID,
  658.            'Y', TO_DATE(NOW()), p_User, TO_DATE(NOW()),
  659.           p_User, 'P+', CUR_PL_Post.M_Locator_ID, CUR_PL_Post.M_Product_ID,
  660.           COALESCE(CUR_PL_Post.M_AttributeSetInstance_ID, '0'), -- not distinguishing between assemby/disassembly
  661.           CUR_PL_Post.MovementDate, CUR_PL_Post.MovementQty, CUR_PL_Post.M_Product_UOM_ID, CUR_PL_Post.QuantityOrder,
  662.           CUR_PL_Post.C_UOM_ID
  663.       );
  664.       SELECT * INTO  v_Result, v_Message FROM M_Check_Stock(CUR_PL_Post.M_Product_ID, v_Client_ID, v_Org_ID, CUR_PL_Post.M_Locator_ID) ;
  665.       IF (v_Result = 0) THEN
  666.         v_Message:=v_Message || ' @Inline@ ' || CUR_PL_Post.line;
  667.         RAISE EXCEPTION '%', v_Message; --OBTG:-20000--
  668.       END IF;
  669.     END LOOP;
  670.     -- Indicate that we are done
  671.     UPDATE M_PRODUCTION
  672.     SET Processed='Y',
  673.         updated=TO_DATE(NOW()),
  674.         updatedby=p_User
  675.     WHERE M_Production_ID=v_Record_ID;
  676.   END IF;
  677.   ---- <<FINISH_PROCESS>>
  678.   --  Update AD_PInstance
  679.   RAISE NOTICE '%','Updating PInstance - Finished ' || v_Message ;
  680.   PERFORM AD_UPDATE_PINSTANCE(PInstance_ID, NULL, 'N', v_Result, v_Message) ;
  681.   RETURN;
  682. END; --BODY
  683. EXCEPTION
  684.   WHEN OTHERS THEN
  685.     RAISE NOTICE '%',v_ResultStr ;
  686.     v_ResultStr:= '@ERROR=' || SQLERRM;
  687.     RAISE NOTICE '%',v_ResultStr ;
  688.     -- ROLLBACK;
  689.     PERFORM AD_UPDATE_PINSTANCE(PInstance_ID, NULL, 'N', 0, v_ResultStr) ;
  690.     RETURN;
  691. END ; $function$;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement