CREATE PROC GEX_RESETINVMONTHCOST_V2 ( @YY1 INTEGER, --計算月加權的西元年/月 @MM1 INTEGER, @LOGINID VARCHAR(30) ) /* Function : 計算進銷存的月加權 V2 的版本是考慮多階 BOM 的成本累計計算 因為考慮到效能的問題, 所以仍保留原版本 Description: 20100726 MICHAEL 有變更 SP 的名稱 Build Date : 2011/07/13 Modify History Item Who Date Modify Docs ==== ========== ========== ================================================ 1 Michael 2011/07/13 加入多選機制 2 Michael 2012/05/21 修改月加權計算時, 前期無資料的問題修改 3 Michael 2012/06/01 新增產品組合單的母件成本計算 目前還有2個問題, 目前版本只能處理一階的組合, 也就是說組合單表身不能是母件 另外一個問題是, 若母件又有進貨且有組合單, 成本目前取進貨成本 4 Michael 2013/03/08 新增 INVSTKBILL7_D,CRMMAINTAIN1_D 的回寫 NOWCOST 作業 */ AS -- -- 將本期資料刪除 DELETE FROM BASPRODMONTHCOST WHERE YEAR(CAST ( YEARMONTH + '01' AS DATETIME)) = @YY1 AND MONTH(CAST (YEARMONTH + '01' AS DATETIME)) = @MM1 -- SELECT A.PRODUCTID, SUM(A.QUANTITY) AS QTY1 INTO #STK31 FROM INVSTKBILL3_D A LEFT JOIN INVSTKBILL3_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 AND PRODUCTID NOT IN ( SELECT M_PRODID FROM MRPBOM_M ) GROUP BY A.PRODUCTID SELECT A.PRODUCTID, SUM(A.QUANTITY*PRICE*CURRRATE) AS AMT1,SUM(A.QUANTITY) AS QTY3 INTO #STK32 FROM INVSTKBILL3_D A LEFT JOIN INVSTKBILL3_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 AND PRODUCTID NOT IN ( SELECT M_PRODID FROM MRPBOM_M ) AND ADJUSTMETHOD > 0 GROUP BY A.PRODUCTID --組合單(子件減) SELECT A.PRODUCTID,SUM(A.QUANTITY)*-1 QTY71 INTO #STK71 FROM INVSTKBILL7_D A INNER JOIN INVSTKBILL7_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 GROUP BY A.PRODUCTID --維修單用料 SELECT A.PRODUCTID,SUM(A.QUANTITY)*-1 QTY73 INTO #STK73 FROM CRMMAINTAIN1_D A INNER JOIN CRMMAINTAIN1_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 GROUP BY A.PRODUCTID --組合單(母件增) SELECT A.M_PRODID PRODUCTID,SUM(A.STANDARDBATCHQTY) QTY72,SUM(A.STANDARDBATCHQTY*A.M_PRODCOST) AMT1 INTO #STK72 FROM INVSTKBILL7_M A WHERE YEAR(A.BILLDATE) = @YY1 AND MONTH(A.BILLDATE) = @MM1 GROUP BY A.M_PRODID; WITH INV1 AS ( SELECT A.PRODUCTID, SUM(A.QUANTITY) AS QTY1,SUM(A.QUANTITY*(PRICE+UNDER_VALUE)*CURRRATE) AS AMT1,SUM(A.QUANTITY) AS QTY3 FROM INVSTKBILL1_D A LEFT JOIN INVSTKBILL1_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 AND PRODUCTID NOT IN ( SELECT M_PRODID FROM MRPBOM_M ) GROUP BY A.PRODUCTID ), INV2 AS ( SELECT A.PRODUCTID, SUM(A.QUANTITY)*-1 AS QTY1,SUM(A.QUANTITY*PRICE*CURRRATE)*-1 AS AMT1,SUM(A.QUANTITY)*-1 AS QTY3 FROM INVSTKBILL2_D A LEFT JOIN INVSTKBILL2_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 AND PRODUCTID NOT IN ( SELECT M_PRODID FROM MRPBOM_M ) GROUP BY A.PRODUCTID ), INV3_DATA AS ( SELECT DISTINCT PRODUCTID FROM #STK31 UNION ALL SELECT DISTINCT PRODUCTID FROM #STK71 UNION ALL SELECT DISTINCT PRODUCTID FROM #STK72 UNION ALL SELECT DISTINCT PRODUCTID FROM #STK73 ), INV3_PROD AS ( SELECT DISTINCT PRODUCTID FROM INV3_DATA ), INV3 AS ( SELECT Z.PRODUCTID, ISNULL(A.QTY1,0)+ISNULL(C.QTY71,0)+ISNULL(D.QTY72,0)+ISNULL(E.QTY73,0) QTY1, ISNULL(B.AMT1,0)+ISNULL(D.AMT1,0) AMT1, ISNULL(B.QTY3,0)+ISNULL(D.QTY72,0) QTY3 FROM INV3_PROD Z LEFT JOIN #STK31 A ON Z.PRODUCTID = A.PRODUCTID LEFT JOIN #STK32 B ON Z.PRODUCTID = B.PRODUCTID LEFT JOIN #STK71 C ON Z.PRODUCTID = C.PRODUCTID LEFT JOIN #STK72 D ON Z.PRODUCTID = D.PRODUCTID LEFT JOIN #STK73 E ON Z.PRODUCTID = E.PRODUCTID ), INV5 AS ( SELECT A.PRODUCTID, SUM(A.QUANTITY)*-1 AS QTY1,0 AS AMT1,0 AS QTY3 FROM INVSTKBILL5_D A LEFT JOIN INVSTKBILL5_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 AND PRODUCTID NOT IN ( SELECT M_PRODID FROM MRPBOM_M ) GROUP BY A.PRODUCTID ), INV6 AS ( SELECT A.PRODUCTID, SUM(A.QUANTITY) AS QTY1,0 AS AMT1,0 AS QTY3 FROM INVSTKBILL6_D A LEFT JOIN INVSTKBILL6_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 AND PRODUCTID NOT IN ( SELECT M_PRODID FROM MRPBOM_M ) GROUP BY A.PRODUCTID ), FINAL99 AS ( SELECT * FROM INV1 UNION ALL SELECT * FROM INV2 UNION ALL SELECT * FROM INV3 UNION ALL SELECT * FROM INV5 UNION ALL SELECT * FROM INV6 ), FINALOK AS ( SELECT PRODUCTID,SUM(QTY1) AS QTY1,SUM(AMT1) AS AMT1,SUM(QTY3) AS QTY3 FROM FINAL99 GROUP BY PRODUCTID ) -- 材料金額(進銷存) -- qty1 本期總進,調,組數量 -- amt1 本期會影響成本的單據總金額 -- qty3 本期會影響成本的單據總數量 -- amt3 本期成本 -- qty2 上期數量 -- amt2 上期成本 SELECT IDENTITY(INT, 1,1) AS SEQNO,PRODUCTID,QTY1,AMT1,QTY3,QTY1*0 AS QTY2,AMT1*0 AS AMT2,AMT1*0 AS AMT3 INTO #AVGCOST FROM FINALOK -- update 上期成本及上期數量 UPDATE #AVGCOST SET QTY2=MONTHENDQTY, AMT2=MONTHAVGCOST FROM BASPRODMONTHCOST WHERE #AVGCOST.PRODUCTID = BASPRODMONTHCOST.PRODUCTID AND YEARMONTH =( SELECT MAX(CAST(YEARMONTH AS INTEGER)) FROM BASPRODMONTHCOST WHERE CAST(YEARMONTH AS INTEGER) < (@YY1 *100 + @MM1) AND #AVGCOST.PRODUCTID = BASPRODMONTHCOST.PRODUCTID AND MONTHAVGCOST > 0 ) --update 本期成本 UPDATE #AVGCOST SET AMT3 = ROUND((AMT1+(QTY2*AMT2))/(QTY2+QTY3),6) WHERE (QTY2+QTY3) > 0 --防特殊狀況, 本月無影響成本的單據, 但是有數量, 成本為0, 此時應取前一有成本的月份資料 --只要本期成本有異(小於等於0), 就取上期成本, 取銷原本的數量判斷 UPDATE #AVGCOST SET AMT3 = AMT2 WHERE AMT3 <= 0 --AND ISNULL(QTY1,0)+ISNULL(QTY2,0) > 0 INSERT INTO BASPRODMONTHCOST (YEARMONTH, SEQNO, PRODUCTID, MONTHAVGCOST, MONTHENDQTY) SELECT CAST( (@YY1*100+@MM1) AS VARCHAR(6)),SEQNO, PRODUCTID, ISNULL(AMT3,0), ISNULL(QTY1,0)+ISNULL(QTY2,0) FROM #AVGCOST WHERE PRODUCTID IS NOT NULL AND PRODUCTID <> '' --******************************** --以下開始計算產品組合單的母件成本 --******************************** EXEC GEX_CALCBOM_COST1 @YY1,@MM1,@LOGINID --***************************************** --等所有產品的月加權算好後, 再一起回寫原單 --***************************************** --取得當月所有產品的月加權 SELECT A.PRODUCTID,A.MONTHAVGCOST INTO #ALLCOST FROM ( SELECT PRODUCTID,MAX(YEARMONTH) MAX_YM FROM BASPRODMONTHCOST WHERE CAST(YEARMONTH AS INTEGER) <= (@YY1 *100 + @MM1) AND MONTHAVGCOST > 0 GROUP BY PRODUCTID ) Z LEFT JOIN BASPRODMONTHCOST A ON A.PRODUCTID = Z.PRODUCTID AND A.YEARMONTH = Z.MAX_YM --回寫原單成本 UPDATE INVSTKBILL1_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM INVSTKBILL1_D A LEFT JOIN INVSTKBILL1_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 UPDATE INVSTKBILL2_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM INVSTKBILL2_D A LEFT JOIN INVSTKBILL2_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 UPDATE INVSTKBILL3_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM INVSTKBILL3_D A LEFT JOIN INVSTKBILL3_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 UPDATE INVSTKBILL4_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM INVSTKBILL4_D A LEFT JOIN INVSTKBILL4_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 UPDATE INVSTKBILL5_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM INVSTKBILL5_D A LEFT JOIN INVSTKBILL5_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 UPDATE INVSTKBILL6_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM INVSTKBILL6_D A LEFT JOIN INVSTKBILL6_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 --ADD UPDATE INVSTKBILL7_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM INVSTKBILL7_D A LEFT JOIN INVSTKBILL7_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 UPDATE CRMMAINTAIN1_D SET NOWCOST = (SELECT ISNULL(MONTHAVGCOST,0) FROM #ALLCOST WHERE A.PRODUCTID = #ALLCOST.PRODUCTID) FROM CRMMAINTAIN1_D A LEFT JOIN CRMMAINTAIN1_M B ON A.BILLNO = B.BILLNO WHERE YEAR(B.BILLDATE) = @YY1 AND MONTH(B.BILLDATE) = @MM1 DROP TABLE #STK31 DROP TABLE #STK32 DROP TABLE #STK71 DROP TABLE #STK72 DROP TABLE #STK73 DROP TABLE #AVGCOST DROP TABLE #ALLCOST