예제 #1
0
		/// <summary>
		/// Adds criteria to the query (the 'where' clause).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public virtual void AddCriteria(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			QueryBuilderHelpers.AddCriteriaToQuery(HqlConstants.WorklistItemQualifier, args.Criteria, query, RemapHqlExpression);

			// modify the query to workaround some NHibernate bugs
			QueryBuilderHelpers.NHibernateBugWorkaround(query.Froms[0], query.Conditions, a => a);
		}
		public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			base.AddRootQuery(query, args);

			var from = query.Froms[0];	// this would be added by the base.AddWorklistRootQuery call

			// join protocol object, because may have criteria on this object
			from.Joins.Add(HqlConstants.JoinProtocol);

			// check if we need to apply the "most recent step" condition
			// this is essentially a workaround to avoid showing duplicates in some worklist results
			// we can only apply this workaround when there is exactly one ps class specified
			// fortunately, there are no use cases yet where more than one ps class is specified
			// that require the workaround
			if (args.ProcedureStepClasses.Length == 1)
			{
				var psClass = CollectionUtils.FirstElement(args.ProcedureStepClasses);
				// the proc step class may be set to the more general "ProtocolProcedureStep" so
				// we need to check for both
				if (psClass == typeof(ProtocolAssignmentStep) || psClass == typeof(ProtocolProcedureStep))
				{
					// when querying for Rejected protocols, only show the most recent ProtocolAssignmentStep
					// There may be many ProtocolAssignmentStep if a protocol is rejected, resubmitted and rejected again.
					// For rejected protocols, the condition "pr.Status not in ('RJ')" is always false.  So the max(EndTime) condition is used
					// For non-rejected protocols, the first condition is always true, and the max(EndTime) condition is never used.
					query.Conditions.Add(ConditionMostRecentProtocolAssignmentStepIfRejected);
				}
			}
		}
예제 #3
0
		private static HqlProjectionQuery GetBaseVisitPractitionerQuery(VisitSearchCriteria visitSearchCriteria, VisitPractitionerSearchCriteria practitionerSearchCriteria)
		{
			var hqlFrom = new HqlFrom(typeof(Visit).Name, "v");
			hqlFrom.Joins.Add(new HqlJoin("v.Practitioners", "vp"));

			var query = new HqlProjectionQuery(hqlFrom);
			query.Conditions.AddRange(HqlCondition.FromSearchCriteria("vp", practitionerSearchCriteria));
			query.Conditions.AddRange(HqlCondition.FromSearchCriteria("v", visitSearchCriteria));
			return query;
		}
예제 #4
0
		private static HqlProjectionQuery GetBaseResultRecipientQuery(OrderSearchCriteria orderSearchCriteria, ResultRecipientSearchCriteria recipientSearchCriteria)
		{
			var hqlFrom = new HqlFrom(typeof(Order).Name, "o");
			hqlFrom.Joins.Add(new HqlJoin("o.ResultRecipients", "rr"));

			var query = new HqlProjectionQuery(hqlFrom);
			query.Conditions.AddRange(HqlCondition.FromSearchCriteria("rr", recipientSearchCriteria));
			query.Conditions.AddRange(HqlCondition.FromSearchCriteria("o", orderSearchCriteria));
			return query;
		}
예제 #5
0
		/// <summary>
		/// Adds the specified ordering to the specified query, pre-pending the specified qualifier.
		/// </summary>
		/// <param name="qualifier"></param>
		/// <param name="query"></param>
		/// <param name="criteria"></param>
		/// <param name="remapHqlExprFunction"></param>
		/// <remarks>
		/// All HQL dot expressions are passed through the <paramref name="remapHqlExprFunction"/>, allowing the expression
		/// to be modified prior to be added to the query.
		/// </remarks>
		public static void AddOrderingToQuery(string qualifier, HqlProjectionQuery query, WorklistItemSearchCriteria[] criteria,
			Converter<string, string> remapHqlExprFunction)
		{
			// use the sorting information from the first WorklistItemSearchCriteria object only
			// (the assumption is that they are all identical)
			var c = CollectionUtils.FirstElement(criteria);
			if (c == null)
				return;

			var sorts = HqlSort.FromSearchCriteria(qualifier, c, remapHqlExprFunction);
			query.Sorts.AddRange(sorts);
		}
예제 #6
0
		public IList<ConfigurationDocument> Find(ConfigurationDocumentSearchCriteria documentCriteria, ConfigurationDocumentBodySearchCriteria bodyCriteria, SearchResultPage page)
		{
			var hqlFrom = new HqlFrom(typeof(ConfigurationDocument).Name, "doc");
			hqlFrom.Joins.Add(new HqlJoin("doc.Body", "body"));

			var query = new HqlProjectionQuery(hqlFrom);
			query.Selects.Add(new HqlSelect("doc"));
			query.Conditions.AddRange(HqlCondition.FromSearchCriteria("doc", documentCriteria));
			query.Conditions.AddRange(HqlCondition.FromSearchCriteria("body", bodyCriteria));
			query.Page = page;

			return ExecuteHql<ConfigurationDocument>(query);
		}
예제 #7
0
		/// <summary>
		/// Adds the specified criteria to the specified query, pre-pending the specified qualifier.
		/// </summary>
		/// <param name="qualifier"></param>
		/// <param name="criteria"></param>
		/// <param name="query"></param>
		/// <param name="remapHqlExprFunction"></param>
		/// <remarks>
		/// All HQL dot expressions are passed through the <paramref name="remapHqlExprFunction"/>, allowing the expression
		/// to be modified prior to be added to the query.
		/// </remarks>
		public static void AddCriteriaToQuery(string qualifier, WorklistItemSearchCriteria[] criteria, HqlProjectionQuery query,
			Converter<string, string> remapHqlExprFunction)
		{
			var or = new HqlOr();
			foreach (var c in criteria)
			{
				if(c.IsEmpty)
					continue;

				var conditions = HqlCondition.FromSearchCriteria(qualifier, c, remapHqlExprFunction);
				var and = new HqlAnd(conditions);
				if (and.Conditions.Count > 0)
					or.Conditions.Add(and);
			}

			if (or.Conditions.Count > 0)
				query.Conditions.Add(or);
		}
		/// <summary>
		/// Establishes the root query (the 'from' clause and any 'join' clauses).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			var procedureStepClasses = args.ProcedureStepClasses;

			// if we have 1 procedure step class, we can say "from x"
			// otherwise we need to say "from ProcedureStep where ps.class = ..."
			if (procedureStepClasses.Length == 1)
			{
				var procStepClass = CollectionUtils.FirstElement(procedureStepClasses);
				query.Froms.Add(new HqlFrom(procStepClass.Name, "ps", WorklistJoins));
			}
			else
			{
				// either 0 or > 1 classes were specified
				query.Froms.Add(new HqlFrom(typeof(ProcedureStep).Name, "ps", WorklistJoins));
				if(procedureStepClasses.Length > 1)
				{
					query.Conditions.Add(HqlCondition.IsOfClass("ps", procedureStepClasses));
				}
			}
		}
		public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			base.AddRootQuery(query, args);

			var from = query.Froms[0]; // added by base.AddRootQuery

			// join report/report part object, because may have criteria or projections on this object
			from.Joins.Add(HqlConstants.JoinReportPart);
			from.Joins.Add(HqlConstants.JoinReport);

			// check if we need to apply the "most recent step" condition
			// this is essentially a workaround to avoid showing duplicates in some worklist results
			// we can only apply this workaround when there is exactly one ps class specified
			// fortunately, there are no use cases yet where more than one ps class is specified
			// that require the workaround
			if (args.ProcedureStepClasses.Length == 1)
			{
				var psClass = CollectionUtils.FirstElement(args.ProcedureStepClasses);
				if (psClass == typeof(PublicationStep))
					query.Conditions.Add(ConditionMostRecentPublicationStep);
				if (psClass == typeof(TranscriptionStep))
					query.Conditions.Add(ConditionMostRecentTranscriptionStep);
			}
		}
		/// <summary>
		/// Constrains the patient profile to match the performing facility.
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public override void AddConstrainPatientProfile(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			// constrain patient profile to performing facility
			query.Conditions.Add(HqlConstants.ConditionConstrainPatientProfile);
		}
		/// <summary>
		/// Adds worklist filters to the query (affects the 'from' clause).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public virtual void AddFilters(HqlProjectionQuery query, WorklistQueryArgs args)
		{
			QueryBuilderHelpers.AddCriteriaToQuery(HqlConstants.WorklistItemQualifier, args.FilterCriteria, query, RemapHqlExpression);
		}
		/// <summary>
		/// Adds the "active procedure step" constraint (affects the 'from' clause).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public void AddActiveProcedureStepConstraint(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			query.Conditions.Add(HqlConstants.ConditionActiveProcedureStep);
		}
예제 #13
0
		/// <summary>
		/// Establishes the root query (the 'from' clause and any 'join' clauses).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			query.Froms.Add(DefaultFrom);

			// do not constrain patient profile
		}
예제 #14
0
		private List<OrderNoteboxItem> BuildOrderNoteboxItems(List<NoteboxItem> inboxItems)
		{
			if (inboxItems.Count == 0)
				return new List<OrderNoteboxItem>();

			// Get all the patients for all the items
			var patients = CollectionUtils.Unique(CollectionUtils.Map<NoteboxItem, Patient>(inboxItems, item => item.Patient));
			var patientQuery = new HqlProjectionQuery(new HqlFrom(typeof(PatientProfile).Name, "pp"));
			var patientCriteria = new PatientProfileSearchCriteria();
			patientCriteria.Patient.In(patients);
			patientQuery.Conditions.AddRange(HqlCondition.FromSearchCriteria("pp", patientCriteria));
			var profiles = ExecuteHql<PatientProfile>(patientQuery);

			// Have to manually get the postings (and later their recipients) to work around a Hibernate fetch="subselect" issue.
			// The subselect somehow removed the "top(100)" and "order by" clause.  Making the query slow.
			// Load all the postings for all the notes.  There may be more than one postings per orderNote.
			// Therefore it is inappropriate to just use the postings in the base query.
			var notes = CollectionUtils.Unique(CollectionUtils.Map<NoteboxItem, Note>(inboxItems, item => item.Note));
			var postingQuery = new HqlProjectionQuery(new HqlFrom(typeof(NotePosting).Name, "np"));
			var postingCriteria = new NotePostingSearchCriteria();
			postingCriteria.Note.In(notes);
			postingQuery.Conditions.AddRange(HqlCondition.FromSearchCriteria("np", postingCriteria));
			postingQuery.Froms[0].Joins.Add(new HqlJoin("np.Recipient", null, HqlJoinMode.Left, true));
			var postings = ExecuteHql<NotePosting>(postingQuery);

			// Build order notebox items
			var orderNoteboxItems = CollectionUtils.Map(inboxItems,
				delegate(NoteboxItem item)
				{
					// Find the appropriate patient profile based on OrderingFacility
					var profile = CollectionUtils.SelectFirst(profiles,
						pp => pp.Patient.Equals(item.Patient)
							&& pp.Mrn.AssigningAuthority.Code.Equals(item.OrderingFacilityInformationAuthority.Code));

					// Find all the recipients
					var postingsForThisNote = CollectionUtils.Select(postings, np => np.Note.Equals(item.Note));
					var recipients = CollectionUtils.Map<NotePosting, object>(postingsForThisNote,
						posting => posting is StaffNotePosting
							? (object)((StaffNotePosting)posting).Recipient
							: (object)((GroupNotePosting)posting).Recipient);

					return new OrderNoteboxItem(item.Note, item.Order, item.Patient, profile, item.Author, recipients,
						item.DiagnosticServiceName, item.NotePostingAcknowledged);
				});

			return orderNoteboxItems;
		}
예제 #15
0
		/// <summary>
		/// Constrains the patient profile to match the performing facility.
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public override void AddConstrainPatientProfile(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			// calling this method on this class would not make any sense
			throw new InvalidOperationException();
		}
예제 #16
0
		private static HqlProjectionQuery GetBaseQuery(INoteboxQueryContext nqc, bool countQuery, 
			string entityAlias, Type fromEntityType, HqlSelect[] itemProjection, HqlJoin[] itemJoins)
		{
			var joins = countQuery ? new HqlJoin[] { } : itemJoins;
			var query = new HqlProjectionQuery(new HqlFrom(fromEntityType.Name, entityAlias, joins));

			if (countQuery)
			{
				query.Selects.AddRange(CountProjection);
			}
			else
			{
				query.Selects.AddRange(itemProjection);

				// need this in case orderNote was sent to staff and staffgroup containing same staff
				//query.SelectDistinct = true;

				// add paging if not a count query
				query.Page = nqc.Page;
			}

			return query;
		}
예제 #17
0
		protected List<OrderNoteboxItem> DoQuery(HqlProjectionQuery query)
		{
			var list = ExecuteHql<object[]>(query);
			var results = new List<NoteboxItem>();
			foreach (var tuple in list)
			{
				var item = (NoteboxItem)Activator.CreateInstance(typeof(NoteboxItem), tuple);
				results.Add(item);
			}

			return BuildOrderNoteboxItems(results);
		}
예제 #18
0
		/// <summary>
		/// Establishes the root query (the 'from' clause and any 'join' clauses).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public override void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			query.Froms.Add(DefaultFrom);
		}
예제 #19
0
		/// <summary>
		/// Establishes the root query (the 'from' clause and any 'join' clauses).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public abstract void AddRootQuery(HqlProjectionQuery query, QueryBuilderArgs args);
예제 #20
0
		/// <summary>
		/// Constrains the patient profile to match the performing facility.
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public abstract void AddConstrainPatientProfile(HqlProjectionQuery query, QueryBuilderArgs args);
예제 #21
0
		/// <summary>
		/// Adds ordering to the query (the 'rder by' clause).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public virtual void AddOrdering(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			QueryBuilderHelpers.AddOrderingToQuery(HqlConstants.WorklistItemQualifier, query, args.Criteria, RemapHqlExpression);
		}
예제 #22
0
		/// <summary>
		/// Adds a paging restriction to the query (the 'top' or 'limit' clause).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public virtual void AddPagingRestriction(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			query.Page = args.Page;
		}
예제 #23
0
		/// <summary>
		/// Adds an item projection to the query (the 'select' clause).
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public virtual void AddItemProjection(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			query.Selects.AddRange(GetWorklistItemSelects(args.Projection));
		}
예제 #24
0
		/// <summary>
		/// Adds a count projection to the query (e.g. 'select count(*)').
		/// </summary>
		/// <param name="query"></param>
		/// <param name="args"></param>
		public virtual void AddCountProjection(HqlProjectionQuery query, QueryBuilderArgs args)
		{
			query.Selects.AddRange(HqlConstants.DefaultCountProjection);
		}