string ValidateEnvelopeSoftErrors() { if (!IsValid()) { throw new InvalidOperationException("Can only validate soft errors after hard errors have been removed"); } if (!WasEnvelopeRandomised) { return(null); } string envelopeSoftError = ((IDataErrorInfo)_patient)["EnvelopeNumber"]; if (envelopeSoftError != null) { string userMsg = string.Format(Strings.NewPatientViewModel_SoftError_Envelope, envelopeSoftError); var result = MessageBox.Show(userMsg, Strings.NewPatientViewModel_SoftError_WarningMsg, MessageBoxButton.OKCancel, MessageBoxImage.Warning); if (result == MessageBoxResult.Cancel) { return(CancelString); } Envelope envelope = EnvelopeDetails.GetEnvelope(EnvelopeNumber.Value); int bottomWeightRange = envelope.WeightLessThan == 1000 ? 0 : envelope.WeightLessThan - 500; return(string.Format("Randomised incorrectly - envelope {0} was designated for a {1}-{2}g {3}, but patient is a {4}g {5}", EnvelopeNumber, bottomWeightRange, envelope.WeightLessThan - 1, envelope.IsMale ? "Male" : "Female", AdmissionWeight, IsMale.Value ? "Male" : "Female")); } return(null); }
static string SqlToUnsetIncorrectEnvelopes() { StringBuilder returnVar = new StringBuilder("UPDATE [Participants] SET [BlockNumber] = NULL, [BlockSize] = 0 WHERE "); var envelopeDetails = EnvelopeDetails.GetAllEnvelopeNumbersByStrata(); returnVar.AppendFormat("(Id IN ({0}) AND IsMale = 0 AND AdmissionWeight >= {1}) OR ", string.Join(",", envelopeDetails[RandomisationStrata.SmallestWeightFemale]), BlockWeight1); returnVar.AppendFormat("(Id IN ({0}) AND IsMale = 1 AND AdmissionWeight >= {1}) OR ", string.Join(",", envelopeDetails[RandomisationStrata.SmallestWeightMale]), BlockWeight1); returnVar.AppendFormat("(Id IN ({0}) AND IsMale = 0 AND (AdmissionWeight < {1} OR AdmissionWeight >= {2})) OR ", string.Join(",", envelopeDetails[RandomisationStrata.MidWeightFemale]), BlockWeight1, BlockWeight2); returnVar.AppendFormat("(Id IN ({0}) AND IsMale = 1 AND (AdmissionWeight < {1} OR AdmissionWeight >= {2})) OR ", string.Join(",", envelopeDetails[RandomisationStrata.MidWeightMale]), BlockWeight1, BlockWeight2); returnVar.AppendFormat("(Id IN ({0}) AND IsMale = 0 AND AdmissionWeight < {1}) OR ", string.Join(",", envelopeDetails[RandomisationStrata.TopWeightFemale]), BlockWeight2); returnVar.AppendFormat("(Id IN ({0}) AND IsMale = 1 AND AdmissionWeight < {1});", string.Join(",", envelopeDetails[RandomisationStrata.TopWeightMale]), BlockWeight2); return(returnVar.ToString()); }
string ValidateEnvelopeNumber(bool hardErrorsOnly) { if (!WasEnvelopeRandomised || !OkToRandomise() || (!IsNewRecord && !EnvelopeNumber.HasValue)) //last logical condition because those siblings who followed randomised to the same arm as another sibbling during envelope randomisation phase { return(null); } if (!MultipleSiblingId.HasValue && !EnvelopeNumber.HasValue) { return(Strings.Field_Error_Empty); } else if (EnvelopeNumber > StudyCentre.MaxIdForSite || EnvelopeNumber < StudyCentre.Id) { return(string.Format(Strings.NewPatientModel_Error_IdOutOfRangeForSite, StudyCentre.Id, StudyCentre.MaxIdForSite)); } else { var envelope = EnvelopeDetails.GetEnvelope(EnvelopeNumber.Value); if (envelope == null) { return(Strings.NewPatientModel_Error_EnvelopeNotFound); } if (!hardErrorsOnly) { if (AdmissionWeight >= envelope.WeightLessThan || (envelope.WeightLessThan != 1000 && AdmissionWeight < envelope.WeightLessThan - 500)) { if (envelope.IsMale != IsMale) { return(Strings.NewPatientModel_Error_EnvelopeDualIncorrect); } return(Strings.NewPatientModel_Error_EnvelopeWeightIncorrect); } if (envelope.IsMale != IsMale) { return(Strings.NewPatientModel_Error_EnvelopeGenderIncorrect); } } } return(null); }
public Participant AddParticipant( string name, string mothersName, string hospitalIdentifier, int admissionWeight, double gestAgeBirth, DateTime dateTimeBirth, string AdmissionDiagnosis, string phoneNumber, bool isMale, bool?inborn, DateTime registeredAt, int centreId, MaternalBCGScarStatus maternalBCGScar, int?multipleSiblingId, int?envelopeNumber = null) { Participant newParticipant = new Participant { Name = name, MothersName = mothersName, HospitalIdentifier = hospitalIdentifier.Trim(), AdmissionWeight = admissionWeight, GestAgeBirth = gestAgeBirth, DateTimeBirth = dateTimeBirth, AdmissionDiagnosis = AdmissionDiagnosis, PhoneNumber = phoneNumber, IsMale = isMale, Inborn = inborn, RegisteredAt = registeredAt, RegisteringInvestigator = System.Threading.Thread.CurrentPrincipal.Identity.Name, CentreId = centreId, WasEnvelopeRandomised = envelopeNumber.HasValue, MaternalBCGScar = maternalBCGScar, AppVersionAtEnrollment = App.CurrentAppVersion, VaccinesAdministered = new List <VaccineAdministered>() }; if (multipleSiblingId.HasValue) { var multipleSibling = _dbContext.Participants.Find(multipleSiblingId.Value); if (multipleSibling == null) { throw new ArgumentException("Participant Not Found", "multipleSiblingId"); } if (multipleSibling.IsMale == newParticipant.IsMale) { newParticipant.TrialArm = multipleSibling.TrialArm; newParticipant.MultipleSiblingId = multipleSiblingId; if (envelopeNumber.HasValue) { newParticipant.Id = (from p in _dbContext.Participants where p.Id > EnvelopeDetails.MaxEnvelopeNumber orderby p.Id descending select p.Id).FirstOrDefault(); if (newParticipant.Id == 0) { newParticipant.Id = EnvelopeDetails.MaxEnvelopeNumber; } newParticipant.Id += 1; } else { newParticipant.Id = GetNextId(_dbContext.Participants, centreId); Engine.ForceAllocationToArm(newParticipant, _dbContext); } } } if (!newParticipant.MultipleSiblingId.HasValue) { if (envelopeNumber.HasValue) { Envelope envelope = EnvelopeDetails.GetEnvelope(envelopeNumber.Value); if (!_dbContext.AllocationBlocks.Any(a => a.Id == envelope.BlockNumber)) { _dbContext.AllocationBlocks.Add(new AllocationBlock { Id = envelope.BlockNumber, GroupRepeats = (byte)(envelope.BlockSize / 2), AllocationGroup = AllocationGroups.India2Arm, RandomisationCategory = envelope.RandomisationCategory }); } newParticipant.AllocationBlockId = envelope.BlockNumber; newParticipant.TrialArm = envelope.IsInterventionArm ? RandomisationArm.RussianBCG : RandomisationArm.Control; newParticipant.Id = envelopeNumber.Value; } else { newParticipant.Id = GetNextId(_dbContext.Participants, centreId); Engine.CreateAllocation(newParticipant, _dbContext); } } Add(newParticipant); return(newParticipant); }
static void CreateAllocationBlocks(TrialDataContext context) { var participants = context.Database.SqlQuery(typeof(OldParticipant), string.Format( "select Id,CentreId,WasEnvelopeRandomised,BlockNumber,BlockSize, case when IsMale = 1 then case when AdmissionWeight< {0} then {2} when AdmissionWeight >={1} then {3} else {4} end else case when AdmissionWeight< {0} then {5} when AdmissionWeight >={1} then {6} else {7} end end as Strata from Participants order by CentreId, BlockNumber, Id", Engine.BlockWeight1, Engine.BlockWeight2, (int)RandomisationStrata.SmallestWeightMale, (int)RandomisationStrata.TopWeightMale, (int)RandomisationStrata.MidWeightMale, (int)RandomisationStrata.SmallestWeightFemale, (int)RandomisationStrata.TopWeightFemale, (int)RandomisationStrata.MidWeightFemale)).Cast <OldParticipant>(); const string updatePreface = "Update Participants set AllocationBlockId = Case Id"; const string updateSufix = " else AllocationBlockId end;"; const int maxArgs = 64; List <StringBuilder> participantUpdate = new List <StringBuilder>(); StringBuilder currentUpdate = new StringBuilder(updatePreface); participantUpdate.Add(currentUpdate); List <AllocationBlock> blocksToInsert = new List <AllocationBlock>(); var now = DateTime.Now; int currentCentreId = 0; int nextId = 0; int argCount = 0; IDictionary <int, RandomisationStrata> blockNumberLookup = null; foreach (var g in participants.GroupBy(p => new { p.CentreId, p.BlockNumber })) { if (g.Key.CentreId != currentCentreId) { currentCentreId = g.Key.CentreId; nextId = (currentCentreId == 1) ?EnvelopeDetails.MaxEnvelopeNumber + 1 :currentCentreId; } //if envelope randomised, use the allocationGroupId for the correctly assigned group //otherwise, keep the allocationGroupId for the goup with the highest number IEnumerable <IGrouping <int, OldParticipant> > forReallocation = g.GroupBy(p => p.Strata).ToList(); if (currentCentreId == 1 && g.Key.BlockNumber.HasValue) { var currentAlloc = new AllocationBlock { Id = g.Key.BlockNumber.Value, AllocationGroup = AllocationGroups.India2Arm, RecordLastModified = now }; blocksToInsert.Add(currentAlloc); if (g.Any(p => p.WasEnvelopeRandomised)) { (blockNumberLookup ?? (blockNumberLookup = EnvelopeDetails.GetStrataByBlockNumber())).TryGetValue(g.Key.BlockNumber.Value, out RandomisationStrata definedStrata); int strataVal = (int)definedStrata; var correctlyAssigned = forReallocation.FirstOrDefault(r => r.Key == strataVal); if (correctlyAssigned == null) { blocksToInsert.RemoveAt(blocksToInsert.Count - 1); } else { currentAlloc.GroupRepeats = (byte)((correctlyAssigned.Count() - 1) / 2 + 1); currentAlloc.RandomisationCategory = definedStrata; forReallocation = forReallocation.Where(r => r != correctlyAssigned); } } else { int maxCount = 0; int largestRandCat = 0; foreach (var r in forReallocation) { int grpCount = r.Count(); if (grpCount > maxCount) { maxCount = grpCount; largestRandCat = r.Key; } } currentAlloc.RandomisationCategory = (RandomisationStrata)largestRandCat; currentAlloc.GroupRepeats = (byte)((maxCount - 1) / 2 + 1); forReallocation = forReallocation.Where(r => r.Key != largestRandCat); System.Diagnostics.Debug.Assert(currentAlloc.Id != 1); } } foreach (var s in forReallocation) { string nextIdStr = nextId.ToString(); blocksToInsert.Add(new AllocationBlock { Id = nextId++, AllocationGroup = AllocationGroups.India2Arm, GroupRepeats = (byte)((s.Count() - 1) / 2 + 1), RandomisationCategory = (RandomisationStrata)s.Key, RecordLastModified = now }); argCount += s.Count(); if (argCount > maxArgs) { argCount = 0; currentUpdate.Append(updateSufix); currentUpdate = new StringBuilder(updatePreface); participantUpdate.Add(currentUpdate); } currentUpdate.AppendFormat(string.Join("", s.Select(p => " When " + p.Id + " Then " + nextIdStr))); } } using (SqlCeBulkCopy bc = new SqlCeBulkCopy((System.Data.SqlServerCe.SqlCeConnection)context.Database.Connection)) { bc.DestinationTableName = "AllocationBlocks"; bc.WriteToServer(blocksToInsert); } if (argCount == 0) { participantUpdate.RemoveAt(participantUpdate.Count - 1); } else { currentUpdate.Append(updateSufix); } foreach (var sb in participantUpdate) { context.Database.ExecuteSqlCommand(sb.ToString()); } context.Database.ExecuteSqlCommand("update Participants set RecordLastModified = GetDate()"); context.Database.ExecuteSqlCommand("Update Participants set AllocationBlockId = BlockNumber where AllocationBlockId is null;"); }