11 Commits

152 changed files with 3818 additions and 5261 deletions

3
.gitignore vendored
View File

@@ -30,7 +30,8 @@
/.nb-gradle/ /.nb-gradle/
/cygnus-onprem-app/target /cygnus-onprem-app/target
/cygnus-cloud-client/target /cygnus-cloud-client/target
/cygnus-installer/src/test
/cygnus-cloud-service/target /cygnus-cloud-service/target
/cygnus-installer/src/target /cygnus-installer/src/target
/cygnus-installer/target /cygnus-installer/target
/cygnus-onprem-db/target
/cygnus-lib/target

3
.vscode/launch.json vendored
View File

@@ -61,6 +61,7 @@
"REDIS_PASSWORD": "M@triXR3d1s@6202", "REDIS_PASSWORD": "M@triXR3d1s@6202",
"REDIS_DATABASE": "1", "REDIS_DATABASE": "1",
"REDIS_SSL": "false", "REDIS_SSL": "false",
"CYGNUS_QUERY_CACHE_ENABLED": "false",
"CYGNUS_CLOUD_BASE_URL": "http://localhost:8090", "CYGNUS_CLOUD_BASE_URL": "http://localhost:8090",
"CYGNUS_TOKEN_URL": "http://localhost:8090/oauth2/token", "CYGNUS_TOKEN_URL": "http://localhost:8090/oauth2/token",
"CYGNUS_CLIENT_ID": "matrix", "CYGNUS_CLIENT_ID": "matrix",
@@ -68,6 +69,8 @@
"CYGNUS_CLIENT_ASSERTION": "file:${workspaceFolder}/config/clients/matrix/matrix-matrix-delhi-cygnus-01-assertion.jwt", "CYGNUS_CLIENT_ASSERTION": "file:${workspaceFolder}/config/clients/matrix/matrix-matrix-delhi-cygnus-01-assertion.jwt",
"CYGNUS_LOGIN_KEY_ID": "cygnus-login-2026-01", "CYGNUS_LOGIN_KEY_ID": "cygnus-login-2026-01",
"CYGNUS_LOGIN_PUBLIC_KEY": "file:${workspaceFolder}/config/keys/login-public.pem", "CYGNUS_LOGIN_PUBLIC_KEY": "file:${workspaceFolder}/config/keys/login-public.pem",
"CYGNUS_PAYLOAD_PRIVATE_KEY": "file:${workspaceFolder}/config/keys/case-save-private.pem",
"CYGNUS_PAYLOAD_PUBLIC_KEY": "file:${workspaceFolder}/config/keys/case-save-public.pem",
"CYGNUS_CLOUD_REQUEST_TIMEOUT": "PT10S", "CYGNUS_CLOUD_REQUEST_TIMEOUT": "PT10S",
"CYGNUS_TOKEN_REFRESH_SKEW": "PT30S" "CYGNUS_TOKEN_REFRESH_SKEW": "PT30S"
}, },

View File

@@ -62,4 +62,15 @@ public class CloudIdentityClient {
.bodyToMono(CloudQueryResponse.class)) .bodyToMono(CloudQueryResponse.class))
.timeout(properties.requestTimeout()); .timeout(properties.requestTimeout());
} }
public Mono<CloudQueryResponse> fetchQuery(String queryKey) {
return tokenProvider.accessToken()
.flatMap(token -> webClient.get()
.uri(properties.baseUri().resolve("/api/v1/queries/key/" + queryKey))
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(CloudQueryResponse.class))
.timeout(properties.requestTimeout());
}
} }

View File

@@ -25,4 +25,10 @@ public class CloudQueryController {
return repository.findEnabled(queryId) return repository.findEnabled(queryId)
.switchIfEmpty(Mono.error(new QueryNotFoundException(queryId))); .switchIfEmpty(Mono.error(new QueryNotFoundException(queryId)));
} }
@GetMapping("/key/{queryKey}")
public Mono<CloudQuery> queryByKey(@PathVariable String queryKey) {
return repository.findEnabled(queryKey)
.switchIfEmpty(Mono.error(new QueryNotFoundException(queryKey)));
}
} }

View File

@@ -10,8 +10,10 @@ public class QueryCatalogRepository {
private static final String INITIALIZE = """ private static final String INITIALIZE = """
CREATE SCHEMA IF NOT EXISTS platform; CREATE SCHEMA IF NOT EXISTS platform;
CREATE SEQUENCE IF NOT EXISTS platform.application_query_id_seq;
CREATE TABLE IF NOT EXISTS platform.application_query ( CREATE TABLE IF NOT EXISTS platform.application_query (
query_id integer PRIMARY KEY, query_id integer PRIMARY KEY DEFAULT nextval('platform.application_query_id_seq'),
query_key varchar(100),
query_text text NOT NULL, query_text text NOT NULL,
enabled boolean NOT NULL DEFAULT true, enabled boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT current_timestamp, created_at timestamptz NOT NULL DEFAULT current_timestamp,
@@ -20,7 +22,15 @@ public class QueryCatalogRepository {
CHECK (query_id > 0), CHECK (query_id > 0),
CONSTRAINT ck_platform_application_query_text CONSTRAINT ck_platform_application_query_text
CHECK (length(btrim(query_text)) > 0) CHECK (length(btrim(query_text)) > 0)
) );
ALTER TABLE platform.application_query
ADD COLUMN IF NOT EXISTS query_key varchar(100);
ALTER TABLE platform.application_query ALTER COLUMN query_id
SET DEFAULT nextval('platform.application_query_id_seq');
CREATE UNIQUE INDEX IF NOT EXISTS ux_platform_application_query_key
ON platform.application_query (query_key) WHERE query_key IS NOT NULL;
SELECT setval('platform.application_query_id_seq',
greatest(coalesce((SELECT max(query_id) FROM platform.application_query), 0) + 1, 1), false)
"""; """;
private static final String FIND = """ private static final String FIND = """
SELECT query_id, query_text SELECT query_id, query_text
@@ -28,6 +38,12 @@ public class QueryCatalogRepository {
WHERE query_id = $1 WHERE query_id = $1
AND enabled = true AND enabled = true
"""; """;
private static final String FIND_BY_KEY = """
SELECT query_id, query_text
FROM platform.application_query
WHERE query_key = $1
AND enabled = true
""";
private final ReactiveDatabaseClient database; private final ReactiveDatabaseClient database;
public QueryCatalogRepository(ReactiveDatabaseClient database) { public QueryCatalogRepository(ReactiveDatabaseClient database) {
@@ -45,4 +61,11 @@ public class QueryCatalogRepository {
.map(row -> new CloudQuery( .map(row -> new CloudQuery(
row.getInteger("query_id"), row.getString("query_text"))); row.getInteger("query_id"), row.getString("query_text")));
} }
public Mono<CloudQuery> findEnabled(String queryKey) {
return database.preparedQuery(FIND_BY_KEY, Tuple.of(queryKey))
.flatMapMany(rows -> reactor.core.publisher.Flux.fromIterable(rows))
.next()
.map(row -> new CloudQuery(row.getInteger("query_id"), row.getString("query_text")));
}
} }

View File

@@ -9,4 +9,8 @@ public class QueryNotFoundException extends RuntimeException {
public QueryNotFoundException(int queryId) { public QueryNotFoundException(int queryId) {
super("Query was not found: " + queryId); super("Query was not found: " + queryId);
} }
public QueryNotFoundException(String queryKey) {
super("Query was not found: " + queryKey);
}
} }

View File

@@ -1,7 +1,9 @@
CREATE SCHEMA IF NOT EXISTS platform; CREATE SCHEMA IF NOT EXISTS platform;
CREATE SEQUENCE IF NOT EXISTS platform.application_query_id_seq;
CREATE TABLE IF NOT EXISTS platform.application_query ( CREATE TABLE IF NOT EXISTS platform.application_query (
query_id integer PRIMARY KEY, query_id integer PRIMARY KEY DEFAULT nextval('platform.application_query_id_seq'),
query_key varchar(100),
query_text text NOT NULL, query_text text NOT NULL,
enabled boolean NOT NULL DEFAULT true, enabled boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT current_timestamp, created_at timestamptz NOT NULL DEFAULT current_timestamp,
@@ -11,3 +13,11 @@ CREATE TABLE IF NOT EXISTS platform.application_query (
CONSTRAINT ck_platform_application_query_text CONSTRAINT ck_platform_application_query_text
CHECK (length(btrim(query_text)) > 0) CHECK (length(btrim(query_text)) > 0)
); );
ALTER TABLE platform.application_query
ADD COLUMN IF NOT EXISTS query_key varchar(100);
CREATE UNIQUE INDEX IF NOT EXISTS ux_platform_application_query_key
ON platform.application_query (query_key) WHERE query_key IS NOT NULL;
ALTER TABLE platform.application_query ALTER COLUMN query_id
SET DEFAULT nextval('platform.application_query_id_seq');
SELECT setval('platform.application_query_id_seq',
greatest(coalesce((SELECT max(query_id) FROM platform.application_query), 0) + 1, 1), false);

View File

@@ -0,0 +1,11 @@
-- Stable query key; query_id is generated by PostgreSQL.
BEGIN;
INSERT INTO platform.application_query(query_key, query_text, enabled, created_at, updated_at, ismigrated)
VALUES ('APPLICATION_SAVE',
'procedure!C0L!select * from public.save_application_details(?::jsonb,?::smallint,?::smallint,?::smallint)',
true, clock_timestamp(), clock_timestamp(), true)
ON CONFLICT (query_key) WHERE query_key IS NOT NULL DO UPDATE SET
query_text=excluded.query_text, enabled=true, updated_at=clock_timestamp(), ismigrated=true;
COMMIT;

View File

@@ -1,9 +1,7 @@
package lib.constants; package lib.constants;
import java.util.Arrays; /** Canonical user-facing messages shared by Cygnus applications. */
public enum ApplicationMessage {
/** Canonical user-facing errors shared by Cygnus applications. */
public enum ApplicationError {
BAD_REQUEST(400, "HTTP-400", "Invalid request", BAD_REQUEST(400, "HTTP-400", "Invalid request",
"Cygnus could not process the submitted request.", "Cygnus could not process the submitted request.",
"Review the supplied information and try again."), "Review the supplied information and try again."),
@@ -28,6 +26,28 @@ public enum ApplicationError {
TOO_MANY_REQUESTS(429, "HTTP-429", "Too many requests", TOO_MANY_REQUESTS(429, "HTTP-429", "Too many requests",
"Cygnus has received too many requests in a short period.", "Cygnus has received too many requests in a short period.",
"Wait briefly before trying again."), "Wait briefly before trying again."),
PAYLOAD_INVALID(400, "REQ-4001", "Invalid request details",
"The encrypted request could not be verified.",
"Refresh the page and submit the form again."),
APPLICATION_VALIDATION_FAILED(422, "APP-4221", "Application validation failed",
"One or more application fields contain invalid information.",
"Correct the highlighted fields and submit the application again."),
APPLICATION_ACCESS_DENIED(403, "APP-4031", "Application access denied",
"The selected portfolio or application is not available to your account.",
"Select an authorized portfolio or contact your administrator."),
APPLICATION_SAVE_CONFLICT(409, "APP-4091", "Application save conflict",
"This request was already processed or the application changed.",
"Refresh the application before submitting it again."),
APPLICATION_SAVED(200, "APP-2001", "Application saved",
"The application details were saved successfully.", ""),
APPLICATIONS_LOADED(200, "APP-2002", "Applications loaded",
"The application records were loaded successfully.", ""),
APPLICATION_LOAD_FAILED(500, "APP-5002", "Applications could not be loaded",
"Cygnus could not load the application details.",
"Try again. If the issue continues, share the reference ID with support."),
APPLICATION_SAVE_FAILED(500, "APP-5001", "Application could not be saved",
"Cygnus could not save the application details.",
"Try again. If the issue continues, share the reference ID with support."),
INTERNAL_SERVER_ERROR(500, "HTTP-500", "Something went wrong", INTERNAL_SERVER_ERROR(500, "HTTP-500", "Something went wrong",
"Cygnus could not complete your request.", "Cygnus could not complete your request.",
"Try again. If the issue continues, share the reference ID with support."), "Try again. If the issue continues, share the reference ID with support."),
@@ -47,7 +67,7 @@ public enum ApplicationError {
private final String message; private final String message;
private final String description; private final String description;
ApplicationError( ApplicationMessage(
int httpStatus, String code, String title, String message, String description) { int httpStatus, String code, String title, String message, String description) {
this.httpStatus = httpStatus; this.httpStatus = httpStatus;
this.code = code; this.code = code;
@@ -56,11 +76,21 @@ public enum ApplicationError {
this.description = description; this.description = description;
} }
public static ApplicationError fromHttpStatus(int status) { public static ApplicationMessage fromHttpStatus(int status) {
return Arrays.stream(values()) return switch (status) {
.filter(error -> error.httpStatus == status) case 400 -> BAD_REQUEST;
.findFirst() case 401 -> SESSION_REQUIRED;
.orElse(INTERNAL_SERVER_ERROR); case 403 -> ACCESS_DENIED;
case 404 -> PAGE_NOT_FOUND;
case 405 -> METHOD_NOT_ALLOWED;
case 409 -> CONFLICT;
case 413 -> PAYLOAD_TOO_LARGE;
case 429 -> TOO_MANY_REQUESTS;
case 502 -> BAD_GATEWAY;
case 503 -> SERVICE_UNAVAILABLE;
case 504 -> GATEWAY_TIMEOUT;
default -> INTERNAL_SERVER_ERROR;
};
} }
public int getHttpStatus() { return httpStatus; } public int getHttpStatus() { return httpStatus; }

View File

@@ -0,0 +1,20 @@
package lib.exceptions;
import lib.constants.ApplicationMessage;
/** Single typed application exception carrying a safe user-facing message. */
public class ApplicationException extends RuntimeException {
private final ApplicationMessage applicationMessage;
public ApplicationException(ApplicationMessage message, String technicalMessage) {
super(technicalMessage);
this.applicationMessage = message;
}
public ApplicationException(ApplicationMessage message, String technicalMessage, Throwable cause) {
super(technicalMessage, cause);
this.applicationMessage = message;
}
public ApplicationMessage getApplicationMessage() { return applicationMessage; }
}

View File

@@ -0,0 +1,12 @@
package lib.models;
/** Consistent API response contract for every migrated workflow. */
public record ApiResponse<T>(boolean success, T data, MessageDetails message) {
public static <T> ApiResponse<T> success(T data, MessageDetails message) {
return new ApiResponse<>(true, data, message);
}
public static <T> ApiResponse<T> failure(MessageDetails message) {
return new ApiResponse<>(false, null, message);
}
}

View File

@@ -0,0 +1,87 @@
package lib.models;
import java.io.Serial;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
/** User-editable case initiation data. Identity and audit fields come from UserSession. */
@Getter
@Setter
public class ApplicationDetails implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Integer applicationId;
private Short portfolioId;
private Short bankBranchId;
private String applicationNumber;
private String bankCode;
private String product;
private String loanAmount;
private String customerName;
private String fatherName;
private String applicationType;
private String category;
private String dateOfBirth;
private String contactPerson;
private String mobileNumber;
private String specialInstruction;
private Boolean residenceVerification;
private Boolean residenceTelephoneVerification;
private Boolean officeVerification;
private Boolean officeTelephoneVerification;
private Boolean propertyVerification;
private Boolean referenceVerification;
private Boolean documentVerification;
private Boolean residenceCoApplicant;
private Boolean residenceCoProprietor;
private Boolean officeCoProprietor;
private Boolean sameResidenceAddress;
private Boolean sameOfficeAddress;
private Boolean samePropertyAddress;
private String residenceAddress1;
private String residenceAddress2;
private String residenceAddress3;
private String residenceLandmark;
private Integer residenceColonyId;
private String residenceCity;
private String residencePincode;
private String residencePhone;
private String companyName;
private String officeAddress1;
private String officeAddress2;
private String officeAddress3;
private String officeLandmark;
private Integer officeColonyId;
private String officeCity;
private String officePincode;
private String department;
private String designation;
private String officePhone;
private String extension;
private String propertyAddress1;
private String propertyAddress2;
private String propertyAddress3;
private String propertyLandmark;
private Integer propertyColonyId;
private String propertyCity;
private String propertyPincode;
private String referenceName1;
private String referenceAddress1;
private String referenceContactNumber1;
private String referenceName2;
private String referenceAddress2;
private String referenceContactNumber2;
private Map<String, String> dynamicFields = new LinkedHashMap<>();
private Boolean autoCutOff;
private Integer formMode;
}

View File

@@ -0,0 +1,4 @@
package lib.models;
/** Data returned after saving a loan-verification application. */
public record ApplicationSaveData(String operation, Integer applicationId, String mvCode) {}

View File

@@ -0,0 +1,16 @@
package lib.models;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/** Result row returned by the application-save database operation. */
@Getter
@Setter
@NoArgsConstructor
public class ApplicationSaveResult {
private String operation;
private Integer applicationId;
private String mvCode;
private String internalUuid;
}

View File

@@ -9,11 +9,11 @@ import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class CasePunching { public class CasePunching {
private ErrorDetails errorDetails; private MessageDetails messageDetails;
private Map<String, String> optionsl; private Map<String, String> optionsl;
private Map<String, List<Option>> options; private Map<String, List<Option>> options;
private List<String> visibleSections; private List<String> visibleSections;
private Integer portfolioId; private Short portfolioId;
private Integer formMode; private Integer formMode;
private String userId; private String userId;
private String dynamicFields; private String dynamicFields;

View File

@@ -0,0 +1,11 @@
package lib.models;
/** Hybrid RSA-OAEP/AES-GCM envelope submitted by the initiation page. */
public record CaseSaveRequest(
String keyId,
String encryptedKey,
String initializationVector,
String encryptedPayload,
String requestId,
String timestamp) {
}

View File

@@ -0,0 +1,15 @@
package lib.models;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/** Existing application details used by the case-initiation duplicate checks. */
public record DuplicateDetailsData(List<Map<String, Object>> records) {
public DuplicateDetailsData {
records = records == null ? List.of() : records.stream()
.map(record -> Collections.unmodifiableMap(new LinkedHashMap<>(record)))
.toList();
}
}

View File

@@ -0,0 +1,19 @@
package lib.models;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
public class EditCaseSummary {
private String documentCaseId;
private String mvCode;
private String fileNumber;
private String customerName;
private String applicationType;
private String product;
private String receivedOn;
private String punchedBy;
private String branchCode;
private Short portfolioId;
}

View File

@@ -0,0 +1,10 @@
package lib.models;
import java.util.List;
/** Localities returned to the case-initiation autocomplete. */
public record LocalityData(List<LocalityOption> localities) {
public LocalityData {
localities = localities == null ? List.of() : List.copyOf(localities);
}
}

View File

@@ -0,0 +1,4 @@
package lib.models;
/** One company-authorized locality autocomplete result. */
public record LocalityOption(Integer id, String location, String pincode, String city) {}

View File

@@ -1,6 +1,6 @@
package lib.models; package lib.models;
import lib.constants.ApplicationError; import lib.constants.ApplicationMessage;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.Instant; import java.time.Instant;
@@ -10,37 +10,37 @@ import lombok.Getter;
/** Dependency-free error information shared across Cygnus modules. */ /** Dependency-free error information shared across Cygnus modules. */
@Getter @Getter
public final class ErrorDetails implements Serializable { public final class MessageDetails implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final int httpStatus; private final int httpStatus;
private final String errorCode; private final String code;
private final String title; private final String title;
private final String message; private final String message;
private final String description; private final String description;
private final String referenceId; private final String referenceId;
private final Instant timestamp; private final Instant timestamp;
public ErrorDetails(ApplicationError error) { public MessageDetails(ApplicationMessage message) {
this(error.getHttpStatus(), error.getCode(), error.getTitle(), this(message.getHttpStatus(), message.getCode(), message.getTitle(),
error.getMessage(), error.getDescription(), message.getMessage(), message.getDescription(),
UUID.randomUUID().toString(), Instant.now()); UUID.randomUUID().toString(), Instant.now());
} }
private ErrorDetails( private MessageDetails(
int httpStatus, int httpStatus,
String errorCode, String code,
String title, String title,
String message, String message,
String description, String description,
String referenceId, String referenceId,
Instant timestamp) { Instant timestamp) {
if (httpStatus < 400 || httpStatus > 599) { if (httpStatus < 100 || httpStatus > 599) {
throw new IllegalArgumentException("HTTP error status must be between 400 and 599"); throw new IllegalArgumentException("HTTP status must be between 100 and 599");
} }
this.httpStatus = httpStatus; this.httpStatus = httpStatus;
this.errorCode = required(errorCode, "errorCode"); this.code = required(code, "code");
this.title = required(title, "title"); this.title = required(title, "title");
this.message = required(message, "message"); this.message = required(message, "message");
this.description = description == null ? "" : description.trim(); this.description = description == null ? "" : description.trim();

View File

@@ -8,5 +8,6 @@ import lombok.Setter;
public class Option { public class Option {
private Object value; private Object value;
private String label; private String label;
private String description;
private String group; private String group;
} }

View File

@@ -0,0 +1,15 @@
package lib.models;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Collections;
/** Form-shaped punched applications returned to the case-initiation workspace. */
public record PunchedRecordsData(List<Map<String, Object>> records) {
public PunchedRecordsData {
records = records == null ? List.of() : records.stream()
.map(record -> Collections.unmodifiableMap(new LinkedHashMap<>(record)))
.toList();
}
}

View File

@@ -0,0 +1,29 @@
package lib.models;
import java.io.Serial;
import java.io.Serializable;
import lombok.Builder;
import lombok.Value;
/** Immutable, type-safe representation of an authenticated Cygnus user. */
@Value
@Builder
public class UserSession implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
Short companyId;
String companyName;
String companyCode;
Short branchId;
String branchName;
String branchCode;
String branchLocation;
Short userId;
String username;
String userDisplayName;
Short userGroupId;
String userGroupName;
String loginTime;
String menuHtml;
}

View File

@@ -1,22 +0,0 @@
package lib.models;
import lib.constants.ApplicationError;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class ErrorDetailsTest {
@Test
void createsAReusableErrorContract() {
ErrorDetails details = new ErrorDetails(ApplicationError.ACCESS_DENIED);
assertEquals(403, details.getHttpStatus());
assertEquals("AUTH-403", details.getErrorCode());
}
@Test
void mapsHttpStatusToCanonicalError() {
assertEquals(ApplicationError.PAGE_NOT_FOUND, ApplicationError.fromHttpStatus(404));
assertEquals(ApplicationError.INTERNAL_SERVER_ERROR,
ApplicationError.fromHttpStatus(599));
}
}

View File

@@ -0,0 +1,22 @@
package lib.models;
import lib.constants.ApplicationMessage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class MessageDetailsTest {
@Test
void createsAReusableErrorContract() {
MessageDetails details = new MessageDetails(ApplicationMessage.ACCESS_DENIED);
assertEquals(403, details.getHttpStatus());
assertEquals("AUTH-403", details.getCode());
}
@Test
void mapsHttpStatusToCanonicalError() {
assertEquals(ApplicationMessage.PAGE_NOT_FOUND, ApplicationMessage.fromHttpStatus(404));
assertEquals(ApplicationMessage.INTERNAL_SERVER_ERROR,
ApplicationMessage.fromHttpStatus(599));
}
}

View File

@@ -1,3 +0,0 @@
artifactId=cygnus-lib
groupId=com.cygnus
version=1.0.0-SNAPSHOT

View File

@@ -1,3 +0,0 @@
lib/models/ErrorDetails.class
lib/models/CasePunching.class
lib/constants/ApplicationError.class

View File

@@ -1,4 +0,0 @@
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/constants/ApplicationError.java
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/CasePunching.java
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/ErrorDetails.java
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/Option.java

View File

@@ -1 +0,0 @@
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/test/java/lib/models/ErrorDetailsTest.java

View File

@@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd" version="3.0.2" name="lib.models.ErrorDetailsTest" time="0.024" tests="2" errors="0" skipped="0" failures="0">
<properties>
<property name="java.specification.version" value="25"/>
<property name="sun.jnu.encoding" value="UTF-8"/>
<property name="java.class.path" value="/Users/maddy/Projects/cygnus/matrix/cygnus-lib/target/test-classes:/Users/maddy/Projects/cygnus/matrix/cygnus-lib/target/classes:/Users/maddy/.m2/repository/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter/5.12.2/junit-jupiter-5.12.2.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.12.2/junit-jupiter-api-5.12.2.jar:/Users/maddy/.m2/repository/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/Users/maddy/.m2/repository/org/junit/platform/junit-platform-commons/1.12.2/junit-platform-commons-1.12.2.jar:/Users/maddy/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.12.2/junit-jupiter-params-5.12.2.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.12.2/junit-jupiter-engine-5.12.2.jar:/Users/maddy/.m2/repository/org/junit/platform/junit-platform-engine/1.12.2/junit-platform-engine-1.12.2.jar:"/>
<property name="java.vm.vendor" value="Homebrew"/>
<property name="sun.arch.data.model" value="64"/>
<property name="java.vendor.url" value="https://github.com/Homebrew/homebrew-core/issues"/>
<property name="os.name" value="Mac OS X"/>
<property name="java.vm.specification.version" value="25"/>
<property name="sun.java.launcher" value="SUN_STANDARD"/>
<property name="user.country" value="US"/>
<property name="sun.boot.library.path" value="/opt/homebrew/Cellar/openjdk/25.0.2/libexec/openjdk.jdk/Contents/Home/lib"/>
<property name="sun.java.command" value="/Users/maddy/Projects/cygnus/matrix/cygnus-lib/target/surefire/surefirebooter-20260801204253825_3.jar /Users/maddy/Projects/cygnus/matrix/cygnus-lib/target/surefire 2026-08-01T20-42-53_787-jvmRun1 surefire-20260801204253825_1tmp surefire_0-20260801204253825_2tmp"/>
<property name="http.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="jdk.debug" value="release"/>
<property name="surefire.test.class.path" value="/Users/maddy/Projects/cygnus/matrix/cygnus-lib/target/test-classes:/Users/maddy/Projects/cygnus/matrix/cygnus-lib/target/classes:/Users/maddy/.m2/repository/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter/5.12.2/junit-jupiter-5.12.2.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.12.2/junit-jupiter-api-5.12.2.jar:/Users/maddy/.m2/repository/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/Users/maddy/.m2/repository/org/junit/platform/junit-platform-commons/1.12.2/junit-platform-commons-1.12.2.jar:/Users/maddy/.m2/repository/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.12.2/junit-jupiter-params-5.12.2.jar:/Users/maddy/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.12.2/junit-jupiter-engine-5.12.2.jar:/Users/maddy/.m2/repository/org/junit/platform/junit-platform-engine/1.12.2/junit-platform-engine-1.12.2.jar:"/>
<property name="sun.cpu.endian" value="little"/>
<property name="user.home" value="/Users/maddy"/>
<property name="user.language" value="en"/>
<property name="java.specification.vendor" value="Oracle Corporation"/>
<property name="java.version.date" value="2026-01-20"/>
<property name="java.home" value="/opt/homebrew/Cellar/openjdk/25.0.2/libexec/openjdk.jdk/Contents/Home"/>
<property name="file.separator" value="/"/>
<property name="basedir" value="/Users/maddy/Projects/cygnus/matrix/cygnus-lib"/>
<property name="java.vm.compressedOopsMode" value="Zero based"/>
<property name="line.separator" value="&#10;"/>
<property name="java.vm.specification.vendor" value="Oracle Corporation"/>
<property name="java.specification.name" value="Java Platform API Specification"/>
<property name="apple.awt.application.name" value="ForkedBooter"/>
<property name="surefire.real.class.path" value="/Users/maddy/Projects/cygnus/matrix/cygnus-lib/target/surefire/surefirebooter-20260801204253825_3.jar"/>
<property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
<property name="ftp.nonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="java.runtime.version" value="25.0.2"/>
<property name="user.name" value="maddy"/>
<property name="stdout.encoding" value="UTF-8"/>
<property name="path.separator" value=":"/>
<property name="os.version" value="26.5.2"/>
<property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
<property name="file.encoding" value="UTF-8"/>
<property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
<property name="java.vendor.version" value="Homebrew"/>
<property name="localRepository" value="/Users/maddy/.m2/repository"/>
<property name="java.vendor.url.bug" value="https://github.com/Homebrew/homebrew-core/issues"/>
<property name="java.io.tmpdir" value="/var/folders/1l/36214rdn79755j30lcnmgsqh0000gn/T/"/>
<property name="java.version" value="25.0.2"/>
<property name="user.dir" value="/Users/maddy/Projects/cygnus/matrix/cygnus-lib"/>
<property name="os.arch" value="aarch64"/>
<property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
<property name="native.encoding" value="UTF-8"/>
<property name="java.library.path" value="/Users/maddy/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/>
<property name="java.vm.info" value="mixed mode, sharing"/>
<property name="stderr.encoding" value="UTF-8"/>
<property name="java.vendor" value="Homebrew"/>
<property name="java.vm.version" value="25.0.2"/>
<property name="stdin.encoding" value="UTF-8"/>
<property name="sun.io.unicode.encoding" value="UnicodeBig"/>
<property name="socksNonProxyHosts" value="local|*.local|169.254/16|*.169.254/16"/>
<property name="java.class.version" value="69.0"/>
</properties>
<testcase name="mapsHttpStatusToCanonicalError" classname="lib.models.ErrorDetailsTest" time="0.008"/>
<testcase name="createsAReusableErrorContract" classname="lib.models.ErrorDetailsTest" time="0.007"/>
</testsuite>

View File

@@ -1,4 +0,0 @@
-------------------------------------------------------------------------------
Test set: lib.models.ErrorDetailsTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 s -- in lib.models.ErrorDetailsTest

View File

@@ -1,686 +0,0 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@page language="java" session="true" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Cygnus 1.0 |
<c:if test="${caseDetails.getFormMode() eq 1}">Add Cases</c:if>
<c:if test="${caseDetails.getFormMode() eq 2}">Edit Details</c:if>
</title>
<script language="javascript" src="/matrix/js/lib/constants.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/jquery1.7.2.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/uifuncs.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/lib/jsfuncs.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/msgdialog.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/select.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/appjs/punching.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/validator.js?ver=2" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ajax.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ajax-dynamic-list.js" type="text/javascript"></script>
<link href="/matrix/css/button.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/div.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/textbox.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/select.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/table.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/autocomplete.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/bootstrap-5.3.8.min.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/matrix-v2.css?v=6" rel="stylesheet" type="text/css" />
<link href="/matrix/css/matrix-shell-v2.css?v=7" rel="stylesheet" type="text/css" />
<link href="/matrix/css/tool-workspace-v3.css?v=2" rel="stylesheet" type="text/css" />
<link href="/matrix/css/punch-workspace-v3.css?v=1" rel="stylesheet" type="text/css" />
<link href="/matrix/css/add-cases-v4.css?v=5" rel="stylesheet" type="text/css" />
<script src="/matrix/js/matrix-dialog-child.js" type="text/javascript"></script>
<script src="/matrix/js/bootstrap-5.3.8.bundle.min.js" defer></script>
<script src="/matrix/js/matrix-shell-v2.js" defer></script>
<link href="/matrix/css/matrix-frame-dialog.css?v=6" rel="stylesheet" type="text/css" />
<script src="/matrix/js/matrix-frame-dialog.js?v=2" defer></script>
<script src="/matrix/js/matrix-dialog-child.js" type="text/javascript"></script>
<script src="/matrix/js/matrix-accessibility-v1.js?v=1" defer></script>
<link href="/matrix/css/matrix-theme-v2.css?v=4" rel="stylesheet" type="text/css" />
</head>
<body class="matrix-v2 matrix-shell matrix-tool-workspace matrix-punch-workspace matrix-add-cases">
<div id='PageFrame'>
<c:if test="${caseDetails.getFormMode() eq 1}">
<%@ include file="/WEB-INF/app/fragments/app-shell-header.jspf" %>
<%-- Shared shell owns ${Sessvals.menuHtml}. --%>
</c:if>
<div id="formcontainer" class="matrix-tool-workspace__content">
<form:form method="post" name="caseDetails" id="caseDetails" modelAttribute="caseDetails" >
<!-- Common Details (Section1) Visible for all portfolios-->
<div>
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/commondet.png" align="absmiddle" />
<span class="matrix-title-text" align="absmiddle">Common Details</span>
<c:choose>
<c:when test="${caseDetails.getFormMode() eq 1}">
<div class="divselect" id="divportfolio" style="width:167px;position:absolute;top:3px;right:13px;">
<form:select path="PortfolioId" multiple="false" id="portlist" style="width:185px" onchange="SubmitForm('casedet','_parent','caseDetails')">
<form:option value="-1" label="SELECT PORTFOLIO" selected="true"/>
<c:forEach items="${portlist}" var="port">
<form:option value="${port[0]}" label="${port[1]}" />
</c:forEach>
</form:select>
</div>
</c:when>
<c:otherwise>
<form:hidden path="PortfolioId" id="portlist" />
</c:otherwise>
</c:choose>
</div>
<!-- -->
<!-- Form (Section1) -->
<div id="FormPanel1" class="FormPanel">
<table align="center" class="matrix-form-controls" width="99%">
<tr>
<td>
<div class="widget">
<div class="lblcontainer">
MV Code
</div>
<div class="inputcontainer">
<form:input style="width:65px;text-transform:uppercase" readonly="true" path="MvCode" value="${caseDeails.getMvCode()}" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Appl No.
</div>
<div class="inputcontainer">
<form:input maxlength="25" style="width:115px;text-transform:uppercase" id="ApplNo" path="ApplNo" value="${caseDetails.getApplNo()}" onblur="if(validate(this,'t','AlphaNumeric')){FindSameDet(this,'A','CustomerName');}" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Bank Code
</div>
<div class="inputcontainer">
<form:input maxlength="25" style="width:70px;text-transform:uppercase" path="BankCode" value="${caseDetails.getBankCode()}" onblur="validate(this,'f','AlphaNumeric');" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Branch
</div>
<div class="inputcontainer">
<div class="divselect" id="divbranch" style="width:135px;">
<form:select path="BankBranchId" multiple="false" id="branchlist" style="width:153px" onblur="validate(this,'t','');">
<form:option value="-1" label="SELECT" selected="true"/>
<c:forEach items="${branchlist}" var="brnch">
<form:option value="${brnch[0]}" label="${brnch[1]}" />
</c:forEach>
</form:select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Product
</div>
<div class="inputcontainer">
<div class="divselect" id="divproduct" style="width:132px;">
<form:select path="Product" multiple="false" id="prodlist" style="width:150px" onblur="validate(this,'t','');">
<form:option value="-1" label="SELECT" selected="true"/>
<c:forEach items="${prodlist}" var="prod">
<form:option value="${prod[0]}" label="${prod[1]}" />
</c:forEach>
</form:select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Name
</div>
<div class="inputcontainer">
<form:input maxlength="60" style="width:200px" path="CustomerName" value="${caseDetails.getCustomerName()}" onblur="validate(this,'t','AlphaSpace');" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Father Name
</div>
<div class="inputcontainer">
<form:input maxlength="25" style="width:145px" path="FatherName" value="${caseDetails.getFatherName()}" onblur="validate(this,'f','AlphaSpace');" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
App Type
</div>
<div class="inputcontainer">
<div class="divselect" id="divapptype" style="width:135px;">
<form:select path="CustomerType" multiple="false" id="typelist" style="width:153px" onchange="ToggleChks((this.value.toUpperCase()!='APPLICANT' && this.value.toUpperCase()!='-1'),'chksresi!C0L!chksoff!C0L!chksprop!C0L!','!C0L!')" onblur="validate(this,'t','');">
<form:option value="-1" label="SELECT" selected="true"/>
<c:forEach items="${typelist}" var="type">
<form:option value="${type[0]}" label="${type[1]}" />
</c:forEach>
</form:select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Category
</div>
<div class="inputcontainer">
<div class="divselect" id="divcategory" style="width:115px;">
<form:select path="Category" multiple="false" id="catlist" style="width:133px">
<form:option value="-1" label="SELECT" selected="true"/>
<c:forEach items="${catlist}" var="cat">
<form:option value="${cat[0]}" label="${cat[1]}" />
</c:forEach>
</form:select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
DOB
</div>
<div class="inputcontainer">
<form:input maxlength="10" style="width:80px" path="DOB" id="dob" value="${caseDetails.getDOB()}" onkeydown="return addSlashes(this,event)" onblur="validate(this,'f','Date')" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Mobile No.
</div>
<div class="inputcontainer">
<form:input maxlength="21" style="width:120px" path="MobileNo" value="${caseDetails.getMobileNo()}" onblur="validate(this,'f','AllowWrong');" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Loan Amt
</div>
<div class="inputcontainer">
<form:input maxlength="15" style="width:100px" path="LoanAmount" value="${caseDetails.getLoanAmount()}" onblur="validate(this,'f','LoanAmount');" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
C Person
</div>
<div class="inputcontainer">
<form:input maxlength="25" style="width:200px" path="ContactPerson" value="${caseDetails.getContactPerson()}" onblur="validate(this,'f','AlphaSpace');" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Special Inst.
</div>
<div class="inputcontainer">
<form:input maxlength="50" id="splist" style="width:833px" path="SpecialInst" value="${caseDetails.getSpecialInst()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
</td>
</tr>
</table>
</div>
<!-- -->
</div>
<!-- -->
<!-- Residence Details (Section2) Visible for portfolios in which residence visit/ residence TVR could be initiated-->
<div id="section2">
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/resdet.png" />
<span class="matrix-title-text">Residence Details</span>
<div class="divchk" id="ctrldiv">
<form:checkbox path="Rvr" id="chkresi" onclick="HandleClick(this)" />RVR&nbsp;
<form:checkbox path="SameResi" id="chksresi" onclick="return FindSameDet(this,'R','ResiPhone')" /><span id="chksresi">Same Resi</span>
<form:checkbox path="Rtvr" id="chkteler" onclick="HandleClick(this)" /><span id="chkteler">RTV</span>
</div>
</div>
<!-- -->
<!-- Form (Section2) -->
<div id="FormPanel2" class="FormPanel">
<table align="center" class="matrix-form-controls" style="width:100%">
<tr>
<td>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
House No.
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="20" style="width:70px" path="ResiAdd1" value="${caseDetails.getResiAdd1()}" onblur="validate(this,document.getElementById('chkresi').checked ? 't':'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Sub Locality
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="70" style="width:180px" path="ResiAdd2" value="${caseDetails.getResiAdd2()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
City
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<div class="divselect" id="divrcity" style="width:110px;">
<form:select path="ResiCity" multiple="false" id="ResiAdd3_citylist" style="width:128px" onblur="validate(this,document.getElementById('chkresi').checked ? 't':'f','')" >
<form:option value="-1" label="Select" selected="true"/>
<form:option value="Unknown" label="Unknown"/>
<c:forEach items="${citylist}" var="city">
<form:option value="${city[0]}" label="${city[1]}" />
</c:forEach>
</form:select>
</div>
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Locality
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="50" style="width:180px" path="ResiAdd3" value="${caseDetails.getResiAdd3()}" onkeyup="ajax_showOptions(this,event)" onblur="onLocalityBlur(this,document.getElementById('chkresi').checked ? 't':'f')" />
<form:hidden path="ResiLoc" id="ResiAdd3_hidden" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Landmark
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="50" style="width:150px" path="ResiLandmark" value="${caseDetails.getResiLandmark()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Pincode
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="6" style="width:45px" id="ResiAdd3_Pincode" path="ResiPincode" value="${caseDetails.getResiPincode()}" onblur="validate(this,document.getElementById('chkresi').checked ? 't':'f','Pincode')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Phone No.
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input maxlength="25" style="width:107px" path="ResiPhone" value="${caseDetails.getResiPhone()}" onblur="validate(this,document.getElementById('chkteler').checked ? 't':'f','Phone')" />
</div>
</div>
</td>
</tr>
</table>
</div>
<!-- -->
</div>
<!-- -->
<!-- Office Details (Section3) Visible for portfolios in which office visit/ office TVR could be initiated-->
<div id="section3">
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/optmale.png" />
<span class="matrix-title-text">Office Details</span>
<div class="divchk" id="ctrldiv">
<form:checkbox path="Ovr" id="chkoffice" onclick="HandleClick(this)" />OVR&nbsp;
<form:checkbox path="RCO" id="chkrco" style="display:none" onclick="HandleClick(this)" /><span id="chkrco">RCO</span>&nbsp;
<form:checkbox path="SameOffice" id="chksoff" onclick="return FindSameDet(this,'O','OffPhone')" /><span id="chksoff">Same Office</span>
<form:checkbox path="Otvr" id="chkteleo" onclick="HandleClick(this)" /><span id="chkteleo">OTV</span>
</div>
</div>
<!-- -->
<!-- Form (Section3) -->
<div id="FormPanel3" class="FormPanel">
<table align="center" class="matrix-form-controls">
<tr>
<td>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Company
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input maxlength="50" style="width:215px" path="CompanyName" value="${caseDetails.getCompanyName()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Plot No.
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="20" style="width:90px" path="OffAdd1" value="${caseDetails.getOffAdd1()}" onblur="validate(this,document.getElementById('chkoffice').checked ? 't':'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Sub Locality
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="70" style="width:200px" path="OffAdd2" value="${caseDetails.getOffAdd2()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
City
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<div class="divselect" id="divocity" style="width:110px;">
<form:select path="OffCity" multiple="false" id="OffAdd3_citylist" style="width:128px" onblur="validate(this,document.getElementById('chkoffice').checked ? 't':'f','')">
<form:option value="-1" label="Select" selected="true"/>
<form:option value="Unknown" label="Unknown"/>
<c:forEach items="${citylist}" var="city">
<form:option value="${city[0]}" label="${city[1]}" />
</c:forEach>
</form:select>
</div>
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Locality
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="50" style="width:200px" path="OffAdd3" value="${caseDetails.getOffAdd3()}" onkeyup="ajax_showOptions(this,event)" onblur="validate(this,document.getElementById('chkoffice').checked ? 't':'f','SplInstruction')" />
<form:hidden path="OffLoc" id="OffAdd3_hidden" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Pincode
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="6" style="width:45px" id="OffAdd3_Pincode" path="OffPincode" value="${caseDetails.getOffPincode()}" onblur="validate(this,document.getElementById('chkoffice').checked ? 't':'f','Pincode')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Landmark
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input maxlength="50" style="width:215px" path="OffLandmark" value="${caseDetails.getOffLandmark()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Department
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input maxlength="25" style="width:200px" path="Department" value="${caseDetails.getDepartment()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Designation
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input maxlength="25" style="width:210px" path="Designation" value="${caseDetails.getDesignation()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Office Phone-Extn
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input maxlength="25" style="width:150px" path="OffPhone" value="${caseDetails.getOffPhone()}" onblur="validate(this,document.getElementById('chkteleo').checked ? 't':'f','Phone')" />-<form:input type="text" style="width:23px" path="Extension" value="${caseDetails.getExtension()}" onblur="validate(this,'f','Extension')" />
</div>
</div>
</td>
</tr>
</table>
</div>
<!-- -->
</div>
<!-- -->
<!-- Property Details (Section4) Visible for portfolios in which property visit could be initiated-->
<div id="section4">
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/resdet.png" />
<span class="matrix-title-text">Property Details</span>
<div class="divchk" id="ctrldiv">
<form:checkbox path="Pvr" id="chkprop" onclick="HandleClick(this)" />PVR&nbsp;
<form:checkbox path="RCP" id="chkrcp" style="display:none" onclick="HandleClick(this)" /><span id="chkrcp">RCP</span>&nbsp;
<form:checkbox path="OCP" id="chkocp" style="display:none" onclick="HandleClick(this)" /><span id="chkocp">OCP</span>&nbsp;
<form:checkbox path="SameProp" id="chksprop" onclick="return FindSameDet(this,'P','PropAdd3_Pincode')" /><span id="chksprop">Same Property</span>
</div>
</div>
<!-- -->
<!-- Form (Section4) -->
<div id="FormPanel4" class="FormPanel">
<table align="center" class="matrix-form-controls">
<tr>
<td>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
House / Plot No.
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="20" style="width:120px" path="PropAdd1" value="${caseDetails.getPropAdd1()}" onblur="validate(this,document.getElementById('chkprop').checked ? 't':'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Sub Locality
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="70" style="width:200px" path="PropAdd2" value="${caseDetails.getPropAdd2()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
City
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<div class="divselect" id="divpcity" style="width:110px;">
<form:select path="PropCity" multiple="false" id="PropAdd3_citylist" style="width:128px" onblur="validate(this,document.getElementById('chkprop').checked ? 't':'f','')">
<form:option value="-1" label="Select" selected="true"/>
<form:option value="Unknown" label="Unknown"/>
<c:forEach items="${citylist}" var="city">
<form:option value="${city[0]}" label="${city[1]}" />
</c:forEach>
</form:select>
</div>
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Locality
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="50" style="width:200px" path="PropAdd3" value="${caseDetails.getPropAdd3()}" onkeyup="ajax_showOptions(this,event)" onblur="validate(this,document.getElementById('chkprop').checked ? 't':'f','SplInstruction')" />
<form:hidden path="PropLoc" id="PropAdd3_hidden" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Landmark
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="50" style="width:180px" path="PropLandmark" value="${caseDetails.getPropLandmark()}" onblur="validate(this,'f','SplInstruction')" />
</div>
</div>
<div class="widget" style="margin-left:2px">
<div class="lblcontainer" style="padding:1px">
Pincode
</div>
<br >
<div class="inputcontainer" style="padding:1px">
<form:input readonly="true" maxlength="6" style="width:45px" id="PropAdd3_Pincode" path="PropPincode" value="${caseDetails.getResiPincode()}" onblur="validate(this,document.getElementById('chkprop').checked ? 't':'f','Pincode')" />
</div>
</div>
</td>
</tr>
</table>
</div>
<!-- -->
</div>
<!-- -->
<!-- Reference Details (Section5) Visible for portfolios in which reference calling could be initiated-->
<div id="section5">
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/ref.png" />
<span class="matrix-title-text">Reference Details</span>
<div class="divchk" id="ctrldiv">
<form:checkbox path="Refvr" id="chkref" onclick="setFormValidation(this,'FormPanel5','Ref1Name,Ref1Address,Ref1Contactno','t,f,t','AlphaSpace,SplInstruction,Phone',false)" />Ref Check&nbsp;
</div>
</div>
<!-- -->
<!-- Form (Section5) -->
<div id="FormPanel5" class="FormPanel">
<table align="center" class="matrix-form-controls">
<tr>
<td>&nbsp;</td>
<td>Name</td>
<td>Address</td>
<td>Contact Numbers</td>
</tr>
<tr>
<td>Reference 1&nbsp;</td>
<td><form:input maxlength="30" style="width:200px" path="Ref1Name" value="${caseDetails.getRef1Name()}" onblur="validate(this,document.getElementById('chkref').checked ? 't':'f','AlphaSpace')" /></td>
<td><form:input maxlength="100" style="width:450px" path="Ref1Address" value="${caseDetails.getRef1Address()}" onblur="validate(this,'f','SplInstruction')" /></td>
<td><form:input maxlength="25" style="width:160px" path="Ref1Contactno" value="${caseDetails.getRef1Contactno()}" onblur="validate(this,document.getElementById('chkref').checked ? 't':'f','Phone')" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>Name</td>
<td>Address</td>
<td>Contact Numbers</td>
</tr>
<tr>
<td>Reference 2&nbsp;</td>
<td><form:input maxlength="30" style="width:200px" path="Ref2Name" value="${caseDetails.getRef2Name()}" onblur="validate(this,'f','AlphaSpace')" /></td>
<td><form:input maxlength="100" style="width:450px" path="Ref2Address" value="${caseDetails.getRef2Address()}" onblur="validate(this,'f','SplInstruction')" /></td>
<td><form:input maxlength="25" style="width:160px" path="Ref2Contactno" value="${caseDetails.getRef2Contactno()}" onblur="validate(this,'f','Phone')" /></td>
</tr>
</table>
</div>
<!-- -->
</div>
<!-- -->
<!-- Dynamic Form (Section6). All controls under this section will be generated dynamically during runtime-->
<div id="section6">
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/edit_form.png" alt="" />
<span class="matrix-title-text">Other Details</span>
</div>
<!-- -->
<div id="FormPanel6" class="FormPanel">
${caseDetails.getDynamicPanel()}
</div>
</div>
<!-- -->
<!-- Document Details (Section7) Visible for portfolios in which document verification could be done-->
<div id="section7">
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/documents.png" />
<span class="matrix-title-text">Document Details</span>
<div class="divchk" id="ctrldiv">
<form:checkbox path="Docvr" id="chkdoc" onclick="hideForm(this.id,'FormPanel7')" />Doc VR&nbsp;
</div>
</div>
<!-- -->
<!-- Form (Section7) -->
<div id="FormPanel7" class="FormPanel">
<table align="center" class="matrix-form-controls">
<tr>
<td>Document</td>
<td>Vendor</td>
<td>Service Provider</td>
<td>Name</td>
<td>Unique No.</td>
</tr>
<tr>
<td>
<div class="divselect" id="divdoclist" style="width:90px;">
<select id="doclist" style="width:108px">
<option value="-1" selected="true">
<c:forEach items="${doclist}" var="doc">
<option value="${doc[0]}" >${doc[1]}</option>
</c:forEach>
</select>
</div>
</td>
<td><input type="text" style="width:150px" value="" id="vendor" /></td>
<td><input type="text" style="width:200px" value="" id="serviceprovider" /></td>
<td><input type="text" style="width:200px" value="" id="name" /></td>
<td><input type="text" style="width:180px" value="" id="uniqueno" /></td>
</tr>
</table>
</div>
<!-- -->
</div>
<form:hidden path="DynamicFields" value="${caseDetails.getDynamicFields()}" />
<form:hidden path="VisibleContents" value="${caseDetails.getVisibleContents()}" />
<form:hidden path="FormMode" />
<form:hidden path="UUID" />
<form:hidden path="CaseId" />
<!-- -->
<input type="hidden" id="invalidfields" value="0" />
<c:if test="${caseDetails.getFormMode() eq 2}">
<input type="button" class="button" name="btncancel" style="margin-left:1px;margin-top:5px;float:right" value="Cancel" id="btncancel" accesskey="C" onclick="MatrixDialog.close(0)" />
</c:if>
<input type="button" class="button" name="btnsave" style="margin-top:5px;float:right" value="Save" id="btnsave" accesskey="S" onclick="return ValidateSubmitForm('caseDetails');" />
</form:form>
</div>
</div>
</body>
<!-- Page Load Javascript -->
<script language="javascript" type="text/javascript">
HideSections('rtv');
HideSections('otv');
HideSections('section');
UnhideSections('${visibleContents}','!C0L!');
hideForm('chkresi','FormPanel2');
hideForm('chkoffice','FormPanel3');
hideForm('chkprop','FormPanel4');
hideForm('chkref','FormPanel5');
hideForm('chkdoc','FormPanel7');
ToggleChks((document.getElementById('chkresi').checked && document.getElementById('chkoffice').checked),'chkrco'+ColDelim,ColDelim);
ToggleChks((document.getElementById('chkresi').checked),'chkrcp'+ColDelim,ColDelim);
ToggleChks((document.getElementById('chkoffice').checked),'chkocp'+ColDelim,ColDelim);
ToggleChks((document.getElementById('typelist').value.toUpperCase()!='APPLICANT' && document.getElementById('typelist').value.toUpperCase()!='-1'),'chksresi!C0L!chksoff!C0L!chksprop!C0L!','!C0L!');
document.getElementById('ApplNo').focus();
</script>
<!-- -->
<!-- Process Message -->
<c:if test="${not empty caseDetails.getErrMsg()}">
<script language="javascript" type="text/javascript"> CallMessage('${caseDetails.getErrMsg()}',3000,200,300); </script>
<c:if test="${caseDetails.isProcessFlag()==true and caseDetails.getFormMode()==2}">
<script language="javascript" type="text/javascript">MatrixDialog.close(1);</script>
</c:if>
</c:if>
<!-- -->
</html>

View File

@@ -13,43 +13,42 @@
<script language="javascript" src="/matrix/js/lib/jsfuncs.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/lib/jsfuncs.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/msgdialog.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/ui/msgdialog.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/select.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/ui/select.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/appjs/editcases.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/edp/punching/edit-cases.js?ver=1" type="text/javascript"></script>
<link href="/matrix/css/div.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/div.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/select.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/select.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/table.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/table.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/bootstrap-5.3.8.min.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/bootstrap-5.3.8.min.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/matrix-v2.css?v=6" rel="stylesheet" type="text/css" /> <link href="/matrix/css/matrix-v2.css?v=6" rel="stylesheet" type="text/css" />
<link href="/matrix/css/tool-workspace-v3.css?v=2" rel="stylesheet" type="text/css" /> <link href="/matrix/css/tool-workspace-v3.css?v=2" rel="stylesheet" type="text/css" />
<link href="/matrix/css/edit-cases-v1.css?v=1" rel="stylesheet" type="text/css" /> <title>Cygnus 1.0 | Edit Cases</title>
<title>Cygnus 1.0 | Edit Cases</title>
<script src="/matrix/js/matrix-accessibility-v1.js?v=1" defer></script> <script src="/matrix/js/matrix-accessibility-v1.js?v=1" defer></script>
<link href="/matrix/css/matrix-theme-v2.css?v=4" rel="stylesheet" type="text/css" /> <link href="/matrix/css/matrix-theme-v2.css?v=4" rel="stylesheet" type="text/css" />
<link href="/matrix/css/edit-cases-v1.css?v=8" rel="stylesheet" type="text/css" />
</head> </head>
<body class="matrix-shell matrix-v2 matrix-tool-workspace matrix-edit-cases"> <body class="matrix-shell matrix-v2 matrix-tool-workspace matrix-edit-cases">
<div id='PageFrame'> <div id='PageFrame'>
<!-- Title Bar --> <!-- Title Bar -->
<%@ include file="/WEB-INF/app/fragments/app-title.jspf" %> <%@ include file="/WEB-INF/app/fragments/app-title.jspf" %>
<!-- --> <!-- -->
<div id="formcontainer" class="matrix-tool-workspace__content"> <div id="formcontainer" class="matrix-tool-workspace__content">
<form:form method="post" name="caseGrid" id="caseGrid" modelAttribute="caseGrid" target="_blank"> <form:form method="post" name="caseGrid" id="caseGrid" modelAttribute="caseGrid" target="_parent">
<!-- Common Details (Section1) Visible for all portfolios--> <!-- Common Details (Section1) Visible for all portfolios-->
<div> <div>
<!-- Title --> <!-- Title -->
<div class="title"> <div class="title">
<img class="matrix-title-icon" src="/matrix/images/commondet.png" align="absmiddle" /> <img class="matrix-title-icon" src="/matrix/images/commondet.png" align="absmiddle" />
<span class="matrix-title-text" align="absmiddle">List of Cases</span> <span class="matrix-title-text" align="absmiddle">List of Cases</span>
<div class="divselect" id="divportfolio" style="width:167px;position:absolute;top:3px;right:30px;"> <form:select path="PortfolioId" multiple="false" id="portlist" cssClass="matrix-edit-cases__portfolio-select" onchange="SubmitForm('caselist','_parent','caseGrid')">
<form:select path="PortfolioId" multiple="false" id="portlist" style="width:185px" onchange="SubmitForm('caselist','_parent','caseGrid')"> <form:option value="-1" label="SELECT PORTFOLIO" selected="true"/>
<form:option value="-1" label="SELECT PORTFOLIO" selected="true"/> <c:forEach items="${portlist}" var="port">
<c:forEach items="${portlist}" var="port"> <form:option value="${port.value}" label="${port.label}" />
<form:option value="${port[0]}" label="${port[1]}" /> </c:forEach>
</c:forEach> </form:select>
</form:select> <button class="matrix-edit-cases__refresh" type="button" title="Refresh Grid" onclick="SubmitForm('caselist','_parent','caseGrid')">
</div> <img src="/matrix/images/reload.png" alt="" />
<img class="matrix-title-action" src="/matrix/images/reload.png" title="Refresh Grid" onclick="SubmitForm('caselist','_parent','caseGrid')"/> </button>
</div> </div>
<!-- --> <!-- -->
<div id="TablePanel" class="tableContainer"> <div id="TablePanel" class="tableContainer">
<table border="0" cellspacing="0" width="100%" id="casetable"> <table border="0" cellspacing="0" width="100%" id="casetable">
@@ -69,19 +68,19 @@
</thead> </thead>
<tbody class="scrollContent"> <tbody class="scrollContent">
<c:forEach items="${caseList}" var="casedet" varStatus="status"> <c:forEach items="${caseList}" var="casedet" varStatus="status">
<tr id="row${status.count}" tabindex="0" title="Open this case for editing"> <tr id="row${status.count}" tabindex="0" title="Open this case for editing">
<td> <td>
<input type="hidden" name="row${status.count}uuid" id="row${status.count}uuid" value="${casedet[0]}" /> <input type="hidden" name="row${status.count}uuid" id="row${status.count}uuid" value="${casedet.documentCaseId}" />
<input type="hidden" name="row${status.count}portid" id="row${status.count}portid" value="${casedet[9]}" /> <input type="hidden" name="row${status.count}portid" id="row${status.count}portid" value="${casedet.portfolioId}" />
${status.count}</td> ${status.count}</td>
<td>${casedet[1]}</td> <td>${casedet.mvCode}</td>
<td>${casedet[2]}</td> <td>${casedet.fileNumber}</td>
<td>${casedet[3]}</td> <td>${casedet.customerName}</td>
<td>${casedet[4]}</td> <td>${casedet.applicationType}</td>
<td>${casedet[5]}</td> <td>${casedet.product}</td>
<td>${casedet[6]}</td> <td>${casedet.receivedOn}</td>
<td>${casedet[7]}</td> <td>${casedet.punchedBy}</td>
<td>${casedet[8]}</td> <td>${casedet.branchCode}</td>
</tr> </tr>
</c:forEach> </c:forEach>
</tbody> </tbody>
@@ -103,4 +102,4 @@
<script language="javascript" type="text/javascript"> CallMessage('${msg}',3000,200,300); </script> <script language="javascript" type="text/javascript"> CallMessage('${msg}',3000,200,300); </script>
</c:if> </c:if>
<!-- --> <!-- -->
</html> </html>

View File

@@ -18,12 +18,16 @@
<script language="javascript" src="/matrix/js/jquery1.7.2.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/jquery1.7.2.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/uifuncs.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/ui/uifuncs.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/lib/jsfuncs.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/lib/jsfuncs.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/lib/notifications.js?ver=1" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/lib/payload-crypto.js?ver=1" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/lib/form-validation.js?ver=1" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/msgdialog.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/ui/msgdialog.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/select.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/ui/select.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/appjs/punching.js?ver=6" type="text/javascript"></script> <script language="javascript" src="/matrix/js/edp/punching/initiation.js?ver=8" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/edp/punching/initiation-validation.js?ver=1" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/edp/punching/application-save.js?ver=2" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/validator.js?ver=2" type="text/javascript"></script> <script language="javascript" src="/matrix/js/validator.js?ver=2" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ajax.js" type="text/javascript"></script> <script language="javascript" src="/matrix/js/ajax-dynamic-list.js?ver=2" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ajax-dynamic-list.js?ver=1" type="text/javascript"></script>
<link href="/matrix/css/button.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/button.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/div.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/div.css" rel="stylesheet" type="text/css" />
@@ -32,11 +36,11 @@
<link href="/matrix/css/table.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/table.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/autocomplete.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/autocomplete.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/bootstrap-5.3.8.min.css" rel="stylesheet" type="text/css" /> <link href="/matrix/css/bootstrap-5.3.8.min.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/matrix-v2.css?v=6" rel="stylesheet" type="text/css" /> <link href="/matrix/css/matrix-v2.css?v=7" rel="stylesheet" type="text/css" />
<link href="/matrix/css/matrix-shell-v2.css?v=7" rel="stylesheet" type="text/css" /> <link href="/matrix/css/matrix-shell-v2.css?v=7" rel="stylesheet" type="text/css" />
<link href="/matrix/css/tool-workspace-v3.css?v=2" rel="stylesheet" type="text/css" /> <link href="/matrix/css/tool-workspace-v3.css?v=2" rel="stylesheet" type="text/css" />
<link href="/matrix/css/punch-workspace-v3.css?v=1" rel="stylesheet" type="text/css" /> <link href="/matrix/css/punch-workspace-v3.css?v=2" rel="stylesheet" type="text/css" />
<link href="/matrix/css/add-cases-v4.css?v=5" rel="stylesheet" type="text/css" /> <link href="/matrix/css/add-cases-v4.css?v=6" rel="stylesheet" type="text/css" />
<script src="/matrix/js/bootstrap-5.3.8.bundle.min.js" defer></script> <script src="/matrix/js/bootstrap-5.3.8.bundle.min.js" defer></script>
<script src="/matrix/js/matrix-shell-v2.js" defer></script> <script src="/matrix/js/matrix-shell-v2.js" defer></script>
<link href="/matrix/css/matrix-frame-dialog.css?v=6" rel="stylesheet" type="text/css" /> <link href="/matrix/css/matrix-frame-dialog.css?v=6" rel="stylesheet" type="text/css" />
@@ -53,7 +57,7 @@
<c:if test="${pageFormMode!=2}"> <c:if test="${pageFormMode!=2}">
<!-- Dynamic Menu --> <!-- Dynamic Menu -->
<nav class="matrix-shell__navigation" aria-label="Primary navigation"> <nav class="matrix-shell__navigation" aria-label="Primary navigation">
<c:out value="${Sessvals.menuHtml}" escapeXml="false" /> <c:out value="${sessionScope.userSession.menuHtml}" escapeXml="false" />
</nav> </nav>
<!-- --> <!-- -->
</c:if> </c:if>
@@ -72,6 +76,9 @@
<label class="matrix-form-title__check"><input type="checkbox" name="autocut" checked id="autocut" /> Auto Cut-Off</label> <label class="matrix-form-title__check"><input type="checkbox" name="autocut" checked id="autocut" /> Auto Cut-Off</label>
<c:if test="${pageFormMode==2}"> <c:if test="${pageFormMode==2}">
<input type="hidden" id="portfolio_id" name="portfolioId" value="${pagePortfolioId}" /> <input type="hidden" id="portfolio_id" name="portfolioId" value="${pagePortfolioId}" />
<button type="button" class="matrix-edit-back" onclick="history.back()" title="Back to case list">
<span aria-hidden="true">&#8592;</span> Back
</button>
</c:if> </c:if>
<c:if test="${pageFormMode!=2}"> <c:if test="${pageFormMode!=2}">
<div class="divselect matrix-form-title__end" id="divportfolio" style="width:297px;"> <div class="divselect matrix-form-title__end" id="divportfolio" style="width:297px;">
@@ -79,9 +86,9 @@
<option value="-1" selected >SELECT PORTFOLIO</option> <option value="-1" selected >SELECT PORTFOLIO</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"> <c:when test="${not empty model}">
<c:forEach items="${model.options['portfolio.']}" var="port"> <c:forEach items="${model.options['portfolio.']}" var="port">
<option value="${port.value}"><c:out value="${port.label}" /></option> <option value="${port.value}"><c:out value="${port.label}" /></option>
</c:forEach> </c:forEach>
</c:when> </c:when>
<c:otherwise> <c:otherwise>
<c:forEach items="${portlist}" var="port"> <c:forEach items="${portlist}" var="port">
@@ -112,7 +119,7 @@
Appl No. Appl No.
</div> </div>
<div class="inputcontainer"> <div class="inputcontainer">
<input type="text" id="applno" name="applno" maxlength="25" style="width:115px;text-transform:uppercase" value="" onblur="if(validate(this,'t','AlphaNumeric')){FindSameDet(this,'A','customername');}" /> <input type="text" id="applno" name="applno" maxlength="25" style="width:115px;text-transform:uppercase" value="" onblur="if(CygnusInitiationValidation.validateField(this)){FindSameDet(this,'A','customername');}" />
</div> </div>
</div> </div>
<div class="widget"> <div class="widget">
@@ -120,7 +127,7 @@
Bank Code Bank Code
</div> </div>
<div class="inputcontainer"> <div class="inputcontainer">
<input type="text" maxlength="25" id="bankcode" name="bankcode" style="width:70px;text-transform:uppercase" value="" onblur="validate(this,'f','AlphaNumeric');" /> <input type="text" maxlength="25" id="bankcode" name="bankcode" style="width:70px;text-transform:uppercase" value="" onblur="CygnusInitiationValidation.validateField(this);" />
</div> </div>
</div> </div>
<div class="widget"> <div class="widget">
@@ -129,13 +136,13 @@
</div> </div>
<div class="inputcontainer"> <div class="inputcontainer">
<div class="divselect" id="divbranch" style="width:135px;"> <div class="divselect" id="divbranch" style="width:135px;">
<select id="bank_branch_id" name="bank_branch_id" style="width:153px" onblur="validate(this,'t','');"> <select id="bank_branch_id" name="bank_branch_id" style="width:153px" onblur="CygnusInitiationValidation.validateField(this);">
<option value="-1" selected >SELECT</option> <option value="-1" selected >SELECT</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"> <c:when test="${not empty model}">
<c:forEach items="${model.options}" var="option"><c:if test="${fn:startsWith(option.key, 'branch.')}"> <c:forEach items="${model.options['branch.']}" var="option">
<option value="${fn:substringAfter(option.key, 'branch.')}"><c:out value="${option.value}" /></option> <option value="${option.value}"><c:out value="${option.label}" /></option>
</c:if></c:forEach> </c:forEach>
</c:when> </c:when>
<c:otherwise><c:forEach items="${branchlist}" var="brnch"><option value="${brnch[0]}"><c:out value="${brnch[1]}" /></option></c:forEach></c:otherwise> <c:otherwise><c:forEach items="${branchlist}" var="brnch"><option value="${brnch[0]}"><c:out value="${brnch[1]}" /></option></c:forEach></c:otherwise>
</c:choose> </c:choose>
@@ -149,10 +156,10 @@
</div> </div>
<div class="inputcontainer"> <div class="inputcontainer">
<div class="divselect" id="divproduct" style="width:132px;"> <div class="divselect" id="divproduct" style="width:132px;">
<select id="product" name="product" style="width:150px" onblur="validate(this,'t','');"> <select id="product" name="product" style="width:150px" onblur="CygnusInitiationValidation.validateField(this);">
<option value="-1" selected >SELECT</option> <option value="-1" selected >SELECT</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"><c:forEach items="${model.options}" var="option"><c:if test="${fn:startsWith(option.key, 'product.')}"><option value="${fn:substringAfter(option.key, 'product.')}"><c:out value="${option.value}" /></option></c:if></c:forEach></c:when> <c:when test="${not empty model}"><c:forEach items="${model.options['product.']}" var="option"><option value="${option.value}"><c:out value="${option.label}" /></option></c:forEach></c:when>
<c:otherwise><c:forEach items="${prodlist}" var="prod"><option value="${prod[0]}"><c:out value="${prod[1]}" /></option></c:forEach></c:otherwise> <c:otherwise><c:forEach items="${prodlist}" var="prod"><option value="${prod[0]}"><c:out value="${prod[1]}" /></option></c:forEach></c:otherwise>
</c:choose> </c:choose>
</select> </select>
@@ -164,7 +171,7 @@
Name Name
</div> </div>
<div class="inputcontainer"> <div class="inputcontainer">
<input type="text" id="customername" name="customername" maxlength="100" style="width:200px" value="" onblur="validate(this,'t','AlphaSpace');" /> <input type="text" id="customername" name="customername" maxlength="100" style="width:200px" value="" onblur="CygnusInitiationValidation.validateField(this);" />
</div> </div>
</div> </div>
<div class="widget"> <div class="widget">
@@ -181,10 +188,10 @@
</div> </div>
<div class="inputcontainer"> <div class="inputcontainer">
<div class="divselect" id="divapptype" style="width:135px;"> <div class="divselect" id="divapptype" style="width:135px;">
<select id="apptype" name="apptype" style="width:153px" onchange="ToggleChks((this.value.toUpperCase()!='APPLICANT' && this.value.toUpperCase()!='-1'),'sradd!C0L!soadd!C0L!spadd!C0L!','!C0L!')" onblur="validate(this,'t','');"> <select id="apptype" name="apptype" style="width:153px" onchange="ToggleChks((this.value.toUpperCase()!='APPLICANT' && this.value.toUpperCase()!='-1'),['sradd','soadd','spadd'])" onblur="CygnusInitiationValidation.validateField(this);">
<option value="-1" selected>SELECT</option> <option value="-1" selected>SELECT</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"><c:forEach items="${model.options}" var="option"><c:if test="${fn:startsWith(option.key, 'applicationType.')}"><option value="${fn:substringAfter(option.key, 'applicationType.')}"><c:out value="${option.value}" /></option></c:if></c:forEach></c:when> <c:when test="${not empty model}"><c:forEach items="${model.options['applicationType.']}" var="option"><option value="${option.value}"><c:out value="${option.label}" /></option></c:forEach></c:when>
<c:otherwise><c:forEach items="${typelist}" var="type"><option value="${type[0]}"><c:out value="${type[1]}" /></option></c:forEach></c:otherwise> <c:otherwise><c:forEach items="${typelist}" var="type"><option value="${type[0]}"><c:out value="${type[1]}" /></option></c:forEach></c:otherwise>
</c:choose> </c:choose>
</select> </select>
@@ -200,7 +207,7 @@
<select id="category" name="category" style="width:133px"> <select id="category" name="category" style="width:133px">
<option value="-1" selected>SELECT</option> <option value="-1" selected>SELECT</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"><c:forEach items="${model.options}" var="option"><c:if test="${fn:startsWith(option.key, 'category.')}"><option value="${fn:substringAfter(option.key, 'category.')}"><c:out value="${option.value}" /></option></c:if></c:forEach></c:when> <c:when test="${not empty model}"><c:forEach items="${model.options['category.']}" var="option"><option value="${option.value}"><c:out value="${option.label}" /></option></c:forEach></c:when>
<c:otherwise><c:forEach items="${catlist}" var="cat"><option value="${cat[0]}"><c:out value="${cat[1]}" /></option></c:forEach></c:otherwise> <c:otherwise><c:forEach items="${catlist}" var="cat"><option value="${cat[0]}"><c:out value="${cat[1]}" /></option></c:forEach></c:otherwise>
</c:choose> </c:choose>
</select> </select>
@@ -261,10 +268,10 @@
<div class="title"> <div class="title">
<img class="matrix-title-icon" src="/matrix/images/resdet.png" /> <img class="matrix-title-icon" src="/matrix/images/resdet.png" />
<span class="matrix-title-text">Residence Details</span> <span class="matrix-title-text">Residence Details</span>
<div class="divchk" id="ctrldiv"> <div class="divchk ctrldiv">
<input type="checkbox" id="rv" name="rv" onclick="HandleClick(this)" />RVR&nbsp; <input type="checkbox" id="rv" name="rv" onclick="HandleClick(this)" />RVR&nbsp;
<input type="checkbox" id="sradd" name="rv" onclick="return FindSameDet(this,'R','rphone')" /><span id="sradd">Same Resi</span> <input type="checkbox" id="sradd" name="sradd" onclick="return FindSameDet(this,'R','rphone')" /><span id="sradd-label">Same Resi</span>
<input type="checkbox" id="rtv" name="rv" onclick="HandleClick(this)" /><span id="rtv">RTV</span> <input type="checkbox" id="rtv" name="rtv" onclick="HandleClick(this)" /><span id="rtv-label">RTV</span>
</div> </div>
</div> </div>
<!-- --> <!-- -->
@@ -311,7 +318,7 @@
<option value="-1">Select</option> <option value="-1">Select</option>
<option value="Unknown">Unknown</option> <option value="Unknown">Unknown</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"><c:forEach items="${model.options}" var="option"><c:if test="${fn:startsWith(option.key, 'city.')}"><option value="${fn:substringAfter(option.key, 'city.')}"><c:out value="${option.value}" /></option></c:if></c:forEach></c:when> <c:when test="${not empty model}"><c:forEach items="${model.options['city.']}" var="option"><option value="${option.value}"><c:out value="${option.label}" /></option></c:forEach></c:when>
<c:otherwise><c:forEach items="${citylist}" var="city"><option value="${city[0]}"><c:out value="${city[1]}" /></option></c:forEach></c:otherwise> <c:otherwise><c:forEach items="${citylist}" var="city"><option value="${city[0]}"><c:out value="${city[1]}" /></option></c:forEach></c:otherwise>
</c:choose> </c:choose>
</select> </select>
@@ -369,11 +376,11 @@
<div class="title"> <div class="title">
<img class="matrix-title-icon" src="/matrix/images/optmale.png" /> <img class="matrix-title-icon" src="/matrix/images/optmale.png" />
<span class="matrix-title-text">Office Details</span> <span class="matrix-title-text">Office Details</span>
<div class="divchk" id="ctrldiv"> <div class="divchk ctrldiv">
<input type="checkbox" id="ov" onclick="HandleClick(this)" />OVR&nbsp; <input type="checkbox" id="ov" onclick="HandleClick(this)" />OVR&nbsp;
<input type="checkbox" id="rco" style="display:none" onclick="HandleClick(this)" /><span id="rco">RCO&nbsp;</span> <input type="checkbox" id="rco" style="display:none" onclick="HandleClick(this)" /><span id="rco-label">RCO&nbsp;</span>
<input type="checkbox" id="soadd" onclick="return FindSameDet(this,'O','ophone')" /><span id="soadd">Same Office</span> <input type="checkbox" id="soadd" onclick="return FindSameDet(this,'O','ophone')" /><span id="soadd-label">Same Office</span>
<input type="checkbox" id="otv" onclick="HandleClick(this)" /><span id="otv">OTV</span> <input type="checkbox" id="otv" onclick="HandleClick(this)" /><span id="otv-label">OTV</span>
</div> </div>
</div> </div>
<!-- --> <!-- -->
@@ -429,7 +436,7 @@
<option value="-1">Select</option> <option value="-1">Select</option>
<option value="Unknown">Unknown</option> <option value="Unknown">Unknown</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"><c:forEach items="${model.options}" var="option"><c:if test="${fn:startsWith(option.key, 'city.')}"><option value="${fn:substringAfter(option.key, 'city.')}"><c:out value="${option.value}" /></option></c:if></c:forEach></c:when> <c:when test="${not empty model}"><c:forEach items="${model.options['city.']}" var="option"><option value="${option.value}"><c:out value="${option.label}" /></option></c:forEach></c:when>
<c:otherwise><c:forEach items="${citylist}" var="city"><option value="${city[0]}"><c:out value="${city[1]}" /></option></c:forEach></c:otherwise> <c:otherwise><c:forEach items="${citylist}" var="city"><option value="${city[0]}"><c:out value="${city[1]}" /></option></c:forEach></c:otherwise>
</c:choose> </c:choose>
</select> </select>
@@ -470,7 +477,7 @@
</div> </div>
<br > <br >
<div class="inputcontainer" style="padding:1px"> <div class="inputcontainer" style="padding:1px">
<input type="text" id="department" name="designation" maxlength="50" style="width:100px" value="" onblur="validate(this,'f','SplInstruction')" /> <input type="text" id="department" name="department" maxlength="50" style="width:100px" value="" onblur="validate(this,'f','SplInstruction')" />
</div> </div>
</div> </div>
<div class="widget" style="margin-left:2px"> <div class="widget" style="margin-left:2px">
@@ -487,8 +494,10 @@
Office Phone-Extn Office Phone-Extn
</div> </div>
<br > <br >
<div class="inputcontainer" style="padding:1px"> <div class="inputcontainer matrix-phone-extension" style="padding:1px">
<input type="text" id="ophone" name="ophone" maxlength="25" style="width:100px" value="" onblur="validate(this,document.getElementById('otv').checked ? 't':'f','Phone')" />-<input type="text" id="extension" name="extension" style="width:23px" maxlength="10" value="" onblur="validate(this,'f','Extension')" /> <input type="text" id="ophone" name="ophone" maxlength="25" value="" onblur="validate(this,document.getElementById('otv').checked ? 't':'f','Phone')" />
<span aria-hidden="true">-</span>
<input type="text" id="extension" name="extension" maxlength="10" value="" aria-label="Office phone extension" onblur="validate(this,'f','Extension')" />
</div> </div>
</div> </div>
</td> </td>
@@ -505,11 +514,11 @@
<div class="title"> <div class="title">
<img class="matrix-title-icon" src="/matrix/images/resdet.png" /> <img class="matrix-title-icon" src="/matrix/images/resdet.png" />
<span class="matrix-title-text">Property Details</span> <span class="matrix-title-text">Property Details</span>
<div class="divchk" id="ctrldiv"> <div class="divchk ctrldiv">
<input type="checkbox" id="pv" onclick="HandleClick(this)" />PVR&nbsp; <input type="checkbox" id="pv" onclick="HandleClick(this)" />PVR&nbsp;
<input type="checkbox" id="rcp" style="display:none" onclick="HandleClick(this)" /><span id="rcp">RCP&nbsp;</span> <input type="checkbox" id="rcp" style="display:none" onclick="HandleClick(this)" /><span id="rcp-label">RCP&nbsp;</span>
<input type="checkbox" id="ocp" style="display:none" onclick="HandleClick(this)" /><span id="ocp">OCP&nbsp;</span> <input type="checkbox" id="ocp" style="display:none" onclick="HandleClick(this)" /><span id="ocp-label">OCP&nbsp;</span>
<input type="checkbox" id="spadd" onclick="return FindSameDet(this,'P','ppincode')" /><span id="spadd">Same Property</span> <input type="checkbox" id="spadd" onclick="return FindSameDet(this,'P','ppincode')" /><span id="spadd-label">Same Property</span>
</div> </div>
</div> </div>
<!-- --> <!-- -->
@@ -524,7 +533,7 @@
</div> </div>
<br > <br >
<div class="inputcontainer" style="padding:1px"> <div class="inputcontainer" style="padding:1px">
<input type="text" id="paddr1" name="paddr1" readonly="readonly" maxlength="40" style="width:90px" value="" onblur="validate(this,document.getElementById('rv').checked ? 't':'f','SplInstruction')" /> <input type="text" id="paddr1" name="paddr1" readonly="readonly" maxlength="40" style="width:90px" value="" onblur="CygnusInitiationValidation.validateField(this);" />
</div> </div>
</div> </div>
<div class="widget" style="margin-left:2px"> <div class="widget" style="margin-left:2px">
@@ -556,7 +565,7 @@
<option value="-1">Select</option> <option value="-1">Select</option>
<option value="Unknown">Unknown</option> <option value="Unknown">Unknown</option>
<c:choose> <c:choose>
<c:when test="${not empty model}"><c:forEach items="${model.options}" var="option"><c:if test="${fn:startsWith(option.key, 'city.')}"><option value="${fn:substringAfter(option.key, 'city.')}"><c:out value="${option.value}" /></option></c:if></c:forEach></c:when> <c:when test="${not empty model}"><c:forEach items="${model.options['city.']}" var="option"><option value="${option.value}"><c:out value="${option.label}" /></option></c:forEach></c:when>
<c:otherwise><c:forEach items="${citylist}" var="city"><option value="${city[0]}"><c:out value="${city[1]}" /></option></c:forEach></c:otherwise> <c:otherwise><c:forEach items="${citylist}" var="city"><option value="${city[0]}"><c:out value="${city[1]}" /></option></c:forEach></c:otherwise>
</c:choose> </c:choose>
</select> </select>
@@ -579,7 +588,7 @@
</div> </div>
<br > <br >
<div class="inputcontainer" style="padding:1px"> <div class="inputcontainer" style="padding:1px">
<input type="text" id="ppincode" name="colp_pincode" readonly="readonly" maxlength="6" style="width:45px" value="" onblur="validate(this,document.getElementById('rv').checked ? 't':'f','Pincode')" /> <input type="text" id="ppincode" name="colp_pincode" readonly="readonly" maxlength="6" style="width:45px" value="" onblur="CygnusInitiationValidation.validateField(this);" />
</div> </div>
</div> </div>
<div class="widget" style="margin-left:2px"> <div class="widget" style="margin-left:2px">
@@ -605,7 +614,7 @@
<div class="title"> <div class="title">
<img class="matrix-title-icon" src="/matrix/images/ref.png" /> <img class="matrix-title-icon" src="/matrix/images/ref.png" />
<span class="matrix-title-text">Reference Details</span> <span class="matrix-title-text">Reference Details</span>
<div class="divchk" id="ctrldiv"> <div class="divchk ctrldiv">
<input type="checkbox" id="refv" name="refv" onclick="HandleClick(this)" />Ref Check&nbsp; <input type="checkbox" id="refv" name="refv" onclick="HandleClick(this)" />Ref Check&nbsp;
</div> </div>
</div> </div>
@@ -670,7 +679,7 @@
<div class="title"> <div class="title">
<img class="matrix-title-icon" src="/matrix/images/documents.png" /> <img class="matrix-title-icon" src="/matrix/images/documents.png" />
<span class="matrix-title-text">Document Details</span> <span class="matrix-title-text">Document Details</span>
<div class="divchk" id="ctrldiv"> <div class="divchk ctrldiv">
<input type="checkbox" name="docv" id="docv" />Doc VR&nbsp; <input type="checkbox" name="docv" id="docv" />Doc VR&nbsp;
</div> </div>
</div> </div>
@@ -689,19 +698,17 @@
</c:if> </c:if>
<input type="hidden" id="uuid" name="uuid" value="${pageDocumentCaseId}" /> <input type="hidden" id="uuid" name="uuid" value="${pageDocumentCaseId}" />
<input type="hidden" id="case_id" name="case_id" value="" /> <input type="hidden" id="case_id" name="case_id" value="" />
<input type="hidden" id="company_id" name="company_id" value="${Sessvals.getCompanyID()}" /> <input type="hidden" id="company_id" name="company_id" value="${sessionScope.userSession.companyId}" />
<input type="hidden" id="branch_id" name="branch_id" value="${Sessvals.getBranchID()}" /> <input type="hidden" id="branch_id" name="branch_id" value="${sessionScope.userSession.branchId}" />
<input type="hidden" id="status" name="status" value="" /> <input type="hidden" id="status" name="status" value="" />
<!-- --> <!-- -->
<input type="hidden" id="invalidfields" value="0" />
<c:if test="${pageFormMode gt 0}"> <c:if test="${pageFormMode gt 0}">
<div style="position:fixed;text-align:right;bottom:0px;width:980px;" class="buttonbar"> <div style="position:fixed;text-align:right;bottom:0px;width:980px;" class="buttonbar">
<input type="hidden" id="invalidfields" value="0" />
<input type="button" class="button" name="btnfirst" style="margin-left:5px;margin-top:-2px;float:left;width:80px" value="" id="btnfirst" accesskey="F" onclick="findRecord(1)" /> <input type="button" class="button" name="btnfirst" style="margin-left:5px;margin-top:-2px;float:left;width:80px" value="" id="btnfirst" accesskey="F" onclick="findRecord(1)" />
<input type="button" class="button" name="btnprev" style="margin-top:-2px;float:left;width:80px" value="" id="btnprev" accesskey="P" onclick="findRecord(2)" /> <input type="button" class="button" name="btnprev" style="margin-top:-2px;float:left;width:80px" value="" id="btnprev" accesskey="P" onclick="findRecord(2)" />
<input type="button" class="button" name="btnnext" style="margin-top:-2px;float:left;width:80px" value="" id="btnnext" accesskey="N" onclick="findRecord(3)" /> <input type="button" class="button" name="btnnext" style="margin-top:-2px;float:left;width:80px" value="" id="btnnext" accesskey="N" onclick="findRecord(3)" />
<input type="button" class="button" name="btnlast" style="margin-top:-2px;float:left;width:80px" value="" id="btnlast" accesskey="L" onclick="findRecord(4)" /> <input type="button" class="button" name="btnlast" style="margin-top:-2px;float:left;width:80px" value="" id="btnlast" accesskey="L" onclick="findRecord(4)" />
<input type="button" class="button" name="btnsave" style="float:right" value="Save" id="btnsave" accesskey="S" onclick="return ValidateSubmitForm('casedetails');" /> <input type="button" class="button" name="btnsave" style="float:right" value="Save" id="btnsave" accesskey="S" onclick="return CygnusInitiation.save(event);" />
<c:if test="${pageFormMode!=2}"> <c:if test="${pageFormMode!=2}">
<input type="button" class="button" name="btnadd" style="float:right" value="Add" id="btnadd" accesskey="A" onclick="return AddNewRecord();" /> <input type="button" class="button" name="btnadd" style="float:right" value="Add" id="btnadd" accesskey="A" onclick="return AddNewRecord();" />
</c:if> </c:if>
@@ -710,9 +717,9 @@
</form> </form>
<input type="hidden" id="formmode" name="formmode" value="${pageFormMode}" /> <input type="hidden" id="formmode" name="formmode" value="${pageFormMode}" />
<input type="hidden" id="usid" name="usid" value="${pageUserId}" /> <input type="hidden" id="usid" name="usid" value="${pageUserId}" />
<c:if test="${not empty model.errorDetails}"> <c:if test="${not empty model.messageDetails}">
<span id="page-error-code" hidden><c:out value="${model.errorDetails.errorCode}" /></span> <span id="page-error-code" hidden><c:out value="${model.messageDetails.code}" /></span>
<span id="page-error-message" hidden><c:out value="${model.errorDetails.message}" /></span> <span id="page-error-message" hidden><c:out value="${model.messageDetails.message}" /></span>
</c:if> </c:if>
</div> </div>
</div> </div>
@@ -720,6 +727,7 @@
<!-- Page Load Javascript --> <!-- Page Load Javascript -->
<script language="javascript" type="text/javascript"> <script language="javascript" type="text/javascript">
(function () { (function () {
CygnusInitiationValidation.bind(document.getElementById("casedetails"));
var sectionFields = document.querySelectorAll(".model-visible-section"); var sectionFields = document.querySelectorAll(".model-visible-section");
if (sectionFields.length > 0) { if (sectionFields.length > 0) {
document.getElementById("visiblecontents").value = Array.prototype.map.call( document.getElementById("visiblecontents").value = Array.prototype.map.call(
@@ -728,10 +736,13 @@
} }
InitPage(); InitPage();
var errorCode = document.getElementById("page-error-code"); var code = document.getElementById("page-error-code");
var errorMessage = document.getElementById("page-error-message"); var errorMessage = document.getElementById("page-error-message");
if (errorCode && errorMessage) { if (code && errorMessage) {
CallMessage(errorCode.textContent + ":error:" + errorMessage.textContent, 3000, 200, 300); CygnusNotifications.show({
type: "danger", code: code.textContent,
message: errorMessage.textContent, duration: 3000
});
} }
}()); }());
</script> </script>

View File

@@ -1,329 +0,0 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@page language="java" session="true" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Cygnus 1.0 | Document Initiation </title>
<script language="javascript" src="/matrix/js/lib/constants.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/jquery1.7.2.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/uifuncs.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/lib/jsfuncs.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/msgdialog.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ui/select.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ajax.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/ajax-dynamic-list.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/appjs/punchingdoc.js" type="text/javascript"></script>
<script language="javascript" src="/matrix/js/validator.js?ver=2" type="text/javascript"></script>
<link href="/matrix/css/button.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/div.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/textbox.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/select.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/table.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/autocomplete.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/bootstrap-5.3.8.min.css" rel="stylesheet" type="text/css" />
<link href="/matrix/css/matrix-v2.css?v=6" rel="stylesheet" type="text/css" />
<link href="/matrix/css/matrix-shell-v2.css?v=7" rel="stylesheet" type="text/css" />
<link href="/matrix/css/tool-workspace-v3.css?v=2" rel="stylesheet" type="text/css" />
<link href="/matrix/css/punch-workspace-v3.css?v=1" rel="stylesheet" type="text/css" />
<link href="/matrix/css/add-cases-v4.css?v=5" rel="stylesheet" type="text/css" />
<script src="/matrix/js/bootstrap-5.3.8.bundle.min.js" defer></script>
<script src="/matrix/js/matrix-shell-v2.js" defer></script>
<link href="/matrix/css/matrix-frame-dialog.css?v=6" rel="stylesheet" type="text/css" />
<script src="/matrix/js/matrix-frame-dialog.js?v=2" defer></script>
<script src="/matrix/js/matrix-accessibility-v1.js?v=1" defer></script>
<link href="/matrix/css/matrix-theme-v2.css?v=4" rel="stylesheet" type="text/css" />
</head>
<body class="matrix-v2 matrix-shell matrix-tool-workspace matrix-punch-workspace matrix-add-cases">
<div id='PageFrame'>
<%@ include file="/WEB-INF/app/fragments/app-shell-header.jspf" %>
<%-- Shared shell owns ${Sessvals.menuHtml}. --%>
<div id="formcontainer" class="matrix-tool-workspace__content">
<form method="post" name="docdetails" id="docdetails" >
<!-- Common Details (Section1) Visible for all portfolios-->
<div>
<!-- Title -->
<div class="title matrix-form-title">
<img class="matrix-title-icon" src="/matrix/images/commondet.png" align="absmiddle" />
<span class="matrix-title-text matrix-form-title__heading">Common Details <span id='recfound'></span></span>
<label class="matrix-form-title__field">Skip To <input type="text" class="textbox" style="width:30px" onkeypress="return NumberOnly(event)" onblur="GotoRecord(this)"></label>
<label class="matrix-form-title__field">Search by File No <input type="text" class="textbox" style="width:200px" onblur="SearchRecord(this)"></label>
<!-- Checkbox for AUTO CUT diabled for now -->
<!-- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" name="autocut" id="autocut" />&nbsp;Automatic Cut-Off -->
<div class="divselect matrix-form-title__end" id="divportfolio" style="width:167px;">
<select id="portfolio_id" name="portfolio_id" style="width:185px" onchange="SubmitForm('docadd','_parent','docdetails')">
<option value="-1" selected >SELECT PORTFOLIO</option>
<c:forEach items="${portlist}" var="port">
<option value="${port[0]}">${port[1]}</option>
</c:forEach>
</select>
</div>
</div>
<!-- -->
<!-- Form (Section1) -->
<div id="FormPanel1" class="FormPanel">
<table align="center" class="matrix-form-controls" width="99%">
<tr>
<td>
<div style="height:auto;width:16px;float:right;margin-top:4px;">
<div id="btnbedit" onclick="EditBasicDetails()" title="edit basic details" style="background:url('/matrix/images/edit_form.png');height:auto;width:16px;cursor:pointer;margin-top:2px">&nbsp;</div>
<div id="btnbsave" onclick="SaveBasicDetails()" title="save details" style="background:url('/matrix/images/disk.png');height:auto;width:16px;cursor:pointer;margin-top:2px">&nbsp;</div>
<div id="btnbcancel" onclick="CancelEdit()" title="cancel" style="background:url('/matrix/images/msgerror.png');height:auto;width:16px;cursor:pointer;margin-top:6px">&nbsp;</div>
</div>
<div class="widget">
<div class="lblcontainer">
Appl No.
</div>
<div class="inputcontainer">
<input type="text" id="applno" name="applno" maxlength="25" style="width:150px;text-transform:uppercase" value="" disabled="disabled" onblur="if(validate(this,'t','AlphaNumeric')){FindSameDet(this,'A','customername');}" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Name
</div>
<div class="inputcontainer">
<input type="text" id="customername" name="customername" maxlength="100" style="width:275px" value="" onblur="validate(this,'t','AlphaSpace');" disabled="disabled" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
DOB
</div>
<div class="inputcontainer">
<input type="text" id="dob" name="dob" maxlength="10" style="width:80px" value="" onkeydown="return addSlashes(this,event)" onblur="validate(this,'f','Date')" disabled="disabled" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Loan Amt
</div>
<div class="inputcontainer">
<input type="text" id="loanamount" name="loanamount" maxlength="15" style="width:115px" value="" onblur="validate(this,'f','LoanAmount');" disabled="disabled" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Branch
</div>
<div class="inputcontainer">
<div class="divselect" id="divbranch" style="width:235px;">
<select id="bank_branch_id" name="bank_branch_id" style="width:253px" onblur="validate(this,'t','');" disabled="disabled">
<option value="-1" selected >SELECT</option>
<c:forEach items="${branchlist}" var="brnch">
<option value="${brnch[0]}">${brnch[1]}</option>
</c:forEach>
</select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Product
</div>
<div class="inputcontainer">
<div class="divselect" id="divproduct" style="width:132px;">
<select id="product" name="product" style="width:150px" onblur="validate(this,'t','');" disabled="disabled">
<option value="-1" selected >SELECT</option>
<c:forEach items="${prodlist}" var="prod">
<option value="${prod[0]}">${prod[1]}</option>
</c:forEach>
</select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
App Type
</div>
<div class="inputcontainer">
<div class="divselect" id="divapptype" style="width:135px;">
<select id="apptype" name="apptype" style="width:153px" onblur="validate(this,'t','');" disabled="disabled">
<option value="-1" selected>SELECT</option>
<c:forEach items="${typelist}" var="type">
<option value="${type[0]}">${type[1]}</option>
</c:forEach>
</select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Category
</div>
<div class="inputcontainer">
<div class="divselect" id="divcategory" style="width:115px;">
<select id="category" name="category" style="width:133px" disabled="disabled">
<option value="-1" selected>SELECT</option>
<c:forEach items="${catlist}" var="cat">
<option value="${cat[0]}">${cat[1]}</option>
</c:forEach>
</select>
</div>
</div>
</div>
${dynamichtml}
<input type="button" class="button" name="btnsave" style="float:right" value="Add Docs" id="btnsave" onclick="return AddDocs();" />
</td>
</tr>
</table>
</div>
<!-- -->
</div>
<!-- -->
<!-- Document Details Visible for portfolios in which document verification could be done-->
<div id="section7">
<!-- Title -->
<div class="title">
<img class="matrix-title-icon" src="/matrix/images/documents.png" />
<span class="matrix-title-text">Document Details</span>
</div>
<!-- -->
<!-- Form (Section1) -->
<div id="FormPanel1" class="FormPanel">
<table align="center" class="matrix-form-controls" width="99%">
<tr>
<td>
<div class="widget">
<div class="lblcontainer">
Document
</div>
<div class="inputcontainer">
<div class="divselect" id="divdoctype" style="width:170px;">
<select id="doctype" name="doctype" style="width:188px" onchange="changeLabel(this)" onblur="validate(this,'t','')">
<option value="-1" uniqueidentifier="Unique No." sprovider="Service Provider" validuno="xxx" ymon="A.Y/Month" validymon="" defsprovider="" genlist="0" selected>SELECT</option>
<c:forEach items="${doclist}" var="doc">
<option value="${doc[0]}" uniqueidentifier="${doc[2]}" sprovider="${doc[3]}" validuno="${doc[4]}" ymon="${doc[5]}" validymon="${doc[6]}" defsprovider="${doc[7]}" genlist="${doc[8]}">${doc[1]}</option>
</c:forEach>
</select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Name
</div>
<div class="inputcontainer">
<input type="text" id="docholdername" name="docholdername" maxlength="100" style="width:200px" value="" onblur="validate(this,'t','AlphaSpace');" />
</div>
</div>
<div class="widget">
<div class="lblcontainer" id="sprovider">
Serivce Provider
</div>
<div class="inputcontainer">
<input type="text" id="serviceprovider" name="serviceprovider" maxlength="100" style="width:200px" value="" onblur="validate(this,'t','SplInstruction');" />
<input type="hidden" id="bank_id" name="serviceprovider_hidden" value="0" />
<input type="hidden" id="serviceprovider_citylist" name="serviceprovider_citylist" value="0" />
</div>
</div>
<div class="widget">
<div class="lblcontainer" id="uniqueidentifier">
Unique No.
</div>
<div class="inputcontainer">
<input type="text" id="uniqueno" name="uniqueno" maxlength="50" style="width:140px" value="" />
</div>
</div>
<div class="widget">
<div class="lblcontainer" id="yearmon">
A.Y/Month
</div>
<div class="inputcontainer">
<input type="text" id="yearmonth" name="yearmonth" maxlength="100" style="width:180px" value="" />
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Location
</div>
<div class="inputcontainer">
<div class="divselect" id="divcity" style="width:120px;" >
<select id="city" name="city" style="width:138px" onblur="validate(this,'t','');">
<option value="-1" selected>SELECT</option>
<option value="CITY" selected>CITY</option>
<option value="SATELLITE CITY">SATELLITE CITY</option>
<option value="OUT STATION">OUT STATION</option>
</select>
</div>
</div>
</div>
<div class="widget">
<div class="lblcontainer">
Vendor
</div>
<div class="inputcontainer">
<div class="divselect" id="divvendor" style="width:120px;">
<select id="vendor_id" name="vendor_id" style="width:138px" onblur="validate(this,'f','');">
<option value="-1" selected>SELECT</option>
</select>
</div>
</div>
</div>
${docdynamichtml}
<input type="button" class="button" name="btnadd" style="float:right" value="Add" id="btnadd" onclick="return AddNewDoc();" />
</td>
</tr>
</table>
</div>
<div id="FormPanel2" class="FormPanel">
<table border="0" cellspacing="0" width="100%" id="casetable">
<thead class="thead">
<tr title="Row Title" id="rowtitle">
<td style="font-size:12px;width:20px">S.No</td>
<td style="font-size:12px;width:150px">Name</td>
<td style="font-size:12px;width:150px">Document</td>
<td style="font-size:12px;width:150px">Provider</td>
<td style="font-size:12px;width:150px">Unique No.</td>
<td style="font-size:12px;width:100px">Extra</td>
<td style="font-size:12px;width:50px">Location</td>
<td style="font-size:12px;width:50px">Vendor</td>
<td style="font-size:12px">Action</td>
</tr>
</thead>
</table>
</div>
<!-- -->
</div>
<input type="hidden" id="dynamicfields" name="dynamicfields" value="${dynamicfields}" />
<input type="hidden" id="docdynamicfields" name="dynamicfields" value="${docdynamicfields}" />
<input type="hidden" id="uuid" name="uuid" value="" />
<input type="hidden" id="case_id" name="case_id" value="" />
<input type="hidden" id="company_id" name="company_id" value="${Sessvals.getCompanyID()}" />
<input type="hidden" id="branch_id" name="branch_id" value="${Sessvals.getBranchID()}" />
<input type="hidden" id="status" name="status" value="" />
<input type="hidden" id="docv" name="docv" value="0" />
<!-- -->
<input type="hidden" id="invalidfields" value="0" />
<c:if test="${formmode gt 0}">
<div style="position:fixed;text-align:right;bottom:0px;width:980px;" class="buttonbar">
<input type="hidden" id="invalidfields" value="0" />
<input type="button" class="button" name="btnfirst" style="margin-left:5px;margin-top:-2px;float:left;width:80px" value="" id="btnfirst" accesskey="F" onclick="findRecord(1)" />
<input type="button" class="button" name="btnprev" style="margin-top:-2px;float:left;width:80px" value="" id="btnprev" accesskey="P" onclick="findRecord(2)" />
<input type="button" class="button" name="btnnext" style="margin-top:-2px;float:left;width:80px" value="" id="btnnext" accesskey="N" onclick="findRecord(3)" />
<input type="button" class="button" name="btnlast" style="margin-top:-2px;float:left;width:80px" value="" id="btnlast" accesskey="L" onclick="findRecord(4)" />
<input type="button" class="button" name="btnadd" style="float:right" value="Add New Record" id="btnadd" accesskey="A" onclick="return AddNewRecord();" />
</div>
</c:if>
</form>
<input type="hidden" id="formmode" name="formmode" value="${formmode}" />
<input type="hidden" id="usid" name="usid" value="${usid}" />
</div>
</div>
</body>
<!-- Page Load Javascript -->
<script language="javascript" type="text/javascript">
InitPage('${portfolio_id}');
</script>
<!-- -->
<!-- Process Message -->
<c:if test="${not empty msg}">
<script language="javascript" type="text/javascript"> CallMessage('${msg}',3000,200,300); </script>
</c:if>
<!-- -->
</html>

View File

@@ -10,9 +10,9 @@
<link href="<c:url value='/css/matrix-shell-v2.css' />" rel="stylesheet" /> <link href="<c:url value='/css/matrix-shell-v2.css' />" rel="stylesheet" />
<link href="<c:url value='/css/matrix-theme-v2.css' />" rel="stylesheet" /> <link href="<c:url value='/css/matrix-theme-v2.css' />" rel="stylesheet" />
<script src="<c:url value='/js/matrix-shell-v2.js' />" defer></script> <script src="<c:url value='/js/matrix-shell-v2.js' />" defer></script>
<title>Cygnus 1.0 | <c:out value="${empty errorDetails.title ? 'Page unavailable' : errorDetails.title}" /></title> <title>Cygnus 1.0 | <c:out value="${empty messageDetails.title ? 'Page unavailable' : messageDetails.title}" /></title>
</head> </head>
<body class="matrix-v2 matrix-shell matrix-error-page matrix-error-page--${empty errorDetails.httpStatus ? 404 : errorDetails.httpStatus}"> <body class="matrix-v2 matrix-shell matrix-error-page matrix-error-page--${empty messageDetails.httpStatus ? 404 : messageDetails.httpStatus}">
<c:choose> <c:choose>
<c:when test="${not empty Sessvals and not empty Sessvals.menuHtml}"> <c:when test="${not empty Sessvals and not empty Sessvals.menuHtml}">
<%@ include file="/WEB-INF/app/fragments/app-shell-header.jspf" %> <%@ include file="/WEB-INF/app/fragments/app-shell-header.jspf" %>
@@ -25,20 +25,20 @@
<main class="matrix-error-layout" id="mainContent"> <main class="matrix-error-layout" id="mainContent">
<section class="matrix-error-card" role="alert" aria-labelledby="errorTitle"> <section class="matrix-error-card" role="alert" aria-labelledby="errorTitle">
<div class="matrix-error-card__status" aria-hidden="true"> <div class="matrix-error-card__status" aria-hidden="true">
<span><c:out value="${empty errorDetails.httpStatus ? 404 : errorDetails.httpStatus}" /></span> <span><c:out value="${empty messageDetails.httpStatus ? 404 : messageDetails.httpStatus}" /></span>
</div> </div>
<div class="matrix-error-card__content"> <div class="matrix-error-card__content">
<span class="matrix-error-card__eyebrow"> <span class="matrix-error-card__eyebrow">
Error <c:out value="${empty errorDetails.errorCode ? 'HTTP-404' : errorDetails.errorCode}" /> Error <c:out value="${empty messageDetails.code ? 'HTTP-404' : messageDetails.code}" />
</span> </span>
<h1 id="errorTitle"> <h1 id="errorTitle">
<c:out value="${empty errorDetails.title ? 'Page unavailable' : errorDetails.title}" /> <c:out value="${empty messageDetails.title ? 'Page unavailable' : messageDetails.title}" />
</h1> </h1>
<p class="matrix-error-card__message"> <p class="matrix-error-card__message">
<c:out value="${empty errorDetails.message ? 'The requested page is unavailable.' : errorDetails.message}" /> <c:out value="${empty messageDetails.message ? 'The requested page is unavailable.' : messageDetails.message}" />
</p> </p>
<c:if test="${not empty errorDetails.description}"> <c:if test="${not empty messageDetails.description}">
<p class="matrix-error-card__description"><c:out value="${errorDetails.description}" /></p> <p class="matrix-error-card__description"><c:out value="${messageDetails.description}" /></p>
</c:if> </c:if>
<div class="matrix-error-card__actions"> <div class="matrix-error-card__actions">
@@ -55,9 +55,9 @@
</c:choose> </c:choose>
</div> </div>
<c:if test="${not empty errorDetails.referenceId}"> <c:if test="${not empty messageDetails.referenceId}">
<p class="matrix-error-card__reference"> <p class="matrix-error-card__reference">
Reference ID: <code><c:out value="${errorDetails.referenceId}" /></code> Reference ID: <code><c:out value="${messageDetails.referenceId}" /></code>
</p> </p>
</c:if> </c:if>
</div> </div>

View File

@@ -6,8 +6,8 @@
<span>Cygnus 1.0</span> <span>Cygnus 1.0</span>
</div> </div>
<div class="matrix-shell__context" aria-label="Current session"> <div class="matrix-shell__context" aria-label="Current session">
<span class="matrix-shell__company"><c:out value="${Sessvals.getCompanyCode()}" /> (<c:out value="${Sessvals.getBranchLocation()}" />)</span> <span class="matrix-shell__company"><c:out value="${sessionScope.userSession.companyCode}" /> (<c:out value="${sessionScope.userSession.branchLocation}" />)</span>
<span class="matrix-shell__user"><c:out value="${Sessvals.getUserDisplayName()}" /> (<c:out value="${Sessvals.getUserGroupName()}" />)</span> <span class="matrix-shell__user"><c:out value="${sessionScope.userSession.userDisplayName}" /> (<c:out value="${sessionScope.userSession.userGroupName}" />)</span>
</div> </div>
</div> </div>
</header> </header>

View File

@@ -63,6 +63,41 @@
.matrix-add-cases .matrix-form-controls textarea { .matrix-add-cases .matrix-form-controls textarea {
width: 100% !important; width: 100% !important;
min-height: 30px; min-height: 30px;
font-weight: 400;
}
.matrix-add-cases .matrix-phone-extension {
display: grid;
grid-template-columns: minmax(0, 1fr) auto 48px;
align-items: center;
gap: 4px;
}
.matrix-add-cases .matrix-phone-extension > input {
width: 100% !important;
min-width: 0;
}
.matrix-add-cases .matrix-edit-back {
display: inline-flex;
align-items: center;
gap: 5px;
min-height: 28px;
margin-left: auto;
padding: 3px 10px;
color: #245f91;
font-size: 12px;
font-weight: 600;
border: 1px solid #9eb5c8;
border-radius: 4px;
background: #f6f9fb;
}
.matrix-add-cases .matrix-edit-back:hover,
.matrix-add-cases .matrix-edit-back:focus-visible {
color: #fff;
border-color: #28699d;
background: #28699d;
} }
.matrix-add-cases .matrix-form-controls .widget:has(#splist), .matrix-add-cases .matrix-form-controls .widget:has(#splist),

View File

@@ -75,7 +75,8 @@
right:8px; right:8px;
cursor:pointer; cursor:pointer;
} }
.title #ctrldiv .title #ctrldiv,
.title .ctrldiv
{ {
border:none; border:none;
position:relative; position:relative;

View File

@@ -4,19 +4,66 @@
background: #f4f8fb; background: #f4f8fb;
} }
.matrix-edit-cases .matrix-tool-workspace__content > .title .divselect { .matrix-edit-cases #caseGrid > div > .title {
width: min(330px, 38vw) !important; display: flex !important;
margin-left: auto; align-items: center;
position: static !important; flex-wrap: nowrap !important;
gap: 7px;
} }
.matrix-edit-cases .matrix-tool-workspace__content > .title select { .matrix-edit-cases #caseGrid > div > .title > .matrix-title-text {
width: 100% !important; flex: 0 0 auto;
min-height: 28px; white-space: nowrap;
padding: 3px 28px 3px 7px; }
border: 1px solid #9fb1c1;
border-radius: 3px; .matrix-edit-cases #caseGrid > div > .title > .matrix-edit-cases__portfolio-select {
background-color: #fff; width: 0 !important;
min-width: 0;
flex: 1 1 auto;
margin: 0 !important;
font-family: Tahoma, Arial, sans-serif;
font-size: 10pt;
font-weight: 400;
padding: 2px 30px 2px 7px !important;
}
.matrix-edit-cases #caseGrid > div > .title > .matrix-edit-cases__refresh {
box-sizing: border-box !important;
width: 27px !important;
height: 27px !important;
min-width: 27px !important;
min-height: 27px !important;
margin: 0 !important;
flex: 0 0 27px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0 !important;
border: 0 !important;
border-radius: 0 !important;
outline: 0 !important;
appearance: none;
background: transparent !important;
box-shadow: none !important;
}
.matrix-edit-cases #caseGrid > div > .title > .matrix-edit-cases__refresh:hover,
.matrix-edit-cases #caseGrid > div > .title > .matrix-edit-cases__refresh:focus,
.matrix-edit-cases #caseGrid > div > .title > .matrix-edit-cases__refresh:focus-visible,
.matrix-edit-cases #caseGrid > div > .title > .matrix-edit-cases__refresh:active {
width: 27px !important;
height: 27px !important;
margin: 0 !important;
padding: 0 !important;
border: 0 !important;
outline: 0 !important;
background: transparent !important;
box-shadow: none !important;
}
.matrix-edit-cases .matrix-edit-cases__refresh img {
width: 16px;
height: 16px;
} }
.matrix-edit-cases .tableContainer { .matrix-edit-cases .tableContainer {
@@ -55,12 +102,4 @@
width: 100% !important; width: 100% !important;
} }
.matrix-edit-cases .matrix-tool-workspace__content > .title {
flex-wrap: wrap;
}
.matrix-edit-cases .matrix-tool-workspace__content > .title .divselect {
width: 100% !important;
order: 3;
}
} }

View File

@@ -123,6 +123,22 @@ body.matrix-v2 #PageFrame {
border-radius: var(--matrix-radius-sm); border-radius: var(--matrix-radius-sm);
} }
.matrix-v2 #cygnus-notifications .alert-dismissible {
position: relative;
padding-right: 38px;
}
.matrix-v2 #cygnus-notifications .alert-dismissible > .btn-close {
position: absolute;
top: 50%;
right: 10px;
width: 1em;
height: 1em;
margin: 0;
padding: 0;
transform: translateY(-50%);
}
/* Shared title treatment for migrated and legacy-backed views. */ /* Shared title treatment for migrated and legacy-backed views. */
.matrix-v2 .title, .matrix-v2 .title,
.matrix-v2 .card-header, .matrix-v2 .card-header,

View File

@@ -53,11 +53,14 @@
min-width: 72px; min-width: 72px;
} }
.matrix-punch-workspace .buttonbar input[id="btnsave"], .matrix-punch-workspace .buttonbar input[id="btnsave"] {
.matrix-punch-workspace .buttonbar input[id="btnadd"] {
margin-left: auto !important; margin-left: auto !important;
} }
.matrix-punch-workspace .buttonbar input[id="btnadd"] {
margin-left: 0 !important;
}
.matrix-punch-workspace #formcontainer > .title { .matrix-punch-workspace #formcontainer > .title {
position: sticky; position: sticky;
z-index: 21; z-index: 21;

View File

@@ -31,8 +31,7 @@ Owner of DHTMLgoodies.com
var ajax_list_externalFile = 'getlocality'; // Path to external file var ajax_list_externalFile = 'getlocality'; // Path to external file
var minimumLettersBeforeLookup = 1; // Number of letters entered before a lookup is performed. var minimumLettersBeforeLookup = 1; // Number of letters entered before a lookup is performed.
var ajax_list_objects = new Array(); var ajax_list_cachedLists = new Array();
var ajax_list_cachedLists = new Array();
var ajax_list_activeInput = false; var ajax_list_activeInput = false;
var ajax_list_activeItem; var ajax_list_activeItem;
var ajax_list_optionDivFirstItem = false; var ajax_list_optionDivFirstItem = false;
@@ -40,7 +39,7 @@ Owner of DHTMLgoodies.com
var ajax_optionDiv = false; var ajax_optionDiv = false;
var ajax_optionDiv_iframe = false; var ajax_optionDiv_iframe = false;
var ajax_list_MSIE = false; var ajax_list_MSIE = false;
var currentListIndex = 0; var currentListIndex = 0;
@@ -75,19 +74,13 @@ Owner of DHTMLgoodies.com
ajax_list_activeInput.value = tmpValue; ajax_list_activeInput.value = tmpValue;
if(document.getElementsByName(ajax_list_activeInput.name + '_hidden')[0]) if(document.getElementsByName(ajax_list_activeInput.name + '_hidden')[0])
{ {
document.getElementsByName(ajax_list_activeInput.name + '_hidden')[0].value = inputObj.id.split("#-#")[0]; document.getElementsByName(ajax_list_activeInput.name + '_hidden')[0].value = inputObj.dataset.localityId;
if(ajax_list_externalFile == 'getlocality') if(ajax_list_externalFile == 'getlocality')
{ {
document.getElementsByName(ajax_list_activeInput.name + '_pincode')[0].value = inputObj.id.split("#-#")[1]; document.getElementsByName(ajax_list_activeInput.name + '_pincode')[0].value = inputObj.dataset.pincode;
document.getElementsByName(ajax_list_activeInput.name + '_citylist')[0].value = inputObj.id.split("#-#")[2]; document.getElementsByName(ajax_list_activeInput.name + '_citylist')[0].value = inputObj.dataset.city;
} }
//$('#'+ajax_list_activeInput.name + '_pincode').val(inputObj.id.split("#-#")[1]);
//$('#'+ajax_list_activeInput.name + '_citylist').val(inputObj.id.split("#-#")[2]);
} }
//var f1=setTimeout('ajax_list_activeInput.focus()',1);
//var f2=setTimeout('ajax_list_activeInput.value = ajax_list_activeInput.value',1);
ajax_options_hide(); ajax_options_hide();
} }
@@ -119,7 +112,7 @@ Owner of DHTMLgoodies.com
ajax_optionDiv.innerHTML = ''; ajax_optionDiv.innerHTML = '';
ajax_list_activeItem = false; ajax_list_activeItem = false;
if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length<=1){ if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length===0){
ajax_options_hide(); ajax_options_hide();
return; return;
} }
@@ -129,19 +122,20 @@ Owner of DHTMLgoodies.com
ajax_list_optionDivFirstItem = false; ajax_list_optionDivFirstItem = false;
var optionsAdded = false; var optionsAdded = false;
for(var no=0;no<ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length;no++){ for(var no=0;no<ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length;no++){
if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()][no].length==0)continue; var locality = ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()][no];
optionsAdded = true; if(!locality || !locality.location)continue;
var div = document.createElement('DIV'); optionsAdded = true;
var items = ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()][no].split(/!C0L!/gi); var div = document.createElement('DIV');
if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length==1 && ajax_list_activeInput.value == items[0]){ if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length==1 && ajax_list_activeInput.value == locality.location){
ajax_options_hide(); ajax_options_hide();
return; return;
} }
div.textContent = locality.location;
div.innerHTML = items[items.length-1]; div.dataset.localityId = locality.id;
div.id = items[0]; div.dataset.pincode = locality.pincode || '';
div.dataset.city = locality.city || '';
div.className='optionDiv'; div.className='optionDiv';
div.onmouseover = function(){ ajax_options_rollOverActiveItem(this,false); }; div.onmouseover = function(){ ajax_options_rollOverActiveItem(this,false); };
div.onclick = ajax_option_setValue; div.onclick = ajax_option_setValue;
@@ -156,17 +150,6 @@ Owner of DHTMLgoodies.com
} }
function ajax_option_list_showContent(ajaxIndex,inputObj,paramToExternalFile,whichIndex)
{
if(whichIndex!=currentListIndex)return;
var letters = inputObj.value;
var content = ajax_list_objects[ajaxIndex].response;
var elements = content.split('!R0W!');
ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()] = elements;
ajax_option_list_buildList(letters,paramToExternalFile);
}
function ajax_option_resize(inputObj) function ajax_option_resize(inputObj)
{ {
ajax_optionDiv.style.top = (ajax_getTopPos(inputObj) + inputObj.offsetHeight + ajaxBox_offsetY) + 'px'; ajax_optionDiv.style.top = (ajax_getTopPos(inputObj) + inputObj.offsetHeight + ajaxBox_offsetY) + 'px';
@@ -250,18 +233,27 @@ Owner of DHTMLgoodies.com
if(ajax_list_cachedLists[paramToExternalFile][inputObj.value.toLowerCase()]){ if(ajax_list_cachedLists[paramToExternalFile][inputObj.value.toLowerCase()]){
ajax_option_list_buildList(inputObj.value,paramToExternalFile,currentListIndex); ajax_option_list_buildList(inputObj.value,paramToExternalFile,currentListIndex);
}else{ }else{
var tmpIndex=currentListIndex/1; var tmpIndex=currentListIndex/1;
ajax_optionDiv.innerHTML = ''; ajax_optionDiv.innerHTML = '';
var ajaxIndex = ajax_list_objects.length; if(cityval.toUpperCase() == "GURGAON") {
ajax_list_objects[ajaxIndex] = new sack(); cityval = "Gurugram";
if(cityval.toUpperCase() == "GURGAON") { }
cityval = "Gurugram"; var letters=inputObj.value;
} var url=ajax_list_externalFile+'?'+new URLSearchParams({city:cityval,letters:letters}).toString();
//var url = ajax_list_externalFile + '?' + paramToExternalFile + '='+cityval+'&letters=' + inputObj.value.replace(" ","+"); fetch(url,{method:'GET',credentials:'same-origin',headers:{Accept:'application/json'}})
var url = ajax_list_externalFile + '?city='+cityval+'&letters=' + inputObj.value.replace(" ","+"); .then(function(response){return response.json().then(function(body){return {response:response,body:body};});})
ajax_list_objects[ajaxIndex].requestFile = url; // Specifying which file to get .then(function(result){
ajax_list_objects[ajaxIndex].onCompletion = function(){ ajax_option_list_showContent(ajaxIndex,inputObj,paramToExternalFile,tmpIndex); }; // Specify function that will be executed after file has been found if(!result.response.ok || !result.body || !result.body.success) throw result.body && result.body.message ? result.body.message : {};
ajax_list_objects[ajaxIndex].runAJAX(); // Execute AJAX function var localities=Array.isArray(result.body.data && result.body.data.localities) ? result.body.data.localities : [];
ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()]=localities;
if(tmpIndex==currentListIndex) ajax_option_list_buildList(letters,paramToExternalFile);
})
.catch(function(error){
if(tmpIndex!=currentListIndex)return;
ajax_options_hide();
CygnusNotifications.show({type:'danger',code:error.code || 'APP-5002',
message:error.message || 'Cygnus could not load localities.',referenceId:error.referenceId});
});
} }
@@ -269,7 +261,7 @@ Owner of DHTMLgoodies.com
function ajax_option_keyNavigation(e) function ajax_option_keyNavigation(e)
{ {
if(!ajax_optionDiv)return; if(!ajax_optionDiv)return;
if(ajax_optionDiv.style.display=='none')return; if(ajax_optionDiv.style.display=='none')return;
if(e.keyCode==38){ // Up arrow if(e.keyCode==38){ // Up arrow
@@ -302,7 +294,7 @@ Owner of DHTMLgoodies.com
function autoHideList(e) function autoHideList(e)
{ {
var source = e.target; var source = e.target;
if (source.nodeType == 3) // defeat Safari bug if (source.nodeType == 3) // defeat Safari bug
source = source.parentNode; source = source.parentNode;
if(source.tagName.toLowerCase()!='input' && source.tagName.toLowerCase()!='textarea') if(source.tagName.toLowerCase()!='input' && source.tagName.toLowerCase()!='textarea')
@@ -310,4 +302,4 @@ Owner of DHTMLgoodies.com
document.getElementsByName(ajax_list_activeInput.name + '_hidden')[0].value = ''; document.getElementsByName(ajax_list_activeInput.name + '_hidden')[0].value = '';
ajax_options_hide(); ajax_options_hide();
} }
} }

View File

@@ -1,120 +0,0 @@
var currow=null;
function ValidateEntry(flag)
{
validate(document.getElementById("doctype"),flag,'');
validate(document.getElementById("docholdername"),flag,'SplInstruction');
if(validateHidden && $("#serviceprovider_hidden").val()=='')
{
$("#serviceprovider").val('');
}
validate(document.getElementById("serviceprovider"),flag,'SplInstruction');
var temp=$("#uniqueno").attr("onblur").replace( "validate(","" ).replace( ")","").replace(/'/g,"").split(",");
validate(document.getElementById("uniqueno"),flag,temp[2]);
var temp=$("#yearmonth").attr("onblur").replace( "validate(","" ).replace( ")","").replace(/'/g,"").split(",");
validate(document.getElementById("yearmonth"),temp[1],temp[2]);
validate(document.getElementById("city"),flag,'');
}
function AddNewDoc()
{
ValidateEntry('t');
if(checkForm())
{
UpdateDoc();
}
else
{
CallMessage('VLFRM:error:There are one or more error(s) in form. Please correct them and try again.',3000,200,300);
}
}
function AddDocRow(data,did,vname)
{
var tbody = $('#doclist');
var totdocs= $('#doclist tr').length;
var row = null;
if(data.doc_id=='0')
{
row = $('<tr></tr>').attr("did",did).attr("onclick","GetRowData(this)").appendTo(tbody);
}
else
{
if(currow != null)
{
row = $("#doclist tr:eq("+currow+")");
$(row).html('');
totdocs = currow;
}
}
$('<td></td>').text(totdocs+1).appendTo(row);
$('<td></td>').text(data.docholdername).appendTo(row);
$('<td></td>').attr("dtype",data.doctype).text($("#doctype option[value='"+data.doctype+"']").text()).appendTo(row);
$('<td></td>').attr("id",data.serviceprovider_hidden).text(data.serviceprovider).appendTo(row);
$('<td></td>').attr("title",data.city).text(data.uniqueno).appendTo(row);
$('<td></td>').text(data.yearmonth).appendTo(row);
$('<td></td>').attr("id",data.vendor_id).text((vname.length > 0 ? vname:$("#vendor_id option[value='"+data.vendor_id+"']").text())).appendTo(row);
$('<td></td>').text("").appendTo(row);
}
function GetRowData(drow)
{
currow = $(drow).index();
$("#doctype").val($(drow).find('td').eq(2).attr("dtype"));
$("#doctype").trigger("change");
$("#docholdername").val($(drow).find('td').eq(1).text().trim());
$("#serviceprovider").val($(drow).find('td').eq(3).text().trim());
$("#serviceprovider_hidden").val($(drow).find('td').eq(3).attr("id"));
$("#uniqueno").val($(drow).find('td').eq(4).text().trim());
$("#yearmonth").val($(drow).find('td').eq(5).text().trim());
$("#city").val($(drow).find('td').eq(4).attr("title").trim());
//$("#vendor_id").val($(drow).find('td').eq(6).attr("id"));
ValidateEntry('t');
$("#doc_id").val($(drow).attr("did"));
}
function resetDocForm()
{
validateHidden = false;
document.getElementById('docdetails').reset();
$('#city').val("-1");
$('#vendor_id').empty().append('<option value="-1" selected>SELECT</option>');
currow = null;
}
function UpdateDoc()
{
var jsonString = JSON.stringify($('#docdetails').serializeObject()).substring();
jsonString = '{'+jsonString.substring(1, jsonString.length-1)+',"uuid":"'+$("#uuid").val()+'","usid":"'+$("#usid").val()+'"}';
$.ajax({
url:"doc/updcasedocs",
type:"POST",
contentType: "application/json; charset=utf-8",
data: jsonString, //Stringified Json Object
async: false, //Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation
cache: false, //This will force requested pages not to be cached by the browser
processData:false, //To avoid making query String instead of JSON
success: function(resposeJsonObject){
var dataArray = jQuery.parseJSON(resposeJsonObject);
if(dataArray.status.search("error") > -1)
{
CallMessage(dataArray.result,3000,200,300);
}
else
{
AddDocRow(dataArray.result,dataArray.did,'');
resetDocForm();
}
}
});
}
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};

View File

@@ -1,68 +0,0 @@
var currow=0;
var lastrow=0;
function InitPage()
{
$('form tbody.scrollContent tr').hover(function () {
$('#row'+lastrow).removeClass('rowhover');
ResetRow();
$(this).addClass('rowhover');
}, function () {
$(this).removeClass('rowhover');
});
$('form tbody.scrollContent tr').click(function () {
GetRowData(this);
});
}
function ResetRow()
{
currow=0;
lastrow=$('#casetable tr').length-1;
}
function GetRowData(SelectedRow)
{
/*QueryStr="rand="+Math.round(Math.random()*4+1)+"&uuid="+$("#"+SelectedRow.id+"uuid").val()+"&pid="+$("#"+SelectedRow.id+"portid").val();
var retVal=0; // Legacy commented example retained without removed browser API.
if(retVal==1)
{
$("#"+SelectedRow.id+"col").html("<img src='/matrix/images/edited.png' title='Details has been edited successfully. Please click refresh button to see the changes' />");
}*/
$("#uuid").val($("#"+SelectedRow.id+"uuid").val());
SubmitForm("caseedit", "_blank", "caseGrid");
}
function keyListen(param1,param2,e) {
var keycode = e.keyCode;
if(keycode==13)
{
GetRowData(document.getElementById("row"+currow));
}
else
{
if(keycode==40)
{
currow=currow+1;
if(currow>=$('#casetable tr').length){currow=1;lastrow=$('#casetable tr').length-1;}
}
if(keycode==38)
{
currow=currow-1;
if(currow<=0){currow=$('#casetable tr').length-1;lastrow=1;}
}
$('#row'+currow).addClass('rowhover');
$('#row'+lastrow).removeClass('rowhover');
document.getElementById('row'+currow).focus();
lastrow=currow;
}
}
function callkeydownhandler(evnt) {
var ev = evnt;
var focusedRow = ev.target && ev.target.tagName === "TR" ? ev.target : null;
if ((ev.key === "Enter" || ev.keyCode === 13) && focusedRow) {
ev.preventDefault();
GetRowData(focusedRow);
return;
}
keyListen('','',ev);
}
window.document.addEventListener("keydown", callkeydownhandler, false);

View File

@@ -19,7 +19,7 @@ function GetMoreDetails(SelectedRow)
$("#"+SelectedRow.id+"col").html("<img src='/matrix/images/edited.png' title='Details has been edited successfully. Please click refresh button to see the changes' />"); $("#"+SelectedRow.id+"col").html("<img src='/matrix/images/edited.png' title='Details has been edited successfully. Please click refresh button to see the changes' />");
}*/ }*/
$("#uuid").val($("#"+SelectedRow.id+"uuid").val()); $("#uuid").val($("#"+SelectedRow.id+"uuid").val());
SubmitForm("caseedit", "_blank", "caseGrid"); SubmitForm("caseedit", "_blank", "caseGrid");
} }
function ValidateEmailSearch() function ValidateEmailSearch()
{ {

View File

@@ -1,765 +0,0 @@
var records=new Array(1);
var fields=new Array(1);
var recIndx = 0;
var recpos = 0;
var autocut = 0;
var SameAddr=new Array(0);
var AddrElem=new Array(4);
var selectedAddr=-1;
var FocusAfter="customername";
AddrElem[0]=["rv","raddr1","raddr2","raddr3","rlandmark","Rcolony","colr","rcity","rpincode","rphone"];
AddrElem[1]=["ov","companyname","oaddr1","oaddr2","oaddr3","olandmark","Ocolony","colo","ocity","opincode","ophone","extension"];
AddrElem[2]=["pv","paddr1","paddr2","paddr3","plandmark","Pcolony","colp","pcity","ppincode"];
AddrElem[3]=["bankcode","bankcode","bank_branch_id","product","loanamount","apptype","contactperson","specialinst"];
function InitPage()
{
var portField = document.getElementById("portfolio_id");
var initialPortField = document.getElementById("initial-portfolio-id");
var visibleContentsField = document.getElementById("visiblecontents");
var port = initialPortField ? initialPortField.value : (portField ? portField.value : "-1");
var viscontents = visibleContentsField ? visibleContentsField.value : "";
if (viscontents && viscontents.slice(-ColDelim.length) !== ColDelim) {
viscontents += ColDelim;
}
centerDivBoth("formcontainer","H");
HideSections('rtv');
HideSections('otv');
HideSections('section');
UnhideSections(viscontents,ColDelim);
if (portField) {
$(portField).val(port);
}
if(port>0)
{
if(document.getElementById("ajaxmsg") !== null)
{
CallMessage('1001AJX:warning:Another operation is being processed, please wait..',3000,200,300);
return;
}
LoadingMsg("Fetching records, please wait...","ajaxmsg");
RunAjax("GET","punchedrecs","val0="+port+"&val1="+($("#dynamicfields").val())+"&val2="+($("#uuid").val()),1);
}
}
function ValidateSubmitForm(FormName)
{
var Chkresi=document.getElementById('rv');
var Chkoff=document.getElementById('ov');
var Chkprop=document.getElementById('pv');
if(Chkresi.checked || Chkoff.checked || Chkprop.checked || document.getElementById('rtv').checked || document.getElementById('otv').checked || document.getElementById('refv').checked)
{
validate(document.getElementById('applno'),'t','AlphaNumeric');
validate(document.getElementById('bank_branch_id'),'t','');
validate(document.getElementById('product'),'t','');
validate(document.getElementById('customername'),'t','AlphaSpace');
validate(document.getElementById('apptype'),'t','');
if(Chkresi.checked)
{
CheckForm(Chkresi,'raddr1,raddr2,raddr3,rlandmark,colr,rcity,rpincode','t,f,t,f,t,t,f','SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode');
if(document.getElementById('Rcolony').value=='' || document.getElementById('Rcolony').value=='0')
{
highlightField(document.getElementById('colr'));
}
}
if(Chkoff.checked)
{
CheckForm(Chkoff,'companyname,oaddr1,oaddr2,oaddr3,olandmark,colo,ocity,opincode,department,designation','f,t,f,t,f,t,t,f,f,f','SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode,SplInstruction,SplInstruction');
if(document.getElementById('Ocolony').value=='' || document.getElementById('Ocolony').value=='0')
{
highlightField(document.getElementById('colo'));
}
}
if(document.getElementById('rtv').checked)
{
CheckForm(document.getElementById('rtv'),'rphone','t','Phone');
}
if(document.getElementById('otv').checked)
{
CheckForm(document.getElementById('otv'),'ophone','t','Phone');
}
if(Chkprop.checked)
{
CheckForm(Chkprop,'paddr1,paddr2,paddr3,plandmark,colp,pcity,ppincode','t,f,t,f,t,t,f','SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode');
if(document.getElementById('Pcolony').value=='' || document.getElementById('Pcolony').value=='0')
{
highlightField(document.getElementById('colp'));
}
}
if(document.getElementById('refv').checked)
{
CheckForm(document.getElementById('refv'),'refname1,refaddress1,refcontactno1','t,f,t','AlphaSpace,SplInstruction,Phone');
}
if (invalidFields>0)
{
CallMessage('VLFRM:error:There are one or more error(s) in form. Please correct them and try again.',3000,200,300);
}
else
{
if(document.getElementById("ajaxmsg") !== null)
{
CallMessage('1001AJX:warning:Another operation is being processed, please wait..',3000,200,300);
return;
}
var Qstr=PrepareQStr();
if(document.getElementById("ajaxmsg") !== null)
{
CallMessage('1001AJX:warning:Another operation is being processed, please wait..',3000,200,300);
return false;
}
LoadingMsg("Saving details, please wait...","ajaxmsg");
RunAjax("GET","updatecase",Qstr,2);
}
}
else
{
CallMessage('VLFRM:error:Atleast one address verification is mandatory.',3000,200,300);
}
}
function PrepareQStr()
{
var val0='';
var val1='';
var indx=3;
autocut=$("#autocut").is(":checked") ? 1 : 0;
var lindx=fields[0].length-1;
var cid=$("#case_id").val();
var temp='';
for(indx;indx<lindx;indx++)
{
temp='';
if($("#"+fields[0][indx]).length > 0)
{
if(fields[0][indx]=='rv' || fields[0][indx]=='sradd' || fields[0][indx]=='rtv' ||
fields[0][indx]=='ov' || fields[0][indx]=='soadd' || fields[0][indx]=='otv' || fields[0][indx]=='rco'
|| fields[0][indx]=='pv' || fields[0][indx]=='rcp' || fields[0][indx]=='ocp' || fields[0][indx]=='spadd'|| fields[0][indx]=='refv'|| fields[0][indx]=='docv')
{
temp=$("#"+fields[0][indx]).is(':checked') ? '1':'0';
}
else if(fields[0][indx]=='portfolio_id' || fields[0][indx]=='bank_branch_id' || fields[0][indx]=='company_id' || fields[0][indx]=='branch_id' || fields[0][indx]=='Rcolony' || fields[0][indx]=='Ocolony' || fields[0][indx]=='Pcolony')
{
temp=$("#"+fields[0][indx]).val()=='' ? '0':$("#"+fields[0][indx]).val();
}
else if(fields[0][indx]=='colr' || fields[0][indx]=='colo' || fields[0][indx]=='colp' || fields[0][indx]=='status')
{
temp=$("#"+fields[0][indx]).val();
records[recpos][indx]=temp.replace(/\'/g,'');
continue;
}
else
{
temp="''"+$("#"+fields[0][indx]).val().replace(/,/g, ' ')+"''";
}
val0=val0+fields[0][indx]+',';
val1=val1+temp+",";
records[recpos][indx]=temp.replace(/\'/g,'');
}
else
{
val0=val0+fields[0][indx]+',';
val1=val1+"NULL,";
records[recpos][indx]=temp.replace(/\'/g,'');
}
}
val1=val1.replace(/&/g,'~AmP~');
return "val0="+val0+"&val1="+val1+"&val2="+cid+"&val3="+($("#uuid").val())+"&val4="+autocut+"&val5="+($("#usid").val())+"&val6="+($("#portfolio_id").val())+"&val7="+($("#formmode").val());
}
function GotoRecord(el,searchtype)
{
recno=el.value;
if(recno!='')
{
if(searchtype == 'recno')
{
if(recno > recIndx || recno <=0)
{
CallMessage('1001IRNG:error:Invalid input. Out of range',3000,200,300);
}
else
{
recpos=recno-1;
FillDetails(recpos);
}
}
else
{
for(index = 0; index < records.length; index++ )
{
if( records[index][4] === recno ) {
recpos = index;
FillDetails(recpos);
break;
}
}
}
}
}
function AddNewRecord()
{
if(recIndx== 0 || records[recIndx-1][0]!='0')
{
var cols=fields[0].length;
recIndx = recIndx+1;
recpos = recIndx-1;
records[recpos]=new Array(cols);
records[recpos][0]='0';
records[recpos][1]=$("#portfolio_id").val();
records[recpos][cols-4]='0';
records[recpos][cols-3]=$("#company_id").val();
records[recpos][cols-2]=$("#branch_id").val();
records[recpos][cols-1]='';
records[recpos][2]='******';
}
else
{
recpos=recIndx-1;
}
FillDetails(recpos);
}
function AfterResponse(response,oprID)
{
var rindx=0;
if(oprID==1)
{
$("#ajaxmsg").remove();
if(response.trim().search('Error')==-1)
{
var rows=response.split(RowDelim);
for(rindx=0;rindx<rows.length-1;rindx++)
{
var cindx=0;
var cols=rows[rindx].split(ColDelim);
if(rindx==0)
{
fields[rindx]=new Array(cols.length);
}
else
{
records[rindx-1]=new Array(cols.length);
}
for(cindx=0;cindx<cols.length;cindx++)
{
if(rindx==0)
{
fields[rindx][cindx]=cols[cindx];
}
else
{
records[rindx-1][cindx]=cols[cindx];
}
}
}
}
else
{
CallMessage(response,3000,200,300);
}
recIndx= rindx==0 ? rindx : rindx-1;
$("#recfound").html("<b>( 0 / "+(recIndx==0 ? "0" : recIndx)+" )</b>");
recpos=recIndx==0 ? 0 : recIndx-1;
FillDetails(recpos);
}
else if(oprID==2)
{
collen=fields[0].length;
$("#ajaxmsg").remove();
if(response.trim().search('Error')==-1)
{
if(autocut==1)
{
records[recpos][collen-4]='1';
}
if($("#case_id").val()!='0')
{
findRecord(3);
}
else
{
records[recpos][2]=response.split(ColDelim)[0];
records[recpos][0]=response.split(ColDelim)[1];
records[recpos][collen-1]=response.split(ColDelim)[2];
AddNewRecord();
}
CallMessage('1001IRNG:info:Record updated successfully',3000,200,300);
}
else
{
records[recpos][collen-4]='-1';
CallMessage(response,3000,200,300);
}
}
else if(oprID==19 || oprID==20 || oprID==21 || oprID==22)
{
TabRows=response.split(RowDelim);
for(indx=0;indx<TabRows.length-1;indx++)
{
if($("#portfolio_id").val()==81)
{
var appl = $("#applno").val();
alert('Application number '+appl+' already exists.');
appl= (appl.search('_1') < 0 ? appl+'_1' : appl.split('_')[0]+'_'+(parseInt(appl.split('_')[1])+1));
$("#applno").val(appl);
validate(document.getElementById('applno'),'t','AlphaNumeric');
document.getElementById('applno').focus();
}
else
{
TabCols=TabRows[indx].split(ColDelim);
SameAddr[indx]=new Array(TabCols.length);
for(cindx=0;cindx<TabCols.length;cindx++)
{
SameAddr[indx][cindx]=TabCols[cindx];
}
}
}
SelectAddr(oprID-19);
}
}
function findRecord(arrOpr)
{
tempPos= recpos;
maxLen= recIndx-1;
if(arrOpr==1) tempPos=0;
if(arrOpr==2)
{
if(tempPos>0) tempPos=tempPos-1;
else return false;
}
if(arrOpr==3)
{
if(tempPos<maxLen) tempPos=tempPos+1;
else return false;
}
if(arrOpr==4) tempPos=maxLen;
recpos= tempPos;
FillDetails(recpos);
}
function FillDetails(indx)
{
if(recIndx > 0)
{
document.forms['casedetails'].reset();
$("#recfound").html("<b>( "+(indx+1)+" / "+(recIndx==0 ? "0" : recIndx)+" )</b>");
var findx=0;
for(findx=0;findx<fields[0].length;findx++)
{
if($("#"+fields[0][findx]).length > 0)
{
if(fields[0][findx]=='rv' || fields[0][findx]=='sradd' || fields[0][findx]=='rtv' ||
fields[0][findx]=='ov' || fields[0][findx]=='soadd' || fields[0][findx]=='otv' || fields[0][findx]=='rco'
|| fields[0][findx]=='pv' || fields[0][findx]=='rcp' || fields[0][findx]=='ocp' || fields[0][findx]=='spadd'|| fields[0][findx]=='refv'|| fields[0][findx]=='docv')
{
if(fields[0][findx]=='docv')
{
if($("#"+fields[0][findx]).is(":visible"))
{
$("#"+fields[0][findx]).attr('checked',true);
}
}
else
{
if(records[indx][findx]=='1')
{
$("#"+fields[0][findx]).attr('checked',true);
}
else
{
$("#"+fields[0][findx]).attr('checked',false);
}
}
}
else
{
$("#"+fields[0][findx]).val(records[indx][findx]);
}
}
}
if($("#status").val()=='1')
{
$("#btnsave").hide();
}
else
{
$("#btnsave").show();
}
FireClickEvents();
document.getElementById("applno").focus();
}
else
{
CallMessage('5005MQRY:error:No records found',3000,200,300);
AddNewRecord();
}
}
function FireClickEvents()
{
HandleClick(document.getElementById('rv'));
HandleClick(document.getElementById('ov'));
HandleClick(document.getElementById('rtv'));
HandleClick(document.getElementById('otv'));
HandleClick(document.getElementById('pv'));
HandleClick(document.getElementById('refv'));
}
function FireToggleEvents()
{
ToggleChks((document.getElementById('rv').checked && document.getElementById('ov').checked),'rco'+ColDelim,ColDelim);
ToggleChks((document.getElementById('apptype').value.toUpperCase()!='APPLICANT' && document.getElementById('apptype').value.toUpperCase()!='-1'),'sradd!C0L!soadd!C0L!spadd!C0L!','!C0L!');
ToggleChks((document.getElementById('rv').checked),'rcp'+ColDelim,ColDelim);
ToggleChks((document.getElementById('ov').checked),'ocp'+ColDelim,ColDelim);
}
function HandleClick(el)
{
if(el.id=='rv')
{
setFormValidation(el,'FormPanel2','raddr1,raddr2,raddr3,rlandmark,rcity,colr,rpincode','t,f,t,f,t,t,f','SplInstruction,SplInstruction,SplInstruction,SplInstruction,,SplInstruction,Pincode',document.getElementById('rtv').checked);
EnableDisableFields(el.checked,'raddr1,raddr2,raddr3,rlandmark,colr,rpincode',',');
}
if(el.id=='rtv')
{
setFormValidation(el,'FormPanel2','rphone','t','Phone',document.getElementById('rv').checked);
}
if(el.id=='ov')
{
setFormValidation(el,'FormPanel3','companyname,oaddr1,oaddr2,oaddr3,olandmark,ocity,colo,opincode,department,designation','f,t,f,t,f,t,t,f,f,f','SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,SplInstruction,Pincode,SplInstruction,SplInstruction',document.getElementById('otv').checked);
EnableDisableFields(el.checked,'oaddr1,oaddr2,oaddr3,olandmark,colo,opincode',',');
}
if(el.id=='rco')
{
if(el.checked)
{
AutoFill('rco',1);
}
else
{AutoFill('rco',0);}
}
if(el.id=='otv')
{
setFormValidation(el,'FormPanel3','ophone','t','Phone',document.getElementById('ov').checked);
}
if(el.id=='pv')
{
setFormValidation(el,'FormPanel4','paddr1,paddr2,paddr3,plandmark,pcity,colp,ppincode','t,f,t,f,t,t,f','SplInstruction,SplInstruction,SplInstruction,SplInstruction,,SplInstruction,Pincode',false);
EnableDisableFields(el.checked,'paddr1,paddr2,paddr3,plandmark,colp,ppincode',',');
if(!el.checked)
{
chkrcp=document.getElementById('rcp');
chkrcp.checked=false;
chkocp=document.getElementById('ocp');
chkocp.checked=false;
}
}
if(el.id=='rcp')
{
if(el.checked)
{
AutoFill('rcp',1);
chkocp=document.getElementById('ocp');
chkocp.checked=false;
chkprop=document.getElementById('pv');
chkprop.checked=true;
HandleClick(chkprop);
}
else
{AutoFill('rcp',0);}
}
if(el.id=='ocp')
{
if(el.checked)
{
AutoFill('ocp',1);
chkrcp=document.getElementById('rcp');
chkrcp.checked=false;
chkprop=document.getElementById('pv');
chkprop.checked=true;
HandleClick(chkprop);
}
else
{AutoFill('ocp',0);}
}
if(el.id=='refv')
{
setFormValidation(el,'FormPanel5','refname1,refaddress1,refcontactno1','t,f,t','AlphaSpace,SplInstruction,Phone',false);
}
}
function setFormValidation(Elem,FormPanel,ChildElems,IsRequired,Validation,CounterPartElem)
{
/*if(Elem.checked && !CounterPartElem)
{
hideForm(Elem.id, FormPanel);
}
if(!Elem.checked)
{
CheckForm(Elem,ChildElems,IsRequired,Validation);
if(!CounterPartElem)
{
hideForm(Elem.id, FormPanel);
}
}*/
if(Elem.checked || CounterPartElem)
{
UnhideSections(FormPanel+ColDelim, ColDelim);
}
else
{
HideSections(FormPanel);
}
CheckForm(Elem,ChildElems,IsRequired,Validation);
FireToggleEvents();
}
function CheckForm(Elem,ChildElems,IsRequired,Validation)
{
var Childs=ChildElems.split(",");
var IsChildReq=IsRequired.split(",");
var ValidString=Validation.split(",");
for(Indx=0;Indx<Childs.length;Indx++)
{
validate(document.getElementById(Childs[Indx]),Elem.checked ? IsChildReq[Indx]:'f',ValidString[Indx]);
}
}
function AutoFill(Opt,FillMode)
{
var SourceFields="";
var TargetFields="";
var isSameAdd=false;
if(Opt=='rco')
{
SourceFields="raddr1"+ColDelim+"raddr2"+ColDelim+"raddr3"+ColDelim+"Rcolony"+ColDelim+"colr"+ColDelim+"rcity"+ColDelim+"rlandmark"+ColDelim+"rpincode"+ColDelim+"rphone";
TargetFields="oaddr1"+ColDelim+"oaddr2"+ColDelim+"oaddr3"+ColDelim+"Ocolony"+ColDelim+"colo"+ColDelim+"ocity"+ColDelim+"olandmark"+ColDelim+"opincode"+ColDelim+"ophone";
if(document.getElementById('Rcolony').value==document.getElementById('Ocolony').value)
{
isSameAdd=true;
}
}
else if(Opt=='rcp')
{
SourceFields="raddr1"+ColDelim+"raddr2"+ColDelim+"raddr3"+ColDelim+"Rcolony"+ColDelim+"colr"+ColDelim+"rcity"+ColDelim+"rlandmark"+ColDelim+"rpincode";
TargetFields="paddr1"+ColDelim+"paddr2"+ColDelim+"paddr3"+ColDelim+"Pcolony"+ColDelim+"colp"+ColDelim+"pcity"+ColDelim+"plandmark"+ColDelim+"ppincode";
if(document.getElementById('Rcolony').value==document.getElementById('Pcolony').value)
{
isSameAdd=true;
}
}
else if(Opt=='ocp')
{
SourceFields="oaddr1"+ColDelim+"oaddr2"+ColDelim+"oaddr3"+ColDelim+"Ocolony"+ColDelim+"colo"+ColDelim+"ocity"+ColDelim+"olandmark"+ColDelim+"opincode";
TargetFields="paddr1"+ColDelim+"paddr2"+ColDelim+"paddr3"+ColDelim+"Pcolony"+ColDelim+"colp"+ColDelim+"pcity"+ColDelim+"plandmark"+ColDelim+"ppincode";
if(document.getElementById('Ocolony').value==document.getElementById('Pcolony').value)
{
isSameAdd=true;
}
}
if(FillMode==1)
{
CopyDetails(SourceFields,TargetFields);
}
else if(FillMode==0 && isSameAdd)
{
ClearDetails(TargetFields);
}
}
function ToggleChks(IsVisible,ChildElems,Delim)
{
if(IsVisible)
{
UnhideSections(ChildElems,Delim);
}
else
{
var Childs=ChildElems.split(Delim);
for(indx=0;indx<Childs.length-1;indx++)
{
HideSections(Childs[indx]);
document.getElementById(Childs[indx]).checked=false;
}
}
}
function ClearDetails(TargetFields)
{
if(TargetFields.length!=0)
{
var TargetList=TargetFields.split(ColDelim);
if(TargetList.length==TargetList.length)
{
for(pos=0;pos<TargetList.length;pos++)
{
$("#"+TargetList[pos]).val("");
}
}
}
}
function CopyDetails(SourceFields,TargetFields)
{
if(SourceFields.length!=0 && TargetFields.length!=0)
{
var SourceList=SourceFields.split(ColDelim);
var TargetList=TargetFields.split(ColDelim);
if(SourceList.length==TargetList.length)
{
for(pos=0;pos<SourceList.length;pos++)
{
$("#"+TargetList[pos]).val($("#"+SourceList[pos]).val());
}
}
}
}
function AfterOptSelect(ElemToRemove,OprID)
{
FillSameDet(selectedAddr, OprID);
selectedAddr=-1;
ElemToRemove.parentNode.removeChild(ElemToRemove);
}
function ShowAddrOptions(OprID)
{
var optDiv=document.createElement("div");
var Addr="";
optDiv.setAttribute("id","optDiv");
optDiv.setAttribute("class","FormPanel");
optDiv.setAttribute("style","font-family:Tahoma;overflow:visible");
var OptionPanel="<div id='TablePanel' class='tableContainer'><table border='0' cellspacing='0' width='100%' id='cutlist'><thead class='thead'><tr title='Row Title'><td colspan='2'>Available Addresses</td></tr></thead><tbody class='scrollContent'>";
for(indx=0;indx<SameAddr.length;indx++)
{
OptionPanel=OptionPanel+"<tr><td><input type='radio' name='rb1' id='rb"+indx+"' value='"+indx+"' onclick='selectedAddr=this.value;' /></td>";
OptionPanel=OptionPanel+"<td style='padding-right:5px'>";
for(cindx=0;cindx<4;cindx++)
{
Addr=Addr+" "+SameAddr[indx][cindx];
}
OptionPanel=OptionPanel+""+Addr+"</td></tr>";
Addr="";
}
OptionPanel=OptionPanel+"<tr><td colspan='2'><input type='button' class='button' name='btnok' style='margin-top:5px;float:right' value='OK' id='btnok' accesskey='K' onclick=\"AfterOptSelect(document.getElementById('inptDialog'),"+OprID+");\"";
OptionPanel=OptionPanel+"</tbody></table></div>";
optDiv.innerHTML=OptionPanel;
ShowInputDialog(optDiv,"Select Address","hint","inptDialog");
document.getElementById('rb0').focus();
}
function FillSameDet(AddrIndex,OprID)
{
if(!(AddrIndex < 0))
{
for(cindx=0;cindx<SameAddr[AddrIndex].length;cindx++)
{
$("#"+AddrElem[OprID][cindx+1]).val((SameAddr[AddrIndex][cindx]));
}
document.getElementById(FocusAfter).focus();
ToggleChks((document.getElementById('apptype').value.toUpperCase()!='APPLICANT' && document.getElementById('apptype').value.toUpperCase()!='-1'),'sradd!C0L!soadd!C0L!spadd!C0L!','!C0L!');
}
else
{
document.getElementById(AddrElem[OprID][0]).focus();
if(document.getElementById(AddrElem[OprID][0]).type=='checkbox'){document.getElementById(AddrElem[OprID][0]).checked=false;}
}
}
function SelectAddr(OprID)
{
if(SameAddr.length>1)
{
ShowAddrOptions(OprID);
}
else
{
FillSameDet(0,OprID);
}
}
function FindSameDet(Elm,Visit,focAfter)
{
if($("#case_id").val()!='0' && Visit=='A')
{
return;
}
else
{
FocusAfter=focAfter;
var procFlag=true;
if(Elm.type=='checkbox')
{
procFlag=Elm.checked;
}
if(procFlag)
{
Applno=document.getElementById('applno').value;
if(Applno.length==0)
{
if(Elm.type=='checkbox'){Elm.checked=false;}
CallMessage('VLFRM:error:Please enter application number.',3000,200,300);
document.getElementById('applno').focus();
return false;
}
else
{
SameAddr=new Array(0); // Empty Address Array
oprId=(Visit=='R' ? 19:Visit=='O' ? 20:Visit=='P' ? 21:22);
QryStr="val="+Applno+"&val1="+$("#portfolio_id").val()+"&val2="+oprId;
RunAjax("GET","findsdet",QryStr,oprId);
}
}
}
}
function FindStr(el,elmids,rstfld)
{
el.value=el.value.split('->')[0];
var skey=el.value.trim().toUpperCase();
if(skey!='UNKNOWN' && skey!='-1')
{
var elms=elmids.split(ColDelim);
var indx=0;
for(indx=0;indx<elms.length;indx++)
{
if($("#"+elms[indx]).val().toUpperCase().search(skey)>-1)
{
return true;
}
}
}
else
{
return true;
}
return false;
}
function HandleBlur(el)
{
if(el.id=='rcity' || el.id=='ocity' || el.id=='pcity')
{
var pel= (el.id=='rcity' ? 'Rcolony':(el.id=='ocity' ? 'Ocolony':'Pcolony'));
var cel= (el.id=='rcity' ? 'raddr':(el.id=='ocity' ? 'oaddr':'paddr'));
var hel= (el.id=='rcity' ? 'colr':(el.id=='ocity' ? 'colo':'colp'));
var chk= (el.id=='rcity' ? 'rv':(el.id=='ocity' ? 'ov':'pv'));
if(!FindStr(el,cel+'2!C0L!'+cel+'3'))
{
CallMessage("1001AREA:error:Invalid area.", 3000, 200, 300);
$(el).val("-1");
$("#"+pel).val("");
$("#"+hel).val("");
}
validate(el,document.getElementById(chk).checked ? 't':'f','');
}
if(el.id=='colr' || el.id=='colo' || el.id=='colp')
{
var pel= (el.id=='colr' ? 'rv':(el.id=='colo' ? 'ov':'pv'));
var cel= (el.id=='colr' ? 'raddr':(el.id=='colo' ? 'oaddr':'paddr'));
if(!FindStr(el,cel+'2!C0L!'+cel+'3'))
{
CallMessage("1001AREA:error:Invalid colony.", 3000, 200, 300);
$(el).val("");
}
if(el.value=='')
{
document.getElementsByName(el.id+'_hidden')[0].value='';
}
if(document.getElementsByName(el.id+'_hidden')[0].value=='')
{
el.value='';
}
validate(el,document.getElementById(pel).checked ? 't':'f','SplInstruction');
}
}

View File

@@ -1,425 +0,0 @@
//RowDelim="~R0W~";
//ColDelim="~C0L~";
var SameAddr=new Array(0);
var AddrElem=new Array(4);
var selectedAddr=-1;
var FocusAfter="CustomerName";
AddrElem[0]=["chksresi","ResiAdd1","ResiAdd2","ResiAdd3","ResiLandmark","ResiAdd3_hidden","ResiAdd3_citylist","ResiAdd3_Pincode","ResiPhone"];
AddrElem[1]=["chksoff","CompanyName","OffAdd1","OffAdd2","OffAdd3","OffLandmark","OffAdd3_hidden","OffAdd3_citylist","OffAdd3_Pincode","OffPhone","Extension"];
AddrElem[2]=["chksprop","PropAdd1","PropAdd2","PropAdd3","PropLandmark","PropAdd3_hidden","PropAdd3_citylist","PropAdd3_Pincode"];
AddrElem[3]=["BankCode","BankCode","branchlist","prodlist","LoanAmount","typelist","ContactPerson","splist"];
function SubmitPunching(pageURL,TargetWindow)
{
document.caseDetails.action=pageURL;
document.caseDetails.target=TargetWindow;
document.caseDetails.submit();
}
function FindSameDet(Elm,Visit,focAfter)
{
if($("#FormMode").val()=='2' && Visit=='A')
{
return;
}
else
{
FocusAfter=focAfter;
var procFlag=true;
if(Elm.type=='checkbox')
{
procFlag=Elm.checked;
}
if(procFlag)
{
Applno=document.getElementById('ApplNo').value;
if(Applno.length==0)
{
if(Elm.type=='checkbox'){Elm.checked=false;}
CallMessage('VLFRM:error:Please enter application number.',3000,200,300);
document.getElementById('ApplNo').focus();
return false;
}
else
{
SameAddr=new Array(0); // Empty Address Array
oprId=(Visit=='R' ? 19:Visit=='O' ? 20:Visit=='P' ? 21:22);
QryStr="val="+Applno+"&val1="+$("#portlist").val()+"&val2="+oprId;
RunAjax("GET","findsdet",QryStr,oprId);
}
}
}
}
function copyTelNo(isCopy,SourceElemId,TargetElemId)
{
if(isCopy)
{
var copyStr="/";
if(($("#"+TargetElemId).val().length) > 0)
{
copyStr=$("#"+TargetElemId).val()+"/"+$("#"+SourceElemId).val();
}
else
{
copyStr=$("#"+SourceElemId).val();
}
$("#"+TargetElemId).val(copyStr);
}
}
function SelectAddr(OprID)
{
if(SameAddr.length>1)
{
ShowAddrOptions(OprID);
}
else
{
FillSameDet(0,OprID);
}
}
function FillSameDet(AddrIndex,OprID)
{
if(!(AddrIndex < 0))
{
for(cindx=0;cindx<SameAddr[AddrIndex].length;cindx++)
{
$("#"+AddrElem[OprID][cindx+1]).val((SameAddr[AddrIndex][cindx]));
}
document.getElementById(FocusAfter).focus();
ToggleChks((document.getElementById('typelist').value.toUpperCase()!='APPLICANT' && document.getElementById('typelist').value.toUpperCase()!='-1'),'chksresi!C0L!chksoff!C0L!chksprop!C0L!','!C0L!');
}
else
{
document.getElementById(AddrElem[OprID][0]).focus();
if(document.getElementById(AddrElem[OprID][0]).type=='checkbox'){document.getElementById(AddrElem[OprID][0]).checked=false;}
}
}
function ShowAddrOptions(OprID)
{
var optDiv=document.createElement("div");
var Addr="";
optDiv.setAttribute("id","optDiv");
optDiv.setAttribute("class","FormPanel");
optDiv.setAttribute("style","font-family:Tahoma;overflow:visible");
var OptionPanel="<div id='TablePanel' class='tableContainer'><table border='0' cellspacing='0' width='100%' id='cutlist'><thead class='thead'><tr title='Row Title'><td colspan='2'>Available Addresses</td></tr></thead><tbody class='scrollContent'>";
for(indx=0;indx<SameAddr.length;indx++)
{
OptionPanel=OptionPanel+"<tr><td><input type='radio' name='rb1' id='rb"+indx+"' value='"+indx+"' onclick='selectedAddr=this.value;' /></td>";
OptionPanel=OptionPanel+"<td style='padding-right:5px'>";
for(cindx=0;cindx<4;cindx++)
{
Addr=Addr+" "+SameAddr[indx][cindx];
}
OptionPanel=OptionPanel+""+Addr+"</td></tr>";
Addr="";
}
OptionPanel=OptionPanel+"<tr><td colspan='2'><input type='button' class='button' name='btnok' style='margin-top:5px;float:right' value='OK' id='btnok' accesskey='K' onclick=\"AfterOptSelect(document.getElementById('inptDialog'),"+OprID+");\"";
OptionPanel=OptionPanel+"</tbody></table></div>";
optDiv.innerHTML=OptionPanel;
ShowInputDialog(optDiv,"Select Address","hint","inptDialog");
document.getElementById('rb0').focus();
}
function AfterOptSelect(ElemToRemove,OprID)
{
FillSameDet(selectedAddr, OprID);
selectedAddr=-1;
ElemToRemove.parentNode.removeChild(ElemToRemove);
}
function GatherRequirement(portID)
{
ClearDropDown("branch"+ColDelim+"product",ColDelim);
HideSections("section");
if(portID!=0)
{
QryStr="val0="+portID;
RunAjax("GET","filldds",QryStr,1);
}
}
function AfterResponse(AjaxResponse,OprID)
{
if(OprID==1)
{
ArrangePage(AjaxResponse);
}
else if(OprID==19 || OprID==20 || OprID==21 || OprID==22)
{
TabRows=AjaxResponse.split(RowDelim);
for(indx=0;indx<TabRows.length-1;indx++)
{
TabCols=TabRows[indx].split(ColDelim);
SameAddr[indx]=new Array(TabCols.length);
for(cindx=0;cindx<TabCols.length;cindx++)
{
SameAddr[indx][cindx]=TabCols[cindx];
}
}
SelectAddr(OprID-19);
}
}
function ArrangePage(AjaxResponse)
{
if(AjaxResponse!='')
{
var TempArr=AjaxResponse.split("#BRAN#");
var branch=TempArr[0];
TempArr=TempArr[1].split("#PROD#");
var product=TempArr[0];
var process=TempArr[1];
FillDD("branch",branch,RowDelim,ColDelim);
FillDD("product",product,RowDelim,ColDelim);
UnhideSections(process,ColDelim);
}
}
function ToggleChks(IsVisible,ChildElems,Delim)
{
if(IsVisible)
{
UnhideSections(ChildElems,Delim);
}
else
{
var Childs=ChildElems.split(Delim);
for(indx=0;indx<Childs.length-1;indx++)
{
HideSections(Childs[indx]);
document.getElementById(Childs[indx]).checked=false;
}
}
}
function setFormValidation(Elem,FormPanel,ChildElems,IsRequired,Validation,CounterPartElem)
{
if(Elem.checked && !CounterPartElem)
{
hideForm(Elem.id, FormPanel);
}
if(!Elem.checked)
{
CheckForm(Elem,ChildElems,IsRequired,Validation);
if(!CounterPartElem)
{
hideForm(Elem.id, FormPanel);
}
}
ToggleChks((document.getElementById('chkresi').checked && document.getElementById('chkoffice').checked),'chkrco'+ColDelim,ColDelim);
ToggleChks((document.getElementById('chkresi').checked),'chkrcp'+ColDelim,ColDelim);
ToggleChks((document.getElementById('chkoffice').checked),'chkocp'+ColDelim,ColDelim);
}
function AutoFill(Opt,FillMode)
{
var SourceFields="";
var TargetFields="";
var isSameAdd=false;
if(Opt=='chkrco')
{
SourceFields="ResiAdd1"+ColDelim+"ResiAdd2"+ColDelim+"ResiAdd3"+ColDelim+"ResiAdd3_hidden"+ColDelim+"ResiAdd3_citylist"+ColDelim+"ResiLandmark"+ColDelim+"ResiAdd3_Pincode"+ColDelim+"ResiPhone";
TargetFields="OffAdd1"+ColDelim+"OffAdd2"+ColDelim+"OffAdd3"+ColDelim+"OffAdd3_hidden"+ColDelim+"OffAdd3_citylist"+ColDelim+"OffLandmark"+ColDelim+"OffAdd3_Pincode"+ColDelim+"OffPhone";
if(document.getElementById('ResiAdd3_hidden').value==document.getElementById('OffAdd3_hidden').value)
{
isSameAdd=true;
}
}
else if(Opt=='chkrcp')
{
SourceFields="ResiAdd1"+ColDelim+"ResiAdd2"+ColDelim+"ResiAdd3"+ColDelim+"ResiAdd3_hidden"+ColDelim+"ResiAdd3_citylist"+ColDelim+"ResiLandmark"+ColDelim+"ResiAdd3_Pincode";
TargetFields="PropAdd1"+ColDelim+"PropAdd2"+ColDelim+"PropAdd3"+ColDelim+"PropAdd3_hidden"+ColDelim+"PropAdd3_citylist"+ColDelim+"PropLandmark"+ColDelim+"PropAdd3_Pincode";
if(document.getElementById('ResiAdd3_hidden').value==document.getElementById('PropAdd3_hidden').value)
{
isSameAdd=true;
}
}
else if(Opt=='chkocp')
{
SourceFields="OffAdd1"+ColDelim+"OffAdd2"+ColDelim+"OffAdd3"+ColDelim+"OffAdd3_hidden"+ColDelim+"OffAdd3_citylist"+ColDelim+"OffLandmark"+ColDelim+"OffAdd3_Pincode";
TargetFields="PropAdd1"+ColDelim+"PropAdd2"+ColDelim+"PropAdd3"+ColDelim+"PropAdd3_hidden"+ColDelim+"PropAdd3_citylist"+ColDelim+"PropLandmark"+ColDelim+"PropAdd3_Pincode";
if(document.getElementById('OffAdd3_hidden').value==document.getElementById('PropAdd3_hidden').value)
{
isSameAdd=true;
}
}
if(FillMode==1)
{
CopyDetails(SourceFields,TargetFields);
}
else if(FillMode==0 && isSameAdd)
{
ClearDetails(TargetFields);
}
}
function ClearDetails(TargetFields)
{
if(TargetFields.length!=0)
{
var TargetList=TargetFields.split(ColDelim);
if(TargetList.length==TargetList.length)
{
for(pos=0;pos<TargetList.length;pos++)
{
$("#"+TargetList[pos]).val("");
}
}
}
}
function CopyDetails(SourceFields,TargetFields)
{
if(SourceFields.length!=0 && TargetFields.length!=0)
{
var SourceList=SourceFields.split(ColDelim);
var TargetList=TargetFields.split(ColDelim);
if(SourceList.length==TargetList.length)
{
for(pos=0;pos<SourceList.length;pos++)
{
$("#"+TargetList[pos]).val($("#"+SourceList[pos]).val());
}
}
}
}
function CheckForm(Elem,ChildElems,IsRequired,Validation)
{
var Childs=ChildElems.split(",");
var IsChildReq=IsRequired.split(",");
var ValidString=Validation.split(",");
for(Indx=0;Indx<Childs.length;Indx++)
{
validate(document.getElementById(Childs[Indx]),Elem.checked ? IsChildReq[Indx]:'f',ValidString[Indx]);
}
}
function onLocalityBlur(el,IsRequired)
{
if(el.value=='')
{
document.getElementById(el.id+'_hidden').value='';
}
if(document.getElementById(el.id+'_hidden').value=='')
{
el.value='';
}
validate(el,IsRequired,'SplInstruction');
}
function ValidateSubmitForm(FormName)
{
var Chkresi=document.getElementById('chkresi');
var Chkoff=document.getElementById('chkoffice');
var Chkprop=document.getElementById('chkprop');
if(Chkresi.checked || Chkoff.checked || Chkprop.checked || document.getElementById('chkteler').checked || document.getElementById('chkteleo').checked || document.getElementById('chkref').checked || document.getElementById('chkdoc').checked)
{
validate(document.getElementById('ApplNo'),'t','AlphaNumeric');
validate(document.getElementById('branchlist'),'t','');
validate(document.getElementById('prodlist'),'t','');
validate(document.getElementById('CustomerName'),'t','AlphaSpace');
validate(document.getElementById('typelist'),'t','');
if(Chkresi.checked)
{
CheckForm(Chkresi,'ResiAdd1,ResiAdd2,ResiAdd3,ResiLandmark,ResiAdd3_citylist,ResiAdd3_Pincode','t,f,t,f,t,t','SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode');
if(document.getElementById('ResiAdd3_hidden').value=='' || document.getElementById('ResiAdd3_hidden').value=='0')
{
highlightField(document.getElementById('ResiAdd3'));
}
}
if(Chkoff.checked)
{
CheckForm(Chkoff,'CompanyName,OffAdd1,OffAdd2,OffAdd3,OffLandmark,OffAdd3_citylist,OffAdd3_Pincode,Department,Designation','f,t,f,t,f,t,t,f,f,t','SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode,SplInstruction,SplInstruction');
if(document.getElementById('OffAdd3_hidden').value=='' || document.getElementById('OffAdd3_hidden').value=='0')
{
highlightField(document.getElementById('OffAdd3'));
}
}
if(document.getElementById('chkteler').checked)
{
CheckForm(document.getElementById('chkteler'),'ResiPhone','t','Phone');
}
if(document.getElementById('chkteleo').checked)
{
CheckForm(document.getElementById('chkteleo'),'OffPhone','t','Phone');
}
if(Chkprop.checked)
{
CheckForm(Chkprop,'PropAdd1,PropAdd2,PropAdd3,PropLandmark,PropAdd3_citylist,PropAdd3_Pincode','t,f,t,f,t,t','SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode');
if(document.getElementById('PropAdd3_hidden').value=='' || document.getElementById('PropAdd3_hidden').value=='0')
{
highlightField(document.getElementById('PropAdd3'));
}
}
if(document.getElementById('chkref').checked)
{
CheckForm(document.getElementById('chkref'),'Ref1Name,Ref1Address,Ref1Contactno','t,f,t','AlphaSpace,SplInstruction,Phone');
}
if (invalidFields>0)
{
CallMessage('VLFRM:error:There are one or more error(s) in form. Please correct them and try again.',3000,200,300);
}
else
{
SubmitForm('casesave','_parent',FormName);
}
}
else
{
CallMessage('VLFRM:error:Atleast one address verification is mandatory.',3000,200,300);
}
}
function HandleClick(el)
{
if(el.id=='chkresi')
{
setFormValidation(el,'FormPanel2','ResiAdd1,ResiAdd2,ResiAdd3,ResiLandmark,ResiAdd3_citylist,ResiAdd3_Pincode','t,f,t,f,t,t,f','SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode',document.getElementById('chkteler').checked);
EnableDisableFields(el.checked,'ResiAdd1,ResiAdd2,ResiAdd3,ResiLandmark,ResiAdd3_Pincode',',');
}
if(el.id=='chkteler')
{
setFormValidation(el,'FormPanel2','ResiPhone','t','Phone',document.getElementById('chkresi').checked);
}
if(el.id=='chkoffice')
{
setFormValidation(el,'FormPanel3','CompanyName,OffAdd1,OffAdd2,OffAdd3,OffLandmark,OffAdd3_citylist,OffAdd3_Pincode,Department,Designation','f,t,f,t,f,t,t,f,f,t','SplInstruction,SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode,SplInstruction,SplInstruction',document.getElementById('chkteleo').checked);
EnableDisableFields(el.checked,'OffAdd1,OffAdd2,OffAdd3,OffLandmark,OffAdd3_Pincode',',');
}
if(el.id=='chkrco')
{
if(el.checked)
{
AutoFill('chkrco',1);
}
else
{AutoFill('chkrco',0);}
}
if(el.id=='chkteleo')
{
setFormValidation(el,'FormPanel3','OffPhone','t','Phone',document.getElementById('chkoffice').checked);
}
if(el.id=='chkprop')
{
setFormValidation(el,'FormPanel4','PropAdd1,PropAdd2,PropAdd3,PropLandmark,PropAdd3_citylist,PropAdd3_Pincode','t,f,t,f,t,t','SplInstruction,SplInstruction,SplInstruction,SplInstruction,,Pincode',false);
EnableDisableFields(el.checked,'PropAdd1,PropAdd2,PropAdd3,PropLandmark,PropAdd3_Pincode',',');
}
if(el.id=='chkrcp')
{
if(el.checked)
{
AutoFill('chkrcp',1);
chkocp=document.getElementById('chkocp');
chkocp.checked=false;
chkprop=document.getElementById('chkprop');
chkprop.checked=true;
HandleClick(chkprop);
}
else
{AutoFill('chkrcp',0);}
}
if(el.id=='chkocp')
{
if(el.checked)
{
AutoFill('chkocp',1);
chkrcp=document.getElementById('chkrcp');
chkrcp.checked=false;
chkprop=document.getElementById('chkprop');
chkprop.checked=true;
HandleClick(chkprop);
}
else
{AutoFill('chkocp',0);}
}
}

View File

@@ -1,403 +0,0 @@
var records=new Array(1);
var fields=new Array(1);
var recIndx = 0;
var recpos = 0;
var FocusAfter="customername";
ajax_list_externalFile = "listservprovider";
var validateHidden = false;
function InitPage(port)
{
centerDivBoth("formcontainer","H");
$("#portfolio_id").val(port);
ManageButtons(true);
$("#btnsave").hide();
if(port>0)
{
if(document.getElementById("ajaxmsg") !== null)
{
CallMessage('1001AJX:warning:Another operation is being processed, please wait..',3000,200,300);
return;
}
LoadingMsg("Fetching records, please wait...","ajaxmsg");
RunAjax("GET","puncheddocrecs","val0="+port+"&val1="+($("#dynamicfields").val()),1);
}
}
function PrepareQStr()
{
var val0='';
var val1='';
var indx=2;
autocut=0;
var lindx=fields[0].length-1;
var cid=$("#case_id").val();
var temp='';
for(indx;indx<lindx;indx++)
{
temp='';
if($("#"+fields[0][indx]).length > 0)
{
if(fields[0][indx]=='docv' || fields[0][indx]=='status')
{
continue;
}
else
{
temp="''"+$("#"+fields[0][indx]).val().replace(/,/g, ' ')+"''";
}
val0=val0+fields[0][indx]+',';
val1=val1+temp+",";
records[recpos][indx]=temp.replace(/\'/g,'');
}
else
{
val0=val0+fields[0][indx]+',';
val1=val1+"NULL,";
records[recpos][indx]=temp.replace(/\'/g,'');
}
}
val1=val1.replace(/&/g,'~AmP~');
return "val0="+val0+"&val1="+val1+"&val2="+cid+"&val3="+($("#uuid").val())+"&val4="+autocut+"&val5="+($("#usid").val())+"&val6="+($("#portfolio_id").val());
}
function GotoRecord(el)
{
recno=el.value;
if(recno!='')
{
if(recno > recIndx || recno <=0)
{
CallMessage('1001IRNG:error:Invalid input. Out of range',3000,200,300);
}
else
{
recpos=recno-1;
FillDetails(recpos);
}
}
}
function AddNewRecord()
{
if(recIndx== 0 || records[recIndx-1][0]!='0')
{
var cols=fields[0].length;
recIndx = recIndx+1;
recpos = recIndx-1;
records[recpos]=new Array(cols);
records[recpos][0]='0';
records[recpos][1]=$("#portfolio_id").val();
records[recpos][cols-4]='0';
records[recpos][cols-3]=$("#company_id").val();
records[recpos][cols-2]=$("#branch_id").val();
records[recpos][cols-1]='';
}
else
{
recpos=recIndx-1;
}
FillDetails(recpos);
}
function AfterResponse(response,oprID)
{
var rindx=0;
if(oprID==1)
{
$("#ajaxmsg").remove();
if(response.trim().search('Error')==-1)
{
var rows=response.split(RowDelim);
for(rindx=0;rindx<rows.length-1;rindx++)
{
var cindx=0;
var cols=rows[rindx].split(ColDelim);
if(rindx==0)
{
fields[rindx]=new Array(cols.length);
}
else
{
records[rindx-1]=new Array(cols.length);
}
for(cindx=0;cindx<cols.length;cindx++)
{
if(rindx==0)
{
fields[rindx][cindx]=cols[cindx];
}
else
{
records[rindx-1][cindx]=cols[cindx];
}
}
}
}
else
{
CallMessage(response,3000,200,300);
}
recIndx= rindx==0 ? rindx : rindx-1;
$("#recfound").html("<b>( 0 / "+(recIndx==0 ? "0" : recIndx)+" )</b>");
recpos=0;
FillDetails(recpos);
}
else if(oprID==2)
{
$("#ajaxmsg").remove();
collen=fields[0].length;
if(response.trim().search('Error')==-1)
{
if(autocut==1)
{
records[recpos][collen-4]='1';
}
if($("#case_id").val()!='0')
{
findRecord(3);
}
else
{
records[recpos][0]=response.split(ColDelim)[0];
records[recpos][collen-1]=response.split(ColDelim)[1];
AddNewRecord();
}
CallMessage('1001IRNG:info:Record updated successfully',3000,200,300);
}
else
{
records[recpos][collen-4]='-1';
CallMessage(response,3000,200,300);
}
}
else if(oprID==3)
{
$("#ajaxmsg").remove();
if(response.trim().search('Error')==-1)
{
CallMessage('1001IRNG:info:Record updated successfully',3000,200,300);
}
else
{
CallMessage(response,3000,200,300);
}
}
else if(oprID==4)
{
if(response.trim().search('Error')==-1)
{
FillDD("vendor_id",response,RowDelim,ColDelim);
if(currow != null)
{
$("#vendor_id").val($("#doclist tr:eq("+currow+")").find('td').eq(6).attr("id"));
}
}
else
{
CallMessage(response,3000,200,300);
}
}
else if(oprID==5)
{
if(response.trim().search('Error')==-1)
{
alert(response);
}
else
{
CallMessage(response,3000,200,300);
}
}
}
function findRecord(arrOpr)
{
tempPos= recpos;
maxLen= recIndx-1;
if(arrOpr==1) tempPos=0;
if(arrOpr==2)
{
if(tempPos>0) tempPos=tempPos-1;
else return false;
}
if(arrOpr==3)
{
if(tempPos<maxLen) tempPos=tempPos+1;
else return false;
}
if(arrOpr==4) tempPos=maxLen;
recpos= tempPos;
FillDetails(recpos);
}
function SearchRecord(elm)
{
var found=false;
var skey=elm.value.trim().toLowerCase();
for(rindx=0;rindx<records.length;rindx++)
{
if(records[rindx][3].trim().toLowerCase().search(skey)>-1)
{
recpos=rindx;
found=true;
FillDetails(recpos);
break;
}
}
if(!found)
{
CallMessage('NOREC1001:error:No record found.',3000,200,300);
}
}
function FillDetails(indx)
{
if(recIndx > 0)
{
CancelEdit();
document.forms['casedetails'].reset();
$("#doclist").html('');
resetDocForm();
$("#recfound").html("<b>( "+(indx+1)+" / "+(recIndx==0 ? "0" : recIndx)+" )</b>");
var cols = fields[0].length;
var findx=0;
for(findx=0;findx < cols;findx++)
{
if($("#"+fields[0][findx]).length > 0)
{
$("#"+fields[0][findx]).val(records[indx][findx]);
}
}
var data = jQuery.parseJSON(records[indx][cols-5].replace('},]}','}]}'));
var tdocs = data.docs.length;
for(indx = 0;indx < tdocs; indx++)
{
var did = data.docs[indx].doc_id;
data.docs[indx].doc_id="0";
AddDocRow(data.docs[indx],did,data.docs[indx].docvendor);
}
document.getElementById("applno").focus();
}
else
{
CallMessage('5005MQRY:error:No records found',3000,200,300);
AddNewRecord();
}
}
function EditBasicDetails()
{
EnableDisableFields(false);
ManageButtons(false);
}
function SaveBasicDetails()
{
if(confirm("Are you sure to update the details?"))
{
var QStr=PrepareQStr();
QStr=QStr+"&val7=2";
if(document.getElementById("ajaxmsg") !== null)
{
CallMessage('1001AJX:warning:Another operation is being processed, please wait..',3000,200,300);
return;
}
LoadingMsg("Updating details, please wait...","ajaxmsg");
RunAjax("POST","updatebdetails",QStr,3);
EnableDisableFields(true);
ManageButtons(true);
}
}
function CancelEdit()
{
SetPrevValues();
EnableDisableFields(true);
ManageButtons(true);
}
function EnableDisableFields(isEnabled)
{
var indx=2;
if(typeof fields[0]!=='undefined')
{
var lindx=fields[0].length-1;
for(indx;indx<lindx;indx++)
{
$("#"+fields[0][indx]).prop("disabled",isEnabled);
}
}
indx=0;
/*$("#applno").prop("disabled",isEnabled);
$("#customername").prop("disabled",isEnabled);
$("#dob").prop("disabled",isEnabled);
$("#loanamount").prop("disabled",isEnabled);
$("#bank_branch_id").prop("disabled",isEnabled);
$("#product").prop("disabled",isEnabled);
$("#apptype").prop("disabled",isEnabled);
$("#category").prop("disabled",isEnabled);*/
}
function SetPrevValues()
{
$("#applno").val(records[recpos][3]);
$("#customername").val(records[recpos][6]);
$("#dob").val(records[recpos][9]);
$("#loanamount").val(records[recpos][5]);
$("#bank_branch_id").val(records[recpos][2]);
$("#product").val(records[recpos][4]);
$("#apptype").val(records[recpos][7]);
$("#category").val(records[recpos][8]);
}
function ManageButtons(bmode)
{
if(bmode)
{
if($("#applno").val().length > 0)
{
$("#btnbedit").show();
$("#btnsave").hide();
$("#section7").show();
}
else
{
$("#btnbedit").hide();
$("#btnsave").show();
$("#section7").hide();
EnableDisableFields(false);
}
$("#btnbsave").hide();
$("#btnbcancel").hide();
}
else
{
$("#btnbedit").hide();
$("#btnbsave").show();
$("#btnbcancel").show();
}
}
function changeLabel(el)
{
$("#uniqueidentifier").html($('option:selected',el).attr("uniqueidentifier"));
$("#sprovider").html($('option:selected',el).attr("sprovider"));
$("#serviceprovider").val($('option:selected',el).attr("defsprovider"));
$("#serviceprovider_hidden").val("0");
if($('option:selected',el).attr("genlist")>0)
{
$("#serviceprovider_citylist").val($('option:selected',el).attr("genlist"));
$("#serviceprovider").attr('onkeyup',"ajax_showOptions(this,event)");
validateHidden = true;
}
else
{
$("#serviceprovider_citylist").val("0");
$("#serviceprovider").removeAttr('onkeyup');
validateHidden = false;
}
$("#uniqueno").attr("onblur","validate(this,'t','"+$('option:selected',el).attr("validuno")+"')");
$("#yearmon").html($('option:selected',el).attr("ymon"));
$("#yearmonth").attr("onblur","validate(this,'f','"+$('option:selected',el).attr("validymon")+"')");
ValidateEntry('f');
GetVerifierList(el);
}
function GetVerifierList(el)
{
$("#vendor_id").empty().append('<option value="-1" selected>SELECT</option>');
if(el.value != '-1')
{
RunAjax("POST","getdocverlist","val0="+el.value,4);
}
}

View File

@@ -0,0 +1,137 @@
(function (window, document) {
"use strict";
const API = Object.freeze({ key: "payload-key", save: "application-save" });
const BOOLEAN_FIELDS = Object.freeze({
residenceVerification: "rv",
residenceTelephoneVerification: "rtv",
officeVerification: "ov",
officeTelephoneVerification: "otv",
propertyVerification: "pv",
referenceVerification: "refv",
documentVerification: "docv",
residenceCoApplicant: "rco",
residenceCoProprietor: "rcp",
officeCoProprietor: "ocp",
sameResidenceAddress: "sradd",
sameOfficeAddress: "soadd",
samePropertyAddress: "spadd",
autoCutOff: "autocut"
});
const VALUE_FIELDS = Object.freeze({
applicationId: "case_id", portfolioId: "portfolio_id", bankBranchId: "bank_branch_id",
applicationNumber: "applno", bankCode: "bankcode", product: "product",
loanAmount: "loanamount", customerName: "customername", fatherName: "fathername",
applicationType: "apptype", category: "category", dateOfBirth: "dob",
contactPerson: "contactperson", mobileNumber: "mobileno", specialInstruction: "specialinst",
residenceAddress1: "raddr1", residenceAddress2: "raddr2", residenceAddress3: "raddr3",
residenceLandmark: "rlandmark", residenceColonyId: "Rcolony", residenceCity: "rcity",
residencePincode: "rpincode", residencePhone: "rphone", companyName: "companyname",
officeAddress1: "oaddr1", officeAddress2: "oaddr2", officeAddress3: "oaddr3",
officeLandmark: "olandmark", officeColonyId: "Ocolony", officeCity: "ocity",
officePincode: "opincode", department: "department", designation: "designation",
officePhone: "ophone", extension: "extension", propertyAddress1: "paddr1",
propertyAddress2: "paddr2", propertyAddress3: "paddr3", propertyLandmark: "plandmark",
propertyColonyId: "Pcolony", propertyCity: "pcity", propertyPincode: "ppincode",
referenceName1: "refname1", referenceAddress1: "refaddress1",
referenceContactNumber1: "refcontactno1", referenceName2: "refname2",
referenceAddress2: "refaddress2", referenceContactNumber2: "refcontactno2",
formMode: "formmode"
});
const INTEGER_FIELDS = new Set(["applicationId", "portfolioId", "bankBranchId", "residenceColonyId",
"officeColonyId", "propertyColonyId", "formMode"]);
const element = (id) => document.getElementById(id);
const value = (id) => {
const field = element(id);
if (!field) return "";
window.CygnusFormValidation.sanitizeElement(field);
return field.value?.trim() ?? "";
};
const integer = (id) => {
const parsed = Number.parseInt(value(id), 10);
return Number.isFinite(parsed) ? parsed : 0;
};
const checked = (id) => Boolean(element(id)?.checked);
function collectDynamicFields() {
const names = value("dynamicfields").split(window.ColDelim || "!C0L!").filter(Boolean);
return names.reduce((result, name) => {
if (/^(?:field(?:[1-9]|1[0-2]|150(?:_2)?)|dtfield1)$/i.test(name) && element(name)) {
result[name] = value(name);
}
return result;
}, {});
}
function collectCase() {
const details = {};
Object.entries(VALUE_FIELDS).forEach(([property, id]) => {
details[property] = INTEGER_FIELDS.has(property) ? integer(id) : value(id);
});
Object.entries(BOOLEAN_FIELDS).forEach(([property, id]) => { details[property] = checked(id); });
details.dynamicFields = collectDynamicFields();
return details;
}
function validateForm() {
const verificationIds = ["rv", "rtv", "ov", "otv", "pv", "refv", "docv"];
if (!verificationIds.some(checked)) {
notify("danger", "APP-4221", "At least one verification type is required.");
return false;
}
const validation = window.CygnusInitiationValidation.validateForm();
[["rv", "Rcolony", "colr"], ["ov", "Ocolony", "colo"], ["pv", "Pcolony", "colp"]]
.forEach(([flag, hidden, visible]) => {
if (checked(flag) && integer(hidden) === 0) window.highlightField(element(visible));
});
if (!validation.valid || document.querySelector(".matrix-validation-error-icon")) {
notify("danger", "APP-4221", "Correct the highlighted fields and submit the application again.");
validation.invalid[0]?.focus();
return false;
}
return true;
}
function notify(type, code, message, referenceId) {
window.CygnusNotifications.show({ type, code, message, referenceId });
}
function applyResult(result, originalApplicationId) {
element("case_id").value = result.applicationId;
if (element("mvcode")) element("mvcode").value = result.mvCode || "";
const currentRecord = window.records?.[window.recpos];
if (currentRecord && !Array.isArray(currentRecord)) {
currentRecord.case_id = result.applicationId;
currentRecord.mvcode = result.mvCode;
}
notify("success", "APP-2001", `Application ${result.mvCode || result.applicationId} saved successfully.`);
if (originalApplicationId === 0 && typeof window.AddNewRecord === "function") window.AddNewRecord();
else if (originalApplicationId > 0 && typeof window.findRecord === "function") window.findRecord(3);
}
async function save(event) {
event?.preventDefault();
if (!validateForm()) return false;
const button = element("btnsave");
if (button?.disabled) return false;
const details = collectCase();
if (button) button.disabled = true;
try {
const envelope = await window.CygnusPayloadCrypto.encrypt(details, { keyUrl: API.key });
const response = await fetch(API.save, { method: "POST", credentials: "same-origin",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify(envelope) });
const body = await response.json().catch(() => null);
if (!response.ok || !body?.success) throw body?.message || body || {};
applyResult(body.data, details.applicationId);
} catch (error) {
notify("danger", error.code || "APP-5001",
error.message || "Cygnus could not save the application details.", error.referenceId);
} finally {
if (button) button.disabled = false;
}
return false;
}
window.CygnusInitiation = Object.freeze({ save });
}(window, document));

View File

@@ -0,0 +1,112 @@
(function () {
"use strict";
var currentRow = 0;
var lastRow = 0;
function rows() {
return Array.prototype.slice.call(document.querySelectorAll("#casetable tbody tr"));
}
function rowNumber(row) {
return Number((row.id || "").replace("row", "")) || 0;
}
function setActiveRow(row) {
if (!row) {
return;
}
rows().forEach(function (item) {
item.classList.remove("rowhover");
});
row.classList.add("rowhover");
currentRow = rowNumber(row);
lastRow = currentRow;
row.focus();
}
function hiddenValue(row, suffix) {
var input = document.getElementById(row.id + suffix);
return input ? input.value : "";
}
function submitForm(action, target, formId) {
if (typeof SubmitForm === "function") {
SubmitForm(action, target, formId);
return;
}
var form = document.getElementById(formId);
if (!form) {
return;
}
form.action = action;
form.target = target;
form.submit();
}
function openRow(row) {
if (!row) {
return;
}
var uuid = hiddenValue(row, "uuid");
var portfolioId = hiddenValue(row, "portid");
if (!uuid || !portfolioId) {
return;
}
document.getElementById("uuid").value = uuid;
document.getElementById("portlist").value = portfolioId;
submitForm("caseedit", "_parent", "caseGrid");
}
function moveSelection(direction) {
var allRows = rows();
if (allRows.length === 0) {
return;
}
var nextIndex = currentRow > 0 ? currentRow - 1 + direction : 0;
if (nextIndex < 0) {
nextIndex = allRows.length - 1;
}
if (nextIndex >= allRows.length) {
nextIndex = 0;
}
setActiveRow(allRows[nextIndex]);
}
function handleKeydown(event) {
var row = event.target && event.target.closest ? event.target.closest("#casetable tbody tr") : null;
if (event.key === "Enter" && row) {
event.preventDefault();
openRow(row);
return;
}
if (event.key === "ArrowDown") {
event.preventDefault();
moveSelection(1);
return;
}
if (event.key === "ArrowUp") {
event.preventDefault();
moveSelection(-1);
}
}
function init() {
rows().forEach(function (row) {
row.addEventListener("mouseenter", function () {
setActiveRow(row);
});
row.addEventListener("click", function () {
openRow(row);
});
});
document.addEventListener("keydown", handleKeydown, false);
}
window.CygnusEditCases = {
init: init,
openRow: openRow
};
window.InitPage = init;
}());

View File

@@ -0,0 +1,94 @@
(function (window, document) {
"use strict";
const element = (id) => document.getElementById(id);
const checked = (id) => Boolean(element(id)?.checked);
const requiredWhen = (id) => () => checked(id);
const sectionRule = (id, rule = {}) => Object.assign({ when: requiredWhen(id) }, rule);
const RULES = {
applno: { required: true, format: "AlphaNumeric", requiredMessage: "Application number is required." },
bank_branch_id: { required: true, requiredMessage: "Bank branch is required." },
product: { required: true, requiredMessage: "Product is required." },
customername: { required: true, format: "AlphaSpace", requiredMessage: "Customer name is required." },
apptype: { required: true, requiredMessage: "Application type is required." },
bankcode: { format: "AlphaNumeric" }, fathername: { format: "AlphaSpace" }, dob: { format: "Date" },
mobileno: { format: "AllowWrong" }, loanamount: { format: "LoanAmount" },
contactperson: { format: "AlphaSpace" }, specialinst: { format: "SplInstruction" },
raddr1: sectionRule("rv", { required: true, format: "SplInstruction" }), raddr2: sectionRule("rv", { format: "SplInstruction" }),
raddr3: sectionRule("rv", { required: true, format: "SplInstruction" }), rlandmark: sectionRule("rv", { format: "SplInstruction" }),
rcity: sectionRule("rv", { required: true }), colr: sectionRule("rv", { required: true, format: "SplInstruction" }),
rpincode: sectionRule("rv", { format: "Pincode" }), rphone: sectionRule("rtv", { required: true, format: "Phone" }),
companyname: sectionRule("ov", { format: "SplInstruction" }), oaddr1: sectionRule("ov", { required: true, format: "SplInstruction" }),
oaddr2: sectionRule("ov", { format: "SplInstruction" }), oaddr3: sectionRule("ov", { required: true, format: "SplInstruction" }),
olandmark: sectionRule("ov", { format: "SplInstruction" }), ocity: sectionRule("ov", { required: true }),
colo: sectionRule("ov", { required: true, format: "SplInstruction" }), opincode: sectionRule("ov", { format: "Pincode" }),
department: sectionRule("ov", { format: "SplInstruction" }), designation: sectionRule("ov", { format: "SplInstruction" }),
ophone: sectionRule("otv", { required: true, format: "Phone" }), extension: sectionRule("otv", { format: "Extension" }),
paddr1: sectionRule("pv", { required: true, format: "SplInstruction" }), paddr2: sectionRule("pv", { format: "SplInstruction" }),
paddr3: sectionRule("pv", { required: true, format: "SplInstruction" }), plandmark: sectionRule("pv", { format: "SplInstruction" }),
pcity: sectionRule("pv", { required: true }), colp: sectionRule("pv", { required: true, format: "SplInstruction" }),
ppincode: sectionRule("pv", { format: "Pincode" }), refname1: sectionRule("refv", { required: true, format: "AlphaSpace" }),
refaddress1: sectionRule("refv", { format: "SplInstruction" }),
refcontactno1: sectionRule("refv", { required: true, format: "Phone" }),
refname2: sectionRule("refv", { format: "AlphaSpace" }), refaddress2: sectionRule("refv", { format: "SplInstruction" }),
refcontactno2: sectionRule("refv", { format: "Phone" })
};
const VERIFICATION_GROUPS = Object.freeze({
rv: ["raddr1", "raddr2", "raddr3", "rlandmark", "rcity", "colr", "rpincode"],
rtv: ["rphone"],
ov: ["companyname", "oaddr1", "oaddr2", "oaddr3", "olandmark", "ocity", "colo",
"opincode", "department", "designation"],
otv: ["ophone"],
pv: ["paddr1", "paddr2", "paddr3", "plandmark", "pcity", "colp", "ppincode"],
refv: ["refname1", "refaddress1", "refcontactno1"]
});
function registerDynamicRules(form) {
if (!form) return;
form.querySelectorAll("#FormPanel6 [data-validation-required]").forEach(function (field) {
const label = field.closest(".widget")?.querySelector(".lblcontainer")?.textContent.trim();
RULES[field.id] = {
required: field.dataset.validationRequired === "true",
format: field.dataset.validationFormat || "",
requiredMessage: (label || "This dynamic field") + " is required."
};
});
}
function validateField(field) {
const target = typeof field === "string" ? element(field) : field;
const rule = target && RULES[target.id];
return !target || !rule || window.CygnusFormValidation.validateElement(target, rule);
}
function validateForm() {
return window.CygnusFormValidation.validateRules(RULES);
}
function validateVerification(verificationId) {
const invalid = [];
(VERIFICATION_GROUPS[verificationId] || []).forEach(function (fieldId) {
const field = element(fieldId);
if (!validateField(field)) invalid.push(field);
});
return { valid: invalid.length === 0, invalid: invalid };
}
function bind(form) {
if (!form || form.dataset.initiationValidationBound === "true") return;
registerDynamicRules(form);
form.dataset.initiationValidationBound = "true";
form.addEventListener("focusout", function (event) {
window.CygnusFormValidation.sanitizeElement(event.target);
validateField(event.target);
});
}
window.CygnusInitiationValidation = Object.freeze({
rules: RULES,
bind: bind,
validateField: validateField,
validateVerification: validateVerification,
validateForm: validateForm
});
}(window, document));

View File

@@ -0,0 +1,502 @@
/*
* Case Initiation page behaviour.
*
* This file owns record loading/navigation, verification-section state,
* address copying and duplicate-address lookup. The encrypted JSON save
* workflow is intentionally isolated in application-save.js.
*/
var records=[];
var recIndx = 0;
var recpos = 0;
var SameAddr=[];
var AddrElem=[
["rv","raddr1","raddr2","raddr3","rlandmark","Rcolony","colr","rcity","rpincode","rphone"],
["ov","companyname","oaddr1","oaddr2","oaddr3","olandmark","Ocolony","colo","ocity","opincode","ophone","extension"],
["pv","paddr1","paddr2","paddr3","plandmark","Pcolony","colp","pcity","ppincode"],
["bankcode","bankcode","bank_branch_id","product","loanamount","apptype","contactperson","specialinst"]
];
var selectedAddr=-1;
var FocusAfter="customername";
var CHECKBOX_FIELDS=new Set(["rv","sradd","rtv","ov","soadd","otv","rco","pv","rcp","ocp","spadd","refv","docv"]);
var DUPLICATE_OPERATION={R:19,O:20,P:21,A:22};
var PUNCHED_RECORDS_URL="punchedrecs";
var DUPLICATE_DETAILS_URL="findsdet";
var DUPLICATE_FIELDS={
19:["raddr1","raddr2","raddr3","rlandmark","rcolony","colr","rcity","rpincode","rphone"],
20:["companyname","oaddr1","oaddr2","oaddr3","olandmark","ocolony","colo","ocity","opincode","ophone","extension"],
21:["paddr1","paddr2","paddr3","plandmark","pcolony","colp","pcity","ppincode"],
22:["bankcode","bank_branch_id","product","loanamount","apptype","contactperson","specialinst"]
};
function InitPage()
{
var portField = document.getElementById("portfolio_id");
var initialPortField = document.getElementById("initial-portfolio-id");
var visibleContentsField = document.getElementById("visiblecontents");
var port = initialPortField ? initialPortField.value : (portField ? portField.value : "-1");
var viscontents = visibleContentsField ? visibleContentsField.value : "";
if (viscontents && viscontents.slice(-ColDelim.length) !== ColDelim) {
viscontents += ColDelim;
}
centerDivBoth("formcontainer","H");
HideSections('rtv');
HideSections('otv');
HideSections('section');
UnhideSections(viscontents,ColDelim);
if (portField) {
$(portField).val(port);
}
if(port>0)
{
if(document.getElementById("ajaxmsg") !== null)
{
CygnusNotifications.show({type:"warning",code:"1001AJX",message:"Another operation is being processed, please wait.",duration:3000});
return;
}
LoadingMsg("Fetching records, please wait...","ajaxmsg");
loadPunchedRecords(port,$("#uuid").val());
}
}
function GotoRecord(el,searchtype)
{
var recno=el.value;
if(recno!='')
{
if(searchtype == 'recno')
{
if(recno > recIndx || recno <=0)
{
CygnusNotifications.show({type:"danger",code:"1001IRNG",message:"Invalid input. Out of range",duration:3000});
}
else
{
recpos=recno-1;
FillDetails(recpos);
}
}
else
{
for(var index = 0; index < records.length; index++ )
{
if( records[index].applno === recno ) {
recpos = index;
FillDetails(recpos);
break;
}
}
}
}
}
function AddNewRecord()
{
if(recIndx==0 || String(records[recIndx-1].case_id)!='0')
{
recIndx = recIndx+1;
recpos = recIndx-1;
records[recpos]={case_id:'0',portfolio_id:$("#portfolio_id").val(),status:'0',
company_id:$("#company_id").val(),branch_id:$("#branch_id").val(),uuid:'',mvcode:'******'};
}
else
{
recpos=recIndx-1;
}
FillDetails(recpos);
}
async function loadPunchedRecords(portfolioId,documentCaseId)
{
try
{
var query=new URLSearchParams({portfolioId:portfolioId,documentCaseId:documentCaseId || ""});
var response=await fetch(PUNCHED_RECORDS_URL+"?"+query.toString(),{
method:"GET",credentials:"same-origin",headers:{Accept:"application/json"}
});
var body=await response.json().catch(function(){return null;});
if(!response.ok || !body || !body.success) throw body && body.message ? body.message : {};
records=Array.isArray(body.data && body.data.records) ? body.data.records : [];
recIndx=records.length;
updateRecordCounter(0,recIndx);
recpos=recIndx==0 ? 0 : recIndx-1;
FillDetails(recpos);
}
catch(error)
{
CygnusNotifications.show({type:"danger",code:error.code || "APP-5002",
message:error.message || "Cygnus could not load punched records.",referenceId:error.referenceId});
records=[];recIndx=0;recpos=0;FillDetails(0);
}
finally{$("#ajaxmsg").remove();}
}
function handleDuplicateDetailsResponse(records,oprID)
{
if($("#portfolio_id").val()==81)
{
for(var index=0;index<records.length;index++) incrementDuplicateApplicationNumber();
}
else SameAddr=records.map(function(record){
return DUPLICATE_FIELDS[oprID].map(function(field){return record[field] == null ? "" : record[field];});
});
SelectAddr(oprID-19);
}
async function loadDuplicateDetails(applicationNumber,portfolioId,queryId)
{
try
{
var query=new URLSearchParams({applicationNumber:applicationNumber,portfolioId:portfolioId,queryId:queryId});
var response=await fetch(DUPLICATE_DETAILS_URL+"?"+query.toString(),{
method:"GET",credentials:"same-origin",headers:{Accept:"application/json"}
});
var body=await response.json().catch(function(){return null;});
if(!response.ok || !body || !body.success) throw body && body.message ? body.message : {};
handleDuplicateDetailsResponse(Array.isArray(body.data && body.data.records) ? body.data.records : [],queryId);
}
catch(error)
{
CygnusNotifications.show({type:"danger",code:error.code || "APP-5002",
message:error.message || "Cygnus could not search existing application details.",referenceId:error.referenceId});
SameAddr=[];
SelectAddr(queryId-19);
}
}
function incrementDuplicateApplicationNumber()
{
var appl=$("#applno").val();
CygnusNotifications.show({type:"warning",code:"APP-DUPLICATE",message:"Application number "+appl+" already exists.",duration:3000});
appl=appl.search('_1')<0 ? appl+'_1' : appl.split('_')[0]+'_'+(parseInt(appl.split('_')[1])+1);
$("#applno").val(appl);
CygnusInitiationValidation.validateField(document.getElementById('applno'));
document.getElementById('applno').focus();
}
function findRecord(arrOpr)
{
var tempPos= recpos;
var maxLen= recIndx-1;
if(arrOpr==1) tempPos=0;
if(arrOpr==2)
{
if(tempPos>0) tempPos=tempPos-1;
else return false;
}
if(arrOpr==3)
{
if(tempPos<maxLen) tempPos=tempPos+1;
else return false;
}
if(arrOpr==4) tempPos=maxLen;
recpos= tempPos;
FillDetails(recpos);
}
function FillDetails(indx)
{
if(recIndx > 0)
{
document.forms['casedetails'].reset();
updateRecordCounter(indx+1,recIndx);
Object.keys(records[indx]).forEach(function(fieldName){fillRecordField(fieldName,records[indx][fieldName]);});
$("#btnsave").toggle($("#status").val()!='1');
FireClickEvents();
document.getElementById("applno").focus();
}
else
{
CygnusNotifications.show({type:"danger",code:"5005MQRY",message:"No records found",duration:3000});
AddNewRecord();
}
}
function fillRecordField(fieldName,fieldValue)
{
var field=document.getElementById(fieldName) || dynamicFieldElement(fieldName);
if(!field) return;
if(CHECKBOX_FIELDS.has(fieldName))
{
field.checked=fieldName=='docv' ? $(field).is(":visible") : fieldValue=='1';
return;
}
field.value=fieldValue;
}
function dynamicFieldElement(fieldName)
{
var dynamicFields=document.querySelectorAll("#FormPanel6 [id]");
for(var index=0;index<dynamicFields.length;index++)
if(dynamicFields[index].id.toLowerCase()==fieldName.toLowerCase()) return dynamicFields[index];
return null;
}
function updateRecordCounter(current,total)
{
$("#recfound").html("<b>( "+current+" / "+total+" )</b>");
}
function FireClickEvents()
{
["rv","ov","rtv","otv","pv","refv"].forEach(function(id){HandleClick(document.getElementById(id));});
}
function FireToggleEvents()
{
ToggleChks(document.getElementById('rv').checked && document.getElementById('ov').checked,["rco"]);
var applicationType=document.getElementById('apptype').value.toUpperCase();
ToggleChks(applicationType!='APPLICANT' && applicationType!='-1',["sradd","soadd","spadd"]);
ToggleChks(document.getElementById('rv').checked,["rcp"]);
ToggleChks(document.getElementById('ov').checked,["ocp"]);
}
function HandleClick(el)
{
var handler=VERIFICATION_HANDLERS[el.id];
if(handler) handler(el);
}
var VERIFICATION_HANDLERS={
rv:function(el){
setFormValidation(el,'FormPanel2',document.getElementById('rtv').checked);
EnableDisableFields(el.checked,'raddr1,raddr2,raddr3,rlandmark,colr,rpincode',',');
},
rtv:function(el){setFormValidation(el,'FormPanel2',document.getElementById('rv').checked);},
ov:function(el){
setFormValidation(el,'FormPanel3',document.getElementById('otv').checked);
EnableDisableFields(el.checked,'oaddr1,oaddr2,oaddr3,olandmark,colo,opincode',',');
},
otv:function(el){setFormValidation(el,'FormPanel3',document.getElementById('ov').checked);},
pv:function(el){
setFormValidation(el,'FormPanel4',false);
EnableDisableFields(el.checked,'paddr1,paddr2,paddr3,plandmark,colp,ppincode',',');
if(!el.checked){document.getElementById('rcp').checked=false;document.getElementById('ocp').checked=false;}
},
refv:function(el){setFormValidation(el,'FormPanel5',false);},
rco:function(el){AutoFill('rco',el.checked ? 1 : 0);},
rcp:function(el){handlePropertyCopy(el,'rcp','ocp');},
ocp:function(el){handlePropertyCopy(el,'ocp','rcp');}
};
function handlePropertyCopy(el,copyType,otherCheckboxId)
{
AutoFill(copyType,el.checked ? 1 : 0);
if(!el.checked) return;
document.getElementById(otherCheckboxId).checked=false;
var property=document.getElementById('pv');
property.checked=true;
HandleClick(property);
}
function setFormValidation(Elem,FormPanel,CounterPartElem)
{
if(Elem.checked || CounterPartElem)
{
UnhideSections(FormPanel+ColDelim, ColDelim);
}
else
{
HideSections(FormPanel);
}
CygnusInitiationValidation.validateVerification(Elem.id);
FireToggleEvents();
}
function AutoFill(Opt,FillMode)
{
var mapping=ADDRESS_COPY_MAPPINGS[Opt];
if(!mapping) return;
if(FillMode==1) CopyDetails(mapping.source,mapping.target);
else if(document.getElementById(mapping.sourceColony).value==document.getElementById(mapping.targetColony).value)
ClearDetails(mapping.target);
}
var ADDRESS_COPY_MAPPINGS={
rco:{
source:["raddr1","raddr2","raddr3","Rcolony","colr","rcity","rlandmark","rpincode","rphone"],
target:["oaddr1","oaddr2","oaddr3","Ocolony","colo","ocity","olandmark","opincode","ophone"],
sourceColony:"Rcolony",targetColony:"Ocolony"
},
rcp:{
source:["raddr1","raddr2","raddr3","Rcolony","colr","rcity","rlandmark","rpincode"],
target:["paddr1","paddr2","paddr3","Pcolony","colp","pcity","plandmark","ppincode"],
sourceColony:"Rcolony",targetColony:"Pcolony"
},
ocp:{
source:["oaddr1","oaddr2","oaddr3","Ocolony","colo","ocity","olandmark","opincode"],
target:["paddr1","paddr2","paddr3","Pcolony","colp","pcity","plandmark","ppincode"],
sourceColony:"Ocolony",targetColony:"Pcolony"
}
};
function ToggleChks(IsVisible,ChildElems)
{
if(IsVisible)
{
ChildElems.forEach(function(id){UnhideSections(id+ColDelim,ColDelim);});
}
else
{
ChildElems.forEach(function(id){HideSections(id);document.getElementById(id).checked=false;});
}
}
function ClearDetails(TargetFields)
{
TargetFields.forEach(function(id){document.getElementById(id).value="";});
}
function CopyDetails(SourceFields,TargetFields)
{
SourceFields.forEach(function(id,index){document.getElementById(TargetFields[index]).value=document.getElementById(id).value;});
}
function AfterOptSelect(ElemToRemove,OprID)
{
FillSameDet(selectedAddr, OprID);
selectedAddr=-1;
ElemToRemove.parentNode.removeChild(ElemToRemove);
}
function ShowAddrOptions(OprID)
{
var optDiv=document.createElement("div");
var Addr="";
optDiv.setAttribute("id","optDiv");
optDiv.setAttribute("class","FormPanel");
optDiv.setAttribute("style","font-family:Tahoma;overflow:visible");
var OptionPanel="<div id='TablePanel' class='tableContainer'><table border='0' cellspacing='0' width='100%' id='cutlist'><thead class='thead'><tr title='Row Title'><td colspan='2'>Available Addresses</td></tr></thead><tbody class='scrollContent'>";
for(var indx=0;indx<SameAddr.length;indx++)
{
OptionPanel=OptionPanel+"<tr><td><input type='radio' name='rb1' id='rb"+indx+"' value='"+indx+"' onclick='selectedAddr=this.value;' /></td>";
OptionPanel=OptionPanel+"<td style='padding-right:5px'>";
for(var cindx=0;cindx<4;cindx++)
{
Addr=Addr+" "+escapeHtml(SameAddr[indx][cindx]);
}
OptionPanel=OptionPanel+""+Addr+"</td></tr>";
Addr="";
}
OptionPanel=OptionPanel+"<tr><td colspan='2'><input type='button' class='button' name='btnok' style='margin-top:5px;float:right' value='OK' id='btnok' accesskey='K' onclick=\"AfterOptSelect(document.getElementById('inptDialog'),"+OprID+");\"";
OptionPanel=OptionPanel+"</tbody></table></div>";
optDiv.innerHTML=OptionPanel;
ShowInputDialog(optDiv,"Select Address","hint","inptDialog");
document.getElementById('rb0').focus();
}
function escapeHtml(value)
{
return String(value == null ? "" : value).replace(/[&<>"']/g, function(character) {
return ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[character];
});
}
function FillSameDet(AddrIndex,OprID)
{
if(!(AddrIndex < 0))
{
for(var cindx=0;cindx<SameAddr[AddrIndex].length;cindx++)
{
$("#"+AddrElem[OprID][cindx+1]).val((SameAddr[AddrIndex][cindx]));
}
document.getElementById(FocusAfter).focus();
var applicationType=document.getElementById('apptype').value.toUpperCase();
ToggleChks(applicationType!='APPLICANT' && applicationType!='-1',["sradd","soadd","spadd"]);
}
else
{
document.getElementById(AddrElem[OprID][0]).focus();
if(document.getElementById(AddrElem[OprID][0]).type=='checkbox'){document.getElementById(AddrElem[OprID][0]).checked=false;}
}
}
function SelectAddr(OprID)
{
if(SameAddr.length>1)
{
ShowAddrOptions(OprID);
}
else if(SameAddr.length===1)
{
FillSameDet(0,OprID);
}
else
{
FillSameDet(-1,OprID);
}
}
function FindSameDet(Elm,Visit,focAfter)
{
if($("#case_id").val()!='0' && Visit=='A')
{
return;
}
else
{
FocusAfter=focAfter;
var procFlag=true;
if(Elm.type=='checkbox')
{
procFlag=Elm.checked;
}
if(procFlag)
{
var Applno=document.getElementById('applno').value;
if(Applno.length==0)
{
if(Elm.type=='checkbox'){Elm.checked=false;}
CygnusNotifications.show({type:"danger",code:"VLFRM",message:"Please enter application number.",duration:3000});
document.getElementById('applno').focus();
return false;
}
else
{
SameAddr=[];
var oprId=DUPLICATE_OPERATION[Visit];
loadDuplicateDetails(Applno,$("#portfolio_id").val(),oprId);
}
}
}
}
function FindStr(el,elmids)
{
el.value=el.value.split('->')[0];
var skey=el.value.trim().toUpperCase();
if(skey!='UNKNOWN' && skey!='-1')
{
for(var indx=0;indx<elmids.length;indx++)
{
if(document.getElementById(elmids[indx]).value.toUpperCase().search(skey)>-1)
{
return true;
}
}
}
else
{
return true;
}
return false;
}
var ADDRESS_SECTIONS={
r:{verification:"rv",city:"rcity",colony:"colr",colonyId:"Rcolony",addressFields:["raddr2","raddr3"]},
o:{verification:"ov",city:"ocity",colony:"colo",colonyId:"Ocolony",addressFields:["oaddr2","oaddr3"]},
p:{verification:"pv",city:"pcity",colony:"colp",colonyId:"Pcolony",addressFields:["paddr2","paddr3"]}
};
function addressSectionFor(fieldId)
{
var keys=Object.keys(ADDRESS_SECTIONS);
for(var index=0;index<keys.length;index++)
{
var section=ADDRESS_SECTIONS[keys[index]];
if(fieldId==section.city || fieldId==section.colony) return section;
}
return null;
}
function HandleBlur(el)
{
var section=addressSectionFor(el.id);
if(!section) return;
if(el.id==section.city)
{
if(!FindStr(el,section.addressFields))
{
CygnusNotifications.show({type:"danger",code:"1001AREA",message:"Invalid area.",duration:3000});
el.value="-1";
document.getElementById(section.colonyId).value="";
document.getElementById(section.colony).value="";
}
CygnusInitiationValidation.validateField(el);
}
if(el.id==section.colony)
{
if(!FindStr(el,section.addressFields))
{
CygnusNotifications.show({type:"danger",code:"1001AREA",message:"Invalid colony.",duration:3000});
el.value="";
}
var colonyId=document.getElementById(section.colonyId);
if(el.value=='') colonyId.value='';
if(colonyId.value=='') el.value='';
CygnusInitiationValidation.validateField(el);
}
}

View File

@@ -0,0 +1,150 @@
(function (window, document) {
"use strict";
const FORMATS = Object.freeze({
Email: /^\S*\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,8}\b\S*$/,
Numeric: /^\d*$/,
AlphaNumeric: /^[a-zA-Z0-9_*\/\-]*$/,
AlphaSpace: /^[a-zA-Z0-9()\/ &]*$/,
LoanAmount: /^[a-zA-Z0-9. ]*$/,
SplInstruction: /^[a-zA-Z0-9():,#@.\-\/ ]*$/,
Remarks: /^[a-zA-Z0-9,(),:+&#@'.\-\/ ]*$/,
Pincode: /^\d{6}$/,
Phone: /^((\d{6,8}|\d{10}|\d{3}-\d{6,8})([\/](\d{6,8}|\d{10}|\d{3}-\d{6,8})){0,2})$/,
Extension: /^\d{3,4}$/
});
const DATE_PATTERN = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
function sanitize(value, options) {
const multiline = Boolean(options && options.multiline);
let sanitized = String(value == null ? "" : value).replace(/\t/g, "");
if (multiline) {
sanitized = sanitized.replace(/\r\n?/g, "\n").replace(/[^\x20-\x7E\n]/g, "");
} else {
sanitized = sanitized.replace(/[\r\n]/g, "").replace(/[^\x20-\x7E]/g, "");
}
return sanitized.trim();
}
function sanitizeElement(element) {
if (!element || typeof element.value !== "string") return "";
const tagName = element.tagName ? element.tagName.toLowerCase() : "";
const inputType = (element.type || "text").toLowerCase();
const sanitizableInput = tagName === "input" &&
["text", "search", "tel", "email", "url", "password"].includes(inputType);
if (tagName !== "textarea" && !sanitizableInput) return element.value;
const sanitized = sanitize(element.value, { multiline: tagName === "textarea" });
if (element.value !== sanitized) element.value = sanitized;
return sanitized;
}
function valueOf(element) {
return element && typeof element.value === "string" ? element.value.trim() : "";
}
function isEmpty(element) {
const value = valueOf(element);
return value === "" || (element.type === "select-one" && value === "-1");
}
function isDate(value) {
const parts = DATE_PATTERN.exec(value);
if (!parts) return false;
const day = Number(parts[1]);
const month = Number(parts[2]);
const year = Number(parts[3]);
if (year < 1900 || year > 2100 || month < 1 || month > 12) return false;
const date = new Date(year, month - 1, day);
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
}
function matchesFormat(value, format) {
if (!value || !format || format === "AllowWrong") return true;
const normalized = Object.keys(FORMATS).find((name) => name.toLowerCase() === format.toLowerCase());
if (format.toLowerCase() === "date") return isDate(value);
return normalized ? FORMATS[normalized].test(value) : true;
}
function errorHost(element) {
let current = element.parentNode;
let host = current;
while (current && current !== document.body) {
if ((" " + (current.className || "") + " ").indexOf(" inputcontainer ") !== -1) return current;
current = current.parentNode;
}
return host;
}
function clearError(element) {
if (!element) return;
const icon = document.getElementById("err" + element.id);
if (icon && icon.parentNode) icon.parentNode.removeChild(icon);
element.classList.remove("errtxt");
if (element.parentNode) element.parentNode.classList.remove("errdiv");
element.removeAttribute("aria-invalid");
element.removeAttribute("aria-describedby");
if (typeof element.setCustomValidity === "function") element.setCustomValidity("");
}
function showError(element, message) {
if (!element) return;
clearError(element);
const host = errorHost(element);
const icon = document.createElement("img");
icon.src = "/matrix/images/exclamation.png";
icon.id = "err" + element.id;
icon.alt = message;
icon.title = message;
icon.className = "matrix-validation-error-icon" +
(element.type === "select-one" ? " matrix-validation-error-icon--select" : "");
icon.style.cssText = "position:absolute;right:" + (element.type === "select-one" ? "24px" : "5px") +
";top:50%;width:14px;height:14px;transform:translateY(-50%);z-index:3;pointer-events:none";
host.style.position = "relative";
host.appendChild(icon);
if (element.type === "select-one") element.parentNode.classList.add("errdiv");
else element.classList.add("errtxt");
element.setAttribute("aria-invalid", "true");
element.setAttribute("aria-describedby", icon.id);
if (typeof element.setCustomValidity === "function") element.setCustomValidity(message);
}
function validateElement(element, rule) {
if (!element) return true;
sanitizeElement(element);
if (typeof rule.when === "function" && !rule.when()) {
clearError(element);
return true;
}
const required = typeof rule.required === "function" ? rule.required() : Boolean(rule.required);
let message = "";
if (required && isEmpty(element)) message = rule.requiredMessage || "This field is required.";
else if (!isEmpty(element) && !matchesFormat(valueOf(element), rule.format)) {
message = rule.formatMessage || "Enter a valid value.";
}
if (message) showError(element, message);
else clearError(element);
return message === "";
}
function validateLegacy(element, requiredFlag, format) {
return validateElement(element, { required: requiredFlag === "t", format: format });
}
function validateRules(rules) {
const invalid = [];
Object.keys(rules).forEach(function (id) {
const element = document.getElementById(id);
if (!validateElement(element, rules[id])) invalid.push(element);
});
return { valid: invalid.length === 0, invalid: invalid };
}
window.CygnusFormValidation = Object.freeze({
clearError: clearError,
sanitize: sanitize,
sanitizeElement: sanitizeElement,
validateElement: validateElement,
validateLegacy: validateLegacy,
validateRules: validateRules
});
}(window, document));

View File

@@ -0,0 +1,95 @@
(function (window, document) {
"use strict";
const DEFAULT_DURATION = 7000;
const VALID_TYPES = new Set(["success", "info", "warning", "danger"]);
function getHost() {
let host = document.getElementById("cygnus-notifications");
if (!host) {
host = document.createElement("div");
host.id = "cygnus-notifications";
host.className = "position-fixed top-0 start-50 translate-middle-x p-3";
host.style.cssText = "z-index:1085;max-width:720px;width:calc(100% - 2rem)";
host.setAttribute("aria-live", "polite");
host.setAttribute("aria-atomic", "true");
document.body.append(host);
}
return host;
}
function dismiss(alert) {
const bootstrapAlert = window.bootstrap?.Alert;
if (bootstrapAlert) {
bootstrapAlert.getOrCreateInstance(alert).close();
} else {
alert.remove();
}
}
function show(options) {
const settings = options || {};
const type = VALID_TYPES.has(settings.type) ? settings.type : "info";
const host = getHost();
const alert = document.createElement("div");
alert.className = `alert alert-${type} alert-dismissible fade show shadow-sm`;
alert.setAttribute("role", type === "danger" ? "alert" : "status");
if (settings.code) {
const code = document.createElement("strong");
code.textContent = `${settings.code}: `;
alert.append(code);
}
alert.append(document.createTextNode(settings.message || ""));
if (settings.referenceId) {
const reference = document.createElement("small");
reference.className = "d-block mt-1";
reference.textContent = `Reference: ${settings.referenceId}`;
alert.append(reference);
}
if (settings.dismissible !== false) {
const close = document.createElement("button");
close.type = "button";
close.className = "btn-close";
close.setAttribute("aria-label", "Close");
close.addEventListener("click", () => dismiss(alert));
alert.append(close);
}
if (settings.stack === true) host.append(alert);
else host.replaceChildren(alert);
const duration = settings.duration === undefined ? DEFAULT_DURATION : settings.duration;
if (Number.isFinite(duration) && duration > 0) {
window.setTimeout(() => {
if (alert.isConnected) dismiss(alert);
}, duration);
}
return alert;
}
function clear() {
document.getElementById("cygnus-notifications")?.replaceChildren();
}
function showLegacy(serialized, options) {
const text = String(serialized || "");
const firstSeparator = text.indexOf(":");
const secondSeparator = firstSeparator < 0 ? -1 : text.indexOf(":", firstSeparator + 1);
const settings = Object.assign({}, options);
if (secondSeparator > firstSeparator) {
settings.code = text.slice(0, firstSeparator);
const legacyType = text.slice(firstSeparator + 1, secondSeparator).toLowerCase();
settings.type = legacyType === "error" ? "danger" : legacyType;
settings.message = text.slice(secondSeparator + 1);
} else {
settings.type = settings.type || "danger";
settings.message = text;
}
return show(settings);
}
window.CygnusNotifications = Object.freeze({ show, showLegacy, clear });
}(window, document));

View File

@@ -0,0 +1,91 @@
(function (window) {
"use strict";
const keyRequests = new Map();
const encoder = new TextEncoder();
function toBase64Url(bytes) {
let binary = "";
const view = new Uint8Array(bytes);
for (let offset = 0; offset < view.length; offset += 0x8000) {
binary += String.fromCharCode(...view.subarray(offset, offset + 0x8000));
}
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
function fromBase64Url(text) {
const normalized = text.replace(/-/g, "+").replace(/_/g, "/");
const binary = atob(normalized + "=".repeat((4 - normalized.length % 4) % 4));
return Uint8Array.from(binary, (character) => character.charCodeAt(0));
}
function fetchKey(keyUrl) {
if (!keyUrl) {
return Promise.reject(new Error("A payload encryption key URL is required."));
}
if (!keyRequests.has(keyUrl)) {
const request = fetch(keyUrl, {
credentials: "same-origin",
headers: { Accept: "application/json" }
}).then(async (response) => {
const body = await response.json();
if (!response.ok) throw body;
if (!body.keyId || !body.publicKey) {
throw new Error("The payload encryption key response is invalid.");
}
return body;
}).catch((error) => {
keyRequests.delete(keyUrl);
throw error;
});
keyRequests.set(keyUrl, request);
}
return keyRequests.get(keyUrl);
}
async function encrypt(payload, options) {
if (!window.crypto?.subtle) {
throw new Error("Secure payload encryption is not supported by this browser.");
}
const keyInfo = await fetchKey(options?.keyUrl);
const publicKey = await window.crypto.subtle.importKey(
"spki",
fromBase64Url(keyInfo.publicKey),
{ name: "RSA-OAEP", hash: "SHA-256" },
false,
["encrypt"]
);
const aesKey = await window.crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 }, true, ["encrypt"]
);
const initializationVector = window.crypto.getRandomValues(new Uint8Array(12));
const requestId = window.crypto.randomUUID();
const timestamp = new Date().toISOString();
const additionalData = encoder.encode(`${keyInfo.keyId}|${requestId}|${timestamp}`);
const encryptedPayload = await window.crypto.subtle.encrypt(
{ name: "AES-GCM", iv: initializationVector, additionalData },
aesKey,
encoder.encode(JSON.stringify(payload))
);
const rawKey = await window.crypto.subtle.exportKey("raw", aesKey);
const encryptedKey = await window.crypto.subtle.encrypt(
{ name: "RSA-OAEP" }, publicKey, rawKey
);
return Object.freeze({
keyId: keyInfo.keyId,
encryptedKey: toBase64Url(encryptedKey),
initializationVector: toBase64Url(initializationVector),
encryptedPayload: toBase64Url(encryptedPayload),
requestId,
timestamp
});
}
function clearKeyCache(keyUrl) {
if (keyUrl) keyRequests.delete(keyUrl);
else keyRequests.clear();
}
window.CygnusPayloadCrypto = Object.freeze({ encrypt, clearKeyCache });
}(window));

View File

@@ -5,7 +5,7 @@ import com.cygnus.client.CloudIdentityClient;
import java.time.Duration; import java.time.Duration;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import matrix.nimble.model.Session; import lib.models.UserSession;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClientResponseException; import org.springframework.web.reactive.function.client.WebClientResponseException;
@@ -28,7 +28,7 @@ public class CloudAuthenticationGateway {
this.sessionMapper = sessionMapper; this.sessionMapper = sessionMapper;
} }
public Session authenticate(String loginId, String password) { public UserSession authenticate(String loginId, String password) {
try { try {
Duration blockingTimeout = properties.requestTimeout().plusSeconds(1); Duration blockingTimeout = properties.requestTimeout().plusSeconds(1);
return sessionMapper.map(client.authenticate(loginId, password).block(blockingTimeout)); return sessionMapper.map(client.authenticate(loginId, password).block(blockingTimeout));

View File

@@ -5,6 +5,7 @@ import com.cygnus.client.model.CloudMenuItem;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import lib.models.UserSession;
import matrix.nimble.model.Session; import matrix.nimble.model.Session;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -20,22 +21,42 @@ public class CloudSessionMapper {
this.menuRenderer = menuRenderer; this.menuRenderer = menuRenderer;
} }
public Session map(CloudIdentitySession source) { public UserSession map(CloudIdentitySession source) {
return UserSession.builder()
.userId(source.userId())
.username(source.loginId())
.userDisplayName(source.displayName())
.userGroupId(source.groupId())
.userGroupName(source.groupName())
.branchId(source.branchId())
.branchName(source.branchName())
.branchCode(source.branchCode())
.branchLocation(source.branchLocation())
.companyId(source.companyId())
.companyName(source.companyName())
.companyCode(source.companyCode())
.loginTime(LEGACY_LOGIN_TIME.format(source.loginTime()))
.menuHtml(menuRenderer.render(toLegacyMenu(source.menu())))
.build();
}
/** Temporary projection used by controllers that have not migrated to UserSession yet. */
public Session toLegacy(UserSession source) {
Session target = new Session(); Session target = new Session();
target.setUserID(Short.toString(source.userId())); target.setUserID(Short.toString(source.getUserId()));
target.setUsername(source.loginId()); target.setUsername(source.getUsername());
target.setUserDisplayName(source.displayName()); target.setUserDisplayName(source.getUserDisplayName());
target.setUserGroupID(Short.toString(source.groupId())); target.setUserGroupID(Short.toString(source.getUserGroupId()));
target.setUserGroupName(source.groupName()); target.setUserGroupName(source.getUserGroupName());
target.setBranchID(Short.toString(source.branchId())); target.setBranchID(Short.toString(source.getBranchId()));
target.setBranchName(source.branchName()); target.setBranchName(source.getBranchName());
target.setBranchCode(source.branchCode()); target.setBranchCode(source.getBranchCode());
target.setBranchLocation(source.branchLocation()); target.setBranchLocation(source.getBranchLocation());
target.setCompanyID(Short.toString(source.companyId())); target.setCompanyID(Short.toString(source.getCompanyId()));
target.setCompanyName(source.companyName()); target.setCompanyName(source.getCompanyName());
target.setCompanyCode(source.companyCode()); target.setCompanyCode(source.getCompanyCode());
target.setLoginTime(LEGACY_LOGIN_TIME.format(source.loginTime())); target.setLoginTime(source.getLoginTime());
target.setMenuHtml(menuRenderer.render(toLegacyMenu(source.menu()))); target.setMenuHtml(source.getMenuHtml());
return target; return target;
} }

View File

@@ -2,9 +2,9 @@ package matrix.nimble.controller;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import lib.constants.ApplicationError; import lib.constants.ApplicationMessage;
import lib.models.ErrorDetails; import lib.models.MessageDetails;
import matrix.nimble.model.Session; import lib.models.UserSession;
import matrix.services.commons.CommonErrorService; import matrix.services.commons.CommonErrorService;
import matrix.services.commons.CommonService; import matrix.services.commons.CommonService;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
@@ -26,29 +26,41 @@ public abstract class AbstractAuthenticatedController {
ModelMap model, ModelMap model,
HttpSession httpSession, HttpSession httpSession,
HttpServletResponse response) { HttpServletResponse response) {
Session session = commonService.getSession(httpSession); UserSession session = commonService.getUserSession(httpSession);
if (session == null) { if (session == null) {
return denied(model, response, httpSession, ApplicationError.SESSION_REQUIRED); return denied(model, response, httpSession, ApplicationMessage.SESSION_REQUIRED);
} }
if (!commonService.hasPageAccess(session, pageRoute)) { if (!commonService.hasPageAccess(session, pageRoute)) {
return denied(model, response, httpSession, ApplicationError.ACCESS_DENIED); return denied(model, response, httpSession, ApplicationMessage.ACCESS_DENIED);
} }
model.addAttribute(CommonService.SESSION_ATTRIBUTE, session); model.addAttribute(CommonService.USER_SESSION_ATTRIBUTE, session);
return PageAuthorization.granted(session); return PageAuthorization.granted(session);
} }
protected final ApiAuthorization authorizeApiPage(
String pageRoute, HttpSession httpSession) {
UserSession session = commonService.getUserSession(httpSession);
if (session == null) {
return ApiAuthorization.denied(new MessageDetails(ApplicationMessage.SESSION_REQUIRED));
}
if (!commonService.hasPageAccess(session, pageRoute)) {
return ApiAuthorization.denied(new MessageDetails(ApplicationMessage.ACCESS_DENIED));
}
return ApiAuthorization.granted(session);
}
private PageAuthorization denied( private PageAuthorization denied(
ModelMap model, ModelMap model,
HttpServletResponse response, HttpServletResponse response,
HttpSession httpSession, HttpSession httpSession,
ApplicationError error) { ApplicationMessage error) {
String viewName = errorService.render( String viewName = errorService.render(
model, response, httpSession, new ErrorDetails(error)); model, response, httpSession, new MessageDetails(error));
return PageAuthorization.denied(viewName); return PageAuthorization.denied(viewName);
} }
protected record PageAuthorization(Session session, String viewName) { protected record PageAuthorization(UserSession session, String viewName) {
private static PageAuthorization granted(Session session) { private static PageAuthorization granted(UserSession session) {
return new PageAuthorization(session, null); return new PageAuthorization(session, null);
} }
@@ -60,4 +72,16 @@ public abstract class AbstractAuthenticatedController {
return session != null; return session != null;
} }
} }
protected record ApiAuthorization(UserSession session, MessageDetails error) {
private static ApiAuthorization granted(UserSession session) {
return new ApiAuthorization(session, null);
}
private static ApiAuthorization denied(MessageDetails error) {
return new ApiAuthorization(null, error);
}
public boolean isGranted() { return session != null; }
}
} }

View File

@@ -13,8 +13,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import matrix.nimble.edp.cutoff.model.AutoCutThread; import matrix.nimble.model.MailboxHandler;
import matrix.nimble.model.MailboxHandler;
import matrix.nimble.model.Session; import matrix.nimble.model.Session;
import matrix.nimble.model.UploadHandler; import matrix.nimble.model.UploadHandler;
import matrix.nimble.utilities.CommonFunctions; import matrix.nimble.utilities.CommonFunctions;
@@ -40,122 +39,7 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
@Controller @Controller
@SessionAttributes({"Sessvals"}) @SessionAttributes({"Sessvals"})
public class Ajax { public class Ajax {
@RequestMapping(value="punchedrecs",method=RequestMethod.GET ) @RequestMapping(value="uploadservice",method=RequestMethod.POST )
public @ResponseBody String PunchedRecords(@RequestParam String val0,@RequestParam String val1,@RequestParam String val2)
{
val1=(val1.replace(GlobalClass.ColDelim, ","));
String fields="case_id,portfolio_id,mvcode,bank_branch_id,applno,product,loanamount,customername,apptype,category,dob,contactperson,mobileno,raddr1,raddr2,raddr3,rlandmark,Rcolony,rcity,rpincode,rphone,companyname,oaddr1,oaddr2,oaddr3,olandmark,Ocolony,ocity,opincode,department,designation,ophone,extension,paddr1,paddr2,paddr3,plandmark,Pcolony,pcity,ppincode,refname1,refaddress1,refcontactno1,refname2,refaddress2,refcontactno2,rv,rtv,ov,otv,pv,refv,docv,rco,rcp,ocp,specialinst,sradd,soadd,spadd,"+val1+"colr,colo,colp,fathername,bankcode,status,company_id,branch_id,uuid";
DBFunctions DBF=new DBFunctions("1001");
DBF.setProcessFlag(true);
if(val2.trim().length() > 20)
{
val0="uuid='"+val2+"'";
}
else
{
val0="portfolio_id="+val0+" and (cutoffby is null or cutoffby=0)";
}
String response= DBF.FetchRunQuery(24, (val0+GlobalClass.ColDelim+val1+GlobalClass.ColDelim+val2+GlobalClass.ColDelim).split(GlobalClass.ColDelim));
fields=fields.replace(",", GlobalClass.ColDelim);
fields=fields+GlobalClass.RowDelim;
if(DBF.isProcessFlag())
{
response=fields+response;
}
else
{
response=DBF.getErrMsg();
response=fields;
}
return response;
}
@RequestMapping(value="puncheddocrecs",method=RequestMethod.GET )
public @ResponseBody String PunchedDocRecords(@RequestParam String val0,@RequestParam String val1)
{
val1=(val1.replace(GlobalClass.ColDelim, ","));
String fields="case_id,portfolio_id,bank_branch_id,applno,product,loanamount,customername,apptype,category,dob,docv,"+val1+"docs,status,company_id,branch_id,uuid";
DBFunctions DBF=new DBFunctions("1001");
DBF.setProcessFlag(true);
String response= DBF.FetchRunQuery(242, (val0+GlobalClass.ColDelim+val1+GlobalClass.ColDelim+"0"+GlobalClass.ColDelim).split(GlobalClass.ColDelim));
fields=fields.replace(",", GlobalClass.ColDelim);
fields=fields+GlobalClass.RowDelim;
if(DBF.isProcessFlag())
{
response=fields+response;
}
else
{
response=DBF.getErrMsg();
response=fields;
}
return response;
}
//insert into main (portfolio_id,bank_branch_id,mvcode,applno,bankcode,product,loanamount,customername,fathername,apptype,category,dob,contactperson,mobileno,specialinst,rv,sradd,rtv,raddr1,raddr2,raddr3,rlandmark,rcolony,rcity,rpincode,rphone,ov,rco,soadd,otv,companyname,oaddr1,oaddr2,oaddr3,olandmark,ocolony,ocity,opincode,department,designation,ophone,extension,pv,rcp,ocp,spadd,paddr1,paddr2,paddr3,plandmark,pcolony,pcity,ppincode,refv,refname1,refaddress1,refcontactno1,refname2,refaddress2,refcontactno2,docv,field1,field2,field3,field4,field5,field6,field7,field8,field9,field10,field11,field12,dtfield1,dtfield2,dtfield3,dtfield4,dtfield5,uuid,receivedate,addedon,addedby,company_id,branch_id) values (val0,val1,'val2','val3','val4','val5','val6','val7','val8','val9','val10','val11','val12','val13','val14',val15,val16,val17,'val18','val19','val20','val21',val22,'val23','val24','val25',val26,val27,val28,val29,'val30','val31','val32','val33','val34',val35,'val36','val37','val38','val39','val40','val41',val42,val43,val44,val45,'val46','val47','val48','val49',val50,'val51','val52',val53,'val54','val55','val56','val57','val58','val59',val60,'val61','val62','val63','val64','val65','val66','val67','val68','val69','val70','val71','val72','val73','val74','val75','val76','val77','val78','val79','val80',val81,val82,val83)
@RequestMapping(value="updatecase",method=RequestMethod.GET )
public @ResponseBody String UpdateRecords(@RequestParam String val0,@RequestParam String val1,@RequestParam String val2,@RequestParam String val3,@RequestParam String val4,@RequestParam String val5,@RequestParam String val6,@RequestParam String val7)
{
String uuid=GlobalClass.GenerateUUID();
String response="";
DBFunctions dbf=new DBFunctions("1001");
dbf.setProcessFlag(true);
val1=val1.replace("~AmP~", "&");
if(val2.equals("0"))
{
val0="mvcode,portfolio_id,"+val0+"receivedate,uuid,addedon,addedby";
val1="''xmvcodex'',"+val6+","+val1+"''"+GlobalClass.DateTime("yyyy/MM/dd", new java.util.Date())+"'',''"+uuid+"'',''"+GlobalClass.DateTime("yyyy/MM/dd HH:mm:ss", new java.util.Date())+"'',"+val5+"";
val0="insert into main ("+val0+") values ("+val1+")";
String [] Qvals=(val0+GlobalClass.ColDelim+"DOCDETAILS"+GlobalClass.ColDelim+val6+GlobalClass.ColDelim+uuid+GlobalClass.ColDelim+val5+GlobalClass.ColDelim+val4+GlobalClass.ColDelim).split(GlobalClass.ColDelim);
dbf.FetchRunQuery(16, Qvals);
if(dbf.isProcessFlag())
{
response=dbf.getProcResult();
if(val4.equals("1")) {
AutoCutThread autoCut = new AutoCutThread();
String [] result = response.split(GlobalClass.ColDelim);
autoCut.setPortfolioid(val6);
autoCut.setUserid(val5);
autoCut.setUuid(result[2]);
autoCut.start();
}
}
else
{
response=dbf.getErrMsg();
}
}
else
{
String [] fields=val0.split(",");
String [] vals=val1.split(",");
val0="";
for(int indx=0;indx<fields.length;indx++)
{
val0=val0+fields[indx]+"="+vals[indx]+",";
}
val0=val0+"addedon=(case when addedby=0 then ''"+GlobalClass.DateTime("yyyy/MM/dd HH:mm:ss", new java.util.Date())+"'' else addedon end),addedby=(case when addedby=0 then "+val5+" else addedby end),lasteditedon=''"+GlobalClass.DateTime("yyyy/MM/dd HH:mm:ss", new java.util.Date())+"'',lasteditedby="+val5;
vals=(val0+GlobalClass.ColDelim+"DOCDETAILS"+GlobalClass.ColDelim+val3+GlobalClass.ColDelim+val6+GlobalClass.ColDelim+val5+GlobalClass.ColDelim+val4+GlobalClass.ColDelim+val7+GlobalClass.ColDelim).split(GlobalClass.ColDelim);
dbf.FetchRunQuery(25, vals);
if(dbf.isProcessFlag())
{
response="success";
if(val4.equals("1")) {
AutoCutThread autoCut = new AutoCutThread();
String [] result = response.split(GlobalClass.ColDelim);
autoCut.setPortfolioid(val6);
autoCut.setUserid(val5);
autoCut.setUuid(val3);
autoCut.start();
}
}
else
{
response=dbf.getErrMsg();
}
}
return response;
}
@RequestMapping(value="uploadservice",method=RequestMethod.POST )
public @ResponseBody String UploadMNimbleCases(@RequestParam String params) public @ResponseBody String UploadMNimbleCases(@RequestParam String params)
{ {
CommonFunctions Cfunc=new CommonFunctions(); CommonFunctions Cfunc=new CommonFunctions();
@@ -211,21 +95,6 @@ public class Ajax {
} }
return response; return response;
} }
@RequestMapping(value="getlocality",method=RequestMethod.POST )
public @ResponseBody String GetLocality(@RequestParam String city, @RequestParam String letters)
{
DBFunctions DBF=new DBFunctions("1001");
DBF.setProcessFlag(true);
String val1="and 1=1";
if(!(city.toUpperCase().equals("-1") || city.toUpperCase().equals("UNKNOWN")))
{
val1="and upper(city)=upper('"+city+"')";
}
String response= DBF.FetchRunQuery(13, (letters.toUpperCase()+GlobalClass.ColDelim+val1+GlobalClass.ColDelim).split(GlobalClass.ColDelim));
response=response.replace(GlobalClass.ColDelim+GlobalClass.RowDelim, GlobalClass.RowDelim);
return response;
}
@RequestMapping(value="listservprovider",method=RequestMethod.POST ) @RequestMapping(value="listservprovider",method=RequestMethod.POST )
public @ResponseBody String ListServProvider(@RequestParam String city, @RequestParam String letters) public @ResponseBody String ListServProvider(@RequestParam String city, @RequestParam String letters)
{ {
@@ -235,16 +104,6 @@ public class Ajax {
response=response.replace(GlobalClass.ColDelim+GlobalClass.RowDelim, GlobalClass.RowDelim); response=response.replace(GlobalClass.ColDelim+GlobalClass.RowDelim, GlobalClass.RowDelim);
return response; return response;
} }
@RequestMapping(value="findsdet",method=RequestMethod.GET )
public @ResponseBody String FindSameAddr(@RequestParam String val, @RequestParam String val1, @RequestParam String val2)
{
String RecDate=GlobalClass.DateTime("yyyy/MM/dd", new java.util.Date());
DBFunctions DBF=new DBFunctions("1001");
DBF.setProcessFlag(true);
String response= DBF.FetchRunQuery(Integer.parseInt(val2), (val+GlobalClass.ColDelim+val1+GlobalClass.ColDelim+RecDate+GlobalClass.ColDelim).split(GlobalClass.ColDelim));
response=response.replace(GlobalClass.ColDelim+GlobalClass.RowDelim, GlobalClass.RowDelim);
return response;
}
@RequestMapping(value="findbyappno",method=RequestMethod.POST ) @RequestMapping(value="findbyappno",method=RequestMethod.POST )
public @ResponseBody String FindByApplno(@RequestParam String val0, @RequestParam String val1, @RequestParam String val2, @RequestParam String val3) public @ResponseBody String FindByApplno(@RequestParam String val0, @RequestParam String val1, @RequestParam String val2, @RequestParam String val3)
{ {

View File

@@ -4,8 +4,8 @@ import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import lib.models.ErrorDetails; import lib.models.MessageDetails;
import lib.constants.ApplicationError; import lib.constants.ApplicationMessage;
import matrix.services.commons.CommonErrorService; import matrix.services.commons.CommonErrorService;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
@@ -37,7 +37,7 @@ public class ApplicationErrorController {
return HttpServletResponse.SC_INTERNAL_SERVER_ERROR; return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
} }
private ErrorDetails details(int status) { private MessageDetails details(int status) {
return new ErrorDetails(ApplicationError.fromHttpStatus(status)); return new MessageDetails(ApplicationMessage.fromHttpStatus(status));
} }
} }

View File

@@ -1,62 +0,0 @@
package matrix.nimble.controller;
import java.util.HashMap;
import java.util.Map;
import matrix.nimble.utilities.DBFunctions;
import matrix.nimble.utilities.GlobalClass;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("doc/")
public class DocAjax {
@RequestMapping(value="updcasedocs",method=RequestMethod.POST )
public @ResponseBody String UpdateEmpRecords(@RequestBody String jsonString)
{
String [] qparams=null;
Map<String,String> jsonMap=new HashMap<String, String>();
String [] splitted = (jsonString.replace(":\"\"", ":\"null\"").replace("\",\"","!R0@W@0L!").replace("\":\"","!C@~@L!").replace("{\"", "").replace("\"}", "")).split("!R0@W@0L!");
String query="";
String opron = GlobalClass.DateTime("yyyy/MM/dd",new java.util.Date());
for(int indx=0;indx < splitted.length; indx++)
{
jsonMap.put(splitted[indx].split("!C@~@L!")[0], splitted[indx].split("!C@~@L!")[1]);
}
String opr = jsonMap.get("doc_id").toString().equals("0") ? "ADD DOC":"UPDATE DOC";
if(jsonMap.get("doc_id").toString().equals("0"))
{
query = "INSERT INTO case_documents(uuid, doctype, bank_id, docholdername, serviceprovider,uniqueno, yearmonth,";
query += "city, docvendor, addedby, addedon) values (''"+jsonMap.get("uuid")+"'',"+jsonMap.get("doctype")+",";
query += jsonMap.get("serviceprovider_hidden")+",''"+jsonMap.get("docholdername")+"'',''"+jsonMap.get("serviceprovider")+"'',";
query += "''"+jsonMap.get("uniqueno")+"'',''"+jsonMap.get("yearmonth")+"'',''"+jsonMap.get("city")+"'',";
query += jsonMap.get("vendor_id")+","+jsonMap.get("usid")+",''"+opron+"'')";
}
else
{
query = "update case_documents set doctype=''"+jsonMap.get("doctype")+"'',bank_id="+jsonMap.get("serviceprovider_hidden")+",";
query += "docholdername=''"+jsonMap.get("docholdername")+"'',serviceprovider=''"+jsonMap.get("serviceprovider")+"'',";
query += "uniqueno=''"+jsonMap.get("uniqueno")+"'',yearmonth=''"+jsonMap.get("yearmonth")+"'',";
query += "city=''"+jsonMap.get("city")+"'',docvendor=''"+jsonMap.get("vendor_id")+"'',";
query += "addedby="+jsonMap.get("usid")+",addedon=''"+jsonMap.get("opr")+"'' where doc_id="+jsonMap.get("doc_id");
}
qparams = new String[]{query,jsonMap.get("usid").toString(),opr,opron};
String response="failed";
DBFunctions DBF=new DBFunctions("D001");
DBF.setProcessFlag(true);
DBF.FetchRunQuery(354, qparams);
if(DBF.isProcessFlag())
{
response="{\"status\":\"success\",\"did\":\""+DBF.getProcResult()+"\",\"result\":"+jsonString+"}";
}
else
{
response="{\"status\":\"success\",\"did\":\""+jsonMap.get("doc_id")+"\",\"result\":\""+DBF.getErrMsg()+"\"}";
}
return response;
}
}

View File

@@ -2,9 +2,11 @@ package matrix.nimble.controller;
import matrix.nimble.cloud.identity.CloudAuthenticationException; import matrix.nimble.cloud.identity.CloudAuthenticationException;
import matrix.nimble.cloud.identity.CloudAuthenticationGateway; import matrix.nimble.cloud.identity.CloudAuthenticationGateway;
import matrix.nimble.cloud.identity.CloudSessionMapper;
import matrix.nimble.model.Login; import matrix.nimble.model.Login;
import matrix.nimble.model.Session; import matrix.nimble.model.Session;
import matrix.services.commons.CommonService; import matrix.services.commons.CommonService;
import lib.models.UserSession;
//servlet libraries //servlet libraries
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@@ -23,12 +25,15 @@ import org.springframework.web.bind.annotation.SessionAttributes;
public class SessionController { public class SessionController {
private final CloudAuthenticationGateway cloudAuthenticationGateway; private final CloudAuthenticationGateway cloudAuthenticationGateway;
private final CommonService commonService; private final CommonService commonService;
private final CloudSessionMapper cloudSessionMapper;
public SessionController( public SessionController(
CloudAuthenticationGateway cloudAuthenticationGateway, CloudAuthenticationGateway cloudAuthenticationGateway,
CommonService commonService) { CommonService commonService,
CloudSessionMapper cloudSessionMapper) {
this.cloudAuthenticationGateway = cloudAuthenticationGateway; this.cloudAuthenticationGateway = cloudAuthenticationGateway;
this.commonService = commonService; this.commonService = commonService;
this.cloudSessionMapper = cloudSessionMapper;
} }
@RequestMapping(value="login", method={RequestMethod.GET, RequestMethod.POST}) @RequestMapping(value="login", method={RequestMethod.GET, RequestMethod.POST})
public String LoginPage(ModelMap model) public String LoginPage(ModelMap model)
@@ -53,10 +58,12 @@ public class SessionController {
HttpSession httpSession) HttpSession httpSession)
{ {
try { try {
Session cloudSession = cloudAuthenticationGateway.authenticate( UserSession userSession = cloudAuthenticationGateway.authenticate(
login.getLoginid(), login.getPassword()); login.getLoginid(), login.getPassword());
Session cloudSession = cloudSessionMapper.toLegacy(userSession);
model.remove("login"); model.remove("login");
model.addAttribute("Sessvals", cloudSession); model.addAttribute("Sessvals", cloudSession);
commonService.storeUserSession(httpSession, userSession);
commonService.storeSession(httpSession, cloudSession); commonService.storeSession(httpSession, cloudSession);
return "home"; return "home";
} catch (CloudAuthenticationException exception) { } catch (CloudAuthenticationException exception) {

View File

@@ -1,160 +0,0 @@
package matrix.nimble.edp.punching.controllers;
//servlet libraries
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
//spring libraries
import matrix.nimble.edp.punching.model.CaseDetails;
import matrix.nimble.model.Session;
import matrix.nimble.utilities.ModuleFunctions;
import matrix.nimble.utilities.GlobalClass;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
@Controller
@SessionAttributes({ "Sessvals" })
public class CasePucnhing {
@RequestMapping(value = "caseadd1", method = RequestMethod.POST)
public String OpenAddCases(ModelMap model, HttpServletRequest request,
@ModelAttribute(value = "Sessvals") Session Sessvals) {
CaseDetails caseDetails = new CaseDetails();
caseDetails.setFormMode(1);
caseDetails.setErrMsg("");
model.addAttribute("visibleContents", "");
model.addAttribute("caseDetails", caseDetails);
model.addAttribute("branchlist", FillBranchList("0"));
model.addAttribute("prodlist", FillProductList("0"));
model.addAttribute("citylist", FillCityList("0"));
model.addAttribute("typelist", FillApptypeList("0"));
model.addAttribute("doclist", FillDocList("0"));
model.addAttribute("catlist", FillCatList("0"));
model.addAttribute("Sessvals", Sessvals);
model.addAttribute("portlist", FillPortList(Sessvals.getBranchID()));
return "edp/punching/addcases";
}
@RequestMapping(value = "casesave", method = RequestMethod.POST)
public String SaveCase(ModelMap model, HttpServletRequest request,
@ModelAttribute(value = "Sessvals") Session Sessvals,
@ModelAttribute(value = "caseDetails") CaseDetails caseDet, HttpSession session) {
String DynamicNsessVals = "";
CaseDetails caseDetails = new CaseDetails();
caseDet.setErrCode("1001");
if (caseDet.getDynamicFields() != "") {
String[] DynamicFields = caseDet.getDynamicFields().split(GlobalClass.ColDelim);
for (int indx = 0; indx < DynamicFields.length; indx++) {
// DynamicNsessVals=DynamicNsessVals+request.getParameter(DynamicFields[indx])+Delimeter.ColDelim;
caseDet.InvokeSetter("set" + DynamicFields[indx], request.getParameter(DynamicFields[indx]));
}
}
if (caseDet.getFormMode() == 1 || caseDet.getFormMode() == 2) {
DynamicNsessVals = DynamicNsessVals + "" + Sessvals.getUserID() + GlobalClass.ColDelim;
DynamicNsessVals = DynamicNsessVals + "" + Sessvals.getCompanyID() + GlobalClass.ColDelim;
DynamicNsessVals = DynamicNsessVals + "" + Sessvals.getBranchID();
}
if (!session.getAttribute("UUID").toString().equals(caseDet.getUUID())) {
caseDetails.setProcessFlag(true);
caseDetails.setErrMsg("");
} else {
caseDet.SaveDetails(DynamicNsessVals);
caseDetails.setProcessFlag(caseDet.isProcessFlag());
caseDetails.setErrMsg(caseDet.getErrMsg());
}
String VisibleContents = caseDet.getVisibleContents();
if (caseDetails.isProcessFlag()) {
String UUID = GlobalClass.GenerateUUID();
caseDetails.setUUID(UUID);
session.setAttribute("UUID", UUID);
caseDetails.setErrCode("1001");
caseDetails.setFormMode(caseDet.getFormMode());
caseDetails.setVisibleContents(VisibleContents);
caseDetails.setPortfolioId(caseDet.getPortfolioId());
caseDetails = caseDetails.DynamicHtml(caseDetails, caseDet.getPortfolioId());
caseDetails.setDynamicFields(caseDet.getDynamicFields());
VisibleContents = VisibleContents + "" + caseDetails.getDynamicSection();
model.addAttribute("caseDetails", caseDetails);
} else {
caseDet = caseDet.DynamicHtml(caseDet, caseDet.getPortfolioId());
VisibleContents = VisibleContents + "" + caseDet.getDynamicSection();
model.addAttribute("caseDetails", caseDet);
}
model.addAttribute("visibleContents", VisibleContents);
model.addAttribute("branchlist", FillBranchList(caseDet.getPortfolioId()));
model.addAttribute("prodlist", FillProductList(caseDet.getPortfolioId()));
model.addAttribute("citylist", FillCityList(Sessvals.getBranchID()));
model.addAttribute("typelist", FillApptypeList(Sessvals.getBranchID()));
model.addAttribute("doclist", FillDocList(caseDet.getPortfolioId()));
model.addAttribute("catlist", FillCatList(caseDet.getPortfolioId()));
model.addAttribute("Sessvals", Sessvals);
model.addAttribute("portlist", FillPortList(Sessvals.getBranchID()));
return "edp/punching/addcases";
}
@RequestMapping(value = "casedet", method = RequestMethod.POST)
public String GetRequiredData(ModelMap model, HttpServletRequest request,
@ModelAttribute(value = "Sessvals") Session Sessvals,
@ModelAttribute(value = "caseDetails") CaseDetails caseDet, HttpSession session) {
CaseDetails caseDetails = new CaseDetails();
caseDetails.setPortfolioId(caseDet.getPortfolioId());
caseDetails.setErrCode("1001");
String UUID = GlobalClass.GenerateUUID();
caseDetails.setUUID(UUID);
session.setAttribute("UUID", UUID);
caseDetails.setFormMode(caseDet.getFormMode());
caseDetails = caseDetails.DynamicHtml(caseDetails, caseDet.getPortfolioId());
String VisibleContents = (new ModuleFunctions("1001").GetDDHashString(10,
("10" + GlobalClass.ColDelim + caseDet.getPortfolioId()).split(GlobalClass.ColDelim)))
.replace(GlobalClass.RowDelim, "");
caseDetails.setVisibleContents(VisibleContents);
VisibleContents = (VisibleContents + "" + caseDetails.getDynamicSection())
.replace(GlobalClass.ColDelim + "null", "");
model.addAttribute("visibleContents", VisibleContents);
model.addAttribute("caseDetails", caseDetails);
model.addAttribute("portlist", Sessvals.getBranchID());
model.addAttribute("branchlist", FillBranchList(caseDet.getPortfolioId()));
model.addAttribute("prodlist", FillProductList(caseDet.getPortfolioId()));
model.addAttribute("citylist", FillCityList(Sessvals.getBranchID()));
model.addAttribute("typelist", FillApptypeList(Sessvals.getBranchID()));
model.addAttribute("doclist", FillDocList(caseDet.getPortfolioId()));
model.addAttribute("catlist", FillCatList(caseDet.getPortfolioId()));
model.addAttribute("Sessvals", Sessvals);
model.addAttribute("portlist", FillPortList(Sessvals.getBranchID()));
return "edp/punching/addcases";
}
public String[][] FillPortList(String BranchId) {
return new ModuleFunctions("1001").GetResultArray(3,
(BranchId + GlobalClass.ColDelim).split(GlobalClass.ColDelim));
}
public String[][] FillCityList(String BranchID) {
return new ModuleFunctions("1001").GetResultArray(6, BranchID.split(GlobalClass.ColDelim));
}
public String[][] FillApptypeList(String BranchID) {
return new ModuleFunctions("1001").GetResultArray(8, BranchID.split(GlobalClass.ColDelim));
}
public String[][] FillCatList(String PortfolioID) {
return new ModuleFunctions("1001").GetResultArray(9, PortfolioID.split(GlobalClass.ColDelim));
}
public String[][] FillDocList(String PortfolioID) {
return new ModuleFunctions("1001").GetResultArray(7, PortfolioID.split(GlobalClass.ColDelim));
}
public String[][] FillBranchList(String PortfolioID) {
return new ModuleFunctions("1001").GetResultArray(4, PortfolioID.split(GlobalClass.ColDelim));
}
public String[][] FillProductList(String PortfolioID) {
return new ModuleFunctions("1001").GetResultArray(5, PortfolioID.split(GlobalClass.ColDelim));
}
}

View File

@@ -1,60 +0,0 @@
package matrix.nimble.edp.punching.controllers;
import java.util.HashMap;
import jakarta.servlet.http.HttpServletRequest;
import matrix.nimble.edp.punching.model.CaseGrid;
import matrix.nimble.model.Session;
import matrix.nimble.utilities.GlobalClass;
import matrix.nimble.utilities.ModuleFunctions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
@Controller
@SessionAttributes({ "Sessvals" })
public class EditCasesGrid {
@RequestMapping(value = "editgrid", method = RequestMethod.POST)
public String OpenEditGrid(ModelMap model, HttpServletRequest request,
@ModelAttribute(value = "Sessvals") Session Sessvals) {
String[][] CaseList = null;
CaseGrid CG = new CaseGrid();
model.addAttribute("Sessvals", Sessvals);
model.addAttribute("caseList", CaseList);
model.addAttribute("caseGrid", CG);
model.addAttribute("portlist", FillPortList(Sessvals.getBranchID(), Sessvals.getUserID()));
return "edp/punching/editcases";
}
@RequestMapping(value = "caselist", method = RequestMethod.POST)
public String ListCases(ModelMap model, HttpServletRequest request,
@ModelAttribute(value = "Sessvals") Session Sessvals,
@ModelAttribute(value = "caseGrid") CaseGrid caseGrid) {
CaseGrid CG = new CaseGrid();
CG.setErrCode("1002");
CG.setPortfolioId(caseGrid.getPortfolioId());
String[][] CaseList = CG.FillCaseList(caseGrid.getPortfolioId(), Sessvals.getBranchID());
if (CG.isProcessFlag()) {
model.addAttribute("caseList", CaseList);
model.addAttribute("caseGrid", CG);
} else {
caseGrid.setErrMsg(CG.getErrMsg());
model.addAttribute("caseList", CaseList);
model.addAttribute("caseGrid", caseGrid);
}
model.addAttribute("Sessvals", Sessvals);
model.addAttribute("portlist", FillPortList(Sessvals.getBranchID(), Sessvals.getUserID()));
return "edp/punching/editcases";
}
public String[][] FillPortList(String BranchId, String userId) {
return new ModuleFunctions("1002").GetResultArray(249,
(BranchId + GlobalClass.ColDelim + userId + GlobalClass.ColDelim).split(GlobalClass.ColDelim));
}
}

View File

@@ -1,128 +0,0 @@
package matrix.nimble.edp.punching.controllers;
//servlet libraries
import java.net.URLDecoder;
import jakarta.servlet.http.HttpServletRequest;
//spring libraries
import matrix.nimble.edp.punching.model.PunchingHandler;
import matrix.nimble.model.Session;
import matrix.nimble.utilities.CommonFunctions;
import matrix.nimble.utilities.GlobalClass;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
@Controller
@SessionAttributes({ "Sessvals" })
public class Punching {
@RequestMapping(value = "initdocview", method = RequestMethod.POST)
public String InitDocScreen(ModelMap model, HttpServletRequest request,
@ModelAttribute(value = "Sessvals") Session Sessvals) {
PunchingHandler PH = new PunchingHandler();
PH.setErrCode("1901");
model.addAttribute("branchlist", null);
model.addAttribute("prodlist", null);
model.addAttribute("typelist", null);
model.addAttribute("doclist", null);
model.addAttribute("catlist", null);
model.addAttribute("portfolio_id", "-1");
model.addAttribute("Sessvals", Sessvals);
PH.GetDDValues(240, Sessvals.getBranchID().split(GlobalClass.ColDelim));
model.addAttribute("portlist", PH.getOptionvals());
model.addAttribute("formmode", 0);
model.addAttribute("stat", true);
model.addAttribute("msg", "");
return "edp/punching/initdocs";
}
@RequestMapping(value = "docadd", method = RequestMethod.POST)
public String PunchDocs(ModelMap model, HttpServletRequest request,
@ModelAttribute(value = "Sessvals") Session Sessvals) {
String msg = "";
PunchingHandler PH = new PunchingHandler();
CommonFunctions comFunc = new CommonFunctions();
PH.setErrCode("1901");
PH.setPortfolioid(request.getParameter("portfolio_id"));
PH.setProcessFlag(true);
PH.DocDynamicHtml();
if (PH.isProcessFlag()) {
model.addAttribute("dynamichtml", PH.getDynamicpanel());
model.addAttribute("dynamicfields", PH.getDynamicfields());
model.addAttribute("docdynamichtml", PH.getDocdynamicpanel());
model.addAttribute("docdynamicfields", PH.getDocdynamicfields());
} else {
msg = PH.getErrMsg();
}
PH.GetDDValues(240, Sessvals.getBranchID().split(GlobalClass.ColDelim));
model.addAttribute("portlist", PH.getOptionvals());
PH.GetDDValues(4, PH.getPortfolioid().split(GlobalClass.ColDelim));
model.addAttribute("branchlist", PH.getOptionvals());
PH.GetDDValues(5,
(Sessvals.getBranchID() + GlobalClass.ColDelim + "op.description='DOCUMENT' or op.description='APPTYPE'"
+ GlobalClass.ColDelim).split(GlobalClass.ColDelim));
if (PH.getOptionvals() != null) {
model.addAttribute("typelist", comFunc.GetSubArray("APPTYPE", 2, PH.getOptionvals()));
} else {
model.addAttribute("typelist", null);
}
PH.GetDDValues(241, PH.getPortfolioid().split(GlobalClass.ColDelim));
model.addAttribute("doclist", PH.getOptionvals());
PH.GetDDValues(70,
(PH.getPortfolioid() + GlobalClass.ColDelim + "op.description='CATEGORY' or op.description='PRODUCT'"
+ GlobalClass.ColDelim).split(GlobalClass.ColDelim));
if (PH.getOptionvals() != null) {
model.addAttribute("prodlist", comFunc.GetSubArray("PRODUCT", 2, PH.getOptionvals()));
model.addAttribute("catlist", comFunc.GetSubArray("CATEGORY", 2, PH.getOptionvals()));
} else {
model.addAttribute("prodlist", null);
model.addAttribute("catlist", null);
}
model.addAttribute("portfolio_id", PH.getPortfolioid());
model.addAttribute("usid", Sessvals.getUserID());
model.addAttribute("Sessvals", Sessvals);
model.addAttribute("formmode", 1);
model.addAttribute("stat", PH.isProcessFlag());
model.addAttribute("msg", msg);
return "edp/punching/initdocs";
}
@RequestMapping(value = "addeditdoc", method = RequestMethod.POST)
public String AddEditDocs(@RequestParam String val0, @RequestParam String val1, @RequestParam String val2,
@RequestParam String val3, @RequestParam String val4, @RequestParam String val5, @RequestParam String val6,
@RequestParam String val7, @RequestParam String val8, @RequestParam String val9,
@RequestParam String val10) {
String retval = "success";
try {
// System.out.println(URLDecoder.decode(val0,"UTF-8"));
// System.out.println(URLDecoder.decode(val1,"UTF-8"));
// System.out.println(URLDecoder.decode(val2,"UTF-8"));
// System.out.println(URLDecoder.decode(val3,"UTF-8"));
// System.out.println(URLDecoder.decode(val4,"UTF-8"));
// System.out.println(URLDecoder.decode(val6,"UTF-8"));
// System.out.println(URLDecoder.decode(val7,"UTF-8"));
// System.out.println(URLDecoder.decode(val8,"UTF-8"));
// System.out.println(URLDecoder.decode(val9,"UTF-8"));
// System.out.println(URLDecoder.decode(val10,"UTF-8"));
PunchingHandler PH = new PunchingHandler();
PH.setErrCode("1902");
PH.setProcessFlag(true);
PH.AddEditDocs(val0, val1, val2, val3, val4, val6, val7, val8, val9, val10);
} catch (Exception exce) {
retval = exce.getMessage();
}
return retval;
}
}

View File

@@ -6,26 +6,182 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import matrix.nimble.controller.AbstractAuthenticatedController; import matrix.nimble.controller.AbstractAuthenticatedController;
import matrix.nimble.model.Session; import lib.models.UserSession;
import matrix.services.commons.CommonService; import matrix.services.commons.CommonService;
import matrix.services.edp.PunchingService; import matrix.services.edp.PunchingService;
import matrix.services.commons.CommonErrorService; import matrix.services.commons.CommonErrorService;
import lib.models.CasePunching; import lib.models.CasePunching;
import lib.models.ApplicationDetails;
import lib.models.ApiResponse;
import lib.models.ApplicationSaveData;
import lib.models.ApplicationSaveResult;
import lib.models.CaseSaveRequest;
import lib.models.MessageDetails;
import lib.models.PunchedRecordsData;
import lib.models.DuplicateDetailsData;
import lib.models.LocalityData;
import matrix.nimble.edp.punching.model.CaseGrid;
import lib.constants.ApplicationMessage;
import matrix.nimble.security.PayloadCryptoService;
import lib.exceptions.ApplicationException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@Controller @Controller
public class PunchingController extends AbstractAuthenticatedController { public class PunchingController extends AbstractAuthenticatedController {
private static final Logger LOGGER = Logger.getLogger(PunchingController.class.getName());
private static final String INIT_VIEW_ROUTE = "initview"; private static final String INIT_VIEW_ROUTE = "initview";
private static final String CASE_ADD_ROUTE = "caseadd";
private static final String CASE_EDIT_ROUTE = "caseedit";
private static final String DUPLICATE_DETAILS_ROUTE = "findsdet";
private static final String LOCALITY_ROUTE = "getlocality";
private static final String EDIT_GRID_ROUTE = "editgrid";
private final PunchingService punchingService; private final PunchingService punchingService;
private final PayloadCryptoService cryptoService;
public PunchingController(CommonService commonService, CommonErrorService errorService, public PunchingController(CommonService commonService, CommonErrorService errorService,
PunchingService punchingService) { PunchingService punchingService, PayloadCryptoService cryptoService) {
super(commonService, errorService); super(commonService, errorService);
this.punchingService = punchingService; this.punchingService = punchingService;
this.cryptoService = cryptoService;
}
@RequestMapping(value = "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());
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)
@ResponseBody
public ResponseEntity<ApiResponse<PunchedRecordsData>> punchedRecords(
@RequestParam("portfolioId") Short portfolioId,
@RequestParam(value = "documentCaseId", required = false) String documentCaseId,
HttpSession httpSession) {
ApiAuthorization authorization = authorizeApiPage(INIT_VIEW_ROUTE, httpSession);
if (!authorization.isGranted()) {
return ResponseEntity.status(authorization.error().getHttpStatus())
.body(ApiResponse.failure(authorization.error()));
}
try {
PunchedRecordsData data = punchingService.loadPunchedRecords(
portfolioId, documentCaseId, authorization.session());
return ResponseEntity.ok(ApiResponse.success(
data, new MessageDetails(ApplicationMessage.APPLICATIONS_LOADED)));
} catch (ApplicationException exception) {
LOGGER.log(Level.WARNING, "Punched records were rejected", exception);
MessageDetails details = new MessageDetails(exception.getApplicationMessage());
return ResponseEntity.status(details.getHttpStatus()).body(ApiResponse.failure(details));
} catch (RuntimeException exception) {
LOGGER.log(Level.SEVERE, "Unable to load punched records", exception);
MessageDetails details = new MessageDetails(ApplicationMessage.INTERNAL_SERVER_ERROR);
return ResponseEntity.status(details.getHttpStatus()).body(ApiResponse.failure(details));
}
}
@RequestMapping(value = DUPLICATE_DETAILS_ROUTE, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<ApiResponse<DuplicateDetailsData>> findDuplicateDetails(
@RequestParam("applicationNumber") String applicationNumber,
@RequestParam("portfolioId") Short portfolioId,
@RequestParam("queryId") Integer queryId,
HttpSession httpSession) {
ApiAuthorization authorization = authorizeApiPage(INIT_VIEW_ROUTE, httpSession);
if (!authorization.isGranted()) {
return ResponseEntity.status(authorization.error().getHttpStatus())
.body(ApiResponse.failure(authorization.error()));
}
try {
DuplicateDetailsData data = punchingService.findDuplicateDetails(
applicationNumber, portfolioId, queryId, authorization.session());
return ResponseEntity.ok(ApiResponse.success(
data, new MessageDetails(ApplicationMessage.APPLICATIONS_LOADED)));
} catch (ApplicationException exception) {
LOGGER.log(Level.WARNING, "Duplicate detail search was rejected", exception);
MessageDetails details = new MessageDetails(exception.getApplicationMessage());
return ResponseEntity.status(details.getHttpStatus()).body(ApiResponse.failure(details));
} catch (RuntimeException exception) {
LOGGER.log(Level.SEVERE, "Unable to search duplicate details", exception);
MessageDetails details = new MessageDetails(ApplicationMessage.INTERNAL_SERVER_ERROR);
return ResponseEntity.status(details.getHttpStatus()).body(ApiResponse.failure(details));
}
}
@RequestMapping(value = LOCALITY_ROUTE, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<ApiResponse<LocalityData>> findLocalities(
@RequestParam("city") String city,
@RequestParam("letters") String letters,
HttpSession httpSession) {
ApiAuthorization authorization = authorizeApiPage(INIT_VIEW_ROUTE, httpSession);
if (!authorization.isGranted()) {
return ResponseEntity.status(authorization.error().getHttpStatus())
.body(ApiResponse.failure(authorization.error()));
}
try {
LocalityData data = punchingService.findLocalities(city, letters, authorization.session());
return ResponseEntity.ok(ApiResponse.success(
data, new MessageDetails(ApplicationMessage.APPLICATIONS_LOADED)));
} catch (ApplicationException exception) {
LOGGER.log(Level.WARNING, "Locality search was rejected", exception);
MessageDetails details = new MessageDetails(exception.getApplicationMessage());
return ResponseEntity.status(details.getHttpStatus()).body(ApiResponse.failure(details));
} catch (RuntimeException exception) {
LOGGER.log(Level.SEVERE, "Unable to search localities", exception);
MessageDetails details = new MessageDetails(ApplicationMessage.INTERNAL_SERVER_ERROR);
return ResponseEntity.status(details.getHttpStatus()).body(ApiResponse.failure(details));
}
}
@RequestMapping(value = "application-save", 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());
try {
ApplicationDetails details = cryptoService.decrypt(request, ApplicationDetails.class);
ApplicationSaveResult saved = punchingService.saveApplication(details, authorization.session());
return ResponseEntity.ok(ApiResponse.success(
new ApplicationSaveData(saved.getOperation(), saved.getApplicationId(), saved.getMvCode()),
new MessageDetails(ApplicationMessage.APPLICATION_SAVED)));
} catch (ApplicationException exception) {
LOGGER.log(Level.WARNING, "Application save was rejected", exception);
return applicationError(new MessageDetails(exception.getApplicationMessage()));
} catch (RuntimeException exception) {
LOGGER.log(Level.SEVERE, "Unexpected case-save failure", exception);
return applicationError(new MessageDetails(ApplicationMessage.APPLICATION_SAVE_FAILED));
}
}
private ResponseEntity<?> error(MessageDetails details) {
return ResponseEntity.status(details.getHttpStatus()).body(details);
}
private ResponseEntity<ApiResponse<ApplicationSaveData>> applicationError(MessageDetails details) {
return ResponseEntity.status(details.getHttpStatus())
.body(ApiResponse.failure(details));
} }
@RequestMapping(value = INIT_VIEW_ROUTE, method = RequestMethod.POST) @RequestMapping(value = INIT_VIEW_ROUTE, method = RequestMethod.POST)
@@ -38,16 +194,15 @@ public class PunchingController extends AbstractAuthenticatedController {
if (!authorization.isGranted()) { if (!authorization.isGranted()) {
return authorization.viewName(); return authorization.viewName();
} }
Session Sessvals = authorization.session(); UserSession userSession = authorization.session();
model.addAttribute("model", punchingService.init( model.addAttribute("model", punchingService.init(
Sessvals.getBranchID(), Sessvals.getUserID(), null, "xxx")); userSession.getBranchId(), userSession.getUserId(), null, null));
model.addAttribute("Sessvals", Sessvals);
return "edp/punching/initcase"; return "edp/punching/initcase";
} }
@RequestMapping(value = "caseadd", method = RequestMethod.POST) @RequestMapping(value = CASE_ADD_ROUTE, method = RequestMethod.POST)
public String addCase( public String prepareNewApplication(
@ModelAttribute("model") CasePunching submitted, @ModelAttribute("model") CasePunching submitted,
ModelMap model, ModelMap model,
HttpSession httpSession, HttpSession httpSession,
@@ -58,16 +213,15 @@ public class PunchingController extends AbstractAuthenticatedController {
return authorization.viewName(); return authorization.viewName();
} }
Session session = authorization.session(); UserSession session = authorization.session();
model.addAttribute("model", punchingService.addCase( model.addAttribute("model", punchingService.prepareNewApplication(
submitted, session.getBranchID(), session.getUserID())); submitted, session.getBranchId(), session.getCompanyId(), session.getUserId()));
model.addAttribute("Sessvals", session);
return "edp/punching/initcase"; return "edp/punching/initcase";
} }
@RequestMapping(value = "caseedit", method = RequestMethod.POST) @RequestMapping(value = CASE_EDIT_ROUTE, method = RequestMethod.POST)
public String editCase( public String prepareApplicationEdit(
@RequestParam("PortfolioId") Integer portfolioId, @RequestParam("PortfolioId") Short portfolioId,
@RequestParam("uuid") String documentCaseId, @RequestParam("uuid") String documentCaseId,
ModelMap model, ModelMap model,
HttpSession httpSession, HttpSession httpSession,
@@ -78,10 +232,58 @@ public class PunchingController extends AbstractAuthenticatedController {
return authorization.viewName(); return authorization.viewName();
} }
Session session = authorization.session(); UserSession session = authorization.session();
model.addAttribute("model", punchingService.editCase( model.addAttribute("model", punchingService.prepareApplicationEdit(
portfolioId, documentCaseId, session.getBranchID(), session.getUserID())); portfolioId, documentCaseId, session.getBranchId(),
model.addAttribute("Sessvals", session); session.getCompanyId(), session.getUserId()));
return "edp/punching/initcase"; return "edp/punching/initcase";
} }
@RequestMapping(value = EDIT_GRID_ROUTE, method = RequestMethod.POST)
public String openEditGrid(
ModelMap model,
HttpSession httpSession,
HttpServletResponse response) {
PageAuthorization authorization = authorizePage(
EDIT_GRID_ROUTE, model, httpSession, response);
if (!authorization.isGranted()) {
return authorization.viewName();
}
populateEditGrid(model, new CaseGrid(), authorization.session(), false);
return "edp/punching/editcases";
}
@RequestMapping(value = "caselist", method = RequestMethod.POST)
public String listEditableCases(
@ModelAttribute("caseGrid") CaseGrid caseGrid,
ModelMap model,
HttpSession httpSession,
HttpServletResponse response) {
PageAuthorization authorization = authorizePage(
EDIT_GRID_ROUTE, model, httpSession, response);
if (!authorization.isGranted()) {
return authorization.viewName();
}
populateEditGrid(model, caseGrid, authorization.session(), true);
return "edp/punching/editcases";
}
private void populateEditGrid(
ModelMap model, CaseGrid caseGrid, UserSession session, boolean loadCases) {
Short portfolioId = selectedPortfolio(caseGrid);
model.addAttribute("caseGrid", caseGrid);
model.addAttribute("portlist", punchingService.loadEditCasePortfolios(session));
model.addAttribute("caseList", loadCases && portfolioId != null
? punchingService.loadEditableCases(portfolioId, session)
: java.util.List.of());
}
private Short selectedPortfolio(CaseGrid caseGrid) {
try {
short portfolioId = Short.parseShort(caseGrid.getPortfolioId());
return portfolioId > 0 ? portfolioId : null;
} catch (NumberFormatException | NullPointerException ignored) {
return null;
}
}
} }

View File

@@ -1,10 +1,6 @@
package matrix.nimble.edp.punching.model; package matrix.nimble.edp.punching.model;
import matrix.nimble.utilities.DBFunctions; public class CaseGrid {
import matrix.nimble.utilities.GlobalClass;
import matrix.nimble.utilities.StringFunctions;
public class CaseGrid {
private String ErrMsg; private String ErrMsg;
private String ErrDesc; private String ErrDesc;
private String ErrCode; private String ErrCode;
@@ -48,23 +44,4 @@ public class CaseGrid {
public void setCaseID(String caseID) { public void setCaseID(String caseID) {
CaseID = caseID; CaseID = caseID;
} }
public String[][] FillCaseList(String PortfolioID,String CompBranchId) }
{
String [][]CaseList=null;
DBFunctions DBF=new DBFunctions(getErrCode());
DBF.setProcessFlag(true);
String ResultData=DBF.FetchRunQuery(23, (PortfolioID+GlobalClass.ColDelim+CompBranchId+GlobalClass.ColDelim).split(GlobalClass.ColDelim));
if(DBF.isProcessFlag())
{
setProcessFlag(DBF.isProcessFlag());
CaseList=new StringFunctions(getErrCode()).ConverTo2DArray(ResultData, GlobalClass.RowDelim, GlobalClass.ColDelim);
}
else
{
setProcessFlag(false);
setErrMsg(DBF.getErrMsg());
setErrDesc(DBF.getErrDesc());
}
return CaseList;
}
}

View File

@@ -1,88 +0,0 @@
package matrix.nimble.edp.punching.model;
public class DocDetails {
private String portfolioid;
private String bankbranchid;
private String applno;
private String customername;
private String product;
private String apptype;
private String category;
private String loanamount;
private String dob;
private String caseid;
private String uuid;
private int formmode;
public String getPortfolioid() {
return portfolioid;
}
public void setPortfolioid(String portfolioid) {
this.portfolioid = portfolioid;
}
public String getBankbranchid() {
return bankbranchid;
}
public void setBankbranchid(String bankbranchid) {
this.bankbranchid = bankbranchid;
}
public String getApplno() {
return applno;
}
public void setApplno(String applno) {
this.applno = applno;
}
public String getCustomername() {
return customername;
}
public void setCustomername(String customername) {
this.customername = customername;
}
public String getProduct() {
return product;
}
public void setProduct(String product) {
this.product = product;
}
public String getApptype() {
return apptype;
}
public void setApptype(String apptype) {
this.apptype = apptype;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getLoanamount() {
return loanamount;
}
public void setLoanamount(String loanamount) {
this.loanamount = loanamount;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getCaseid() {
return caseid;
}
public void setCaseid(String caseid) {
this.caseid = caseid;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public int getFormmode() {
return formmode;
}
public void setFormmode(int formmode) {
this.formmode = formmode;
}
}

View File

@@ -1,13 +1,6 @@
package matrix.nimble.edp.punching.model; package matrix.nimble.edp.punching.model;
import java.util.ArrayList; import matrix.nimble.utilities.CommonFunctions;
import java.util.List;
import org.apache.commons.collections.FactoryUtils;
import org.apache.commons.collections.list.LazyList;
import matrix.nimble.edp.cutoff.model.CutOffRecord;
import matrix.nimble.utilities.CommonFunctions;
import matrix.nimble.utilities.DBFunctions; import matrix.nimble.utilities.DBFunctions;
import matrix.nimble.utilities.GlobalClass; import matrix.nimble.utilities.GlobalClass;
import matrix.nimble.utilities.StringFunctions; import matrix.nimble.utilities.StringFunctions;
@@ -21,8 +14,6 @@ public class PunchingHandler {
private String dynamicpanel; private String dynamicpanel;
private String dynamicsection; private String dynamicsection;
private String dynamicfields; private String dynamicfields;
private String docdynamicfields;
private String docdynamicpanel;
private String portfolioid; private String portfolioid;
private String [][] optionvals; private String [][] optionvals;
@@ -62,18 +53,6 @@ public class PunchingHandler {
public void setDynamicpanel(String dynamicpanel) { public void setDynamicpanel(String dynamicpanel) {
this.dynamicpanel = dynamicpanel; this.dynamicpanel = dynamicpanel;
} }
public String getDocdynamicfields() {
return docdynamicfields;
}
public void setDocdynamicfields(String docdynamicfields) {
this.docdynamicfields = docdynamicfields;
}
public String getDocdynamicpanel() {
return docdynamicpanel;
}
public void setDocdynamicpanel(String docdynamicpanel) {
this.docdynamicpanel = docdynamicpanel;
}
public String getDynamicsection() { public String getDynamicsection() {
return dynamicsection; return dynamicsection;
} }
@@ -119,70 +98,6 @@ public class PunchingHandler {
setOptionvals(null); setOptionvals(null);
} }
} }
public void DocDynamicHtml()
{
DBFunctions dbf=new DBFunctions(getErrCode());
dbf.setProcessFlag(true);
setDynamicfields("");
setDynamicpanel("");
setDocdynamicfields("");
setDocdynamicpanel("");
dbf.FetchRunQuery(74, (getPortfolioid()+GlobalClass.ColDelim+"75"+GlobalClass.ColDelim+"ADDDOC"+GlobalClass.ColDelim).split(GlobalClass.ColDelim));
if(dbf.isProcessFlag())
{
CommonFunctions Cfunc=new CommonFunctions();
String [][] ResultSet=dbf.getResultArray();
if(ResultSet.length > 0)
{
Cfunc.setGeneratedHtml("");
Cfunc.setPrevControl("");
Cfunc.setDynamicCtrls("");
for(int indx=0;indx<ResultSet.length;indx++)
{
String ControlVal="";
String secContainer="";
String Temp="";
secContainer=Cfunc.DynamicControls(ResultSet[indx], ControlVal);
if(secContainer.equals("Generalsec"))
{
Temp=getDynamicpanel();
setDynamicfields(getDynamicfields()+ResultSet[indx][2]+GlobalClass.ColDelim);
if(Temp.endsWith("</select></div></div></div>") && Cfunc.getGeneratedHtml().endsWith("</select></div></div></div>"))
{
if(!Cfunc.getGeneratedHtml().startsWith("<div class='widget'>"))
{
Temp=Temp.substring(0,Temp.lastIndexOf("</select></div></div></div>"));
}
}
setDynamicpanel(Temp+""+Cfunc.getGeneratedHtml());
}
if(secContainer.equals("Docsec"))
{
Temp=getDocdynamicpanel();
setDocdynamicfields(getDocdynamicfields()+ResultSet[indx][2]+GlobalClass.ColDelim);
if(Temp.endsWith("</select></div></div></div>") && Cfunc.getGeneratedHtml().endsWith("</select></div></div></div>"))
{
if(!Cfunc.getGeneratedHtml().startsWith("<div class='widget'>"))
{
Temp=Temp.substring(0,Temp.lastIndexOf("</select></div></div></div>"));
}
}
setDocdynamicpanel(Temp+""+Cfunc.getGeneratedHtml());
}
}
}
else
{
setProcessFlag(false);
setErrMsg(dbf.getErrMsg());
setErrDesc(dbf.getErrDesc());
}
}
}
public void DynamicHtml(String pageId) public void DynamicHtml(String pageId)
{ {
DBFunctions dbf=new DBFunctions(getErrCode()); DBFunctions dbf=new DBFunctions(getErrCode());
@@ -242,11 +157,6 @@ public class PunchingHandler {
setErrDesc(dbf.getErrDesc()); setErrDesc(dbf.getErrDesc());
} }
} }
public void AddEditDocs(String docType,String docHolder,String serviceProvider,String uniqueNo,String bankId,String yearMonth,String city,String vendorId,String uuId,String userId)
{
}
public String[][] loadCasesForAddrCorrection() { public String[][] loadCasesForAddrCorrection() {
String [][]resultArray = null; String [][]resultArray = null;
DBFunctions dbf=new DBFunctions(getErrCode()); DBFunctions dbf=new DBFunctions(getErrCode());

View File

@@ -14,4 +14,10 @@ public final class CloudQueryDefinitionProvider implements QueryDefinitionProvid
public QueryDefinition get(int queryId) { public QueryDefinition get(int queryId) {
return QueryDefinition.parse(queryId, provider.getQuery(queryId)); return QueryDefinition.parse(queryId, provider.getQuery(queryId));
} }
@Override
public QueryDefinition get(String queryKey) {
int diagnosticId = Math.max(1, queryKey.hashCode() & Integer.MAX_VALUE);
return QueryDefinition.parse(diagnosticId, provider.getQuery(queryKey));
}
} }

View File

@@ -19,4 +19,11 @@ public final class CloudQuerySource implements QuerySource {
.orElseThrow(() -> new QueryProviderException( .orElseThrow(() -> new QueryProviderException(
"Cloud query was empty: " + queryId)); "Cloud query was empty: " + queryId));
} }
@Override
public String fetch(String queryKey) {
return client.fetchQuery(queryKey).map(response -> response.query()).blockOptional()
.filter(query -> !query.isBlank())
.orElseThrow(() -> new QueryProviderException("Cloud query was empty: " + queryKey));
}
} }

View File

@@ -0,0 +1,21 @@
package matrix.nimble.query;
import java.util.Objects;
public final class DirectQueryProvider implements QueryProvider {
private final QuerySource source;
public DirectQueryProvider(QuerySource source) {
this.source = Objects.requireNonNull(source, "source");
}
@Override
public String getQuery(int queryId) {
return source.fetch(queryId);
}
@Override
public String getQuery(String queryKey) {
return source.fetch(queryKey);
}
}

View File

@@ -1,6 +1,10 @@
package matrix.nimble.query; package matrix.nimble.query;
@FunctionalInterface
public interface QueryProvider { public interface QueryProvider {
String getQuery(int queryId); String getQuery(int queryId);
default String getQuery(String queryKey) {
throw new UnsupportedOperationException("Query keys are not supported by this provider");
}
} }

View File

@@ -23,12 +23,14 @@ public class QueryProviderConfiguration implements DisposableBean {
OnPremRedisCacheService cache, OnPremRedisCacheService cache,
CloudIdentityClient cloudClient, CloudIdentityClient cloudClient,
CloudClientProperties cloudProperties, CloudClientProperties cloudProperties,
@Value("${CYGNUS_QUERY_CACHE_ENABLED:true}") boolean cacheEnabled,
@Value("${CYGNUS_QUERY_CACHE_AES_KEY:}") String configuredKey) { @Value("${CYGNUS_QUERY_CACHE_AES_KEY:}") String configuredKey) {
byte[] key = queryCacheKey(configuredKey, cloudProperties.clientAssertion()); QuerySource cloudSource = new CloudQuerySource(cloudClient);
installed = new RedisCachingQueryProvider( installed = cacheEnabled
cache, ? new RedisCachingQueryProvider(
new CloudQuerySource(cloudClient), cache, cloudSource, new AesGcmQueryCipher(
new AesGcmQueryCipher(key)); queryCacheKey(configuredKey, cloudProperties.clientAssertion())))
: new DirectQueryProvider(cloudSource);
QueryProviders.install(installed); QueryProviders.install(installed);
return installed; return installed;
} }

View File

@@ -4,4 +4,7 @@ package matrix.nimble.query;
public interface QuerySource { public interface QuerySource {
String fetch(int queryId); String fetch(int queryId);
default String fetch(String queryKey) {
throw new UnsupportedOperationException("Query keys are not supported by this source");
}
} }

View File

@@ -30,7 +30,18 @@ public final class RedisCachingQueryProvider implements QueryProvider {
@Override @Override
public String getQuery(int queryId) { public String getQuery(int queryId) {
String cacheKey = cacheKey(queryId); return get("id:" + cacheKey(queryId), () -> cloudSource.fetch(queryId));
}
@Override
public String getQuery(String queryKey) {
if (queryKey == null || !queryKey.matches("[A-Z][A-Z0-9_]{2,99}")) {
throw new IllegalArgumentException("Invalid query key");
}
return get("key:" + queryKey, () -> cloudSource.fetch(queryKey));
}
private String get(String cacheKey, java.util.function.Supplier<String> source) {
Optional<String> cached = cached(cacheKey); Optional<String> cached = cached(cacheKey);
if (cached.isPresent()) { if (cached.isPresent()) {
return cached.get(); return cached.get();
@@ -42,14 +53,14 @@ public final class RedisCachingQueryProvider implements QueryProvider {
return cached.get(); return cached.get();
} }
try { try {
String query = cloudSource.fetch(queryId); String query = source.get();
cache.put(cacheKey, cipher.encrypt(cacheKey, query), QUERY_TTL); cache.put(cacheKey, cipher.encrypt(cacheKey, query), QUERY_TTL);
return query; return query;
} catch (QueryProviderException exception) { } catch (QueryProviderException exception) {
throw exception; throw exception;
} catch (RuntimeException exception) { } catch (RuntimeException exception) {
throw new QueryProviderException( throw new QueryProviderException(
"Unable to retrieve query: " + queryId, exception); "Unable to retrieve query: " + cacheKey, exception);
} }
} }
} }

View File

@@ -0,0 +1,174 @@
package matrix.nimble.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.MGF1ParameterSpec;
import java.time.Duration;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import javax.crypto.spec.SecretKeySpec;
import lib.constants.ApplicationMessage;
import lib.exceptions.ApplicationException;
import lib.models.CaseSaveRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/** Thread-safe decryption for short-lived form envelopes created with Web Crypto. */
@Service
public final class PayloadCryptoService {
private static final Duration REQUEST_TTL = Duration.ofMinutes(5);
private static final int GCM_TAG_BITS = 128;
private final ObjectMapper objectMapper;
private final PrivateKey privateKey;
private final PublicKey publicKey;
private final String keyId;
private final Map<String, Instant> acceptedRequests = new ConcurrentHashMap<>();
public PayloadCryptoService(
ObjectMapper objectMapper,
@Value("${CYGNUS_PAYLOAD_PRIVATE_KEY:${CYGNUS_CASE_SAVE_PRIVATE_KEY:}}") String privateKeyLocation,
@Value("${CYGNUS_PAYLOAD_PUBLIC_KEY:${CYGNUS_CASE_SAVE_PUBLIC_KEY:}}") String publicKeyLocation) {
this.objectMapper = objectMapper;
KeyPair pair = loadOrGenerate(privateKeyLocation, publicKeyLocation);
this.privateKey = pair.getPrivate();
this.publicKey = pair.getPublic();
this.keyId = fingerprint(publicKey);
}
public String keyId() { return keyId; }
public String encodedPublicKey() {
return Base64.getUrlEncoder().withoutPadding().encodeToString(publicKey.getEncoded());
}
public <T> T decrypt(CaseSaveRequest request, Class<T> payloadType) {
validateEnvelope(request);
Instant now = Instant.now();
Instant submittedAt;
try {
submittedAt = Instant.parse(request.timestamp());
} catch (DateTimeParseException exception) {
throw invalid("Invalid request timestamp", exception);
}
if (submittedAt.isBefore(now.minus(REQUEST_TTL))
|| submittedAt.isAfter(now.plusSeconds(30))) {
throw invalid("Expired request payload");
}
discardExpired(now);
if (acceptedRequests.putIfAbsent(request.requestId(), now) != null) {
throw invalid("Duplicate request payload");
}
try {
Base64.Decoder decoder = Base64.getUrlDecoder();
Cipher keyCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
keyCipher.init(Cipher.DECRYPT_MODE, privateKey,
new OAEPParameterSpec("SHA-256", "MGF1",
MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
byte[] aesKey = keyCipher.doFinal(decoder.decode(request.encryptedKey()));
byte[] iv = decoder.decode(request.initializationVector());
if (iv.length != 12) throw invalid("Invalid initialization vector");
Cipher payloadCipher = Cipher.getInstance("AES/GCM/NoPadding");
payloadCipher.init(Cipher.DECRYPT_MODE,
new SecretKeySpec(aesKey, "AES"), new GCMParameterSpec(GCM_TAG_BITS, iv));
payloadCipher.updateAAD(aad(request));
byte[] json = payloadCipher.doFinal(decoder.decode(request.encryptedPayload()));
return objectMapper.readValue(json, payloadType);
} catch (ApplicationException exception) {
throw exception;
} catch (Exception exception) {
acceptedRequests.remove(request.requestId());
throw invalid("Unable to decrypt payload", exception);
}
}
private byte[] aad(CaseSaveRequest request) {
return String.join("|", request.keyId(), request.requestId(), request.timestamp())
.getBytes(StandardCharsets.UTF_8);
}
private void validateEnvelope(CaseSaveRequest request) {
if (request == null || blank(request.keyId()) || blank(request.encryptedKey())
|| blank(request.initializationVector()) || blank(request.encryptedPayload())
|| blank(request.requestId()) || blank(request.timestamp())) {
throw invalid("Incomplete encrypted request");
}
if (!keyId.equals(request.keyId())) throw invalid("Unsupported encryption key");
}
private void discardExpired(Instant now) {
Instant cutoff = now.minus(REQUEST_TTL);
acceptedRequests.entrySet().removeIf(entry -> entry.getValue().isBefore(cutoff));
}
private KeyPair loadOrGenerate(String privateLocation, String publicLocation) {
if (blank(privateLocation) && blank(publicLocation)) {
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(3072);
return generator.generateKeyPair();
} catch (Exception exception) {
throw new IllegalStateException("Unable to generate payload key pair", exception);
}
}
if (blank(privateLocation) || blank(publicLocation)) {
throw new IllegalStateException(
"Both CYGNUS_PAYLOAD_PRIVATE_KEY and CYGNUS_PAYLOAD_PUBLIC_KEY are required");
}
try {
KeyFactory factory = KeyFactory.getInstance("RSA");
return new KeyPair(
factory.generatePublic(new X509EncodedKeySpec(pem(publicLocation, "PUBLIC KEY"))),
factory.generatePrivate(new PKCS8EncodedKeySpec(pem(privateLocation, "PRIVATE KEY"))));
} catch (Exception exception) {
throw new IllegalStateException("Unable to load payload key pair", exception);
}
}
private byte[] pem(String location, String type) throws Exception {
String path = location.startsWith("file:") ? location.substring(5) : location;
String value = Files.readString(Path.of(path), StandardCharsets.US_ASCII)
.replace("-----BEGIN " + type + "-----", "")
.replace("-----END " + type + "-----", "")
.replaceAll("\\s", "");
return Base64.getDecoder().decode(value);
}
private String fingerprint(PublicKey key) {
try {
byte[] digest = MessageDigest.getInstance("SHA-256").digest(key.getEncoded());
return Base64.getUrlEncoder().withoutPadding().encodeToString(digest);
} catch (Exception exception) {
throw new IllegalStateException("Unable to identify payload key", exception);
}
}
private boolean blank(String value) { return value == null || value.isBlank(); }
private ApplicationException invalid(String technicalMessage) {
return new ApplicationException(ApplicationMessage.PAYLOAD_INVALID, technicalMessage);
}
private ApplicationException invalid(String technicalMessage, Throwable cause) {
return new ApplicationException(ApplicationMessage.PAYLOAD_INVALID, technicalMessage, cause);
}
}

View File

@@ -0,0 +1,16 @@
package matrix.nimble.security;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebJsonConfiguration {
@Bean
ObjectMapper webObjectMapper() {
return new ObjectMapper()
.findAndRegisterModules()
.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
}

View File

@@ -5,10 +5,14 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CommonFunctions { public class CommonFunctions {
private static final Pattern DYNAMIC_VALIDATION = Pattern.compile(
"(?i)validate\\s*\\(\\s*this\\s*,\\s*'([tf])'\\s*,\\s*'([^']*)");
private String ErrMsg; private String ErrMsg;
private String ErrCode; private String ErrCode;
private String ErrDesc; private String ErrDesc;
@@ -102,14 +106,15 @@ public class CommonFunctions {
} }
return GatewayList; return GatewayList;
} }
public String DynamicControls(String [] Controls,String ControlVal) public String DynamicControls(String [] Controls,String ControlVal)
{ {
String CtrlHtml=""; String CtrlHtml="";
String CtrlStyle=""; String CtrlStyle="";
String CtrlClass=""; String CtrlClass="";
String CtrlEvents=""; String CtrlEvents="";
String isSelected=""; String isSelected="";
String maxLength="maxlength"; String maxLength="maxlength";
String validationAttributes=dynamicValidationAttributes(Controls[9]);
String unit="px"; String unit="px";
setCtrlType(Controls[14]); setCtrlType(Controls[14]);
ControlVal=(ControlVal==null || ControlVal.equals("")) ? Controls[17] : ControlVal; ControlVal=(ControlVal==null || ControlVal.equals("")) ? Controls[17] : ControlVal;
@@ -151,11 +156,11 @@ public class CommonFunctions {
CtrlHtml=CtrlHtml+"</div><div class='inputcontainer'>"; CtrlHtml=CtrlHtml+"</div><div class='inputcontainer'>";
if(getCtrlType().equals("text")) if(getCtrlType().equals("text"))
{ {
CtrlHtml=CtrlHtml+"<input type=\"text\" id='"+Controls[2]+"' name='"+Controls[2]+"' "+maxLength+" "+CtrlEvents+" "+CtrlStyle+" "+CtrlClass+" value=\""+ControlVal+"\" />"; CtrlHtml=CtrlHtml+"<input type=\"text\" id='"+Controls[2]+"' name='"+Controls[2]+"' "+maxLength+" "+validationAttributes+" "+CtrlEvents+" "+CtrlStyle+" "+CtrlClass+" value=\""+ControlVal+"\" />";
} }
else if(getCtrlType().equals("checkbox")) else if(getCtrlType().equals("checkbox"))
{ {
CtrlHtml=CtrlHtml+"<input id='"+Controls[2]+"' name='"+Controls[2]+"' "+maxLength+" "+CtrlEvents+" "+CtrlStyle+" "+CtrlClass+" value='"+ControlVal+"' />"; CtrlHtml=CtrlHtml+"<input id='"+Controls[2]+"' name='"+Controls[2]+"' "+maxLength+" "+validationAttributes+" "+CtrlEvents+" "+CtrlStyle+" "+CtrlClass+" value='"+ControlVal+"' />";
} }
CtrlHtml=CtrlHtml+"</div></div>"; CtrlHtml=CtrlHtml+"</div></div>";
} }
@@ -167,7 +172,7 @@ public class CommonFunctions {
} }
CtrlHtml="<div class='widget'><div class='lblcontainer'>"+Controls[1]; CtrlHtml="<div class='widget'><div class='lblcontainer'>"+Controls[1];
CtrlHtml=CtrlHtml+"</div><div class='inputcontainer'>"; CtrlHtml=CtrlHtml+"</div><div class='inputcontainer'>";
CtrlHtml=CtrlHtml+"<textarea id='"+Controls[2]+"' name='"+Controls[2]+"' "+maxLength+" "+CtrlEvents+" "+CtrlStyle+" "+CtrlClass+" >"+ControlVal+"</textarea>"; CtrlHtml=CtrlHtml+"<textarea id='"+Controls[2]+"' name='"+Controls[2]+"' "+maxLength+" "+validationAttributes+" "+CtrlEvents+" "+CtrlStyle+" "+CtrlClass+" >"+ControlVal+"</textarea>";
CtrlHtml=CtrlHtml+"</div></div>"; CtrlHtml=CtrlHtml+"</div></div>";
} }
else if(getCtrlType().equals("select")) else if(getCtrlType().equals("select"))
@@ -194,7 +199,7 @@ public class CommonFunctions {
CtrlHtml="<div class='widget'><div class='lblcontainer'>"+Controls[1]; CtrlHtml="<div class='widget'><div class='lblcontainer'>"+Controls[1];
CtrlHtml=CtrlHtml+"</div><div class='inputcontainer'>"; CtrlHtml=CtrlHtml+"</div><div class='inputcontainer'>";
CtrlHtml=CtrlHtml+"<div "+CtrlClass+" id='div"+Controls[2]+"' "+CtrlStyle+" >"; CtrlHtml=CtrlHtml+"<div "+CtrlClass+" id='div"+Controls[2]+"' "+CtrlStyle+" >";
CtrlHtml=CtrlHtml+"<select id='"+Controls[2]+"' name='"+Controls[2]+"' "+CtrlEvents+" "+CtrlStyle1+" >"; CtrlHtml=CtrlHtml+"<select id='"+Controls[2]+"' name='"+Controls[2]+"' "+validationAttributes+" "+CtrlEvents+" "+CtrlStyle1+" >";
CtrlHtml=CtrlHtml+"<option value='-1' selected>NA</option>"; CtrlHtml=CtrlHtml+"<option value='-1' selected>NA</option>";
CtrlHtml=CtrlHtml+"<option value='"+Controls[19]+"' "+isSelected+" >"+Controls[19]+"</option></select></div></div></div>"; CtrlHtml=CtrlHtml+"<option value='"+Controls[19]+"' "+isSelected+" >"+Controls[19]+"</option></select></div></div></div>";
} }
@@ -211,8 +216,18 @@ public class CommonFunctions {
setGeneratedHtml(CtrlHtml); setGeneratedHtml(CtrlHtml);
setDynamicCtrls(getDynamicCtrls()+Controls[2]+GlobalClass.ColDelim); setDynamicCtrls(getDynamicCtrls()+Controls[2]+GlobalClass.ColDelim);
} }
return Controls[4]; return Controls[4];
} }
private String dynamicValidationAttributes(String onBlur)
{
if(onBlur==null || onBlur.isBlank()) return "";
Matcher matcher=DYNAMIC_VALIDATION.matcher(onBlur);
if(!matcher.find()) return "";
String format=matcher.group(2).trim().replaceFirst("[^A-Za-z0-9]+$", "");
return "data-validation-required='"+(matcher.group(1).equalsIgnoreCase("t") ? "true" : "false")+
"' data-validation-format='"+format+"'";
}
public String DesignControls(String ControlType,String Controlid,String TypeScript,String ValidationScript,String Style, String CssClass,String Fieldid,DBFunctions DBFunc,StringFunctions SFunc,String ControlVal) public String DesignControls(String ControlType,String Controlid,String TypeScript,String ValidationScript,String Style, String CssClass,String Fieldid,DBFunctions DBFunc,StringFunctions SFunc,String ControlVal)
{ {
String HtmlControl=""; String HtmlControl="";

View File

@@ -2,14 +2,14 @@ package matrix.services.commons;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import lib.models.ErrorDetails; import lib.models.MessageDetails;
import matrix.nimble.model.Session; import matrix.nimble.model.Session;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
@Service @Service
public class CommonErrorService { public class CommonErrorService {
public static final String ERROR_ATTRIBUTE = "errorDetails"; public static final String ERROR_ATTRIBUTE = "messageDetails";
private final CommonService commonService; private final CommonService commonService;
public CommonErrorService(CommonService commonService) { public CommonErrorService(CommonService commonService) {
@@ -20,9 +20,9 @@ public class CommonErrorService {
ModelMap model, ModelMap model,
HttpServletResponse response, HttpServletResponse response,
HttpSession httpSession, HttpSession httpSession,
ErrorDetails errorDetails) { MessageDetails messageDetails) {
response.setStatus(errorDetails.getHttpStatus()); response.setStatus(messageDetails.getHttpStatus());
model.addAttribute(ERROR_ATTRIBUTE, errorDetails); model.addAttribute(ERROR_ATTRIBUTE, messageDetails);
Session session = commonService.getSession(httpSession); Session session = commonService.getSession(httpSession);
if (session != null) { if (session != null) {

View File

@@ -3,6 +3,7 @@ package matrix.services.commons;
import com.cygnus.db.CygnusDbExecutor; import com.cygnus.db.CygnusDbExecutor;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSession;
import lib.models.Option; import lib.models.Option;
import lib.models.UserSession;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -15,6 +16,7 @@ import org.springframework.stereotype.Service;
@Service @Service
public class CommonService { public class CommonService {
public static final String SESSION_ATTRIBUTE = "Sessvals"; public static final String SESSION_ATTRIBUTE = "Sessvals";
public static final String USER_SESSION_ATTRIBUTE = "userSession";
private static final Pattern MENU_COMMAND = Pattern.compile( private static final Pattern MENU_COMMAND = Pattern.compile(
"SubmitMenuCommand\\(\\s*'([^']+)'\\s*,", "SubmitMenuCommand\\(\\s*'([^']+)'\\s*,",
@@ -46,6 +48,20 @@ public class CommonService {
httpSession.setAttribute(SESSION_ATTRIBUTE, Objects.requireNonNull(session, "session")); httpSession.setAttribute(SESSION_ATTRIBUTE, Objects.requireNonNull(session, "session"));
} }
public UserSession getUserSession(HttpSession httpSession) {
if (httpSession == null) {
return null;
}
Object value = httpSession.getAttribute(USER_SESSION_ATTRIBUTE);
return value instanceof UserSession session ? session : null;
}
public void storeUserSession(HttpSession httpSession, UserSession session) {
Objects.requireNonNull(httpSession, "httpSession");
httpSession.setAttribute(
USER_SESSION_ATTRIBUTE, Objects.requireNonNull(session, "session"));
}
public boolean hasPageAccess(HttpSession httpSession, String pageRoute) { public boolean hasPageAccess(HttpSession httpSession, String pageRoute) {
return hasPageAccess(getSession(httpSession), pageRoute); return hasPageAccess(getSession(httpSession), pageRoute);
} }
@@ -69,6 +85,29 @@ public class CommonService {
return false; return false;
} }
public boolean hasPageAccess(UserSession session, String pageRoute) {
return session != null && hasPageAccess(session.getMenuHtml(), pageRoute);
}
private boolean hasPageAccess(String menuHtml, String pageRoute) {
if (menuHtml == null) {
return false;
}
String requiredRoute = normalizeRoute(pageRoute);
if (requiredRoute.isEmpty()) {
return false;
}
Matcher matcher = MENU_COMMAND.matcher(menuHtml);
while (matcher.find()) {
if (normalizeRoute(matcher.group(1)).equals(requiredRoute)) {
return true;
}
}
return false;
}
private String normalizeRoute(String route) { private String normalizeRoute(String route) {
if (route == null) { if (route == null) {
return ""; return "";

View File

@@ -1,19 +1,37 @@
package matrix.services.edp; package matrix.services.edp;
import com.cygnus.db.CygnusDbExecutor;
import com.cygnus.db.RowView;
import com.cygnus.db.SqlArrayParameter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.sql.SQLException;
import java.sql.Date;
import java.time.LocalDate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import lib.models.ApplicationDetails;
import lib.models.CasePunching; import lib.models.CasePunching;
import lib.models.ErrorDetails; import lib.models.ApplicationSaveResult;
import lib.models.MessageDetails;
import lib.models.Option; import lib.models.Option;
import lib.constants.ApplicationError; import lib.models.PunchedRecordsData;
import lib.models.DuplicateDetailsData;
import lib.models.EditCaseSummary;
import lib.models.LocalityData;
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.edp.punching.model.PunchingHandler;
import matrix.nimble.utilities.CommonFunctions;
import matrix.nimble.utilities.GlobalClass; import matrix.nimble.utilities.GlobalClass;
import matrix.services.commons.CommonService; import matrix.services.commons.CommonService;
@@ -25,17 +43,294 @@ public class PunchingService {
private static final String PRODUCT = "product."; private static final String PRODUCT = "product.";
private static final String CITY = "city."; private static final String CITY = "city.";
private static final String APPLICATION_TYPE = "applicationType."; private static final String APPLICATION_TYPE = "applicationType.";
private static final String DATABASE_APPLICATION_TYPE = "apptype.";
private static final String CATEGORY = "category."; private static final String CATEGORY = "category.";
private static final Short ACTIVE = Short.valueOf((short) 1);
private static final int PUNCHED_RECORDS_QUERY = 24;
private static final int EDIT_CASES_QUERY = 23;
private static final int EDIT_CASE_PORTFOLIOS_QUERY = 249;
private static final int LOCALITY_QUERY = 13;
private static final int RESIDENCE_DETAILS_QUERY = 19;
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 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 final CommonService commonService; private final CommonService commonService;
private final CygnusDbExecutor dbExecutor;
private final ObjectMapper objectMapper;
public PunchingService(CommonService commonService) { public PunchingService(CommonService commonService) {
this.commonService = commonService; this.commonService = commonService;
this.dbExecutor = null;
this.objectMapper = null;
} }
@Autowired
public PunchingService(
CommonService commonService, CygnusDbExecutor dbExecutor, ObjectMapper objectMapper) {
this.commonService = commonService;
this.dbExecutor = dbExecutor;
this.objectMapper = objectMapper;
}
public ApplicationSaveResult saveApplication(ApplicationDetails details, UserSession session) {
if (dbExecutor == null || objectMapper == null) {
throw new IllegalStateException("Application-save dependencies are not configured");
}
validate(details, session);
sanitizeDynamicFields(details);
try {
String json = objectMapper.writeValueAsString(details);
ApplicationSaveResult result = dbExecutor.procedure("APPLICATION_SAVE",
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");
}
return result;
} catch (JsonProcessingException exception) {
throw new ApplicationException(
ApplicationMessage.PAYLOAD_INVALID, "Unable to serialize application details", exception);
} catch (ApplicationException exception) {
throw exception;
} catch (RuntimeException exception) {
throw databaseFailure(exception);
}
}
public List<Option> loadEditCasePortfolios(UserSession session) {
requireSessionScope(session);
return commonService.getOptions(EDIT_CASE_PORTFOLIOS_QUERY, new Object[] {
session.getCompanyId(), session.getBranchId(), session.getUserId(),
session.getUserId(), ACTIVE
});
}
public List<EditCaseSummary> loadEditableCases(Short portfolioId, UserSession session) {
requireSessionScope(session);
if (portfolioId == null || portfolioId <= 0) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Portfolio is required");
}
try {
return dbExecutor.query(EDIT_CASES_QUERY, new Object[] {
portfolioId, session.getCompanyId(), session.getBranchId()
}, EditCaseSummary.class);
} catch (RuntimeException exception) {
throw databaseFailure(exception);
}
}
private void requireSessionScope(UserSession session) {
if (session == null || session.getCompanyId() == null || session.getBranchId() == null
|| session.getUserId() == null) {
throw new ApplicationException(
ApplicationMessage.SESSION_REQUIRED, "Authenticated session scope is required");
}
if (dbExecutor == null) {
throw new IllegalStateException("Database dependencies are not configured");
}
}
public PunchedRecordsData loadPunchedRecords(
Short portfolioId, String documentCaseId, UserSession session) {
if (dbExecutor == null || objectMapper == null) {
throw new IllegalStateException("Punched-record dependencies are not configured");
}
if (portfolioId == null || portfolioId <= 0 || session == null) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Portfolio is required");
}
String caseUuid = documentCaseId != null && documentCaseId.trim().length() > 20
? documentCaseId.trim() : "";
try {
List<RowView> rows = dbExecutor.query(PUNCHED_RECORDS_QUERY, new Object[] {
caseUuid, caseUuid, caseUuid, portfolioId,
session.getCompanyId(), session.getBranchId()
});
return new PunchedRecordsData(rows.stream().map(this::toPunchedRecord).toList());
} catch (ApplicationException exception) {
throw exception;
} catch (RuntimeException exception) {
throw databaseReadFailure(exception);
}
}
public DuplicateDetailsData findDuplicateDetails(
String applicationNumber, Short portfolioId, Integer queryId, UserSession session) {
if (dbExecutor == null) {
throw new IllegalStateException("Duplicate-detail dependencies are not configured");
}
if (blank(applicationNumber) || portfolioId == null || portfolioId <= 0
|| queryId == null || session == null) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Duplicate search details are invalid");
}
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()};
case PROPERTY_DETAILS_QUERY ->
new Object[] {applicationNumber.trim(), portfolioId,
session.getCompanyId(), session.getBranchId(), receivedDate};
default -> throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Unsupported duplicate search type");
};
try {
List<Map<String, Object>> records = dbExecutor.query(queryId, parameters).stream()
.map(row -> {
Map<String, Object> record = new LinkedHashMap<>();
row.asMap().forEach((name, value) -> record.put(name, value == null ? "" : value));
return record;
})
.toList();
return new DuplicateDetailsData(records);
} catch (ApplicationException exception) {
throw exception;
} catch (RuntimeException exception) {
throw databaseFailure(exception);
}
}
public LocalityData findLocalities(String city, String letters, UserSession session) {
if (dbExecutor == null) {
throw new IllegalStateException("Locality dependencies are not configured");
}
String normalizedCity = city == null ? "-1" : city.trim();
String prefix = letters == null ? "" : letters.trim();
if (session == null || session.getBranchId() == null || prefix.isEmpty()
|| prefix.length() > 50 || normalizedCity.length() > 100) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Locality search details are invalid");
}
try {
List<LocalityOption> localities = dbExecutor.query(LOCALITY_QUERY, new Object[] {
session.getBranchId(), prefix, normalizedCity, normalizedCity
}).stream().map(row -> new LocalityOption(
row.get("id", Integer.class), rowText(row, "location"),
rowText(row, "pincode").trim(), rowText(row, "city"))).toList();
return new LocalityData(localities);
} catch (ApplicationException exception) {
throw exception;
} catch (RuntimeException exception) {
throw new ApplicationException(
ApplicationMessage.INTERNAL_SERVER_ERROR, "Locality lookup failed", exception);
}
}
private String rowText(RowView row, String column) {
Object value = row.get(column);
return value == null ? "" : value.toString();
}
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);
});
Object dynamicValue = row.get("dynamic_fields");
if (dynamicValue == null || dynamicValue.toString().isBlank()) return record;
try {
Map<String, Object> dynamicFields = objectMapper.readValue(
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);
}
});
return record;
} catch (JsonProcessingException exception) {
throw new ApplicationException(
ApplicationMessage.INTERNAL_SERVER_ERROR,
"Punched-record dynamic fields are invalid", exception);
}
}
private void validate(ApplicationDetails details, UserSession session) {
if (details == null || session == null || details.getPortfolioId() == null
|| details.getPortfolioId() <= 0) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Portfolio is required");
}
if (details.getBankBranchId() == null || details.getBankBranchId() <= 0) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Bank branch is required");
}
if (blank(details.getApplicationNumber()) || blank(details.getProduct())
|| blank(details.getCustomerName()) || blank(details.getApplicationType())) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, "Required application fields are missing");
}
if (!Boolean.TRUE.equals(details.getResidenceVerification())
&& !Boolean.TRUE.equals(details.getResidenceTelephoneVerification())
&& !Boolean.TRUE.equals(details.getOfficeVerification())
&& !Boolean.TRUE.equals(details.getOfficeTelephoneVerification())
&& !Boolean.TRUE.equals(details.getPropertyVerification())
&& !Boolean.TRUE.equals(details.getReferenceVerification())
&& !Boolean.TRUE.equals(details.getDocumentVerification())) {
throw new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED,
"At least one verification type is required");
}
}
private void sanitizeDynamicFields(ApplicationDetails details) {
if (details.getDynamicFields() == null || details.getDynamicFields().isEmpty()) {
details.setDynamicFields(new LinkedHashMap<>());
return;
}
Map<String, String> allowed = new LinkedHashMap<>();
details.getDynamicFields().forEach((name, value) -> {
if (name != null && DYNAMIC_FIELD.matcher(name).matches()) {
allowed.put(name, value == null ? null : value.trim());
}
});
details.setDynamicFields(allowed);
}
private ApplicationException databaseFailure(RuntimeException exception) {
Throwable cause = exception;
while (cause != null) {
if (cause instanceof SQLException sqlException) {
return switch (sqlException.getSQLState()) {
case "42501" -> new ApplicationException(
ApplicationMessage.APPLICATION_ACCESS_DENIED, sqlException.getMessage(), exception);
case "22023", "23502", "23503" -> new ApplicationException(
ApplicationMessage.APPLICATION_VALIDATION_FAILED, sqlException.getMessage(), exception);
case "23505" -> new ApplicationException(
ApplicationMessage.APPLICATION_SAVE_CONFLICT, sqlException.getMessage(), exception);
default -> new ApplicationException(
ApplicationMessage.APPLICATION_SAVE_FAILED, "Database save failed", exception);
};
}
cause = cause.getCause();
}
return new ApplicationException(
ApplicationMessage.APPLICATION_SAVE_FAILED, "Database save failed", exception);
}
private ApplicationException databaseReadFailure(RuntimeException exception) {
return new ApplicationException(
ApplicationMessage.APPLICATION_LOAD_FAILED,
"Database read failed", exception);
}
private boolean blank(String value) { return value == null || value.isBlank(); }
public CasePunching init( public CasePunching init(
String branchId, Short branchId,
String userId, Short userId,
String verificationCaseId, String verificationCaseId,
String documentCaseId) { String documentCaseId) {
PunchingHandler punchingHandler = new PunchingHandler(); PunchingHandler punchingHandler = new PunchingHandler();
@@ -43,16 +338,15 @@ public class PunchingService {
CasePunching casePunching = new CasePunching(); CasePunching casePunching = new CasePunching();
Map<String, List<Option>> options = new LinkedHashMap<>(); Map<String, List<Option>> options = new LinkedHashMap<>();
Short databaseBranchId = Short.valueOf(branchId.trim());
List<Option> portfolios = commonService.getOptions( List<Option> portfolios = commonService.getOptions(
3, new Object[] { databaseBranchId, Short.valueOf((short) 1) }); 3, new Object[] { branchId, ACTIVE });
addOptions(options, PORTFOLIO, portfolios); addOptions(options, PORTFOLIO, portfolios);
casePunching.setOptions(Collections.unmodifiableMap(options)); casePunching.setOptions(freezeOptions(options));
casePunching.setVisibleSections(List.of()); casePunching.setVisibleSections(List.of());
casePunching.setPortfolioId(-1); casePunching.setPortfolioId((short) -1);
casePunching.setFormMode(0); casePunching.setFormMode(0);
casePunching.setUserId(userId); casePunching.setUserId(Short.toString(userId));
casePunching.setDynamicFields(""); casePunching.setDynamicFields("");
casePunching.setDynamicHtml(""); casePunching.setDynamicHtml("");
casePunching.setVerificationCaseId(verificationCaseId); casePunching.setVerificationCaseId(verificationCaseId);
@@ -60,31 +354,31 @@ public class PunchingService {
return casePunching; return casePunching;
} }
public CasePunching addCase( public CasePunching prepareNewApplication(
CasePunching submitted, CasePunching submitted,
String branchIds, Short branchId,
String userId) { Short companyId,
Short userId) {
CasePunching result = new CasePunching(); CasePunching result = new CasePunching();
result.setPortfolioId(submitted.getPortfolioId()); result.setPortfolioId(submitted.getPortfolioId());
result.setFormMode(1); result.setFormMode(1);
result.setUserId(userId); result.setUserId(Short.toString(userId));
result.setVerificationCaseId(submitted.getVerificationCaseId()); result.setVerificationCaseId(submitted.getVerificationCaseId());
result.setDocumentCaseId("xxx"); result.setDocumentCaseId("xxx");
if (submitted.getPortfolioId() == null || submitted.getPortfolioId() <= 0) { if (submitted.getPortfolioId() == null || submitted.getPortfolioId() <= 0) {
result.setOptions(Collections.emptyMap()); result.setOptions(Map.of());
result.setVisibleSections(List.of()); result.setVisibleSections(List.of());
result.setDynamicFields(""); result.setDynamicFields("");
result.setDynamicHtml(""); result.setDynamicHtml("");
result.setErrorDetails(new ErrorDetails(ApplicationError.BAD_REQUEST)); result.setMessageDetails(new MessageDetails(ApplicationMessage.BAD_REQUEST));
return result; return result;
} }
String portfolioId = submitted.getPortfolioId().toString(); Short portfolioId = submitted.getPortfolioId();
PunchingHandler punchingHandler = new PunchingHandler(); PunchingHandler punchingHandler = new PunchingHandler();
CommonFunctions commonFunctions = new CommonFunctions();
punchingHandler.setErrCode("1001"); punchingHandler.setErrCode("1001");
punchingHandler.setPortfolioid(portfolioId); punchingHandler.setPortfolioid(Short.toString(portfolioId));
punchingHandler.setProcessFlag(true); punchingHandler.setProcessFlag(true);
punchingHandler.DynamicHtml("10"); punchingHandler.DynamicHtml("10");
@@ -98,68 +392,43 @@ public class PunchingService {
result.setDynamicFields(""); result.setDynamicFields("");
result.setDynamicHtml(""); result.setDynamicHtml("");
result.setVisibleSections(List.of()); result.setVisibleSections(List.of());
result.setErrorDetails(new ErrorDetails(ApplicationError.INTERNAL_SERVER_ERROR)); result.setMessageDetails(new MessageDetails(ApplicationMessage.INTERNAL_SERVER_ERROR));
} }
Map<String, String> options = new LinkedHashMap<>(); result.setOptions(loadOptions(branchId, companyId, portfolioId));
punchingHandler.GetDDValues(3, branchIds.split(GlobalClass.ColDelim));
addOptions(options, PORTFOLIO, punchingHandler.getOptionvals());
punchingHandler.GetDDValues(4, new String[] { portfolioId });
addOptions(options, BRANCH, punchingHandler.getOptionvals());
punchingHandler.GetDDValues(5,
(branchIds + GlobalClass.ColDelim
+ "op.description='CITY' or op.description='APPTYPE'"
+ GlobalClass.ColDelim).split(GlobalClass.ColDelim));
String[][] generalOptions = punchingHandler.getOptionvals();
if (generalOptions != null) {
addOptions(options, CITY,
commonFunctions.GetSubArray("CITY", 2, generalOptions));
addOptions(options, APPLICATION_TYPE,
commonFunctions.GetSubArray("APPTYPE", 2, generalOptions));
}
punchingHandler.GetDDValues(70,
(portfolioId + GlobalClass.ColDelim
+ "op.description='CATEGORY' or op.description='PRODUCT'"
+ GlobalClass.ColDelim).split(GlobalClass.ColDelim));
String[][] portfolioOptions = punchingHandler.getOptionvals();
if (portfolioOptions != null) {
addOptions(options, PRODUCT,
commonFunctions.GetSubArray("PRODUCT", 2, portfolioOptions));
addOptions(options, CATEGORY,
commonFunctions.GetSubArray("CATEGORY", 2, portfolioOptions));
}
result.setOptionsl(Collections.unmodifiableMap(options));
return result; return result;
} }
public CasePunching editCase( Map<String, List<Option>> loadOptions(
Integer portfolioId, Short branchId, Short companyId, Short portfolioId) {
Map<String, List<Option>> options = new LinkedHashMap<>();
addOptions(options, PORTFOLIO, commonService.getOptions(
3, new Object[] {branchId, ACTIVE}));
addOptions(options, BRANCH, commonService.getOptions(
4, new Object[] {portfolioId, ACTIVE}));
addGroupedOptions(options, commonService.getOptions(
5, new Object[] {companyId, GENERAL_OPTION_TYPES}));
addGroupedOptions(options, commonService.getOptions(
70, new Object[] {portfolioId, PORTFOLIO_OPTION_TYPES}));
return freezeOptions(options);
}
public CasePunching prepareApplicationEdit(
Short portfolioId,
String documentCaseId, String documentCaseId,
String branchIds, Short branchId,
String userId) { Short companyId,
Short userId) {
CasePunching submitted = new CasePunching(); CasePunching submitted = new CasePunching();
submitted.setPortfolioId(portfolioId); submitted.setPortfolioId(portfolioId);
submitted.setDocumentCaseId(documentCaseId); submitted.setDocumentCaseId(documentCaseId);
CasePunching result = addCase(submitted, branchIds, userId); CasePunching result = prepareNewApplication(submitted, branchId, companyId, userId);
result.setFormMode(2); result.setFormMode(2);
result.setDocumentCaseId(documentCaseId); result.setDocumentCaseId(documentCaseId);
return result; return result;
} }
private void addOptions(Map<String, String> options, String prefix, String[][] values) {
if (values == null) {
return;
}
for (String[] value : values) {
if (value != null && value.length >= 2 && value[0] != null) {
options.put(prefix + value[0], value[1] == null ? "" : value[1]);
}
}
}
private void addOptions(Map<String, List<Option>> options, String prefix, List<Option> values) { private void addOptions(Map<String, List<Option>> options, String prefix, List<Option> values) {
if (values == null || values.isEmpty()) { if (values == null || values.isEmpty()) {
return; return;
@@ -178,6 +447,45 @@ public class PunchingService {
} }
} }
private void addGroupedOptions(Map<String, List<Option>> options, List<Option> values) {
if (values == null || values.isEmpty()) {
return;
}
for (Option value : values) {
if (value == null || value.getValue() == null) {
continue;
}
String group = normalizeGroup(value.getGroup());
if (group == null) {
continue;
}
options.computeIfAbsent(group, ignored -> new java.util.ArrayList<>()).add(value);
}
}
private String normalizeGroup(String group) {
if (group == null || group.isBlank()) {
return null;
}
String normalized = group.trim();
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;
return null;
}
private Map<String, List<Option>> freezeOptions(Map<String, List<Option>> options) {
if (options.isEmpty()) {
return Map.of();
}
Map<String, List<Option>> immutable = new LinkedHashMap<>(options.size());
options.forEach((group, values) -> immutable.put(group, List.copyOf(values)));
return Collections.unmodifiableMap(immutable);
}
private List<String> toVisibleSections(String sections) { private List<String> toVisibleSections(String sections) {
if (sections == null || sections.isBlank()) { if (sections == null || sections.isBlank()) {
return List.of(); return List.of();

View File

@@ -310,7 +310,8 @@ class RoleVisibleBatchMigrationTest {
Path.of("build/WebContent/WEB-INF/app/operation/tools").resolve(page)); Path.of("build/WebContent/WEB-INF/app/operation/tools").resolve(page));
assertTrue(content.contains("matrix-shell matrix-tool-workspace"), page); assertTrue(content.contains("matrix-shell matrix-tool-workspace"), page);
assertTrue(content.contains("tool-workspace-v3.css"), page); assertTrue(content.contains("tool-workspace-v3.css"), page);
assertTrue(content.contains("Sessvals.menuHtml"), page); assertTrue(content.contains("Sessvals.menuHtml")
|| content.contains("sessionScope.userSession.menuHtml"), page);
assertFalse(content.contains("z-index:-1"), page); assertFalse(content.contains("z-index:-1"), page);
assertFalse(content.contains("centerDivBoth(\"formcontainer\""), page); assertFalse(content.contains("centerDivBoth(\"formcontainer\""), page);
} }
@@ -501,34 +502,22 @@ class RoleVisibleBatchMigrationTest {
assertFalse(documents.contains("z-index:-1")); assertFalse(documents.contains("z-index:-1"));
Path punching = Path.of("build/WebContent/WEB-INF/app/edp/punching"); Path punching = Path.of("build/WebContent/WEB-INF/app/edp/punching");
for (String page : List.of("addcases.jsp", "initcase.jsp", "initdocs.jsp")) { for (String page : List.of("initcase.jsp")) {
String content = Files.readString(punching.resolve(page)); String content = Files.readString(punching.resolve(page));
assertTrue(content.contains("matrix-tool-workspace matrix-punch-workspace"), page); assertTrue(content.contains("matrix-tool-workspace matrix-punch-workspace"), page);
assertTrue(content.contains("punch-workspace-v3.css"), page); assertTrue(content.contains("punch-workspace-v3.css"), page);
assertTrue(content.contains("Sessvals.menuHtml"), page); assertTrue(content.contains("Sessvals.menuHtml")
|| content.contains("sessionScope.userSession.menuHtml"), page);
assertFalse(content.contains("z-index:-1"), page); assertFalse(content.contains("z-index:-1"), page);
assertFalse(content.contains("centerDivBoth(\"formcontainer\""), page); assertFalse(content.contains("centerDivBoth(\"formcontainer\""), page);
} }
String addCases = Files.readString(punching.resolve("addcases.jsp"));
assertTrue(addCases.contains("ValidateSubmitForm('caseDetails')"));
assertTrue(addCases.contains("FindSameDet(this,'R','ResiPhone')"));
assertTrue(addCases.contains("matrix-dialog-child.js"));
assertTrue(addCases.contains("MatrixDialog.close(0)"));
assertTrue(addCases.contains("MatrixDialog.close(1)"));
assertFalse(addCases.contains("window.returnValue"));
assertFalse(addCases.contains("window.close()"));
String initialCase = Files.readString(punching.resolve("initcase.jsp")); String initialCase = Files.readString(punching.resolve("initcase.jsp"));
assertTrue(initialCase.contains("GotoRecord(this,'recno')")); assertTrue(initialCase.contains("GotoRecord(this,'recno')"));
assertTrue(initialCase.contains("ValidateSubmitForm('casedetails')")); assertTrue(initialCase.contains("CygnusInitiation.save(event)"));
assertTrue(initialCase.contains("/matrix/js/edp/punching/initiation.js"));
assertTrue(initialCase.contains("AddNewRecord()")); assertTrue(initialCase.contains("AddNewRecord()"));
String initialDocs = Files.readString(punching.resolve("initdocs.jsp"));
assertTrue(initialDocs.contains("EditBasicDetails()"));
assertTrue(initialDocs.contains("AddDocs()"));
assertTrue(initialDocs.contains("AddNewDoc()"));
String editCases = Files.readString(punching.resolve("editcases.jsp")); String editCases = Files.readString(punching.resolve("editcases.jsp"));
assertTrue(editCases.contains("matrix-tool-workspace")); assertTrue(editCases.contains("matrix-tool-workspace"));
assertTrue(editCases.contains("SubmitForm('caselist','_parent','caseGrid')")); assertTrue(editCases.contains("SubmitForm('caselist','_parent','caseGrid')"));
@@ -551,7 +540,7 @@ class RoleVisibleBatchMigrationTest {
assertTrue(workspace.contains("left: auto !important")); assertTrue(workspace.contains("left: auto !important"));
Path punching = Path.of("build/WebContent/WEB-INF/app/edp/punching"); Path punching = Path.of("build/WebContent/WEB-INF/app/edp/punching");
for (String page : List.of("addcases.jsp", "initcase.jsp", "initdocs.jsp")) { for (String page : List.of("initcase.jsp")) {
String content = Files.readString(punching.resolve(page)); String content = Files.readString(punching.resolve(page));
assertTrue(content.contains("matrix-add-cases"), page); assertTrue(content.contains("matrix-add-cases"), page);
assertTrue(content.contains("add-cases-v4.css"), page); assertTrue(content.contains("add-cases-v4.css"), page);

View File

@@ -5,11 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import jakarta.servlet.http.HttpSession;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import matrix.nimble.controller.Ajax; import matrix.nimble.edp.punching.controllers.PunchingController;
class SpringWebContextTest { class SpringWebContextTest {
@@ -33,8 +34,8 @@ class SpringWebContextTest {
@Test @Test
void requestParameterNamesAreRetained() throws Exception { void requestParameterNamesAreRetained() throws Exception {
Method method = Ajax.class.getMethod( Method method = PunchingController.class.getMethod(
"PunchedRecords", String.class, String.class, String.class); "punchedRecords", Short.class, String.class, HttpSession.class);
assertTrue(method.getParameters()[0].isNamePresent()); assertTrue(method.getParameters()[0].isNamePresent());
assertTrue(method.getParameters()[1].isNamePresent()); assertTrue(method.getParameters()[1].isNamePresent());

View File

@@ -8,13 +8,13 @@ import com.cygnus.client.model.CloudIdentitySession;
import com.cygnus.client.model.CloudMenuItem; import com.cygnus.client.model.CloudMenuItem;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
import matrix.nimble.model.Session; import lib.models.UserSession;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
class CloudSessionMapperTest { class CloudSessionMapperTest {
@Test @Test
void mapsCloudIdentityAndStructuredMenuToLegacySession() { void mapsCloudIdentityAndStructuredMenuToTypedSession() {
CloudIdentitySession identity = new CloudIdentitySession( CloudIdentitySession identity = new CloudIdentitySession(
(short) 17, (short) 17,
"maddy", "maddy",
@@ -37,9 +37,9 @@ class CloudSessionMapperTest {
(short) 11, "Scanning", "scanreporting", (short) 10, (short) 11, "Scanning", "scanreporting", (short) 10,
(short) 1, "111", "_parent", ""))); (short) 1, "111", "_parent", "")));
Session session = new CloudSessionMapper(new SessionMenuRenderer()).map(identity); UserSession session = new CloudSessionMapper(new SessionMenuRenderer()).map(identity);
assertEquals("17", session.getUserID()); assertEquals((short) 17, session.getUserId());
assertEquals("maddy", session.getUsername()); assertEquals("maddy", session.getUsername());
assertEquals("Operations", session.getUserGroupName()); assertEquals("Operations", session.getUserGroupName());
assertEquals("Mayapuri", session.getBranchName()); assertEquals("Mayapuri", session.getBranchName());
@@ -49,4 +49,19 @@ class CloudSessionMapperTest {
assertTrue(session.getMenuHtml().contains("Scanning")); assertTrue(session.getMenuHtml().contains("Scanning"));
assertTrue(session.getMenuHtml().contains("scanreporting")); assertTrue(session.getMenuHtml().contains("scanreporting"));
} }
@Test
void createsLegacyProjectionWithoutLosingIdentityValues() {
CloudIdentitySession identity = new CloudIdentitySession(
(short) 17, "maddy", "Maddy", (short) 5, "Operations",
(short) 9, "Mayapuri", "MYP", "Delhi", (short) 2,
"Matrix", "MCR", Instant.parse("2026-07-23T06:30:00Z"), List.of());
CloudSessionMapper mapper = new CloudSessionMapper(new SessionMenuRenderer());
matrix.nimble.model.Session legacy = mapper.toLegacy(mapper.map(identity));
assertEquals("17", legacy.getUserID());
assertEquals("9", legacy.getBranchID());
assertEquals("2", legacy.getCompanyID());
}
} }

View File

@@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import matrix.nimble.model.Session; import lib.models.UserSession;
import matrix.services.commons.CommonErrorService; import matrix.services.commons.CommonErrorService;
import matrix.services.commons.CommonService; import matrix.services.commons.CommonService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -20,8 +20,8 @@ class AbstractAuthenticatedControllerTest {
@Test @Test
void grantsAConfiguredMenuRoute() { void grantsAConfiguredMenuRoute() {
MockHttpSession httpSession = new MockHttpSession(); MockHttpSession httpSession = new MockHttpSession();
Session session = sessionWithRoute("initview"); UserSession session = sessionWithRoute("initview");
commonService.storeSession(httpSession, session); commonService.storeUserSession(httpSession, session);
AbstractAuthenticatedController.PageAuthorization result = controller.authorize( AbstractAuthenticatedController.PageAuthorization result = controller.authorize(
"initview", new ModelMap(), httpSession, new MockHttpServletResponse()); "initview", new ModelMap(), httpSession, new MockHttpServletResponse());
@@ -39,7 +39,7 @@ class AbstractAuthenticatedControllerTest {
assertEquals(401, noSessionResponse.getStatus()); assertEquals(401, noSessionResponse.getStatus());
MockHttpSession httpSession = new MockHttpSession(); MockHttpSession httpSession = new MockHttpSession();
commonService.storeSession(httpSession, sessionWithRoute("dashboard")); commonService.storeUserSession(httpSession, sessionWithRoute("dashboard"));
MockHttpServletResponse deniedResponse = new MockHttpServletResponse(); MockHttpServletResponse deniedResponse = new MockHttpServletResponse();
AbstractAuthenticatedController.PageAuthorization denied = controller.authorize( AbstractAuthenticatedController.PageAuthorization denied = controller.authorize(
"initview", new ModelMap(), httpSession, deniedResponse); "initview", new ModelMap(), httpSession, deniedResponse);
@@ -47,11 +47,11 @@ class AbstractAuthenticatedControllerTest {
assertEquals(403, deniedResponse.getStatus()); assertEquals(403, deniedResponse.getStatus());
} }
private Session sessionWithRoute(String route) { private UserSession sessionWithRoute(String route) {
Session session = new Session(); return UserSession.builder()
session.setMenuHtml("<a onclick=\"SubmitMenuCommand('" + route .menuHtml("<a onclick=\"SubmitMenuCommand('" + route
+ "','_parent','MenuForm','')\">Page</a>"); + "','_parent','MenuForm','')\">Page</a>")
return session; .build();
} }
private static final class TestController extends AbstractAuthenticatedController { private static final class TestController extends AbstractAuthenticatedController {

View File

@@ -0,0 +1,66 @@
package matrix.nimble.security;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.X509EncodedKeySpec;
import java.time.Instant;
import java.util.Base64;
import java.util.UUID;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import lib.models.ApplicationDetails;
import lib.models.CaseSaveRequest;
import lib.exceptions.ApplicationException;
import org.junit.jupiter.api.Test;
class PayloadCryptoServiceTest {
@Test
void decryptsBrowserCompatibleEnvelopeAndRejectsReplay() throws Exception {
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
PayloadCryptoService service = new PayloadCryptoService(mapper, "", "");
ApplicationDetails details = new ApplicationDetails();
details.setApplicationId(42);
details.setApplicationNumber("APP-42");
String requestId = UUID.randomUUID().toString();
String timestamp = Instant.now().toString();
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(
new X509EncodedKeySpec(Base64.getUrlDecoder().decode(service.encodedPublicKey())));
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(256);
SecretKey aesKey = generator.generateKey();
byte[] iv = new byte[12];
java.security.SecureRandom.getInstanceStrong().nextBytes(iv);
byte[] aad = String.join("|", service.keyId(), requestId, timestamp)
.getBytes(StandardCharsets.UTF_8);
Cipher payload = Cipher.getInstance("AES/GCM/NoPadding");
payload.init(Cipher.ENCRYPT_MODE, aesKey, new GCMParameterSpec(128, iv));
payload.updateAAD(aad);
byte[] encryptedPayload = payload.doFinal(mapper.writeValueAsBytes(details));
Cipher wrapper = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
wrapper.init(Cipher.ENCRYPT_MODE, publicKey,
new OAEPParameterSpec("SHA-256", "MGF1",
MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
byte[] encryptedKey = wrapper.doFinal(aesKey.getEncoded());
Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();
CaseSaveRequest request = new CaseSaveRequest(
service.keyId(), encoder.encodeToString(encryptedKey), encoder.encodeToString(iv),
encoder.encodeToString(encryptedPayload), requestId, timestamp);
assertEquals(42, service.decrypt(request, ApplicationDetails.class).getApplicationId());
assertThrows(ApplicationException.class, () -> service.decrypt(request, ApplicationDetails.class));
}
}

Some files were not shown because too many files have changed in this diff Show More