一般财务计算产品价格又很多方法,我这里做了几个供参考,实体属性主要是编号、数量、价格等,这里就不列出了。
/// <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; }