Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Choose payment screen OOBO flow for PBL #61

Merged
merged 7 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions force-app/main/default/classes/AdyenOOBOController.cls
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
public with sharing class AdyenOOBOController {

@AuraEnabled(cacheable=true)
@AuraEnabled(Cacheable=true)
public static Id getOrderSummaryIdByOrderNumber(String orderNumber) {
try {
List<OrderSummary> orderSummaries = [
Expand All @@ -19,4 +19,48 @@ public with sharing class AdyenOOBOController {
throw new AuraHandledException(e.getMessage());
}
}
}

@AuraEnabled(Cacheable=true)
public static Decimal getExpiryDuration() {
try {
Decimal expiryDurationDays = [SELECT Payment_Link_Expiry_Duration__c FROM Adyen_Adapter__mdt WHERE DeveloperName = :AdyenConstants.DEFAULT_ADAPTER_NAME].Payment_Link_Expiry_Duration__c;
if (expiryDurationDays == null) {
expiryDurationDays = 1;
}
return expiryDurationDays;
} catch (Exception ex) {
throw new AuraHandledException('Unable to fetch ' + AdyenConstants.DEFAULT_ADAPTER_NAME + ' custom metadata Adyen Adapter record. Error: ' + ex.getMessage());
}
}

@AuraEnabled(Cacheable=true)
public static AccountEmailAndName getAccountEmailAndName(Id accountId) {
try {
if (AdyenPaymentUtility.personAccountsEnabled()) {
Account accountRecord = Database.query('SELECT Name, PersonEmail FROM Account WHERE Id = :accountId');
return new AccountEmailAndName(accountRecord.Name, (String)accountRecord.get('PersonEmail'));
} else {
List<Contact> contactRecords = [SELECT Name, Email FROM Contact WHERE AccountId = :accountId AND Email <> NULL ORDER BY CreatedDate DESC];
if (contactRecords.size() >= 1) {
return new AccountEmailAndName(contactRecords[0].Name, contactRecords[0].Email);
} else {
throw new AuraHandledException('No contact found for this account id ' + accountId);
}
}
} catch (Exception ex) {
throw new AuraHandledException('Unable to fetch account email. Error: ' + ex.getMessage());
}
}

public class AccountEmailAndName {
@AuraEnabled
public String name;
@AuraEnabled
public String email;

public AccountEmailAndName(String name, String email) {
this.name = name;
this.email = email;
}
}
}
36 changes: 34 additions & 2 deletions force-app/main/default/classes/AdyenOOBOControllerTest.cls
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@isTest
@IsTest
public class AdyenOOBOControllerTest {

@IsTest(SeeAllData=true)
Expand Down Expand Up @@ -40,4 +40,36 @@ public class AdyenOOBOControllerTest {
}
Test.stopTest();
}
}

@IsTest
static void getExpiryDurationTest() {
// given
// when
Decimal expireDays = AdyenOOBOController.getExpiryDuration();
// then
Assert.areEqual(1, expireDays);
}

@IsTest
static void getAccountEmailAndNameTest() {
// given
Contact newContact = TestDataFactory.insertAccountWithContact();
newContact = [SELECT Name, Email, AccountId FROM Contact WHERE Id = :newContact.Id];
// when
AdyenOOBOController.AccountEmailAndName acctInfo = AdyenOOBOController.getAccountEmailAndName(newContact.AccountId);
// then
Assert.areEqual(newContact.Email, acctInfo.email);
Assert.areEqual(newContact.Name, acctInfo.name);
}

@IsTest
static void getAccountEmailAndNameErrorTest() {
// given - no account
try { // when
AdyenOOBOController.getAccountEmailAndName(null);
Assert.fail();
} catch (Exception ex) { // then
Assert.isInstanceOfType(ex, AuraHandledException.class);
}
}
}
8 changes: 4 additions & 4 deletions force-app/main/default/classes/AdyenPaymentHelper.cls
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,16 @@ public with sharing class AdyenPaymentHelper {
}

public class PBLPostAuthRequest {
@InvocableVariable(required=true)
@InvocableVariable(Required=true)
public String paymentGatewayId;

@InvocableVariable(required=true)
@InvocableVariable(Required=true)
public String accountId;

@InvocableVariable(required=true)
@InvocableVariable(Required=true)
public String currencyIsoCode;

@InvocableVariable(required=true)
@InvocableVariable(Required=true)
public Decimal amount;
}

Expand Down
4 changes: 4 additions & 0 deletions force-app/main/default/classes/AdyenPaymentUtility.cls
Original file line number Diff line number Diff line change
Expand Up @@ -390,4 +390,8 @@ public with sharing class AdyenPaymentUtility {
return response;
}
}

public static Boolean personAccountsEnabled() {
return Schema.SObjectType.Account.fields.getMap().containsKey( 'isPersonAccount' );
}
}
8 changes: 8 additions & 0 deletions force-app/main/default/classes/TestDataFactory.cls
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ public class TestDataFactory {
return new Account(Name = 'Test Account');
}

public static Contact insertAccountWithContact() {
Account newAccount = createAccount();
insert newAccount;
Contact newContact = new Contact(FirstName = 'Test', LastName = 'last', AccountId = newAccount.Id, Email = '[email protected]');
insert newContact;
return newContact;
}

public static CardPaymentMethod createCardPaymentMethod() {
return new CardPaymentMethod(
GatewayToken = TEST_PAYMENT_TOKEN,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { NavigationMixin } from 'lightning/navigation';
import { PAYMENT_MODES } from 'c/payByLinkUtils';
import getOrderSummaryIdByOrderNumber from '@salesforce/apex/AdyenOOBOController.getOrderSummaryIdByOrderNumber';
export default class AdyenPblConfirmationScreen extends NavigationMixin(LightningElement) {
PAYMENT_MODES = {
PBL: 'pbl',
CARD: 'card',
};

export default class AdyenPblConfirmationScreen extends NavigationMixin(LightningElement) {
@api shopperName;
@api paymentLink;
@api orderReference;
Expand All @@ -18,7 +15,9 @@ export default class AdyenPblConfirmationScreen extends NavigationMixin(Lightnin
@api currencyIsoCode;

connectedCallback() {
this.linkExpiryDate = this.formatDate(this.linkExpiryDate);
if (this.isPblPaymentMode) {
this.linkExpiryDate = this.formatDate(this.linkExpiryDate);
}
}

copyPaymentLink() {
Expand All @@ -30,11 +29,11 @@ export default class AdyenPblConfirmationScreen extends NavigationMixin(Lightnin
}

get isPblPaymentMode() {
return this.paymentMode === this.PAYMENT_MODES.PBL;
return this.paymentMode === PAYMENT_MODES.PBL;
}

get isCardPaymentMode() {
return this.paymentMode === this.PAYMENT_MODES.CARD;
return this.paymentMode === PAYMENT_MODES.CARD;
}

async openOrderSummary() {
Expand Down Expand Up @@ -101,4 +100,4 @@ export default class AdyenPblConfirmationScreen extends NavigationMixin(Lightnin
formattedDate = formattedDate.replace(day, ordinalDay);
return `${formattedTime}, ${formattedDate}`;
}
}
}
33 changes: 33 additions & 0 deletions force-app/main/default/lwc/choosePayment/choosePayment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<lightning-layout horizontal-align="space">
<lightning-layout-item flexibility="auto, no-grow" padding="around-small">
<lightning-button-group>
<lightning-button icon-name="utility:send" label="Payment link" onclick={handlePblButtonClick} variant={pblButtonVariant}></lightning-button>
<lightning-button icon-name="utility:text_template" label="Manual card entry" onclick={handleCardButtonClick} variant={cardButtonVariant}></lightning-button>
</lightning-button-group>
</lightning-layout-item>
</lightning-layout>
<lightning-spinner lwc:if={isLoading}></lightning-spinner>
<template lwc:elseif={error}>
<c-error-panel errors={error}></c-error-panel>
</template>
<template lwc:else>
<lightning-layout multiple-rows lwc:if={pblSelected}>
<lightning-layout-item size="12" padding="horizontal-small">
<lightning-input disabled type="email" label="Shopper email" value={shopperEmail}></lightning-input>
</lightning-layout-item>
<lightning-layout-item size="12" padding="horizontal-small">
<div class="slds-var-p-around_medium slds-text-align_center" style="background-color: #D8E6FE; color: #0B5CAB">
<p>By submitting this order you will generate a payment link that needs to be paid in <b>{expirationDays} day(s).</b></p>
</div>
</lightning-layout-item>
</lightning-layout>
<lightning-layout multiple-rows lwc:else>
<lightning-layout-item size="12" padding="horizontal-small">
<div class="slds-var-p-around_medium slds-text-align_center" style="background-color: #D8E6FE; color: #0B5CAB">
<p>We are working on it! =)</p>
</div>
</lightning-layout-item>
</lightning-layout>
</template>
</template>
58 changes: 58 additions & 0 deletions force-app/main/default/lwc/choosePayment/choosePayment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { LightningElement, api } from 'lwc';
import getExpirationDays from '@salesforce/apex/AdyenOOBOController.getExpiryDuration';
import getAccountNameAndEmail from '@salesforce/apex/AdyenOOBOController.getAccountEmailAndName';
import { PAYMENT_MODES } from 'c/payByLinkUtils';

export default class ChoosePayment extends LightningElement {
pblSelected = true;
expirationDays;
error;
isLoading;
@api accountId;
@api shopperEmail;
@api shopperName;
@api paymentMode;

get pblButtonVariant() {
return this.pblSelected ? "brand" : "neutral";
}

get cardButtonVariant() {
return this.pblSelected ? "neutral" : "brand";
}

async connectedCallback() {
this.isLoading = true;
this.handlePblButtonClick(); // initializing values
try {
await Promise.all([
this.fetchExpirationDays(),
this.fetchShopperInfo(),
]);
} catch (error) {
this.error = error;
} finally {
this.isLoading = false;
}
}

async fetchExpirationDays() {
this.expirationDays = await getExpirationDays();
}

async fetchShopperInfo() {
const shopperInfo = await getAccountNameAndEmail({ accountId: this.accountId });
this.shopperName = shopperInfo.name;
this.shopperEmail = shopperInfo.email;
}

handlePblButtonClick () {
this.pblSelected = true;
this.paymentMode = PAYMENT_MODES.PBL;
}

handleCardButtonClick () {
this.pblSelected = false;
this.paymentMode = PAYMENT_MODES.CARD;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<description>Choose Payment</description>
<isExposed>true</isExposed>
<targets>
<target>lightning__FlowScreen</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__FlowScreen">
<property name="accountId" type="String" label="Account Id" />
<property name="shopperName" type="String" label="Shopper Name" />
<property name="shopperEmail" type="String" label="Shopper Email" />
<property name="paymentMode" type="String" label="Payment Mode" />
</targetConfig>
</targetConfigs>
<masterLabel>Choose Payment</masterLabel>
</LightningComponentBundle>
28 changes: 28 additions & 0 deletions force-app/main/default/lwc/errorPanel/errorPanel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { LightningElement, api } from 'lwc';
import { reduceErrors } from 'c/ldsUtils';
import noDataIllustration from './templates/noDataIllustration.html';
import inlineMessage from './templates/inlineMessage.html';

export default class ErrorPanel extends LightningElement {
viewDetails = false;

/** Single or array of LDS errors */
@api errors;
/** Generic / user-friendly message */
@api friendlyMessage = 'An error has occurred.';
/** Type of error message **/
@api type;

get errorMessages() {
return reduceErrors(this.errors);
}

handleShowDetailsClick() {
this.viewDetails = !this.viewDetails;
}

render() {
if (this.type === 'inlineMessage') return inlineMessage;
return noDataIllustration;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<description>Error Panel</description>
<isExposed>false</isExposed>
<masterLabel>Error Panel</masterLabel>
</LightningComponentBundle>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<div class="slds-var-m-vertical_small">
<span class="slds-text-color_destructive">
{friendlyMessage}.
<template if:true={errorMessages.length}>
<a onclick={handleShowDetailsClick}> Show details.</a>
</template>
</span>
<template if:true={errorMessages.length}>
<template if:true={viewDetails}>
<template for:each={errorMessages} for:item="message">
<p class="slds-text-body_regular" key={message}>
{message}
</p>
</template>
</template>
</template>
</div>
</template>
Loading