Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/Config/AppConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public static Javalin appFactory(DeploymentLevel deploymentLevel) {
new MailController(mailDao, fileDao, encryptionController, deploymentLevel);
FileBackfillController backfillController = new FileBackfillController(db, fileDao, userDao);
PdfControllerV2 pdfControllerV2 =
new PdfControllerV2(fileDao, formDao, activityDao, userDao, encryptionController);
new PdfControllerV2(fileDao, formDao, activityDao, orgDao, userDao, encryptionController);
// try { do not recommend this block of code, this will delete and regenerate our encryption
// key
// System.out.println("generating keyset");
Expand Down
25 changes: 23 additions & 2 deletions src/main/PDF/PdfControllerV2.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import Database.Activity.ActivityDao;
import Database.File.FileDao;
import Database.Form.FormDao;
import Database.Organization.OrgDao;
import Database.User.UserDao;
import File.IdCategoryType;
import PDF.Services.V2Services.*;
Expand All @@ -29,6 +30,7 @@ public class PdfControllerV2 {
private FileDao fileDao;
private ActivityDao activityDao;
private UserDao userDao;
private OrgDao orgDao;

// Needed for EncryptionController
private EncryptionController encryptionController;
Expand All @@ -37,11 +39,13 @@ public PdfControllerV2(
FileDao fileDao,
FormDao formDao,
ActivityDao activityDao,
OrgDao orgDao,
UserDao userDao,
EncryptionController encryptionController) {
this.fileDao = fileDao;
this.formDao = formDao;
this.activityDao = activityDao;
this.orgDao = orgDao;
this.userDao = userDao;
this.encryptionController = encryptionController;
}
Expand Down Expand Up @@ -172,7 +176,7 @@ public PdfControllerV2(
}
UploadSignedPDFServiceV2 uploadSignedPDFServiceV2 =
new UploadSignedPDFServiceV2(
fileDao, formDao, activityDao, userParams, fileParams, encryptionController);
fileDao, formDao, activityDao, userDao, userParams, fileParams, encryptionController);
ctx.result(uploadSignedPDFServiceV2.executeAndGetResponse().toResponseString());
};

Expand All @@ -185,7 +189,7 @@ public PdfControllerV2(
userParams.setUserParamsGetApplicationQuestions(ctx, req);
fileParams.setFileParamsGetApplicationQuestions(req);
GetQuestionsPDFServiceV2 getQuestionsPDFServiceV2 =
new GetQuestionsPDFServiceV2(formDao, userDao, userParams, fileParams);
new GetQuestionsPDFServiceV2(formDao, userDao, orgDao, userParams, fileParams);
Message response = getQuestionsPDFServiceV2.executeAndGetResponse();
if (response != PdfMessage.SUCCESS) {
ctx.result(response.toResponseString());
Expand Down Expand Up @@ -218,13 +222,15 @@ public PdfControllerV2(

public static class UserParams {
private String username;
private String workerUsername;
private String organizationName;
private UserType privilegeLevel;

public UserParams() {}

public UserParams(String username, String organizationName, UserType privilegeLevel) {
this.username = username;
this.workerUsername = username;
this.organizationName = organizationName;
this.privilegeLevel = privilegeLevel;
}
Expand Down Expand Up @@ -265,6 +271,7 @@ public Message setUserParamsFillAndUploadSignedPDF(Context ctx) {
String clientUsernameParameter = Objects.requireNonNull(ctx.formParam("clientUsername"));
this.username =
clientUsernameParameter.equals("") ? sessionUsername : clientUsernameParameter;
this.workerUsername = sessionUsername;
} catch (Exception e) {
return PdfMessage.INVALID_PARAMETER;
}
Expand All @@ -275,6 +282,7 @@ public Message setUserParamsFillAndUploadSignedPDF(Context ctx) {

public void setUserParamsUploadAnnotatedPDF(Context ctx) {
this.username = ctx.sessionAttribute("username");
this.workerUsername = ctx.sessionAttribute("username");
this.organizationName = ctx.sessionAttribute("orgName");
this.privilegeLevel = UserType.Developer;
}
Expand All @@ -284,6 +292,8 @@ public void setUserParamsGetApplicationQuestions(Context ctx, JSONObject req) {
String clientUsernameParameter = req.getString("clientUsername");
this.username =
clientUsernameParameter.equals("") ? sessionUsername : clientUsernameParameter;
this.workerUsername = sessionUsername;
this.organizationName = ctx.sessionAttribute("orgName");
this.privilegeLevel = ctx.sessionAttribute("privilegeLevel");
}

Expand Down Expand Up @@ -328,12 +338,14 @@ public Message setUserParamsFromTargetUser(User targetUser, Context ctx) {
}
this.username = targetUser.getUsername();
this.organizationName = targetUserOrg;
this.workerUsername = ctx.sessionAttribute("username");
this.privilegeLevel = targetUser.getUserType();
return null;
}

public Message setUserParamsFromSessionUser(Context ctx) {
this.username = ctx.sessionAttribute("username");
this.workerUsername = this.username;
this.organizationName = ctx.sessionAttribute("orgName");
this.privilegeLevel = ctx.sessionAttribute("privilegeLevel");
return null;
Expand All @@ -348,6 +360,15 @@ public UserParams setUsername(String username) {
return this;
}

public String getWorkerUsername() {
return workerUsername;
}

public UserParams setWorkerUsername(String workerUsername) {
this.workerUsername = workerUsername;
return this;
}

public String getOrganizationName() {
return organizationName;
}
Expand Down
151 changes: 133 additions & 18 deletions src/main/PDF/Services/V2Services/GetQuestionsPDFServiceV2.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@
import Config.Message;
import Config.Service;
import Database.Form.FormDao;
import Database.Organization.OrgDao;
import Database.User.UserDao;
import Form.FieldType;
import Form.Form;
import Form.FormQuestion;
import Form.FormSection;
import Organization.Organization;
import PDF.PdfControllerV2.FileParams;
import PDF.PdfControllerV2.UserParams;
import PDF.PdfMessage;
import User.Address;
import User.Services.GetUserInfoService;
import User.UserMessage;
import User.UserType;
import Validation.ValidationUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
Expand All @@ -30,12 +34,17 @@
public class GetQuestionsPDFServiceV2 implements Service {
private FormDao formDao;
private UserDao userDao;
private String username;
private OrgDao orgDao;
private String clientUsername;
private String workerUsername;
private String orgName;
private UserType privilegeLevel;
private String fileId;
private JSONObject applicationInformation;
private Form form;
private Map<String, String> flattenedFieldMap;
private Map<String, String> clientFieldMap;
private Map<String, String> workerFieldMap;
private Map<String, String> orgFieldMap;
private FormQuestion currentFormQuestion;

/** Alias map: common alternative field names -> canonical flattened map keys. */
Expand All @@ -58,12 +67,23 @@ public class GetQuestionsPDFServiceV2 implements Service {

public GetQuestionsPDFServiceV2(
FormDao formDao, UserDao userDao, UserParams userParams, FileParams fileParams) {
this(formDao, userDao, null, userParams, fileParams);
}

public GetQuestionsPDFServiceV2(
FormDao formDao, UserDao userDao, OrgDao orgDao, UserParams userParams, FileParams fileParams) {
this.formDao = formDao;
this.userDao = userDao;
this.username = userParams.getUsername();
this.orgDao = orgDao;
this.clientUsername = userParams.getUsername();
this.workerUsername = userParams.getWorkerUsername();
this.orgName = userParams.getOrganizationName();
this.privilegeLevel = userParams.getPrivilegeLevel();
this.fileId = fileParams.getFileId();
this.applicationInformation = new JSONObject();
this.clientFieldMap = new HashMap<>();
this.workerFieldMap = new HashMap<>();
this.orgFieldMap = new HashMap<>();
}

public JSONObject getApplicationInformation() {
Expand All @@ -76,12 +96,34 @@ public Message executeAndGetResponse() {
if (getQuestionsConditionsErrorMessage != null) {
return getQuestionsConditionsErrorMessage;
}
GetUserInfoService getUserInfoService = new GetUserInfoService(userDao, username);
GetUserInfoService getUserInfoService = new GetUserInfoService(userDao, clientUsername);
Message getUserInfoServiceResponse = getUserInfoService.executeAndGetResponse();
if (getUserInfoServiceResponse != UserMessage.SUCCESS) {
return getUserInfoServiceResponse;
}
this.flattenedFieldMap = getUserInfoService.getFlattenedFieldMap();
this.clientFieldMap = getUserInfoService.getFlattenedFieldMap();

if (workerUsername == null || workerUsername.isBlank() || workerUsername.equals(clientUsername)) {
this.workerFieldMap = this.clientFieldMap;
} else {
GetUserInfoService workerInfoService = new GetUserInfoService(userDao, workerUsername);
Message workerInfoResponse = workerInfoService.executeAndGetResponse();
if (workerInfoResponse == UserMessage.SUCCESS) {
this.workerFieldMap = workerInfoService.getFlattenedFieldMap();
} else {
log.warn(
"Could not load worker profile '{}' for getQuestions; leaving worker.* unmatched",
workerUsername);
this.workerFieldMap = new HashMap<>();
}
}

this.orgFieldMap = new HashMap<>();
if (orgDao != null && orgName != null && !orgName.isBlank()) {
Optional<Organization> orgOptional = orgDao.get(orgName);
orgOptional.ifPresent(organization -> this.orgFieldMap = flattenOrganization(organization));
}

return getQuestions();
}

Expand Down Expand Up @@ -183,24 +225,48 @@ private static String humanizeFieldName(String fieldName) {
* (graceful degradation -- never errors).
*/
private void matchFieldFromFlattenedMap(FormQuestion fq, String directive) {
if (this.flattenedFieldMap == null) {
log.warn("Flattened field map is null; cannot match directive '{}'", directive);
return;
String source = "client";
String field = directive;

int dotIndex = directive.indexOf('.');
if (dotIndex > 0) {
String prefix = directive.substring(0, dotIndex);
if (prefix.equals("client") || prefix.equals("worker") || prefix.equals("org")) {
source = prefix;
field = directive.substring(dotIndex + 1);
}
}

Map<String, String> targetMap;
switch (source) {
case "worker":
targetMap = this.workerFieldMap;
break;
case "org":
targetMap = this.orgFieldMap;
break;
default:
targetMap = this.clientFieldMap;
break;
}

if (targetMap == null) {
targetMap = Collections.emptyMap();
}

// 1. Exact key match
String value = this.flattenedFieldMap.get(directive);
String value = targetMap.get(field);

// 2. Alias lookup
if (value == null && FIELD_ALIASES.containsKey(directive)) {
String aliasedKey = FIELD_ALIASES.get(directive);
value = this.flattenedFieldMap.get(aliasedKey);
if (value == null && FIELD_ALIASES.containsKey(field)) {
String aliasedKey = FIELD_ALIASES.get(field);
value = targetMap.get(aliasedKey);
}

// 3. Case-insensitive full-key match
if (value == null) {
for (Map.Entry<String, String> entry : this.flattenedFieldMap.entrySet()) {
if (entry.getKey().equalsIgnoreCase(directive)) {
for (Map.Entry<String, String> entry : targetMap.entrySet()) {
if (entry.getKey().equalsIgnoreCase(field)) {
value = entry.getValue();
break;
}
Expand All @@ -209,11 +275,11 @@ private void matchFieldFromFlattenedMap(FormQuestion fq, String directive) {

// 4. Case-insensitive leaf-key match (e.g. "firstname" matches "optionalInformation.person.firstName")
if (value == null) {
for (Map.Entry<String, String> entry : this.flattenedFieldMap.entrySet()) {
for (Map.Entry<String, String> entry : targetMap.entrySet()) {
String key = entry.getKey();
int lastDot = key.lastIndexOf('.');
String leafKey = lastDot >= 0 ? key.substring(lastDot + 1) : key;
if (leafKey.equalsIgnoreCase(directive)) {
if (leafKey.equalsIgnoreCase(field)) {
value = entry.getValue();
break;
}
Expand All @@ -225,14 +291,63 @@ private void matchFieldFromFlattenedMap(FormQuestion fq, String directive) {
fq.setDefaultValue(value);
} else {
log.debug(
"Field directive '{}' not found in user profile for user '{}'; skipping autofill",
"Field directive '{}' not found in source '{}' for client '{}' / worker '{}' / org '{}'; skipping autofill",
directive,
this.username);
source,
this.clientUsername,
this.workerUsername,
this.orgName);
fq.setMatched(false);
fq.setDefaultValue("");
}
}

private Map<String, String> flattenOrganization(Organization org) {
Map<String, String> map = new HashMap<>();
if (org.getOrgName() != null) {
map.put("name", org.getOrgName());
}
if (org.getOrgPhoneNumber() != null) {
map.put("phone", org.getOrgPhoneNumber());
}
if (org.getOrgEmail() != null) {
map.put("email", org.getOrgEmail());
}
if (org.getOrgWebsite() != null) {
map.put("website", org.getOrgWebsite());
}
if (org.getOrgEIN() != null) {
map.put("ein", org.getOrgEIN());
}

Address addr = org.getOrgAddress();
if (addr != null) {
if (addr.getLine1() != null) {
map.put("address.line1", addr.getLine1());
map.put("address", addr.getLine1());
}
if (addr.getLine2() != null) {
map.put("address.line2", addr.getLine2());
}
if (addr.getCity() != null) {
map.put("address.city", addr.getCity());
map.put("city", addr.getCity());
}
if (addr.getState() != null) {
map.put("address.state", addr.getState());
map.put("state", addr.getState());
}
if (addr.getZip() != null) {
map.put("address.zip", addr.getZip());
map.put("zip", addr.getZip());
}
if (addr.getCounty() != null) {
map.put("address.county", addr.getCounty());
}
}
return map;
}

public Message getQuestions() {
FormSection formBody = form.getBody();
applicationInformation.put("title", formBody.getTitle());
Expand Down
Loading