Example #1
0
 public object FindQuantityById(ReturnPoPK pk)
 {
     return ReturnPoDAO.FindQuantityById(pk);
 }
Example #2
0
        public object FindQuantityById(ReturnPoPK pk)
        {
            ObjectCriteria objectCriteria = new ObjectCriteria();
            objectCriteria.AddEqCriteria("ReturnPoPK.DepartmentId", pk.DepartmentId);
            objectCriteria.AddEqCriteria("ReturnPoPK.PurchaseOrderId", pk.PurchaseOrderId);
            objectCriteria.AddEqCriteria("ReturnPoPK.PurchaseOrderDetailId", pk.PurchaseOrderDetailId);

            IList list = FindAll(objectCriteria);
            long returnAmount = 0;
            foreach (ReturnPo returnPo in list)
            {
                returnAmount += returnPo.Quantity;
            }
            return returnAmount;
        }
        public PurchaseOrder Add(PurchaseOrder data)
        {
            /*var maxId = PurchaseOrderDAO.SelectSpecificType(null, Projections.Max("PurchaseOrderPK.PurchaseOrderId"));
            var purchaseOrderId = maxId == null ? 1 : (Int64.Parse(maxId.ToString()) + 1);*/
            string deptId = string.Format("{0:000}", CurrentDepartment.Get().DepartmentId);
            object maxId = PurchaseOrderDAO.SelectSpecificType(null, Projections.Max("PurchaseOrderPK.PurchaseOrderId"));
            string purchaseOrderId = "000000000001";
            if (maxId != null)
            {
                purchaseOrderId = string.Format("{0:000000000000000}", Int64.Parse(maxId.ToString()) + 1);
            }
            else
            {
                purchaseOrderId = deptId + "000000000001";
            }

            object maxReceptId = ReceiptDAO.SelectSpecificType(null, Projections.Max("ReceiptPK.ReceiptId"));
            string receiptId = "000000000001";
            if (maxReceptId != null)
            {
                receiptId = string.Format("{0:000000000000000}", Int64.Parse(maxReceptId.ToString()) + 1);
            }
            else
            {
                receiptId = deptId + "000000000001";
            }
            /*if(data.Receipts!= null && data.Receipts.Count > 0)
            {
                foreach (Receipt receipt in data.Receipts)
                {
                    receipt.ReceiptPK.ReceiptId = receiptId;
                    ReceiptDAO.Add(receipt);

                    // increase receiptId
                    receiptId = string.Format("{0:000000000000000}", Int64.Parse(receiptId.ToString()) + 1);
                }
            }*/
            /*var purchaseOrderId =
            if(purchaseOrderId==null)
            {
                string shortDateTime = DateTime.Now.ToString("yyMMdd");
                long departmentId = CurrentDepartment.Get().DepartmentId;
                purchaseOrderId = departmentId.ToString().PadLeft(3,'0') + shortDateTime + "0001";
            }
            else
            {
                // add max
                string purchaseCount = purchaseOrderId.Substring(purchaseOrderId.Length - 4);
                int nextPurchaseOrderIdNumber = int.Parse(purchaseCount) + 1;
                string nextPurchaseOrderId = nextPurchaseOrderIdNumber.ToString().PadLeft(4, '0');
                purchaseOrderId = purchaseOrderId.Substring(0, purchaseOrderId.Length - 4) + nextPurchaseOrderId;
            }*/
            PurchaseOrderPK purchaseOrderPk = new PurchaseOrderPK { DepartmentId = CurrentDepartment.Get().DepartmentId, PurchaseOrderId = purchaseOrderId };
            data.PurchaseOrderPK = purchaseOrderPk;
            data.UpdateDate = DateTime.Now;
            data.CreateDate = DateTime.Now;
            data.CreateId = ClientInfo.getInstance().LoggedUser.Name;
            data.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
            // add description
            string description = "";
            foreach (PurchaseOrderDetail detail in data.PurchaseOrderDetails)
            {
                description += detail.ProductMaster.ProductName+ " "+ System.Environment.NewLine;
            }
            data.PurchaseOrderDescription = description;

            // save customer
            Customer customer = data.Customer;

            bool isReturnOrder = IsReturnOrder(purchaseOrderPk.PurchaseOrderId,data.PurchaseOrderDetails);

            if(!isReturnOrder)
            {
                PurchaseOrderDAO.Add(data);
            }

            long id = 1;
            // create PurchaseOrderId for Undefined Purchase Order
            string undefinedPOId = null;
            long undefinedPODetailId = 1;
            foreach (PurchaseOrderDetail detail in data.PurchaseOrderDetails)
            {
                if (detail.PurchaseOrder != null
                   && detail.PurchaseOrder.PurchaseOrderPK!=null
                   && !string.IsNullOrEmpty(detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId)
                   && detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId.Equals("000"))
                {
                    undefinedPOId = deptId + "NA" + DateTime.Now.ToString("yyMMddHHmmss");
                    break;
                }
            }
            IDictionary<string,long> stockList = new Dictionary<string,long>();
            IDictionary<string, Product> productList = new Dictionary<string, Product>();
            foreach (PurchaseOrderDetail detail in data.PurchaseOrderDetails)
            {
                // nếu là hàng trả đổi
                if(     detail.PurchaseOrder!= null
                    && detail.PurchaseOrderDetailPK!= null
                    && !CheckUtility.IsNullOrEmpty(detail.PurchaseOrderDetailPK.PurchaseOrderId)
                    && !purchaseOrderId.Equals(detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId)
                    )
                {
                    // Hàng trả đổi
                    ReturnPo po = new ReturnPo();
                    po.CreateDate = DateTime.Now;
                    po.CreateId = ClientInfo.getInstance().LoggedUser.Name;
                    po.UpdateDate = DateTime.Now;
                    po.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                    ReturnPoPK poPK = new ReturnPoPK
                    {
                        DepartmentId = detail.PurchaseOrderDetailPK.DepartmentId,
                        PurchaseOrderId =
                            detail.PurchaseOrderDetailPK.PurchaseOrderId,
                        PurchaseOrderDetailId =
                            detail.PurchaseOrderDetailPK.PurchaseOrderDetailId,
                        CreateDate = DateTime.Now

                    };
                    po.ReturnPoPK = poPK;
                    po.Quantity = detail.Quantity;
                    if(detail.Price < 0)
                    {
                        po.Price = 0 - detail.Price;
                    }
                    else
                    {
                        po.Price = detail.Price;
                    }
                    po.ReturnDate = DateTime.Now;
                    po.Product = detail.Product;
                    if (detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId.Equals("000"))
                    {
                        po.ReturnPoPK.PurchaseOrderId = undefinedPOId;
                        po.ReturnPoPK.PurchaseOrderDetailId = undefinedPODetailId++;

                    }
                    else
                    {

                        long originAmount = FindOriginAmount(detail);
                        if (originAmount == 0)
                        {
                            throw new BusinessException("Có lỗi ở hoá đơn gốc, đề nghị kiểm tra");
                        }
                        long returnedQuantity = (long) ReturnPoDAO.FindQuantityById(poPK);
                        long currentReturnQuantity = returnedQuantity + po.Quantity;
                        if (originAmount < currentReturnQuantity)
                        {
                            throw new BusinessException(
                                "Lỗi :" + detail.Product.ProductMaster.ProductName +
                                " .Tổng cộng :" + originAmount +
                                " .Đã trả : " + returnedQuantity +
                                " .Số lượng muốn trả: " + po.Quantity + " !");
                        }
                    }

                    ObjectCriteria stockCrit = new ObjectCriteria();
                    stockCrit.AddEqCriteria("DepartmentStockPK.ProductId", detail.Product.ProductId);
                    IList deptStockList = DepartmentStockDAO.FindAll(stockCrit);
                    if (deptStockList != null && deptStockList.Count > 0)
                    {

                        bool hasPrdFound = false;
                        foreach (string productId in stockList.Keys)
                        {
                            if (productId.Equals(detail.Product.ProductId))
                            {
                                long qty = stockList[productId];
                                qty = qty + detail.Quantity;
                                stockList[productId] = qty;
                                hasPrdFound = true;
                                break;
                            }
                        }
                        if (!hasPrdFound)
                        {
                            stockList.Add(detail.Product.ProductId,detail.Quantity);
                            productList.Add(detail.Product.ProductId,detail.Product);
                        }
                    }
                    else
                    {
                        throw new BusinessException("Không có mặt hàng này trong kho. Xin vui lòng kiểm tra dữ liệu");
                    }
                    if(!isReturnOrder)
                    {
                        po.NextPurchaseOrderId = purchaseOrderId;
                    }
                    ReturnPoDAO.Add(po);
                    // go to next detail
                    continue;
                }

                /*var sql = new StringBuilder(FIND_STOCK_SQL);
                // load the stock
                var criteria = new ObjectCriteria(true);
                criteria.AddEqCriteria("s.DelFlg", CommonConstants.DEL_FLG_NO)
                        .AddEqCriteria("s.DepartmentStockPK.DepartmentId", CurrentDepartment.Get().DepartmentId)
                        .AddEqCriteria("pm.ProductMasterId", detail.ProductMaster.ProductMasterId)
                        .AddEqCriteria("s.Product.ProductId",detail.Product.ProductId);
                foreach (SQLQueryCriteria crit in criteria.GetQueryCriteria())
                {
                    sql.Append(" AND ")
                       .Append(crit.PropertyName)
                       .Append(" ")
                       .Append(crit.SQLString)
                       .Append(" :")
                       .Append(crit.PropertyName)
                       .Append(" ");
                }
                sql.Append(" ORDER BY s.CreateDate ASC");*/
                bool hasFound = false;
                foreach (string productId in stockList.Keys)
                {
                   if(productId.Equals(detail.Product.ProductId))
                   {
                       long qty = stockList[productId];
                       qty = qty - detail.Quantity;
                       stockList[productId] = qty;
                       hasFound = true;
                       break;
                   }
                }
                if(!hasFound)
                {
                    stockList.Add(detail.Product.ProductId,0-detail.Quantity);
                    productList.Add(detail.Product.ProductId, detail.Product);
                }

                detail.CreateDate = DateTime.Now;
                detail.UpdateDate = DateTime.Now;
                detail.CreateId = ClientInfo.getInstance().LoggedUser.Name;
                detail.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                var purchaseOrderDetailPk = new PurchaseOrderDetailPK{DepartmentId = CurrentDepartment.Get().DepartmentId, PurchaseOrderId = purchaseOrderId, PurchaseOrderDetailId = id++};
                detail.PurchaseOrderDetailPK = purchaseOrderDetailPk;
                detail.PurchaseOrder = data;
                PurchaseOrderDetailDAO.Add(detail);

                // create Receipt.
            }

            // if departmentstock needs update
            if(stockList.Keys.Count > 0)
            {
                IList departmentStockViewList = new ArrayList();
                // get stock by product master
                foreach (string productId in stockList.Keys)
                {
                    if(!InDepartmentStockViewList(departmentStockViewList,productId))
                    {
                        Product searchProduct = productList[productId];
                        ObjectCriteria pmCrit = new ObjectCriteria();
                        pmCrit.AddEqCriteria("ProductMaster.ProductMasterId", searchProduct.ProductMaster.ProductMasterId);
                        IList list = ProductDAO.FindAll(pmCrit);

                        IList searchPrdIds = new ArrayList();
                        foreach (Product product in list)
                        {
                            searchPrdIds.Add(product.ProductId);
                        }
                        ObjectCriteria crit = new ObjectCriteria();
                        crit.AddSearchInCriteria("DepartmentStockPK.ProductId", searchPrdIds);
                        IList deptStockList = DepartmentStockDAO.FindAll(crit);

                        DepartmentStockView stockView = new DepartmentStockView();
                        stockView.ProductMaster = searchProduct.ProductMaster;
                        SortByProductId(deptStockList);
                        stockView.DepartmentStocks = deptStockList;
                        departmentStockViewList.Add(stockView);
                    }
                }

                foreach (string productId in stockList.Keys)
                {
                    /*ObjectCriteria crit = new ObjectCriteria();
                    crit.AddEqCriteria("DepartmentStockPK.ProductId", productId);
                    IList list = DepartmentStockDAO.FindAll(crit);
                    if(list!=null && list.Count == 1)
                    {
                        DepartmentStock stock = (DepartmentStock) list[0];
                        stock.GoodQuantity += stockList[productId];
                        if (stock.GoodQuantity < 0)
                        {
                            // strange
                            throw new BusinessException("Số lượng trong kho không đáp ứng đủ số lượng bán cho sản phẩm có mã vạch: " + productId);
                        }
                        stock.Quantity += stockList[productId];
                        DepartmentStockDAO.Update(stock);
                    }
                    else
                    {
                        throw new DataLayerException(" Dữ liệu không đồng nhất");
                    }*/
                    if(InDepartmentStockViewList(departmentStockViewList,productId))
                    {

                        // get origin product id and minus first
                        DepartmentStockView view = GetDepartmentStockViewList(departmentStockViewList, productId);
                        long updateQty = stockList[productId];
                        DepartmentStock departmentStock = GetDepartmentStockFromView(view, productId);
                        // if stock has been negative
                        if (departmentStock.GoodQuantity < 0)
                        {
                            // accept negative quantity and process later
                            departmentStock.GoodQuantity += updateQty;
                            departmentStock.Quantity += updateQty;
                            continue;
                        }
                        long originUpdateQty = updateQty;
                        updateQty = departmentStock.GoodQuantity + updateQty;

                        // if not enough quantity and still remains update-needing quantity
                        if(updateQty < 0)
                        {
                            // empty the origin product id in stock
                            departmentStock.Quantity -= departmentStock.GoodQuantity;
                            departmentStock.GoodQuantity = 0;
                            // continue do minusing on other product id in stock;
                            foreach (DepartmentStock otherStock in view.DepartmentStocks)
                            {
                                if(otherStock.DepartmentStockPK.ProductId.Equals(departmentStock.DepartmentStockPK.ProductId))
                                {
                                    continue;
                                }
                                long backupUpdateQty = updateQty;
                                updateQty = otherStock.GoodQuantity + updateQty;
                                if(updateQty < 0)
                                {
                                    otherStock.Quantity -= otherStock.GoodQuantity;
                                    otherStock.GoodQuantity = 0;
                                }
                                else
                                {
                                    otherStock.GoodQuantity += backupUpdateQty;
                                    otherStock.Quantity += backupUpdateQty;
                                    break;
                                }
                            }
                            // if still remain, we accept the negative quantity
                            if(updateQty < 0)
                            {
                                departmentStock.GoodQuantity += updateQty;
                                departmentStock.Quantity += updateQty;
                            }
                        }
                        else // enough quantity
                        {
                            departmentStock.GoodQuantity += originUpdateQty;
                            departmentStock.Quantity += originUpdateQty;
                        }
                    }
                }

                // update stock
                foreach (DepartmentStockView departmentStockView in departmentStockViewList)
                {
                    foreach (DepartmentStock stock in departmentStockView.DepartmentStocks)
                    {
                        DepartmentStockDAO.Update(stock);
                    }
                }
            }

            return data;
        }
        void goodsSaleReturnView_SavePurchaseOrderEvent(object sender, GoodsSaleReturnEventArgs e)
        {
            try
                {
            // save return order to ReturnPo
            foreach (PurchaseOrderDetail purchaseOrderDetail in e.ReturnPurchaseOrderDetails)
            {

                    ReturnPo po = new ReturnPo();
                    po.CreateDate = DateTime.Now;
                    po.CreateId = ClientInfo.getInstance().LoggedUser.Name;
                    po.UpdateDate = DateTime.Now;
                    po.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                    ReturnPoPK poPK = new ReturnPoPK
                                          {
                                              DepartmentId = purchaseOrderDetail.PurchaseOrderDetailPK.DepartmentId,
                                              PurchaseOrderId =
                                                  purchaseOrderDetail.PurchaseOrderDetailPK.PurchaseOrderId,
                                              PurchaseOrderDetailId =
                                                  purchaseOrderDetail.PurchaseOrderDetailPK.PurchaseOrderDetailId,
                                              CreateDate = DateTime.Now

                                          };
                    po.ReturnPoPK = poPK;
                    po.Quantity = purchaseOrderDetail.Quantity;
                    po.ReturnDate = DateTime.Now;

                    long originAmount = FindOriginAmount(e.RefPurchaseOrder.PurchaseOrderDetails, purchaseOrderDetail);
                    if (originAmount == 0)
                    {
                        throw new BusinessException("Có lỗi ở hoá đơn gốc, đề nghị kiểm tra");
                    }
                    long returnedQuantity = (long) ReturnPoLogic.FindQuantityById(poPK);
                    long currentReturnQuantity = returnedQuantity + +po.Quantity;
                    if (originAmount < currentReturnQuantity)
                    {
                        throw new BusinessException(
                            "Lỗi :" + purchaseOrderDetail.Product.ProductMaster.ProductName +
                            " .Tổng cộng :" + originAmount +
                            " .Đã trả : " + returnedQuantity +
                            " .Số lượng muốn trả: " + po.Quantity + " !");
                    }

                    ObjectCriteria criteria = new ObjectCriteria();
                    criteria.AddEqCriteria("DepartmentStockPK.ProductId", purchaseOrderDetail.Product.ProductId);
                    IList deptStockList = DepartmentStockLogic.FindAll(criteria);
                    if(deptStockList!=null && deptStockList.Count > 0)
                    {

                        DepartmentStock departmentStock = (DepartmentStock)deptStockList[0];
                        departmentStock.GoodQuantity += po.Quantity;
                        departmentStock.Quantity += po.Quantity;
                        DepartmentStockLogic.Update(departmentStock);
                    }
                    else
                    {
                        throw new BusinessException("Không có mặt hàng này trong kho. Xin vui lòng kiểm tra dữ liệu");
                    }
                    ReturnPoLogic.Add(po);

                    }
            if (e.NextPurchaseOrder != null
                && e.NextPurchaseOrder.PurchaseOrderDetails!=null
                && e.NextPurchaseOrder.PurchaseOrderDetails.Count > 0)
            {
                PurchaseOrderLogic.Add(e.NextPurchaseOrder);
            }
                    e.HasErrors = false;
                }
            catch (Exception ex )
            {
                e.HasErrors = true;
                throw ex;
            }
        }
        public PurchaseOrder Add(PurchaseOrder data)
        {
            string deptId = string.Format("{0:000}", CurrentDepartment.Get().DepartmentId);
            object maxId = PurchaseOrderDAO.SelectSpecificType(null, Projections.Max("PurchaseOrderPK.PurchaseOrderId"));
            string purchaseOrderId = "000000000001";
            if (maxId != null)
            {
                purchaseOrderId = string.Format("{0:000000000000000}", Int64.Parse(maxId.ToString()) + 1);
            }
            else
            {
                long tempId = ClientSetting.MaxPOId;
                if(tempId ==1)
                {
                    purchaseOrderId = deptId + "000000000001";
                }
                else
                {
                    purchaseOrderId = string.Format("{0:000000000000000}", Int64.Parse(tempId.ToString()) + 1);
                }

            }
            ClientSetting.MaxPOId = Int64.Parse(purchaseOrderId);
            ClientSetting.Save();
            object maxReceptId = ReceiptDAO.SelectSpecificType(null, Projections.Max("ReceiptPK.ReceiptId"));
            string receiptId = "000000000001";
            if (maxReceptId != null)
            {
                receiptId = string.Format("{0:000000000000000}", Int64.Parse(maxReceptId.ToString()) + 1);
            }
            else
            {
                receiptId = deptId + "000000000001";
            }

            PurchaseOrderPK purchaseOrderPk = new PurchaseOrderPK { DepartmentId = CurrentDepartment.Get().DepartmentId, PurchaseOrderId = purchaseOrderId };
            data.PurchaseOrderPK = purchaseOrderPk;
            data.UpdateDate = DateTime.Now;
            data.CreateDate = DateTime.Now;
            data.CreateId = ClientInfo.getInstance().LoggedUser.Name;
            data.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
            // add description
            string description = "";
            foreach (PurchaseOrderDetail detail in data.PurchaseOrderDetails)
            {
                description += detail.ProductMaster.ProductName+ " "+ System.Environment.NewLine;
            }
            data.PurchaseOrderDescription = description;

            // save customer
            Customer customer = data.Customer;

            bool isReturnOrder = IsReturnOrder(purchaseOrderPk.PurchaseOrderId,data.PurchaseOrderDetails);

            if(!isReturnOrder)
            {
                PurchaseOrderDAO.Add(data);
            }

            long id = 1;
            // create PurchaseOrderId for Undefined Purchase Order
            string undefinedPOId = null;
            long undefinedPODetailId = 1;
            foreach (PurchaseOrderDetail detail in data.PurchaseOrderDetails)
            {
                if (detail.PurchaseOrder != null
                   && detail.PurchaseOrder.PurchaseOrderPK!=null
                   && !string.IsNullOrEmpty(detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId)
                   && detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId.Equals("000"))
                {
                    undefinedPOId = deptId + "NA" + DateTime.Now.ToString("yyMMddHHmmss");
                    break;
                }
            }
            IDictionary<string,long> stockList = new Dictionary<string,long>();
            IDictionary<string, Product> productList = new Dictionary<string, Product>();
            foreach (PurchaseOrderDetail detail in data.PurchaseOrderDetails)
            {
                PurchaseOrderDetailPK currDetailKey = detail.PurchaseOrderDetailPK;
                // nếu là hàng trả đổi có xác định hóa đơn
                if(     detail.PurchaseOrder!= null
                    && currDetailKey != null
                    && !CheckUtility.IsNullOrEmpty(currDetailKey.PurchaseOrderId)
                    && !purchaseOrderId.Equals(detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId)
                    )
                {
                    // Hàng trả đổi

                    ReturnPo po = new ReturnPo();
                    po.CreateDate = DateTime.Now;
                    po.CreateId = ClientInfo.getInstance().LoggedUser.Name;
                    po.UpdateDate = DateTime.Now;
                    po.UpdateId = ClientInfo.getInstance().LoggedUser.Name;

                    ReturnPoPK poPK = new ReturnPoPK
                    {
                        DepartmentId = detail.PurchaseOrderDetailPK.DepartmentId,
                        PurchaseOrderId =
                            detail.PurchaseOrderDetailPK.PurchaseOrderId,
                        PurchaseOrderDetailId =
                            detail.PurchaseOrderDetailPK.PurchaseOrderDetailId,
                        CreateDate = DateTime.Now

                    };

                    po.ReturnPoPK = poPK;
                    po.Quantity = detail.Quantity;
                    if(detail.Price < 0)
                    {
                        po.Price = 0 - detail.Price;
                    }
                    else
                    {
                        po.Price = detail.Price;
                    }

                    po.ReturnDate = DateTime.Now;
                    po.Product = detail.Product;

                    // hàng trả không xác định
                    if (detail.PurchaseOrder.PurchaseOrderPK.PurchaseOrderId.Equals("000"))
                    {
                        po.ReturnPoPK.PurchaseOrderId = undefinedPOId;
                        po.ReturnPoPK.PurchaseOrderDetailId = undefinedPODetailId++;

                    }
                    else // hàng trả có xác định
                    {
                        // xác định số hàng đã trả so với hóa đơn gốc.
                        long originAmount = FindOriginAmount(detail);
                        if (originAmount == 0)
                        {
                            throw new BusinessException("Có lỗi ở hoá đơn gốc, đề nghị kiểm tra");
                        }
                        long returnedQuantity = (long) ReturnPoDAO.FindQuantityById(poPK);
                        long currentReturnQuantity = returnedQuantity + po.Quantity;
                        if (originAmount < currentReturnQuantity)
                        {
                            throw new BusinessException(
                                "Lỗi :" + detail.Product.ProductMaster.ProductName +
                                " .Tổng cộng :" + originAmount +
                                " .Đã trả : " + returnedQuantity +
                                " .Số lượng muốn trả: " + po.Quantity + " !");
                        }
                    }

                    ObjectCriteria stockCrit = new ObjectCriteria();
                    stockCrit.AddEqCriteria("DepartmentStockPK.ProductId", detail.Product.ProductId);
                    IList deptStockList = DepartmentStockDAO.FindAll(stockCrit);
                    if (deptStockList != null && deptStockList.Count > 0)
                    {

                        bool hasPrdFound = false;
                        foreach (string productId in stockList.Keys)
                        {
                            if (productId.Equals(detail.Product.ProductId))
                            {
                                long qty = stockList[productId];
                                qty = qty + detail.Quantity;
                                stockList[productId] = qty;
                                hasPrdFound = true;
                                break;
                            }
                        }
                        if (!hasPrdFound)
                        {
                            stockList.Add(detail.Product.ProductId,detail.Quantity);
                            productList.Add(detail.Product.ProductId,detail.Product);
                        }
                    }
                    else
                    {
                        throw new BusinessException("Không có mặt hàng này trong kho. Xin vui lòng kiểm tra dữ liệu");
                    }
                    if(!isReturnOrder)
                    {
                        po.NextPurchaseOrderId = purchaseOrderId;
                    }
                    ReturnPoDAO.Add(po);
                    // go to next detail
                    continue;
                }

                bool hasFound = false;
                foreach (string productId in stockList.Keys)
                {
                   if(productId.Equals(detail.Product.ProductId))
                   {
                       long qty = stockList[productId];
                       qty = qty - detail.Quantity;
                       stockList[productId] = qty;
                       hasFound = true;
                       break;
                   }
                }
                if(!hasFound)
                {
                    // add update quantity under a negative number
                    stockList.Add(detail.Product.ProductId,0-detail.Quantity);
                    productList.Add(detail.Product.ProductId, detail.Product);
                }

                detail.CreateDate = DateTime.Now;
                detail.UpdateDate = DateTime.Now;
                detail.CreateId = ClientInfo.getInstance().LoggedUser.Name;
                detail.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                var purchaseOrderDetailPk = new PurchaseOrderDetailPK{DepartmentId = CurrentDepartment.Get().DepartmentId, PurchaseOrderId = purchaseOrderId, PurchaseOrderDetailId = id++};
                detail.PurchaseOrderDetailPK = purchaseOrderDetailPk;
                detail.PurchaseOrder = data;
                PurchaseOrderDetailDAO.Add(detail);

                // create Receipt.
            }

            // if departmentstock needs update
            if(stockList.Keys.Count > 0)
            {
                IList departmentStockViewList = new ArrayList();
                // get stock by product master
                foreach (string productId in stockList.Keys)
                {
                    if(!InDepartmentStockViewList(departmentStockViewList,productId))
                    {
                        Product searchProduct = productList[productId];
                        ObjectCriteria pmCrit = new ObjectCriteria();
                        pmCrit.AddEqCriteria("ProductMaster.ProductMasterId", searchProduct.ProductMaster.ProductMasterId);
                        IList list = ProductDAO.FindAll(pmCrit);

                        IList searchPrdIds = new ArrayList();
                        foreach (Product product in list)
                        {
                            searchPrdIds.Add(product.ProductId);
                        }
                        ObjectCriteria crit = new ObjectCriteria();
                        crit.AddSearchInCriteria("DepartmentStockPK.ProductId", searchPrdIds);
                        IList deptStockList = DepartmentStockDAO.FindAll(crit);

                        DepartmentStockView stockView = new DepartmentStockView();
                        stockView.ProductMaster = searchProduct.ProductMaster;
                        ((ArrayList)deptStockList).Sort();
                        stockView.DepartmentStocks = deptStockList;
                        departmentStockViewList.Add(stockView);
                    }
                }

                bool allowTempNegativeSelling = false;
                // slide id selling
                foreach (string productId in stockList.Keys)
                {

                    if(InDepartmentStockViewList(departmentStockViewList,productId))
                    {

                        // get origin product id and minus first
                        DepartmentStockView view = GetDepartmentStockViewList(departmentStockViewList, productId);
                        long updateQty = stockList[productId];
                        long originUpdateQty = updateQty;
                        DepartmentStock departmentStock = GetDepartmentStockFromView(view, productId);
                        // if stock has been negative
                        if (departmentStock.GoodQuantity <= 0)
                        {
                            // FIX : Using negative update setting
                            // accept negative quantity and process later
                            if (ClientSetting.NegativeSelling)
                            {
                                departmentStock.GoodQuantity += updateQty;
                                departmentStock.Quantity += updateQty;
                                continue;
                            }

                            // END FIX
                        }
                        else // do minusing to stock
                        {
                            updateQty = departmentStock.GoodQuantity + updateQty;
                        }

                        // if not enough quantity and still remains update-needing quantity
                        if(updateQty < 0)
                        {
                            // empty the origin product id in stock
                            departmentStock.Quantity -= departmentStock.GoodQuantity;
                            departmentStock.GoodQuantity = 0;
                            // continue do minusing on other product id in stock;
                            foreach (DepartmentStock otherStock in view.DepartmentStocks)
                            {
                                if(otherStock.DepartmentStockPK.ProductId.Equals(departmentStock.DepartmentStockPK.ProductId))
                                {
                                    continue;
                                }
                                long backupUpdateQty = updateQty;
                                updateQty = otherStock.GoodQuantity + updateQty;
                                if(updateQty < 0)
                                {
                                    otherStock.Quantity -= otherStock.GoodQuantity;
                                    otherStock.GoodQuantity = 0;
                                }
                                else
                                {
                                    otherStock.GoodQuantity += backupUpdateQty;
                                    otherStock.Quantity += backupUpdateQty;
                                    break;
                                }
                            }
                            // FIX : Do not accept negative quantity
                            // if still remain, we accept the negative quantity
                            if(updateQty < 0)
                            {

                                if (!ClientSetting.NegativeSelling)
                                {
                                    throw new BusinessException("Mặt hàng " +
                                                                departmentStock.Product.ProductMaster.ProductName +
                                                                " đã hết.");
                                }
                                else
                                {
                                    if (allowTempNegativeSelling == false)
                                    {
                                        // confirm before save
                                        DialogResult isConfirmed = System.Windows.Forms.DialogResult.Cancel;
                                        if (!ClientSetting.ConfirmByEmployeeId)
                                        {
                                            LoginForm loginForm =
                                                GlobalUtility.GetFormObject<LoginForm>(FormConstants.CONFIRM_LOGIN_VIEW);
                                            loginForm.ConfirmNegativeSelling = true;
                                            loginForm.StartPosition = FormStartPosition.CenterScreen;
                                            isConfirmed = loginForm.ShowDialog();
                                        }
                                        else
                                        {
                                            EmployeeCheckingForm employeeCheckingForm =
                                                GlobalUtility.GetFormObject<EmployeeCheckingForm>(
                                                    FormConstants.EMPLOYEE_CHECKING_VIEW);
                                            employeeCheckingForm.StartPosition = FormStartPosition.CenterScreen;
                                            isConfirmed = employeeCheckingForm.ShowDialog();
                                        }
                                        if (isConfirmed != System.Windows.Forms.DialogResult.OK)
                                        {
                                            throw new BusinessException("Không xác nhận được nguoi gửi ....");
                                        }
                                        else
                                        {
                                            allowTempNegativeSelling = true;
                                        }
                                    }

                                    departmentStock.GoodQuantity += updateQty;
                                    departmentStock.Quantity += updateQty;
                                }
                            }
                            // END FIX
                        }
                        else // enough quantity
                        {
                            departmentStock.GoodQuantity += originUpdateQty;
                            departmentStock.Quantity += originUpdateQty;
                        }
                    }
                }

                // update stock
                foreach (DepartmentStockView departmentStockView in departmentStockViewList)
                {
                    foreach (DepartmentStock stock in departmentStockView.DepartmentStocks)
                    {
                        DepartmentStockDAO.Update(stock);
                    }
                }
            }

            return data;
        }