/// <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成本核算基本程序是: 庫存系統月底根據日常業務進行審核結帳,通過取數你能得到相關的材料成本 賬務系統月底結帳後,你能得到相關的人工、動能、制造費用等相關成本 根據當月完工數量或者工時,在成本核算模塊進行數據錄入,確定完工及在產相關數據 最後運行核算模塊得出相關成本,根據相關成本在財務模塊轉帳,這樣成本核算就實現了