import ACTION_TYPE from '../enum/actionType'; import AMENDMENT_ACTION from '../enum/amendmentAction'; import DC_ACTION from '../enum/dcAction'; import PARTY, { isBankParty } from '../enum/party'; import USER_ROLE, { hasApproverRole } from '../enum/userRole'; import envConfig from '../env/env-config'; import { getNodeProfile } from '../env/nodeProfile'; import { changeAmendmentJson } from './changeAmendmentJson'; import { checkerApproverProceedDraft } from './checkerApproverProceedDraft'; import * as dateUtil from './dateUtil'; import { generateAdvisingBankProceededDc } from './generateDC/generateAdvisingBankProceededDc'; import { generateDocumentSourceJson } from './generateDocumentSourceJson'; import { generateOtherDocumentsJson } from './generateOtherDocumentsJson'; import { HTTP_METHOD } from './httpMethod'; import * as loginUtil from './loginUtil'; import scenarioContext from './scenarioContext'; import { updateAmendmentId } from './updateAmendmentId'; import { getUserSessionAndUploadAttachment } from './uploadAttachment'; export async function applicantOrBeneficiaryCreateAmendment( dcScenario, toParty = PARTY.ISSUING_BANK, amendPos = 0, proceededUserRoles = USER_ROLE.ADMIN1, originalAttachmentNum = 0, updatedAttachmentNum = 0, documentSourceDataTable = null, changeData = null ) { if (amendPos == 0) { await generateAdvisingBankProceededDc( dcScenario, DC_ACTION.ADVISED, USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER, originalAttachmentNum, documentSourceDataTable ); } const roles = proceededUserRoles.split('.'); const attachments = scenarioContext().dc.attachments; let endPoint = ''; let currentPartyName = envConfig.scenario[dcScenario].applicant; let currentParty = PARTY.APPLICANT; if (toParty == PARTY.BENEFICIARY) { endPoint = 'locamend/applicant/proposal/' + scenarioContext().dc.uuid + '/to/beneficiary'; } else if (toParty == PARTY.APPLICANT) { endPoint = 'locamend/beneficiary/proposal/' + scenarioContext().dc.uuid; currentPartyName = envConfig.scenario[dcScenario].beneficiary; currentParty = PARTY.BENEFICIARY; } else { endPoint = 'locamend/applicant/proposal/' + scenarioContext().dc.uuid + '/to/issuer'; } if (updatedAttachmentNum > originalAttachmentNum) { for (let i = 0; i < updatedAttachmentNum - originalAttachmentNum; i++) { const bash = await getUserSessionAndUploadAttachment( currentPartyName, USER_ROLE.MAKER, './src/util/pdf/pdfAmendment' + (i + 1) + '.pdf' ); attachments.push({ name: 'pdfAmendment' + (i + 1) + '.pdf', id: bash }); } } else if (updatedAttachmentNum < originalAttachmentNum) { for (let i = 0; i < originalAttachmentNum - updatedAttachmentNum; i++) { attachments.pop(); } } scenarioContext().dc.attachments = attachments; let json = {}; if (!scenarioContext().amendment.amendAcceptedJson) { json = { args: { props: { issuedLCRef: '123', advisedLCRef: '123', confirmedLCRef: '123', availableWithLCRef: '123', applicationDate: dateUtil.getTodayDate(), formOfDc: 'IRREVOCABLE', applicableRules: 'UCP_LATEST_VERSION', otherApplicableRules: 'Updated', expiryDate: '2025-01-01', placePresentation: 'Updated', periodPresentation: '321', typeCredit: null, typeCredits: [ { typeCredit: 'SIGHT', availableCreditsProps: {} }, { typeCredit: 'NEGOTIABLE_CREDIT', availableCreditsProps: { deferredPaymentDetails: 'Updated' } }, { typeCredit: 'DEFERRED_PAYMENT', availableCreditsProps: { deferredPaymentDetails: 'Updated' } }, { typeCredit: 'ACCEPTANCE', availableCreditsProps: { draftsAt: 'Updated', drawee: getNodeProfile(envConfig.scenario[dcScenario].issuingBank).name, draweeAddress: 'Bank A Address', draweeSWIFTBIC: '', draweeLegalName: 'Bank A' } } ], issuerClause: { content: 'Additional clause from issuing bank', attachments: [] }, amount: '20000.00 USD', additionalAmountsCovered: 'Updated', tolerance: ['30.00', '30.00'], placeOfFinalDestination: 'Updated', placeOfTakingInCharge: 'Updated', shipmentPeriod: '20', draftsAt: null, deferredPaymentDetails: null, partialShipment: 'NOT_ALLOWED', transShipment: 'CONDITIONAL', portLoading: 'Updated', portDischarge: 'Updated', lastShipmentDate: null, goods: 'Updated', instructionsToPayingBank: 'Instructions to paying bank', documentsRequired: generateDocumentSourceJson(documentSourceDataTable, true), otherDocumentsRequired: generateOtherDocumentsJson(documentSourceDataTable, true), additionalConditions: 'Presentation to be made through Voltron application under eUCP Latest Version', detailsCharges: 'All charges outside country of issue for account of applicant / importer', confirmation: 'WITH', attachments: attachments, parties: { applicant: getNodeProfile(envConfig.scenario[dcScenario].applicant).name, beneficiary: getNodeProfile(envConfig.scenario[dcScenario].beneficiary).name, issuer: getNodeProfile(envConfig.scenario[dcScenario].issuingBank).name, advisingBank: getNodeProfile(envConfig.scenario[dcScenario].advisingBank).name, confirmingBank: getNodeProfile(envConfig.scenario[dcScenario].confirmingBank)?.name ?? null, availableWithBank: getNodeProfile(envConfig.scenario[dcScenario].nominatedBank)?.name ?? null, drawee: null }, partyAddresses: { applicant: 'Updated', beneficiary: 'Updated', issuer: 'Updated', advisingBank: 'Updated', confirmingBank: 'Updated', availableWithBank: 'Updated', drawee: null }, issueDate: null, shipment: 'SHIPMENT_PERIOD', availableBy: null } }, draftComment: null }; scenarioContext().amendment.amendInProgressJson = json; } else { json = JSON.parse(JSON.stringify(scenarioContext().amendment.amendAcceptedJson)); } if (changeData) { json = changeAmendmentJson(json, changeData, dcScenario); scenarioContext().amendment.amendInProgressJson = json; } const res = await loginUtil.makeAuthenticatedRequest( currentPartyName, roles[0], endPoint, HTTP_METHOD.POST, JSON.stringify(json) ); if (hasApproverRole.includes(roles[0])) { await updateAmendmentId(currentPartyName, amendPos, res.id); } else { for (let i = 1; i < roles.length; i++) { await checkerApproverProceedDraft(currentParty, roles[i], dcScenario, res.id, ACTION_TYPE.LOCAMEND, amendPos); } } } export async function generateApplicantOrBeneficiaryProceededAmendment( dcScenario, action = AMENDMENT_ACTION.ENDORSED, amendPos = 0, proceededUserRoles = USER_ROLE.ADMIN1, currentParty = PARTY.BENEFICIARY ) { await applicantOrBeneficiaryCreateAmendment(dcScenario, currentParty); const roles = proceededUserRoles.split('.'); let prefix = ''; let suffix = ''; let currentCorp = ''; if (action == AMENDMENT_ACTION.EDITEDANDRETURNED) { suffix = '/edit'; if (currentParty == PARTY.APPLICANT) { suffix = '/edit/to/beneficiary'; } } else if (action == AMENDMENT_ACTION.REJECTED) { suffix = '/reject'; } else if (action == AMENDMENT_ACTION.ENDORSED) { suffix = '/accept'; } if (currentParty == PARTY.BENEFICIARY) { prefix = 'locamend/beneficiary/negotiation/'; currentCorp = envConfig.scenario[dcScenario].beneficiary; } else { prefix = 'locamend/applicant/negotiation/'; currentCorp = envConfig.scenario[dcScenario].applicant; } const actionInfoMap = new Map() .set(AMENDMENT_ACTION.EDITEDANDRETURNED, { endPoint: prefix + (await scenarioContext().dc.locAmendId[amendPos]) + suffix, json: { args: { props: { issuedLCRef: '123', advisedLCRef: '123', confirmedLCRef: '123', availableWithLCRef: '123', applicationDate: '2020-06-18', formOfDc: 'IRREVOCABLE', applicableRules: 'UCP_LATEST_VERSION', otherApplicableRules: 'Updated2', expiryDate: '2025-01-02', placePresentation: 'Updated2', periodPresentation: '100', typeOfPresentation: 'Updated2', issuerClause: { content: 'Additional clause from issuing bank', attachments: [] }, amount: '30000.00 USD', additionalAmountsCovered: 'Updated2', tolerance: ['50.00', '50'], placeOfFinalDestination: 'Updated2', placeOfTakingInCharge: 'Updated2', shipmentPeriod: '50', typeCredit: null, typeCredits: [ { typeCredit: 'SIGHT', availableCreditsProps: {} }, { typeCredit: 'NEGOTIABLE_CREDIT', availableCreditsProps: { deferredPaymentDetails: 'Updated2' } }, { typeCredit: 'ACCEPTANCE', availableCreditsProps: { draftsAt: 'Updated2', drawee: getNodeProfile(envConfig.scenario[dcScenario].issuingBank).name, draweeAddress: 'Updated2', draweeSWIFTBIC: 'Updated2', draweeLegalName: getNodeProfile(envConfig.scenario[dcScenario].issuingBank).displayName } } ], draftsAt: null, deferredPaymentDetails: null, partialShipment: 'CONDITIONAL', transShipment: 'ALLOWED', portLoading: 'Updated2', portDischarge: 'Updated2', lastShipmentDate: null, goods: 'Updated2', instructionsToPayingBank: 'Instructions to paying bank', documentsRequired: [ { documentType: 'PACKING_LIST', description: 'Packing List Description', subtype: null }, { documentType: 'CERTIFICATE_OF_ORIGIN', description: 'Certificate of Origin Description', subtype: null }, { documentType: 'INVOICE', description: 'Invoice Description', subtype: null }, { documentType: 'TRANSPORT_DOCUMENT_OTHER', subtype: 'Other Transport Document', description: 'Transport Document Description' } ], otherDocumentsRequired: [ { documentType: 'Other Doc 1', description: 'Other Doc Description 1' }, { documentType: 'Other Doc 2', description: 'Other Doc Description 2' } ], additionalConditions: 'Presentation to be made through Voltron application under eUCP Latest Version', detailsCharges: 'All charges outside country of issue for account of applicant / importer', confirmation: 'WITH', attachments: [], parties: { applicant: getNodeProfile(envConfig.scenario[dcScenario].applicant).name, beneficiary: getNodeProfile(envConfig.scenario[dcScenario].beneficiary).name, issuer: getNodeProfile(envConfig.scenario[dcScenario].issuingBank).name, advisingBank: getNodeProfile(envConfig.scenario[dcScenario].advisingBank).name, confirmingBank: getNodeProfile(envConfig.scenario[dcScenario].confirmingBank)?.name ?? null, availableWithBank: getNodeProfile(envConfig.scenario[dcScenario].nominatedBank)?.name ?? null, drawee: null }, partyAddresses: { applicant: 'Updated2', beneficiary: 'Updated2', issuer: 'Updated2', advisingBank: 'Updated2', confirmingBank: 'Updated2', availableWithBank: 'Updated2', drawee: null } } } } }) .set(AMENDMENT_ACTION.ENDORSED, { endPoint: prefix + (await scenarioContext().dc.locAmendId[amendPos]) + suffix, json: { args: {} } }) .set(AMENDMENT_ACTION.REJECTED, { endPoint: prefix + (await scenarioContext().dc.locAmendId[amendPos]) + suffix, json: { args: {} } }); const endPoint = actionInfoMap.get(action).endPoint; const json = actionInfoMap.get(action).json; const res = await loginUtil.makeAuthenticatedRequest( currentCorp, roles[0], endPoint, HTTP_METHOD.PUT, JSON.stringify(json) ); if (hasApproverRole.includes(roles[0])) { await updateAmendmentId(currentCorp, amendPos, res.id); } else { for (let i = 1; i < roles.length; i++) { await checkerApproverProceedDraft(currentParty, roles[i], dcScenario, res.id, ACTION_TYPE.LOCAMEND, amendPos); } } } export async function generateApplicantOrBeneficiaryDiscardedAmendment( currentParty: string, counterParty: PARTY, dcScenario: string, proceedRoles: string = USER_ROLE.ADMIN1, amendPos = 0 ) { await generateApplicantOrBeneficiaryProceededAmendment( dcScenario, AMENDMENT_ACTION.EDITEDANDRETURNED, 0, USER_ROLE.ADMIN1, counterParty ); const roles = proceedRoles.split('.'); let endPoint = ''; let json = {}; let currentCorp = ''; if (currentParty == PARTY.APPLICANT) { endPoint = `locamend/applicant/negotiation/${await scenarioContext().dc.locAmendId[amendPos]}/reject`; json = { args: {} }; currentCorp = envConfig.scenario[dcScenario].applicant; } else if (currentParty == PARTY.BENEFICIARY) { endPoint = `locamend/beneficiary/negotiation/${await scenarioContext().dc.locAmendId[amendPos]}/reject`; json = { args: {} }; currentCorp = envConfig.scenario[dcScenario].beneficiary; } const res = await loginUtil.makeAuthenticatedRequest( currentCorp, roles[0], endPoint, HTTP_METHOD.PUT, JSON.stringify(json) ); if (hasApproverRole.includes(roles[0])) { await updateAmendmentId(currentCorp, amendPos, res.id); } else { for (let i = 1; i < roles.length; i++) { await checkerApproverProceedDraft(currentParty, roles[i], dcScenario, res.id, ACTION_TYPE.LOCAMEND, amendPos); } } } export async function generateIssuingBankProceededAmendment( dcScenario, action = AMENDMENT_ACTION.ISSUED, amendPos = 0, proceededUserRoles = USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER, originalAttachmentNum = 0, updatedAttachmentNum = 0, documentSourceDataTable = null, changeData = null ) { await applicantOrBeneficiaryCreateAmendment( dcScenario, PARTY.ISSUING_BANK, amendPos, USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER, originalAttachmentNum, updatedAttachmentNum, documentSourceDataTable, changeData ); const roles = proceededUserRoles.split('.'); const actionInfoMap = new Map() .set(AMENDMENT_ACTION.ISSUED, { endPoint: 'locamend/bank/endorsement/' + scenarioContext().dc.locAmendId[amendPos] + '/accept', json: { args: {} } }) .set(AMENDMENT_ACTION.REJECTED, { endPoint: 'locamend/issuer/endorsement/' + scenarioContext().dc.locAmendId[amendPos] + '/return', json: { args: {} } }); const endPoint = actionInfoMap.get(action).endPoint; const json = actionInfoMap.get(action).json; const res = await loginUtil.makeAuthenticatedRequest( envConfig.scenario[dcScenario].issuingBank, roles[0], endPoint, HTTP_METHOD.PUT, JSON.stringify(json) ); if (hasApproverRole.includes(roles[0])) { await updateAmendmentId(envConfig.scenario[dcScenario].issuingBank, amendPos, res.id); } else { for (let i = 1; i < roles.length; i++) { await checkerApproverProceedDraft( PARTY.ISSUING_BANK, roles[i], dcScenario, res.id, ACTION_TYPE.LOCAMEND, amendPos ); } } } export async function generateBankProceededAmendment( currentParty, dcScenario, currentAction = AMENDMENT_ACTION.ADVISED, amendPos = 0, proceededUserRoles = USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER, originalAttachmentNum = 0, updatedAttachmentNum = 0, previousRoleAndActionDataTable = null, changeData = null ) { await generateIssuingBankProceededAmendment( dcScenario, AMENDMENT_ACTION.ISSUED, amendPos, USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER, originalAttachmentNum, updatedAttachmentNum, previousRoleAndActionDataTable, changeData ); await browser.pause(2000); if (previousRoleAndActionDataTable != null) { let data = null; try { data = previousRoleAndActionDataTable.raw(); } catch (e) { data = previousRoleAndActionDataTable; } for (const element of data) { const party = element[0]; const action = element[1]; if (party != '' && isBankParty.includes(party)) { await bankProceededAmendment( party, dcScenario, action, amendPos, USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER ); } else { continue; } } } if (isBankParty.includes(currentParty)) { await bankProceededAmendment(currentParty, dcScenario, currentAction, amendPos, proceededUserRoles); } } export async function beneficiaryConcludeAmendment( dcScenario, action = AMENDMENT_ACTION.ACCEPTED, amendPos = 0, proceededUserRoles = USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER, previousRoleAndActionDataTable = null, originalAttachmentNum = 0, updatedAttachmentNum = 0, changeData = null ) { await generateBankProceededAmendment( envConfig.scenario[dcScenario].beneficiary, dcScenario, null, amendPos, null, originalAttachmentNum, updatedAttachmentNum, previousRoleAndActionDataTable, changeData ); const roles = proceededUserRoles.split('.'); const actionInfoMap = new Map() .set(AMENDMENT_ACTION.ACCEPTED, { endPoint: 'locamend/beneficiary/conclusion/' + scenarioContext().dc.locAmendId[amendPos] + '/accept', json: { args: {} } }) .set(AMENDMENT_ACTION.REJECTED, { endPoint: 'locamend/beneficiary/conclusion/' + scenarioContext().dc.locAmendId[amendPos] + '/reject', json: { args: {} } }); const endPoint = actionInfoMap.get(action).endPoint; const json = actionInfoMap.get(action).json; const res = await loginUtil.makeAuthenticatedRequest( envConfig.scenario[dcScenario].beneficiary, roles[0], endPoint, HTTP_METHOD.PUT, JSON.stringify(json) ); if (hasApproverRole.includes(roles[0])) { await updateAmendmentId(envConfig.scenario[dcScenario].beneficiary, amendPos, res.id); } else { for (let i = 1; i < roles.length; i++) { await checkerApproverProceedDraft( PARTY.BENEFICIARY, roles[i], dcScenario, res.id, ACTION_TYPE.LOCAMEND, amendPos ); if (action == AMENDMENT_ACTION.ACCEPTED) { scenarioContext().amendment.amendAcceptedJson = scenarioContext().amendment.amendInProgressJson; } scenarioContext().dc.concludedAmendmentSize++; } } } export async function generateMutipleAmendments(scenario: string, proceededRole: string, dataTable: any) { const data = dataTable.rowsHash(); const amendmentKeys = Object.keys(data).filter((v) => v.startsWith('Amendment')); const changeFieldKeys = Object.keys(data).filter((v) => v.startsWith('Changed')); // Banks for (let i = 0; i < amendmentKeys.length; i++) { const proceedSteps = data['Amendment ' + (i + 1)]; let changesAndValues = []; let changes = null; const changeData = []; let originalAttachmentNum = 0; let newAttachmentNum = 0; if (changeFieldKeys.length > 0) { changes = data['Changed - Amendment ' + (i + 1)]; changesAndValues = changes.split('.'); } const rolesAndSteps = proceedSteps.split('.'); const stepData = []; for (let j = 0; j < rolesAndSteps.length / 2; j++) { const party = rolesAndSteps[j * 2]; const action = rolesAndSteps[j * 2 + 1]; stepData.push([party, action]); } for (let j = 0; j < changesAndValues.length / 2; j++) { const change = changesAndValues[j * 2]; const value = changesAndValues[j * 2 + 1]; if (change == 'originalAttachmentNum') { originalAttachmentNum = value; continue; } else if (change == 'newAttachmentNum') { newAttachmentNum = value; continue; } changeData.push([change, value]); } const lastParty = stepData[stepData.length - 1][0]; const lastAction = stepData[stepData.length - 1][1]; stepData.pop(); if (lastParty == PARTY.BENEFICIARY) { await beneficiaryConcludeAmendment( scenario, lastAction, i, proceededRole, stepData, originalAttachmentNum, newAttachmentNum, changeData ); } else if (lastParty == PARTY.ISSUING_BANK) { await generateIssuingBankProceededAmendment( scenario, lastAction, i, proceededRole, originalAttachmentNum, newAttachmentNum, null, changeData ); } else { await generateBankProceededAmendment( lastParty, scenario, lastAction, i, proceededRole, originalAttachmentNum, newAttachmentNum, stepData, changeData ); } } } async function bankProceededAmendment( party, dcScenario, action = AMENDMENT_ACTION.ADVISED, amendPos = 0, proceededUserRoles = USER_ROLE.MAKER + '.' + USER_ROLE.CHECKER_APPROVER ) { const roles = proceededUserRoles.split('.'); const actionInfoMap = new Map() .set(AMENDMENT_ACTION.ADVISED_WITH_CONFIRMATION, { endPoint: 'locamend/bank/endorsement/' + scenarioContext().dc.locAmendId[amendPos] + '/accept', json: { args: { withConfirmation: true } } }) .set(AMENDMENT_ACTION.ADVISED_WITHOUT_CONFIRMATION, { endPoint: 'locamend/bank/endorsement/' + scenarioContext().dc.locAmendId[amendPos] + '/accept', json: { args: { withConfirmation: false } } }) .set(AMENDMENT_ACTION.REJECTED, { endPoint: 'locamend/bank/endorsement/' + scenarioContext().dc.locAmendId[amendPos] + '/reject', json: { args: {} } }) .set(AMENDMENT_ACTION.ADVISED, { endPoint: 'locamend/bank/endorsement/' + scenarioContext().dc.locAmendId[amendPos] + '/accept', json: { args: {} } }); const endPoint = actionInfoMap.get(action).endPoint; const json = actionInfoMap.get(action).json; const res = await loginUtil.makeAuthenticatedRequest( envConfig.scenario[dcScenario][party], roles[0], endPoint, HTTP_METHOD.PUT, JSON.stringify(json) ); if (hasApproverRole.includes(roles[0])) { await updateAmendmentId(envConfig.scenario[dcScenario][party], amendPos, res.id); } else { for (let i = 1; i < roles.length; i++) { await checkerApproverProceedDraft(party, roles[i], dcScenario, res.id, ACTION_TYPE.LOCAMEND, amendPos); } } }