/// <summary> /// 先進先出算法 /// </summary> /// <param name="inRecord">入庫記錄(一個周期內)</param> /// <param name="outRecord">出庫記錄(一個周期內)</param> /// <returns>InventoryPrice為結果價格</returns> public List<BaseStock> ComputerPriceFIFO (List<BaseStock> inRecord, List<BaseStock> outRecord) { //排序 var inList = (from o in inRecord orderby o.CDate select o).ToList(); var outList = (from o in outRecord orderby o.CDate select o).ToList(); foreach (var outItem in outList) { //當前條已出部分金額 decimal money = 0; //當前還需出的數量 decimal qty = outItem.Qty; foreach (var inItem in inList) { //如果當前這一條夠出庫,那麼結束去計算價格 if (inItem.Qty > qty) { money = money + inItem.Price * qty; //更新入庫表 inItem.Qty = inItem.Qty - qty; break; } else { qty = qty - inItem.Qty; money = money + (inItem.Price * inItem.Qty); //更新入庫表 inItem.Qty = 0; } } //計算出貨價格 outItem.Price = money / outItem.Qty; } return outList; } /// <summary> /// 後進先出算法 /// </summary> /// <param name="inRecord">入庫記錄(一個周期內)</param> /// <param name="outRecord">出庫記錄(一個周期內)</param> /// <returns>InventoryPrice為結果價格</returns> public List<BaseStock> ComputerPriceFOFI (List<BaseStock> inRecord, List<BaseStock> outRecord) { //排序 var inList = (from o in inRecord orderby o.CDate descending select o).ToList(); var outList = (from o in outRecord orderby o.CDate select o).ToList(); foreach (var outItem in outList) { //當前條已出部分金額 decimal money = 0; //當前還需出的數量 decimal qty = outItem.Qty; foreach (var inItem in inList) { //如果當前這一條夠出庫,那麼結束去計算價格 if (inItem.Qty > qty) { money = money + inItem.Price * qty; //更新入庫表 inItem.Qty = inItem.Qty - qty; break; } else { qty = qty - inItem.Qty; money = money + (inItem.Price * inItem.Qty); //更新入庫表 inItem.Qty = 0; } } //計算出貨價格 outItem.Price = money / outItem.Qty; } return outList; } /// <summary> /// 加權平均算法 /// </summary> /// <param name="inRecord">入庫記錄(一個周期內)</param> /// <param name="outRecord">出庫記錄(一個周期內)</param> /// <param name="prePrice">上期價格</param> /// <param name="preQty">上期數量</param> /// <returns></returns> public List<BaseStock> ComputerPriceBalance (List<BaseStock> inRecord, List<BaseStock> outRecord, decimal prePrice, decimal preQty) { decimal money = 0; decimal qty = 0; foreach (var inItem in inRecord) { money = money + inItem.Price * inItem.Qty; qty = qty + inItem.Qty; } decimal price = (money + prePrice * preQty) / (qty + preQty); foreach (var outItem in outRecord) { outItem.Price = price; } return outRecord; } /// <summary> /// 移動加權平均算法 /// </summary> /// <param name="inRecord">入庫記錄(一個周期內)</param> /// <param name="outRecord">出庫記錄(一個周期內)</param> /// <param name="prePrice">上期價格</param> /// <param name="preQty">上期數量</param> /// <returns></returns> public List<BaseStock> ComputerPriceTrack (List<BaseStock> inRecord, List<BaseStock> outRecord, decimal prePrice, decimal preQty, DateTime preDate) { //排序 var outList = (from o in outRecord orderby o.CDate select o).ToList(); List<Guid> preDetail_IDs = new List<Guid>(); foreach (var outItem in outList) { //取出比當前出庫記錄要早的入庫記錄,並且排除已經結算的記錄 var inList = (from o in inRecord where o.CDate <= outItem.CDate && !preDetail_IDs.Contains(o.Detail_ID) orderby o.CDate select o).ToList(); decimal money = 0; decimal qty = 0; foreach (var inItem in inList) { money = money + inItem.Price * inItem.Qty; qty = qty + inItem.Qty; preDetail_IDs.Add(inItem.Detail_ID); } outItem.Price = (money + prePrice * preQty) / (qty + preQty); //修改上期價格和數量 prePrice = outItem.Price; preQty = qty - outItem.Qty; } return outList; }
其實ERP成本核算原理差不多,我以我們公司SAP為例,平時的成本核算是用標准成本的
即BOM + ROUTING,BOM就很明顯了,routing指的就是我們的人工和制造費用,每道工序都會有這個標准,然後再計算費率,這樣用標准人工工時*費用率就得到標准人工成本,制費也一樣的道理
月末進行成本結算,原理是標准+差異=實際成本,即財務報表上是以實際成本來反映,至於差異可以選擇分攤或者不分攤都是可以的。標准成本一般3個月或更長時間才會更新一次
我用過用友ERP,金蝶沒用過,但一般ERP成本核算基本程序是: 庫存系統月底根據日常業務進行審核結帳,通過取數你能得到相關的材料成本 賬務系統月底結帳後,你能得到相關的人工、動能、制造費用等相關成本 根據當月完工數量或者工時,在成本核算模塊進行數據錄入,確定完工及在產相關數據 最後運行核算模塊得出相關成本,根據相關成本在財務模塊轉帳,這樣成本核算就實現了