PageSourceSearch

https://fxboss.firstcitizens.com/app/components/payees/bulk_beneficiary_upload.js?v=31082026-1758

js firstcitizens.com collected 2026-09-24 21:51:25 UTC 51,874 bytes, 1,379 lines download raw bytes

1var app = angular.module('bossApp');
2app.controller('bulkBeneficiaryUploadCtlr', ['$q', '$scope', '$rootScope', '$http', 'readFileData', '$filter', '$state', '$location', '$timeout', 'PayeeNewEditService', 'StaticDataService', 'BankService', 'limitToFilter', function ($q, $scope, $rootScope, $http, readFileData, $filter, $state, $location, $timeout, PayeeNewEditService, StaticDataService, BankService, limitToFilter) {
3	var myEl = angular.element(document.querySelector('#addEditBeneficiaryLabel'));
4	myEl.text('Add Beneficiary');
5	$rootScope.isNewPayee = true;
6	$("#bulkBeneficiary-upload").addClass("btn-circle-2-current");
7	$scope.bulkBeneUploadForm = true;
8	$scope.fileDataObj = {};
9	$scope.payeeFiles = [];
10	$scope.existingPayees = [];
11	var payeeListTimer;
12	var jGrowlLife = 10000;
13	$scope.payeeGlobalListCount = 0;
14	$scope.payeeGlobalList = [];
15	$scope.currentRequestList = [];
16	$rootScope.recordsCountFlag = false;
17	$rootScope.beneUploadValidatedCount = 0;
18	$rootScope.beneUploadSuccessCount = 0;
19	$rootScope.beneUploadFailedCount = 0;
20	$scope.remainingBeneList = [];
21	$scope.completedProgressSize = 0;
22	$scope.totalProgressSize = 0;
23	$scope.fileListArrayBatch = [];
24	$scope.hasRemainingRecordsToValidate = false;
25	$scope.APIcallBatchSize = 2;
26	var beneficiaryConfig = {
27		"Recipient Type*": "recipientType",
28		"Beneficiary Name*": "legalName",
29		"Beneficiary Template Name*": "aliasName",
30		"Beneficiary Address1*": "legalAddress.address1",
31		"Beneficiary Address2": "legalAddress.address2",
32		"Beneficiary Country*": "legalAddress.country",
33		"Beneficiary State": "legalAddress.state",
34		"Beneficiary City*": "legalAddress.city",
35		"Beneficiary Postalcode": "legalAddress.postalCode",
36		"Beneficiary Email": "emailAddress",
37		"Beneficiary PhoneNumber": "phoneNumber",
38		"OBI": "additionalInfo",
39		"Beneficiary BankCountry*": "bankCountry",
40		"Beneficiary Account Currency*": "accountCcy",
41		"Beneficiary BankSWIFT": "accountWithBank.bic",
42		"Beneficiary BankName": "accountWithBank.institutionName",
43		"Beneficiary BankCity": "accountWithBank.city",
44		"Beneficiary BankAddress1": "accountWithBank.streetAddress1",
45		"Beneficiary BankNationalID": "accountWithBank.nationalId",
46		"Beneficiary AccountNumber*": "accountNumber",
47		"Regulatory Fields": "wireTransferFields",
48		"Category*": "category",
49		"Beneficiary BankAddress2": "accountWithBank.streetAddress2",
50		"Beneficiary BankState": "accountWithBank.state",
51		"Beneficiary BankPostalcode": "accountWithBank.postalCode",
52		"Intermediary BankName": "intermediaryBank.institutionName",
53		"Intermediary BankAccountNumber": "intermediaryBank.accountNumber",
54		"Intermediary BankAddress1": "intermediaryBank.streetAddress1",
55		"Intermediary BankAddress2": "intermediaryBank.streetAddress2",
56		"Intermediary BankCity": "intermediaryBank.city",
57		"Intermediary BankState": "intermediaryBank.state",
58		"Intermediary BankPostalcode": "intermediaryBank.postalCode",
59		"Intermediary BankCountry": "intermediaryCountry",
60		"Intermediary BankSWIFT": "intermediaryBank.bic",
61		"Intermediary BankNationalID": "intermediaryBank.nationalId"
62	};
63	/***********************************************
64	|			Country List typeahead list   	   |
65	***********************************************/
66	StaticDataService.newCountryList().then(function (response) {
67		if (response.responseObj == undefined || response.responseObj == null) {
68			$scope.countryObjList = response;
69		} else {
70			$scope.countryObjList = response.responseObj;
71		}
72	});
73
74	$scope.selectFileType = function (e) {
75		$scope.fileType = this.fileType;
76	}
77
78	/***********************************************
79	|	Input File onChange/onSelect Event         |
80	***********************************************/
81	$scope.parsedExcelToCsvContent = function (file) {
82		let fileReader = new FileReader();
83		$scope.fileContent = [];
84		fileReader.readAsArrayBuffer(file);
85		fileReader.onload = function (e) {
86			var data = new Uint8Array(e.target.result);
87			var workbook = XLSX.read(data, { type: 'array' });
88			workbook.SheetNames.forEach(function (sheetName) {
89				var csvContent = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetName]);
90				if (csvContent.length) {
91					$scope.fileContent = csvContent;
92				}
93			});
94		};
95	}
96
97
98	$scope.selectPayeeFile = function (evt) {
99		var files = evt.files;
100		$scope.payeeFiles = [files[0]];
101		if (files.length) {
102			var fileSizeInKb = files[0].size / 1000;
103			let fileExtension = [];
104			if ($scope.fileType == 'xlsx') {
105				fileExtension = files[0].name.split('.')
106			}
107			if (fileSizeInKb < $rootScope.bulkBeneFileSize && (files[0].name.indexOf("." + $scope.fileType) != -1 || ($scope.fileType == 'xlsx' && fileExtension[1] == 'xls'))) {
108				if ($scope.fileType == 'xlsx' && fileExtension[1] != 'xls') {
109					this.file = files[0];
110					$scope.parsedExcelToCsvContent(this.file);
111				} else if ($scope.fileType == 'csv') {
112					var r = new FileReader();
113					r.onload = function (e) {
114						var contents = e.target.result;
115						$scope.$apply(function () {
116							$scope.fileContent = contents;
117						});
118					};
119					r.readAsText(files[0]);
120				}
121			} else {
122				$scope.removePayeeFile();
123				if (fileSizeInKb >= $rootScope.bulkBeneFileSize) {
124					$.jGrowl("File size should be less than " + $rootScope.bulkBeneFileSize + "kb.", {
125						sticky: false,
126						life: jGrowlLife,
127						position: 'center',
128						theme: 'notification-size notification-alert'
129					});
130				} else {
131					$.jGrowl("Sorry, Selected file is invalid!. Please change the File Type and try again", {
132						sticky: false,
133						life: jGrowlLife,
134						position: 'center',
135						theme: 'notification-size notification-alert'
136					});
137				}
138			}
139		}
140	}
141
142	/***********************************************
143	|	Drag & Drop Bulk benificiary File          |
144	***********************************************/
145	//$timeout(function(){
146	var loadPayeeDropbox = setInterval(function () {
147		if ($('#payeeDropbox').length) {
148			clearInterval(loadPayeeDropbox);
149			var payeeDropbox = document.getElementById("payeeDropbox")
150			payeeDropbox.addEventListener("dragover", function (evt) {
151				evt.stopPropagation();
152				evt.preventDefault();
153				var ok = evt.dataTransfer && evt.dataTransfer.types && evt.dataTransfer.types.indexOf('Files') >= 0
154			}, false)
155			payeeDropbox.addEventListener("drop", function (evt) {
156				evt.stopPropagation()
157				evt.preventDefault()
158				var files = evt.dataTransfer.files;
159				var fileSizeInKb = Math.round(files[0].size / 1000);
160				var file = files[0];
161				let fileExtension = [];
162				if ($scope.fileType == 'xlsx') {
163					fileExtension = files[0].name.split('.')
164				}
165				if (fileSizeInKb < $rootScope.bulkBeneFileSize && $scope.fileType && (file.name.indexOf("." + $scope.fileType) != -1 || ($scope.fileType == 'xlsx' && fileExtension[1] == 'xls'))) {
166					$scope.payeeFiles = [file];
167					if ($scope.fileType == 'xlsx' && fileExtension[1] != 'xls') {
168						this.file = files[0];
169						$scope.parsedExcelToCsvContent(this.file);
170					} else if ($scope.fileType == 'csv') {
171						var r = new FileReader();
172						r.onload = function (e) {
173							var contents = e.target.result;
174							$scope.$apply(function () {
175								$scope.fileContent = contents;
176							});
177						};
178						r.readAsText(files[0]);
179					}
180				} else {
181					angular.element("input[type='file']").val(null);
182					if (fileSizeInKb >= $rootScope.bulkBeneFileSize) {
183						$.jGrowl("File size should be less than " + $rootScope.bulkBeneFileSize + "kb.", {
184							sticky: false,
185							life: jGrowlLife,
186							position: 'center',
187							theme: 'notification-size notification-alert'
188						});
189
190					} else {
191						$.jGrowl("Sorry, Selected file is invalid!. Please change the File Type and try again", {
192							sticky: false,
193							life: jGrowlLife,
194							position: 'center',
195							theme: 'notification-size notification-alert'
196						});
197					}
198				}
199			}, false)
200		}
201	}, 100);
202
203	$scope.removePayeeFile = function (evt) {
204		$scope.payeeFiles = [];
205		$scope.fileContent = null;
206		angular.element("input[type='file']").val(null);
207	}
208
209	$scope.uploadBeneficiary = function () {
210		if ($scope.fileType == "csv" || $scope.fileType == "xlsx") {
211			$scope.fileDataObj = readFileData.processData(this.fileContent);
212			$scope.fileData = angular.copy($scope.fileDataObj);
213			if ($scope.validateBeneBulkUploadFields($scope.fileData)) {
214				$scope.convertCsvFileToJSon();
215			}
216		}
217	}
218
219
220	/***********************************************
221	|	Conver CSV data into JSON Object           |
222	***********************************************/
223	$scope.convertCsvFileToJSon = function () {
224		var length = Object.keys($scope.fileData).length;
225		if (length > $rootScope.bulkBeneNoOfRecords+1) {
226			$.jGrowl("Sorry, File can't have more than " + $rootScope.bulkBeneNoOfRecords + " records.", {
227				sticky: false,
228				life: jGrowlLife,
229				position: 'center',
230				theme: 'notification-size notification-alert'
231			});
232			return false;
233		}
234		$("#bulkBeneficiary-upload").removeClass("btn-circle-2-current");
235		$("#bulkBeneficiary-review").addClass("btn-circle-2-current");
236		$scope.bulkBeneUploadForm = false;
237		$scope.bulkBeneReviewGrid = true;
238		$scope.uploadInProgress = true;
239		$scope.uploadPercentage = 0;
240		var sheetColums = [];
241		var payeeList = [];
242		var size = Object.keys($scope.fileData).length;
243		var invalidColumns = [];
244		angular.forEach(beneficiaryConfig, function (v, k) {
245			var isValidColumn = $scope.fileData[0].indexOf(k) == -1;
246			if (k.indexOf("*") != -1 && isValidColumn) {
247				invalidColumns.push(k);
248			}
249		});
250		let filedataValues = Object.values($scope.fileData);
251		$scope.fileData = filedataValues.filter(array => array.some(value => value !== ""));
252		length = Object.values($scope.fileData).length;
253		var inValidRecordsCount = 0;
254		if (length > 1 && invalidColumns.length == 0) {
255			try {
256				var notEmptyMandatoryFlds = [];
257				var invalidRecipientType = []
258				var isCountryValid = true;
259				var isBeneficiaryCountryValid = true;
260				angular.forEach($scope.fileData, function (value, key) {
261					if (key == "0") {//Column names
262						sheetColums = angular.copy(value);
263					} else {//Colum values
264						var payeeObj = {};
265						var invalidCount = 0;
266						var regulatoryFields = {};
267						var colCategoryVal = null;
268						angular.forEach(value, function (val, i) {
269							var column = sheetColums[i];
270							var fieldName = beneficiaryConfig[column];
271
272							if (column.search("Category") != -1) {
273								colCategoryVal = val;
274							}
275							// Collect all RegulatoryFields at one object.
276							if (column.search("RegulatoryField.LABEL") != -1 && val) {
277								/*var re = new RegExp('""', 'g');
278								var sReg = new RegExp("'", 'g');
279								val=val.replace(";",",").replace(re,'').replace(/\\/g, "'").replace('"{',"{").replace('}"',"}").replace(sReg,'"');
280								val=JSON.parse(val);*/
281								fieldName = beneficiaryConfig["Regulatory Fields"];
282								regulatoryFields[column.split(".")[2]] = val;
283								payeeObj[fieldName] = regulatoryFields;
284								return;
285							}
286							if (fieldName && fieldName != "wireTransferFields") {
287								if (fieldName.indexOf(".") == -1) {
288									payeeObj[fieldName] = val;
289								} else {
290									var keylist = fieldName.split(".");
291									payeeObj[keylist[0]] = payeeObj[keylist[0]] ? payeeObj[keylist[0]] : {};
292									payeeObj[keylist[0]][keylist[1]] = val;
293								}
294							}
295							if (colCategoryVal != null && colCategoryVal == "Domestic") {
296								if (column.search("Beneficiary BankSWIFT") != -1 && val == "") {
297									return;
298								}
299								if (column.search("Beneficiary BankNationalID") != -1 && val == "") {
300									notEmptyMandatoryFlds.push(parseInt(key) + 1 + " " + column);
301								}
302							}
303							if (column.indexOf("*") != -1) {
304								if (!val) {
305									invalidCount++;
306									notEmptyMandatoryFlds.push(parseInt(key) + 1 + " " + column);
307								}
308							}
309
310							if (column == "Intermediary BankSWIFT" && val) {// GT-468
311								var isExist = $scope.searchValFromArray("Beneficiary BankSWIFT", notEmptyMandatoryFlds);
312								if (isExist != -1) {
313									notEmptyMandatoryFlds.splice(isExist, 1);
314									invalidCount--;
315								}
316							}
317
318							if (column == "Recipient Type*") {
319								if (val && !(val == "Individual" || val == "Entity")) {
320									invalidCount++;
321									invalidRecipientType.push(parseInt(key) + 1 + " " + column);
322								}
323							}
324						});
325						if (invalidCount == 0) {
326							$scope.buildBeneficiaryObject(payeeObj);
327							$timeout(function () {
328								$scope.setCountryDetails(payeeObj, [], false, []);
329								if (!payeeObj.bankIsoCountryCode)
330									isCountryValid = false;
331								if (!payeeObj.legalAddress.country)
332									isBeneficiaryCountryValid = false;
333							});
334							$timeout(function () {
335								payeeList.push(payeeObj);
336								if (payeeList.length == length - 1) {
337									let bankIsoCountryCodeList = [];
338									payeeList.forEach(ele => { bankIsoCountryCodeList.push(ele.bankIsoCountryCode.toUpperCase()) })
339									bankIsoCountryCodeList = new Set(bankIsoCountryCodeList);
340									var stringValueYouWant = ""
341									angular.forEach(bankIsoCountryCodeList, function (ele, key) { stringValueYouWant = stringValueYouWant + ele + ',' })
342									$scope.setCountryDetails({}, stringValueYouWant.slice(0, -1), true, payeeList);
343								}
344							}, 100
345							);
346						}else{
347							inValidRecordsCount++;
348						}
349					}
350				});
351
352				$timeout(function () {
353					if (!isCountryValid || !isBeneficiaryCountryValid) {
354						showErrorMsg(notEmptyMandatoryFlds, "countryInvalid");
355						return;
356					}
357					if (notEmptyMandatoryFlds.length > 0) {
358						showErrorMsg(notEmptyMandatoryFlds, "MandatoryFieldEmpty");
359						return;
360					}
361					if (invalidRecipientType.length > 0) {
362						showErrorMsg(invalidRecipientType, "invalidRecipientType");
363						return;
364					}
365				});
366			} catch (e) {
367				payeeList = [];
368				console.error(e);
369			}
370			payeeListTimer = $timeout(function () {
371				if (payeeList.length > 0 && inValidRecordsCount == 0) {
372					const validateArr = $scope.splitArrayIntoBatches(payeeList, $rootScope.bulkBeneRequestSize);
373					$scope.completedProgressSize = 0;
374					$scope.totalProgressSize = 0;
375					$scope.fileListArrayBatch = [];
376					$scope.payeeList = [];
377					$scope.payeeGlobalListCount = 0;
378					$scope.payeeGlobalList = [];
379					$rootScope.beneUploadFailedCount = 0;
380					for (let i = 0; i < validateArr.length; i++) {
381						$scope.totalProgressSize += 1;
382						if (i < $scope.APIcallBatchSize) {
383							$scope.validateOrSaveBeneficiaries(validateArr[i], true);
384						} else {
385							$scope.fileListArrayBatch.push(validateArr[i]);
386						}
387					}
388				} else if (payeeList.length === 0 &&
389					notEmptyMandatoryFlds.length === 0 &&
390					invalidRecipientType.length === 0 &&
391					isCountryValid &&
392					isBeneficiaryCountryValid) {
393					uploadError()
394				}
395			}, 2000);
396		} else {
397			uploadError(invalidColumns)
398		}
399
400		function uploadError(invalidColumns) {
401			var errorMsg = "Sorry, One or more field(s) do not match. Please follow the instructions and try again.";
402			if (invalidColumns && invalidColumns.length > 0) {
403				errorMsg = "Missing mandatory column(s): <br> " + invalidColumns.join("<br>");
404			}
405			$("#bulkBeneficiary-upload").addClass("btn-circle-2-current");
406			$("#bulkBeneficiary-review").removeClass("btn-circle-2-current");
407			$scope.bulkBeneUploadForm = true;
408			$scope.bulkBeneReviewGrid = false;
409			$scope.uploadInProgress = false;
410			$.jGrowl(errorMsg, {
411				sticky: false,
412				life: jGrowlLife,
413				theme: 'alert alert-danger',
414				color: "#fff"
415			});
416
417		}
418	}
419
420	$scope.splitArrayIntoBatches = function (array, batchSize) {
421		const batches = [];
422		for (let i = 0; i < array.length; i += batchSize) {
423			batches.push(array.slice(i, i + batchSize));
424		}
425		return batches;
426	}
427
428	$scope.continueToSubmit = function () {
429		const listOfPayee = angular.copy($scope.payeeList);
430		const inValidListOfPayee = [];
431		const validListOfPayee = [];
432
433		$scope.totalPayees = 0;
434		$scope.totalValidPayees = 0;
435		$scope.totalInvalidPayees = 0;
436
437		angular.forEach(listOfPayee, function (value, key) {
438			if (value.status == "Error") {
439				inValidListOfPayee.push(value);
440			} else if (value.status == "Validated") {
441				validListOfPayee.push(value);
442			} else {
443				console.error("Invalid payee: ", value);
444			}
445		});
446		if (listOfPayee != undefined && listOfPayee != null) {
447			$scope.totalPayees = listOfPayee.length;
448		}
449		if (validListOfPayee != "undefined" && validListOfPayee != null) {
450			$scope.totalValidPayees = validListOfPayee.length;
451		}
452		if (inValidListOfPayee != "undefined" && inValidListOfPayee != null) {
453			$scope.totalInvalidPayees = inValidListOfPayee.length;
454		}
455
456		if (inValidListOfPayee != "undefined" && inValidListOfPayee != null && inValidListOfPayee.length > 0) {
457			bootbox.confirm({
458				title: "Confirmation",
459				message: "Beneficiaries with Error will not be saved - Do you want to continue?",
460				swapButtonOrder: true,
461				closeButton: false,
462				buttons: {
463					confirm: { label: 'Yes', className: 'btn-primary' },
464					cancel: { label: 'No', className: 'btn-danger' }
465				},
466				callback: function (result) {
467					if (result) {
468						$scope.submitPayees();
469					} else {
470						console.log("Beneficiaries not submitted.")
471					}
472				}
473			}); // End confirm box
474		} else {
475			$scope.submitPayees();
476		}
477	}
478
479	$scope.submitPayees = function () {
480		if ($scope.payeeList != undefined && $scope.payeeList != null && $scope.payeeList.length > 0 && $rootScope.beneUploadValidatedCount > 0) {
481			const submitArr = $scope.splitArrayIntoBatches($scope.payeeList, $rootScope.bulkBeneRequestSize);
482			$scope.completedProgressSize = 0;
483			$scope.totalProgressSize = 0;
484			$scope.uploadPercentage = 0;
485			$scope.fileListArrayBatch = [];
486			$scope.payeeList = [];
487			for (let i = 0; i < submitArr.length; i++) {
488				$scope.totalProgressSize += 1;
489				if (i < $scope.APIcallBatchSize) {
490					$scope.validateOrSaveBeneficiaries(submitArr[i], false);
491				} else {
492					$scope.fileListArrayBatch.push(submitArr[i]);
493				}
494			}
495			$scope.beneficiariesSubmitted = true;
496		} else {
497			$.jGrowl("Sorry, No valid record found. Please upload file and try again.", {
498				sticky: false,
499				life: jGrowlLife,
500				theme: 'alert alert-danger',
501				color: "#fff"
502			});
503		}
504	}
505
506	$scope.validateOrSaveBeneficiaries = function (payeeList, isValidate) {
507		$scope.uploadInProgress = true;
508		var uniquePayees = uniqueArraybyKey(payeeList, "aliasName");
509		var uniquePayeesList = [];
510		angular.forEach(uniquePayees, function (value, key) {
511			if (!value.intermediaryCountry) {
512				value.intermediaryBank = null;
513			}
514			if (!value.wireTransferFields) {
515				value.wireTransferFields = null;
516			}
517			uniquePayeesList.push(value);
518			// $scope.validateOrSaveBeneficiary(uniquePayees,key,value,isValidate);
519		});
520		$scope.validateOrSaveBeneficiary(uniquePayees, 1, uniquePayeesList, isValidate);
521	}
522
523	/********************************************************************
524	|	If isValidate=true then Validate method will be triggered   	|
525	|   If isValidate=false then Save Beneficiary will be triggered		|
526	********************************************************************/
527
528	$scope.filterBeneList = function (status) {
529		$scope.payeeList = [];
530		angular.forEach($scope.payeeGlobalList, function (payeeval) {
531			if (status == 'Success' && (payeeval.status == 'Validated' || payeeval.status == 'Success')) {
532				addValidatedRecordsToGrid(payeeval, $scope.isValidate, null);
533			} else if (status == 'Failed' && (payeeval.status == 'Error' || payeeval.status == 'Duplicate')) {
534				addValidatedRecordsToGrid(payeeval, $scope.isValidate, null);
535			}
536		});
537	}
538
539	$scope.triggerbalanceFileListbatch = function (action) {
540		$scope.fileListArrayBatchBalance = [];
541		if ($scope.fileListArrayBatch.length > 0) {
542			$scope.hasRemainingRecordsToValidate = true;
543			$scope.fileListArrayBatchBalance = [...$scope.fileListArrayBatch];
544			$scope.fileListArrayBatch = [];
545			for (let i = 0; i < $scope.fileListArrayBatchBalance.length; i++) {
546				if (i < $scope.APIcallBatchSize) {
547					if (action == 'VALIDATE')
548						$scope.validateOrSaveBeneficiaries($scope.fileListArrayBatchBalance[i], true);
549					else
550						$scope.validateOrSaveBeneficiaries($scope.fileListArrayBatchBalance[i], false);
551				} else {
552					$scope.fileListArrayBatch.push($scope.fileListArrayBatchBalance[i]);
553				}
554			}
555			$scope.hasRemainingRecordsToValidate = false;
556		}
557	}
558
559
560	$scope.validateOrSaveBeneficiary = function (payeeList, key, reqList, isValidate) {
561		$scope.isValidate = isValidate;
562		if (isValidate) {//Validate Beneficiary
563			$rootScope.recordsCountFlag = false;
564			PayeeNewEditService.validateBeneficiaryList(reqList, isValidate).then(function (responseList) {
565				$scope.completedProgressSize += 1;
566				var percentage = ($scope.completedProgressSize) * 100 / $scope.totalProgressSize;
567				$scope.uploadPercentage = Math.round(percentage);
568				if ($scope.fileListArrayBatch.length > 0 && !$scope.hasRemainingRecordsToValidate) {
569					$scope.hasRemainingRecordsToValidate = true;
570					$timeout(function () {
571						$scope.triggerbalanceFileListbatch('VALIDATE');
572					});
573				}
574				resList = responseList.responseObj;
575				$rootScope.recordsCountFlag = true;
576				if (responseList.errorCode != 'PC_06') {
577					angular.forEach(reqList, function (reqVal) {
578						angular.forEach(resList, function (resVal) {
579							if (reqVal.aliasName == resVal.aliasName) {
580								if (resVal.status == 'Validated') {
581									reqVal.accountWithBank = resVal.accountWithBank;
582									reqVal.intermediaryBank = resVal.intermediaryBank;
583									reqVal.status = isValidate ? "Validated" : "Success";
584									$rootScope.beneUploadValidatedCount = $rootScope.beneUploadValidatedCount + 1;
585								} else if (resVal.status == "Error") {
586									reqVal.status = resVal.status;
587									reqVal.errorMsg = resVal.errorMessage;
588								} else {
589									reqVal.status = resVal.status;
590									reqVal.errorMsg = resVal.errorMessage;
591								}
592								addValidatedRecordsToGrid(reqVal, isValidate, payeeList)
593							}
594						})
595					})
596				}
597			});
598		} else {//Save Beneficiary
599			var requestLst = [];
600			angular.forEach(reqList, function (reqVal) {
601				if (reqVal.status != 'Error' && reqVal.status != 'Duplicate') {
602					requestLst.push(reqVal);
603				}
604			});
605			$scope.ReceivedSocketMessages = [];
606			$rootScope.recordsCountFlag = false;
607
608			PayeeNewEditService.saveBeneficiaryList(requestLst, isValidate).then(function (responseList) {
609				$scope.completedProgressSize += 1;
610				var percentage = ($scope.completedProgressSize) * 100 / $scope.totalProgressSize;
611				$scope.uploadPercentage = Math.round(percentage);
612				if ($scope.fileListArrayBatch.length > 0 && !$scope.hasRemainingRecordsToValidate) {
613					$scope.hasRemainingRecordsToValidate = true;
614					$timeout(function () {
615						$scope.triggerbalanceFileListbatch('SAVE');
616					});
617				}
618
619				resList = responseList.responseObj
620				angular.forEach(requestLst, function (reqVal) {
621					angular.forEach(resList, function (resVal) {
622						if (reqVal.aliasName == resVal.aliasName) {
623							if (resVal.status == 'Success') {
624								reqVal.accountWithBank = resVal.accountWithBank;
625								reqVal.intermediaryBank = resVal.intermediaryBank;
626								reqVal.status = resVal.status;
627								$rootScope.beneUploadSuccessCount = $rootScope.beneUploadSuccessCount + 1;
628							} else if (resVal.status == "Error") {
629								reqVal.status = resVal.status;
630								reqVal.errorMsg = resVal.errorMessage;
631							} else {
632								reqVal.status = resVal.status;
633								reqVal.errorMsg = resVal.errorMessage;
634							}
635							addValidatedRecordsToGrid(reqVal, false, payeeList)
636							$scope.payeeSuccessMsg = $rootScope.beneUploadSuccessCount + " out of " + $scope.totalPayees + " beneficiaries were saved successfully.";
637						}
638					})
639				})
640			});
641		}
642	}
643
644	function addValidatedRecordsToGrid(value, isValidate, payeeList) {
645		validateAccountCcy(value);
646		if (value.accountNumber) {
647			value.accountNumber = value.accountNumber.replace(/\s/g, '');
648		}
649		let tempArr = [];
650		if ($scope.payeeList != undefined && $scope.payeeList?.length > 0) {
651			tempArr = $scope.payeeList;
652			$scope.payeeList = [];
653		}
654		tempArr.push(angular.copy(value));
655		$scope.payeeList = tempArr;
656		if (payeeList != null) {
657			$scope.payeeGlobalList.push(angular.copy(value));
658		}
659		setGridDetails(isValidate);
660	}
661
662	function validateAccountCcy(beneficiary) {
663
664		if (beneficiary.accountCcy) {
665			beneficiary.accountCcy = $filter('uppercase')(beneficiary.accountCcy);
666			if (beneficiary.accountCcy.length == 3) {
667				var beneficiaryCountry = $scope.getCountryObject(beneficiary.bankCountry);
668				var tempCcyList = beneficiaryCountry.paymentCurrencies;
669				if (tempCcyList.indexOf(beneficiary.accountCcy) == -1) {
670					beneficiary.status = "Error";
671					beneficiary.errorMsg = "Invalid Account currency.";
672				}
673			} else {
674				beneficiary.status = "Error";
675				beneficiary.errorMsg = "Account currency should be 3 characters.";
676			}
677		} else {
678			beneficiary.status = "Error";
679			beneficiary.errorMsg = "Invalid Account currency.";
680		}
681	}
682
683	function setGridDetails(isValidate) {
684		$scope.uploadInProgress = false;
685		$scope.tableViewby = "10";
686		$scope.tableTotalItems = ($scope.payeeList != undefined) ? $scope.payeeList.length : 0;
687		$scope.tableCurrentPage = 1;
688		$scope.tableItemsPerPage = $scope.tableViewby;
689		if (!isValidate) {
690			$scope.uploadProcessed = true;
691			$("#bulkBeneficiary-finish").addClass("btn-circle-2-current");
692			$("#bulkBeneficiary-review").removeClass("btn-circle-2-current");
693			$scope.bulkBeneUploadForm = false;
694			$scope.bulkBeneReviewGrid = true;
695		}
696	}
697	$scope.setCountryDetails = function (payeeObj, bankIsoCountryCodeList, loadWireTransferFields, payeeList) {
698		if (!loadWireTransferFields) {
699			var selectedCountry = $scope.getCountryObject(payeeObj.bankCountry);
700			var beneficiaryCountry = $scope.getCountryObject(payeeObj.legalAddress.country);
701			if (beneficiaryCountry) {
702				payeeObj.legalAddress.country = beneficiaryCountry.country;
703				payeeObj.legalAddress.isoCountryCode = beneficiaryCountry.code;
704				isBeneficiaryCountryValid = false;
705			} else {
706				payeeObj.legalAddress.country = null;
707			}
708		}
709		if (selectedCountry) {
710			if (!loadWireTransferFields) {
711				payeeObj.NBIDLabel = selectedCountry.nationalBankIdentifierLabel;
712				payeeObj.bankIsoCountryCode = selectedCountry.code;
713				payeeObj.accountWithBank.countryName = selectedCountry.country;
714				payeeObj.accountWithBank.isoCountryCode = selectedCountry.code;
715				payeeObj.nationalBankAccountNumberLabel = selectedCountry.nationalBankAccountNumberLabel;
716				payeeObj.NBIDLabel = payeeObj.NBIDLabel ? payeeObj.NBIDLabel : "National ID";
717			}
718
719			if (!loadWireTransferFields) {
720				if (payeeObj.isInternational && payeeObj.intermediaryCountry) {
721					var selectedCountry = $scope.getCountryObject(payeeObj.intermediaryCountry);
722					$scope.setIntermediaryCountryDetails(payeeObj, selectedCountry);
723				}
724			}
725		}
726		if (loadWireTransferFields) {
727			PayeeNewEditService.getWireTransferFieldsByCountries(bankIsoCountryCodeList).then(function (data) {
728				angular.forEach(payeeList, function (payeeListValue) {
729					angular.forEach(data.responseObj, function (wirefieldValue, wirefieldKey) {
730						if (payeeListValue.bankIsoCountryCode == wirefieldKey && wirefieldValue != null && wirefieldValue) {
731							var WireTransferFieldsKeys = wirefieldValue;
732							var wireTransFields = {};
733							if (WireTransferFieldsKeys != null && WireTransferFieldsKeys.length == 0) {
734								payeeListValue.wtfReqd = false;
735							} else {
736								payeeListValue.wtfReqd = true;
737							}
738							angular.forEach(WireTransferFieldsKeys, function (value) {
739								angular.forEach(payeeListValue.wireTransferFields, function (v, k) {
740									if (value.fieldLabel == k) {
741										wireTransFields[value.fieldName] = v;
742									}
743								});
744							});
745							payeeListValue.wireTransferFields = wireTransFields;
746						}
747					})
748				})
749			});
750		}
751	}
752
753	$scope.setIntermediaryCountryDetails = function (payeeObj, filteredCountry) {
754		payeeObj.intermediaryNBIDLabel = filteredCountry.nationalBankIdentifierLabel;
755		payeeObj.intermediaryCountryCode = filteredCountry.code;
756		payeeObj.intermediaryBank.countryName = filteredCountry.country;
757		payeeObj.intermediaryNBIDLabel = payeeObj.intermediaryNBIDLabel ? payeeObj.intermediaryNBIDLabel : "National ID";
758		payeeObj.intermediaryBank.isoCountryCode = filteredCountry.code;
759	}
760
761	$scope.getCountryObject = function (countryName) {
762		var filteredCountry = $filter('filter')($scope.countryObjList, { country: countryName.trim().toUpperCase() });
763		var selectedCountry = filteredCountry;
764		if (filteredCountry.length > 1) {
765			selectedCountry = $filter('filter')(filteredCountry, function (value) {
766				return value.country.toUpperCase() == countryName.trim().toUpperCase();
767			});
768		}
769		return selectedCountry ? selectedCountry[0] : null
770	}
771
772	$scope.buildBeneficiaryObject = function (payee) {
773		//var d = $q.defer();
774		//$timeout(function () {
775		if (payee.category == "Domestic") {
776			payee.isInternational = false;
777			payee.accountCcy = $rootScope.domesticCountryAccCcy;
778			payee.legalAddress.isoCountryCode = $rootScope.domesticCountryIsoCode;
779		} else {
780			payee.isInternational = true;
781		}
782		//d.resolve();
783		//});
784		//return d.promise;
785	}
786
787	$scope.setTableItemsPerPage = function (num) {
788		$scope.tableItemsPerPage = num;
789		$scope.tableCurrentPage = 1;
790	}
791
792	$scope.filterByTemplate = function () {
793		$scope.filteredPayeeList = $filter('filter')($scope.payeeList, { aliasName: this.searchByTemplate });
794		$scope.tableTotalItems = ($scope.filteredPayeeList != undefined) ? $scope.filteredPayeeList.length : 0;
795	}
796
797	$scope.abortBulkBeneficiaryUpload = function () {
798		//$state.go($state.current, {}, {reload: true});
799		$state.reload($state.current); // This is look for current state or even states we're coming from.
800	}
801
802	$scope.removeSelectedBeneficiary = function () {
803		if ($("#allBeneficiary").is(":checked")) {
804			$scope.payeeList = [];
805			$scope.filteredPayeeList = [];
806			$scope.abortBulkBeneficiaryUpload();
807		} else {
808			$(".beneficiaryi-list:checked").each(function (i, val) {
809				$scope.payeeList.splice(val, 1);
810			});
811		}
812	}
813
814	$scope.changeBeneficiary = function () {
815		if ($(".beneficiaryi-list:checked").length == $scope.payeeList.length) {
816			$("#allBeneficiary").prop("checked", true);
817		} else {
818			$("#allBeneficiary").prop("checked", false);
819		}
820	}
821
822	$scope.changeAllBeneficiary = function () {
823		if ($("#allBeneficiary").is(":checked")) {
824			$scope.allBeneficiary = true;
825		} else {
826			$scope.allBeneficiary = false;
827		}
828		$("input:checkbox[class=beneficiaryi-list]").prop('checked', $scope.allBeneficiary);
829	}
830
831	$scope.editBeneficiary = function (index, tableCurrentPage) {
832		$timeout(function () {
833			var recordsPerPage = parseInt($scope.tableItemsPerPage);
834			var indexNum = (tableCurrentPage * recordsPerPage) - recordsPerPage + index;
835			$scope.payee = angular.copy($scope.payeeList[indexNum]);
836			var payeeCountry = $scope.getCountryObject($scope.payee.bankCountry);
837			$scope.populateCountryDetails(payeeCountry, "");
838			if ($scope.payee.isInternational && $scope.payee.intermediaryCountry) {
839				var intermediaryCountry = $scope.getCountryObject($scope.payee.intermediaryCountry);
840				$scope.populateCountryDetails(intermediaryCountry, "intermediaryBank");
841			}
842			$scope.editPayeeId = angular.copy(indexNum);
843			$scope.bulkBeneReviewGrid = false;
844			$scope.bulkBeneEditForm = true;
845			$scope.viewOnly = false;
846		}, 1000);
847	}
848
849	$scope.deleteBeneficiary = function (index, tableCurrentPage) {
850		var recordsPerPage = parseInt($scope.tableItemsPerPage);
851		var indexNum = (tableCurrentPage * recordsPerPage) - recordsPerPage + index;
852		var payee = $scope.payeeList[indexNum];
853		if(payee.status=="Validated"){
854			$scope.beneUploadValidatedCount--;
855		}
856		$scope.payeeList.splice(indexNum, 1);
857		$scope.tableTotalItems = ($scope.payeeList != undefined) ? $scope.payeeList.length : 0;
858	}
859
860	/***********************************************
861	|	Modify the Benificiary Object and validate  |
862	***********************************************/
863	$scope.modifyAndValidateBeneficiary = function () {
864		$scope.payeeList[$scope.editPayeeId] = $scope.payee;
865		var swiftChar = $scope.payee.accountWithBank.bic;
866		var nationalId = $scope.payee.accountWithBank.nationalId;
867		var isoCountryCode = $scope.payee.bankIsoCountryCode;
868		var imSwiftChar, imNationalId, imIsoCountryCode, isValidBank = true, isValidImBank = true;
869		if (!$scope.payee.intermediaryBank && (!swiftChar && !nationalId) || !$scope.payee.bankCountry) {
870			$scope.payee.status = "Error";
871			$scope.payee.errorMsg = "Bank details are incorrect. Please correct and try again.";
872			isValidBank = false;
873		}
874
875		if ($scope.payee.intermediaryCountry && isValidBank) {
876			//if(isValidBank){
877			if($scope.payee.intermediaryBank) {
878				imSwiftChar = $scope.payee.intermediaryBank.bic;
879				imNationalId = $scope.payee.intermediaryBank.nationalId;
880				imIsoCountryCode = $scope.payee.intermediaryCountryCode;
881			}
882			if ((!imSwiftChar && !imNationalId) || !$scope.payee.intermediaryCountry) {
883				$scope.payee.status = "Error";
884				$scope.payee.errorMsg = "Intermediary Bank details are incorrect. Please correct and try again.";
885				isValidImBank = false;
886			}
887		}
888
889		if(!$scope.payee.intermediaryCountry && $scope.payee.intermediaryBank &&  ($scope.payee.intermediaryBank.bic || $scope.payee.intermediaryBank.nationalId)) {
890			$scope.payee.status = "Error";
891			$scope.payee.errorMsg = "Intermediary Bank details are incorrect. Please correct and try again.";
892			isValidImBank = false;
893		}
894
895		if (isValidBank && isValidImBank) {
896			validateSwiftAndNID(isoCountryCode, swiftChar, nationalId, "");
897		}
898
899		function validateSwiftAndNID(countryCode, swiftCode, Nid, text) {
900			if (swiftCode) {
901				BankService.searchBanksWithSwift(countryCode, swiftCode).then(function (response) {
902					//setValidationStatus(response,text);
903					if (response.success && response.responseObj.length == 0) {
904						setValidationStatus(response, "SWIFT_NOT_VERIFIED");
905					} else {
906						setValidationStatus(response, text);
907					}
908				});
909			} else if (Nid) {
910				BankService.searchBanksWithNBID(countryCode, Nid).then(function (response) {
911					setValidationStatus(response, text)
912				});
913			} else if ($scope.payee.intermediaryBank) {
914				BankService.searchBanksWithSwift($scope.payee.intermediaryCountryCode, $scope.payee.intermediaryBank.bic).then(function (response) {
915					if (response.success && response.responseObj.length == 0) {
916						warnSwiftNotVerified();
917					}
918					serviceValidate();
919				})
920					.catch(function (fallback) {
921						console.error("Error: ", fallback);
922					});
923			} else {
924				$scope.payee.status = "Error";
925				$scope.payee.errorMsg = text + "Bank details are incorrect. Please correct and try again.";
926			}
927		}
928		function setValidationStatus(response, text) {
929			if (response.success && response.responseObj.length > 0) {
930				if ($scope.payee.intermediaryCountry && text == "") {
931					validateSwiftAndNID(imIsoCountryCode, imSwiftChar, imNationalId, "Intermediary ");
932				} else {
933					serviceValidate();
934				}
935			} else if (text == "SWIFT_NOT_VERIFIED") {
936				serviceValidate();
937				warnSwiftNotVerified();
938			} else {
939				$scope.payee.status = "Error";
940				$scope.payee.errorMsg = text + "Bank details are incorrect. Please correct and try again.";
941			}
942		}
943		function sanitizeIntermediaryBank() {
944			if(!$scope.payee.intermediaryBank)
945				return;
946			if(!$scope.payee.intermediaryCountry && !$scope.payee.intermediaryBank.bic && !$scope.payee.intermediaryBank.nationalId) {
947				$scope.payee.intermediaryBank = null;
948			}
949		}
950		function serviceValidate() {
951			sanitizeIntermediaryBank();
952			PayeeNewEditService.validateBeneficiary($scope.payee, true).then(function (response) {
953				if (response.success) {
954					$scope.payee.status = "Validated";
955					$rootScope.beneUploadValidatedCount = $rootScope.beneUploadValidatedCount + 1;
956				} else if (response.errorCode == "PSI_10") {
957					$scope.payee.status = "Duplicate";
958					$scope.payee.errorMsg = response.errorResponse;
959				} else {
960					$scope.payee.status = "Error";
961					$scope.payee.errorMsg = response.errorResponse;
962				}
963				if (!response.success) {
964					$scope.payee.errorMsg = response.errorResponse;
965					$.jGrowl(response.errorResponse, {
966						sticky: false,
967						life: jGrowlLife,
968						position: 'center',
969						theme: 'notification-size notification-alert'
970					});
971				}
972				$scope.gotoReview();
973			});
974		}
975
976	}
977
978	$scope.gotoReview = function () {
979		$scope.payee = {};
980		$scope.bulkBeneReviewGrid = true;
981		$scope.bulkBeneViewForm = false;
982		$scope.bulkBeneEditForm = false;
983		$scope.viewOnly = false;
984	}
985
986	/***********************************************
987	|			Bank lookup based on SWIFT	   	   |
988	***********************************************/
989	$scope.searchBanksWithSwift = function (swiftChar, searchFor) {
990		var isoCountryCode = "intermediaryBank" == searchFor ? $scope.payee.intermediaryCountryCode : $scope.payee.bankIsoCountryCode;
991
992		return BankService.searchBanksWithSwift(isoCountryCode, swiftChar).then(function (response) {
993			if (response.success) {
994				if (response.responseObj.length > 0) {
995					if (response.responseObj.length == 1) {
996						if ("intermediaryBank" == searchFor) {
997							$scope.payee.intermediaryBank = response.responseObj[0];
998						} else {
999							$scope.payee.accountWithBank = response.responseObj[0];
1000						}
1001						return false;
1002					}
1003					return limitToFilter(response.responseObj, 10);
1004				}
1005			}
1006		});
1007	};
1008
1009
1010	$scope.populateBankDetail = function (bank) {
1011		$scope.payee.accountWithBank = bank;
1012	}
1013
1014	$scope.populateInterBankDetail = function (bank) {
1015		$scope.payee.intermediaryBank = bank;
1016	}
1017
1018	/***********************************************
1019	|			Bank lookup based on NID	   	   |
1020	***********************************************/
1021	$scope.searchBanksWithNBID = function (nbidChar, formName) {
1022		var isoCountryCode = formName == "intermediaryBank" ? $scope.payee.intermediaryCountryCode : $scope.payee.bankIsoCountryCode;
1023		return BankService.searchBanksWithNBID(isoCountryCode, nbidChar).then(function (response) {
1024			if (response.success) {
1025				if (response.responseObj.length > 0) {
1026					if (response.responseObj.length == 1 && response.responseObj[0].nationalId == nbidChar) {
1027						if (formName == "intermediaryBank") {
1028							$scope.payee.intermediaryBank = response.responseObj[0];
1029						} else {
1030							$scope.payee.accountWithBank = response.responseObj[0];
1031						}
1032						return false;
1033					}
1034					return limitToFilter(response.responseObj, 10);
1035				}
1036			}
1037		});
1038	};
1039
1040	/***********************************************
1041	| Populate Country details on country select   |
1042	***********************************************/
1043	$scope.populateCountryDetails = function (
1044		selectedCountry, formName) {
1045		if (formName != "intermediaryBank") {
1046			var tempCcyList = selectedCountry.paymentCurrencies;
1047			if (tempCcyList) {
1048				$scope.ccyList = tempCcyList.split(',');
1049			}
1050			$scope.payee.NBIDLabel = selectedCountry.nationalBankIdentifierLabel;
1051			$scope.payee.bankIsoCountryCode = selectedCountry.code;
1052			$scope.payee.accountWithBank.countryName = selectedCountry.country;
1053			$scope.payee.nationalBankAccountNumberLabel = selectedCountry.nationalBankAccountNumberLabel;
1054			$scope.payee.NBIDLabel = $scope.payee.NBIDLabel ? $scope.payee.NBIDLabel
1055				: "National ID";
1056			PayeeNewEditService.getWireTransferFields($scope.payee.bankIsoCountryCode).then(function (data) {
1057				$scope.payee.WireTransferFieldsKeys = data.responseObj;
1058				if ($scope.payee.WireTransferFieldsKeys != null && $scope.payee.WireTransferFieldsKeys.length == 0) {
1059					$scope.payee.wtfReqd = false;
1060				} else {
1061					$scope.payee.wtfReqd = true;
1062				}
1063			});
1064		} else {
1065			$scope.payee.intermediaryNBIDLabel = selectedCountry.nationalBankIdentifierLabel;
1066			$scope.payee.intermediaryCountryCode = selectedCountry.code;
1067			$scope.payee.intermediaryBank.countryName = selectedCountry.country;
1068			$scope.payee.intermediaryNBIDLabel = $scope.payee.intermediaryNBIDLabel ? $scope.payee.intermediaryNBIDLabel
1069				: "National ID";
1070		}
1071	}
1072	// checking country based data 
1073	$scope.countryExist = function (country,source,isBeneCountry){
1074        if($scope.countryObjList && $scope.countryObjList.length == 0){
1075            console.error("country list is empty");return;
1076        }
1077        if(!country){
1078            console.error("country parameter should not be empty");return;
1079        }
1080        var filteredCountry = $.grep($scope.countryObjList, function(elem){ return elem.country.toLowerCase() == country.toLowerCase(); });
1081        if(filteredCountry.length == 1){
1082            if(isBeneCountry){
1083                $scope.payee.legalAddress.country = filteredCountry[0].country;
1084            }else if(source=="intermediaryBank"){
1085                $scope.payee.intermediaryCountry = filteredCountry[0].country;
1086            }else{
1087                $scope.payee.bankCountry = filteredCountry[0].country;
1088            }
1089            $scope.populateCountryDetails(filteredCountry[0],source);
1090        }
1091        return filteredCountry.length == 0 ? false : true;
1092    };
1093
1094	$scope.resetPayeeBankDetails = function () {
1095		$scope.payee.WireTransferFieldsKeys = {};
1096		$scope.payee.accountWithBank.bic = '';
1097		$scope.payee.accountWithBank.city = '';
1098		$scope.payee.accountWithBank.institutionName = '';
1099		$scope.payee.accountWithBank.streetAddress1 = '';
1100		$scope.payee.accountCcy = '';
1101		$scope.payee.accountNumber = '';
1102	}
1103
1104	$scope.isCountryAvailable = function (){
1105		$scope.countryNotAvailableMsg = false;
1106		$scope.resetPayeeBankDetails();
1107		let country = $('[name=country]').val().trim();
1108		if( country && !$scope.countryExist( country,"",true )){
1109			$scope.countryNotAvailableMsg = true;
1110			$scope.payee.legalAddress.country = null;
1111		}
1112	};
1113
1114	$scope.isBankCountryAvailable = function (){
1115		$scope.bankCountryNotAvailableMsg = false;
1116		$scope.resetPayeeBankDetails();
1117		let bankCountry = $('[name=payeeBankCountry]').val().trim();
1118		if( bankCountry && !$scope.countryExist( bankCountry ) ){
1119			$scope.bankCountryNotAvailableMsg = true;
1120			$scope.payee.bankCountry = null;
1121		}
1122	};
1123	$scope.isImBankCountryAvailable = function (){
1124		$scope.imBankCountryMsg = false;
1125		let bankCountry = $('[name=payeeIntermediaryCountry]').val().trim();
1126		if( bankCountry && !$scope.countryExist( bankCountry,"intermediaryBank" ) ){
1127			$scope.imBankCountryMsg = true;
1128			$scope.payee.intermediaryCountry = null;
1129		}
1130	};
1131
1132	/***********************************************
1133	|			Bank lookup based on SWIFT	   	   |
1134	***********************************************/
1135	$scope.searchBanksWithRoutingNo = function (nbidChar) {
1136
1137		return BankService.searchBanksWithNBID("US", nbidChar).then(function (response) {
1138			if (response.success) {
1139				if (response.responseObj.length > 0) {
1140					if (response.responseObj.length == 1 && response.responseObj[0].nationalId == nbidChar) {
1141						$scope.populateBankDetail(response.responseObj[0]);
1142						return false;
1143					}
1144					return limitToFilter(response.responseObj, 10);
1145				}
1146			}
1147		});
1148	};
1149
1150	$scope.displayAddress = function (bank) {
1151		var str = "";
1152		if (bank.city) {
1153			str += bank.city;
1154		}
1155		if (bank.zipCode) {
1156			if (str) str += ",";
1157			str += bank.zipCode;
1158		}
1159		if (bank.countryName) {
1160			if (str) str += ",";
1161			str += bank.countryName;
1162		}
1163		return str;
1164	}
1165
1166	/***********************************************
1167	|			Get Unique object list by fieldname	|
1168	***********************************************/
1169	function uniqueArraybyKey(collection, keyname) {
1170		var output = [], keys = [];
1171		angular.forEach(collection, function (item) {
1172			var key = item[keyname];
1173			if (keys.indexOf(key) === -1) {
1174				keys.push(key);
1175				output.push(item);
1176			}
1177		});
1178		return output;
1179	}
1180
1181	$scope.validateBeneBulkUploadFields = function (fileData) {
1182		var success = true;
1183		if (fileData) {
1184			var OBIIndx = fileData[0].indexOf('OBI');
1185			var headCols = fileData[0];
1186			var regex = new RegExp("^[(\r\n) A-Za-z0-9/?:().,'+ -]*$"); // X-Char Set
1187			var mxRegex = new RegExp("^[0-9a-zA-Z\/\\-\\?:\\(\\)\\.,'\\+ !#$%&\\*=^_`\\{\\|\\}~\";<>@\\[\\\\\\]\\r\\n]*$");
1188			var errorColsList = [];
1189			var invalidLengthList = [];
1190			var swiftLengthList = [];
1191			var mxInvalidLengthList = [];
1192            var mxErrorColsList = [];
1193
1194			angular.forEach(headCols, function (headCol, index) {
1195				angular.forEach(fileData, function (value, key) {
1196					if (key != "0") {// Skipping Header row names
1197					var cellValue = value[index];
1198						if ((headCol.search("BankSWIFT") != -1 && cellValue != "") && (cellValue.length < 8 | cellValue.length > 11)) {
1199							success = false;
1200							swiftLengthList.push(parseInt(key) + 1 + " " + headCol);
1201						}
1202						if (headCol == "OBI" && cellValue.length > 140) {
1203							success = false;
1204							invalidLengthList.push(parseInt(key) + 1 + " " + headCol);
1205						}
1206						if (!$rootScope.isSwiftMXMessage) {
1207						if (headCol != "Beneficiary Email" && headCol.search("RegulatoryField.LABEL") == -1) {
1208							var isValidChar = regex.test(value[index]);
1209							if (!isValidChar) {
1210								success = false;
1211								errorColsList.push(parseInt(key) + 1 + " " + headCol);
1212							}
1213						}
1214						}
1215						else {
1216                            var mxFields = ["Beneficiary Name*", "Beneficiary Address1*", "Beneficiary Address2", "Beneficiary City*", "Beneficiary State", "Beneficiary Postalcode", "Beneficiary BankName", "Beneficiary BankCity"];
1217                            if (headCol != "Beneficiary Email" && headCol.search("RegulatoryField.LABEL") == -1 && mxFields.indexOf(headCol) === -1) {
1218                                var isValidChar = regex.test(value[index]);
1219                                if (!isValidChar) {
1220                                    success = false;
1221                                    errorColsList.push(parseInt(key) + 1 + " " + headCol);
1222                                }
1223                            }
1224                        }
1225						if (headCol.search("RegulatoryField.LABEL") != -1 && value[index] != "") {
1226							//console.log("RegulatoryField {}", headCol.split(".")[2] + ": " + value[index]);
1227							if (!regex.test(value[index])) {
1228								success = false;
1229								errorColsList.push(parseInt(key) + 1 + " " + headCol);
1230							}
1231						}
1232						if ($rootScope.isSwiftMXMessage) {
1233                            var fieldMaxLength = {
1234                                "Beneficiary Name*": 140,
1235                                "Beneficiary Address1*": 70,
1236                                "Beneficiary Address2": 70,
1237                                "Beneficiary City*": 35,
1238                                "Beneficiary State": 35,
1239                                "Beneficiary Postalcode": 16,
1240                                "Beneficiary BankName": 140,
1241                                "Beneficiary BankCity": 35
1242                            };
1243                            angular.forEach(fieldMaxLength, function (maxLen, fieldName) {
1244                                if (headCol === fieldName) {
1245                                    if (cellValue.length > maxLen) {
1246                                        success = false;
1247                                        mxInvalidLengthList.push((parseInt(key) + 1) + " " + headCol + " (max " + maxLen + " chars)");
1248                                    }
1249                                    if (cellValue && !mxRegex.test(cellValue)) {
1250                                        success = false;
1251                                        mxErrorColsList.push((parseInt(key) + 1) + " " + headCol);
1252                                    }
1253                                }
1254                            });
1255                        }
1256					} // end first if
1257				});
1258			});
1259			if (invalidLengthList.length > 0) {
1260				showErrorMsg(invalidLengthList, "lengthErr");
1261				success = false;
1262			}
1263			if (errorColsList.length > 0) {
1264				showErrorMsg(errorColsList, "X-CharErr");
1265				success = false;
1266			}
1267			if (mxInvalidLengthList.length > 0) {
1268                showErrorMsg(mxInvalidLengthList, "mxLengthErr");
1269                success = false;
1270            }
1271            if (mxErrorColsList.length > 0) {
1272                showErrorMsg(mxErrorColsList, "mxCharErr");
1273                success = false;
1274            }
1275			if (swiftLengthList.length > 0) {
1276				showErrorMsg(swiftLengthList, "swiftLengthErr");
1277				success = false;
1278			}
1279			if (!success) {
1280                return;
1281            }
1282		} // End of IF
1283		return success;
1284	}
1285	$scope.convertWireTransferFields = function (payeeObj) {
1286		//var d = $q.defer();
1287		$timeout(function () {
1288			if (payeeObj.bankIsoCountryCode)
1289				PayeeNewEditService.getWireTransferFields(payeeObj.bankIsoCountryCode).then(function (data) {
1290					var wireTransferFieldsKeys = data.responseObj;
1291					var wireTransFields = {};
1292					angular.forEach(wireTransferFieldsKeys, function (value) {
1293						angular.forEach(payeeObj.wireTransferFields, function (v, k) {
1294							if (value.fieldLabel == k) {
1295								wireTransFields[value.fieldName] = v;
1296							}
1297						});
1298					});
1299					payeeObj.wireTransferFields = wireTransFields;
1300				});
1301			//d.resolve();
1302		});
1303		//return d.promise;
1304	}
1305
1306	function showErrorMsg(columnName, errType) {
1307		var colName;
1308		var errorMsg;
1309		if (angular.isArray(columnName) && errType == "X-CharErr") {
1310			colName = 'At row ' + columnName.join("<br> At row ");
1311			errorMsg = colName + " <br>Invalid Swift Char entered. Allowed CharSet is : A-Za-z0-9/?:().,'+-CrLf Space";
1312		}
1313		if (angular.isArray(columnName) && errType == "lengthErr") {
1314			colName = 'At row ' + columnName.join("<br> At row ");
1315			errorMsg = colName + " <br>column not allow more than 140 characters";
1316		}
1317		if (angular.isArray(columnName) && errType == "mxCharErr") {
1318            colName = 'At row ' + columnName.join("<br> At row ");
1319            errorMsg = colName + " <br>Invalid Swift Char entered. Allowed CharSet is : /\\-?:().,'+ !#$%&*=^_`{|}~\";<>@[] CrLf Space";
1320        }
1321        if (angular.isArray(columnName) && errType == "mxLengthErr") {
1322            errorMsg = 'At row ' + columnName.join("<br> At row ");
1323        }
1324		if (angular.isArray(columnName) && errType == "MandatoryFieldEmpty") {
1325			colName = 'At row ' + columnName.join("<br> At row ");
1326			errorMsg = colName + " <br>Cannot be empty";
1327		}
1328		if (angular.isArray(columnName) && errType == "swiftLengthErr") {
1329			colName = 'At row ' + columnName.join("<br> At row ");
1330			errorMsg = colName + " <br>column allow min 8 and max 11 characters";
1331		}
1332		if (angular.isArray(columnName) && errType == "invalidRecipientType") {
1333			colName = 'At row ' + columnName.join("<br> At row ");
1334			errorMsg = colName + " <br>Invlid/unsupported RecipientType.";
1335		}
1336		if (errType == "countryInvalid") {
1337			errorMsg = "File contains invalid country name<br> Please correct and try again.";
1338		}
1339		$("#bulkBeneficiary-upload").addClass("btn-circle-2-current");
1340		$("#bulkBeneficiary-review").removeClass("btn-circle-2-current");
1341		$scope.bulkBeneUploadForm = true;
1342		$scope.bulkBeneReviewGrid = false;
1343		$scope.uploadInProgress = false;
1344		$.jGrowl(errorMsg, {
1345			sticky: false,
1346			life: jGrowlLife,
1347			theme: 'alert alert-danger ',
1348
1349		});
1350	}
1351
1352	// If found any element in an array, returns its index else -1
1353	$scope.searchValFromArray = function (value, arr) {
1354		var isExist = -1; // default val not exist
1355		for (var i = 0; i < arr.length; i++) {
1356			isExist = arr[i].search(value);
1357			if (isExist != -1) {
1358				isExist = parseInt(i); // assigning index
1359				break;
1360			}
1361		}
1362		// return val as index
1363		return isExist;
1364	};
1365
1366	function warnSwiftNotVerified() {
1367		$.jGrowl("Unable to verify swift code", {
1368			header: 'Warning!',
1369			life: jGrowlLife,
1370			sticky: true,
1371			theme: 'alert alert-warning',
1372		});
1373	}
1374	$scope.removeSpaces = function () {
1375		if ($scope.payee.accountNumber) {
1376			$scope.payee.accountNumber = $scope.payee.accountNumber.replace(/\s+/g, '').toUpperCase();
1377		}
1378	};
1379}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.