diff --git a/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs b/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs index 1f74f37d..8061d7b1 100644 --- a/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs +++ b/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs @@ -231,6 +231,7 @@ public static A2 ToVM(this A2FormFields fields, int formId) INBIRMO = fields.INBIRMO, INBIRYR = fields.INBIRYR, INSEX = fields.INSEX, + NEWINF = fields.NEWINF, INHISP = fields.INHISP, INHISPOR = fields.INHISPOR, INHISPOX = fields.INHISPOX, diff --git a/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs b/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs index 23b13803..bd8b8cce 100644 --- a/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs +++ b/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs @@ -115,6 +115,7 @@ public static Form ToEntity(this A2 vm) INBIRMO = vm.INBIRMO, INBIRYR = vm.INBIRYR, INSEX = vm.INSEX, + NEWINF = vm.NEWINF, INHISP = vm.INHISP, INHISPOR = vm.INHISPOR, INHISPOX = vm.INHISPOX, diff --git a/src/UDS.Net.Forms/Models/UDS3/A2.cs b/src/UDS.Net.Forms/Models/UDS3/A2.cs index 38b48fad..28b857bd 100644 --- a/src/UDS.Net.Forms/Models/UDS3/A2.cs +++ b/src/UDS.Net.Forms/Models/UDS3/A2.cs @@ -5,6 +5,7 @@ using System.Xml.Linq; using UDS.Net.Forms.DataAnnotations; using UDS.Net.Forms.TagHelpers; +using UDS.Net.Services.Enums; namespace UDS.Net.Forms.Models.UDS3 { @@ -22,71 +23,107 @@ public class A2 : FormModel public int? INBIRYR { get; set; } [Display(Name = "Co-participant's sex")] + [RequiredOnComplete(ErrorMessage = "Response required")] public int? INSEX { get; set; } [Display(Name = "Is this a new co-participant - i.e., one who was not a co-participant at any past UDS visit?")] public int? NEWINF { get; set; } [Display(Name = "Does the co-participant report being of Hispanic/Latino ethnicity  (i.e., having origins from a mainly Spanish-speaking Latin American country), regardless of race?")] + [RequiredIf(nameof(NEWINF), "1", ErrorMessage = "Does the co-participant report being of Hispanic/Latino ethnicity?")] public int? INHISP { get; set; } [Display(Name = "If yes, what are the co-participant's reported origins?")] + [RequiredIf(nameof(INHISP), "2", ErrorMessage = "What are the co-participant's reported origins?")] public int? INHISPOR { get; set; } [Display(Name = "Other (SPECIFY)")] [MaxLength(60)] [ProhibitedCharacters] + [RequiredIf(nameof(INHISPOR), "50", ErrorMessage = "Indicate other additional origin")] public string? INHISPOX { get; set; } [Display(Name = "What does the co-participant report as his or her race?")] + [RequiredIf(nameof(NEWINF), "1", ErrorMessage = "Indicate co-participants race")] public int? INRACE { get; set; } [Display(Name = "Other (SPECIFY)")] [MaxLength(60)] + [RequiredIf(nameof(INRACE), "50", ErrorMessage = "Indicate other additional race")] [ProhibitedCharacters] public string? INRACEX { get; set; } [Display(Name = "What additional race does the co-participant report?")] + [RequiredIf(nameof(NEWINF), "1", ErrorMessage = "Indicate additional race")] public int? INRASEC { get; set; } [Display(Name = "Other (SPECIFY)")] [MaxLength(60)] + [RequiredIf(nameof(INRASEC), "50", ErrorMessage = "Indicate other additional race")] [ProhibitedCharacters] public string? INRASECX { get; set; } [Display(Name = "What additional race, beyond those reported in Questions 4 and 5, does the co-participant report?")] + [RequiredIf(nameof(NEWINF), "1", ErrorMessage = "Indicate additional race")] public int? INRATER { get; set; } [Display(Name = "Other (SPECIFY)")] [MaxLength(60)] + [RequiredIf(nameof(INRATER), "50", ErrorMessage = "Indicate other additional race")] [ProhibitedCharacters] public string? INRATERX { get; set; } - [Display(Name = "Co-participant's years of education — use the codes below to report the level achieved; if an attempted level is not completed, enter the number of years completed")] - [Range(0, 99, ErrorMessage = "Co-participants years of education must be within 0 and 99")] + [Display(Name = "Co-participant's years of education — use the codes below to report the level achieved; if an attempted level is not completed, enter the number of years completed" + + "

12 = high school or GED
16 = bachelor's degree
18 = master's degree
20 = doctorate
99 = unknown")] + [RegularExpression(@"^(99|[0-9]|[1-2][0-9]|3[0-6])$", ErrorMessage = "Co-participants years of education must be within 0 and 36 or 99.")] + [RequiredIf(nameof(NEWINF), "1", ErrorMessage = "Indicate years of education")] public int? INEDUC { get; set; } [Display(Name = "What is the co-participant's relationship to the participant?")] + [RequiredOnComplete(ErrorMessage = "Response required")] public int? INRELTO { get; set; } [Display(Name = "How long has the co-participant known the participant?")] - [Range(0, 999, ErrorMessage = "Years known must be within 0 and 999")] + [RegularExpression(@"^(0|[1-9]\d?|120|999)$", ErrorMessage = "Years known must be within 0-120 or 999")] + [RequiredOnComplete(ErrorMessage = "Response required")] public int? INKNOWN { get; set; } [Display(Name = "Does the co-participant live with the subject?")] + [RequiredOnComplete(ErrorMessage = "Response required")] public int? INLIVWTH { get; set; } [Display(Name = "If no, approximate frequency of in-person visits?")] + [RequiredIf(nameof(INLIVWTH), "0", ErrorMessage = "Indicate frequency of visits")] public int? INVISITS { get; set; } [Display(Name = "If no, approximate frequency of telephone contact?")] + [RequiredIf(nameof(INLIVWTH), "0", ErrorMessage = "Indicate frequency of telephone calls")] public int? INCALLS { get; set; } [Display(Name = "Is there a question about the co-participant's reliability?")] + [RequiredOnComplete(ErrorMessage = "Response required")] public int? INRELY { get; set; } public override IEnumerable Validate(ValidationContext validationContext) { + + if (Status == FormStatus.Complete) + { + var visitValue = validationContext.Items.FirstOrDefault(v => v.Key.ToString() == "Visit").Value; + if (visitValue is VisitModel) + { + VisitModel visit = (VisitModel)visitValue; + + if (visit != null) + { + if (visit.Kind == VisitKind.FVP || visit.Kind == VisitKind.TFP) + { + if (!NEWINF.HasValue) + yield return new ValidationResult("Response required", new[] { nameof(NEWINF) }); + } + } + } + } foreach (var result in base.Validate(validationContext)) { yield return result; diff --git a/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml b/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml index 4f7ff475..db2bf24a 100644 --- a/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml +++ b/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml @@ -35,32 +35,48 @@ - @if (Model.Visit != null && Model.Visit.Kind == VisitKind.FVP) + @if (Model.Visit != null && Model.Visit.Kind == VisitKind.FVP || Model.Visit != null && Model.Visit.Kind == VisitKind.TFP) {

- +
} -
- + @if (Model.Visit != null && Model.Visit.Kind == VisitKind.FVP || Model.Visit !=null && Model.Visit.Kind == VisitKind.TFP) + { +
+

- +
-
+
+ } + else + { +
+ +
+

+ + +
+
+ } + +
- +

- +
@@ -70,6 +86,7 @@

+
@@ -77,7 +94,7 @@

- +
@@ -94,38 +111,60 @@

- +
-

- +

+
- +
- +
-
- + @if (Model.Visit.Kind == VisitKind.IVP || Model.Visit.Kind == VisitKind.TIP) + { +
+

- +
-

- +

+
- + +
+
-
-
+ } + else + { +
+ +
+

+ + +
+
+

+ +
+ +
+ +
+
+ }
- +

@@ -143,44 +182,62 @@
+
- +

+
+ @if (Model.Visit.Kind == VisitKind.FVP || Model.Visit.Kind == VisitKind.TFP) + { +
+ +
+

+ + +
+
+ } + + else + {

- +
+ } +
- - +

- +
- +

- +
+
diff --git a/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml.cs b/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml.cs index 422b12d6..bfc4927e 100644 --- a/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml.cs +++ b/src/UDS.Net.Forms/Pages/UDS3/A2.cshtml.cs @@ -25,11 +25,58 @@ public class A2Model : FormPageModel new RadioListItem("Female", "2") }; + public List NewCoParticipantListItems { get; } = new List + { + new RadioListItem("No (If No, SKIP TO QUESTION 9)", "0"), + new RadioListItem("Yes", "1") + }; + + public Dictionary NewCoParticipantUIBehavior = new Dictionary + { + { "0", new UIBehavior{ + PropertyAttributes = new List + { + new UIDisableAttribute("A2.INHISP"), + new UIDisableAttribute("A2.INHISPOR"), + new UIDisableAttribute("A2.INRACE"), + new UIDisableAttribute("A2.INRASEC"), + new UIDisableAttribute("A2.INRATER"), + new UIDisableAttribute("A2.INEDUC") + }, + InstructionalMessage = "skip to question 9" + + } }, + { "1", new UIBehavior{ + PropertyAttributes = new List + { + new UIEnableAttribute("A2.INHISP"), + new UIEnableAttribute("A2.INHISPOR"), + new UIEnableAttribute("A2.INRACE"), + new UIEnableAttribute("A2.INRASEC"), + new UIEnableAttribute("A2.INRATER"), + new UIEnableAttribute("A2.INEDUC") + }, + } } + }; + public List HispanicLatinoListItems { get; } = new List { - new RadioListItem("No  (If No, SKIP TO QUESTION below)", "1"), + new RadioListItem("No  (If No, SKIP TO QUESTION 4)", "1"), new RadioListItem("Yes", "2"), - new RadioListItem("Unknown (If Unknown, SKIP TO QUESTION below)", "9") + new RadioListItem("Unknown (If Unknown, SKIP TO QUESTION 4)", "9") + }; + + public List HispanicLatinoFVPListItems { get; } = new List + { + new RadioListItem("No  (If No, SKIP TO QUESTION 5)", "1"), + new RadioListItem("Yes", "2"), + new RadioListItem("Unknown (If Unknown, SKIP TO QUESTION 5)", "9") + }; + public Dictionary HispanicLatinoUIBehavior = new Dictionary + { + { "1", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOR") } }, + { "2", new UIBehavior { PropertyAttribute = new UIEnableAttribute("A2.INHISPOR") } }, + { "9", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOR") } } }; public List OriginsListItems { get; } = new List @@ -44,6 +91,18 @@ public class A2Model : FormPageModel new RadioListItem("Unknown","99") }; + public Dictionary OriginsUIBehavior = new Dictionary + { + { "1", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOX") } }, + { "2", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOX") } }, + { "3", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOX") } }, + { "4", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOX") } }, + { "5", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOX") } }, + { "6", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOX") } }, + { "50", new UIBehavior { PropertyAttribute = new UIEnableAttribute("A2.INHISPOX") } }, + { "99", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INHISPOX") } } + + }; public List RacialGroupsListItems { get; } = new List { new RadioListItem("White", "1"), @@ -55,6 +114,66 @@ public class A2Model : FormPageModel new RadioListItem("Unknown", "99") }; + + public Dictionary RacialGroupsUIBehavior = new Dictionary + { + { "1", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRACEX") } }, + { "2", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRACEX") } }, + { "3", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRACEX") } }, + { "4", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRACEX" ) } }, + { "5", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRACEX") } }, + { "50", new UIBehavior { PropertyAttribute = new UIEnableAttribute("A2.INRACEX") } }, + { "99", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRACEX") } }, + + }; + + public List AdditionalRacialGroupsListItems { get; } = new List + { + new RadioListItem("White", "1"), + new RadioListItem("Black or African American", "2"), + new RadioListItem("American Indian or Alaska Native", "3"), + new RadioListItem("Native Hawaiian or other Pacific Islander", "4"), + new RadioListItem("Asian", "5"), + new RadioListItem("Other (specify)", "50"), + new RadioListItem("Unknown", "99") + }; + + public Dictionary AdditionalRacialGroupsUIBehavior = new Dictionary + { + { "1", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRASECX") } }, + { "2", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRASECX") } }, + { "3", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRACEX") } }, + { "4", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRASECX" ) } }, + { "5", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRASECX") } }, + { "50", new UIBehavior { PropertyAttribute = new UIEnableAttribute("A2.INRASECX") } }, + { "99", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRASECX") } }, + + }; + + public List BeyondAdditionalRacialGroupsListItems { get; } = new List + { + new RadioListItem("White", "1"), + new RadioListItem("Black or African American", "2"), + new RadioListItem("American Indian or Alaska Native", "3"), + new RadioListItem("Native Hawaiian or other Pacific Islander", "4"), + new RadioListItem("Asian", "5"), + new RadioListItem("Other (specify)", "50"), + new RadioListItem("Unknown", "99") + }; + + public Dictionary BeyondAdditionalRacialGroupsUIBehavior = new Dictionary + { + { "1", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRATERX") } }, + { "2", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRATERX") } }, + { "3", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRATERX") } }, + { "4", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRATERX" ) } }, + { "5", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRATERX") } }, + { "50", new UIBehavior { PropertyAttribute = new UIEnableAttribute("A2.INRATERX") } }, + { "99", new UIBehavior { PropertyAttribute = new UIDisableAttribute("A2.INRATERX") } }, + + }; + + public List RelationshipTypesListItems { get; } = new List { new RadioListItem("Spouse, partner, or companion (include ex-spouse, ex-partner, fiancé, boyfriend, girlfriend)", "1"), @@ -71,7 +190,41 @@ public class A2Model : FormPageModel new RadioListItem("Yes (If Yes, SKIP TO QUESTION 10)", "1") }; - public List ContactFrequencyListItems { get; } = new List + public List LivingSituationFVPListItems { get; } = new List + { + new RadioListItem("No", "0"), + new RadioListItem("Yes (If Yes, SKIP TO QUESTION 11)", "1") + }; + + public Dictionary LivingSituationUIBehavior = new Dictionary + { + + { "0", new UIBehavior { PropertyAttributes = new List + { + new UIEnableAttribute("A2.INVISITS"), + new UIEnableAttribute("A2.INCALLS")} + } }, + + {"1", new UIBehavior {PropertyAttributes = new List + { + new UIDisableAttribute("A2.INVISITS"), + new UIDisableAttribute("A2.INCALLS") + } + } } + + }; + + public List VisitContactFrequencyListItems { get; } = new List + { + new RadioListItem("Daily", "1"), + new RadioListItem("At least 3 times per week", "2"), + new RadioListItem("Weekly", "3"), + new RadioListItem("At least three times per month", "4"), + new RadioListItem("Monthly", "5"), + new RadioListItem("Less than once a month", "6"), + }; + + public List TelephoneContactFrequencyListItems { get; } = new List { new RadioListItem("Daily", "1"), new RadioListItem("At least 3 times per week", "2"), diff --git a/src/UDS.Net.Services/DomainModels/Forms/A2FormFields.cs b/src/UDS.Net.Services/DomainModels/Forms/A2FormFields.cs index a5d251a2..31364e34 100644 --- a/src/UDS.Net.Services/DomainModels/Forms/A2FormFields.cs +++ b/src/UDS.Net.Services/DomainModels/Forms/A2FormFields.cs @@ -8,6 +8,7 @@ public class A2FormFields : IFormFields public int? INBIRMO { get; set; } public int? INBIRYR { get; set; } public int? INSEX { get; set; } + public int? NEWINF { get; set; } public int? INHISP { get; set; } public int? INHISPOR { get; set; } public string INHISPOX { get; set; } @@ -45,6 +46,7 @@ public A2FormFields(FormDto dto) : this() this.INBIRMO = a2Dto.INBIRMO; this.INBIRYR = a2Dto.INBIRYR; this.INSEX = a2Dto.INSEX; + this.NEWINF = a2Dto.NEWINF; this.INHISP = a2Dto.INHISP; this.INHISPOR = a2Dto.INHISPOR; this.INHISPOX = a2Dto.INHISPOX; @@ -61,6 +63,7 @@ public A2FormFields(FormDto dto) : this() this.INVISITS = a2Dto.INVISITS; this.INCALLS = a2Dto.INCALLS; this.INRELY = a2Dto.INRELY; + this.NEWINF = a2Dto.NEWINF; } } } diff --git a/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs b/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs index 0eb03825..89617d50 100644 --- a/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs +++ b/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs @@ -337,7 +337,8 @@ public static A2Dto ToDto(this A2FormFields fields) INLIVWTH = fields.INLIVWTH, INVISITS = fields.INVISITS, INCALLS = fields.INCALLS, - INRELY = fields.INRELY + INRELY = fields.INRELY, + NEWINF = fields.NEWINF }; }