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; }