Query 19,20,21,22 migrated - Find same case details in punching screen in case of co-applicant
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/ApplicationSaveResult.java
|
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/ApplicationSaveResult.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/CasePunching.java
|
||||||
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/CaseSaveRequest.java
|
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/CaseSaveRequest.java
|
||||||
|
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/DuplicateDetailsData.java
|
||||||
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/MessageDetails.java
|
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/MessageDetails.java
|
||||||
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/Option.java
|
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/Option.java
|
||||||
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/PunchedRecordsData.java
|
/Users/maddy/Projects/cygnus/matrix/cygnus-lib/src/main/java/lib/models/PunchedRecordsData.java
|
||||||
|
|||||||
Binary file not shown.
@@ -23,7 +23,7 @@
|
|||||||
<script language="javascript" src="/matrix/js/lib/form-validation.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/edp/punching/initiation.js?ver=7" 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/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/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>
|
||||||
|
|||||||
@@ -81,13 +81,7 @@ Owner of DHTMLgoodies.com
|
|||||||
document.getElementsByName(ajax_list_activeInput.name + '_pincode')[0].value = inputObj.id.split("#-#")[1];
|
document.getElementsByName(ajax_list_activeInput.name + '_pincode')[0].value = inputObj.id.split("#-#")[1];
|
||||||
document.getElementsByName(ajax_list_activeInput.name + '_citylist')[0].value = inputObj.id.split("#-#")[2];
|
document.getElementsByName(ajax_list_activeInput.name + '_citylist')[0].value = inputObj.id.split("#-#")[2];
|
||||||
}
|
}
|
||||||
//$('#'+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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
};
|
|
||||||
@@ -20,6 +20,13 @@ var FocusAfter="customername";
|
|||||||
var CHECKBOX_FIELDS=new Set(["rv","sradd","rtv","ov","soadd","otv","rco","pv","rcp","ocp","spadd","refv","docv"]);
|
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 DUPLICATE_OPERATION={R:19,O:20,P:21,A:22};
|
||||||
var PUNCHED_RECORDS_URL="punchedrecs";
|
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()
|
function InitPage()
|
||||||
{
|
{
|
||||||
@@ -98,10 +105,6 @@ function AddNewRecord()
|
|||||||
}
|
}
|
||||||
FillDetails(recpos);
|
FillDetails(recpos);
|
||||||
}
|
}
|
||||||
function AfterResponse(response,oprID)
|
|
||||||
{
|
|
||||||
if(oprID>=19 && oprID<=22) handleDuplicateDetailsResponse(response,oprID);
|
|
||||||
}
|
|
||||||
async function loadPunchedRecords(portfolioId,documentCaseId)
|
async function loadPunchedRecords(portfolioId,documentCaseId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -126,16 +129,37 @@ async function loadPunchedRecords(portfolioId,documentCaseId)
|
|||||||
}
|
}
|
||||||
finally{$("#ajaxmsg").remove();}
|
finally{$("#ajaxmsg").remove();}
|
||||||
}
|
}
|
||||||
function handleDuplicateDetailsResponse(response,oprID)
|
function handleDuplicateDetailsResponse(records,oprID)
|
||||||
{
|
{
|
||||||
var rows=response.split(RowDelim).slice(0,-1);
|
|
||||||
if($("#portfolio_id").val()==81)
|
if($("#portfolio_id").val()==81)
|
||||||
{
|
{
|
||||||
for(var index=0;index<rows.length;index++) incrementDuplicateApplicationNumber();
|
for(var index=0;index<records.length;index++) incrementDuplicateApplicationNumber();
|
||||||
}
|
}
|
||||||
else SameAddr=rows.map(function(row){return row.split(ColDelim);});
|
else SameAddr=records.map(function(record){
|
||||||
|
return DUPLICATE_FIELDS[oprID].map(function(field){return record[field] == null ? "" : record[field];});
|
||||||
|
});
|
||||||
SelectAddr(oprID-19);
|
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()
|
function incrementDuplicateApplicationNumber()
|
||||||
{
|
{
|
||||||
var appl=$("#applno").val();
|
var appl=$("#applno").val();
|
||||||
@@ -408,8 +432,7 @@ function FindSameDet(Elm,Visit,focAfter)
|
|||||||
{
|
{
|
||||||
SameAddr=[];
|
SameAddr=[];
|
||||||
var oprId=DUPLICATE_OPERATION[Visit];
|
var oprId=DUPLICATE_OPERATION[Visit];
|
||||||
var QryStr="val="+encodeURIComponent(Applno)+"&val1="+encodeURIComponent($("#portfolio_id").val())+"&val2="+encodeURIComponent(oprId);
|
loadDuplicateDetails(Applno,$("#portfolio_id").val(),oprId);
|
||||||
RunAjax("GET","findsdet",QryStr,oprId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -119,16 +119,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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,6 +26,7 @@ import lib.models.ApplicationSaveResult;
|
|||||||
import lib.models.CaseSaveRequest;
|
import lib.models.CaseSaveRequest;
|
||||||
import lib.models.MessageDetails;
|
import lib.models.MessageDetails;
|
||||||
import lib.models.PunchedRecordsData;
|
import lib.models.PunchedRecordsData;
|
||||||
|
import lib.models.DuplicateDetailsData;
|
||||||
import lib.constants.ApplicationMessage;
|
import lib.constants.ApplicationMessage;
|
||||||
import matrix.nimble.security.PayloadCryptoService;
|
import matrix.nimble.security.PayloadCryptoService;
|
||||||
import lib.exceptions.ApplicationException;
|
import lib.exceptions.ApplicationException;
|
||||||
@@ -40,6 +41,7 @@ public class PunchingController extends AbstractAuthenticatedController {
|
|||||||
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_ADD_ROUTE = "caseadd";
|
||||||
private static final String CASE_EDIT_ROUTE = "caseedit";
|
private static final String CASE_EDIT_ROUTE = "caseedit";
|
||||||
|
private static final String DUPLICATE_DETAILS_ROUTE = "findsdet";
|
||||||
private final PunchingService punchingService;
|
private final PunchingService punchingService;
|
||||||
private final PayloadCryptoService cryptoService;
|
private final PayloadCryptoService cryptoService;
|
||||||
|
|
||||||
@@ -90,6 +92,35 @@ public class PunchingController extends AbstractAuthenticatedController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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 = "application-save", method = RequestMethod.POST,
|
@RequestMapping(value = "application-save", method = RequestMethod.POST,
|
||||||
consumes = MediaType.APPLICATION_JSON_VALUE,
|
consumes = MediaType.APPLICATION_JSON_VALUE,
|
||||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ 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.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 org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -22,6 +24,7 @@ import lib.models.ApplicationSaveResult;
|
|||||||
import lib.models.MessageDetails;
|
import lib.models.MessageDetails;
|
||||||
import lib.models.Option;
|
import lib.models.Option;
|
||||||
import lib.models.PunchedRecordsData;
|
import lib.models.PunchedRecordsData;
|
||||||
|
import lib.models.DuplicateDetailsData;
|
||||||
import lib.models.UserSession;
|
import lib.models.UserSession;
|
||||||
import lib.constants.ApplicationMessage;
|
import lib.constants.ApplicationMessage;
|
||||||
import lib.exceptions.ApplicationException;
|
import lib.exceptions.ApplicationException;
|
||||||
@@ -42,6 +45,10 @@ public class PunchingService {
|
|||||||
|
|
||||||
private static final Short ACTIVE = Short.valueOf((short) 1);
|
private static final Short ACTIVE = Short.valueOf((short) 1);
|
||||||
private static final int PUNCHED_RECORDS_QUERY = 24;
|
private static final int PUNCHED_RECORDS_QUERY = 24;
|
||||||
|
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(
|
private static final Pattern DYNAMIC_FIELD = Pattern.compile(
|
||||||
"(?:field(?:[1-9]|1[0-2]|150(?:_2)?)|dtfield1)", Pattern.CASE_INSENSITIVE);
|
"(?:field(?:[1-9]|1[0-2]|150(?:_2)?)|dtfield1)", Pattern.CASE_INSENSITIVE);
|
||||||
private static final SqlArrayParameter GENERAL_OPTION_TYPES =
|
private static final SqlArrayParameter GENERAL_OPTION_TYPES =
|
||||||
@@ -117,6 +124,45 @@ public class PunchingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Object> toPunchedRecord(RowView row) {
|
private Map<String, Object> toPunchedRecord(RowView row) {
|
||||||
Map<String, Object> record = new LinkedHashMap<>();
|
Map<String, Object> record = new LinkedHashMap<>();
|
||||||
row.asMap().forEach((name, value) -> {
|
row.asMap().forEach((name, value) -> {
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import lib.exceptions.ApplicationException;
|
||||||
import lib.models.PunchedRecordsData;
|
import lib.models.PunchedRecordsData;
|
||||||
import lib.models.UserSession;
|
import lib.models.UserSession;
|
||||||
import lib.models.Option;
|
import lib.models.Option;
|
||||||
@@ -22,6 +25,36 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
class PunchingServiceTest {
|
class PunchingServiceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void loadsDuplicateDetailsWithAllowlistedQueryAndSessionScope() {
|
||||||
|
AtomicReference<Integer> query = new AtomicReference<>();
|
||||||
|
AtomicReference<Object[]> parameters = new AtomicReference<>();
|
||||||
|
RowView row = row(new LinkedHashMap<>(Map.of("paddr1", "House 1", "pcolony", 42)));
|
||||||
|
CygnusDbExecutor executor = (CygnusDbExecutor) Proxy.newProxyInstance(
|
||||||
|
getClass().getClassLoader(), new Class<?>[] {CygnusDbExecutor.class},
|
||||||
|
(proxy, method, args) -> {
|
||||||
|
if (method.getName().equals("query") && args.length == 2) {
|
||||||
|
query.set((Integer) args[0]);
|
||||||
|
parameters.set(((Object[]) args[1]).clone());
|
||||||
|
return List.of(row);
|
||||||
|
}
|
||||||
|
throw new UnsupportedOperationException(method.toString());
|
||||||
|
});
|
||||||
|
PunchingService service = new PunchingService(
|
||||||
|
new CommonService(), executor, new ObjectMapper());
|
||||||
|
UserSession session = UserSession.builder()
|
||||||
|
.companyId((short) 3).branchId((short) 7).build();
|
||||||
|
|
||||||
|
var result = service.findDuplicateDetails(" APP-1 ", (short) 38, 21, session);
|
||||||
|
|
||||||
|
assertEquals(21, query.get());
|
||||||
|
assertArrayEquals(new Object[] {"APP-1", (short) 38, (short) 3, (short) 7,
|
||||||
|
Date.valueOf(LocalDate.now())}, parameters.get());
|
||||||
|
assertEquals("House 1", result.records().getFirst().get("paddr1"));
|
||||||
|
assertThrows(ApplicationException.class,
|
||||||
|
() -> service.findDuplicateDetails("APP-1", (short) 38, 23, session));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void loadsPunchedRecordsAsFormShapedObjectsAndMergesDynamicFields() {
|
void loadsPunchedRecordsAsFormShapedObjectsAndMergesDynamicFields() {
|
||||||
AtomicReference<Object[]> parameters = new AtomicReference<>();
|
AtomicReference<Object[]> parameters = new AtomicReference<>();
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
-- Remove view/materialized-view dependencies from the application-save workflow.
|
||||||
|
-- Each replacement expands the original view predicate against its base tables.
|
||||||
|
DO $migration$
|
||||||
|
DECLARE
|
||||||
|
change record;
|
||||||
|
definition text;
|
||||||
|
BEGIN
|
||||||
|
FOR change IN
|
||||||
|
SELECT *
|
||||||
|
FROM (VALUES
|
||||||
|
(
|
||||||
|
'public.autocut(integer,text,integer)'::regprocedure,
|
||||||
|
'FROM main_mainopr WHERE uuid = unqueid',
|
||||||
|
'FROM main m JOIN main_operations mo ON mo.uuid::text = m.uuid::text WHERE m.isdeleted = 0 AND m.uuid = unqueid'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'public.autocut(integer,text,integer)'::regprocedure,
|
||||||
|
'SELECT rv,ov,pv,rcolony,ocolony,pcolony,company_id,branch_id,oprsendon,allocationon,earlier,negative',
|
||||||
|
'SELECT m.rv,m.ov,m.pv,m.rcolony,m.ocolony,m.pcolony,m.company_id,m.branch_id,mo.oprsendon,mo.allocationon,mo.earlier,mo.negative'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'public.dedupebyuuid(text,integer,text,text,integer)'::regprocedure,
|
||||||
|
'from cutoff_operations where uuid=uniqueid',
|
||||||
|
'from (select c.*, mo.cutoffon from main c join main_operations mo on mo.uuid::text = c.uuid::text join portfolio p on p.portfolio_id = c.portfolio_id join company co on co.company_id = c.company_id where c.isdeleted = 0 and mo.sdone = 0) source_case where uuid=uniqueid'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'public.smsentry(text,integer,text,integer,integer,integer,integer)'::regprocedure,
|
||||||
|
'from cutoff_operations where uuid=uniqueid',
|
||||||
|
'from (select c.*, p.portname from main c join main_operations mo on mo.uuid::text = c.uuid::text join portfolio p on p.portfolio_id = c.portfolio_id join company co on co.company_id = c.company_id where c.isdeleted = 0 and mo.sdone = 0) source_case where uuid=uniqueid'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'public.checkaddress(text,text,integer,text,integer,text,date,integer,timestamp without time zone,integer)'::regprocedure,
|
||||||
|
'from mview_main_mainopr where',
|
||||||
|
'from (select m.*, mo.cutoffon from main m join main_operations mo on mo.uuid::text = m.uuid::text where m.isdeleted = 0 and m.receivedate > (current_date - interval ''6 months'')) prior_cases where'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'public.checkphonenos(text,text,text,integer,text,date,timestamp without time zone,integer)'::regprocedure,
|
||||||
|
'from mview_main_mainopr where',
|
||||||
|
'from (select m.*, mo.cutoffon from main m join main_operations mo on mo.uuid::text = m.uuid::text where m.isdeleted = 0 and m.receivedate > (current_date - interval ''6 months'')) prior_cases where'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'public.checknamedob(text,text,integer,text,date)'::regprocedure,
|
||||||
|
'from mview_main_namedob_ear where',
|
||||||
|
'from (select m.* from main m where m.dob::text <> '''' and m.dob is not null and m.isdeleted = 0 and m.receivedate > (current_date - interval ''6 months'')) prior_namedob_cases where'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'public.sendtooperation(character,integer,character,integer,integer,integer,integer)'::regprocedure,
|
||||||
|
'from main_mainopr m where',
|
||||||
|
'from (select mn.*, mo.batch, mo.rvdone, mo.rvdoneon, mo.rvdoneby, mo.ovdone, mo.ovdoneon, mo.ovdoneby, mo.tvrdone, mo.tvrdoneon, mo.tvrdoneby, mo.pvdone, mo.pvdoneon, mo.pvdoneby, mo.docdone, mo.docdoneon, mo.docdoneby from main mn join main_operations mo on mo.uuid::text = mn.uuid::text where mn.isdeleted = 0) m where'
|
||||||
|
)
|
||||||
|
) AS replacements(function_oid, old_sql, new_sql)
|
||||||
|
LOOP
|
||||||
|
definition := pg_get_functiondef(change.function_oid);
|
||||||
|
|
||||||
|
-- Makes the migration safe to re-run after a successful deployment.
|
||||||
|
IF position(change.old_sql IN definition) = 0 THEN
|
||||||
|
IF position(change.new_sql IN definition) = 0 THEN
|
||||||
|
RAISE EXCEPTION 'Expected SQL was not found in %', change.function_oid;
|
||||||
|
END IF;
|
||||||
|
CONTINUE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXECUTE replace(definition, change.old_sql, change.new_sql);
|
||||||
|
END LOOP;
|
||||||
|
END
|
||||||
|
$migration$;
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
CREATE INDEX idx_portfolio_branch_active_name
|
CREATE INDEX idx_portfolio_branch_active_name
|
||||||
ON portfolio (branch_id, isactive, portname);
|
ON portfolio (branch_id, isactive, portname);
|
||||||
|
|
||||||
|
CREATE INDEX idx_main_applno_portfolio_company_branch_date_deleted ON main (applno, portfolio_id, company_id, branch_id, receivedate, isdeleted);
|
||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user