// 檢查Locked 狀況 bool ValidateLocked(bool locked, MyInventoryRow current) { if (locked) // 檢查 核可 打勾情況 { if (current.IsEvaluatedDateNull() || current.EvaluatedDate.Year < 2000) { MessageBox.Show("此盤點單未曾估值!"); return(false); } return(true); } // 只有最後一張可以取消核可 int maxID = 0; try { maxID = (from r in m_DataSet.Inventory select r.InventoryID).Max(); } catch {} if (current.InventoryID != maxID) { if (current.IsEvaluatedDateNull() || current.EvaluatedDate.Year < 2000) { MessageBox.Show("此盤點單未曾估值 又不是最後一張, 請速處理!"); return(true); } MessageBox.Show("只有最後一張才能取消核可!"); return(false); } return(true); }
private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e) { DateTime maxDate = new DateTime(MyFunction.IntHeaderYear, 1, 1); MyInventoryRow rowIsnull = null; foreach (var r in m_DataSet.Inventory) { rowIsnull = r; if (r.RowState == DataRowState.Deleted) { continue; } if (!r.IsCheckDayNull()) { if (r.CheckDay >= maxDate) { maxDate = r.CheckDay.AddDays(1); // 設定盤點日為最大那張的加一天 } } if (r.Locked) { continue; } MessageBox.Show("有尚未核可的單子,無法新增盤點表!"); return; } if (rowIsnull == null) { MessageBox.Show("初值,请输入食材的盘点、金额和产品的本期"); prevVolumeColumn.Visible = false; dgvColumnCurrentIn.Visible = false; dgvColumnPrevStockVolume.Visible = false; StockMoneyColumn.ReadOnly = false; dgvColumnLostMoney.Visible = false; isFrist = true; } else { prevVolumeColumn.Visible = true; dgvColumnCurrentIn.Visible = true; dgvColumnPrevStockVolume.Visible = true; StockMoneyColumn.ReadOnly = true; dgvColumnLostMoney.Visible = true; isFrist = false; } if (maxDate.Year != MyFunction.IntHeaderYear) { MessageBox.Show("預計的盤點日超過資料年<" + MyFunction.HeaderYear + ">"); return; } this.inventoryBindingSource.AddNew(); DataGridViewRow row = dgvInventories.CurrentRow; DataGridViewCell cell = row.Cells["ColumnInventoryID"]; if (cell == null) { MessageBox.Show("程式或資料庫版本錯誤, <dgvInventories>沒有<ColumnInventoryID>!"); return; } if (Convert.IsDBNull(cell.Value)) { try { MyFunction.AddNewItem(dgvInventories, "ColumnInventoryID", "InventoryID", m_DataSet.Inventory); bindingNavigatorAddNewItem.Enabled = false; DataRowView rowView = row.DataBoundItem as DataRowView; var data = rowView.Row as MyInventoryRow; data.CheckDay = maxDate; // 盤點日 int inventoryID = data.InventoryID; // 從食材表中有Code的,加入vEDataSet.InventoryDetail foreach (var ingredient in m_DataSet.Ingredient) { if (ingredient.IsCodeNull()) { continue; } if (ingredient.Code <= 0) { continue; // 無代号食材不納入盤點 } var detail = m_DataSet.InventoryDetail.NewInventoryDetailRow(); detail.ID = Guid.NewGuid(); detail.IngredientID = ingredient.IngredientID; detail.InventoryID = inventoryID; m_DataSet.InventoryDetail.AddInventoryDetailRow(detail); } // 產品表中有Code的,加入vEDataSet.InventoryProducts foreach (var product in m_OrderSet.Product) { if (product.IsClassNull()) { continue; } if (product.Code <= 0) { continue; } var inventoryProducts = m_DataSet.InventoryProducts.NewInventoryProductsRow(); inventoryProducts.ID = Guid.NewGuid(); inventoryProducts.ProductID = product.ProductID; inventoryProducts.InventoryID = inventoryID; m_DataSet.InventoryProducts.AddInventoryProductsRow(inventoryProducts); } inventoryBindingSource.ResetBindings(false); // inventoryDetailBindingSource 會連動,不用自己呼叫 chBoxHide.Checked = false; // 初創立,要看到所有有產品碼的 } catch (Exception ex) { MessageBox.Show("新增時錯誤,原因<" + ex.Message + ">"); return; } } }
private void btnEvaluate_Click(object sender, EventArgs e) { // 先把螢幕內容存回 inventoryBindingSource.EndEdit(); DetailBindingSource(SaveToDataTable: true); try { DataRowView rowView = inventoryBindingSource.Current as DataRowView; if (rowView == null) { MessageBox.Show("沒有記錄,請先新增一筆!"); return; } var curr = rowView.Row as MyInventoryRow; var details = curr.GetInventoryDetailRows(); var productDetails = curr.GetInventoryProductsRows(); // 清除本單的進貨及金額 if (!isFrist) { foreach (var dRow in details) { dRow.StockMoney = 0; dRow.LostMoney = 0; dRow.CurrentIn = 0; } } MyInventoryRow prev = null; foreach (var r in m_DataSet.Inventory) // 找到前一張單子 { if (r.InventoryID >= curr.InventoryID) { continue; } if (prev == null) { prev = r; } else if (prev.InventoryID < r.InventoryID) { prev = r; } } if (prev == null) // 這是本年第一張 { //var detailTable = sQLVEDataSet.InventoryDetail.GetChanges() as SQLVEDataSet.InventoryDetailDataTable; //if (detailTable != null) inventoryDetailTableAdapter1.Update(sQLVEDataSet.InventoryDetail); //details = curr.GetInventoryDetailRows(); } else if (prev.IsCheckDayNull()) { MessageBox.Show("前期盤點單無日期,無法查找 進貨數量及估值!"); return; } else if (prev.Locked == false) { MessageBox.Show("前期" + prev.CheckDay.ToShortDateString() + "盤點單尚未核可, 本期估值無法進行!"); return; } else if (curr.IsCheckDayNull()) { MessageBox.Show("本盤點單無日期,無法查找 進貨數量及估值!"); return; } else if (curr.CheckDay.Year != MyFunction.IntHeaderYear) { MessageBox.Show("本單盤點日期有誤, 和資料年" + MyFunction.IntHeaderYear.ToString() + "不同,,無法查找 進貨數量及估值!"); return; } else if (curr.CheckDay.Date <= prev.CheckDay.Date) { MessageBox.Show("盤點單日期有誤, 比前期盤點表日期還早!"); return; } // 載入進貨單資料 if (m_VoucherAdapter == null) { m_VoucherAdapter = new MyVoucherAdapter(); m_VoucherAdapter.Fill(m_DataSet.Voucher); } if (m_VoucherDetailAdapter == null) { m_VoucherDetailAdapter = new MyVoucherDetailAdapter(); m_VoucherDetailAdapter.Fill(m_DataSet.VoucherDetail); } //inventoryBindingSource.SuspendBinding(); //inventoryDetailBindingSource.SuspendBinding(); // DataGridView是複雜Binding ,使用無效 // 算先進先出成本,暫存未計算成本的庫存量 Dictionary <int, CalcInventory> dicCalcStock = new Dictionary <int, CalcInventory>(); // 填CalcInventory 內容 if (prev != null) { foreach (var d in details) { CalcInventory inv = new CalcInventory(); int id = d.IngredientID; if (d.IsStockVolumeNull()) { inv.StockVolume = 0; } else { inv.StockVolume = d.StockVolume; } if (!d.IsAreaCodeNull()) { if (d.AreaCode == "???") { d.AreaCode = ""; // 清除??? ,後面再設上去 } } if (dicCalcStock.Keys.Contains(id)) // 表不正常, 重覆了 { d.Delete(); // 刪除重的這筆 } else { dicCalcStock.Add(id, inv); } } } // 找出期間的進貨單 DateTime prevDate = new DateTime(MyFunction.IntHeaderYear - 1, 12, 31); if (prev != null) { prevDate = prev.CheckDay.Date; // 盤點日當天的進貨單,都計入是本期的 } var vouchers = from vo in m_DataSet.Voucher where (!vo.IsStockTimeNull()) && (vo.StockTime.Date > prevDate) && (vo.StockTime.Date <= curr.CheckDay.Date) && (vo.IsRemovedNull() || (!vo.Removed)) orderby vo.StockTime descending select vo; // 計算本期進貨 if (isFrist) { } else { foreach (var vo in vouchers) { var ds = vo.GetVoucherDetailRows(); foreach (var d in ds) { if (d.IsIngredientIDNull()) { continue; } if (d.IsVolumeNull()) { continue; // 沒有數量 } if (d.Volume <= 0) { continue; } int id = d.IngredientID; var des = from de in details where de.IngredientID == id select de; if (des.Count() <= 0) { continue; // 盤點單找不到此食材 } var de1 = des.First(); double vol = (double)d.Volume; de1.CurrentIn += vol; CalcInventory inv = dicCalcStock[de1.IngredientID]; decimal dCost = 0; if (!d.IsCostNull()) { dCost = d.Cost; } inv.CurrInMoney += dCost; // 算出相對應庫存的成本 if (inv.StockVolume >= vol) { de1.StockMoney += dCost; inv.StockVolume -= vol; } else if (inv.StockVolume > 0) { de1.StockMoney += (dCost / (decimal)vol * (decimal)inv.StockVolume); // 小於 inv.StockVolume = 0; } } } } // 將前期盤點及位置 資料填入, 並計算多於進貨remainStock的成本 if (prev == null) { //foreach (SQLVEDataSet.InventoryDetailRow d in details) //{ // d.PrevStockVolume = 0; // CalcInventory inv = dicCalcStock[d.IngredientID]; // if (inv.StockVolume > 0) // RemainStockWarning(d, inv.StockVolume); // d.LostMoney = inv.CurrInMoney - d.StockMoney; // 沒有前期 //} //foreach (var p in productDetails) // p.PrevVolume = 0; try { DataRowView inventoryrow = inventoryBindingSource.Current as DataRowView; if (rowView == null) { return; } var inventory = rowView.Row as MyInventoryRow; inventory.IngredientsCost = 0; var detailrows = inventory.GetInventoryDetailRows(); foreach (var item in detailrows) { if (item.IsStockMoneyNull())//计算初值时,如果输入初值金额,就不估算,没有就估算 { var ingredientrows = from r in m_DataSet.Ingredient where r.IngredientID == item.IngredientID select r; // vEDataSet.Ingredient.Select("IngredientID=" + item.IngredientID); if (item.IsStockVolumeNull()) { continue; } if (ingredientrows.Count() == 0) { continue; } item.StockMoney = (decimal)(item.StockVolume * ingredientrows.First().Price); } else { if (item.StockMoney == 0) { continue; } if (item.IsStockVolumeNull() || item.StockVolume == 0) // 本年第一張 ,數量為0 , 金額不為0 ,不可 { item.StockMoney = 0; } } inventory.IngredientsCost += item.StockMoney; } // 產品不管是不是第一單,在下方都直接以 Volume*EvaluatedCost代入 } catch (Exception ex) { MessageBox.Show("错误:" + ex.Message); }; } else { // 找出食材前期值代入 var prevDetails = prev.GetInventoryDetailRows(); foreach (var d in details) { d.PrevStockVolume = 0; int dIngredientID = d.IngredientID; CalcInventory inv = dicCalcStock[dIngredientID]; double remainStock = inv.StockVolume; var ds = from r in prevDetails where r.IngredientID == dIngredientID select r; if (ds.Count() <= 0) { if (remainStock > 0) { RemainStockWarning(d, remainStock); } continue; } var p = ds.First(); if (!p.IsAreaCodeNull()) { if (d.IsAreaCodeNull() || d.AreaCode.Trim().Count() == 0) // 沒有位置資料才從前期代入 { d.AreaCode = p.AreaCode; } } if (!p.IsStockVolumeNull()) { d.PrevStockVolume = p.StockVolume; if (remainStock > 0) // 庫存量大於進貨量,所以從前一張盤點單算平均成本 { if (p.StockVolume > 0) { if (remainStock > p.StockVolume) { d.StockMoney += p.StockMoney; var ings = from r in m_DataSet.Ingredient where r.IngredientID == dIngredientID select r; if (ings.Count() > 0) { var ing = ings.First(); MessageBox.Show("產品<" + ing.Name + "> ,庫存量大於(本期進貨+前期庫存) " + (remainStock - p.StockVolume).ToString() + ing.Unit + ",多餘部分 估值為 0 !!!"); d.AreaCode = "???"; } } else { d.StockMoney += p.StockMoney / (decimal)p.StockVolume * (decimal)remainStock; } } else { RemainStockWarning(d, remainStock); } } } else { if (remainStock > 0) { RemainStockWarning(d, remainStock); } } // 計算損失金額, 必需在RemainStock計算完之後d.StockMoney才有值 if (!p.IsStockMoneyNull()) { d.LostMoney = inv.CurrInMoney + p.StockMoney - d.StockMoney; } else { d.LostMoney = inv.CurrInMoney - d.StockMoney; } } // 找出前期產品庫存值代入 var prevProducts = prev.GetInventoryProductsRows(); foreach (var pd in productDetails) { var ds = from r in prevProducts where r.ProductID == pd.ProductID select r; if (ds.Count() > 0) { var d = ds.First(); if (!d.IsVolumeNull()) { pd.PrevVolume = d.Volume; } } else { pd.PrevVolume = 0; } } } // 找出產品表.EvaluatedCost 計算產品Cost decimal productCost = 0; foreach (var pd in productDetails) { pd.Cost = 0m; if ((!pd.IsVolumeNull()) && pd.Volume > 0) { var ps = from r in m_OrderSet.Product where r.ProductID == pd.ProductID select r; if (ps.Count() > 0) { var p = ps.First(); if (!p.IsEvaluatedCostNull()) { pd.Cost = p.EvaluatedCost * (decimal)pd.Volume; productCost += pd.Cost; } } } } // 計算總食材庫材及損失 decimal ingredientsCost = 0, ingredientsLost = 0; foreach (var d in details) { if (!d.IsStockMoneyNull()) { ingredientsCost += d.StockMoney; } if (!d.IsLostMoneyNull()) { ingredientsLost += d.LostMoney; } } curr.IngredientsCost = Math.Round(ingredientsCost, 1); curr.IngredientsLost = Math.Round(ingredientsLost, 1); curr.ProductsCost = Math.Round(productCost, 1); curr.EvaluatedDate = DateTime.Now; inventoryBindingSource.ResetBindings(false); DetailBindingSource(SaveToDataTable: false); } catch (Exception ex) { MessageBox.Show("計算估值時發生錯誤,原因:" + ex.Message); } }