/// <summary>
        /// Validates this instance.
        /// </summary>
        /// <param name="edc">The <see cref="Entities"/>.</param>
        /// <param name="disposals">The list of disposals created already.</param>
        /// <exception cref="InputDataValidationException">Batch content validate failed;XML content validation</exception>
        public void Validate(Entities edc, IEnumerable <Disposal> disposals)
        {
            ErrorsList _validationErrors = new ErrorsList();

            if (Product == null)
            {
                _validationErrors.Add(new Warnning("Unrecognized finished good", true));
            }
            SKULookup = SKUCommonPart.Find(edc, Product.SKU);
            if (SKULookup == null)
            {
                string _msg = "Cannot find finished good SKU={0} in the SKU dictionary - dictionary update is required";
                _validationErrors.Add(new Warnning(String.Format(_msg, Product.SKU), true));
            }
            if (Product.ProductType != ProductType.Cigarette)
            {
                return;
            }
            Dictionary <string, IGrouping <string, Disposal> > _disposalGroups;

            _disposalGroups = (from _mx in disposals
                               group _mx by _mx.Disposal2IPRIndex.Batch).ToDictionary <IGrouping <string, Disposal>, string>(k => k.Key);
            Dictionary <string, decimal> _materials = new Dictionary <string, decimal>();

            //sum disposed material
            foreach (IGrouping <string, Disposal> _groupX in _disposalGroups.Values)
            {
                _materials.Add(_groupX.Key, _groupX.Sum <Disposal>(x => x.SettledQuantityDec));
            }
            foreach (Material _materialX in this.Values)
            {
                if (_materialX.ProductType.Value != Linq.ProductType.IPRTobacco)
                {
                    continue;
                }
                decimal _disposed = 0;
                if (_materials.ContainsKey(_materialX.Batch))
                {
                    _disposed = _materials[_materialX.Batch];
                }
                decimal _diff = _materialX.Accounts2Dispose.Sum <IPR>(a => a.TobaccoNotAllocatedDec) + _disposed - _materialX.TobaccoQuantityDec;
                if (_diff < -Settings.MinimalOveruse)
                {
                    string _mssg = "Cannot find any IPR account to dispose the quantity {3}: Tobacco batch: {0}, fg batch: {1}, quantity to dispose: {2} kg";
                    _validationErrors.Add(new Warnning(String.Format(_mssg, _materialX.Batch, Product.Batch, _materialX.TobaccoQuantityDec, -_diff), true));
                }
            }
            if (_validationErrors.Count > 0)
            {
                throw new InputDataValidationException("Batch content validation failed", "XML content validation", _validationErrors);
            }
        }
        /// <summary>
        /// Gets the type of the product.
        /// </summary>
        /// <param name="sku">The sku.</param>
        /// <param name="location">The warehouse.</param>
        /// <param name="isFinishedGood">if set to <c>true</c> it is finished good.</param>
        /// <returns></returns>
        /// <exception cref="InputDataValidationException">Cannot find finisched good in the SKU dictionary;Get Product Type</exception>
        public ProductDescription GetProductType(string sku, string location, bool isFinishedGood)
        {
            ProductDescription _ret = null;

            if (isFinishedGood)
            {
                SKUCommonPart entity = SKUCommonPart.Find(this, sku);
                if (entity == null)
                {
                    string _mssg = String.Format("Cannot find finisched good {0}", sku);
                    throw new InputDataValidationException("Cannot find finisched good in the SKU dictionary", "Get Product Type", _mssg, true);
                }
                _ret = new ProductDescription(entity.ProductType.GetValueOrDefault(ProductType.Other), entity.IPRMaterial.GetValueOrDefault(false), entity);
            }
            else
            {
                _ret = GetProductType(Linq.Warehouse.Find(this, location));
            }
            return(_ret);
        }
        /// <summary>
        /// Gets the type of the product.
        /// </summary>
        /// <param name="sku">The sku.</param>
        /// <param name="location">The warehouse.</param>
        /// <returns></returns>
        public ProductDescription GetProductType(string sku, string location)
        {
            ProductDescription _ret       = new ProductDescription(ProductType.Other, false);
            Warehouse          _Warehouse = Linq.Warehouse.Find(this, location);

            if (_Warehouse == null)
            {
                return(_ret);
            }
            SKUCommonPart _sku = SKUCommonPart.Find(this, sku);

            if (_sku != null)
            {
                _ret = new ProductDescription(_sku.ProductType.GetValueOrDefault(ProductType.Other), _sku.IPRMaterial.GetValueOrDefault(false), _sku);
            }
            else
            {
                _ret = GetProductType(_Warehouse);
            }
            return(_ret);
        }
 internal ProductDescription(ProductType type, bool ipr, SKUCommonPart lookup)
 {
     productType = type;
     IPRMaterial = ipr;
     skuLookup   = lookup;
 }