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)
{
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
};
}