diff --git a/pom.xml b/pom.xml
index 3599fac1..ba473d75 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
org.ohdsi
circe
- 1.11.1-SNAPSHOT
+ 1.11.2-SNAPSHOT
1.8
1.8
diff --git a/src/main/resources/resources/cohortdefinition/printfriendly/cohortExpression.ftl b/src/main/resources/resources/cohortdefinition/printfriendly/cohortExpression.ftl
index 8d685318..16bc52e4 100644
--- a/src/main/resources/resources/cohortdefinition/printfriendly/cohortExpression.ftl
+++ b/src/main/resources/resources/cohortdefinition/printfriendly/cohortExpression.ftl
@@ -42,7 +42,7 @@ Limit these restricted entry events to the <@inputTypes.Limit limit=qualifiedLim
### Inclusion Criteria
<#list inclusionRules as rule>
-#### ${rule?counter}. ${rule.name}<#if rule.description??>: ${rule.description} #if>
+#### ${rule?counter}. ${(rule.name)!"Unnamed Rule"}<#if rule.description??>: ${rule.description} #if>
Entry events <@ct.Group group=rule.expression />
#list>
@@ -64,7 +64,7 @@ ${cc?counter}. <@ct.Criteria c=cc/>
### Cohort Eras
-Entry events will be combined into cohort eras if they are within ${collapseSettings.eraPad} days of each other.
+Remaining events will be combined into cohort eras if they are within ${collapseSettings.eraPad} days of each other.
<#-- main template: end -->
diff --git a/src/main/resources/resources/cohortdefinition/printfriendly/criteriaTypes.ftl b/src/main/resources/resources/cohortdefinition/printfriendly/criteriaTypes.ftl
index ab1392a3..715d86d5 100644
--- a/src/main/resources/resources/cohortdefinition/printfriendly/criteriaTypes.ftl
+++ b/src/main/resources/resources/cohortdefinition/printfriendly/criteriaTypes.ftl
@@ -33,6 +33,7 @@ END Note!!!!
<#macro ConditionEra c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.ageAtStart!{} ageAtEnd=c.ageAtEnd!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.eraStartDate!{} c.eraEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.eraLength??><#local temp>era length is <@inputTypes.NumericRange range=c.eraLength /> days#local><#local attrs+=[temp]>#if><#if
c.occurrenceCount??><#local temp>containing <@inputTypes.NumericRange range=c.occurrenceCount /> occurrences#local><#local attrs+=[temp]>#if>
@@ -43,6 +44,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro ConditionOccurrence c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.conditionType??><#local temp>a condition type that<#if c.conditionTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.conditionType/>#local><#local attrs+=[temp]>#if><#if c.stopReason??>
<#local temp>with a stop reason <@inputTypes.TextFilter filter=c.stopReason />#local><#local attrs+=[temp]>#if><#if c.providerSpecialty??>
@@ -66,6 +68,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro DeviceExposure c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.deviceType??><#local temp>a device type that<#if c.deviceTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.deviceType/>#local><#local attrs+=[temp]>#if><#if c.uniqueDeviceId??>
<#local temp>unique device ID <@inputTypes.TextFilter filter=c.uniqueDeviceId />#local><#local attrs+=[temp]>#if><#if c.quantity??>
@@ -80,6 +83,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro DoseEra c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.ageAtStart!{} ageAtEnd=c.ageAtEnd!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.eraStartDate!{} c.eraEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if c.unit??>
<#local temp>unit is: <@inputTypes.ConceptList list=c.unit/>#local><#local attrs+=[temp]>#if><#if c.eraLength??>
<#local temp>with era length <@inputTypes.NumericRange range=c.eraLength /> days#local><#local attrs+=[temp]>#if><#if c.doseValue??>
@@ -91,6 +95,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro DrugEra c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.ageAtStart!{} ageAtEnd=c.ageAtEnd!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.eraStartDate!{} c.eraEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if c.eraLength??>
<#local temp>with era length <@inputTypes.NumericRange range=c.eraLength /> days#local><#local attrs+=[temp]>#if><#if c.occurrenceCount??>
<#local temp>with occurrence count <@inputTypes.NumericRange range=c.occurrenceCount />#local><#local attrs+=[temp]>#if><#if c.gapDays??>
@@ -102,6 +107,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro DrugExposure c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.drugType??><#local temp>a drug type that<#if c.drugTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.drugType/>#local><#local attrs+=[temp]>#if><#if c.refills??>
<#local temp>with refills <@inputTypes.NumericRange range=c.refills />#local><#local attrs+=[temp]>#if><#if c.quantity??>
@@ -128,6 +134,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro Measurement c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.measurementType??><#local temp>a measurement type that<#if c.measurementTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.measurementType/>#local><#local attrs+=[temp]>#if><#if
c.operator??><#local temp>with operator: <@inputTypes.ConceptList list=c.operator/>#local><#local attrs+=[temp]>#if><#if
@@ -149,6 +156,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro Observation c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.observationType??><#local temp>an observation type that<#if c.observationTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.observationType/>#local><#local attrs+=[temp]>#if><#if
c.valueAsNumber??><#local temp>numeric value <@inputTypes.NumericRange range=c.valueAsNumber />#local><#local attrs+=[temp]>#if><#if
@@ -166,6 +174,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro ObservationPeriod c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.ageAtStart!{} ageAtEnd=c.ageAtEnd!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.periodStartDate!{} c.periodEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.userDefinedPeriod??><#local temp><@inputTypes.UserDefinedPeriod c.userDefinedPeriod />#local><#if temp?has_content><#local attrs+=[temp]>#if>#if><#if
c.periodType??><#local temp>period type is: <@inputTypes.ConceptList list=c.periodType/>#local><#local attrs+=[temp]>#if><#if
@@ -177,6 +186,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro ProcedureOccurrence c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.procedureType??><#local temp>a procedure type that<#if c.procedureTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.procedureType/>#local><#local attrs+=[temp]>#if><#if
c.modifier??><#local temp>with modifier: <@inputTypes.ConceptList list=c.modifier/>#local><#local attrs+=[temp]>#if><#if
@@ -191,6 +201,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro Specimen c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.specimenType??><#local temp>a specimen type that<#if c.specimenTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.specimenType/>#local><#local attrs+=[temp]>#if><#if
c.quantity??><#local temp>with quantity <@inputTypes.NumericRange range=c.quantity />#local><#local attrs+=[temp]>#if><#if
@@ -206,6 +217,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro VisitOccurrence c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCriteria ageAtStart=c.age!{} gender=c.gender!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.occurrenceStartDate!{} c.occurrenceEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.visitType??><#local temp>a visit type that<#if c.visitTypeExclude!false> is not:<#else> is:#if> <@inputTypes.ConceptList list=c.visitType/>#local><#local attrs+=[temp]>#if><#if
c.providerSpecialty??><#local temp>a provider specialty that is: <@inputTypes.ConceptList list=c.providerSpecialty/>#local><#local attrs+=[temp]>#if><#if
@@ -219,6 +231,7 @@ c.CorrelatedCriteria??>; <@Group group=c.CorrelatedCriteria level=level indexLab
<#macro VisitDetail c level isPlural=true countCriteria={} indexLabel="cohort entry"><#local attrs = []><#local attrs = []><#if countCriteria?has_content>
<#local temp><@WindowCriteria countCriteria=countCriteria indexLabel=indexLabel/>#local><#if temp?has_content><#local attrs+=[temp]>#if>#if>
<#local temp><@AgeGenderCSCriteria ageAtStart=c.age!{} genderCS=c.genderCS!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
+<#local temp><@inputTypes.DateAdjustment da=c.dateAdjustment!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if>
<#local temp><@EventDateCriteria c.visitDetailStartDate!{} c.visitDetailEndDate!{} />#local><#if temp?has_content><#local attrs+=[temp]>#if><#if
c.visitDetailTypeCS?? && c.visitDetailTypeCS.codesetId??><#local temp>a visit detail type that is <@inputTypes.ConceptSetSelection selection=c.visitDetailTypeCS /> concept set#local><#local attrs+=[temp]>#if><#if
c.providerSpecialtyCS?? && c.providerSpecialtyCS.codesetId??><#local temp>a provider specialty that is <@inputTypes.ConceptSetSelection selection=c.providerSpecialtyCS /> concept set#local><#local attrs+=[temp]>#if><#if
diff --git a/src/main/resources/resources/cohortdefinition/printfriendly/inputTypes.ftl b/src/main/resources/resources/cohortdefinition/printfriendly/inputTypes.ftl
index 00928c04..2860374a 100644
--- a/src/main/resources/resources/cohortdefinition/printfriendly/inputTypes.ftl
+++ b/src/main/resources/resources/cohortdefinition/printfriendly/inputTypes.ftl
@@ -1,8 +1,8 @@
<#--
Note!!!!!
-FTL and markdown are both EXTREMLY senstive to white space, leading to awkward formatting of
-if-else statements and other end tags to eliminate CR/LF and other witespace that interferes with proper
+FTL and markdown are both EXTREMELY sensitive to white space, leading to awkward formatting of
+if-else statements and other end tags to eliminate CR/LF and other whitespace that interferes with proper
markdown rendering. Do not try to change the formatting/indentation of these statements or else you risk
breaking the markdown formatting rules!
END Note!!!!
@@ -25,8 +25,8 @@ END Note!!!!
--><#if range.op?ends_with("bt")> and <#if range.extent?has_content>${utils.formatDate(range.extent)}<#else>_empty_#if>#if>#macro>
<#-- ConceptList -->
-<#macro ConceptList list quote="\""><#list list?map(item->(quote + item.conceptName?lower_case + quote)) as item><#if item?counter gt 1><#if
- item?counter == list?size> or <#else>, #if>#if>${item}#list>#macro>
+<#macro ConceptList list quote="\""><#if (list?size > 0)><#list list?map(item->(quote + item.conceptName?lower_case + quote)) as item><#if
+item?counter gt 1><#if item?counter == list?size> or <#else>, #if>#if>${item}#list><#else>[none specified]#if>#macro>
<#-- ConceptSetSelection -->
<#macro ConceptSetSelection selection defaultName="any"><#if selection.isExcluded!false>not #if>in ${utils.codesetName(selection.codesetId!"", defaultName)}#macro>
@@ -101,3 +101,11 @@ END Note!!!!
<#macro UserDefinedPeriod p><#if
p.startDate?has_content>a user defiend start date of ${utils.formatDate(p.startDate)}<#if p.endDate?has_content> and#if>#if><#if
p.endDate?has_content><#if !p.startDate?has_content>a user defined#if> end date of ${utils.formatDate(p.endDate)}#if>#macro>
+
+<#-- Date Adjustment -->
+
+<#function toDatePart dateType><#if dateType == "START_DATE"><#return "start date"><#else><#return "end date">#if>#function>
+
+<#macro DateAdjustment da><#if
+da?has_content>starting ${(da.startOffset != 0)?then((da.startOffset?abs + " days " + (da.startOffset < 0)?then("before","after")), "on")}${(da.startWith != da.endWith)?then(" the event ${toDatePart(da.startWith)}","")}<#--
+--> and ending ${(da.endOffset != 0)?then((da.endOffset?abs + " days " + (da.endOffset < 0)?then("before","after")), "on")} the event ${toDatePart(da.endWith)}#if>#macro>
\ No newline at end of file
diff --git a/src/test/java/org/ohdsi/circe/cohortdefinition/printfriendly/PrintFriendlyTest.java b/src/test/java/org/ohdsi/circe/cohortdefinition/printfriendly/PrintFriendlyTest.java
index dd384912..4e0dc1a0 100644
--- a/src/test/java/org/ohdsi/circe/cohortdefinition/printfriendly/PrintFriendlyTest.java
+++ b/src/test/java/org/ohdsi/circe/cohortdefinition/printfriendly/PrintFriendlyTest.java
@@ -641,4 +641,35 @@ public void nullConceptSetListTest() {
pf.renderConceptSetList((ConceptSet[])null);
}
+
+ @Test
+ public void dateAdjustTest() {
+ CohortExpression expression = CohortExpression.fromJson(ResourceHelper.GetResourceAsString("/printfriendly/dateAdjust.json"));
+ String markdown = pf.renderCohort(expression);
+ assertThat(markdown, stringContainsInOrder(
+ "1. condition eras of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date.",
+ "2. condition occurrences of 'Concept Set 1', starting 30 days after and ending 40 days after the event end date.",
+ "3. dose eras of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date.",
+ "4. drug eras of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date.",
+ "6. device exposures of 'Concept Set 1', starting on the event start date and ending 20 days after the event end date.",
+ "7. measurements of 'Concept Set 1', starting on and ending 20 days after the event end date.",
+ "8. observations of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date.",
+ "9. observation periods, starting 10 days after and ending 20 days after the event start date.",
+ "10. procedure occurrences of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date.",
+ "11. specimens of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date.",
+ "12. visit occurrences of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date.",
+ "13. visit details of 'Concept Set 1', starting 10 days after and ending 20 days after the event start date."
+ ));
+
+ }
+
+ @Test
+ public void emptyConceptListTest() {
+ CohortExpression expression = CohortExpression.fromJson(ResourceHelper.GetResourceAsString("/printfriendly/emptyConceptList.json"));
+ String markdown = pf.renderCohort(expression);
+ assertThat(markdown, stringContainsInOrder(
+ "1. condition occurrences of 'Concept Set 1', a provider specialty that is: [none specified]; a visit occurrence that is: [none specified]."
+ ));
+
+ }
}
diff --git a/src/test/resources/printfriendly/dateAdjust.json b/src/test/resources/printfriendly/dateAdjust.json
new file mode 100644
index 00000000..cc71d5db
--- /dev/null
+++ b/src/test/resources/printfriendly/dateAdjust.json
@@ -0,0 +1,177 @@
+{
+ "ConceptSets": [
+ {
+ "id": 0,
+ "name": "Concept Set 1",
+ "expression": {
+ "items": []
+ }
+ }
+ ],
+ "PrimaryCriteria": {
+ "CriteriaList": [
+ {
+ "ConditionEra": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "ConditionOccurrence": {
+ "DateAdjustment": {
+ "StartWith": "END_DATE",
+ "StartOffset": 30,
+ "EndWith": "END_DATE",
+ "EndOffset": 40
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "DoseEra": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "DrugEra": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "DrugExposure": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 0,
+ "EndWith": "END_DATE",
+ "EndOffset": 0
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "DeviceExposure": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 0,
+ "EndWith": "END_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "Measurement": {
+ "DateAdjustment": {
+ "StartWith": "END_DATE",
+ "StartOffset": 0,
+ "EndWith": "END_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "Observation": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "ObservationPeriod": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ }
+ }
+ },
+ {
+ "ProcedureOccurrence": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "Specimen": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "VisitOccurrence": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ },
+ {
+ "VisitDetail": {
+ "DateAdjustment": {
+ "StartWith": "START_DATE",
+ "StartOffset": 10,
+ "EndWith": "START_DATE",
+ "EndOffset": 20
+ },
+ "CodesetId": 0
+ }
+ }
+ ],
+ "ObservationWindow": {
+ "PriorDays": 0,
+ "PostDays": 0
+ },
+ "PrimaryCriteriaLimit": {
+ "Type": "First"
+ }
+ },
+ "QualifiedLimit": {
+ "Type": "First"
+ },
+ "ExpressionLimit": {
+ "Type": "First"
+ },
+ "InclusionRules": [],
+ "CensoringCriteria": [],
+ "CollapseSettings": {
+ "CollapseType": "ERA",
+ "EraPad": 0
+ },
+ "CensorWindow": {}
+}
\ No newline at end of file
diff --git a/src/test/resources/printfriendly/emptyConceptList.json b/src/test/resources/printfriendly/emptyConceptList.json
new file mode 100644
index 00000000..851741b1
--- /dev/null
+++ b/src/test/resources/printfriendly/emptyConceptList.json
@@ -0,0 +1,42 @@
+{
+ "ConceptSets": [
+ {
+ "id": 0,
+ "name": "Concept Set 1",
+ "expression": {
+ "items": []
+ }
+ }
+ ],
+ "PrimaryCriteria": {
+ "CriteriaList": [
+ {
+ "ConditionOccurrence": {
+ "ProviderSpecialty" : [],
+ "VisitType" : [],
+ "CodesetId": 0
+ }
+ }
+ ],
+ "ObservationWindow": {
+ "PriorDays": 0,
+ "PostDays": 0
+ },
+ "PrimaryCriteriaLimit": {
+ "Type": "First"
+ }
+ },
+ "QualifiedLimit": {
+ "Type": "First"
+ },
+ "ExpressionLimit": {
+ "Type": "First"
+ },
+ "InclusionRules": [],
+ "CensoringCriteria": [],
+ "CollapseSettings": {
+ "CollapseType": "ERA",
+ "EraPad": 0
+ },
+ "CensorWindow": {}
+}
\ No newline at end of file