DetailedBatchSupplyChainQueryData ISupplyChainService.GetDetailedBatchSupplyChain(Guid batchId) { var result = new DetailedBatchSupplyChainQueryData(); var transfersOfThatBatch = medicineBatchTransferRepository.GetAll() .Where(t => t.MedicineBatchId == batchId) .ToList(); // Get all last tier transfers var higestTier = transfersOfThatBatch.Max(t => t.Tier); List <MedicineBatchTransfer> lastTierTransfers = transfersOfThatBatch .Where(t => t.Tier == higestTier) .ToList(); result.TransferChains = new List <List <MedicineBatchTransferQueryData> >(); // Trace backwards foreach (var transfer in lastTierTransfers) { List <MedicineBatchTransferQueryData> transferChain = new List <MedicineBatchTransferQueryData>(); var iterator = transfer; var transferPool = transfersOfThatBatch; bool parentMatchCondition(MedicineBatchTransfer t) => t.ToId == iterator.FromId; transferChain.Add(iterator.ToMedicineBatchTransferQueryData()); while (iterator.HasParent(transferPool, parentMatchCondition)) { iterator = iterator.Parent(transferPool, parentMatchCondition).Single(); transferChain.Add(iterator.ToMedicineBatchTransferQueryData()); } result.TransferChains.Add(transferChain); } // TODO: Trace tier backwards. There might be missing chains in which transfers have lower tier than the highest one of the whole batch supply chain. // Calculate the summary section CalculateSummarySection(result); // Format the result foreach (var chain in result.TransferChains) { chain.Reverse(); } return(result); }
async Task <Guid> IMedicineBatchTransferService.Create(Guid medicineBatchId, Guid fromTenantId, Guid toTenantId, uint quantity) { var allTransfer = medicineBatchTransferRepository.GetAll(); var batch = medicineBatchRepository.Get(medicineBatchId); var transfer = new MedicineBatchTransfer() { MedicineBatchId = batch.Id, FromId = fromTenantId, ToId = toTenantId, Quantity = quantity, IsConfirmed = false, DateCreated = DateTime.UtcNow }; // TODO: Check inventory of fromTenant // Set the tier. uint tier = 999; if (fromTenantId == batch.ManufacturerId) { tier = 0; } else { var firstTransaction = allTransfer .Where(t => t.MedicineBatchId == batch.Id && t.FromId == batch.ManufacturerId) .SingleOrDefault(); if (fromTenantId == firstTransaction.ToId) { tier = 1; } else { // Loop through all parent transactions of FromTenantId var transferPool = allTransfer.Where(t => t.MedicineBatchId == batch.Id).ToList(); bool parentMatchCondition(MedicineBatchTransfer t) => t.ToId == transfer.FromId; if (transfer.HasParent(transferPool, parentMatchCondition)) { tier = transfer.Parent(transferPool, parentMatchCondition).First().Tier + 1; } // TODO: Some errors occured here. } } transfer.Tier = tier; var newTransferId = medicineBatchTransferRepository.CreateAndReturnId(transfer); var function = ethereumService.GetFunction(EthereumFunctions.AddMedicineBatchTransfer); var transactionHash = await function.SendTransactionAsync( ethereumService.GetEthereumAccount(), new HexBigInteger(6000000), new HexBigInteger(Nethereum.Web3.Web3.Convert.ToWei(10, UnitConversion.EthUnit.Gwei)), new HexBigInteger(0), functionInput : new object[] { newTransferId.ToString(), transfer.MedicineBatchId.ToString(), transfer.FromId.ToString(), transfer.ToId.ToString(), transfer.Quantity, transfer.DateCreated.ToUnixTimestamp(), tier }); transfer.TransactionHash = transactionHash; medicineBatchTransferRepository.Update(transfer); BackgroundJob.Schedule <IMedicineBatchTransferBackgroundJob>( job => job.WaitForTransactionToSuccessThenFinishCreating(transfer), TimeSpan.FromSeconds(3) ); return(newTransferId); }