src-db/database/model/functions/M_INOUT_POST.xml
changeset 28246 fb23aa4df32e
parent 28229 ef895ced13c2
child 28265 52f41dec669a
child 28677 35618c095a22
equal deleted inserted replaced
28245:4cf3d0e24951 28246:fb23aa4df32e
   100     FINISH_PROCESS BOOLEAN:=false;
   100     FINISH_PROCESS BOOLEAN:=false;
   101     v_Aux NUMBER;
   101     v_Aux NUMBER;
   102     v_isSoTrx CHAR(1);
   102     v_isSoTrx CHAR(1);
   103     v_ProductName M_Product.name%TYPE;
   103     v_ProductName M_Product.name%TYPE;
   104     v_reservation_id    VARCHAR2(32);
   104     v_reservation_id    VARCHAR2(32);
       
   105     v_reservationstock_id    VARCHAR2(32);
   105     v_M_Warehouse_ID    VARCHAR2(32);
   106     v_M_Warehouse_ID    VARCHAR2(32);
   106     v_voidmovementdate M_Inout.MovementDate%TYPE;
   107     v_voidmovementdate M_Inout.MovementDate%TYPE;
   107     v_voiddate_acct M_Inout.DateAcct%TYPE;
   108     v_voiddate_acct M_Inout.DateAcct%TYPE;
   108     v_bpartner_blocked VARCHAR2(1):='N';
   109     v_bpartner_blocked VARCHAR2(1):='N';
   109     v_goods_blocked VARCHAR2(1):='N';
   110     v_goods_blocked VARCHAR2(1):='N';
   117     
   118     
   118     v_bp_isactive c_bpartner.isactive%Type;
   119     v_bp_isactive c_bpartner.isactive%Type;
   119     v_IsQtyVariable M_Product.IsQuantityVariable%TYPE;
   120     v_IsQtyVariable M_Product.IsQuantityVariable%TYPE;
   120     v_IsReversedDoc CHAR(1);
   121     v_IsReversedDoc CHAR(1);
   121 
   122 
   122     v_uuid VARCHAR2(32);
   123     v_countRS NUMBER:=0;
   123     v_qtyordered NUMBER;
   124     v_R_Quantity NUMBER;
       
   125     v_R_Reservedqty NUMBER;
       
   126     v_RS_Quantity NUMBER;
       
   127     v_RS_Releasedqty NUMBER;
   124 
   128 
   125   BEGIN
   129   BEGIN
   126   
   130   
   127     IF(p_PInstance_ID IS NOT NULL) THEN
   131     IF(p_PInstance_ID IS NOT NULL) THEN
   128       --  Update AD_PInstance
   132       --  Update AD_PInstance
   555                   RAISE_APPLICATION_ERROR(-20000, '@SOLineWithMoreThanOneOpenReservation@');
   559                   RAISE_APPLICATION_ERROR(-20000, '@SOLineWithMoreThanOneOpenReservation@');
   556                 ELSIF (v_aux = 1) THEN
   560                 ELSIF (v_aux = 1) THEN
   557                   M_RESERVATION_CONSUMPTION(v_reservation_id, cur_inoutline.m_locator_id, cur_inoutline.m_attributesetinstance_id, cur_inoutline.movementqty, v_user, v_result, v_message);
   561                   M_RESERVATION_CONSUMPTION(v_reservation_id, cur_inoutline.m_locator_id, cur_inoutline.m_attributesetinstance_id, cur_inoutline.movementqty, v_user, v_result, v_message);
   558                 END IF;
   562                 END IF;
   559               ELSIF (cur_inout.issotrx = 'Y' AND cur_inoutline.c_orderline_id IS NOT NULL AND v_qty > 0 AND cur_inoutline.canceled_inoutline_id IS NOT NULL) THEN
   563               ELSIF (cur_inout.issotrx = 'Y' AND cur_inoutline.c_orderline_id IS NOT NULL AND v_qty > 0 AND cur_inoutline.canceled_inoutline_id IS NOT NULL) THEN
   560                 -- Undo reservation
   564                 -- Undo reservation is done when voiding shipment
   561                 DECLARE
   565                 SELECT count(*), max(m_reservation_id)
   562                   cur_released_stock RECORD;
   566                 INTO v_aux, v_reservation_id
   563                   v_qtyaux NUMBER;
   567                 FROM m_reservation
   564                   v_undoqty NUMBER;
   568                 WHERE c_orderline_id = cur_inoutline.c_orderline_id
   565                 BEGIN
   569                 AND res_status NOT IN ('DR', 'CL');
   566                   SELECT count(*), max(m_reservation_id)
   570                 IF (v_aux > 1) THEN
   567                     INTO v_aux, v_reservation_id
   571                   RAISE_APPLICATION_ERROR(-20000, '@SOLineWithMoreThanOneOpenReservation@');
   568                   FROM m_reservation
   572                 END IF;
   569                   WHERE c_orderline_id = cur_inoutline.c_orderline_id
       
   570                   AND res_status NOT IN ('DR', 'CL');
       
   571                   IF (v_aux > 1) THEN
       
   572                     RAISE_APPLICATION_ERROR(-20000, '@SOLineWithMoreThanOneOpenReservation@');
       
   573                   ELSIF (v_aux = 1) THEN
       
   574                     v_qtyaux := v_qty;
       
   575                     FOR cur_released_stock IN (
       
   576                         SELECT m_reservation_stock_id, quantity, releasedqty
       
   577                         FROM m_reservation_stock
       
   578                         WHERE m_locator_id = cur_inoutline.m_locator_id
       
   579                           AND COALESCE(m_attributesetinstance_id, '0') = COALESCE(cur_inoutline.m_attributesetinstance_id, '0')
       
   580                           AND m_reservation_id = v_reservation_id
       
   581                           AND COALESCE(releasedqty, 0) > 0
       
   582                         ORDER BY CASE isallocated WHEN 'N' THEN 0 ELSE 1 END
       
   583                     ) LOOP
       
   584                       v_undoqty := LEAST(v_qtyaux, cur_released_stock.releasedqty);
       
   585                       UPDATE m_reservation_stock
       
   586                       SET releasedqty = releasedqty - v_undoqty
       
   587                       WHERE m_reservation_stock_id = cur_released_stock.m_reservation_stock_id;
       
   588                       v_qtyaux := v_qtyaux - v_undoqty;
       
   589                     END LOOP;
       
   590                   END IF;
       
   591                 END;
       
   592               ELSIF (cur_inout.issotrx = 'N' AND cur_inoutline.canceled_inoutline_id IS NULL) THEN
   573               ELSIF (cur_inout.issotrx = 'N' AND cur_inoutline.canceled_inoutline_id IS NULL) THEN
   593                 -- Manage pre-reserves
   574                 -- Manage pre-reserves
   594                 DECLARE
   575                 DECLARE
   595                   cur_reserve_stock RECORD;
   576                   cur_reserve_stock RECORD;
   596                   v_pendingqty NUMBER;
   577                   v_pendingqty NUMBER;
  1166             UPDATE M_INOUTLINE
  1147             UPDATE M_INOUTLINE
  1167               SET Description=COALESCE(TO_CHAR(Cur_InOutLine.Description), '') || ' : *R*',
  1148               SET Description=COALESCE(TO_CHAR(Cur_InOutLine.Description), '') || ' : *R*',
  1168               Updated=now(),
  1149               Updated=now(),
  1169               UpdatedBy=v_User
  1150               UpdatedBy=v_User
  1170             WHERE M_INOUTLINE.M_INOUTLINE_ID=Cur_InOutLine.M_INOUTLINE_ID;
  1151             WHERE M_INOUTLINE.M_INOUTLINE_ID=Cur_InOutLine.M_INOUTLINE_ID;
  1171 
       
  1172 	    -- Create new reservation to replace the closed related one
       
  1173 	    FOR Cur_Reservation IN
       
  1174               (SELECT *
       
  1175               FROM M_RESERVATION
       
  1176               WHERE M_RESERVATION.C_OrderLine_ID=Cur_InOutLine.C_OrderLine_ID
       
  1177               AND IsActive='Y')
       
  1178 	    LOOP
       
  1179 	      IF (Cur_Reservation.Res_Status = 'CL') THEN
       
  1180 
       
  1181 		v_uuid := get_uuid();
       
  1182 
       
  1183 		-- Get the ordered quantity from the order line
       
  1184 	        SELECT qtyordered
       
  1185 	        INTO v_qtyordered
       
  1186 	        FROM C_ORDERLINE
       
  1187 	        WHERE C_OrderLine_ID=Cur_Reservation.C_OrderLine_ID;
       
  1188 
       
  1189 	        -- Create a new reservation with the ordered quantity
       
  1190 	        INSERT INTO M_RESERVATION (
       
  1191 		  m_reservation_id, ad_client_id, ad_org_id, isactive,
       
  1192 		  created, createdby, updated, updatedby,
       
  1193 		  m_product_id, quantity, c_uom_id, c_orderline_id,
       
  1194 		  ad_user_id, c_bpartner_id, m_warehouse_id, m_attributesetinstance_id, m_locator_id,
       
  1195 		  res_status, res_process, managereservation_pe, reservedgoodmnt_pe
       
  1196 	        ) VALUES (
       
  1197 		  v_uuid, Cur_Reservation.ad_client_id, Cur_Reservation.ad_org_id, 'Y',
       
  1198 		  now(), v_user, now(), v_user,
       
  1199 		  Cur_Reservation.m_product_id, v_qtyordered, Cur_Reservation.c_uom_id, Cur_Reservation.c_orderline_id,
       
  1200 		  Cur_Reservation.ad_user_id, Cur_Reservation.c_bpartner_id, Cur_Reservation.m_warehouse_id,
       
  1201 		  Cur_Reservation.m_attributesetinstance_id, Cur_Reservation.m_locator_id, 'DR', 'PR',
       
  1202 		  Cur_Reservation.managereservation_pe, Cur_Reservation.reservedgoodmnt_pe
       
  1203 	        );
       
  1204 
       
  1205 		-- Add a reservation stock with the ordered quantity
       
  1206 		INSERT INTO M_RESERVATION_STOCK (
       
  1207 		  m_reservation_stock_id, ad_client_id, ad_org_id, isactive,
       
  1208    	          created, createdby, updated, updatedby,
       
  1209 		  m_reservation_id, c_orderline_id, quantity, isallocated,
       
  1210 		  m_locator_id, m_attributesetinstance_id )
       
  1211 		SELECT get_uuid(), ad_client_id, ad_org_id, 'Y',
       
  1212 		  now(), v_user, now(), v_user,
       
  1213 		  v_uuid, c_orderline_id, v_qtyordered, isallocated,
       
  1214 		  m_locator_id, m_attributesetinstance_id
       
  1215 		FROM M_RESERVATION_STOCK
       
  1216 		WHERE M_RESERVATION_STOCK.M_Reservation_ID=Cur_Reservation.M_Reservation_ID
       
  1217 		AND IsActive='Y';
       
  1218 
       
  1219 	        -- Process the reservation
       
  1220 	        M_RESERVATION_POST(null, v_uuid, 'PR', v_user);
       
  1221 
       
  1222 	      END IF;
       
  1223 	    END LOOP;
       
  1224 
       
  1225           END LOOP;
  1152           END LOOP;
  1226           
  1153 
  1227           -- Post Reversal
  1154           -- Post Reversal
  1228           v_ResultStr:='PostReversal';
  1155           v_ResultStr:='PostReversal';
  1229           -- Update reversal goods dates
  1156           -- Update reversal goods dates
  1230           IF (v_voidmovementdate IS NOT NULL) THEN
  1157           IF (v_voidmovementdate IS NOT NULL) THEN
  1231             UPDATE M_INOUT SET MovementDate = v_voidmovementdate WHERE M_INOUT_ID = v_RInOut_ID;
  1158             UPDATE M_INOUT SET MovementDate = v_voidmovementdate WHERE M_INOUT_ID = v_RInOut_ID;
  1232           END IF;
  1159           END IF;
  1233           IF (v_voiddate_acct IS NOT NULL) THEN
  1160           IF (v_voiddate_acct IS NOT NULL) THEN
  1234             UPDATE M_INOUT SET DateAcct = v_voiddate_acct WHERE M_INOUT_ID = v_RInOut_ID;
  1161             UPDATE M_INOUT SET DateAcct = v_voiddate_acct WHERE M_INOUT_ID = v_RInOut_ID;
  1235           END IF;
  1162           END IF;
  1236           M_INOUT_POST(NULL, v_RInOut_ID) ;
  1163           M_INOUT_POST(NULL, v_RInOut_ID) ;
       
  1164 
       
  1165           -- Undo reservation by updating completed existing one or
       
  1166           -- by creating new reservation to replace closed existing one
       
  1167           IF (Cur_InOut.issotrx = 'Y') THEN
       
  1168             FOR Cur_Reservation IN (
       
  1169               SELECT r.m_reservation_id, r.ad_client_id, r.ad_org_id,
       
  1170               r.m_product_id, r.quantity, r.c_uom_id, r.c_orderline_id, r.ad_user_id,
       
  1171               r.c_bpartner_id, r.m_warehouse_id, r.m_attributesetinstance_id, r.m_locator_id,
       
  1172               r.reservedqty, r.res_status, r.managereservation_pe, r.reservedgoodmnt_pe,
       
  1173               ol.qtyordered, sum(iol.movementqty) as movementqty
       
  1174               FROM M_RESERVATION r
       
  1175               JOIN C_ORDERLINE ol
       
  1176               ON r.c_orderline_id = ol.c_orderline_id
       
  1177               JOIN M_INOUTLINE iol
       
  1178               ON ol.c_orderline_id = iol.c_orderline_id
       
  1179               AND ol.m_product_id = iol.m_product_id
       
  1180               WHERE iol.m_inout_id = Cur_InOut.m_inout_id
       
  1181               AND r.res_status <> 'DR'
       
  1182               AND iol.movementqty > 0
       
  1183               AND iol.canceled_inoutline_id IS NULL
       
  1184               AND r.created = (
       
  1185                 SELECT max(created)
       
  1186                 FROM M_RESERVATION
       
  1187                 WHERE c_orderline_id = r.c_orderline_id
       
  1188                 AND res_status <> 'DR'
       
  1189               )
       
  1190 	      GROUP BY r.m_reservation_id, r.ad_client_id, r.ad_org_id,
       
  1191 	      r.m_product_id, r.quantity, r.c_uom_id, r.c_orderline_id, r.ad_user_id,
       
  1192 	      r.c_bpartner_id, r.m_warehouse_id, r.m_attributesetinstance_id, r.m_locator_id,
       
  1193 	      r.reservedqty, r.res_status, r.managereservation_pe, r.reservedgoodmnt_pe, ol.qtyordered
       
  1194             )
       
  1195 	    LOOP
       
  1196 
       
  1197 	      -- Get the least quantity between ordered quantity and movement quantity
       
  1198 	      v_R_Quantity := LEAST(Cur_Reservation.qtyordered, Cur_Reservation.movementqty);
       
  1199 
       
  1200               -- If completed reservation exists already update it,
       
  1201               -- otherwise create a new one with this quantity
       
  1202               IF (Cur_Reservation.res_status <> 'CL') THEN
       
  1203                 v_reservation_id := Cur_Reservation.m_reservation_id;
       
  1204                 v_R_Reservedqty := Cur_Reservation.reservedqty;
       
  1205               ELSE
       
  1206                 v_reservation_id := get_uuid();
       
  1207                 v_R_Reservedqty := 0;
       
  1208                 INSERT INTO M_RESERVATION (
       
  1209                   m_reservation_id, ad_client_id, ad_org_id, isactive,
       
  1210                   created, createdby, updated, updatedby,
       
  1211                   m_product_id, quantity, c_uom_id, c_orderline_id,
       
  1212                   ad_user_id, c_bpartner_id, m_warehouse_id, m_attributesetinstance_id, m_locator_id,
       
  1213                   res_status, res_process, managereservation_pe, reservedgoodmnt_pe
       
  1214                 ) VALUES (
       
  1215                   v_reservation_id, Cur_Reservation.ad_client_id, Cur_Reservation.ad_org_id, 'Y',
       
  1216                   now(), v_user, now(), v_user,
       
  1217                   Cur_Reservation.m_product_id, Cur_Reservation.qtyordered, Cur_Reservation.c_uom_id, Cur_Reservation.c_orderline_id,
       
  1218                   Cur_Reservation.ad_user_id, Cur_Reservation.c_bpartner_id, Cur_Reservation.m_warehouse_id,
       
  1219                   Cur_Reservation.m_attributesetinstance_id, Cur_Reservation.m_locator_id,
       
  1220                   'DR', 'PR', Cur_Reservation.managereservation_pe, Cur_Reservation.reservedgoodmnt_pe
       
  1221                 );
       
  1222                 -- To avoid create a reservation with all available stock,
       
  1223                 -- process new reservation before creating new stock reservations
       
  1224                 -- and delete stock reservation created by m_reserve_stock_manual
       
  1225                 M_RESERVATION_POST(null, v_reservation_id, 'PR', v_user);
       
  1226                 UPDATE M_RESERVATION_STOCK SET releasedqty = 0 WHERE m_reservation_id = v_reservation_id;
       
  1227                 DELETE FROM M_RESERVATION_STOCK WHERE m_reservation_id = v_reservation_id;
       
  1228               END IF;
       
  1229 
       
  1230               -- Add a reservation stock fo each related inout line
       
  1231               FOR Cur_InOutLine IN (
       
  1232                 SELECT iol.m_locator_id, COALESCE(iol.m_attributesetinstance_id, '0') as m_attributesetinstance_id,
       
  1233                 sum(iol.movementqty) as movementqty
       
  1234                 FROM M_INOUTLINE iol
       
  1235                 WHERE iol.m_inout_id = Cur_InOut.m_inout_id
       
  1236                 AND iol.c_orderline_id = Cur_Reservation.c_orderline_id
       
  1237                 AND iol.m_product_id = Cur_Reservation.m_product_id
       
  1238                 AND iol.movementqty > 0
       
  1239                 AND iol.canceled_inoutline_id IS NULL
       
  1240                 GROUP BY iol.m_locator_id, COALESCE(iol.m_attributesetinstance_id, '0')
       
  1241               )
       
  1242               LOOP
       
  1243 
       
  1244                 -- Check if movement quantity is less or equals than ordered quantity,
       
  1245                 -- if so insert a new reservation stock with movement quantity,
       
  1246                 -- otherwise insert a new reservation stock with pending ordered quantity
       
  1247                 IF (Cur_InOutLine.movementqty <= v_R_Quantity) THEN
       
  1248                   v_RS_Quantity := Cur_InOutLine.movementqty;
       
  1249                 ELSE
       
  1250                   v_RS_Quantity := v_R_Quantity;
       
  1251                 END IF;
       
  1252                 v_R_Quantity := v_R_Quantity - v_RS_Quantity;
       
  1253 
       
  1254                 -- If completed reservation stock exists already update it
       
  1255                 -- by decreasing its releasedqty or by increasing its quantity,
       
  1256                 -- otherwise create a new one with this quantity
       
  1257                 SELECT count(*), max(rs.m_reservation_stock_id), max(rs.releasedqty)
       
  1258                 INTO v_countRS, v_reservationstock_id, v_RS_Releasedqty
       
  1259                 FROM M_RESERVATION_STOCK rs
       
  1260                 WHERE rs.m_reservation_id = v_reservation_id
       
  1261                 AND rs.m_locator_id = Cur_InOutLine.m_locator_id
       
  1262                 AND COALESCE(rs.m_attributesetinstance_id, '0') = Cur_InOutLine.m_attributesetinstance_id;
       
  1263 
       
  1264                 IF (v_countRS > 0) THEN
       
  1265                   IF (v_RS_Releasedqty > 0) THEN
       
  1266                     v_RS_Releasedqty := LEAST(v_RS_Releasedqty, v_RS_Quantity);
       
  1267                     UPDATE M_RESERVATION_STOCK
       
  1268                     SET releasedqty = releasedqty - v_RS_Releasedqty
       
  1269                     WHERE m_reservation_stock_id = v_reservationstock_id;
       
  1270                     v_RS_Quantity := v_RS_Quantity - v_RS_Releasedqty;
       
  1271                   END IF;
       
  1272                   IF (v_RS_Quantity > 0 AND Cur_Reservation.quantity >= v_R_Reservedqty + v_RS_Quantity) THEN
       
  1273                     UPDATE M_RESERVATION_STOCK
       
  1274                     SET quantity = quantity + v_RS_Quantity
       
  1275                     WHERE m_reservation_stock_id = v_reservationstock_id;
       
  1276                     v_R_Reservedqty := v_R_Reservedqty + v_RS_Quantity;
       
  1277                   END IF;
       
  1278                 ELSE
       
  1279                   INSERT INTO M_RESERVATION_STOCK (
       
  1280                     m_reservation_stock_id, ad_client_id, ad_org_id, isactive,
       
  1281                     created, createdby, updated, updatedby,
       
  1282                     m_reservation_id, quantity, isallocated,
       
  1283                     m_locator_id, m_attributesetinstance_id
       
  1284                   ) VALUES (
       
  1285                     get_uuid(), Cur_Reservation.ad_client_id, Cur_Reservation.ad_org_id, 'Y',
       
  1286                     now(), v_user, now(), v_user,
       
  1287                     v_reservation_id, v_RS_Quantity, 'N',
       
  1288                     Cur_InOutLine.m_locator_id, Cur_InOutLine.m_attributesetinstance_id
       
  1289                   );
       
  1290                   v_R_Reservedqty := v_R_Reservedqty + v_RS_Quantity;
       
  1291                 END IF;
       
  1292 
       
  1293                 -- Exit if we have reserved all pending ordered quantity
       
  1294                 IF (v_R_Quantity <= 0) THEN
       
  1295                   EXIT;
       
  1296                 END IF;
       
  1297 
       
  1298               END LOOP;
       
  1299             END LOOP;
       
  1300           END IF;
       
  1301 
  1237           -- Indicate as Reversal Transaction
  1302           -- Indicate as Reversal Transaction
  1238           v_ResultStr:='IndicateReversal';
  1303           v_ResultStr:='IndicateReversal';
  1239           UPDATE M_INOUT
  1304           UPDATE M_INOUT
  1240             SET Updated=now(),
  1305             SET Updated=now(),
  1241             UpdatedBy=v_User,
  1306             UpdatedBy=v_User,