Skip to content

Commit

Permalink
Merge pull request #8 from maze-consulting/feature/KSCU-44-ID-user-fr…
Browse files Browse the repository at this point in the history
…om-login-state

KSCU-44: refactor to get ID off SFCC Profile out of cached controllers, SFRA and SiteGen
  • Loading branch information
aidrian-maze committed Mar 30, 2023
2 parents 734f662 + cb7bb7c commit 7eb6e42
Show file tree
Hide file tree
Showing 12 changed files with 1,323 additions and 105 deletions.
504 changes: 504 additions & 0 deletions _sitegen/controllers/Account.js

Large diffs are not rendered by default.

118 changes: 118 additions & 0 deletions _sitegen/controllers/COCustomer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
'use strict';

/**
* Controller for the first step of the cart checkout process, which is to ask the customer to login, register, or
* checkout anonymously.
*
* @module controllers/COCustomer
*/

/* API Includes */
var Transaction = require('dw/system/Transaction');
var URLUtils = require('dw/web/URLUtils');

/* Script Modules */
var app = require('~/cartridge/scripts/app');
var guard = require('~/cartridge/scripts/guard');

var Cart = require('~/cartridge/scripts/models/CartModel');
var Content = require('~/cartridge/scripts/models/ContentModel');

/**
* First step of the checkout is to choose the checkout type: returning, guest or create account checkout.
* Prepares the checkout initially: removes all payment instruments from the basket and clears all
* forms used in the checkout process, when the customer enters the checkout. The single steps (shipping, billing etc.)
* may not contain the form clearing, in order to support navigating forth and back in the checkout steps without losing
* already entered form values.
*/
function start() {
var oauthLoginForm = app.getForm('oauthlogin');
app.getForm('singleshipping').clear();
app.getForm('multishipping').clear();
app.getForm('billing').clear();

Transaction.wrap(function () {
Cart.goc().removeAllPaymentInstruments();
});

/* Klaviyo Started Checkout event tracking */
var basketMgr = require('dw/order/BasketMgr');
var klaviyoUtils = require('*/cartridge/scripts/klaviyo/utils');
var startedCheckoutData = require('*/cartridge/scripts/klaviyo/eventData/startedCheckout');
if(dw.system.Site.getCurrent().getCustomPreferenceValue('klaviyo_enabled')){
var exchangeID = klaviyoUtils.getKlaviyoExchangeID();
var dataObj, serviceCallResult, currentBasket;
if (exchangeID) {
currentBasket = basketMgr.getCurrentBasket()
if (currentBasket && currentBasket.getProductLineItems().toArray().length) { //TODO: is there a property for isEmpty on basket object?
dataObj = startedCheckoutData.getData(currentBasket);
serviceCallResult = klaviyoUtils.trackEvent(exchangeID, dataObj, klaviyoUtils.EVENT_NAMES.startedCheckout);
}
}
}
/* END Klaviyo Started Checkout event tracking */


// Direct to first checkout step if already authenticated.
if (customer.authenticated) {
response.redirect(URLUtils.https('COShipping-Start'));
return;
} else {
var loginForm = app.getForm('login');
loginForm.clear();
oauthLoginForm.clear();

// Prepopulate login form field with customer's login name.
if (customer.registered) {
loginForm.setValue('username', customer.profile.credentials.login);
}

var loginAsset = Content.get('myaccount-login');

var pageMeta = require('~/cartridge/scripts/meta');
pageMeta.update(loginAsset);

app.getView({
ContinueURL: URLUtils.https('COCustomer-LoginForm').append('scope', 'checkout')
}).render('checkout/checkoutlogin');
}

}

/**
* Form handler for the login form. Handles the following actions:
* - __login__ - Calls the {@link module:controllers/Login~process|Login controller Process function}. If this returns successfully, calls
* the {@link module:controllers/COShipping~Start|COShipping controller Start function}.
* - __register__ - Calls the {@link module:controllers/Account~StartRegister|Account controller StartRegister function}.
* - __unregistered__ - Calls the {@link module:controllers/COShipping~Start|COShipping controller Start function}.
*/
function showLoginForm() {
var loginForm = app.getForm('login');
session.custom.TargetLocation = URLUtils.https('COShipping-Start').toString();

loginForm.handleAction({
login: function () {
app.getController('Login').LoginForm();
},
register: function () {
response.redirect(URLUtils.https('Account-StartRegister'));
},
unregistered: function () {
response.redirect(URLUtils.https('COShipping-Start'));
}
});
}

/*
* Module exports
*/

/*
* Web exposed methods
*/
/** Selects the type of checkout: returning, guest, or create account. The first step in the checkout process.
* @see module:controllers/COCustomer~start */
exports.Start = guard.ensure(['https'], start);
/** Form handler for the login form.
* @see module:controllers/COCustomer~showLoginForm */
exports.LoginForm = guard.ensure(['https', 'post', 'csrf'], showLoginForm);
138 changes: 138 additions & 0 deletions _sitegen/controllers/COSummary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
'use strict';

/**
* This controller implements the last step of the checkout. A successful handling
* of billing address and payment method selection leads to this controller. It
* provides the customer with a last overview of the basket prior to confirm the
* final order creation.
*
* @module controllers/COSummary
*/

/* API Includes */
var Resource = require('dw/web/Resource');
var Transaction = require('dw/system/Transaction');
var URLUtils = require('dw/web/URLUtils');

/* Script Modules */
var app = require('~/cartridge/scripts/app');
var guard = require('~/cartridge/scripts/guard');

var Cart = app.getModel('Cart');

/**
* Renders the summary page prior to order creation.
* @param {Object} context context object used for the view
*/
function start(context) {
var cart = Cart.get();

// Checks whether all payment methods are still applicable. Recalculates all existing non-gift certificate payment
// instrument totals according to redeemed gift certificates or additional discounts granted through coupon
// redemptions on this page.
var COBilling = app.getController('COBilling');
if (!COBilling.ValidatePayment(cart)) {
COBilling.Start();
return;
} else {
Transaction.wrap(function () {
cart.calculate();
});

Transaction.wrap(function () {
if (!cart.calculatePaymentTransactionTotal()) {
COBilling.Start();
}
});

var pageMeta = require('~/cartridge/scripts/meta');
var viewContext = require('app_storefront_core/cartridge/scripts/common/extend').immutable(context, {
Basket: cart.object
});
pageMeta.update({pageTitle: Resource.msg('summary.meta.pagetitle', 'checkout', 'SiteGenesis Checkout')});
app.getView(viewContext).render('checkout/summary/summary');
}
}

/**
* This function is called when the "Place Order" action is triggered by the
* customer.
*/
function submit() {
// Calls the COPlaceOrder controller that does the place order action and any payment authorization.
// COPlaceOrder returns a JSON object with an order_created key and a boolean value if the order was created successfully.
// If the order creation failed, it returns a JSON object with an error key and a boolean value.
var placeOrderResult = app.getController('COPlaceOrder').Start();
if (placeOrderResult.error) {
start({
PlaceOrderError: placeOrderResult.PlaceOrderError
});
} else if (placeOrderResult.order_created) {
showConfirmation(placeOrderResult.Order);
}
}

/**
* Renders the order confirmation page after successful order
* creation. If a nonregistered customer has checked out, the confirmation page
* provides a "Create Account" form. This function handles the
* account creation.
*/
function showConfirmation(order) {
if (!customer.authenticated) {
// Initializes the account creation form for guest checkouts by populating the first and last name with the
// used billing address.
var customerForm = app.getForm('profile.customer');
customerForm.setValue('firstname', order.billingAddress.firstName);
customerForm.setValue('lastname', order.billingAddress.lastName);
customerForm.setValue('email', order.customerEmail);
customerForm.setValue('orderNo', order.orderNo);
customerForm.setValue('orderUUID', order.getUUID());
}

/* Klaviyo Order Confirmation event tracking */
//var OrderMgr = require('dw/order/OrderMgr');
var klaviyoUtils = require('*/cartridge/scripts/klaviyo/utils');
var orderConfirmationData = require('*/cartridge/scripts/klaviyo/eventData/orderConfirmation');
if(dw.system.Site.getCurrent().getCustomPreferenceValue('klaviyo_enabled')){
var exchangeID = klaviyoUtils.getKlaviyoExchangeID();
var dataObj, serviceCallResult; //, currentOrder;
if (exchangeID && order) {
// check to see if the status is new or created
if (order.status == dw.order.Order.ORDER_STATUS_NEW || order.status == dw.order.Order.ORDER_STATUS_OPEN) {
dataObj = orderConfirmationData.getData(order, exchangeID);
serviceCallResult = klaviyoUtils.trackEvent(exchangeID, dataObj, klaviyoUtils.EVENT_NAMES.orderConfirmation);
}

}
}
/* ENDKlaviyo Order Confirmation event tracking */


app.getForm('profile.login.passwordconfirm').clear();
app.getForm('profile.login.password').clear();

var pageMeta = require('~/cartridge/scripts/meta');
pageMeta.update({pageTitle: Resource.msg('confirmation.meta.pagetitle', 'checkout', 'SiteGenesis Checkout Confirmation')});
app.getView({
Order: order,
ContinueURL: URLUtils.https('Account-RegistrationForm') // needed by registration form after anonymous checkouts
}).render('checkout/confirmation/confirmation');
}

/*
* Module exports
*/

/*
* Web exposed methods
*/
/** @see module:controllers/COSummary~Start */
exports.Start = guard.ensure(['https'], start);
/** @see module:controllers/COSummary~Submit */
exports.Submit = guard.ensure(['https', 'post', 'csrf'], submit);

/*
* Local method
*/
exports.ShowConfirmation = showConfirmation;
Loading

0 comments on commit 7eb6e42

Please sign in to comment.