public async Task<decimal> CalculateItemPrice(int typeId) { var bpInfo = await _dataService.GetBlueprintInfoByProductTypeIdAsync(typeId); if (bpInfo == null) return 0; // todo: Create indy job repository var indyHistory = await _apiService.GetApiResult<IndustryJobDto>(new Credential(), CallContext.Corp, CallEndPoint.IndustryJobsHistory); if (!indyHistory.Success) throw new Exception($"IndustryJob history failed... error: {indyHistory.Message}"); var job = indyHistory.Result.Where(p => p.ProductTypeId == typeId && p.ActivityId == 1).OrderByDescending(p => p.EndDate).FirstOrDefault(); if (job == null) return 0; var itemPrice = (decimal)job.Cost / job.Runs / (decimal)bpInfo.Manufacturing.Products.First(p => p.TypeId == typeId).Quantity; //var bp = await _blueprintRepository.FindBlueperintByItemIdAsync(job.BlueprintId) ?? var bp = await _blueprintRepository.FindBlueprintAsync(bpInfo.BlueprintId); if (bp == null) bp = new Blueprint(bpInfo.BlueprintId, 4, 4, 10); var jobInfo = new Domains.IndustryJob(bpInfo, bp); var materials = await jobInfo.GetMaterialNeeds(job.SuccesfulRuns); var matPrices = await _apiService.GetMarketStatistics(materials.Select(p => p.TypeId).ToList(), 30000142); // todo: Create Transaction Repository foreach (var mat in materials) { var used = mat.Quantity/(decimal)job.SuccesfulRuns; var matBp = await _dataService.GetBlueprintInfoByProductTypeIdAsync(mat.TypeId); if (matBp == null) { try { var matPrice = used * matPrices.FirstOrDefault(p => p.TypeId == mat.TypeId).Buy / (decimal)jobInfo.BlueprintInfo.Manufacturing.Products.First(p => p.TypeId == typeId).Quantity; itemPrice += matPrice; continue; } catch (Exception e) { throw new Exception($"Material {mat.TypeName} (ID: {mat.TypeId}) failed due to not being in price list"); } } itemPrice += (await CalculateItemPrice(mat.TypeId)) * mat.Quantity; } return itemPrice; }
public async Task<InventionJob> CalculateInventionCosts(int typeId, IEnumerable<Decryptor> decryptors) { try { var print = await _staticService.GetBlueprintInfoByProductTypeIdAsync(typeId); var t2Item = await _staticService.GetProductTypeAsync(typeId); var parent = await _staticService.GetBlueprintInfoByProductTypeIdAsync(t2Item.MetaParent); if (parent == null) throw new Exception("Parent blueprint does not exist"); var job = new Domains.IndustryJob(parent, new Blueprint(parent.BlueprintId, 0, 0, 1)); var inventionMaterialPrices = await _apiService.GetMarketStatistics(job.BlueprintInfo.Invention.Materials.Select(p => p.TypeId).ToList(), 30000142); return await GetInventionJob(job, print, decryptors, inventionMaterialPrices); } catch (Exception e) { throw new Exception($"Invention of itemId {typeId} failed with message: {e.Message}"); } }
private async Task CreateManufacturingViewModel(Blueprint blueprint) { var bpInfo = _bpInfo.FirstOrDefault(p => p.BlueprintId.Equals(blueprint.TypeId)); if (bpInfo == null || !bpInfo.Manufacturing.Products.Any() || bpInfo.Manufacturing.Products.First().MetaGroup < 2) return; var product = bpInfo.Manufacturing?.Products?.First(); if (product == null || !await PreManufacturingValidation(product)) return; var job = new Domains.IndustryJob(bpInfo, blueprint); var rawMaterials = await _manufacturingService.GetRawMaterials(job, 1); var marketStatIds = rawMaterials.Select(p => p.TypeId).ToList(); marketStatIds.Add(product.TypeId); var marketStats = await _apiService.GetMarketStatistics(marketStatIds, 30000142); var productCost = rawMaterials.Sum(mat => Convert.ToDecimal(mat.Quantity) * marketStats.First(p => p.TypeId.Equals(mat.TypeId)).Buy); productCost = productCost / Convert.ToDecimal(bpInfo.Manufacturing.Products.First().Quantity); var productPrice = marketStats.First(p => p.TypeId.Equals(product.TypeId)).Buy; if (productPrice <= productCost) return; var runs = 0; if (productCost < 8000000 && blueprint.Runs > 0) runs = blueprint.Runs; else if (productCost < 8000000 && blueprint.Runs == -1) runs = product.CategoryId == 6 ? 5 : 20; else if (productCost > 8000000 && productCost < 30000000 && blueprint.Runs > 0) runs = blueprint.Runs >= 10 ? 10 : blueprint.Runs; else if (productCost > 1500000000) return; else runs = 1; if (runs > 100) runs = 100; var manufTime = await _manufacturingService.GetTotalManufacturingTime(job, runs); var profitPerHour = (productPrice - productCost / (decimal)job.BlueprintInfo.Manufacturing.Products.First().Quantity) / manufTime * 60 * 60; var materials = await job.GetMaterialNeeds(runs); foreach (var mat in materials) { var bp = await _staticService.GetBlueprintInfoByProductTypeIdAsync(mat.TypeId); if (bp == null || bp.BlueprintId == 0) { _materials.Add(mat); continue; } _components.Add(new Component(mat.TypeId, mat.TypeName, (int)mat.Quantity)); } _products.Add(new Product(product.TypeId, product.TypeName, runs, profitPerHour, product.CategoryId)); }
private async Task DoStuffToInvention(InventionJob job) { var decryptor = job.Decryptors.OrderByDescending(p => p.ProfitPerInvention).First(); if (decryptor.Price < 50000) return; var indyJob = new Domains.IndustryJob(await _staticService.GetBlueprintInfoAsync(job.ParentId), new Blueprint(job.ParentId, 0, 0, 1)); var runs = Math.Floor((double)60 * 60 * 24 / await indyJob.GetInventionTime() / 2); runs = runs > 0 ? runs : 1; _inventions.Add(new Invention(job.ParentId, job.ParentName, job.Name, decryptor.TypeName, decryptor.ProfitPerInvention, (int)runs)); if (decryptor.TypeId > 0) _materials.Add(new Material(decryptor.TypeId, decryptor.TypeName, (int)runs)); foreach (var p in indyJob.BlueprintInfo.Invention.Materials) _materials.Add(new Material(p.TypeId, p.TypeName, (int)(p.Quantity * runs))); }
internal async Task CheckManufacturingJob(IndustryJobDto job) { var print = _blueprints.First(p => p.ItemId == job.BlueprintId); if (print == null) return; var printInfo = _printInfos.FirstOrDefault(p => p.BlueprintId == job.BlueprintTypeId); if (printInfo == null) throw new InvalidOperationException("It seems there was an item that has no blueprint being built... sort it out."); var indyJob = new Domains.IndustryJob(printInfo, print); var mats = await indyJob.GetMaterialNeeds(job.Runs); foreach (var mat in mats) { var m = _stock.FirstOrDefault(p => p.TypeId == mat.TypeId); if (m == null) continue; if (m.Quantity <= mat.Quantity) _stock.Remove(m); else m.DecreaseQuantity(mat.Quantity); } var comp = _components.FirstOrDefault(p => p.TypeId == job.ProductTypeId); if (comp != null) { if (comp.Quantity <= job.Runs) _components.Remove(comp); else comp.DecreaseQuantity(job.Runs); return; } var prod = _products.FirstOrDefault(p => p.TypeId == job.ProductTypeId); if (prod == null) return; if (prod.Quantity <= job.Runs) _products.Remove(prod); else prod.DecreaseQuantity(job.Runs); }
private async Task<Decryptor> CheckDecryptor(Decryptor decryptor, Domains.IndustryJob job, BlueprintInfo t2Print, decimal costOfInvention, int baseRuns, IEnumerable<MarketPrice> materialPrices) { try { var probability = await job.GetInventionSuccessProbability(5, 5, 5, decryptor.ProbabilityModifier); if (decryptor.TypeId > 0) costOfInvention += decryptor.Price; var runs = baseRuns + decryptor.MaxRunModifier; var t2Job = new Domains.IndustryJob(t2Print, new Blueprint { MaterialEfficiency = 2 + decryptor.MaterialEfficiencyModifier }); var materials = await _manufacturingService.GetRawMaterials(t2Job, 1); var itemCost = materials.Sum(mat => materialPrices.First(p => p.TypeId == mat.TypeId).Buy * mat.Quantity); var inventionCostPerRun = costOfInvention / runs * probability * (decimal)t2Print.Manufacturing.Products.First().Quantity; var dec = new Decryptor(decryptor.TypeId, decryptor.TypeName, decryptor.ProbabilityModifier, decryptor.MaxRunModifier, decryptor.MaterialEfficiencyModifier, decryptor.TimeEfficiencyModifier, decryptor.Price); dec.ProfitPerInvention = materialPrices.First(p => p.TypeId == t2Print.Manufacturing.Products.First().TypeId).Buy - inventionCostPerRun - itemCost; dec.ME = 2 + decryptor.MaterialEfficiencyModifier; dec.TE = 4 + decryptor.TimeEfficiencyModifier; dec.Runs = runs; return dec; } catch (Exception e) { throw new Exception($"{t2Print.Manufacturing.Products.First().TypeName} Failed with {decryptor.TypeName} with message: {e.Message}"); } }