PageSourceSearch

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

js firstcitizens.com collected 2026-09-24 21:51:18 UTC 139,680 bytes, 3,660 lines download raw bytes

1var app = angular.module('bossApp');
2app.controller('paymentCtrl', ['$compile','$scope', '$rootScope', '$http', '$timeout','$state', '$interval', 'PayeeNewEditService', 'AccountSummaryService', 'PaymentService','$anchorScroll', '$location','TwoFAService','$stateParams','CommonService','PinService','$interpolate','$filter','$modal','LegalEntityService',
3    function($compile,$scope, $rootScope, $http, $timeout, $state, $interval , PayeeNewEditService, AccountSummaryService, PaymentService,$anchorScroll, $location,TwoFAService,$stateParams,CommonService,PinService,$interpolate,$filter,$modal,LegalEntityService) {
4		var EXCHANGE_RATE_REJECTED_USER_MSG = 'Exchange Rate Rejected. You can Request Another Rate.';
5		$scope.isExchangeRateRejectedBannerVisible = function () {
6			return $scope.expMsg === EXCHANGE_RATE_REJECTED_USER_MSG;
7		};
8	$scope.numberOfDecimals = 2;
9	$scope.minRecurringEndDate=null;
10	$scope.waitForGetRate=true;
11	$scope.isReinstruct=false;
12	$scope.rejectRateBtnDisable=false;
13	$scope.acceptRateBtnDisable=false;
14	$scope.hideGetRateBtn=false;
15	$scope.showGetRateForPricingCustomerMessage = false;
16	$scope.missedPaymentRepriceGotRate = false;
17	$scope.initiatorIndicativeDisclaimerAfterSuccessfulRate = false;
18	$scope.indicativeRateDisclaimerPrefix = "Rates shown are indicative";
19	$scope.ratetxtInverse = "";
20	$scope.isCurrentUserFinalApprover=false;
21	$scope.disableResubmit = true;
22	$scope._suppressResubmitWatch = false;
23	$scope.currentApprovalLevel=0; // Track which approval level this payment is at
24	$scope.showCancelButton=true;
25	$rootScope.showUiSref = true;
26	$scope.isPaymentWatchenabled = false;
27	$scope.hideApprovePayment = false;
28	if ($rootScope.defaultCharges && $rootScope.clientChargeTypes && $rootScope.clientChargeTypes.indexOf($rootScope.defaultCharges) == -1) {
29		$rootScope.clientChargeTypes = $rootScope.defaultCharges + "," + $rootScope.clientChargeTypes;
30	} else if (!$rootScope.defaultCharges && $rootScope.clientChargeTypes) {
31		$rootScope.defaultCharges = $rootScope.clientChargeTypes.split(",")[0];
32	}
33	function watchPaymentObject() {
34		$scope.$watch('payment', function (newValue, oldValue) {
35			if (oldValue !== undefined && newValue !== oldValue) {
36				if (!$scope._suppressResubmitWatch) {
37					$scope.disableResubmit = false;
38					$scope.hideGetRateBtn = true;
39				}
40			} else {
41				$scope.disableResubmit = true;
42			}
43		}, true);
44		$timeout(function(){
45			$scope.isPaymentWatchenabled = true;
46		},1000);
47	}
48	function beginSuppressResubmitWatch() {
49		$scope._suppressResubmitWatch = true;
50	}
51	function endSuppressResubmitWatch() {
52		$timeout(function () {
53			$scope._suppressResubmitWatch = false;
54		}, 0);
55	}
56	var _user = angular.copy($rootScope.currentUser);
57		$scope.loading=true;
58		$scope.today = new Date();
59		$scope.today.setHours(0, 0, 0, 0);
60		$scope.minDate = new Date();
61		$scope.maxFutureDate = '';
62		$scope.pinVerified = false;
63		$scope.pinVerifyCallBackRequired = true;
64		$scope.isAllowedToApprovePayment = false;
65		LegalEntityService.getLE().then(function(data){
66			$scope.le = angular.copy(data.legalEntity);
67			$scope.deliveryMethodMap = angular.copy(data.deliveryMethodMap);
68			const le = $scope.le;
69			$scope.legalEntityValidationErrors = [];
70
71			if (le.fullName && le.fullName.length > 140) {
72				$scope.legalEntityValidationErrors.push("Legal Entity Full Name exceeds the maximum length of 140 characters.");
73			}
74
75			if (le.legalAddress) {
76				$scope.legalEntityValidationErrors = $scope.legalEntityValidationErrors.concat(validateAddress(le.legalAddress, "Legal Entity"));
77			}
78
79			if ($scope.legalEntityValidationErrors.length > 0) {
80				$scope.paymentNotAllowed = true;
81				var numberedErrors = $scope.legalEntityValidationErrors.map((err, index) => (index + 1) + ". " + err);
82				var errorMessage = ("<div style='color: red;'<b>Your 'Legal Entity' contains error(s). Please correct the following:</b><br><br></div>" + numberedErrors.join("<br>"));
83				bootbox.alert({
84					title: "Validation Error: Unable to Initiate Payment",
85					message: errorMessage,
86					closeButton: false,
87					className: 'bootbox-alert-custom'
88				});
89			}
90		});
91		// Recompute approver level when entity (le) loads, e.g. after opening payment for edit; also set noOfApprovalsRequiredForPayment for new payment
92		$scope.$watch('le', function (newLe) {
93			if (newLe && $scope.editPaymentMode && $scope.privateTrade && ($scope.privateTrade.status.id === 'PendingApproval' || $scope.privateTrade.status.id === 'PartiallyApproved')) {
94				$scope.determineApproverLevel();
95			}
96			if (newLe && !$scope.editPaymentMode && $scope.payment) {
97				$scope.noOfApprovalsRequiredForPayment = computeNoOfApprovalsRequiredFromEntity();
98			}
99		}, true);
100		// For new payment: compute noOfApprovalsRequiredForPayment from entity + amount so Accept/Reject show when below first approver limit
101		$scope.$watch(function () {
102			var p = $scope.payment;
103			return p && (p.paymentAmount != null || (p.fxSpotForward && (p.fxSpotForward.dealCcy || p.fxSpotForward.debitCcy || p.fxSpotForward.creditCcy)));
104		}, function () {
105			if (!$scope.editPaymentMode && $scope.le && $scope.payment) {
106				$scope.noOfApprovalsRequiredForPayment = computeNoOfApprovalsRequiredFromEntity();
107			}
108		});
109
110		$scope.accordionToggleEvents=function(){
111				var $active = $('#accordion .panel-collapse.show').prev().addClass('active');
112				$active.find('a').each(function() {
113					if ($(this).find('i.glyph-icon').length === 0) {
114						$(this).prepend('<i class="glyph-icon fa fa-minus"></i>');
115					}
116				});
117			   if($scope.editPaymentMode){
118					$("#accordion .panel-heading").addClass( "ui-state-disabled" );
119					$("#accordion .panel-heading").attr("disabled","disabled");
120					$('.accordion-toggle').attr("disabled","disabled");
121					$('.accordion-toggle').removeAttr("href");
122					$('#accordion .panel-heading').not($active).find('a').each(function() {
123						if ($(this).find('i.glyph-icon').length === 0) {
124							$(this).prepend('<i class="glyph-icon fa fa-minus"></i>');
125						}
126					});
127			   }else{
128					$('#accordion .panel-heading').not($active).find('a').each(function() {
129						if ($(this).find('i.glyph-icon').length === 0) {
130							$(this).prepend('<i class="glyph-icon fa fa-plus"></i>');
131						}
132					});
133					$('#accordion').off('show.bs.collapse hide.bs.collapse').on('show.bs.collapse', function(e) {
134						var $accordion = $('#accordion .panel-heading.active');
135						$accordion.removeClass('active');
136						$accordion.find('i.glyph-icon').removeClass('fa-minus').addClass('fa-plus');
137						$(e.target).prev().addClass('active').find('i.glyph-icon').removeClass('fa-plus').addClass('fa-minus');
138					}).on('hide.bs.collapse', function(e) {
139						$(e.target).prev().removeClass('active').find('i.glyph-icon').removeClass('fa-minus').addClass('fa-plus');
140					});
141			   }
142		 }
143
144		/*var chargeTypeOrder={"OUR":0,"BEN":1,"SHA":2};
145		PaymentService.feeChargeTypes(_user.entityId).then(function(response){
146			 if(response.success && response.responseObj!=null){
147				$scope.feeChargeTypes =sortChargeType(response.responseObj);
148			 }
149		});*/
150		$scope.feeChargeTypes=$rootScope.clientChargeTypes?$rootScope.clientChargeTypes.split(","):["OUR","BEN","SHA"];
151
152		function sortChargeType(items){
153			 var sortedList=[];
154			 angular.forEach(items,function(value,index){
155				sortedList[chargeTypeOrder[value]]=value;
156			 });
157			 angular.forEach(sortedList,function(value,index){
158				if(!value){
159					sortedList.splice(index, 1);
160				}
161			 });
162			 return sortedList;
163		 }
164
165		function paymentHasExternalParentRef(payment) {
166			if (!payment) return false;
167			var ref = payment.externalParentReferenceNumber;
168			return ref != null && String(ref).trim() !== '';
169		}
170		$scope.paymentHasExternalParentRef = paymentHasExternalParentRef;
171
172		// Helper to compute disabled state for Confirm/Save Payment button
173		$scope.isConfirmDisabled = function () {
174			if ($scope.paymentNotAllowed || $scope.uploadDocumentBtn || $scope.askConfirmCancel) {
175				return true;
176			}
177
178		    if ($scope.lockUiForStreamingCrossCcySession?.()) {
179		        return true;
180		    }
181
182		    if ($scope.msgEmailForm?.recipientEmailAddress?.$invalid) {
183		        return true;
184		    }
185
186		    if ($scope.isSameCurrency) {
187		        return false;
188		    }
189
190		    const saveEnabled =$scope.isSavePaymentEnabled ?? $rootScope.isSavePaymentEnabled;
191		    const dualApproval = $scope.isDualApprovalEnabled ?? $rootScope.isDualApprovalEnabled;
192		    const isFuturePayment = $scope.isFutureDatedPayment;
193
194		    if (saveEnabled && dualApproval) {
195		        const rateUnavailable =!$scope.displayExRateInfo;
196		        if (rateUnavailable && !isFuturePayment) {
197		            return true;
198		        }
199		    }
200		    else if (!$scope.rateaccepted && !isFuturePayment) {
201		        return true;
202		    }
203			if(!saveEnabled){
204				if ($scope.displayRateTimer || ($scope.isStramingRate && !$scope.rateaccepted)) {
205					return true;
206				}
207			}
208		    
209		    return false;
210		};
211
212		function updateCancelButtonVisibility() {
213			if ($scope.editPaymentMode && $scope.privateTrade) {
214				$scope.showCancelButton = false;
215				var pt = $scope.privateTrade;
216				if (pt.pricingStatus && pt.pricingStatus.id == "PriceInFuture") {
217					$scope.showCancelButton = true;
218				}
219				if ($rootScope.isSavePaymentEnabled && pt.status && (pt.status.id === "PendingApproval" || pt.status.id === "PartiallyApproved")) {
220					$scope.showCancelButton = true;
221				}
222				return;
223			}
224			if (!$scope.privateTrade && !$scope.askConfirmCancel) {
225				$scope.showCancelButton = true;
226			} else if ($rootScope.isSavePaymentEnabled) {
227				$scope.showCancelButton = true;
228			}
229		}
230
231		if($stateParams.paymentId){
232			$scope.hideGetRateBtn = true;
233      		$scope.noDataErrorMsg = '';
234			PaymentService.getPayment($stateParams.paymentId).then(function(response){
235				if(!response.success){
236					$scope.noDataErrorMsg = response.errorResponse ? response.errorResponse: 'Payment Not Found';
237					return
238				}
239				$scope.privateTrade = response.responseObj;
240				rememberMissedPaymentRepriceIfNeeded($scope.privateTrade);
241				$scope.payment = angular.copy(response.responseObj);
242				var fx = response.responseObj.fxSpotForward;
243				if (fx && fx.allInRate) {
244					$scope.previousAcceptedRate = { fxSpotForward: angular.copy(fx), externalRefId: response.responseObj.externalRefId };
245				}
246				$scope.editPaymentMode = true;
247				$scope.isStramingRate = false;
248				$scope.displayRateTimer = false;
249				$scope.displayExRateInfo = false;
250				$scope.quoteId = undefined;
251				$scope.ticketId = undefined;
252				$timeout.cancel(timer);
253				if ($scope.stopKnob) {
254					$scope.stopKnob();
255				}
256				updateCancelButtonVisibility();
257				if ($scope.privateTrade && $scope.privateTrade.status && ($scope.privateTrade.status.id === "PendingApproval" || $scope.privateTrade.status.id === "PartiallyApproved")
258                					&& $scope.privateTrade.pricingStatus && $scope.privateTrade.pricingStatus.id !== "PriceInFuture") {
259					$scope.isReinstruct = true;
260				}
261				//$scope.getSwiftMessage(response.responseObj.externalRefId);
262				loadAccounts(true);
263				$scope.isAllowedToApprove(response.responseObj);
264				if ($scope.privateTrade.status.id === 'PendingApproval' || $scope.privateTrade.status.id === 'PartiallyApproved') {
265					$scope.determineApproverLevel();
266				}
267			});
268		}else{
269			$scope.accordionToggleEvents();
270			loadAccounts(false);
271		}
272		$scope.hideRepeatThisPaymentDiv=true;
273		var hasRecurringPayment=$filter("contains")($rootScope.entitlements, 'BOSS_RECURRING_PAYMENT');
274		if(hasRecurringPayment){
275			$scope.hideRepeatThisPaymentDiv=false;
276		}
277
278		$rootScope.getSrefUrl = function(toState, $event) {
279			if ($event && angular.isFunction($event.preventDefault)) {
280				$event.preventDefault();
281				$event.stopPropagation();
282			}
283			if (!bypassStateRecurrsion) {
284				$scope.showWarningDialog({ menuNavigation: true }, toState, {});
285				return false;
286			}
287			if ($rootScope.showUiSref) {
288				$state.go(toState, {}, { reload: true, inherit: false, notify: false });
289			} else {
290				return false;
291			}
292		}
293
294		/***********************************************
295		| Confirm box if user navigates away from Form |
296		***********************************************/
297		let bypassStateRecurrsion;
298		$scope.$on('$stateChangeStart', function( event, toState, toParams, fromState ) {
299			if (bypassStateRecurrsion) return;
300			$scope.showWarningDialog(event,toState,toParams);
301		});
302
303		$rootScope.redirectToFxweb = function(url) {
304			if ($scope.paymentForm && $scope.paymentForm.$dirty && !$scope.paymentProcessed) {
305				$scope.showWarningDialog($scope,url,null,PaymentService.loadFxweb);
306			}else{
307				PaymentService.loadFxweb(url);
308			}
309		}
310
311		$rootScope.redirectToEximweb = function(id) {
312			var url = $(id).attr("data-redirectURL");
313			if ($scope.paymentForm && $scope.paymentForm.$dirty && !$scope.paymentProcessed) {
314				$scope.showWarningDialog($scope,url,null,PaymentService.loadEximweb);
315			}else{
316				PaymentService.loadEximweb(url);
317			}
318		}
319
320		$rootScope.redirectToMicroService = function(appUrl) {
321			if ($scope.paymentForm && $scope.paymentForm.$dirty && !$scope.paymentProcessed) {
322				$scope.showWarningDialog($scope,appUrl,null,PaymentService.loadMicroservices);
323			}else{
324				PaymentService.loadMicroservices(appUrl);
325			}
326		}
327
328		$timeout(function(){
329			$('#sidebar-menu a').each(function() {
330				$(this).removeAttr('href');
331				$(this).css('cursor', 'pointer');
332			});
333		},1000);
334
335		$scope.showWarningDialog = function(event, toState, toParams, callback) {
336			var menuNavigation = event && event.menuNavigation;
337			if (!$scope.editPaymentMode && $scope.rateaccepted && !$scope.paymentProcessed) {
338            	  if (event && event.currentScope && angular.isFunction(event.preventDefault)) {
339            			event.preventDefault();
340            	  }
341            	$.jGrowl("Please save the payment to proceed.", {
342            			sticky: false,
343            			life: 10000,
344            			position: 'top-right',
345            			theme: 'notification-size notification-error'
346            	});
347            	return;
348            }
349			if(!menuNavigation && !$scope.editPaymentMode && !$scope.showCancelButton && !$scope.rateaccepted){
350				if(event.currentScope){
351					event.preventDefault();
352				}
353				let toastrMsg = $scope.askConfirmCancel ? "Please Click Back Button" : "Please Accept or Reject the Rate"
354				$.jGrowl(toastrMsg, {
355					sticky: false,
356					life: 10000,
357					position: 'top-right',
358					theme: 'notification-size notification-error'
359				});
360				return;
361			}
362			var confirmationMessage = ($scope.rateaccepted ? "The payment is not cancelled by your action, but the data on recurring payment/uploaded documents and Message to recipient if any, will be lost. Do you want to Continue?" : "All changes will be lost. Do you want to continue?");
363			if($scope.isFutureDatedPayment || $scope.editPaymentMode){
364				confirmationMessage = "All changes will be lost. Do you want to continue?";
365			}
366			var _scope = menuNavigation ? $scope : (event.currentScope ? event.currentScope : event);
367			if (_scope.paymentForm && _scope.paymentForm.$dirty && !$scope.paymentProcessed) {
368				bypassStateRecurrsion = true;
369				if (event.currentScope) {
370					event.preventDefault();
371				}
372				bootbox.confirm({
373					title: "Discard Changes?",
374					message: confirmationMessage,
375					swapButtonOrder: true,
376					closeButton: false,
377					buttons: {
378						confirm: { label: 'Yes', className: 'btn-primary' },
379						cancel: { label: 'No', className: 'btn-danger' }
380					},
381					callback: function(result) {
382						if (result) {
383							if ($scope.payment.status == "WaitingRFQ" && !$scope.rateaccepted) {
384								var isPaymentNotSaved = $scope.isSavePaymentEnabled && $scope.payment.id && !$scope.editPaymentMode;
385								if (isPaymentNotSaved) {
386									PaymentService.cancelPayment($scope.payment.id, null).then(function (response) {
387									});
388								}
389								canPoll = false;
390								if ($scope.pricingStatusId != "RejectedByTrader") {
391									$scope.cancelRate();
392								}
393							}
394							if(callback){
395								callback(toState);
396							}else{
397								$state.go(toState, toParams, { reload: true, inherit: false, notify: true });
398							}
399							canPoll = false;
400							return result;
401						} else {
402							canPoll = true;
403							bypassStateRecurrsion = false;
404						}
405					}
406				}); // End confirm box
407			} else {
408				if(callback){
409					callback(toState);
410				}else{
411					bypassStateRecurrsion = true;
412					$state.go(toState, toParams, { reload: true, inherit: false, notify: false });
413					$timeout(function() {
414						bypassStateRecurrsion = false;
415					}, 0);
416					return;
417				}
418			}
419		}
420
421		$scope.swiftMessageFiles = [];
422		$scope.getSwiftMessage = function(externalRefId) {
423			PaymentService.getSwiftMessage(externalRefId).then(function(response) {
424				if (response.responseObj && response.responseObj.messageStr) {
425					const msgStr = response.responseObj.messageStr;
426					var blobData = new Blob([msgStr], { type: 'text/plain' });
427					var blobURL = URL.createObjectURL(blobData);
428					response.responseObj.directory = blobURL;
429					response.responseObj.fileName = externalRefId + "_SWIFT_MT103_message.txt";
430					$scope.swiftMessageFile = response.responseObj;
431				}
432			});
433		}
434
435		$scope.isAllowedStatusForMissedPayments = function(privateTrade) {
436            return privateTrade && privateTrade.status && (privateTrade.status.id === 'PendingApproval' || privateTrade.status.id === 'PartiallyApproved');
437        }
438
439		$scope.downloadDocument = function(url, tradeNo) {
440			const tempLink = document.createElement('a');
441			tempLink.href = url;
442			tempLink.download = tradeNo + '_SWIFT_MT103_message.txt';
443			document.body.appendChild(tempLink);
444			tempLink.click();
445			document.body.removeChild(tempLink);
446		}
447		/**
448		* Get To Account and From AccountList.
449		*/
450		function loadAccounts(showInActiveAccounts){
451			var accountIds = $scope.privateTrade && $scope.privateTrade.fromAccId ? $scope.privateTrade.fromAccId : null;
452			if(accountIds && $scope.privateTrade.fxSpotForward.deliveryType =="Transfer"){
453			    accountIds +=","+ $scope.privateTrade.toAccId;
454			}
455			PayeeNewEditService.active_payee_list($stateParams.paymentId).then(function(response) {
456				$scope.filterUserActivePayees(response,showInActiveAccounts);
457				// Create Two list s of payee 1. Domestic and 2. International.
458				let domesticPayeeList = [];
459				let internationalPayeeList = [];
460				angular.forEach($scope.payeeList, function(value, key){
461					if(value && value.accountWithBank){
462						if(value.accountWithBank.isoCountryCode === $rootScope.domesticCountryIsoCode){
463						domesticPayeeList.push(value);
464						}else{
465								internationalPayeeList.push(value);
466						}
467					}
468				});
469				$scope.domesticPayeeList = angular.copy(domesticPayeeList);
470				$scope.internationalPayeeList = angular.copy(internationalPayeeList);
471				AccountSummaryService.bankAccount_list(accountIds).then(function(response) {
472					if (response.errorResponse != null) {
473						$scope.noDataErrorMsg = response.errorResponse ? response.errorResponse : 'Payment Not Found';
474						return;
475					}
476					if(response.responseObj){
477						$scope.filterUserActiveAccounts(response);
478						populateFromAccount();
479						populateToAccount();
480					}
481					$scope.loading=false;
482					if(sessionStorage.showHelpMe && JSON.parse(sessionStorage.showHelpMe)){
483						sessionStorage.showHelpMe=false;
484						startHelpMeTour(getTargetIndex("fromAccount_chosen"), true, 10);
485					}
486				});
487			});
488		}
489
490		function getDefaultPaymentModel() {
491			return {
492				customerId : undefined,
493				customerName : undefined,
494				submitterId : undefined,
495				submitterName : undefined,
496				paymentDeliveryMethod : undefined,
497				recipientEmailAddress : undefined,
498				recipientPhoneNumber : undefined,
499				recipientMessageToPayee : undefined,
500				detailsOfCharges : $rootScope.defaultCharges,
501				fxSpotForward : {
502					debitCcy : undefined,
503					creditCcy : undefined,
504					dealCcy : undefined,
505					debitCcyAmount : undefined,
506					creditCcyAmount : undefined,
507					allInRate : undefined,
508					baseCcySettlementAccountId : undefined,
509					quoteCcySettlementAccountId : undefined,
510					debitAccountNo : undefined,
511					creditAccountNo : undefined,
512					debitAccountType : undefined,
513					creditAccountType : undefined,
514					paymentNotes : undefined,
515					deliveryType : "Payment"
516				}
517			};
518		}
519
520		$scope.payment = $stateParams.paymentId ? $scope.privateTrade : getDefaultPaymentModel();
521
522		/******
523		** From account selection get account balance and update payment object.
524		*/
525		$scope.getAccountBalance = function(fromAccount){
526			if(!$scope.isReinstruct){
527				$scope.revertPaymentObject();
528			}
529			if(fromAccount){
530				$scope.twoFARequired=false;
531				$scope.differentCCYtwoFARequired = false;
532				var account=$scope.stageAccountList[fromAccount.id];
533				$scope.payment.fxSpotForward.baseCcySettlementAccountId = fromAccount.id;
534				$scope.payment.fxSpotForward.debitAccountNo = account.accountNumber;
535				$scope.payment.fxSpotForward.debitAccountType = fromAccount.accountType;
536				$scope.bankAccount = angular.copy(fromAccount);
537				if(!$scope.isReinstruct){
538					isSameCcyPayment();
539				}
540				// Get Account Balance.
541				AccountSummaryService.getAccountBalance(fromAccount.id).then(function(response) {
542					if(response.success){
543						$scope.fromAccount.accountBalance = response.responseObj.availableBalance;
544						$scope.fromAccount.ledgerBalance = response.responseObj.ledgerBalance;
545						if(!$scope.isReinstruct){
546							$scope.getCcyPair($scope.payeeAccount?.accountCcy);
547						}
548					}
549				});
550				$scope.changePayEquivalent();
551			}
552		}
553
554		$scope.isToggleDisabled = function() {
555            return (!this.isReinstruct && this.disablePaymentFields)
556                || this.askConfirmCancel
557                || (this.legalEntityValidationErrors && this.legalEntityValidationErrors.length > 0);
558        };
559
560		function updatePayeeAccount(toAccount, uiAction){
561			if(toAccount){
562				let _index = $scope.indexOfObject($scope.stagePayeeList, 'id', toAccount);
563				let _account = $scope.stagePayeeList[_index];
564				$scope.payment.fxSpotForward.quoteCcySettlementAccountId = _account.id;
565				$scope.payment.fxSpotForward.creditAccountNo = _account.accountNumber;
566				$scope.payment.fxSpotForward.creditAccountType = "SWIFT";
567				$scope.payeeAccount = angular.copy(_account);
568				$scope.getCcyPair(_account.accountCcy);
569				if(_account.chargeType){
570					$scope.payment.detailsOfCharges = _account.chargeType;
571				}
572				isSameCcyPayment();
573
574				$scope.changePayEquivalent();
575				// update email and phone number on to account update.
576				if (!$stateParams.paymentId || uiAction) {
577					$scope.payment.recipientEmailAddress = angular.copy(_account.legalAddress.emailAddress);
578					$scope.payment.recipientPhoneNumber = _account.legalAddress.phoneNumber ? angular.copy(_account.legalAddress.phoneNumber).trim().replace(/[^\d\+]/g, "") : undefined;
579					$timeout(function () {
580						intlInput.setNumber($scope.payment.recipientPhoneNumber ? $scope.payment.recipientPhoneNumber : "");
581					}, 0);
582					$scope.payment.recipientMessageToPayee = "";
583				}else if($stateParams.paymentId && $scope.isSameCurrency){
584					var _pricingStatus = $scope.privateTrade.pricingStatus;
585					var msg= _pricingStatus.desc + "<br><strong> Reason: " + $scope.privateTrade.messageToCustomer + "</strong>";
586					$scope.messageToCustomer = _pricingStatus.id=="RejectedBySystem"?msg:"";
587				}
588			}
589		}
590
591		var isFirstTime=true;
592		/******
593		** To account selection get delivery method and Ccy pair.
594		*/
595		$scope.updateDeliveryMethodAndGetCcy = function(toAccount){
596			$scope.revertPaymentObject();
597
598			if(toAccount){
599				updatePayeeAccount(toAccount);
600				if($scope.payment.recipientPhoneNumber && $scope.payment.recipientPhoneNumber.trim().length>16){
601					bootbox.dialog({
602						closeButton: false,
603						title: "Error",
604						message: "Selected Beneficiary has invalid phone number.",
605						buttons: {
606							success: {
607								label: "Ok",
608							}
609						}
610					});
611					bypassStateRecurrsion = true;
612					$state.reload();
613				}
614				$timeout(function(){
615					intlInput.setCountry('');
616					intlInput.setNumber($scope.payment.recipientPhoneNumber?$scope.payment.recipientPhoneNumber:"");
617				},200);
618			}
619			$scope.getHolidays();
620		}
621
622		$scope.getHolidays=function(){
623			PaymentService.getHolidays($scope.bankAccount.depositCcy, $scope.payeeAccount.accountCcy).then(function(response){
624				if(response.success && response.responseObj){
625					$scope.holidayList = angular.copy(response.responseObj);
626				}else{
627					$scope.holidayList=[];
628				}
629			});
630		}
631
632		/******
633		** Get delivery method for particular currency - account change watcher
634		*/
635		$scope.getDeliveryMethod = function(_currency){
636			if($stateParams.paymentId){
637				$scope.deliveryMethodList=$rootScope.paymentDeliveryTypes;
638				$scope.getCcyPair();
639				selectDeliveryMethod();
640			}else if(_currency){
641				PaymentService.getPaymentDeliveryMethod($scope.payment.fxSpotForward).then(function(response){
642					$scope.deliveryMethodList=response.responseObj;
643					selectDeliveryMethod();
644				});
645			}
646		}
647		/**
648		*  Get currency pair for selected to & from account CCY.
649		*/
650		$scope.getCcyPair = function(_currency){
651			if(angular.isDefined($scope.bankAccount) && angular.isDefined($scope.payeeAccount)){
652				var _fundingCcy = $scope.bankAccount.depositCcy;
653				var _payeeCcy = $scope.payeeAccount.accountCcy;
654				PaymentService.getCcyPair(_fundingCcy,_payeeCcy).then(function(response){
655					if(response.errorResponse){
656						$scope.paymentNotAllowed = true;
657						$scope.ccyError = response.errorResponse;
658					} else if(response.responseObj && response.responseObj.ccyPair != undefined){
659						$scope.paymentNotAllowed = angular.copy(false);
660						var _ccyPair = response.responseObj.ccyPair;
661						$scope.baseCcy=angular.copy(_ccyPair.substr(0,3));
662						$scope.quoteCcy=angular.copy(_ccyPair.substr(3,3));
663						$scope.baseCcyAmountPrecision = response.responseObj.baseCcyAmountPrecision;
664						$scope.quoteCcyAmountPrecision = response.responseObj.quoteCcyAmountPrecision;
665
666						updateAmountPrecision();
667
668						$scope.payment.fxSpotForward.debitCcy = _fundingCcy;
669						$scope.payment.fxSpotForward.creditCcy = _payeeCcy;
670						$scope.ccyError = undefined;
671						if(_currency){
672							$scope.getDeliveryMethod(_currency);
673						}
674						if(_ccyPair){
675							PaymentService.getPollTimeout($scope.baseCcy,$scope.quoteCcy).then(function(response){
676								if(response.responseObj){
677									$scope.PollDuration = response.responseObj;
678								}
679							});
680						}
681					}
682
683				});
684			}
685		}
686		/******
687		** If To acocunt or from account is changed remove all updation for payment object.
688		*/
689		$scope.revertPaymentObject = function(){
690			$scope.payment.fxSpotForward.valueDate = undefined;
691			$scope.payment.paymentFee = {};
692			$scope.payment.paymentAmount = undefined;
693			$scope.payment.fxSpotForward.paymentNotes = undefined;
694			$scope.rejectRate("watch");
695			$timeout.cancel(timer);
696			$scope.loadingScreen = false;
697			$scope.displayExRateInfo=false;
698			$scope.isHoliday = false;
699			$scope.paymentMethod = undefined;
700			$scope.exception=undefined;
701			$scope.payment.id=null;
702			$scope.isFutureDatedPayment = false;
703			$('[name=paymentDate]').removeClass("txtbxReq");
704			$("#deliveryMethod").removeClass("txtbxReq");
705			$('[name=paymentNotes]').removeClass("txtbxReq");
706		}
707
708		function fxHasValidAllInRate(fx) {
709			if (!fx) return false;
710			if (fx.allInRate == null || fx.allInRate === undefined || fx.allInRate === "") return false;
711			var rate = parseFloat(fx.allInRate);
712			return !isNaN(rate) && rate !== 0;
713		}
714
715		$scope.hasDisplayableAcceptedOrPricedFxRate = function () {
716			if (fxHasValidAllInRate($scope.exchangeRateInformation)) return true;
717			if ($scope.previousAcceptedRate && fxHasValidAllInRate($scope.previousAcceptedRate.fxSpotForward)) return true;
718			if ($scope.payment && fxHasValidAllInRate($scope.payment.fxSpotForward)) return true;
719			if ($scope.ratetxt) return true;
720			return false;
721		};
722
723		/******
724		** Get Delivery Date.
725		*/
726		$scope.getDeliveryDate = function() {
727				if(! $rootScope.isUndefined( $('[name=paymentDate]').val() )){
728					$('[name=paymentDate]').removeClass("txtbxReq");
729				}else{
730					$('[name=paymentDate]').addClass("txtbxReq");
731				}
732				$scope.isFutureDatedPayment = false;
733				$scope.isHoliday = false;
734				$scope.holidayError = "";
735				// check for holiday
736				// check if tradeDate is greater than spot date(today fior now) it is future dated payment.
737				var tradeDate = new Date($scope.payment.fxSpotForward.valueDate);
738				var del_ethod=$scope.paymentMethod;
739				if(del_ethod=="FuturePayment"){
740					 $scope.isFutureDatedPayment = true;
741					 $scope.displayRateTimer = false;
742					 $scope.rateaccepted = true;
743					 if(($stateParams.paymentId && $scope.privateTrade.pricingStatus.id=="PriceInFuture")
744							 || !$stateParams.paymentId){
745						 $scope.expMsg = $rootScope.paymentFutureDatedMessage;
746						 $scope.ratetxt = "";
747						 $scope.exchangeRateInformation = undefined;
748					 }
749					 $scope.displayExRateInfo = !!$scope.hasDisplayableAcceptedOrPricedFxRate();
750					let hasFutureEntitlement =  $filter("contains")($rootScope.entitlements, 'FXWEB_SCHEDULED_PAYMENTS');
751					if(!hasFutureEntitlement){
752						$scope.isHoliday = true;
753						$scope.holidayError = "You do not have permission to make FUTURE payment.";
754					}
755				 }else if(!$scope.payment.id){
756					 $scope.displayExRateInfo = false;
757					 $scope.rateaccepted = false;
758					 $scope.displayRateTimer = false;
759					 $scope.expMsg = "";
760				 }
761				// check for holiday.
762				if(! $rootScope.isUndefined(tradeDate) && !isNaN(tradeDate) &&
763					! $rootScope.isUndefined($scope.bankAccount) &&
764					! $rootScope.isUndefined($scope.payeeAccount) &&
765					!$scope.isHoliday
766					){
767					PaymentService.checkHoliday(tradeDate, $scope.bankAccount.depositCcy, $scope.payeeAccount.accountCcy).then(function(response){
768							// Selected Date is on Holiday for either or both selected currency.
769							if(response.success){
770								$scope.isHoliday = angular.copy(response.responseObj);
771								$scope.holidayError = "Sorry cannot process payment on Holiday. Please select some other date.";
772							}else{
773								$scope.isHoliday = angular.copy(true);
774								$scope.holidayError = response.errorResponse;
775							}
776
777					});
778				}
779		};
780
781		/******
782		** Get Payment fees amount input type text blur event. // Fees is not part of payment object.
783		*/
784		var _fees = {
785			feeAmount : undefined,
786			feeCcy : undefined
787		};
788		$scope.fees = angular.copy(_fees);
789		$scope.getFee = function() {
790			let paymentAmount = ($scope.payment.paymentAmount)?$scope.payment.paymentAmount:1;
791			if(paymentAmount && parseFloat(paymentAmount)>parseFloat("0")){
792				$scope.waitForGetRate=true;
793				$scope.getRateError = "";
794				$scope.invalidAmount =false;
795				 if($scope.payeeAccount.accountCcy == $scope.bankAccount.depositCcy){
796					$scope.getSameCcyFees();
797				}else if ($scope.payment.fxSpotForward.dealCcy != null){ //angular.isDefined($scope.payment.paymentAmount) &&
798					let wireCcy =$scope.payeeAccount.accountCcy;
799					let dealCcy =$scope.payment.fxSpotForward.dealCcy;
800					let payeeId =$scope.payeeAccount.id;
801					let detailsOfCharges =$scope.payment.detailsOfCharges;
802					if(!$scope.payment.id){
803						PaymentService.getFee(wireCcy,paymentAmount,payeeId,detailsOfCharges,dealCcy).then(function(response) {
804		            		if(response.responseObj){
805		            			$scope.fees.feeAmount = response.responseObj.feeAmount;
806		            			$scope.fees.feeCcy = response.responseObj.feeCcy;
807		            			$scope.payment.paymentFee=$scope.fees;
808		            		}else{
809		            			$scope.fees.feeAmount = "0.00";
810		            			$scope.fees.feeCcy = undefined;
811		            		}
812		            		if(!$scope.payment.id)
813		            			$scope.payment.paymentFee=$scope.fees;
814						});
815					}
816				}
817			}
818			else{
819				$scope.getRateError = "Please enter currency amount greater than zero.";
820				$scope.invalidAmount =true;
821			}
822        }
823		// Same Ccy Fees
824		$scope.getSameCcyFees = function() {
825				if(! $rootScope.isUndefined($scope.payment.fxSpotForward.dealCcy) && ! $rootScope.isUndefined($scope.payeeAccount.id)){
826					// && ! $rootScope.isUndefined($scope.payment.paymentAmount)
827					$timeout(function(){
828						let paymentAmount = ($scope.payment.paymentAmount)?$scope.payment.paymentAmount:1;
829						let dealCcy =$scope.payment.fxSpotForward.dealCcy;
830						let payeeId =$scope.payeeAccount.id;
831						let detailsOfCharges =$scope.payment.detailsOfCharges;
832						if(!$scope.payment.id){
833							PaymentService.getSameCcyFee(dealCcy,paymentAmount,payeeId,detailsOfCharges,dealCcy).then(function(response) {
834								$scope.waitForGetRate= false;
835								if(response.responseObj){
836									$scope.fees.feeAmount = angular.copy(response.responseObj.feeAmount);
837									$scope.fees.feeCcy = angular.copy(response.responseObj.feeCcy);
838									$scope.payment.paymentFee=$scope.fees;
839								}else{
840									$scope.fees.feeAmount = 0;
841								}
842								if(!$scope.payment.id)
843									$scope.payment.paymentFee=$scope.fees;
844								$scope.showFeeDiv = true;
845							});
846						}
847					});
848				}
849		}
850
851		/******
852		** Amount Selection validation.
853		*/
854		$scope.$watch('amountOption', function () {
855			$scope.changePayEquivalent();
856		});
857
858		$scope.changePayEquivalent = function () {
859			if (!$rootScope.isUndefined($scope.bankAccount) && !$rootScope.isUndefined($scope.payeeAccount)) {
860				var _dealCcy;
861				if (!$rootScope.isUndefined($scope.amountOption) && $scope.amountOption == "notEquivalent") {
862					_dealCcy = $scope.payeeAccount.accountCcy;
863				} else {
864					_dealCcy = $scope.bankAccount.depositCcy;
865				}
866				updateAmountPrecision();
867
868				$scope.payment.fxSpotForward.dealCcy = angular.copy(_dealCcy);
869			}
870		}
871
872		function updateAmountPrecision(){
873			var _dealCcy = (!$rootScope.isUndefined($scope.amountOption) && $scope.amountOption == "notEquivalent") ? $scope.payeeAccount.accountCcy : $scope.bankAccount.depositCcy;
874			if(!$rootScope.isUndefined($scope.baseCcyAmountPrecision) && !$rootScope.isUndefined($scope.quoteCcyAmountPrecision)){
875				if(_dealCcy == $scope.baseCcy){
876					$scope.numberOfDecimals = $scope.baseCcyAmountPrecision;
877				}
878				else{
879					$scope.numberOfDecimals = $scope.quoteCcyAmountPrecision;
880				}
881				if ($scope.payment.paymentAmount && $scope.payment.paymentAmount !== '') {
882					$scope.payment.paymentAmount = parseFloat($scope.payment.paymentAmount).toFixed($scope.numberOfDecimals);
883				}
884			}
885		}
886
887		/********************
888		***** Get Rate ******
889		********************/
890
891		$scope.getRate = function(){
892			$scope.rejectRateBtnDisable=false;
893			$scope.acceptRateBtnDisable=false
894			$scope.loadingScreen = true;
895			$scope.displayExRateInfo = false;
896			$scope.getRateError = undefined;
897			$scope.showGetRateForPricingCustomerMessage = false;
898			$scope.expMsg = "";
899			$scope.initiatorIndicativeDisclaimerAfterSuccessfulRate = false;
900			$scope.invalidAmount =false;
901			$scope.getPinNotVerifiedError ="";
902			$("#deliveryMethod").removeClass("txtbxReq");
903			$('[name=paymentNotes]').removeClass("txtbxReq");
904
905			if(
906				 $rootScope.isUndefined($scope.fromAccount) ||
907				 $rootScope.isUndefined($scope.toAccount) ||
908				 $rootScope.isUndefined($scope.paymentMethod) ||
909				 $rootScope.isUndefined($scope.payment.fxSpotForward.valueDate) ||
910				$scope.isHoliday ||
911				 $rootScope.isUndefined($scope.payment.paymentAmount) ||
912				 $rootScope.isUndefined($scope.payment.detailsOfCharges) ||
913				 $rootScope.isUndefined($scope.payment.fxSpotForward.paymentNotes) ||
914				parseFloat($scope.payment.paymentAmount)<=parseFloat("0")
915			){
916				if(parseFloat($scope.payment.paymentAmount)<=parseFloat("0")){
917					$scope.getRateError = "Please enter currency amount greater than zero.";
918					$scope.invalidAmount =true;
919				}else{
920					$scope.getRateError = "";
921					if( $rootScope.isUndefined( $('[name=paymentDate]').val() )){
922						$('[name=paymentDate]').addClass("txtbxReq");
923					}
924					if( !$scope.payment.paymentAmount ){
925						$scope.getRateError = "Please provide amount." + "<br>";
926					}
927					if( $("#deliveryMethod").val() == null){
928						$("#deliveryMethod").addClass("txtbxReq");
929						$scope.getRateError = $scope.getRateError + "Please select delivery method." + "<br>";
930					}
931					if( $("#deliveryMethod").val() && !$scope.payment.fxSpotForward.valueDate ){
932						$scope.getRateError = $scope.getRateError + "Please provide payment date." + "<br>";
933					}
934					if(!$scope.payment.fxSpotForward.paymentNotes){
935						$('[name=paymentNotes]').addClass("txtbxReq");
936						$scope.getRateError = $scope.getRateError +"Please provide purpose of payment." + "<br>";
937					}
938					if($scope.isHoliday){
939						$scope.getRateError = $scope.getRateError + "Sorry cannot process payment on Holiday. Please select some other date." + "<br>";
940					}
941					if( $rootScope.isUndefined($scope.payment.detailsOfCharges)){
942						$scope.getRateError = $scope.getRateError + "Please provide details of charges.";
943					}
944				}
945
946				$scope.requiredToGetRate = true;
947				$scope.loadingScreen = false;
948			}else{
949
950				if(parseFloat($scope.payment.paymentAmount)<=parseFloat("0")){
951					$scope.getRateError = "Please enter currency amount greater than zero.";
952					$scope.invalidAmount =true;
953					$scope.loadingScreen = false;
954				}else{
955				$scope.isStramingRate = false;
956				beginSuppressResubmitWatch();
957				let fundingAcctId = angular.copy($scope.fromAccount.id);
958				let beneAcctId = angular.copy($scope.toAccount);
959				$scope.payment.fromAccId=fundingAcctId;
960				$scope.payment.toAccId=beneAcctId;
961				let _payment = angular.copy($scope.payment);
962				let _paymentAmount = angular.copy(_payment.paymentAmount);
963				delete _payment["fxSpotForward"]["debitCcyAmount"];
964                delete _payment["fxSpotForward"]["creditCcyAmount"];
965				delete  _payment["tradeDate"];
966				if($scope.amountOption == "equivalent"){
967					if(_payment.fxSpotForward.debitCcy == $scope.bankAccount.depositCcy){
968						_payment.fxSpotForward.debitCcyAmount = angular.copy(_paymentAmount);
969					}else if(_payment.fxSpotForward.creditCcy == $scope.bankAccount.depositCcy){
970						_payment.fxSpotForward.creditCcyAmount = angular.copy(_paymentAmount);
971					}
972				}else{
973					if(_payment.fxSpotForward.debitCcy == $scope.payeeAccount.accountCcy){
974						_payment.fxSpotForward.debitCcyAmount = angular.copy(_paymentAmount);
975					}else if(_payment.fxSpotForward.creditCcy == $scope.payeeAccount.accountCcy){
976						_payment.fxSpotForward.creditCcyAmount = angular.copy(_paymentAmount);
977					}
978				}
979					_payment.paymentDeliveryMethod = angular.copy($scope.paymentMethod);
980					if (_payment.fxSpotForward && _payment.tenor != null) {
981						_payment.fxSpotForward.tenor = angular.copy(_payment.tenor);
982					}
983					let _formatedPayment = formatPaymentDate(_payment);
984					let _currentPaymentId = ($scope.privateTrade && $scope.privateTrade.id) || ($scope.payment && $scope.payment.id) || null;
985					$scope.paymentRequest = angular.copy(_formatedPayment);
986					$scope.disableChargeType = true;
987					$scope.exception = "";
988					if (_currentPaymentId != null) {
989						_formatedPayment.id = _currentPaymentId;
990					}
991
992					if ($scope.editPaymentMode && !_currentPaymentId) {
993						$scope.loadingScreen = false;
994						$scope.disableChargeType = false;
995						$scope.getRateError = "Payment reference is missing. Please reload and try again.";
996						endSuppressResubmitWatch();
997						return;
998					}
999					if (_currentPaymentId != null) {
1000						$scope.payment.id = _currentPaymentId;
1001					}
1002					var _paymentStatus = _payment.status;
1003					if (!_paymentStatus && $scope.privateTrade && $scope.privateTrade.status) {
1004						_paymentStatus = $scope.privateTrade.status;
1005					}
1006				var normalizedStatus = normalizePaymentStatusForRequest(_paymentStatus);
1007				if (normalizedStatus) {
1008					_formatedPayment.status = normalizedStatus.id;
1009				} else {
1010					delete _formatedPayment.status;
1011				}
1012
1013					$scope.missedPaymentRepriceGotRate = true;
1014					var isFinalApproverGetRate = $rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled
1015						&& $scope.isFinalApproverRateAcceptanceRequired();
1016						if (!_formatedPayment.businessUnitId) {
1017							_formatedPayment.externalRefId = null;
1018						}
1019					if($scope.privateTrade && $scope.privateTrade.externalRefId){
1020                        _formatedPayment.externalRefId = $scope.privateTrade.externalRefId;
1021                    }
1022					PaymentService.oobaWithCallBack(_formatedPayment, "GetRate", _currentPaymentId, null, isFinalApproverGetRate).then(function (response) {
1023						if (typeof response.result === 'object') {
1024							getRateCallBack(response.result);
1025						} else {
1026							$("#differentCCY_ooba").html(response.result);
1027							$scope.disablePaymentFields = true;
1028							$scope.loadingScreen = false;
1029							$scope.hideGetRateBtn = true;
1030							$scope.initiateOOBA(getRateCallBack, _formatedPayment, "GetRate", _currentPaymentId);
1031						}
1032					}).catch(function (err) {
1033						endSuppressResubmitWatch();
1034						$scope.missedPaymentRepriceGotRate = false;
1035						$scope.loadingScreen = false;
1036						$scope.disablePaymentFields = false;
1037						$scope.hideGetRateBtn = false;
1038						$scope.disableChargeType = false;
1039						$timeout(function () {
1040							$scope.getRateError = (err.data && (err.data.errorResponse || err.data.message)) || (err.data && err.data.responseObj && err.data.responseObj.messageToCustomer) || "Unable to get rate. Please try again.";
1041						}, 500);
1042					});
1043				}
1044			}
1045		}
1046
1047		function getRateCallBack (response){
1048			beginSuppressResubmitWatch();
1049			try {
1050			if(response.responseObj){
1051				updatePaymentObjectFromServer(response.responseObj);
1052			}
1053			if(response.success){
1054				$scope.disablePaymentFields = true;
1055				$scope.loadingScreen = false;
1056				$timeout.cancel(timer);
1057				$scope.displayRate(response.responseObj);
1058				$scope.payment.paymentFee=response.responseObj.paymentFee;
1059				$scope.setAmountAfterPricing(response.responseObj);
1060				$scope.noOfApprovalsRequiredForPayment = computeNoOfApprovalsRequiredFromEntity();
1061				if($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && !$scope.isFinalApproverRateAcceptanceRequired() && isUsdAmountStrictlyAboveFirstApproverLimit()){
1062					$scope.displayRateTimer = false;
1063					var _fx = response.responseObj.fxSpotForward;
1064					if(_fx){
1065						$scope.payment.fxSpotForward.allInRate = _fx.allInRate;
1066						$scope.payment.fxSpotForward.debitCcyAmount = _fx.debitCcyAmount;
1067						$scope.payment.fxSpotForward.creditCcyAmount = _fx.creditCcyAmount;
1068					}
1069					$scope.privateTrade = response.responseObj;
1070					if (!$scope.editPaymentMode) {
1071						$scope.initiatorIndicativeDisclaimerAfterSuccessfulRate = true;
1072					}
1073					$scope.expMsg = $scope.getIndicativeRateMessage();
1074					$scope.hideGetRateBtn = true;
1075				}else{
1076					if ($scope.isFinalApproverRateAcceptanceRequired()) {
1077						$scope.expMsg = "";
1078					}
1079					$scope.displayRateTimer = true;
1080					$scope.expiryValue = response.responseObj.priceExpiresInSeconds;
1081					$scope.startKnob();
1082					$scope.showCancelButton=false;
1083				}
1084			}else{
1085				$scope.disablePaymentFields = false;
1086				var _pricingDesc = response.responseObj && response.responseObj.pricingStatus
1087					&& (response.responseObj.pricingStatus.desc || response.responseObj.pricingStatus.id);
1088				if(response.errorResponse == "WaitingRFQ"){
1089					$scope.loadingScreen = true;
1090					$scope.hideGetRateBtn = false;
1091					$timeout(function () {
1092						$scope.getRateError = _pricingDesc || response.errorResponse;
1093					}, 500);
1094					$scope.poll(response.responseObj.id);
1095					$scope.tradeNo = response.responseObj.externalRefId;
1096					$scope.payment.status = response.errorResponse;
1097				}else if(response.errorResponse == "WaitingRFP"){
1098					$scope.loadingScreen = true;
1099					$scope.hideGetRateBtn = false;
1100					$timeout(function () {
1101						$scope.getRateError = _pricingDesc || response.errorResponse;
1102					}, 500);
1103					$scope.ticketId=response.responseObj.quoteId;
1104					$scope.isStramingRate=true;
1105					$scope.payment.executionVenue=response.responseObj.executionVenue;
1106					if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.isFinalApproverRateAcceptanceRequired()) {
1107						$scope.disablePaymentFields = true;
1108					}
1109					$scope.pollStreamingRate($scope.ticketId);
1110				}else if(!response.success){
1111					$scope.missedPaymentRepriceGotRate = false;
1112					$scope.loadingScreen = false;
1113					$timeout(function () {
1114						$scope.getRateError = response.errorResponse || (response.responseObj && response.responseObj.messageToCustomer) || "An error occurred while getting the rate.";
1115					}, 500);
1116					$scope.disableChargeType = false;
1117					$scope.hideGetRateBtn = false;
1118					$scope.payment.id = null;
1119				}
1120			}
1121			} finally {
1122				endSuppressResubmitWatch();
1123			}
1124		}
1125
1126		$scope.initiateOOBA = function (callBackfunc, requestObj, action, paymentId) {
1127			function getDeliveryMethod() {
1128				return $('input[name="deliveryMethod"]:checked').val();
1129			}
1130
1131			$(".btnCreateSubmit").click(function () {
1132				var deliveryMethod = getDeliveryMethod();
1133				$("#deliveryMethodError").val("");
1134				if (!deliveryMethod) {
1135					$("#deliveryMethodError").val("Please select delivery method.")
1136					return;
1137				}
1138				PinService.requestPin(deliveryMethod).then(function (response) {
1139					$("#ooba_create").hide();
1140					$("#ooba_validate").show();
1141				});
1142			});
1143
1144			$(".btnValidateResent").click(function () {
1145				$("#otp_text").val("");
1146				$(".error-message").text("");
1147				$("#ooba_create").show();
1148				$("#ooba_validate").hide();
1149			});
1150
1151			$(".btnValidateSubmit").click(function () {
1152				var otp = $("#otp_text").val();
1153				if (!otp) {
1154					$('#invalid-error').val('Please enter the pin.');
1155					return;
1156				}
1157
1158				PinService.validatePaymentPin(otp, requestObj, action, paymentId).then(function (response) {
1159					$("#payment_ooba").html("");
1160					$("#differentCCY_ooba").html("");
1161					if (typeof response.result === 'object') {
1162						callBackfunc(response.result);
1163					} else {
1164						if (action === "GetRate") {
1165							$("#differentCCY_ooba").html(response.result);
1166						} else {
1167							$("#payment_ooba").html(response.result);
1168						}
1169						$scope.initiateOOBA(callBackfunc, requestObj, action, paymentId);
1170					}
1171				});
1172			});
1173		}
1174
1175		$scope.setAmountAfterPricing=function(_payment){
1176			if($scope.payment.fxSpotForward.dealCcy==_payment.fxSpotForward.debitCcy){
1177				$scope.payment.paymentAmount=_payment.fxSpotForward.debitCcyAmount;
1178			}else{
1179				$scope.payment.paymentAmount=_payment.fxSpotForward.creditCcyAmount;
1180			}
1181		}
1182
1183		function formatPaymentDate(_payment) {
1184			if (_payment.deliveryDate) {
1185				let _deliveryDate = new Date(_payment.deliveryDate);
1186				_payment.deliveryDate = formatDateMMDDYYYY(_deliveryDate);
1187			}
1188			if (_payment.tradeDate) {
1189				let _tradeDate = new Date(_payment.tradeDate);
1190				if (isNaN(_tradeDate.getTime())) {
1191					if (_payment.fxSpotForward && _payment.fxSpotForward.valueDate) {
1192						_tradeDate = new Date(_payment.fxSpotForward.valueDate);
1193						if (!isNaN(_tradeDate.getTime())) {
1194							_payment.tradeDate = formatDateMMDDYYYY(_tradeDate);
1195						} else {
1196							delete _payment.tradeDate;
1197						}
1198					} else {
1199						delete _payment.tradeDate;
1200					}
1201				} else {
1202					_payment.tradeDate = formatDateMMDDYYYY(_tradeDate);
1203				}
1204			}
1205			if (_payment.fxSpotForward.valueDate) {
1206				let _valueDate = new Date(_payment.fxSpotForward.valueDate);
1207				_payment.fxSpotForward.valueDate = formatDateMMDDYYYY(_valueDate);
1208			}
1209			return _payment;
1210		}
1211
1212		function normalizePaymentStatusForRequest(st) {
1213			if (st == null || st === '') {
1214				return undefined;
1215			}
1216			if (typeof st === 'object' && st !== null && st.id) {
1217				return { id: st.id, desc: st.desc != null ? st.desc : st.id };
1218			}
1219			if (typeof st === 'string') {
1220				return { id: st };
1221			}
1222			return undefined;
1223		}
1224
1225		function formatDateMMDDYYYY(date){
1226			let _date = new Date(date);
1227			let dd = _date.getDate();
1228			let mm = _date.getMonth()+1;
1229
1230			let yyyy = _date.getFullYear();
1231			if(dd<10){
1232				dd='0'+dd;
1233			}
1234			if(mm<10){
1235				mm='0'+mm;
1236			}
1237			return (mm+'/'+dd+'/'+yyyy);
1238		}
1239
1240		function updatePaymentObjectFromServer(_payment) {
1241			if (!_payment) return;
1242			if (_payment.fxSpotForward && _payment.fxSpotForward.valueDate !== undefined && _payment.fxSpotForward.valueDate !== null && _payment.fxSpotForward.valueDate !== "") {
1243				let _valueDate = angular.copy(_payment.fxSpotForward.valueDate);
1244				var _vd = new Date(_valueDate);
1245				if (!isNaN(_vd.getTime())) {
1246					_payment.fxSpotForward.valueDate = angular.copy(_vd);
1247					if ($scope.payment && $scope.payment.fxSpotForward) {
1248						$scope.payment.fxSpotForward.valueDate = angular.copy(_vd);
1249					}
1250				}
1251			}
1252			$scope.payment.id = _payment.id;
1253			if (_payment.externalRefId != null && _payment.externalRefId !== "") {
1254				$scope.payment.externalRefId = _payment.externalRefId;
1255			}
1256			if (_payment.usdAmount != null && _payment.usdAmount !== undefined) {
1257				$scope.payment.usdAmount = _payment.usdAmount;
1258			}
1259		}
1260
1261		function setRateDisplayLinesFromFx(fx) {
1262			$scope.ratetxtInverse = "";
1263			if (!fx || fx.allInRate == null || fx.allInRate === undefined || !$scope.baseCcy || !$scope.quoteCcy) {
1264				$scope.ratetxt = "";
1265				return;
1266			}
1267			var rate = parseFloat(fx.allInRate);
1268			if (isNaN(rate) || rate === 0) {
1269				$scope.ratetxt = "";
1270				return;
1271			}
1272			var inv = 1 / rate;
1273			$scope.ratetxt = "1 " + $scope.baseCcy + " = " + fx.allInRate + " " + $scope.quoteCcy;
1274			$scope.ratetxtInverse = "1 " + $scope.quoteCcy + " = " + inv.toFixed(4) + " " + $scope.baseCcy;
1275		}
1276
1277		$scope.displayRate=function(payment){
1278			$scope.getRateError = undefined;
1279			setRateDisplayLinesFromFx(payment.fxSpotForward);
1280			$scope.tradeNo=payment.externalRefId;
1281			$scope.exchangeRateInformation = payment.fxSpotForward;
1282			$scope.displayExRateInfo = true;
1283		}
1284
1285		function applyPricedWithCustomerMessageRecovery(customerMessage, isStreamingPoll) {
1286			$scope.loadingScreen = false;
1287			$timeout.cancel(timer);
1288			$scope.disablePaymentFields = false;
1289			if (isStreamingPoll) {
1290				$scope.isStramingRate = false;
1291			}
1292			$scope.missedPaymentRepriceGotRate = false;
1293			$scope.displayRateTimer = false;
1294			if ($scope.stopKnob) {
1295				$scope.stopKnob();
1296			}
1297			$scope.displayExRateInfo = false;
1298			$timeout(function () {
1299				$scope.getRateError = customerMessage;
1300			}, 500);
1301			beginSuppressResubmitWatch();
1302			try {
1303				var previousAcceptedRate = $scope.previousAcceptedRate;
1304				if ($stateParams.paymentId && previousAcceptedRate && $scope.payment && $scope.payment.fxSpotForward) {
1305					angular.extend($scope.payment.fxSpotForward, previousAcceptedRate.fxSpotForward);
1306					$scope.exchangeRateInformation = $scope.payment.fxSpotForward;
1307					setRateDisplayLinesFromFx($scope.exchangeRateInformation);
1308					$scope.displayExRateInfo = true;
1309					if (previousAcceptedRate.externalRefId) {
1310						$scope.tradeNo = previousAcceptedRate.externalRefId;
1311						$scope.payment.externalRefId = previousAcceptedRate.externalRefId;
1312					}
1313				}
1314				$scope.hideGetRateBtn = false;
1315				$scope.showGetRateForPricingCustomerMessage = true;
1316			} finally {
1317				endSuppressResubmitWatch();
1318			}
1319		}
1320
1321		/*****
1322		** Poll Continuiosly to get the rate when Waiting RFQ
1323		*/
1324	let canPoll = true;
1325     	var timer;
1326        $scope.poll = function( _paymentId ){
1327        	timer = $timeout(function () {
1328        		PaymentService.poll(_paymentId).then(function(response){
1329					var data = response;
1330					$scope.pricingStatusId = response.responseObj?.pricingStatus?.id;
1331					if(data.errorResponse && data.errorResponse.indexOf("Rejected By Trader") != -1 && !data.success){
1332						beginSuppressResubmitWatch();
1333						$scope.missedPaymentRepriceGotRate = false;
1334						$scope.disablePaymentFields = false;
1335						$scope.loadingScreen = false;
1336						$timeout.cancel(timer);
1337						$timeout(function () {
1338							$scope.getRateError = data.errorResponse;
1339						}, 500);
1340						$scope.payment.id = null;
1341						endSuppressResubmitWatch();
1342					} else if(!data.success && data.errorResponse){
1343						$scope.loadingScreen = false;
1344						$timeout.cancel(timer);
1345						$scope.cancelRate();
1346						$timeout(function () {
1347							$scope.getRateError = data.errorResponse;
1348						}, 500);
1349					} else if(data.errorResponse == "Declined" && !data.success){
1350						beginSuppressResubmitWatch();
1351						$scope.missedPaymentRepriceGotRate = false;
1352						$scope.payment.id = null;
1353						endSuppressResubmitWatch();
1354					}else if(data.success && data.responseObj.pricingStatus.id == "Priced" && data.responseObj.messageToCustomer){
1355						applyPricedWithCustomerMessageRecovery(data.responseObj.messageToCustomer, false);
1356					} else if(data.success && data.responseObj.pricingStatus.id == "Priced"){
1357						beginSuppressResubmitWatch();
1358						try {
1359						$scope.disablePaymentFields = true;
1360						$scope.loadingScreen = false;
1361						$timeout.cancel(timer);
1362						if (data.responseObj) updatePaymentObjectFromServer(data.responseObj);
1363						$scope.displayRate(data.responseObj);
1364						$scope.payment.paymentFee=data.responseObj.paymentFee;
1365						$scope.setAmountAfterPricing(data.responseObj);
1366						$scope.noOfApprovalsRequiredForPayment = computeNoOfApprovalsRequiredFromEntity();
1367						if($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && !$scope.isFinalApproverRateAcceptanceRequired() && isUsdAmountStrictlyAboveFirstApproverLimit()){
1368							$scope.displayRateTimer = false;
1369							var _fx = data.responseObj.fxSpotForward;
1370							if(_fx){
1371								$scope.payment.fxSpotForward.allInRate = _fx.allInRate;
1372								$scope.payment.fxSpotForward.debitCcyAmount = _fx.debitCcyAmount;
1373								$scope.payment.fxSpotForward.creditCcyAmount = _fx.creditCcyAmount;
1374							}
1375							$scope.privateTrade = data.responseObj;
1376							if (!$scope.editPaymentMode) {
1377								$scope.initiatorIndicativeDisclaimerAfterSuccessfulRate = true;
1378							}
1379							$scope.expMsg = $scope.getIndicativeRateMessage();
1380							$scope.hideGetRateBtn = true;
1381						}else{
1382							if ($scope.isFinalApproverRateAcceptanceRequired()) {
1383								$scope.expMsg = "";
1384							}
1385							$scope.expiryValue = data.responseObj.priceExpiresInSeconds;
1386							$scope.displayRateTimer = true;
1387							$scope.startKnob();
1388							$scope.showCancelButton=false;
1389							$scope.askConfirmCancel=false;
1390							if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.isFinalApproverRateAcceptanceRequired()) {
1391								$scope.disablePaymentFields = true;
1392							}
1393						}
1394						} finally {
1395							endSuppressResubmitWatch();
1396						}
1397            		}
1397 else if( data.responseObj && canPoll){
1398            			$scope.poll( _paymentId );
1399            		}
1400            	});
1401        	}, 1000);
1402		}
1403
1404		$scope.pollStreamingRateCount=0;
1405
1406        $scope.handleIncompleteStreamingRate = function(ticketId, stopPolling) {
1407            if($scope.pollStreamingRateCount<stopPolling){
1408                if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.isFinalApproverRateAcceptanceRequired()) {
1409                    $scope.disablePaymentFields = true;
1410                }
1411                $scope.pollStreamingRate( ticketId );
1412                $scope.loadingScreen = true;
1413            }else{
1414                $scope.loadingScreen = false;
1415                $scope.pollStreamingRateCount=0;
1416                $scope.missedPaymentRepriceGotRate = false;
1417                $scope.disablePaymentFields = false;
1418                $scope.hideGetRateBtn = false;
1419                $scope.isStramingRate = false;
1420                $timeout(function () {
1421					$scope.getRateError = $rootScope.streamingRateError;
1422				}, 500);
1423            }
1424        };
1425
1426        /*****
1427		** Streaming Rates
1428		** Poll Every 5 Seconds to get the Streaming Rates
1429		**/
1430        $scope.pollStreamingRate = function( ticketId ){
1431			$scope.pollStreamingRateCount+=3;
1432			var stopPolling=$scope.PollDuration?parseInt($scope.PollDuration):15;
1433			let _currentPaymentId = ($scope.privateTrade && $scope.privateTrade.id) || ($scope.payment && $scope.payment.id) || null;
1434			$scope.paymentRequest.id = _currentPaymentId
1435			let beneAcctId = angular.copy($scope.toAccount);
1436			$scope.paymentRequest.quoteId = ticketId;
1437        	timer = $timeout(function () {
1438        		PaymentService.pollRFP($scope.paymentRequest).then(function(response){
1439					$scope.loadingScreen = false;
1440            		var data = response;
1441					if(data.errorResponse == "RejectedByTrader" && !data.success ){
1442            			$scope.loadingScreen = false;
1443						$timeout.cancel(timer);
1444						$scope.missedPaymentRepriceGotRate = false;
1445						$scope.disablePaymentFields = false;
1446						$scope.hideGetRateBtn = false;
1447						$scope.isStramingRate = false;
1448						$scope.displayExRateInfo = false;
1449						$timeout(function () {
1450							$scope.getRateError = (data.responseObj && data.responseObj.messageToCustomer) || data.errorResponse || data.errorCode;
1451						}, 500);
1452					} else if(data.errorResponse == "Declined" && !data.success){
1453						$timeout.cancel(timer);
1454						$scope.missedPaymentRepriceGotRate = false;
1455						$scope.disablePaymentFields = false;
1456						$scope.hideGetRateBtn = false;
1457						$scope.isStramingRate = false;
1458						$scope.displayExRateInfo = false;
1459						$timeout(function () {
1460							$scope.getRateError = (data.responseObj && data.responseObj.messageToCustomer) || data.errorResponse || data.errorCode;
1461						}, 500);
1462            		} else if (!data.success && (data.errorResponse || data.errorCode)) {
1463						$timeout.cancel(timer);
1464						$scope.missedPaymentRepriceGotRate = false;
1465						$scope.disablePaymentFields = false;
1466						$scope.disableChargeType = false;
1467						$scope.hideGetRateBtn = false;
1468						$scope.isStramingRate = false;
1469						$scope.loadingScreen = false;
1470						$scope.displayExRateInfo = false;
1471						$timeout(function () {
1472							$scope.getRateError = (data.responseObj && data.responseObj.messageToCustomer) || data.errorResponse || data.errorCode;
1473						}, 500);
1474					} else if(data.success && data.responseObj.pricingStatus && data.responseObj.pricingStatus.id == "Priced" && data.responseObj.messageToCustomer){
1475						applyPricedWithCustomerMessageRecovery(data.responseObj.messageToCustomer, true);
1476					} else if(data.success){
1477            			var _payment=data.responseObj;
1478            			$scope.loadingScreen = false;
1479						$timeout.cancel(timer);
1480						$scope.displayRate(data.responseObj);
1481            			if(_payment && _payment.fxSpotForward.creditCcyAmount){
1482            				beginSuppressResubmitWatch();
1483            				try {
1484            				$scope.payment.fxSpotForward.debitCcyAmount =_payment.fxSpotForward.debitCcyAmount;
1485    						$scope.payment.fxSpotForward.creditCcyAmount =_payment.fxSpotForward.creditCcyAmount;
1486    						$scope.payment.fxSpotForward.allInRate =_payment.fxSpotForward.allInRate;
1487    						$scope.quoteId=_payment.quoteId;
1488    						if(_payment.paymentFee){
1489    							$scope.payment.paymentFee=_payment.paymentFee;
1490    						}
1491    						if (_payment) updatePaymentObjectFromServer(_payment);
1492    						$scope.noOfApprovalsRequiredForPayment = computeNoOfApprovalsRequiredFromEntity();
1493    						if($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && !$scope.isFinalApproverRateAcceptanceRequired() && isUsdAmountStrictlyAboveFirstApproverLimit()){
1494    							$scope.displayRateTimer = false;
1495    							$scope.privateTrade = data.responseObj;
1496    							if (!$scope.editPaymentMode) {
1497    								$scope.initiatorIndicativeDisclaimerAfterSuccessfulRate = true;
1498    							}
1499    							$scope.expMsg = $scope.getIndicativeRateMessage();
1500    							$scope.hideGetRateBtn = true;
1501    							$scope.displayRate($scope.payment);
1502								$scope.displayExRateInfo = true;
1503    						}else{
1504								if ($scope.isFinalApproverRateAcceptanceRequired()) {
1505									$scope.expMsg = "";
1506								}
1507    							$scope.expiryValue = data.responseObj.priceExpiresInSeconds;
1508    							$scope.displayRateTimer = true;
1509                				$scope.displayRate($scope.payment);
1510								$scope.startKnob();
1511								$scope.showCancelButton = false;
1512								$scope.askConfirmCancel=false;
1513								if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.isFinalApproverRateAcceptanceRequired()) {
1514									$scope.disablePaymentFields = true;
1515								}
1516    						}
1517            				} finally {
1518            					endSuppressResubmitWatch();
1519            				}
1520            			}else{
1521							$scope.handleIncompleteStreamingRate(ticketId, stopPolling);
1522            			}
1523            		}else{
1524						$scope.handleIncompleteStreamingRate(ticketId, stopPolling);
1525					}
1526
1527            	});
1528        	}, 3000);
1529		}
1530		/***
1531		** Message to Receipient Info.
1532		*/
1533		$scope.isValidate = true;
1534
1535		$scope.$watchCollection('[payment.fxSpotForward.paymentNotes,payment.paymentAmount,payment.fxSpotForward.valueDate,paymentMethod]', function() {
1536			$scope.requiredToGetRate = false;
1537			$scope.getRateError = undefined;
1538		});
1539
1540		$scope.$watchCollection('recurringPayment', function(newValue, oldValue) {
1541			$scope.recurringPayReq = (newValue.frequency || newValue.firstPaymentDate || newValue.limit)?true:false;
1542		});
1543
1544		$scope.validateRecurringPayment = function(){
1545			var isValid = true;
1546			if($scope.recurringPayment.limit=="amount" && parseFloat($scope.recurringPayment.maxAmount)<parseFloat($scope.payment.paymentAmount)){
1547				$scope.formErrorMessage = "The recurring payment total amount should be greater than or equal to the original payment amount.";
1548				$scope.formError = true;
1549				isValid = false;
1550			}else if($scope.recurringPayment.limit=="noOfPayments" && parseInt($scope.recurringPayment.noOfPayments)<1){
1551				$scope.formErrorMessage = "The number of recurring payments should be greater than or equal to one.";
1552				$scope.formError = true;
1553				isValid = false;
1554			}
1555			return isValid;
1556		}
1557
1558		/*******
1559		** Function to review Payment.
1560		*/
1561		$scope.reviewPayment = function(){
1562			$scope.formError = false;
1563			let feeAmount = ($scope.payment.paymentAmount)?$scope.payment.paymentAmount:1;
1564			$scope.formErrorMessage = "";
1565			$scope.exception = "";
1566			$("#deliveryMethod").removeClass("txtbxReq");
1567			if( $("#deliveryMethod").val() == null){
1568				$("#deliveryMethod").addClass("txtbxReq");
1569			}
1570			if( $rootScope.isUndefined( $('[name=paymentDate]').val() )){
1571				$('[name=paymentDate]').addClass("txtbxReq");
1572			}
1573			if($scope.paymentForm.$error.required ||  $rootScope.isUndefined($scope.payment.paymentAmount)){
1574				if( !$scope.payment.paymentAmount ){
1575					$scope.formErrorMessage = "Please provide amount." + "<br>";
1576				}
1577				if( $("#deliveryMethod").val() == null){
1578					$scope.formErrorMessage = $scope.formErrorMessage + " Please select delivery method." + "<br>";
1579				}
1580				if( $("#deliveryMethod").val() && !$scope.payment.fxSpotForward.valueDate ){
1581					$scope.formErrorMessage = $scope.formErrorMessage + " Please provide payment date." + "<br>";
1582				}
1583				if(!$scope.payment.fxSpotForward.paymentNotes){
1584					$scope.formErrorMessage = $scope.formErrorMessage +" Please provide purpose of payment.";
1585				}
1586				if($scope.recurringPayment.limit=="noOfPayments" && !$scope.recurringPayment.noOfPayments){
1587					$scope.formErrorMessage = $scope.formErrorMessage +" Please provide number of recurring payment(s).";
1588				}
1589				if($scope.recurringPayment.limit=="amount" && !$scope.recurringPayment.maxAmount){
1590					$scope.formErrorMessage = $scope.formErrorMessage +" Please provide recurring payment total amount.";
1591				}
1592				if($scope.recurringPayment.frequency && !$scope.recurringPayment.firstPaymentDate){
1593					$scope.formErrorMessage = $scope.formErrorMessage +" Please select recurring payment start date.";
1594				}
1595				if($scope.recurringPayment.frequency && !recurringPayment.limit){
1596					$scope.formErrorMessage = $scope.formErrorMessage +" Please select recurring payment limit.";
1597				}
1598				if($scope.recurringPayment.limit=="date" && !$scope.recurringPayment.recurringEndDate){
1599					$scope.formErrorMessage = $scope.formErrorMessage +" Please select recurring payment end date.";
1600				}
1601				if($scope.paymentForm.$error.required && $scope.paymentForm.$error.required[0].$name=="recurringFrequency"){
1602					$scope.formErrorMessage = $scope.formErrorMessage +" Please select recurring Valid Recurring Frequency.";
1603				}
1604				$scope.formError = true;
1605				return;
1606			}
1607			if(feeAmount && parseFloat(feeAmount)<=parseFloat("0")){
1608				$scope.formErrorMessage = "Please enter currency amount greater than zero.";
1609				$scope.formError = true;
1610				$scope.invalidAmount =true;
1611				return;
1612			}
1613			if(!$scope.isSameCurrency && !$scope.rateaccepted && !($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.displayExRateInfo)){
1614				$scope.formErrorMessage = "Please get the rate.";
1615				$scope.formError = true;
1616				return;
1617			}
1618			if($scope.isHoliday || ($scope.payment.fxSpotForward.valueDate < $scope.today)){
1619				$scope.formErrorMessage = "Please select a different date.";
1620				$scope.formError = true;
1621				return;
1622			}
1623			if($scope.paymentForm.paymentNotes.$error.swiftValidate){
1624				$scope.formErrorMessage = "Please remove invalid character from Purpose of payment.";
1625				$scope.formError = true;
1626				return;
1627			}
1628			if($scope.firstPaymentDateInvalid){
1629				let _minimumAllowedDate = new Date((($scope.payment.fxSpotForward.valueDate)?$scope.payment.fxSpotForward.valueDate:$scope.today));
1630				$scope.formErrorMessage = "Please select recurring payment date on or after : " + $filter("date")(_minimumAllowedDate,'MM/dd/yyyy');
1631				$scope.formError = true;
1632				return;
1633			}
1634			if(!$scope.validateRecurringPayment()){
1635				return;
1636			}
1637			$scope.payment.recipientPhoneNumber = intlInput.getNumber();
1638			var isValid=validateRecipiantInfo();
1639			if(!isValid) return;
1640
1641			if ($scope.payment.recipientPhoneNumber && !$scope.payment.recipientPhoneNumber.startsWith("+")) {
1642				bootbox.confirm({
1643					title: "Warning Message",
1644					message: "Mobile numbers outside the US must be prefixed with +Country Code (e.g. +49 for Germany). For US numbers this is not mandatory. Do you want to proceed?",
1645					swapButtonOrder: true,
1646					closeButton: false,
1647					buttons: {
1648						confirm: { label: 'Yes', className: 'btn-primary' },
1649						cancel: { label: 'No', className: 'btn-danger' }
1650					},
1651					callback: function (result) {
1652						if (result) {
1653							$scope.proceedSavePayment();
1654							return result;
1655						}
1656					}
1657				});
1658			}else{
1659				$scope.proceedSavePayment();
1660			}
1661		}
1662
1663		$scope.proceedSavePayment = function(){
1664			$scope.paymentNotAllowed = true;
1665			$scope.postPayment();
1666			return true;
1667		}
1668
1669		function validateRecipiantInfo(){
1670			// validate for Message To Recipient
1671			if($scope.msgEmailForm.recipientEmailAddress.$invalid){
1672				$scope.formErrorMessage = "Invalid email address";
1673				$scope.formError = true;
1674				return;
1675			}
1676			if($scope.paymentForm.recipientPhoneNumber.$invalid){
1677				$scope.formErrorMessage = "Invalid Phone Number";
1678				$scope.formError = true;
1679				return;
1680			}
1681			if($scope.payment.recipientMessageToPayee){
1682				if( !$scope.payment.recipientPhoneNumber & !$scope.payment.recipientEmailAddress){
1683					$scope.formErrorMessage = "Please provide recipient's phone number or email address.";
1684					$scope.formError = true;
1685					return;
1686				}
1687			}
1688			if($scope.payment.recipientPhoneNumber || $scope.payment.recipientEmailAddress){
1689				if(!$scope.payment.recipientMessageToPayee){
1690					$scope.formErrorMessage = "Please provide the message to recipient.";
1691					$scope.formError = true;
1692					return;
1693				}
1694			}
1695			if ($scope.payment.recipientEmailAddress ) {
1696				var emailList = angular.copy($scope.payment.recipientEmailAddress.split(","));
1697				if (emailList.length > 10) {
1698					$scope.formErrorMessage = "Exceeds email limit, more than 10 not allowed";
1699					$scope.formError = true;
1700					return;
1701				}
1702				if (!$scope.payment.recipientMessageToPayee) {
1703					$scope.formErrorMessage = "Enter message";
1704					$scope.formError = true;
1705					return;
1706				}
1707			}
1708
1709			return true;
1710		}
1711
1712		function displayConfirmationPage(){
1713			$scope.paymentProcessed = true;
1714			$location.hash('confirmPage');
1715		}
1716		function isAcceptAndApproveRateAcceptance() {
1717			var required = $scope.noOfApprovalsRequiredForPayment != null ? $scope.noOfApprovalsRequiredForPayment : $rootScope.noOfApprovalsRequired;
1718			return (required >= 1) && $rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.isCurrentUserFinalApprover && $scope.isAllowedToApprovePayment;
1719		}
1720		function isIndicativeRateAcceptance() {
1721			if (!$rootScope.isSavePaymentEnabled || !$rootScope.isDualApprovalEnabled) return false;
1722			/* Above first-approver USD limit: always indicative wording; hide "Your payment has been submitted." */
1723			if (isUsdAmountStrictlyAboveFirstApproverLimit()) return true;
1724			return !isAcceptAndApproveRateAcceptance();
1725		}
1726		function getAcceptedRateHeader() {
1727			if (!paymentHasExternalParentRef($scope.privateTrade) && $rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && isUsdAmountStrictlyAboveFirstApproverLimit()) {
1728				return "Accepted Indicative Rate:";
1729			}
1730			return "Accepted Rate:";
1731		}
1732		$scope.isIndicativeRateAcceptance = isIndicativeRateAcceptance;
1733		$scope.shouldShowPaymentSubmittedMessage = function () {
1734			if (!$scope.rateaccepted || $scope.isFutureDatedPayment) return false;
1735			var required = $scope.noOfApprovalsRequiredForPayment != null ? $scope.noOfApprovalsRequiredForPayment : $rootScope.noOfApprovalsRequired;
1736			if (required === 0) return true;
1737			return !isIndicativeRateAcceptance();
1738		};
1739		/****
1740		** Cancel Payment
1741		*/
1742		$scope.cancelPayment = function(){
1743			$scope.askConfirmCancel = angular.copy(true);
1744			$scope.showCancelButton = false;
1745			$('input[name="recipientPhoneNumber"]').prop('disabled', true);
1746		}
1747		$scope.cancelCancellation = function(){
1748			$scope.askConfirmCancel = angular.copy(false);
1749			if ($scope.editPaymentMode && $scope.privateTrade) {
1750				updateCancelButtonVisibility();
1751			} else {
1752				$scope.showCancelButton = true;
1753			}
1754			$('input[name="recipientPhoneNumber"]').prop('disabled', false);
1755		}
1756		$scope.confirmCancel = function(_type) {
1757		    var paymentId = $scope.payment.id;
1758			var recurringPaymentId = undefined;
1759			if (_type !== "recurring" && $scope.rateRejected === true && !$rootScope.isSavePaymentEnabled) {
1760            		bypassStateRecurrsion = true;
1761            		$state.go("home.makePayment");
1762            		return;
1763            }
1764		    /*if(_type=="new" || _type=="edit"){
1765		    	paymentId = $scope.paymentId;
1766		    }else */if(_type=="recurring"){
1767		    	recurringPaymentId = $scope.recurringPaymentId;
1768		    	$scope.repeatButtonText = "Canceled";
1769    			angular.element( document.querySelector("#recurringCancel")).addClass('btn-danger');
1770    			angular.element( document.querySelector("#recurringCancel")).removeClass('btn-primary');
1771    			angular.element( document.querySelector("#recurringCancel")).disabled = true;
1772		    }
1773		    if (!paymentId && _type !== "recurring" && !$scope.isSameCurrency && ($scope.tradeNo || $scope.ticketId)) {
1774		    	var _ccyCancelPs = ($scope.privateTrade && $scope.privateTrade.pricingStatus && $scope.privateTrade.pricingStatus.id)
1775		    		|| $scope.pricingStatusId
1776		    		|| ($scope.payment && $scope.payment.pricingStatus && $scope.payment.pricingStatus.id);
1777		    	if (_ccyCancelPs !== "PriceInFuture") {
1778		    		canPoll = false;
1779		    		$scope.exception = undefined;
1780		    		$timeout.cancel(timer);
1781		    		$scope.cancelRate();
1782		    		$scope.askConfirmCancel = false;
1783		    		$('input[name="recipientPhoneNumber"]').prop('disabled', false);
1784		    		bypassStateRecurrsion = true;
1785		    		$state.go("home.makePayment");
1786		    		return;
1787		    	}
1788		    }
1789		    if(!paymentId){
1790		    	bypassStateRecurrsion=true;
1791		    	$state.go("home.makePayment");
1792		    	return;
1793		    }
1794			if ($scope.payment.status == "WaitingRFQ") {
1795				canPoll = false;
1796				bypassStateRecurrsion=true;
1797				bypassStateRecurrsion = true;
1798                $timeout.cancel(timer);
1799                PaymentService.cancelPayment(paymentId, recurringPaymentId).then(function (response) {
1800                		if (response && response.errorResponse) {
1801                			$scope.exception = response.errorResponse;
1802                		}
1803                		$state.go("home.makePayment");
1804                		});
1805			}
1806			else {
1807				PaymentService.cancelPayment(paymentId, recurringPaymentId).then(function (response) {
1808					bypassStateRecurrsion = true;
1809					$timeout.cancel(timer);
1810					if (_type == "goBack") {
1811						$state.go("home.makePayment");
1812					}
1813					if (response.errorResponse) {
1814						$scope.exception = response.errorResponse;
1815					} else if (_type == "new" || _type == "edit") {
1816						$state.go("home.makePayment");
1817					}
1818				});
1819			}
1820		}
1821		/*******
1822		**  Confirm payment functionality.
1823		*/
1824		$scope.postPayment = function(){
1825			$scope.paymentNotAllowed = true;
1826			let fundingAcctId = angular.copy($scope.fromAccount.id);
1827			let beneAcctId = angular.copy($scope.toAccount);
1828			$scope.payment.fromAccId=fundingAcctId;
1829			$scope.payment.toAccId=beneAcctId;
1830			let _paymentObj = angular.copy($scope.payment);
1831			if(_paymentObj.id){
1832				if (!$scope.payment.externalRefId && $scope.privateTrade && $scope.privateTrade.externalRefId) {
1833					$scope.payment.externalRefId = $scope.privateTrade.externalRefId;
1834				}
1835				saveRecurringPaymentInfo();
1836			}else if($scope.isSameCurrency){
1837				makeSameCcyPayment();
1838			}else{
1839				let _payment = angular.copy($scope.payment);
1840				let _paymentAmount = angular.copy(_payment.paymentAmount);
1841				if($scope.amountOption == "equivalent"){
1842					if(_payment.fxSpotForward.debitCcy == $scope.bankAccount.depositCcy){
1843						_payment.fxSpotForward.debitCcyAmount = angular.copy(_paymentAmount);
1844					}else if(_payment.fxSpotForward.creditCcy == $scope.bankAccount.depositCcy){
1845						_payment.fxSpotForward.creditCcyAmount = angular.copy(_paymentAmount);
1846					}
1847				}else{
1848					if(_payment.fxSpotForward.debitCcy == $scope.payeeAccount.accountCcy){
1849						_payment.fxSpotForward.debitCcyAmount = angular.copy(_paymentAmount);
1850					}else if(_payment.fxSpotForward.creditCcy == $scope.payeeAccount.accountCcy){
1851						_payment.fxSpotForward.creditCcyAmount = angular.copy(_paymentAmount);
1852					}
1853				}
1854				_payment.paymentDeliveryMethod = $scope.paymentMethod;
1855				let _formatedPayment = formatPaymentDate(_payment);
1856				delete _formatedPayment["tradeDate"];
1857				PaymentService.oobaWithCallBack(_formatedPayment, "FuturePayment", null, null).then(function (response) {
1858					$scope.paymentNotAllowed = true;
1859					if (typeof response.result === 'object') {
1860						callbackFuturePayment(response.result);
1861					} else {
1862						$scope.disablePaymentFields = true;
1863						$('.add-on').off('click');
1864						$('.add-on').css('pointer-events', 'none').css('opacity', '0.5');
1865						$("#payment_ooba").html(response.result);
1866						setTimeout(function () {
1867							$("input[name='recipientEmailAddress']").removeAttr('disabled');
1868							$("textarea[name='recipientMessageToPayee']").removeAttr('disabled');
1869						}, 100);
1870						$scope.initiateOOBA(callbackFuturePayment, _formatedPayment, "FuturePayment", null);
1871					}
1872				});
1873			}
1874
1875		}
1876		function callbackFuturePayment(response) {
1877			if (response.success) {
1878				$scope.payment.id = angular.copy(response.responseObj.id);
1879				$scope.payment.externalRefId = response.responseObj.externalRefId;
1880				$scope.payment.tradeDate = response.responseObj.tradeDate;
1881				$scope.setAmountAfterPricing(response.responseObj);
1882				saveRecurringPaymentInfo();
1883			} else {
1884				$scope.paymentNotAllowed = false;
1885				$scope.disablePaymentFields = false;
1886				$scope.exception = response.errorResponse;
1887			}
1888		}
1889
1890		function saveRecurringPaymentInfo(){
1891			deleteDocuments();
1892			if($scope.savePayeeFiles.length>0 && $scope.saveReferenceFiles.length>0){
1893				uploadDocuments($scope.savePayeeFiles,true,uploadDocuments,$scope.savePayeeFiles);
1894			}else if($scope.savePayeeFiles.length>0){
1895				uploadDocuments($scope.savePayeeFiles,true,savePaymentInfo);//to upload the payee documents
1896			}else if($scope.saveReferenceFiles.length>0){
1897				uploadDocuments($scope.saveReferenceFiles,false,savePaymentInfo);//to upload the reference documents
1898			}else{
1899				var startDate = $filter('date')($scope.recurringPayment.firstPaymentDate,'yyyy-MM-dd');
1900				$scope.recurringPayment.firstPaymentDate=angular.copy(startDate);
1901				if($scope.recurringPayment.recurringEndDate){
1902					var endDate = $filter('date')($scope.recurringPayment.recurringEndDate,'yyyy-MM-dd');
1903					$scope.recurringPayment.recurringEndDate=angular.copy(endDate);
1904				}
1905				savePaymentInfo()
1906			}
1907		}
1908
1909		function savePaymentInfo(){
1910			var recurringPayment = angular.copy($scope.recurringPayment);
1911			recurringPayment.paymentId = angular.copy($scope.payment.id);
1912			let _formatedPayment = formatPaymentDate($scope.payment);
1913			PaymentService.savePaymentInfo(recurringPayment,_formatedPayment, $scope.payment.detailsOfCharges).then(function(response){
1914					if(!response.success){
1915						$scope.formErrorMessage = response.errorResponse;
1916						$scope.formError = true;
1917						$scope.paymentNotAllowed = false;
1918						return;
1919					}else{
1920						var _ro = response.responseObj;
1921						if (_ro && _ro.externalRefId != null && _ro.externalRefId !== "") {
1922							$scope.payment.externalRefId = _ro.externalRefId;
1923						} else if (!$scope.payment.externalRefId && $scope.privateTrade && $scope.privateTrade.externalRefId) {
1924							$scope.payment.externalRefId = $scope.privateTrade.externalRefId;
1925						}
1926						$scope.paymentNotAllowed = true;
1927						  //$state.go('home.makePayment.paymentActivity');
1928						displayConfirmationPage();
1929					}
1930                });
1931		}
1932
1933		$scope.reUploadDocument = function() {
1934			saveRecurringPaymentInfo();
1935		};
1936
1937		/**
1938		*   Upload Documents for your reference.
1939		*/
1940		function uploadDocuments(_files,_isPayeeDoc,callbackFunc,callbackData) {
1941			var _paymentId = angular.copy($scope.payment.id);
1942		    if (_files) {
1943		    	angular.forEach(_files, function(fileObject,index) {
1944					_isPayeeDoc=_isPayeeDoc?_isPayeeDoc:false;
1945		    		PaymentService.uploadDocument(fileObject, _paymentId ,_isPayeeDoc).then(function(response){
1946						if(!response.success){
1947							$scope.paymentNotAllowed = false;
1948							showUploadConfirmation(response, $scope, savePaymentInfo);
1949						}else{
1950							if(_files.length-1==index){
1951								if(callbackFunc && callbackData){
1952									callbackFunc(callbackData);
1953								}else if(callbackFunc)
1954								{
1955									callbackFunc();
1956								}else{
1957									savePaymentInfo();
1958								}
1959							}
1960						}
1961					});
1962				});
1963		    }
1964		}
1965		function showUploadConfirmation(response, $scope, savePaymentInfo) {
1966			var confirmMessage = response.errorResponse + '". Do you want to reload the document?';
1967
1968			bootbox.confirm({
1969				title: "Warning Message",
1970				message: confirmMessage,
1971				swapButtonOrder: true,
1972				closeButton: false,
1973				buttons: {
1974					confirm: { label: 'Yes', className: 'btn-primary' },
1975					cancel: { label: 'No', className: 'btn-danger' }
1976				},
1977				callback: function (result) {
1978					if (!result) {
1979						savePaymentInfo();
1980					} else {
1981						$scope.$apply(function() {
1982							$scope.uploadDocumentBtn = true;
1983						});
1984					}
1985				}
1986			});
1987		}
1988		/**
1989		*   Delete Documents for your reference.
1990		*/
1991		function deleteDocuments(){
1992			var documents=[];
1993			if($scope.removedReferenceDocuments){
1994				documents=angular.extend(documents, $scope.removedReferenceDocuments);
1995			}
1996			if($scope.removedPaymentDocuments){
1997				documents=angular.extend(documents, $scope.removedPaymentDocuments);
1998			}
1999			angular.forEach(documents, function(document, key) {
2000				  if (document.id) {
2001						PaymentService.removePaymentDocument(document.id).then(function(response) {
2002							if (response.errorResponse) {
2003								$scope.errorDocument = response.errorResponse;
2004							}
2005						});
2006					}
2007
2008				});
2009		}
2010
2011		/***************************************
2012		**** Recurring Payment Functionality *****
2013		***************************************/
2014		var recurringPayment = {
2015			frequency : undefined,
2016			firstPaymentDate : undefined,
2017			limit : undefined,
2018			maxAmount : undefined,
2019			recurringEndDate : undefined,
2020			cronPattern : undefined,
2021			paymentId: undefined,
2022			noOfPayments: undefined
2023		};
2024		$scope.recurringPayment = recurringPayment;
2025		$scope.lockUiForStreamingCrossCcySession = function () {
2026			if (!$scope.isStramingRate || $scope.rateaccepted) {
2027				return false;
2028			}
2029			if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.exchangeRateInformation) {
2030				return false;
2031			}
2032			return true;
2033		};
2034		/* date picker */
2035		$scope.openFirstPaymentDate = function($event) {
2036			if ($scope.lockUiForStreamingCrossCcySession()) {
2037				return;
2038			}
2039            $event.preventDefault();
2040            $event.stopPropagation();
2041            $scope.openFirstPaymentCal = true;
2042        }
2043		$scope.openRecurringEndDate = function($event) {
2044			if ($scope.lockUiForStreamingCrossCcySession()) {
2045				return;
2046			}
2047            $event.preventDefault();
2048            $event.stopPropagation();
2049            $scope.openLastPaymentCal = true;
2050        }
2051		$scope.populateDay = function () {
2052			 	if($scope.recurringPayment.frequency == "Monthly" && $scope.recurringPayment.firstPaymentDate){
2053
2054			 		var day = new Date($scope.recurringPayment.firstPaymentDate).getDate();
2055			 			day = day + nth(day);
2056			 	} else if($scope.recurringPayment.firstPaymentDate){
2057			 		day = weekDay(new Date($scope.recurringPayment.firstPaymentDate));
2058			 	}
2059			 	$scope.day = day;
2060				isFirstPaymentDateValid();
2061		}
2062
2063
2064		/********************************************************************************************
2065		**** This watchgroup is used to listen the change event of firstPaymentDate & frequency *****
2066		*********************************************************************************************/
2067		$scope.$watchGroup(["recurringPayment.firstPaymentDate","recurringPayment.frequency"], function(newValue, oldValue) {
2068			if($scope.recurringPayment.firstPaymentDate){
2069				angular.element("#recurringEndDate")[0].value = null;
2070				var date=new Date($scope.recurringPayment.firstPaymentDate);
2071				if($scope.recurringPayment.frequency == "Monthly"){
2072					$scope.minRecurringEndDate=date.setMonth(date.getMonth()+1);
2073				}else{
2074					$scope.minRecurringEndDate=new Date(date.getFullYear(),date.getMonth(),date.getDate()+7);
2075				}
2076			}
2077		});
2078
2079		function nth(day) {
2080		      switch (day % 10) {
2081		            case 1:  return "st";
2082		            case 2:  return "nd";
2083		            case 3:  return "rd";
2084		            default: return "th";
2085		        }
2086		    }
2087		function weekDay(date) {
2088			var weekday = new Array(7);
2089		    weekday[0] = "Sunday";
2090		    weekday[1] = "Monday";
2091		    weekday[2] = "Tuesday";
2092		    weekday[3] = "Wednesday";
2093		    weekday[4] = "Thursday";
2094		    weekday[5] = "Friday";
2095		    weekday[6] = "Saturday";
2096		    if(date){
2097		    	return weekday[date.getDay()];
2098		    }
2099		}
2100		function isFirstPaymentDateValid(){
2101			if($scope.recurringPayment.firstPaymentDate){
2102				$scope.firstPaymentDateInvalid = false;
2103				let _firstPaymentDate = new Date($scope.recurringPayment.firstPaymentDate);
2104				let _minimumAllowedDate = new Date((($scope.payment.fxSpotForward.valueDate)?$scope.payment.fxSpotForward.valueDate:$scope.today));
2105
2106				let _firstPaymentDateT00 = new Date($scope.recurringPayment.firstPaymentDate.getFullYear(), ($scope.recurringPayment.firstPaymentDate.getMonth()+1), $scope.recurringPayment.firstPaymentDate.getDate(), 00, 00, 00, 00);
2107				let _minimumAllowedDateT00 = new Date(_minimumAllowedDate.getFullYear(), (_minimumAllowedDate.getMonth()+1), _minimumAllowedDate.getDate(), 00, 00, 00, 00);
2108
2109				if(_firstPaymentDateT00 < _minimumAllowedDateT00){
2110					$scope.firstPaymentDateInvalid = true;
2111				}
2112			}
2113		}
2114		/**
2115		* Recurring payment static information.
2116		*/
2117		PaymentService.getRecurringPaymentInfo().then(function(response) {
2118        	var responseObj = response.responseObj;
2119        	$scope.frequencyList = responseObj.recurringPaymentFrequencyList;
2120        	$scope.limitList = responseObj.recurringPaymentLimitList;
2121
2122        });
2123
2124	/***************************************************************************************
2125	              DRAG and DROP Reference Documents
2126	***************************************************************************************/
2127	$scope.referenceFiles = [];
2128	$scope.saveReferenceFiles = [];
2129	if(!$stateParams.paymentId){
2130		var dropbox = document.getElementById("dropbox")
2131
2132		dropbox.addEventListener("dragover", function(evt) {
2133			evt.stopPropagation();
2134			evt.preventDefault();
2135			var ok = evt.dataTransfer && evt.dataTransfer.types && evt.dataTransfer.types.indexOf('Files') >= 0
2136		}, false)
2137		dropbox.addEventListener("drop", function(evt) {
2138			evt.stopPropagation()
2139			evt.preventDefault()
2140			/*$scope.$apply(function(){
2141				$scope.dropText = 'Drop files here...'
2142				$scope.dropClass = ''
2143			})*/
2144			var files = evt.dataTransfer.files;
2145			if (files.length > 0) {
2146				$scope.$apply(function(){
2147					for (var i = 0; i < files.length; i++) {
2148						var file=$scope.readFileData(files[i]);
2149						$scope.referenceFiles.push(file);
2150						$scope.saveReferenceFiles.push(file);
2151					}
2152				})
2153			}
2154		}, false)
2155	}
2156    $scope.setReferenceFiles = function(element) {
2157    $scope.$apply(function(scope) {
2158      // Turn the FileList object into an Array
2159        //$scope.referenceFiles = []
2160        for (var i = 0; i < element.files.length; i++) {
2161			var file=$scope.readFileData(element.files[i]);
2162          $scope.referenceFiles.push(file)
2163          $scope.saveReferenceFiles.push(file);
2164        }
2165      scope.progressVisible = false
2166      });
2167    };
2168
2169	$scope.readFileData = function(file){
2170		if (file) {
2171			var reader = new FileReader();
2172			reader.onload = function (e) {
2173			  file.directory=e.target.result;
2174			};
2175			reader.readAsDataURL(file);
2176		  }
2177	  file.fileName=file.name;
2178	  return file;
2179	};
2180	$scope.removeFiles = function(_index){
2181		 var referenceDocument =  $scope.referenceFiles[_index];
2182		 if(!$scope.removedReferenceDocuments){
2183			 $scope.removedReferenceDocuments=[];
2184		 }
2185		 $scope.removedReferenceDocuments.push(referenceDocument);
2186		 $scope.referenceFiles.splice(_index, 1);
2187			if($scope.saveReferenceFiles){
2188				$scope.saveReferenceFiles.splice(_index, 1);
2189			}
2190    };
2191	/***************************************************************************************
2192	              DRAG and DROP Payee Documents
2193	***************************************************************************************/
2194	$scope.payeeFiles = [];
2195	$scope.savePayeeFiles = [];
2196	if(!$stateParams.paymentId){
2197		var payeeDropbox = document.getElementById("payeeDropbox")
2198
2199		payeeDropbox.addEventListener("dragover", function(evt) {
2200			evt.stopPropagation();
2201			evt.preventDefault();
2202			var ok = evt.dataTransfer && evt.dataTransfer.types && evt.dataTransfer.types.indexOf('Files') >= 0
2203		}, false)
2204		payeeDropbox.addEventListener("drop", function(evt) {
2205			evt.stopPropagation()
2206			evt.preventDefault()
2207			$scope.$apply(function(){
2208				$scope.dropText = 'Drop files here...'
2209				$scope.dropClass = ''
2210			})
2211			var payeeFiles = evt.dataTransfer.files;
2212			if (payeeFiles.length > 0) {
2213				$scope.$apply(function(){
2214					for (var i = 0; i < payeeFiles.length; i++) {
2215						$scope.payeeFiles.push(payeeFiles[i])
2216						$scope.savePayeeFiles.push(payeeFiles[i])
2217					}
2218				})
2219			}
2220		}, false)
2221	}
2222    $scope.setPayeeFiles = function(element) {
2223		console.log("called");
2224    //$scope.$apply(function(scope) {
2225		$timeout(function(){
2226      // Turn the FileList object into an Array
2227       // $scope.payeeFiles = []
2228	   console.log("element.files",element.files);
2229	   for (var i = 0; i < element.files.length; i++) {
2230			var file=$scope.readFileData(element.files[i]);
2231		  $scope.payeeFiles.push(file);
2232		  $scope.savePayeeFiles.push(file);
2233       }
2234      $scope.progressVisible = false
2235      });
2236    };
2237
2238	$scope.removePayeeFiles = function(_index){
2239		var paymentDocument =  $scope.payeeFiles[_index];
2240		if(!$scope.removedPaymentDocuments){
2241			 $scope.removedPaymentDocuments=[];
2242		 }
2243		 $scope.removedPaymentDocuments.push(paymentDocument);
2244		 $scope.payeeFiles.splice(_index, 1);
2245		 if($scope.savePayeeFiles)
2246			 $scope.savePayeeFiles.splice(_index, 1);
2247    };
2248		/**
2249	     * This function will start the timer
2250	     */
2251        $scope.startKnob = function() {
2252
2253            /*******************
2254    			NG-KNOB Options
2255    		*******************/
2256    	    var options = {
2257    	        subText: {
2258    	            enabled: true,
2259    	            text: '',
2260    	            color: 'black',
2261    	            font: '11'
2262    	        },
2263    	        min: 0,
2264    	        max: $scope.expiryValue,
2265    	        scale: {
2266    	            enabled: true,
2267    	            type: 'lines',
2268    	            color: 'gray',
2269    	            width: 0,
2270    	            quantity: 0,
2271    	            height: 2
2272    	        },
2273    	        animate: {
2274    	            enabled: true,
2275    	            duration: 2000,
2276    	            ease: 'linear'
2277    	        },
2278    	        size: 140,
2279    	        fontSize: 30,
2280    	        trackWidth: 5,
2281    	        readOnly: true,
2282    	        barWidth: 5,
2283    	        step: 1,
2284    	        trackColor: 'rgba(52,152,219,.1)',
2285    	        barColor: '#00a792',
2286    	        barCap: 5,
2287    	        dynamicOptions: true,
2288
2289    	    };
2290    	    $scope.knobOptions = angular.copy(options);
2291
2292    	    //KNOB PRE-DEFINED OPTIONS
2293           /* $scope.expiryValue = 0;
2294            $scope.knobValue = 0;
2295            $scope.knobOptions = {};*/
2296    	    $scope.knobValue = 0;
2297            $scope.timerVal = 0;
2298			var _val = 0;
2299            var started = Date.now();
2300			if(!$scope.loopStart){
2301	            $scope.interval = $interval(function() {
2302					$scope.loopStart = true;
2303	                var _int = $scope.expiryValue * 1000;
2304	                if (Date.now() - started >= _int) {
2305	                   $scope.stopKnob();
2306					   $scope.showCancelButton = true;
2307					   $scope.displayExRateInfo = false;
2308					   $scope.cancelRate();
2309					} else {
2310	                    $scope.knobValue = _val;
2311						$scope.timerVal = angular.copy($scope.expiryValue - ($scope.knobValue));
2312	                    _val = (Date.now() - started) / 1000;
2313	                }
2314	            }, 10);
2315			}
2316        };
2317		$scope.rejectRate = function(_val){
2318			$scope.missedPaymentRepriceGotRate = false;
2319			$scope.initiatorIndicativeDisclaimerAfterSuccessfulRate = false;
2320			$scope.stopKnob();
2321			$scope.rateaccepted = false;
2322			$scope.isStramingRate = false;
2323			$scope.displayExRateInfo = false;
2324			$scope.exchangeRateInformation=undefined;
2325			$scope.ratetxt="";
2326			$scope.ratetxtInverse = "";
2327			$scope.expMsg=(_val)?"":EXCHANGE_RATE_REJECTED_USER_MSG;
2328			if (_val !== "watch" && $rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled
2329				&& $scope.editPaymentMode && $scope.isFinalApproverRateAcceptanceRequired()) {
2330				$scope.expMsg = getAcceptedRateHeader();
2331			}
2332			if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled
2333                && $scope.editPaymentMode && $scope.isFinalApproverRateAcceptanceRequired()) {
2334                var _pt = $scope.privateTrade;
2335                var _st = _pt && _pt.status && _pt.status.id;
2336                var _ps = _pt && _pt.pricingStatus && _pt.pricingStatus.id;
2337                if ((_st === "PendingApproval" || _st === "PartiallyApproved") && _ps !== "PriceInFuture") {
2338                    $scope.isReinstruct = true;
2339                    $scope.disablePaymentFields = true;
2340                    $scope.disableChargeType = true;
2341                } else {
2342                    $scope.disablePaymentFields = false;
2343                    $scope.disableChargeType = false;
2344                }
2345            } else {
2346                $scope.disablePaymentFields = false;
2347            	$scope.disableChargeType = false;
2348            }
2349			$timeout.cancel(timer);
2350			updateCancelButtonVisibility();
2351		}
2352
2353		$scope.cancelRate = function(){
2354			$scope.acceptRateBtnDisable = true;
2355			if ($scope.editPaymentMode && $scope.privateTrade && ($scope.privateTrade.status.id === 'PendingApproval' || $scope.privateTrade.status.id === 'PartiallyApproved')) {
2356				$scope.determineApproverLevel();
2357			} else {
2358				$scope.hideGetRateBtn = false;
2359			}
2360			$scope.rejectRate();
2361			$scope.getRateError = "";
2362			if(($scope.tradeNo!=null && $scope.tradeNo!="") || $scope.ticketId){
2363				PaymentService.rejectRate($scope.tradeNo,$scope.ticketId).then(function(response){
2364					if(response.success){
2365						beginSuppressResubmitWatch();
2366						try {
2367							$scope.rejectRate();
2368							scope.rateRejected = true;
2369							if (!$rootScope.isSavePaymentEnabled){
2370								$scope.payment.id = null;
2371							}
2372							$scope.tradeNo = null;
2373                            $scope.ticketId = null;
2374							var previousAcceptedRate = $scope.previousAcceptedRate;
2375							if ($stateParams.paymentId && previousAcceptedRate && $scope.payment && $scope.payment.fxSpotForward) {
2376								angular.extend($scope.payment.fxSpotForward, previousAcceptedRate.fxSpotForward);
2377								$scope.exchangeRateInformation = $scope.payment.fxSpotForward;
2378								setRateDisplayLinesFromFx($scope.exchangeRateInformation);
2379								$scope.displayExRateInfo = true;
2380								if (previousAcceptedRate.externalRefId) {
2381									$scope.tradeNo = previousAcceptedRate.externalRefId;
2382									$scope.payment.externalRefId = previousAcceptedRate.externalRefId;
2383								}
2384								if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled
2385									&& $scope.isFinalApproverRateAcceptanceRequired()) {
2386									$scope.expMsg = getAcceptedRateHeader();
2387								}
2388							}
2389
2390						} finally {
2391							endSuppressResubmitWatch();
2392						}
2393					}
2394				});
2395			}
2396		}
2397
2398		function getPaymentUsdAmount(paymentOrTrade) {
2399			if (!paymentOrTrade) return null;
2400			var amt = null;
2401			if (paymentOrTrade.usdAmount != null && paymentOrTrade.usdAmount !== undefined) {
2402				amt = parseFloat(paymentOrTrade.usdAmount);
2403			} else if (paymentOrTrade.fxSpotForward) {
2404				var fx = paymentOrTrade.fxSpotForward;
2405				var dealCcy = (fx.dealCcy || '').toUpperCase();
2406				if (dealCcy === 'USD' && paymentOrTrade.paymentAmount != null) {
2407					amt = parseFloat(paymentOrTrade.paymentAmount);
2408				} else if ((fx.debitCcy || '').toUpperCase() === 'USD' && fx.debitCcyAmount != null) {
2409					amt = parseFloat(fx.debitCcyAmount);
2410				} else if ((fx.creditCcy || '').toUpperCase() === 'USD' && fx.creditCcyAmount != null) {
2411					amt = parseFloat(fx.creditCcyAmount);
2412				} else if (paymentOrTrade.paymentAmount != null && dealCcy === 'USD') {
2413					amt = parseFloat(paymentOrTrade.paymentAmount);
2414				}
2415			}
2416			return (amt != null && !isNaN(amt)) ? amt : null;
2417		}
2418
2419		function dateAtMidnight(dateLike) {
2420			if (!dateLike) return null;
2421			var d = new Date(dateLike);
2422			if (isNaN(d.getTime())) return null;
2423			d.setHours(0, 0, 0, 0);
2424			return d;
2425		}
2426
2427		function parseSystemTradeDate() {
2428			var s = $rootScope.systemTradeDate;
2429			if (!s) return null;
2430			var parts = String(s).split("-");
2431			if (parts.length === 3) {
2432				var y = parseInt(parts[0], 10);
2433				var m = parseInt(parts[1], 10) - 1;
2434				var d = parseInt(parts[2], 10);
2435				if (!isNaN(y) && !isNaN(m) && !isNaN(d)) {
2436					return new Date(y, m, d);
2437				}
2438			}
2439			return dateAtMidnight(s);
2440		}
2441
2442		function rememberMissedPaymentRepriceIfNeeded(trade) {
2443			if (!trade || !trade.id || trade.tradeDate === undefined || trade.tradeDate === null || trade.tradeDate === "") {
2444				return;
2445			}
2446			var tradeDay = dateAtMidnight(trade.tradeDate);
2447			var systemDate = parseSystemTradeDate();
2448			if (!tradeDay || !systemDate || tradeDay.getTime() >= systemDate.getTime()) {
2449				return;
2450			}
2451			try {
2452				sessionStorage.setItem("bossMissedPaymentReprice_" + trade.id, "1");
2453			} catch (e) {}
2454		}
2455
2456		function clearMissedPaymentRepriceSessionIfFinalApprover() {
2457			if (!$scope.payment || !$scope.payment.id) {
2458				return;
2459			}
2460			var req = $scope.noOfApprovalsRequiredForPayment != null ? $scope.noOfApprovalsRequiredForPayment : $rootScope.noOfApprovalsRequired;
2461			var isFinalApprovalStep = $scope.isCurrentUserFinalApprover || req == null || req <= 1;
2462			if (!isFinalApprovalStep) {
2463				return;
2464			}
2465			try {
2466				sessionStorage.removeItem("bossMissedPaymentReprice_" + $scope.payment.id);
2467			} catch (e) {}
2468		}
2469
2470		$scope.isMissedPaymentForReprice = function () {
2471			if (!$scope.editPaymentMode) return false;
2472			var pt = $scope.privateTrade;
2473			var pm = $scope.payment;
2474			var tradeDateRaw = pt && pt.tradeDate !== undefined && pt.tradeDate !== null && pt.tradeDate !== "" ? pt.tradeDate : (pm && pm.tradeDate);
2475			if (tradeDateRaw === undefined || tradeDateRaw === null || tradeDateRaw === "") {
2476				return false;
2477			}
2478			var tradeDay = dateAtMidnight(tradeDateRaw);
2479			var systemDate = parseSystemTradeDate();
2480			if (!tradeDay || !systemDate) return false;
2481			if (tradeDay.getTime() < systemDate.getTime()) return true;
2482			var id = ($scope.privateTrade && $scope.privateTrade.id) || ($scope.payment && $scope.payment.id);
2483			if (!id) return false;
2484			var persisted = false;
2485			try {
2486				persisted = sessionStorage.getItem("bossMissedPaymentReprice_" + id) === "1";
2487			} catch (e) {}
2488			if (!persisted) return false;
2489			if ($scope.isSameCurrency) return true;
2490			if ($scope.canShowGetRateButton && $scope.canShowGetRateButton()) return true;
2491			return false;
2492		};
2493
2494		$scope.isPrivateTradeApprovedOrBooked = function () {
2495			var st = $scope.privateTrade && $scope.privateTrade.status && $scope.privateTrade.status.id;
2496			return st === "Approved" || st === "Booked";
2497		};
2498
2499		function getIndicativeDisclaimerDatePart() {
2500			var s = $rootScope.systemTradeDate;
2501			if (!s) return "";
2502			var d = parseSystemTradeDate();
2503			return (d && !isNaN(d.getTime())) ? $filter("date")(d, "MM/dd/yyyy") : String(s);
2504		}
2505
2506
2507		function indicativeDisclaimerBaseConditionsMet() {
2508			if ($scope.isPrivateTradeApprovedOrBooked()) return false;
2509			if (!$rootScope.isSavePaymentEnabled || !$rootScope.isDualApprovalEnabled) return false;
2510			if (!isUsdAmountStrictlyAboveFirstApproverLimit()) return false;
2511			if ($scope.isSameCurrency) return false;
2512			return true;
2513		}
2514
2515		$scope.getIndicativeRateMessage = function () {
2516			if (paymentHasExternalParentRef($scope.privateTrade)) return "";
2517			if (!indicativeDisclaimerBaseConditionsMet()) return "";
2518			if (!$scope.hasDisplayableAcceptedOrPricedFxRate()) return "";
2519
2520			var date = getIndicativeDisclaimerDatePart();
2521			var prefix = $scope.indicativeRateDisclaimerPrefix;
2522			var deliveryLine = " The delivery date will be updated if the payment is not approved by today (" + date + ").";
2523
2524			if ($scope.isFinalApproverRateAcceptanceRequired()) {
2525				if ($scope.loadingScreen || $scope.displayRateTimer || $scope.isStramingRate) {
2526					return "";
2527				}
2528				return prefix + ". Please use 'Get Rate' to retrieve the final rate and approve the payment." + deliveryLine;
2529			}
2530
2531			if ($scope.editPaymentMode && !$scope.loadingScreen) {
2532				return prefix + ". Final rates will be provided upon payment approval." + deliveryLine;
2533			}
2534
2535			if (!$scope.editPaymentMode) {
2536				if ($scope.initiatorIndicativeDisclaimerAfterSuccessfulRate && $rootScope.isSavePaymentEnabled && $scope.displayExRateInfo && !$scope.loadingScreen && !$scope.displayRateTimer) {
2537					return prefix + ". Final rates will be provided upon payment approval." + deliveryLine + " Please submit the payment for approval.";
2538				}
2539			}
2540
2541			return "";
2542		};
2543
2544		$scope.isIndicativeRateDisclaimerActive = function () {
2545			return !!$scope.getIndicativeRateMessage();
2546		};
2547
2548		$scope.suppressIndicativeExpMsgForFinalStatus = function () {
2549			if (!$scope.isPrivateTradeApprovedOrBooked() || !$scope.expMsg) return false;
2550			return $scope.expMsg.indexOf($scope.indicativeRateDisclaimerPrefix) === 0 || $scope.expMsg === "Accepted Indicative Rate:";
2551		};
2552
2553		function isUsdAmountBelowFirstApproverLimit() {
2554			if (!$rootScope.isDualApprovalEnabled) return false;
2555			var le = $scope.le;
2556			if (!le || le.paymentLimitForFirstApprover == null) return false;
2557			var limitFirst = parseFloat(String(le.paymentLimitForFirstApprover));
2558			if (isNaN(limitFirst)) return false;
2559			var usdAmount = getPaymentUsdAmount($scope.privateTrade || $scope.payment);
2560			if (usdAmount == null) return false;
2561			return usdAmount <= limitFirst;
2562		}
2563
2564		function isUsdAmountStrictlyAboveFirstApproverLimit() {
2565			if (!$rootScope.isDualApprovalEnabled) return false;
2566			var le = $scope.le;
2567			if (!le || le.paymentLimitForFirstApprover == null) return false;
2568			var limitFirst = parseFloat(String(le.paymentLimitForFirstApprover));
2569			if (isNaN(limitFirst)) return false;
2570			var usdAmount = getPaymentUsdAmount($scope.privateTrade || $scope.payment);
2571			if (usdAmount == null) return false;
2572			return usdAmount >= limitFirst;
2573		}
2574
2575		function computeNoOfApprovalsRequiredFromEntity() {
2576			var le = $scope.le;
2577			if (!le) return $rootScope.noOfApprovalsRequired;
2578			if (le.isDualApprovalRequiredForPayment === false) return 0;
2579			var noOfRequired = le.noOfRequiredTradeAuth != null ? parseInt(le.noOfRequiredTradeAuth, 10) : ($rootScope.noOfApprovalsRequired || 0);
2580			if (isNaN(noOfRequired) || noOfRequired <= 0) return 0;
2581			var usdAmount = getPaymentUsdAmount($scope.privateTrade || $scope.payment);
2582			if (usdAmount == null) return $rootScope.noOfApprovalsRequired;
2583			var limitFirst = le.paymentLimitForFirstApprover != null ? parseFloat(String(le.paymentLimitForFirstApprover)) : null;
2584			var limitSecond = le.paymentLimitForSecondApprover != null ? parseFloat(String(le.paymentLimitForSecondApprover)) : null;
2585			if (limitFirst == null || isNaN(limitFirst)) return $rootScope.noOfApprovalsRequired;
2586			if (usdAmount < limitFirst) return 0;
2587			if (limitSecond == null || isNaN(limitSecond) || usdAmount < limitSecond) return Math.min(1, noOfRequired);
2588			return Math.min(2, noOfRequired);
2589		}
2590
2591		$scope.determineApproverLevel = function () {
2592			if (!$scope.privateTrade) {
2593				$scope.isCurrentUserFinalApprover = false;
2594				$scope.noOfApprovalsRequiredForPayment = $rootScope.noOfApprovalsRequired;
2595				return;
2596			}
2597			var approvalsMade = 0;
2598			var tradeStatus = $scope.privateTrade.status && $scope.privateTrade.status.id;
2599			if (tradeStatus === 'PendingApproval') {
2600				approvalsMade = 0;
2601			} else if (tradeStatus === 'PartiallyApproved') {
2602				approvalsMade = 1;
2603			} else {
2604				if ($scope.privateTrade.approval1Time) approvalsMade++;
2605				if ($scope.privateTrade.approval2Time) approvalsMade++;
2606			}
2607			$scope.currentApprovalLevel = approvalsMade + 1;
2608
2609			var pendingOrPartial = (tradeStatus === 'PendingApproval' || tradeStatus === 'PartiallyApproved');
2610			var dualSave = $rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled;
2611			if (pendingOrPartial && dualSave && !$scope.le) {
2612				$scope.hideGetRateBtn = true;
2613				$scope.isCurrentUserFinalApprover = false;
2614				$scope.noOfApprovalsRequiredForPayment = $rootScope.noOfApprovalsRequired;
2615				return;
2616			}
2617
2618			var requiredForPayment = computeNoOfApprovalsRequiredFromEntity();
2619			$scope.noOfApprovalsRequiredForPayment = requiredForPayment;
2620			if (requiredForPayment == null || requiredForPayment === undefined || requiredForPayment === 0) {
2621				$scope.isCurrentUserFinalApprover = false;
2622				return;
2623			}
2624
2625			$scope.isCurrentUserFinalApprover = ($scope.currentApprovalLevel >= requiredForPayment);
2626			if (pendingOrPartial && dualSave) {
2627				if ($scope.isCurrentUserFinalApprover && $scope.isAllowedToApprovePayment) {
2628					$scope.hideGetRateBtn = false;
2629				} else {
2630					$scope.hideGetRateBtn = true;
2631				}
2632			} else if ($scope.isCurrentUserFinalApprover) {
2633				$scope.hideGetRateBtn = false;
2634			} else if (!$scope.isCurrentUserFinalApprover && pendingOrPartial) {
2635				$scope.hideGetRateBtn = true;
2636			}
2637		};
2638
2639		$scope.isFinalApproverRateAcceptanceRequired = function () {
2640			return !!($scope.editPaymentMode && $scope.isCurrentUserFinalApprover && $scope.isAllowedToApprovePayment);
2641		};
2642
2643		$scope.isFinalApproverStreamingFormLockActive = function () {
2644			if (!$rootScope.isSavePaymentEnabled || !$rootScope.isDualApprovalEnabled) {
2645				return false;
2646			}
2647			if (!$scope.isFinalApproverRateAcceptanceRequired()) {
2648				return false;
2649			}
2650			if ($scope.isSameCurrency) {
2651				return false;
2652			}
2653			if ($scope.rateaccepted) {
2654				return false;
2655			}
2656			if ($scope.getRateError) {
2657				return false;
2658			}
2659			return !!($scope.displayRateTimer || $scope.isStramingRate);
2660		};
2661
2662		$scope.canShowGetRateButton = function () {
2663			if ($scope.hideGetRateBtn) {
2664				return false;
2665			}
2666			if ($scope.showGetRateForPricingCustomerMessage && !$scope.isStramingRate) {
2667				if ($scope.isSameCurrency) {
2668					return false;
2669				}
2670				return true;
2671			}
2672			if ($scope.isStramingRate) {
2673				return false;
2674			}
2675			if ($scope.rateaccepted) {
2676				var st = $scope.privateTrade && $scope.privateTrade.status && $scope.privateTrade.status.id;
2677				var pendingOrPartialApproval = st === 'PendingApproval' || st === 'PartiallyApproved';
2678				if (!($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled
2679					&& pendingOrPartialApproval && $scope.isFinalApproverRateAcceptanceRequired())) {
2680					return false;
2681				}
2682			}
2683			if ($scope.displayExRateInfo && $scope.displayRateTimer) {
2684				return false;
2685			}
2686			var finalApproverDualSave = $rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled
2687				&& $scope.isFinalApproverRateAcceptanceRequired();
2688			if ($scope.displayRateTimer && !finalApproverDualSave) {
2689				return false;
2690			}
2691			if ($scope.isSameCurrency) {
2692				return false;
2693			}
2694			if (!$scope.editPaymentMode) {
2695				return true;
2696			}
2697			return !!($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.isCurrentUserFinalApprover && $scope.isAllowedToApprovePayment);
2698		};
2699
2700		$scope.isGetRateButtonDisabled = function () {
2701			if ($scope.paymentNotAllowed || $scope.askConfirmCancel) {
2702				return true;
2703			}
2704			if ($scope.isStramingRate) {
2705				return true;
2706			}
2707			var finalApproverDualStream = $rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled
2708				&& $scope.isFinalApproverRateAcceptanceRequired() && ($scope.displayRateTimer || $scope.isStramingRate);
2709			if ($scope.loadingScreen && !finalApproverDualStream) {
2710				return true;
2711			}
2712			if ($scope.isSameCurrency) {
2713				return true;
2714			}
2715			if ($rootScope.isSavePaymentEnabled && $rootScope.isDualApprovalEnabled && $scope.editPaymentMode) {
2716				var st = $scope.privateTrade && $scope.privateTrade.status && $scope.privateTrade.status.id;
2717				var pendingOrPartial = st === 'PendingApproval' || st === 'PartiallyApproved';
2718				if (pendingOrPartial && !$scope.isAllowedToApprovePayment) {
2719					return true;
2720				}
2721				var n = $scope.noOfApprovalsRequiredForPayment;
2722				if (n != null && n !== 0 && !$scope.isCurrentUserFinalApprover) {
2723					return true;
2724				}
2725			}
2726			return false;
2727		};
2728
2729		$scope.acceptRate = function(){
2730			$scope.rejectRateBtnDisable = true;
2731			$scope.hideGetRateBtn=true;
2732			$scope.stopKnob();
2733			$scope.showCancelButton=false;
2734			var quoteId=null;
2735			var ticketId=null;
2736			if($scope.isStramingRate){
2737				$timeout.cancel(timer);
2738				quoteId=$scope.quoteId;
2739				ticketId=$scope.ticketId;
2740				let _payment=angular.copy($scope.payment);
2741				_payment.paymentDeliveryMethod = angular.copy($scope.paymentMethod);
2742				 _payment=formatPaymentDate(_payment);
2743				 delete _payment.tradeDate;
2744				PaymentService.acceptStreamingRate(_payment,ticketId,quoteId).then(function(response){
2745					$scope.hideGetRateBtn=false;
2746					var data = response;
2747					var responseObj = response.responseObj;
2748					if( responseObj ){
2749						$timeout(function(){
2750							beginSuppressResubmitWatch();
2751							try {
2752							$scope.expMsg=getAcceptedRateHeader();
2753							$scope.displayExRateInfo = true;
2754							$scope.waitForGetRate =false;
2755							$scope.rateaccepted = angular.copy(true);
2756							$scope.isStramingRate = false;
2757							clearMissedPaymentRepriceSessionIfFinalApprover();
2758							$scope.disablePaymentFields = true;
2759							$scope.payment.externalRefId = responseObj.externalRefId;
2760							updatePaymentObjectFromServer(responseObj);
2761							$scope.showCancelButton = false;
2762							if (isAcceptAndApproveRateAcceptance()) {
2763								displayConfirmationPage();
2764							}
2765							} finally {
2766								endSuppressResubmitWatch();
2767							}
2768						});
2769					}else if("POLL_FOR_TRADE" === data.errorCode) {
2770						$scope.rateaccepted = angular.copy(false);
2771						$scope.POLL_FOR_TRADE($scope.ticketId,_payment);
2772					}else{
2773						$scope.rejectRate();
2774						$timeout(function () {
2775							$scope.getRateError = response.errorResponse;
2776						}, 500);
2777					}
2778				});
2779			}else{
2780				PaymentService.accept_rate( $scope.payment.id).then(function(response){
2781					$scope.hideGetRateBtn=false;
2782					$scope.waitForGetRate = false;
2783					$scope.paymentNotAllowed = angular.copy(false);
2784					var data = response;
2785					var responseObj = response.responseObj;
2786					if( responseObj ){
2787						$timeout(function(){
2788							beginSuppressResubmitWatch();
2789							try {
2790							$scope.expMsg=getAcceptedRateHeader();
2791							$scope.displayExRateInfo = true;
2792							$scope.rateaccepted = angular.copy(true);
2793							clearMissedPaymentRepriceSessionIfFinalApprover();
2794							$scope.disablePaymentFields = true;
2795							$scope.payment.externalRefId = responseObj.externalRefId;
2796							$scope.showCancelButton = false;
2797							if (isAcceptAndApproveRateAcceptance()) {
2798								displayConfirmationPage();
2799							}
2800							} finally {
2801								endSuppressResubmitWatch();
2802							}
2803						});
2804					} else if("POLL_FOR_TRADE" === data.errorResponse) {
2805						$scope.rateaccepted = angular.copy(false);
2806						$scope.poll( $scope.paymentId);
2807					}else{
2808						$scope.rejectRate();
2809						$timeout(function () {
2810							$scope.getRateError = response.errorResponse;
2811						}, 500);
2812					}
2813				});
2814			}
2815		}
2816
2817		$scope.POLL_FOR_TRADE=function(ticketId,_payment){
2818			PaymentService.POLL_FOR_TRADE(ticketId,_payment.executionVenue, _payment).then(function(response){
2819				var data = response;
2820				var responseObj = response.responseObj;
2821				if( responseObj ){
2822					$timeout(function(){
2823						beginSuppressResubmitWatch();
2824						try {
2825						$scope.expMsg=getAcceptedRateHeader();
2826						$scope.displayExRateInfo = true;
2827						$scope.rateaccepted = angular.copy(true);
2828						clearMissedPaymentRepriceSessionIfFinalApprover();
2829						$scope.disablePaymentFields = true;
2830						$scope.payment.externalRefId = responseObj.externalRefId;
2831						updatePaymentObjectFromServer(responseObj);
2832						$scope.showCancelButton = false;
2833						} finally {
2834							endSuppressResubmitWatch();
2835						}
2836					});
2837				} else if("POLL_FOR_TRADE" === data.errorResponse) {
2838					$scope.rateaccepted = angular.copy(false);
2839					$scope.POLL_FOR_TRADE( ticketId,_payment);
2840				}else{
2841					$scope.rejectRate();
2842					$timeout(function () {
2843						$scope.getRateError = response.errorResponse;
2844					}, 500);
2845				}
2846			});
2847		}
2848
2849        $scope.stopKnob = function() {
2850			$scope.loopStart = false;
2851			$scope.knobValue = 0;
2852            $interval.cancel($scope.interval);
2853            $scope.displayRateTimer = false;
2854        }
2855		/* Date Picker */
2856        $scope.openPaymentDate = function($event) {
2857			if ($scope.lockUiForStreamingCrossCcySession()) {
2858				return;
2859			}
2860            $event.preventDefault();
2861            $event.stopPropagation();
2862            $scope.openPaymentCal = true;
2863        }
2864		$scope.indexOfObject = function indexOfObject(array, property, value) {
2865            for (var i = 0; i < array.length; i++) {
2866                if (array[i][property] === value) return i;
2867            }
2868            return -1;
2869        };
2870
2871		/**********************************************
2872		******* Same Ccy Payment **********************
2873		**********************************************/
2874		function isSameCcyPayment(){
2875			$scope.showFeeDiv = false;
2876			$scope.fees = angular.copy(_fees);
2877			let _toAccount = $scope.payeeAccount;
2878			let _fromAccount = $scope.fromAccount;
2879			if(_toAccount && _fromAccount){
2880				if(_toAccount.accountCcy == _fromAccount.depositCcy){
2881					$scope.isSameCurrency = true;
2882				}else{
2883					$scope.isSameCurrency = false;
2884				}
2885			}
2886		}
2887
2888		function makeSameCcyPayment(){
2889			let _paymentObj = angular.copy($scope.payment);
2890			_paymentObj.fxSpotForward.debitCcyAmount = _paymentObj.paymentAmount;
2891			_paymentObj.fxSpotForward.creditCcyAmount = _paymentObj.paymentAmount;
2892			_paymentObj.paymentDeliveryMethod = $scope.paymentMethod;
2893			let _formatedPayment = formatPaymentDate(_paymentObj);
2894			PaymentService.oobaWithCallBack(_formatedPayment, "sameCcyPayment").then(function (response) {
2895				if (typeof response.result === 'object') {
2896					if (!response.result.success) {
2897						$("#payment_ooba").html("");
2898						$scope.exception = response.result.errorResponse;
2899						$scope.paymentNotAllowed = false;
2900					} else {
2901						sameCcyPaymentCallBack(response.result);
2902					}
2903				} else {
2904					$("#payment_ooba").html(response.result);
2905					$scope.disablePaymentFields = true;
2906					$scope.loadingScreen = false;
2907					$scope.hideGetRateBtn = true;
2908					$scope.initiateOOBA(sameCcyPaymentCallBack, _formatedPayment, "sameCcyPayment");
2909				}
2910			});
2911		}
2912
2913		function sameCcyPaymentCallBack(response) {
2914			if (response.success) {
2915				$scope.payment.id = angular.copy(response.responseObj.id);
2916				$scope.payment.externalRefId = response.responseObj.externalRefId;
2917				$scope.setAmountAfterPricing(response.responseObj);
2918				$scope.payment.tradeDate = response.responseObj.tradeDate;
2919				saveRecurringPaymentInfo();
2920			} else {
2921				$scope.disablePaymentFields = false;
2922				$scope.exception = response.errorResponse;
2923				$scope.paymentNotAllowed = false;
2924			}
2925		}
2926
2927
2928		/**********************************************
2929		******* Edit User Functionalities.  ***********
2930		**********************************************/
2931		if("view" == $stateParams.view){
2932			$scope.viewOnly = true;
2933		}
2934		if($stateParams.paymentId){
2935			$scope.hideRepeatThisPaymentDiv = true;
2936		}
2937
2938		function loadPaymentObject(){
2939			if($stateParams.paymentId){
2940				let _trade = $scope.privateTrade;
2941				let tradeDate="";
2942
2943				$scope.isDomesticPayment=$scope.isDomesticPaymentMethod(_trade.paymentDeliveryMethod.deliveryMethod)?true:false;
2944				if($scope.isDomesticPayment){
2945					tradeDate=new Date(_trade.fxSpotForward.valueDate);
2946				}else if(_trade.tradeDate){
2947					tradeDate=new Date(_trade.tradeDate[1]+'-'+_trade.tradeDate[2]+"-"+_trade.tradeDate[0]);
2948				}
2949				let _tenorFromApi = (_trade.fxSpotForward && _trade.fxSpotForward.tenor != null)
2950					? _trade.fxSpotForward.tenor
2951					: _trade.tenor;
2952				let _payment = _trade;
2953
2954				if (_tenorFromApi != null) {
2955					let _tenorVal = angular.copy(_tenorFromApi);
2956					_payment.tenor = _tenorVal;
2957					_payment.fxSpotForward.tenor = _tenorVal;
2958				}
2959			$scope.payment = angular.copy(_payment);
2960			$timeout(function() {
2961				if (angular.isDefined($scope.message)) {
2962					angular.element(document.querySelector("#panel3")).addClass("show");
2963					angular.element(document.querySelector(".accordion-toggle")).removeClass("collapsed");
2964					angular.element(document.querySelector(".recipientInfo")).addClass("active");
2965				}
2966
2967				populateAcceptedRateInfo();
2968				$scope.getFee();
2969				populatePaymentDocument();
2970				if($stateParams.paymentId){
2971					watchPaymentObject();
2972					$scope.disableResubmit = true;
2973				}
2974			}, 1000);
2975			}
2976			//Radio button selection.
2977			if($scope.privateTrade.fxSpotForward.dealCcy == $scope.payeeAccount.accountCcy){
2978				$scope.amountOption = "notEquivalent";
2979			}else{
2980				$scope.amountOption = "equivalent";
2981			}
2982			$scope.accordionToggleEvents();
2983		}
2984		function selectDeliveryMethod(){
2985			$timeout(function(){
2986			if($stateParams.paymentId){
2987				let deliveryMethod = $scope.privateTrade.paymentDeliveryMethod;
2988				$scope.paymentMethod = angular.copy(deliveryMethod);
2989				$scope.getDateByTenor();
2990				$scope.setDeliveryMethodNote($scope.paymentMethod);
2991			}
2992			},300);
2993		}
2994		$scope.onSelectDeliveryMethod = function () {
2995			$scope.isFutureDatedPayment = false;
2996			$scope.displayExRateInfo = false;
2997			if ($scope.editPaymentMode && $scope.privateTrade && ($scope.privateTrade.status.id === 'PendingApproval' || $scope.privateTrade.status.id === 'PartiallyApproved')) {
2998				$scope.determineApproverLevel();
2999			} else {
3000				$scope.hideGetRateBtn = false;
3001			}
3002			$scope.rateaccepted = false;
3003			if ($("#deliveryMethod").val() != null) {
3004				$("#deliveryMethod").removeClass("txtbxReq");
3005			}
3006			$timeout(function(){
3007				if($scope.paymentMethod){
3008					$scope.isDomesticPayment=$scope.isDomesticPaymentMethod($scope.paymentMethod)?true:false;
3009					if($scope.isDomesticPayment){
3010						$scope.setDeliveryMethodNote($scope.paymentMethod);
3011					}else{
3012						$scope.deliveryMethodNote=null;
3013					}
3014					$scope.getDateByTenor();
3015				}
3016			},300);
3017		}
3018
3019		/**
3020		 * Parse an ISO date string "YYYY-MM-DD" returned by the tenor API
3021		 * into a local-timezone Date object to avoid UTC offset issues.
3022		 */
3023		function parseTenorDate(dateStr) {
3024			if (!dateStr) return null;
3025			var parts = dateStr.split("-");
3026			if (parts.length !== 3) return null;
3027			return new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]));
3028		}
3029
3030		$scope.getDateByTenor=function(){
3031			if(!$stateParams.paymentId){
3032				PaymentService.getTenorDateMap($scope.bankAccount.depositCcy, $scope.payeeAccount.accountCcy).then(function(response){
3033					var tenorMap,paymentDate;
3034					tenorMap=response.responseObj;
3035					var deliveryMethod=$scope.paymentMethod;
3036					var sameDay=["SameDayPayment","ACHSameDay","FedWireRealTime","RTPRealTime"];
3037					if(sameDay.indexOf(deliveryMethod)!=-1){
3038						paymentDate=tenorMap["ON"];
3039					}else if(deliveryMethod=="NextDayPayment"){
3040						paymentDate=tenorMap["TN"];
3041					}else if(deliveryMethod=="SpotPayment"){
3042						paymentDate=tenorMap["SPOT"];
3043					}else if(deliveryMethod=="FuturePayment"){
3044						paymentDate=tenorMap["SPOT"];
3045					}
3046					var spotDate = parseTenorDate(tenorMap["SPOT"]);
3047					if (spotDate) {
3048						var _minRecurringDate = new Date(spotDate);
3049						_minRecurringDate.setDate(_minRecurringDate.getDate() + 1);
3050						$scope.minRecurringDate = _minRecurringDate;
3051					}
3052					if(paymentDate){
3053						var valueDate = parseTenorDate(paymentDate);
3054						var onDate = parseTenorDate(tenorMap["ON"]);
3055						var _maxFutureDate = new Date(onDate.getFullYear() + 1, onDate.getMonth(), onDate.getDate() - 1);
3056						if($scope.isSameCurrency){
3057							$scope.maxFutureDate=_maxFutureDate;
3058						}else{
3059							$scope.maxFutureDate=null;
3060						}
3061						if(deliveryMethod=="FuturePayment" && !$stateParams.paymentId){
3062							valueDate.setDate(valueDate.getDate() + 1);
3063							$scope.minDate	=angular.copy(valueDate);
3064							$scope.payment.fxSpotForward.valueDate=null;
3065						}else{
3066							$scope.payment.fxSpotForward.valueDate = angular.copy(valueDate);
3067						}
3068						$scope.getDeliveryDate();
3069					}
3070				});
3071			}else{
3072				$scope.getDeliveryDate();
3073			}
3074		};
3075
3076		// rate accepted information.
3077		function populateAcceptedRateInfo(){
3078			$timeout(function() {
3079				let message
3080				if($scope.privateTrade.fxSpotForward && $scope.privateTrade.fxSpotForward.allInRate){
3081					$scope.exchangeRateInformation = $scope.privateTrade.fxSpotForward;
3082
3083					if ($scope.privateTrade && $scope.privateTrade.pricingStatus && $scope.privateTrade.pricingStatus.id == "PriceInFuture") {
3084						message = $rootScope.paymentFutureDatedMessage;
3085						$scope.payment.fxSpotForward.allInRate = null;
3086						$scope.exchangeRateInformation = null;
3087						$scope.ratetxt = "";
3088						$scope.ratetxtInverse = "";
3089					} else {
3090						$timeout(function(){
3091							setRateDisplayLinesFromFx($scope.privateTrade.fxSpotForward);
3092						},1000);
3093						message = ($scope.privateTrade.fxSpotForward.allInRate || ($scope.payment.fxSpotForward && $scope.payment.fxSpotForward.allInRate)) ? getAcceptedRateHeader() : $rootScope.paymentFutureDatedMessage;
3094					}
3095				} else {
3096					message = $rootScope.paymentFutureDatedMessage;
3097				}
3098				var _status=$scope.privateTrade.status
3099				var _pricingStatus=$scope.privateTrade.pricingStatus
3100				if(_status.id=="Cancelled" || _status.id=="RejectedByTrader"){
3101					message=_status.desc;
3102				}
3103				if(_pricingStatus.id=="Cancelled" || _pricingStatus.id=="RejectedByTrader"
3104					|| _pricingStatus.id=="Declined" || _pricingStatus.id=="RejectedBySystem"){
3105					$scope.payment.fxSpotForward.allInRate = null;
3106					$scope.exchangeRateInformation = null;
3107					$scope.ratetxt = "";
3108					$scope.ratetxtInverse = "";
3109					if($scope.privateTrade.messageToCustomer){
3110						$scope.rejectedMsgFuturePayment = _pricingStatus.desc + "<br><strong> Reason: " + $scope.privateTrade.messageToCustomer + "</strong>";
3111					} else {
3112						message=_pricingStatus.desc;
3113					}
3114				}
3115				$scope.expMsg= angular.copy(message);
3116				$scope.displayExRateInfo = true;
3117				$scope.rateaccepted = true;
3118				$scope.disablePaymentFields = true;
3119			});
3120		}
3121
3122		$scope.disabledWeekends = function (date, mode) {
3123			var isHoliday = false;
3124			var holidays=$scope.holidayList;
3125			if ($scope.holidayList) {
3126				for (var i = 0; i < holidays.length; i++) {
3127					if (areDatesEqual(
3128							new Date(holidays[i]), date)) {
3129						isHoliday = true;
3130					}
3131				}
3132			}
3133
3134			return (mode === 'day' && (date.getDay() === 0 || date.getDay() === 6 || isHoliday));
3135
3136			function areDatesEqual(date1, date2) {
3137			  return date1.setHours(0,0,0,0) === date2.setHours(0,0,0,0)
3138		    }
3139		};
3140
3141		function populateFromAccount(){
3142			if($stateParams.paymentId && $scope.privateTrade.fromAccId){
3143							var _index = $scope.indexOfObject( $scope.accountList,'id' , $scope.privateTrade.fromAccId);
3144				if(_index !=-1){
3145					// from account
3146					$scope.fromAccount = $scope.accountList[_index];
3147					$scope.bankAccount = angular.copy($scope.fromAccount);
3148				}
3149			}
3150			$timeout(function(){
3151				$scope.getAccountBalance($scope.fromAccount);
3152			});
3153
3154		}
3155		function populateToAccount(){
3156			//$timeout(function(){
3157			if($stateParams.paymentId && $scope.privateTrade.toAccId){
3158				$timeout(function(){
3159					var _index = $scope.indexOfObject( $scope.payeeList,'id' , $scope.privateTrade.toAccId);
3160					if(_index !=-1){
3161					$scope.toAccount = $scope.payeeList[_index].id;
3162				}
3163					let _toAccount = angular.copy($scope.toAccount);
3164					$scope.updateDeliveryMethodAndGetCcy(_toAccount);
3165					loadPaymentObject();
3166				});
3167			}
3168			//});
3169		}
3170		
3171		function populatePaymentDocument(){
3172        	if($scope.privateTrade.externalRefId){
3173        		PaymentService.getPaymentDocuments($scope.privateTrade.externalRefId).then(function(response){
3174					if(response.responseObj){
3175            			angular.forEach(response.responseObj, function(fileObject) {
3176            				fileObject.name = fileObject.fileName;
3177							if(fileObject.fileName){
3178								var type = fileObject.fileName.split('.');
3179								fileObject.type = type[type.length -1];
3180								if(fileObject.attributes.sendThisToBene){
3181									$scope.payeeFiles.push(fileObject);
3182								}else {
3183									$scope.referenceFiles.push(fileObject);
3184								}
3185							}
3186        				});
3187            			if($scope.payeeFiles.length>0 || $scope.referenceFiles.length>0){
3188							angular.element( document.querySelector("#panel2")).addClass("show");
3189							angular.element( document.querySelector(".accordion-toggle")).removeClass("collapsed");
3190							angular.element( document.querySelector(".uploadPaymentTitle")).addClass("active");
3191						}
3192            		}
3193            	})
3194        	}
3195        }
3196
3197		function formatDate(value)
3198		{
3199		   return value.getMonth()+1 + "/" + value.getDate() + "/" + value.getYear();
3200		}
3201		/***
3202	* View Document Overlay/modal.
3203	*/
3204
3205	 $scope.viewDocument = function(row) {
3206		console.log("row",row);
3207	    $scope.documentObject = angular.copy(row);
3208	 		var modalOptions = {
3209            templateUrl: 'app/templates/document/view_document.html',
3210            controller: 'viewDocumentCtrl',
3211            backdrop: 'static',
3212            size: 'lg'
3213        };
3214        var modalInstance = $modal.open(modalOptions);
3215        modalInstance.documentObject = $scope.documentObject;
3216     }
3217
3218	 /******
3219		** Filter active from accountlist by user
3220		*/
3221		$scope.filterUserActiveAccounts =function(response)
3222		{
3223			var accountsMap={};
3224			angular.forEach(response.responseObj, function(account) {
3225				accountsMap[account.id]=account;
3226			});
3227			var userAccountList=angular.copy(response.responseObj);
3228			$scope.stageAccountList = accountsMap;
3229			$scope.accountList = $scope.filterInstructableAccountList(CommonService.maskAccountNumber(angular.copy(userAccountList)));
3230		}
3231
3232		/******
3233		** Filter active payee list by user
3234		*/
3235		$scope.filterUserActivePayees = function (response, showInActiveAccounts) {
3236			var userPayeeList = angular.copy(response.responseObj);
3237			$scope.stagePayeeList = angular.copy(userPayeeList);
3238			$scope.payeeList = $scope.filterInstructablePayeeList(CommonService.maskAccountNumber(userPayeeList), showInActiveAccounts);
3239		}
3240
3241		$rootScope.makeNewPayment=function(){
3242		  if($scope.paymentProcessed){
3243			  $scope.paymentProcessed=false;
3244			  $state.go("home.makePayment.makeAPayment", {}, { reload: "home.makePayment.makeAPayment" });
3245		  }
3246	 }
3247		$scope.pinVerifyCallBack = function(){
3248			$scope.pinVerified = angular.copy(true);
3249		}
3250
3251		/*
3252		* Function To Approve Payment.
3253		*/
3254		 $scope.isAllowedToApprove= function(payment){
3255				var userId = _user.userId.toLowerCase();
3256				var resubmitter = payment.resubmittedBy?payment.resubmittedBy.toLowerCase():"";
3257				var submitter = payment.submitterId?payment.submitterId.toLowerCase():"";
3258				var authorizedBy = payment.approver1Id?payment.approver1Id.toLowerCase():"";
3259				if(submitter == userId || resubmitter == userId){
3260					$scope.disabledMsg = "Same user is not allowed to Approve.";
3261					$scope.isAllowedToApprovePayment = false;
3262				}else if(authorizedBy == userId){
3263					$scope.disabledMsg = "You've already Approved.";
3264					$scope.isAllowedToApprovePayment = false;
3265				}else{
3266					$scope.disabledMsg = "";
3267					$scope.isAllowedToApprovePayment=true;
3268				}
3269		}
3270
3271		$scope.approvePayment = function (payment) {
3272			$scope.formErrorMessage = "";
3273			$scope.formError = false;
3274			var isFinalApprover = $rootScope.isSavePaymentEnabled && $scope.isCurrentUserFinalApprover;
3275            PaymentService.oobaWithCallBack(null, "ApprovePayment", payment.id, null, isFinalApprover).then(function (response) {
3276				if (typeof response.result === 'object') {
3277					callbackApprovePayment(response.result);
3278				} else {
3279					$("#payment_ooba").html(response.result);
3280					$scope.disablePaymentFields = true;
3281					$scope.isReinstruct = false;
3282					$('textarea[name="recipientMessageToPayee"], input[name="recipientEmailAddress"], input[name="recipientPhoneNumber"]').prop('disabled', true);
3283					$scope.loadingScreen = false;
3284					$scope.hideGetRateBtn = true;
3285					$scope.hideApprovePayment = true;
3286					$scope.initiateOOBA(callbackApprovePayment, null, "ApprovePayment", payment.id);
3287				}
3288
3289			});
3290		}
3291		function callbackApprovePayment(response) {
3292			var responseData = response;
3293			//Display Response message as error.
3294			if (responseData.errorResponse) {
3295				$scope.formErrorMessage = responseData.errorMessage ? responseData.errorMessage : responseData.errorResponse;
3296				$scope.formError = true;
3297				$scope.hideApprovePayment = false;
3298			} else {
3299				bypassStateRecurrsion = true;
3300				$state.go("home.makePayment.paymentActivity", {});
3301			}
3302		}
3303
3304		 $scope.isDomesticPaymentMethod = function(deliveryMethod){
3305			 var deliveryMethodMap={"ACHSameDay":true,
3306					 "ACHRegular":true,
3307					 "FedWireRealTime":true,
3308					 "RTPRealTime":true}
3309				return deliveryMethodMap[deliveryMethod];
3310		 }
3311
3312		 $scope.setDeliveryMethodNote = function(deliveryMethod){
3313			 $scope.isACHRegular=false;
3314			 var noteMap={"ACHSameDay":"Expected delivery date for the payment is same day.",
3315					 "FedWireRealTime":"Expected delivery date for the payment is in real time.",
3316					 "RTPRealTime":"Expected delivery date for the payment is in real time."}
3317			 if(deliveryMethod=="ACHRegular"){
3318				 $scope.isACHRegular=true;
3319				 $scope.dateNew = new Date();
3320				 $scope.payment.fxSpotForward.valueDate=angular.copy(new Date($scope.dateNew.setDate($scope.dateNew.getDate()+2)));
3321				 noteMap.ACHRegular="Expected delivery date for the payment is";
3322			 }
3323
3324			 $scope.deliveryMethodNote=noteMap[deliveryMethod];
3325		 }
3326		 $scope.waitingForGetRate = function(deliveryMethod){
3327			$scope.waitForGetRate=true;
3328		 }
3329
3330		 $rootScope.isUndefined = function(value) {
3331	            if (value == null || value === undefined || value.toString().trim() == "")
3332	                return true;
3333	            else
3334	                return false;
3335	        }
3336
3337		 $scope.displayApprover1Info=function(isTime,isId){
3338			 if($scope.privateTrade.status.id=='PendingApproval')
3339				 return 'N/A';
3340			 if ($scope.privateTrade.status.id == 'Booked'
3341										|| $scope.privateTrade.status.id == 'Approved'
3342										|| $scope.privateTrade.status.id == 'PartiallyApproved') {
3343				 if(isTime){
3344					 if($scope.privateTrade.approval1Time)
3345						 return $scope.privateTrade.approval1Time;
3346					 if($scope.privateTrade.authorizedTime)
3347						 return $scope.privateTrade.authorizedTime;
3348
3349					 return $scope.privateTrade.submitTime;
3350				 }else if(isId){
3351					 if($scope.privateTrade.approver1Id)
3352						 return $scope.privateTrade.approver1Id;
3353					 if($scope.privateTrade.authorizedBy)
3354						 return $scope.privateTrade.authorizedBy;
3355
3356					 return $scope.privateTrade.submitterId;
3357				 }
3358
3359			 }else{
3360				 return 'N/A';
3361			 }
3362		 };
3363
3364		$scope.filterInstructablePayeeList = function(payeeList, showInActiveAccounts) {
3365			var currentInstruction = null;
3366			var currencycheck = true;
3367			if ($scope.isReinstruct) {
3368				currentInstruction = payeeList.filter(function(payee) {
3369					return payee.id === $scope.privateTrade.toAccId;
3370				});
3371				currentInstruction = currentInstruction ? currentInstruction[0] : null;
3372			}
3373			var filteredList = [];
3374			angular.forEach(payeeList, function(value, key) {
3375				if ($scope.checkAccountStatus(showInActiveAccounts, value)) {
3376					if (currentInstruction) {
3377						currencycheck = value.accountCcy == currentInstruction.accountCcy;
3378					}
3379					if (currencycheck) {
3380						filteredList.push(value);
3381					}
3382				}
3383			});
3384			return filteredList;
3385		}
3386
3387		$scope.checkAccountStatus = function (showInActiveAccounts, value) {
3388            if (!value) {
3389                return false;
3390            }
3391            return showInActiveAccounts ? ($scope.privateTrade.toAccId === value.id || value.status === "Active") : value.status === "Active";
3392        };
3393
3394		$scope.filterInstructableAccountList = function(accountList) {
3395			var currentInstruction = null;
3396			var currencycheck = true;
3397			if ($scope.isReinstruct && $scope.privateTrade) {
3398				currentInstruction = accountList.filter(function(account) {
3399					return account.id === $scope.privateTrade.fromAccId;
3400				});
3401				currentInstruction = currentInstruction ? currentInstruction[0] : null;
3402			}
3403			var filteredList = [];
3404			angular.forEach(accountList, function(value, key) {
3405				if (value) {
3406					if (currentInstruction) {
3407						currencycheck = value.depositCcy == currentInstruction.depositCcy;
3408					}
3409					if (currencycheck) {
3410						filteredList.push(value);
3411					}
3412				}
3413			});
3414			return filteredList;
3415		}
3416
3417		$scope.reInstructPayment = function() {
3418			let fundingAcctId = angular.copy($scope.fromAccount.id);
3419			let beneAcctId = angular.copy($scope.toAccount);
3420			if (!fundingAcctId || !beneAcctId) {
3421				$scope.formErrorMessage = "Please select the accounts!.";
3422				$scope.formError = true;
3423				return;
3424			} else if (!$scope.payment.fxSpotForward.paymentNotes) {
3425				$scope.formErrorMessage = "Purpose of payment can not be empty.";
3426				$scope.formError = true;
3427				return;
3428			}
3429			$scope.payment.recipientPhoneNumber = intlInput.getNumber();
3430			var isValid = validateRecipiantInfo();
3431			if(!isValid) return;
3432
3433			$scope.disableResubmit = true;
3434			$scope.paymentNotAllowed = true;
3435			$scope.payment.fromAccId = fundingAcctId;
3436			$scope.payment.toAccId = beneAcctId;
3437			$scope.payment.paymentStatus = null;
3438			$scope.payment.paymentAmount = $scope.payment.paymentAmount.toString();
3439			$scope.payment.tradeDate = $scope.privateTrade.tradeDate;
3440			$scope.payment.externalRefId = $scope.privateTrade.externalRefId;
3441			let _payment = formatPaymentDate($scope.payment);
3442			delete _payment.tradeDate;
3443			delete _payment.pricingStatus;
3444			delete _payment.paymentStatus;
3445
3446			if ($scope.payment.recipientPhoneNumber && !$scope.payment.recipientPhoneNumber.startsWith("+")) {
3447				bootbox.confirm({
3448					title: "Warning Message",
3449					message: "Mobile numbers outside the US must be prefixed with +Country Code (e.g. +49 for Germany). For US numbers this is not mandatory. Do you want to proceed?",
3450					swapButtonOrder: true,
3451					closeButton: false,
3452					buttons: {
3453						confirm: { label: 'Yes', className: 'btn-primary' },
3454						cancel: { label: 'No', className: 'btn-danger' }
3455					},
3456					callback: function (result) {
3457						if (result) {
3458							$scope.proceedReinstruct(_payment);
3459							return result;
3460						}else{
3461							$scope.disableResubmit = false;
3462							$scope.paymentNotAllowed = false;
3463							$scope.$apply();
3464							}
3465					}
3466				});
3467			}else{
3468				$scope.proceedReinstruct(_payment);
3469			}
3470		}
3471
3472		$scope.proceedReinstruct = function (_payment) {
3473			PaymentService.oobaWithCallBack(_payment, "ReSubmit").then(function (response) {
3474				if (typeof response.result === 'object') {
3475					callbackResubmitPayment(response.result);
3476				} else {
3477					$("#payment_ooba").html(response.result);
3478					$('#paymentForm').find('input, label, select').not('#payment_ooba input, #payment_ooba label, #payment_ooba select').prop('disabled', true);
3479					$('textarea[name="recipientMessageToPayee"]').prop('disabled', true);
3480					$scope.loadingScreen = false;
3481					$scope.hideGetRateBtn = true;
3482					$scope.hideApprovePayment = true;
3483					$scope.disableResubmit = true;
3484					$scope.isReinstruct = false;
3485					$scope.disablePaymentFields = true;
3486					$scope.initiateOOBA(callbackResubmitPayment, _payment, "ReSubmit");
3487				}
3488			});
3489		}
3490		function callbackResubmitPayment(response) {
3491			if (!response.success) {
3492				$scope.formErrorMessage = response.errorResponse;
3493				$scope.formError = true;
3494				$scope.paymentNotAllowed = false;
3495				$scope.disableResubmit = false;
3496				return;
3497			} else {
3498				var _ro = response.responseObj;
3499				if (_ro && _ro.externalRefId != null && _ro.externalRefId !== "") {
3500					$scope.payment.externalRefId = _ro.externalRefId;
3501				} else if ($scope.privateTrade && $scope.privateTrade.externalRefId) {
3502					$scope.payment.externalRefId = $scope.privateTrade.externalRefId;
3503				}
3504				$scope.hideApprovePayment = false;
3505				$scope.paymentNotAllowed = true;
3506				//$state.go('home.makePayment.paymentActivity');
3507				displayConfirmationPage();
3508			}
3509		}
3510		$scope.searchMode = 'BENEFICIARY';
3511
3512        $scope.setSearchMode = function (mode) {
3513        	$scope.searchMode = mode;
3514        	$scope.toAccount = null;
3515        	$scope.payeeAccount = null;
3516
3517        	// Refresh the chosen dropdown to reflect the new search mode
3518        	$timeout(function() {
3519        		$('#toAccount').trigger('chosen:updated');
3520        	}, 0);
3521        };
3522
3523        $scope.getPayeeDisplayName = function (payee) {
3524        	var name = $scope.searchMode === 'BENEFICIARY'
3525        		? payee.legalName
3526        		: payee.aliasName;
3527
3528        	return name + ' - ****' + payee.accountNumber +
3529        		' ( ' + payee.accountCcy + ' )';
3530        };
3531		$scope.changeToAccount = function (toAccount, uiAction) {
3532			$scope.payeeAccount = null;
3533			$scope.paymentNotAllowed = false;
3534
3535			if (toAccount) {
3536				let selectedPayee = $scope.payeeList.find(p => p.id === toAccount);
3537
3538				if (selectedPayee) {
3539					$scope.payeeAccount = selectedPayee;
3540
3541					let tempErrors = [];
3542
3543					if (selectedPayee.legalName && selectedPayee.legalName.length > 140) {
3544						tempErrors.push("Beneficiary Name exceeds the maximum length of 140 characters.");
3545					}
3546
3547					if (selectedPayee.legalAddress) {
3548						tempErrors = tempErrors.concat(validateAddress(selectedPayee.legalAddress, "Beneficiary"));
3549					}
3550
3551					if (selectedPayee.accountWithBank) {
3552						tempErrors = tempErrors.concat(validateBank(selectedPayee.accountWithBank, "Beneficiary Bank"));
3553					}
3554
3555					if (selectedPayee.intermediaryBank) {
3556						tempErrors = tempErrors.concat(validateBank(selectedPayee.intermediaryBank, "Intermediary Bank"));
3557					}
3558
3559					if (tempErrors.length > 0) {
3560						$scope.paymentNotAllowed = true;
3561						var numberedErrors = tempErrors.map((err, index) => (index + 1) + ". " + err);
3562						var errorMessage = ("<div style='color: red;'<b>Selected 'To Account' details contains error(s). Please update the beneficiary template to continue:</b><br><br></div>" + numberedErrors.join("<br>"));
3563						bootbox.alert({
3564							title: "Validation Error: Unable to Initiate Payment",
3565							message: errorMessage,
3566							closeButton: false,
3567							className: 'bootbox-alert-custom',
3568							callback: function () {
3569                                $scope.payment.toAccId = null;
3570                                $scope.toAccount = null;
3571                                $scope.payeeAccount = null;
3572                                $scope.$apply();
3573                            }
3574						});
3575					} else {
3576						if ($scope.isReinstruct) {
3577							updatePayeeAccount(toAccount, uiAction);
3578						} else {
3579							$scope.updateDeliveryMethodAndGetCcy(toAccount);
3580						}
3581					}
3582				}
3583			} else {
3584				$scope.paymentNotAllowed = false;
3585			}
3586		}
3587		$scope.paymentIntlTelInput = function(id, scopeObj){
3588			var input = document.querySelector("#"+id);
3589			var formname=$("#"+id).closest("form").attr("name");
3590			var iti = window.intlTelInput(input, {
3591			utilsScript: "app/assets/intl/intl-utils.js",
3592			});
3593			var handleChange = function() {
3594
3595				if (iti.isValidNumber()) {
3596					$scope[formname][id].$setValidity(id, true);
3597					$scope.payment.recipientPhoneNumber = iti.getNumber();
3598					iti.setNumber(iti.getNumber());
3599				} else if(iti.getNumber()){
3600				  $scope[formname][id].$setValidity(id, false);
3601				}else{
3602					$scope[formname][id].$setValidity(id, true);
3603				}
3604				if($scope.isPaymentWatchenabled){
3605					$scope.payment.recipientPhoneNumber = iti.getNumber();
3606				}
3607				$scope.$apply();
3608			};
3609			document.querySelector("#"+id).addEventListener('countrychange', handleChange);
3610			document.querySelector("#"+id).addEventListener('change', handleChange);
3611			document.querySelector("#"+id).addEventListener('keyup', handleChange);
3612			return iti;
3613		}
3614		var intlInput = $scope.paymentIntlTelInput("recipientPhoneNumber",$scope.payment);
3615
3616		$scope.canShowOOBA = function(){
3617			var isOOBARequired = false;
3618			if($stateParams.paymentId && $scope.privateTrade){ // View/Edit Payment
3619				var status = $scope.privateTrade.status.id;
3620				var pricingStatus = $scope.privateTrade.pricingStatus.id;
3621				if(pricingStatus!="PriceInFuture"){
3622					var isStatusEligible = (status == "PendingApproval" || status == "PartiallyApproved");
3623					if(!$scope.disableResubmit){
3624						isOOBARequired = $scope.twoFARequired && isStatusEligible;
3625					}else{
3626						var isUserAllowedToApprove = $scope.le.is2FARequiredToApprovePayment && $scope.isAllowedToApprovePayment;
3627						isOOBARequired = isStatusEligible && isUserAllowedToApprove;
3628					}
3629				}
3630			}else{ // New Payemnt
3631				isOOBARequired = $scope.twoFARequired && ($scope.isSameCurrency || $scope.isFutureDatedPayment)
3632			}
3633			return isOOBARequired;
3634		}
3635
3636		$scope.disableRecepientForm = function () {
3637			if ($scope.privateTrade && (($scope.privateTrade.status && $scope.privateTrade.status.id === "Booked") || ($scope.privateTrade.pricingStatus && $scope.privateTrade.pricingStatus.id == "PriceInFuture"))) {
3638				$('input[name="recipientPhoneNumber"]').prop('disabled', true);
3639				return true;
3640			}
3641			return false;
3642		}
3643	}]);
3644
3645app.filter('addDaysToDate', [ function() {
3646	return function(isoDateString, days) {
3647		if (isoDateString) {
3648			var date;
3649			days = days || 0;
3650			date = new Date(isoDateString);
3651			if (days) {
3652				date.setDate(date.getDate() + days);
3653			}
3654
3655			return date;
3656		} else {
3657			return "";
3658		}
3659	};
3660} ]);

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.