Exemple #1
0
 public Product(ProductType invType)
 {
     Name = invType.Name;
     ProductTypeId = invType.Id;
     ProductType = invType;
     ManufacturerTypeId = invType.ManufacturerTypeId;
     TotalDuration = 0;
     Quantity = 0;
 }
 private static int CalculateTimeToManufacture(ProductType productType, ICollection<int> typesAlreadyAdded)
 {
     //if supports parallel manufacturing then we only need to include the duration once.
     var supportsParallelManufacturing = productType.ManufacturerType.SupportsParallelManufacturing;
     var parallelDuration = 0;
     if (supportsParallelManufacturing)
     {
         if (typesAlreadyAdded.All(x => x != productType.Id))
         {
             //if its not in city storage then add it to the total duration
             parallelDuration = productType.TimeToManufacture ?? 0;
             typesAlreadyAdded.Add(productType.Id);
         }
     }
     else
         parallelDuration = productType.TimeToManufacture ?? 0;
     return parallelDuration;
 }
        /// <summary>
        /// Recurses through required products and calculates the total time required to produce the product 
        ///     based on product type duration and quanity of child products required. If city storage  
        ///     is specified then the amount in storage is subrtacted from the total durations and the
        ///     quantity of items in storage is decremented to reflect the use of the required products. 
        /// </summary>
        /// <param name="productType"></param>
        /// <param name="typesAlreadyAdded"></param>
        /// <param name="includeRequiredTypes"></param>
        /// <param name="cityStorage">If included then duration is decreased by what's in storage.</param>
        /// <param name="productsToUpdate"></param>
        /// <returns></returns>
        private int CalculateInventoryItemDurationByType(ProductType productType, ICollection<int> typesAlreadyAdded, bool includeRequiredTypes, CityStorage cityStorage, Product[] productsToUpdate)
        {
            // if we have one in storage then we consider the duration already having been elapsed.
            var cityStorageSpecified = cityStorage != null;
            var cityStorageDecremented = DecrementCityStorageByProductType(productType, cityStorage);
            if (cityStorageDecremented)
                return 0;

            var productTypeTotalDuration = CalculateTimeToManufacture(productType, typesAlreadyAdded);

            if (!includeRequiredTypes)
                return productTypeTotalDuration;

            foreach (var prod in productsToUpdate)
            {
                var productTotalDuration = 0;

                //product types should always have any product type.
                var requiredProductType = _productTypes.First(x => x.Id == prod.ProductTypeId);
                if (prod.RequiredProducts == null)
                    prod.RequiredProducts = requiredProductType.RequiredProducts.Select(x => x.Clone()).ToArray();
                for (var a = 0; a < prod.Quantity; a++)
                {
                    productTotalDuration += CalculateInventoryItemDurationByType(requiredProductType, typesAlreadyAdded, true, cityStorage, prod.RequiredProducts);
                }

                //if city storage is not null then set remaining time
                if (cityStorageSpecified)
                {
                    if (!prod.RemainingDuration.HasValue)
                        prod.RemainingDuration = 0;
                    prod.RemainingDuration += productTotalDuration;
                }
                else
                {
                    if (!prod.TotalDuration.HasValue)
                        prod.TotalDuration = 0;
                    prod.TotalDuration += productTotalDuration;
                }
                productTypeTotalDuration += productTotalDuration;

            }
            return productTypeTotalDuration;
        }
        private static bool DecrementCityStorageByProductType(ProductType productType, CityStorage cityStorage)
        {
            if (cityStorage==null) return false;
            var storageProduct = cityStorage.CurrentInventory.FirstOrDefault(x => x.ProductTypeId == productType.Id);
            if (storageProduct == null || storageProduct.Quantity <= 0) return false;

            storageProduct.Quantity -= 1;
            return true;
        }
 private static Product[] PopulateRequiredProducts(ProductType[] productTypes, Product[] products)
 {
     foreach (var rp in products)
     {
         var pd = productTypes.FirstOrDefault(x => x.Id == rp.ProductTypeId);
         rp.RequiredProducts = pd != null ? pd.RequiredProducts.ToArray() : new Product[0];
     }
     return products;
 }