Fixed Installer Issue
This commit is contained in:
@@ -46,6 +46,10 @@ public class PunchingController extends AbstractAuthenticatedController {
|
||||
private static final String DUPLICATE_DETAILS_ROUTE = "findsdet";
|
||||
private static final String LOCALITY_ROUTE = "getlocality";
|
||||
private static final String EDIT_GRID_ROUTE = "editgrid";
|
||||
private static final String GET_PUNCHED_RECORDS = "punchedrecs";
|
||||
private static final String GET_PAYLOAD_KEY = "payload-key";
|
||||
private static final String SAVE_APPLICATION = "application-save";
|
||||
private static final String GET_CASE_LIST = "caselist";
|
||||
private final PunchingService punchingService;
|
||||
private final PayloadCryptoService cryptoService;
|
||||
|
||||
@@ -56,20 +60,19 @@ public class PunchingController extends AbstractAuthenticatedController {
|
||||
this.cryptoService = cryptoService;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "payload-key", method = RequestMethod.GET,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(value = GET_PAYLOAD_KEY, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> caseSaveKey(HttpSession httpSession) {
|
||||
ApiAuthorization authorization = authorizeApiPage(INIT_VIEW_ROUTE, httpSession);
|
||||
if (!authorization.isGranted()) return error(authorization.error());
|
||||
if (!authorization.isGranted())
|
||||
return error(authorization.error());
|
||||
return ResponseEntity.ok(Map.of(
|
||||
"keyId", cryptoService.keyId(),
|
||||
"algorithm", "RSA-OAEP-256",
|
||||
"publicKey", cryptoService.encodedPublicKey()));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "punchedrecs", method = RequestMethod.GET,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(value = GET_PUNCHED_RECORDS, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<ApiResponse<PunchedRecordsData>> punchedRecords(
|
||||
@RequestParam("portfolioId") Short portfolioId,
|
||||
@@ -96,8 +99,7 @@ public class PunchingController extends AbstractAuthenticatedController {
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = DUPLICATE_DETAILS_ROUTE, method = RequestMethod.GET,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(value = DUPLICATE_DETAILS_ROUTE, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<ApiResponse<DuplicateDetailsData>> findDuplicateDetails(
|
||||
@RequestParam("applicationNumber") String applicationNumber,
|
||||
@@ -125,8 +127,7 @@ public class PunchingController extends AbstractAuthenticatedController {
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = LOCALITY_ROUTE, method = RequestMethod.GET,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(value = LOCALITY_ROUTE, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<ApiResponse<LocalityData>> findLocalities(
|
||||
@RequestParam("city") String city,
|
||||
@@ -152,14 +153,13 @@ public class PunchingController extends AbstractAuthenticatedController {
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "application-save", method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_JSON_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(value = SAVE_APPLICATION, method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<ApiResponse<ApplicationSaveData>> saveApplication(
|
||||
@RequestBody CaseSaveRequest request, HttpSession httpSession) {
|
||||
ApiAuthorization authorization = authorizeApiPage(INIT_VIEW_ROUTE, httpSession);
|
||||
if (!authorization.isGranted()) return applicationError(authorization.error());
|
||||
if (!authorization.isGranted())
|
||||
return applicationError(authorization.error());
|
||||
try {
|
||||
ApplicationDetails details = cryptoService.decrypt(request, ApplicationDetails.class);
|
||||
ApplicationSaveResult saved = punchingService.saveApplication(details, authorization.session());
|
||||
@@ -253,7 +253,7 @@ public class PunchingController extends AbstractAuthenticatedController {
|
||||
return "edp/punching/editcases";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "caselist", method = RequestMethod.POST)
|
||||
@RequestMapping(value = GET_CASE_LIST, method = RequestMethod.POST)
|
||||
public String listEditableCases(
|
||||
@ModelAttribute("caseGrid") CaseGrid caseGrid,
|
||||
ModelMap model,
|
||||
|
||||
@@ -31,8 +31,7 @@ import lib.models.LocalityOption;
|
||||
import lib.models.UserSession;
|
||||
import lib.constants.ApplicationMessage;
|
||||
import lib.exceptions.ApplicationException;
|
||||
import matrix.nimble.edp.punching.model.PunchingHandler;
|
||||
import matrix.nimble.utilities.GlobalClass;
|
||||
import matrix.nimble.utilities.CommonFunctions;
|
||||
import matrix.services.commons.CommonService;
|
||||
|
||||
@Service
|
||||
@@ -55,12 +54,14 @@ public class PunchingService {
|
||||
private static final int OFFICE_DETAILS_QUERY = 20;
|
||||
private static final int PROPERTY_DETAILS_QUERY = 21;
|
||||
private static final int CO_APPLICANT_DETAILS_QUERY = 22;
|
||||
private static final int VISIBLE_SECTIONS_QUERY = 10;
|
||||
private static final int DYNAMIC_CONTROLS_QUERY = 74;
|
||||
private static final Short CASE_INITIATION_PAGE = Short.valueOf((short) 10);
|
||||
private static final String ADD_CASE_TEMPLATE = "ADDCASE";
|
||||
private static final Pattern DYNAMIC_FIELD = Pattern.compile(
|
||||
"(?:field(?:[1-9]|1[0-2]|150(?:_2)?)|dtfield1)", Pattern.CASE_INSENSITIVE);
|
||||
private static final SqlArrayParameter GENERAL_OPTION_TYPES =
|
||||
SqlArrayParameter.text("CITY", "APPTYPE");
|
||||
private static final SqlArrayParameter PORTFOLIO_OPTION_TYPES =
|
||||
SqlArrayParameter.text("CATEGORY", "PRODUCT");
|
||||
private static final SqlArrayParameter GENERAL_OPTION_TYPES = SqlArrayParameter.text("CITY", "APPTYPE");
|
||||
private static final SqlArrayParameter PORTFOLIO_OPTION_TYPES = SqlArrayParameter.text("CATEGORY", "PRODUCT");
|
||||
|
||||
private final CommonService commonService;
|
||||
private final CygnusDbExecutor dbExecutor;
|
||||
@@ -89,8 +90,9 @@ public class PunchingService {
|
||||
try {
|
||||
String json = objectMapper.writeValueAsString(details);
|
||||
ApplicationSaveResult result = dbExecutor.procedure("APPLICATION_SAVE",
|
||||
new Object[] {json, session.getCompanyId(), session.getBranchId(),
|
||||
session.getUserId()}, ApplicationSaveResult.class);
|
||||
new Object[] { json, session.getCompanyId(), session.getBranchId(),
|
||||
session.getUserId() },
|
||||
ApplicationSaveResult.class);
|
||||
if (result == null || result.getApplicationId() == null) {
|
||||
throw new ApplicationException(
|
||||
ApplicationMessage.APPLICATION_SAVE_FAILED, "Database returned no application result");
|
||||
@@ -150,7 +152,8 @@ public class PunchingService {
|
||||
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Portfolio is required");
|
||||
}
|
||||
String caseUuid = documentCaseId != null && documentCaseId.trim().length() > 20
|
||||
? documentCaseId.trim() : "";
|
||||
? documentCaseId.trim()
|
||||
: "";
|
||||
try {
|
||||
List<RowView> rows = dbExecutor.query(PUNCHED_RECORDS_QUERY, new Object[] {
|
||||
caseUuid, caseUuid, caseUuid, portfolioId,
|
||||
@@ -178,11 +181,11 @@ public class PunchingService {
|
||||
Date receivedDate = Date.valueOf(LocalDate.now());
|
||||
Object[] parameters = switch (queryId) {
|
||||
case RESIDENCE_DETAILS_QUERY, OFFICE_DETAILS_QUERY, CO_APPLICANT_DETAILS_QUERY ->
|
||||
new Object[] {applicationNumber.trim(), portfolioId, receivedDate,
|
||||
session.getCompanyId(), session.getBranchId()};
|
||||
new Object[] { applicationNumber.trim(), portfolioId, receivedDate,
|
||||
session.getCompanyId(), session.getBranchId() };
|
||||
case PROPERTY_DETAILS_QUERY ->
|
||||
new Object[] {applicationNumber.trim(), portfolioId,
|
||||
session.getCompanyId(), session.getBranchId(), receivedDate};
|
||||
new Object[] { applicationNumber.trim(), portfolioId,
|
||||
session.getCompanyId(), session.getBranchId(), receivedDate };
|
||||
default -> throw new ApplicationException(
|
||||
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Unsupported duplicate search type");
|
||||
};
|
||||
@@ -237,13 +240,16 @@ public class PunchingService {
|
||||
private Map<String, Object> toPunchedRecord(RowView row) {
|
||||
Map<String, Object> record = new LinkedHashMap<>();
|
||||
row.asMap().forEach((name, value) -> {
|
||||
if (!"dynamic_fields".equalsIgnoreCase(name)) record.put(name, value == null ? "" : value);
|
||||
if (!"dynamic_fields".equalsIgnoreCase(name))
|
||||
record.put(name, value == null ? "" : value);
|
||||
});
|
||||
Object dynamicValue = row.get("dynamic_fields");
|
||||
if (dynamicValue == null || dynamicValue.toString().isBlank()) return record;
|
||||
if (dynamicValue == null || dynamicValue.toString().isBlank())
|
||||
return record;
|
||||
try {
|
||||
Map<String, Object> dynamicFields = objectMapper.readValue(
|
||||
dynamicValue.toString(), new TypeReference<Map<String, Object>>() {});
|
||||
dynamicValue.toString(), new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
dynamicFields.forEach((name, value) -> {
|
||||
if (name != null && DYNAMIC_FIELD.matcher(name).matches()) {
|
||||
record.put(name, value == null ? "" : value);
|
||||
@@ -326,16 +332,15 @@ public class PunchingService {
|
||||
"Database read failed", exception);
|
||||
}
|
||||
|
||||
private boolean blank(String value) { return value == null || value.isBlank(); }
|
||||
private boolean blank(String value) {
|
||||
return value == null || value.isBlank();
|
||||
}
|
||||
|
||||
public CasePunching init(
|
||||
Short branchId,
|
||||
Short userId,
|
||||
String verificationCaseId,
|
||||
String documentCaseId) {
|
||||
PunchingHandler punchingHandler = new PunchingHandler();
|
||||
punchingHandler.setErrCode("1001");
|
||||
|
||||
CasePunching casePunching = new CasePunching();
|
||||
Map<String, List<Option>> options = new LinkedHashMap<>();
|
||||
List<Option> portfolios = commonService.getOptions(
|
||||
@@ -376,41 +381,97 @@ public class PunchingService {
|
||||
}
|
||||
|
||||
Short portfolioId = submitted.getPortfolioId();
|
||||
PunchingHandler punchingHandler = new PunchingHandler();
|
||||
punchingHandler.setErrCode("1001");
|
||||
punchingHandler.setPortfolioid(Short.toString(portfolioId));
|
||||
punchingHandler.setProcessFlag(true);
|
||||
punchingHandler.DynamicHtml("10");
|
||||
|
||||
if (punchingHandler.isProcessFlag()) {
|
||||
result.setDynamicFields(defaultString(punchingHandler.getDynamicfields()));
|
||||
result.setDynamicHtml(defaultString(punchingHandler.getDynamicpanel()));
|
||||
String sections = defaultString(punchingHandler.GetVisibleSections())
|
||||
+ defaultString(punchingHandler.getDynamicsection());
|
||||
result.setVisibleSections(toVisibleSections(sections));
|
||||
} else {
|
||||
result.setDynamicFields("");
|
||||
result.setDynamicHtml("");
|
||||
result.setVisibleSections(List.of());
|
||||
result.setMessageDetails(new MessageDetails(ApplicationMessage.INTERNAL_SERVER_ERROR));
|
||||
try {
|
||||
DynamicContent dynamicContent = loadDynamicContent(portfolioId);
|
||||
result.setDynamicFields(dynamicContent.fields());
|
||||
result.setDynamicHtml(dynamicContent.html());
|
||||
result.setVisibleSections(dynamicContent.visibleSections());
|
||||
} catch (RuntimeException exception) {
|
||||
throw databaseReadFailure(exception);
|
||||
}
|
||||
|
||||
result.setOptions(loadOptions(branchId, companyId, portfolioId));
|
||||
return result;
|
||||
}
|
||||
|
||||
private DynamicContent loadDynamicContent(Short portfolioId) {
|
||||
if (dbExecutor == null) {
|
||||
throw new IllegalStateException("Database dependencies are not configured");
|
||||
}
|
||||
List<String> visibleSections = dbExecutor.query(
|
||||
VISIBLE_SECTIONS_QUERY,
|
||||
new Object[] {CASE_INITIATION_PAGE, portfolioId})
|
||||
.stream()
|
||||
.map(row -> rowText(row, "control").trim())
|
||||
.filter(value -> !value.isEmpty())
|
||||
.distinct()
|
||||
.collect(java.util.stream.Collectors.toCollection(java.util.ArrayList::new));
|
||||
|
||||
List<RowView> controls = dbExecutor.query(
|
||||
DYNAMIC_CONTROLS_QUERY,
|
||||
new Object[] {portfolioId, CASE_INITIATION_PAGE, ADD_CASE_TEMPLATE});
|
||||
if (controls.isEmpty()) {
|
||||
return new DynamicContent("", "", List.copyOf(visibleSections));
|
||||
}
|
||||
|
||||
CommonFunctions controlsRenderer = new CommonFunctions();
|
||||
controlsRenderer.setGeneratedHtml("");
|
||||
controlsRenderer.setPrevControl("");
|
||||
controlsRenderer.setDynamicCtrls("");
|
||||
StringBuilder html = new StringBuilder();
|
||||
for (RowView row : controls) {
|
||||
String container = controlsRenderer.DynamicControls(
|
||||
dynamicControlValues(row), "");
|
||||
if (!"Othersec".equals(container)) {
|
||||
continue;
|
||||
}
|
||||
String generated = defaultString(controlsRenderer.getGeneratedHtml());
|
||||
trimDuplicateSelectClosing(html, generated);
|
||||
html.append(generated);
|
||||
}
|
||||
visibleSections.add("section6");
|
||||
return new DynamicContent(
|
||||
defaultString(controlsRenderer.getDynamicCtrls()),
|
||||
html.toString(),
|
||||
visibleSections.stream().distinct().toList());
|
||||
}
|
||||
|
||||
private String[] dynamicControlValues(RowView row) {
|
||||
String[] columns = {
|
||||
"field_id", "label", "controlid", "cssclass", "containerid", "maxlength",
|
||||
"onclick", "ondbclick", "onfocus", "onblur", "onkeypress", "onkeydown",
|
||||
"onkeyup", "onchange", "ctrltype", "ctrlwidth", "ctrlheight", "defaultvalue",
|
||||
"fieldorder", "fieldvalue", "valorder", "page_id", "portfolio_id",
|
||||
"template_id", "template", "template_type", "isvisible"
|
||||
};
|
||||
String[] values = new String[columns.length];
|
||||
for (int index = 0; index < columns.length; index++) {
|
||||
values[index] = rowText(row, columns[index]);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private void trimDuplicateSelectClosing(StringBuilder html, String generated) {
|
||||
String closing = "</select></div></div></div>";
|
||||
if (html.toString().endsWith(closing)
|
||||
&& generated.endsWith(closing)
|
||||
&& !generated.startsWith("<div class='widget'>")) {
|
||||
html.setLength(html.length() - closing.length());
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, List<Option>> loadOptions(
|
||||
Short branchId, Short companyId, Short portfolioId) {
|
||||
|
||||
Map<String, List<Option>> options = new LinkedHashMap<>();
|
||||
addOptions(options, PORTFOLIO, commonService.getOptions(
|
||||
3, new Object[] {branchId, ACTIVE}));
|
||||
3, new Object[] { branchId, ACTIVE }));
|
||||
addOptions(options, BRANCH, commonService.getOptions(
|
||||
4, new Object[] {portfolioId, ACTIVE}));
|
||||
4, new Object[] { portfolioId, ACTIVE }));
|
||||
addGroupedOptions(options, commonService.getOptions(
|
||||
5, new Object[] {companyId, GENERAL_OPTION_TYPES}));
|
||||
5, new Object[] { companyId, GENERAL_OPTION_TYPES }));
|
||||
addGroupedOptions(options, commonService.getOptions(
|
||||
70, new Object[] {portfolioId, PORTFOLIO_OPTION_TYPES}));
|
||||
70, new Object[] { portfolioId, PORTFOLIO_OPTION_TYPES }));
|
||||
return freezeOptions(options);
|
||||
}
|
||||
|
||||
@@ -471,9 +532,12 @@ public class PunchingService {
|
||||
if (DATABASE_APPLICATION_TYPE.equalsIgnoreCase(normalized)) {
|
||||
return APPLICATION_TYPE;
|
||||
}
|
||||
if (CITY.equalsIgnoreCase(normalized)) return CITY;
|
||||
if (CATEGORY.equalsIgnoreCase(normalized)) return CATEGORY;
|
||||
if (PRODUCT.equalsIgnoreCase(normalized)) return PRODUCT;
|
||||
if (CITY.equalsIgnoreCase(normalized))
|
||||
return CITY;
|
||||
if (CATEGORY.equalsIgnoreCase(normalized))
|
||||
return CATEGORY;
|
||||
if (PRODUCT.equalsIgnoreCase(normalized))
|
||||
return PRODUCT;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -486,18 +550,13 @@ public class PunchingService {
|
||||
return Collections.unmodifiableMap(immutable);
|
||||
}
|
||||
|
||||
private List<String> toVisibleSections(String sections) {
|
||||
if (sections == null || sections.isBlank()) {
|
||||
return List.of();
|
||||
}
|
||||
return List.of(sections.split(Pattern.quote(GlobalClass.ColDelim))).stream()
|
||||
.map(String::trim)
|
||||
.filter(section -> !section.isEmpty() && !"null".equalsIgnoreCase(section))
|
||||
.distinct()
|
||||
.toList();
|
||||
}
|
||||
|
||||
private String defaultString(String value) {
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
private record DynamicContent(
|
||||
String fields,
|
||||
String html,
|
||||
List<String> visibleSections) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import java.sql.Date;
|
||||
import java.time.LocalDate;
|
||||
import lib.exceptions.ApplicationException;
|
||||
import lib.models.PunchedRecordsData;
|
||||
import lib.models.CasePunching;
|
||||
import lib.models.UserSession;
|
||||
import lib.models.Option;
|
||||
import matrix.services.commons.CommonService;
|
||||
@@ -152,6 +153,40 @@ class PunchingServiceTest {
|
||||
() -> options.put("other.", List.of()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void preparesNewApplicationWithoutLegacyPunchingHandlerQueries() {
|
||||
List<Call> databaseCalls = new ArrayList<>();
|
||||
CygnusDbExecutor executor = (CygnusDbExecutor) Proxy.newProxyInstance(
|
||||
getClass().getClassLoader(), new Class<?>[] {CygnusDbExecutor.class},
|
||||
(proxy, method, args) -> {
|
||||
if (!method.getName().equals("query") || args.length != 2) {
|
||||
throw new UnsupportedOperationException(method.toString());
|
||||
}
|
||||
int queryId = (Integer) args[0];
|
||||
databaseCalls.add(new Call(queryId, ((Object[]) args[1]).clone()));
|
||||
return queryId == 10
|
||||
? List.of(row(new LinkedHashMap<>(Map.of("control", "section1"))))
|
||||
: List.of();
|
||||
});
|
||||
PunchingService service = new PunchingService(
|
||||
new RecordingCommonService(), executor, new ObjectMapper());
|
||||
CasePunching submitted = new CasePunching();
|
||||
submitted.setPortfolioId((short) 38);
|
||||
|
||||
CasePunching result = service.prepareNewApplication(
|
||||
submitted, (short) 5, (short) 1, (short) 9);
|
||||
|
||||
assertEquals(List.of(10, 74),
|
||||
databaseCalls.stream().map(Call::queryId).toList());
|
||||
assertArrayEquals(new Object[] {(short) 10, (short) 38},
|
||||
databaseCalls.get(0).parameters());
|
||||
assertArrayEquals(new Object[] {(short) 38, (short) 10, "ADDCASE"},
|
||||
databaseCalls.get(1).parameters());
|
||||
assertEquals(List.of("section1"), result.getVisibleSections());
|
||||
assertEquals("", result.getDynamicHtml());
|
||||
assertEquals("", result.getDynamicFields());
|
||||
}
|
||||
|
||||
private static final class RecordingCommonService extends CommonService {
|
||||
private final List<Call> calls = new ArrayList<>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user