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.