public void AddStockInBack(DepartmentStockIn data)
        {
            long deptId = data.DepartmentStockInPK.DepartmentId;
            string deptStr = "000";
            if (deptId > 9999)
            {
                deptStr = deptId.ToString();
            }
            else
            {
                deptStr = string.Format("{0:000}", data.DepartmentStockInPK.DepartmentId);
            }
            string dateStr = data.StockInDate.ToString("yyMMdd");
            var criteria = new ObjectCriteria();
            string extraZero = "00000";
            if(deptId > 9999)
            {
                extraZero = "000";
            }
            criteria.AddGreaterCriteria("DepartmentStockInPK.StockInId", dateStr + deptStr + extraZero);
            var maxId = DepartmentStockInDAO.SelectSpecificType(criteria,
                                                                Projections.Max("DepartmentStockInPK.StockInId"));
            string startNum = "00001";
            if(deptId > 9999)
            {
                startNum = "001";
            }
            var stockInId = maxId == null
                                ? dateStr + deptStr + startNum
                                : string.Format("{0:00000000000000}", (Int64.Parse(maxId.ToString()) + 1));

            var stockInPk = new DepartmentStockInPK {DepartmentId = deptId, StockInId = stockInId + ""};

            data.DepartmentStockInPK = stockInPk;
            data.CreateDate = DateTime.Now;
            data.UpdateDate = DateTime.Now;
            data.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
            data.CreateId = ClientInfo.getInstance().LoggedUser.Name;
            DepartmentStockInDAO.Add(data);

            // we will get the stock to get the data
            IList productMasterIds = new ArrayList();
            IList productIds = new ArrayList();
            foreach (DepartmentStockInDetail stockInDetail in data.DepartmentStockInDetails)
            {
                productIds.Add(stockInDetail.Product.ProductId);
            }

            criteria = new ObjectCriteria();
            criteria.AddEqCriteria("DelFlg", CommonConstants.DEL_FLG_NO);
            criteria.AddSearchInCriteria("DepartmentStockPK.ProductId", productIds);
            criteria.AddOrder("Product.ProductId", true);
            IList stockList = DepartmentStockDAO.FindAll(criteria);

            IList updateStockList = new ArrayList();
            IList stockInDetailList = new ArrayList();
            foreach (DepartmentStockInDetail stockInDetail in data.DepartmentStockInDetails)
            {
                long quantity = stockInDetail.Quantity;
                DepartmentStockPK stockPk = new DepartmentStockPK
                                                {
                                                    DepartmentId = deptId,
                                                    ProductId = stockInDetail.Product.ProductId
                                                };
                DepartmentStock departmentStock = DepartmentStockDAO.FindById(stockPk);

                if (departmentStock.DepartmentStockPK.ProductId.Equals(stockInDetail.Product.ProductId))
                {
                        departmentStock.GoodQuantity += stockInDetail.Quantity;
                        departmentStock.Quantity += stockInDetail.Quantity;
                        departmentStock.UpdateDate = DateTime.Now;
                        departmentStock.UpdateId = ClientInfo.getInstance().LoggedUser.Name;

                        DepartmentStockDAO.Update(departmentStock);

                        var pk = new DepartmentStockInDetailPK
                                     {
                                         DepartmentId = data.DepartmentStockInPK.DepartmentId,
                                         ProductId = departmentStock.Product.ProductId,
                                         StockInId = stockInId
                                     };
                        stockInDetail.DepartmentStockInDetailPK = pk;
                        DepartmentStockInDetailDAO.Add(stockInDetail);
                }
            }
        }
        public DepartmentStockIn Add(DepartmentStockIn data)
        {
            string deptStr = "";
            if(ClientSetting.IsSubStock())
            {
                deptStr = string.Format("{0:00000}", data.DepartmentStockInPK.DepartmentId);
            }
            else
            {
                deptStr = string.Format("{0:000}", data.DepartmentStockInPK.DepartmentId);
            }

            string dateStr = data.StockInDate.ToString("yyMMdd");
            var criteria = new ObjectCriteria();
            if(ClientSetting.IsSubStock())
            {
                criteria.AddGreaterCriteria("DepartmentStockInPK.StockInId", dateStr + deptStr + "000");
            }
            else
            {
                criteria.AddGreaterCriteria("DepartmentStockInPK.StockInId", dateStr + deptStr + "00000");
            }

            var maxId = DepartmentStockInDAO.SelectSpecificType(criteria, Projections.Max("DepartmentStockInPK.StockInId"));
            string stockInId = "";
            if(ClientSetting.IsSubStock())
            {
                stockInId = maxId == null ? dateStr + deptStr + "001" :   string.Format("{0:00000000000000}", (Int64.Parse(maxId.ToString()) + 1));
            }
            else
            {
                stockInId = maxId == null ? dateStr + deptStr + "00001" : string.Format("{0:00000000000000}", (Int64.Parse(maxId.ToString()) + 1));
            }

            var stockInPk = new DepartmentStockInPK {DepartmentId = data.DepartmentId, StockInId = stockInId + ""};

            data.DepartmentStockInPK = stockInPk;
            data.CreateDate = DateTime.Now;
            data.UpdateDate = DateTime.Now;
            data.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
            data.CreateId = ClientInfo.getInstance().LoggedUser.Name;
            DepartmentStockInDAO.Add(data);

            // we will get the stock to get the data
            IList productMasterIds = new ArrayList();
            foreach (DepartmentStockInDetail stockInDetail in data.DepartmentStockInDetails)
            {
                productMasterIds.Add(stockInDetail.Product.ProductMaster.ProductMasterId);
            }

            criteria = new ObjectCriteria();
            criteria.AddEqCriteria("DelFlg", CommonConstants.DEL_FLG_NO);
            criteria.AddGreaterCriteria("Quantity", (long)0);
            criteria.AddSearchInCriteria("ProductMaster.ProductMasterId", productMasterIds);
            criteria.AddOrder("ProductMaster.ProductMasterId", true);
            criteria.AddOrder("Product.ProductId", true);
            IList stockList = DepartmentStockDAO.FindAll(criteria);

            IList updateStockList = new ArrayList();
            IList stockInDetailList = new ArrayList();
            foreach (DepartmentStockInDetail stockInDetail in data.DepartmentStockInDetails)
            {
                long quantity = stockInDetail.Quantity;
                foreach (DepartmentStock stock in stockList)
                {
                    long stockInQty = 0;
                   if (stock.Product.ProductId.Equals(stockInDetail.ProductId) && stock.Quantity >= 0)
                    {
                        /*if (quantity >= stock.Quantity)
                        {
                            stockInQty = stock.Quantity;
                            quantity -= stock.Quantity;
                            stock.Quantity = 0;
                        }
                        else
                        {
                            stockInQty = quantity;
                            stock.Quantity -= quantity;
                            quantity = 0;
                        }*/
                        if (quantity >= stock.GoodQuantity)
                        {
                            stockInQty = stock.GoodQuantity;
                            quantity -= stock.GoodQuantity;
                            stock.GoodQuantity = 0;
                        }
                        else
                        {
                            stockInQty = quantity;
                            stock.GoodQuantity -= quantity;
                            quantity = 0;
                        }
                        stock.Quantity = stock.GoodQuantity + stock.ErrorQuantity + stock.DamageQuantity +
                                         stock.LostQuantity + stock.UnconfirmQuantity;
                        stock.UpdateDate = DateTime.Now;
                        stock.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                        updateStockList.Add(stock);
                        var pk = new DepartmentStockInDetailPK
                                   {
                                       DepartmentId = data.DepartmentId,
                                       ProductId = stock.Product.ProductId,
                                       StockInId = stockInId
                                   };
                        var detail = new DepartmentStockInDetail
                        {
                            DepartmentStockInDetailPK = pk,
                            Quantity = stockInQty,
                            CreateDate = DateTime.Now,
                            UpdateDate = DateTime.Now,
                            UpdateId = ClientInfo.getInstance().LoggedUser.Name,
                            CreateId = ClientInfo.getInstance().LoggedUser.Name,
                            ProductMaster = stock.ProductMaster
                        };
                        var deptStock = new DepartmentStock
                                            {
                                                DepartmentStockPK = new DepartmentStockPK
                                                                        {
                                                                            DepartmentId = data.DepartmentId,
                                                                            ProductId = stock.Product.ProductId
                                                                        },
                                                CreateDate = DateTime.Now,
                                                UpdateDate = DateTime.Now,
                                                UpdateId = ClientInfo.getInstance().LoggedUser.Name,
                                                CreateId = ClientInfo.getInstance().LoggedUser.Name,
                                                ProductMaster = stock.ProductMaster
                                            };
                        stockInDetailList.Add(detail);
                        if (quantity == 0)
                        {
                            break;
                        }
                    }
                }
                if (quantity > 0)
                {
                    data.DepartmentStockInPK.StockInId = null;
                    throw new BusinessException("Số lượng xuất kho lớn hơn số lượng trong kho");
                }
            }

            foreach (DepartmentStockInDetail detail in stockInDetailList)
            {
                DepartmentStockInDetailDAO.Add(detail);
            }

            foreach (Stock stock in updateStockList)
            {
                StockDAO.Update(stock);
            }
            return data;
        }
        public void AddReStock(DepartmentStockIn data)
        {
            string deptStr = string.Format("{0:000}", data.DepartmentId);
            string dateStr = data.StockInDate.ToString("yyMMdd");
            var criteria = new ObjectCriteria();
            criteria.AddGreaterCriteria("DepartmentStockInPK.StockInId", dateStr + deptStr + "00000");
            var maxId = DepartmentStockInDAO.SelectSpecificType(criteria, Projections.Max("DepartmentStockInPK.StockInId"));
            var stockInId = maxId == null ? dateStr + deptStr + "00001" : string.Format("{0:00000000000000}", (Int64.Parse(maxId.ToString()) + 1));

            var stockInPk = new DepartmentStockInPK { DepartmentId = data.DepartmentId, StockInId = stockInId + "" };

            data.CreateDate = DateTime.Now;
            data.UpdateDate = DateTime.Now;
            data.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
            data.CreateId = ClientInfo.getInstance().LoggedUser.Name;
            data.StockInType = (long)1;
            data.DepartmentStockInPK = stockInPk;
            DepartmentStockInDAO.Add(data);

            foreach (DepartmentStockInDetail stockInDetail in data.DepartmentStockInDetails)
            {
                // add dept stock in
                var detailPK = new DepartmentStockInDetailPK
                { ProductId = stockInDetail.Product.ProductId,
                  StockInId = stockInId,
                  DepartmentId = data.DepartmentId};

                stockInDetail.DepartmentStockInDetailPK = detailPK;
                stockInDetail.CreateDate = DateTime.Now;
                stockInDetail.UpdateDate = DateTime.Now;
                stockInDetail.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                stockInDetail.CreateId = ClientInfo.getInstance().LoggedUser.Name;
                stockInDetail.ProductMaster = stockInDetail.Product.ProductMaster;

                //                    stockInDetail.CurrentStockQuantity = (sum == null) ? 0 : Int64.Parse(sum.ToString());
                DepartmentStockInDetailDAO.Add(stockInDetail);
                ObjectCriteria stockCriteria = new ObjectCriteria();
                stockCriteria.AddEqCriteria("DepartmentStockPK.ProductId", stockInDetail.Product.ProductId);
                stockCriteria.AddEqCriteria("DepartmentStockPK.DepartmentId", data.DepartmentId);
                IList stockList = DepartmentStockDAO.FindAll(stockCriteria);

                // decrease error and increase good
                if (stockList != null)
                {
                    DepartmentStock stock = (DepartmentStock)stockList[0];
                    stock.ErrorQuantity -= stockInDetail.Quantity;
                    stock.GoodQuantity += stockInDetail.Quantity;
                    stock.Quantity = stock.ErrorQuantity + stock.GoodQuantity + stock.DamageQuantity +
                                     stock.UnconfirmQuantity + stock.LostQuantity;
                    DepartmentStockDAO.Update(stock);
                }
            }
        }
        public LogicResult SyncFromSubStock(DepartmentStockIn stockIn)
        {
            LogicResult result = new LogicResult();
            result.HasError = false;
            string deptStr = string.Format("{0:000}", stockIn.DepartmentStockInPK.DepartmentId);
            string dateStr = stockIn.StockInDate.ToString("yyMMdd");
            var crit = new ObjectCriteria();
            crit.AddGreaterCriteria("DepartmentStockInPK.StockInId", dateStr + deptStr + "00000");
            var maxId = DepartmentStockInDAO.SelectSpecificType(crit, Projections.Max("DepartmentStockInPK.StockInId"));
            var stockInId = maxId == null ? dateStr + deptStr + "00001" : string.Format("{0:00000000000000}", (Int64.Parse(maxId.ToString()) + 1));

            var stockInPk = new DepartmentStockInPK
                                                    { DepartmentId = stockIn.DepartmentStockInPK.DepartmentId,
                                                      StockInId = stockInId + ""
                                                    };
            stockIn.DepartmentStockInPK = stockInPk;

            IList productMasterIds = new ArrayList();
            IList productIds = new ArrayList();
            IList priceList = new ArrayList();
            IList quantityList = new ArrayList();

            if(stockIn.DepartmentStockInDetails== null || stockIn.DepartmentStockInDetails.Count == 0)
            {
                result.HasError = true;
                result.Messages = new ArrayList();
                result.Messages.Add("Stock-in do not have details ?!?!");
                return result;
            }
            try
            {
                DepartmentStockIn DepartmentStockIn = DepartmentStockInDAO.FindById(stockIn.DepartmentStockInPK);
                if (DepartmentStockIn == null)
                {
                    DepartmentStockInDAO.Add(stockIn);
                }
                else
                {
                    ObjectCriteria criteria = new ObjectCriteria();

                    // currently we do not accept update department-stock-in in
                    //return;
                    // amend for debug
                    return result;
                }
                // put master data first
                foreach (DepartmentStockInDetail detail in stockIn.DepartmentStockInDetails)
                {
                    detail.DepartmentStockInDetailPK.StockInId = stockInId;
                    if (detail.Product.ProductMaster.ProductColor != null)
                    {
                        ProductColor color = ProductColorDAO.FindById(detail.Product.ProductMaster.ProductColor.ColorId);
                        if (color == null)
                        {
                            ProductColorDAO.Add(detail.Product.ProductMaster.ProductColor);
                        }
                    }
                    if (detail.Product.ProductMaster.ProductSize != null)
                    {
                        ProductSize Size = ProductSizeDAO.FindById(detail.Product.ProductMaster.ProductSize.SizeId);
                        if (Size == null)
                        {
                            ProductSizeDAO.Add(detail.Product.ProductMaster.ProductSize);
                        }
                    }
                    if (detail.Product.ProductMaster.ProductType != null)
                    {
                        ProductType Type = ProductTypeDAO.FindById(detail.Product.ProductMaster.ProductType.TypeId);
                        if (Type == null)
                        {
                            ProductTypeDAO.Add(detail.Product.ProductMaster.ProductType);
                        }
                    }
                    if (detail.Product.ProductMaster.Country != null)
                    {
                        Country Country = CountryDAO.FindById(detail.Product.ProductMaster.Country.CountryId);
                        if (Country == null)
                        {
                            CountryDAO.Add(detail.Product.ProductMaster.Country);
                        }
                    }
                    if (detail.Product.ProductMaster.Distributor != null)
                    {
                        Distributor Distributor =
                            DistributorDAO.FindById(detail.Product.ProductMaster.Distributor.DistributorId);
                        if (Distributor == null)
                        {
                            DistributorDAO.Add(detail.Product.ProductMaster.Distributor);
                        }
                    }
                    if (detail.Product.ProductMaster.Packager != null)
                    {
                        Packager Packager = PackagerDAO.FindById(detail.Product.ProductMaster.Packager.PackagerId);
                        if (Packager == null)
                        {
                            PackagerDAO.Add(detail.Product.ProductMaster.Packager);
                        }
                    }
                    if (detail.Product.ProductMaster.Manufacturer != null)
                    {
                        Manufacturer Manufacturer =
                            ManufacturerDAO.FindById(detail.Product.ProductMaster.Manufacturer.ManufacturerId);
                        if (Manufacturer == null)
                        {
                            ManufacturerDAO.Add(detail.Product.ProductMaster.Manufacturer);
                        }
                    }

                    ProductMaster ProductMaster = ProductMasterDAO.FindById(detail.Product.ProductMaster.ProductMasterId);
                    if (ProductMaster == null)
                    {
                        ProductMasterDAO.Add(detail.Product.ProductMaster);
                    }
                    else
                    {
                        /*ProductMaster.Country = detail.Product.ProductMaster.Country;
                        ProductMaster.Packager = detail.Product.ProductMaster.Packager;
                        ProductMaster.ProductColor = detail.Product.ProductMaster.ProductColor;
                        ProductMaster.ProductFullName = detail.Product.ProductMaster.ProductFullName;
                        ProductMaster.ProductName = detail.Product.ProductMaster.ProductName;
                        ProductMaster.ProductSize = detail.Product.ProductMaster.ProductSize;
                        ProductMaster.ProductType = detail.Product.ProductMaster.ProductType;
                        ProductMaster.UpdateDate = detail.Product.ProductMaster.UpdateDate;
                        ProductMaster.UpdateId = detail.Product.ProductMaster.UpdateId;
                        ProductMaster.CreateDate = detail.Product.ProductMaster.CreateDate;
                        ProductMaster.CreateId = detail.Product.ProductMaster.CreateId;
                        ProductMaster.Distributor = detail.Product.ProductMaster.Distributor;
                        ProductMaster.Manufacturer = detail.Product.ProductMaster.Manufacturer;
                        ProductMaster.ImagePath = detail.Product.ProductMaster.ImagePath;
                        ProductMaster.ExclusiveKey = detail.Product.ProductMaster.ExclusiveKey;

                        ProductMasterDAO.Update(ProductMaster);*/
                    }
                    if (!productMasterIds.Contains(detail.Product.ProductMaster.ProductMasterId))
                    {
                        productMasterIds.Add(detail.Product.ProductMaster.ProductMasterId);
                        priceList.Add(detail.Price);
                    }

                    Product Product = ProductDAO.FindById(detail.Product.ProductId);
                    if (Product == null)
                    {
                        ProductDAO.Add(detail.Product);
                    }
                    else
                    {
                        /*Product.UpdateDate = detail.Product.UpdateDate;
                        Product.UpdateId = detail.Product.UpdateId;
                        Product.CreateDate = detail.Product.CreateDate;
                        Product.CreateId = detail.Product.CreateId;
                        Product.ProductMaster = detail.Product.ProductMaster;
                        Product.Quantity = detail.Product.Quantity;
                        Product.Price = detail.Product.Price;
                        ProductDAO.Update(Product);*/
                    }

                    if (!productIds.Contains(detail.Product.ProductId))
                    {
                        productIds.Add(detail.Product.ProductId);
                        quantityList.Add(detail.Quantity);
                    }

                    DepartmentStockInDetail DepartmentStockInDetail =
                        DepartmentStockInDetailDAO.FindById(detail.DepartmentStockInDetailPK);
                    if (DepartmentStockInDetail == null)
                    {
                        DepartmentStockInDetailDAO.Add(detail);
                    }
                    else
                    {
                        /*DepartmentStockInDetail.UpdateDate = detail.UpdateDate;
                        DepartmentStockInDetail.UpdateId = detail.UpdateId;
                        DepartmentStockInDetail.CreateDate = detail.CreateDate;
                        DepartmentStockInDetail.CreateId = detail.CreateId;
                        DepartmentStockInDetail.Quantity = DepartmentStockInDetail.Quantity;
                        DepartmentStockInDetail.Price = DepartmentStockInDetail.Price;
                        DepartmentStockInDetailDAO.Update(DepartmentStockInDetail);*/
                    }
                }

                // update price
                if (productMasterIds.Count > 0)
                {
                    var criteria = new ObjectCriteria();
                    criteria.AddEqCriteria("DelFlg", CommonConstants.DEL_FLG_NO);
                    criteria.AddEqCriteria("DepartmentPricePK.DepartmentId", (long)0);
                    criteria.AddSearchInCriteria("DepartmentPricePK.ProductMasterId", productMasterIds);
                    IList deptPriceList = DepartmentPriceDAO.FindAll(criteria);
                    int i = 0;
                    foreach (string productMasterId in productMasterIds)
                    {
                        DepartmentPrice price = null;
                        foreach (DepartmentPrice price1 in deptPriceList)
                        {
                            if (price1.DepartmentPricePK.ProductMasterId.Equals(productMasterId))
                            {
                                price = price1;
                                price.Price = (Int64)priceList[i];
                                break;
                            }
                        }
                        if (price == null)
                        {
                            price = new DepartmentPrice
                            {
                                DepartmentPricePK = new DepartmentPricePK { DepartmentId = 0, ProductMasterId = productMasterId },
                                Price = (Int64)priceList[i],
                                CreateDate = DateTime.Now,
                                CreateId = ClientInfo.getInstance().LoggedUser.Name,
                                UpdateDate = DateTime.Now,
                                UpdateId = ClientInfo.getInstance().LoggedUser.Name
                            };
                            DepartmentPriceDAO.Add(price);
                        }
                        else
                        {
                            price.UpdateDate = DateTime.Now;
                            price.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                            DepartmentPriceDAO.Update(price);
                        }
                        i++;
                    }
                }

                if (productIds.Count > 0)
                {
                    var criteria = new ObjectCriteria();
                    criteria.AddEqCriteria("DelFlg", CommonConstants.DEL_FLG_NO);
                    criteria.AddEqCriteria("DepartmentStockPK.DepartmentId", stockIn.DepartmentStockInPK.DepartmentId);
                    criteria.AddSearchInCriteria("DepartmentStockPK.ProductId", productIds);
                    IList stockList = DepartmentStockDAO.FindAll(criteria);
                    int i = 0;
                    foreach (string productId in productIds)
                    {
                        DepartmentStock stock = null;
                        foreach (DepartmentStock price1 in stockList)
                        {
                            if (price1.DepartmentStockPK.ProductId.Equals(productId))
                            {
                                stock = price1;
                                //stock.Quantity += (Int64)quantityList[i];
                                stock.GoodQuantity += (Int64)quantityList[i];
                                stock.Quantity += (Int64)quantityList[i];
                                break;
                            }
                        }
                        if (stock == null)
                        {
                            stock = new DepartmentStock
                            {
                                DepartmentStockPK = new DepartmentStockPK { DepartmentId = stockIn.DepartmentStockInPK.DepartmentId, ProductId = productId },
                                Quantity = (Int64)quantityList[i],
                                GoodQuantity = (Int64)quantityList[i],
                                CreateDate = DateTime.Now,
                                CreateId = ClientInfo.getInstance().LoggedUser.Name,
                                UpdateDate = DateTime.Now,
                                UpdateId = ClientInfo.getInstance().LoggedUser.Name
                            };
                            DepartmentStockDAO.Add(stock);
                        }
                        else
                        {
                            stock.UpdateId = ClientInfo.getInstance().LoggedUser.Name;
                            stock.UpdateDate = DateTime.Now;
                            DepartmentStockDAO.Update(stock);
                        }
                        i++;
                    }
                }
                return result;
            }
            catch (Exception ex)
            {
                result.HasError = true;
                result.Messages = new ArrayList();
                result.Messages.Add(ex.Message);
                return result;
            }
        }