import { CheckoutService } from '../../services/checkout.service';
import template from './checkout-finalize-order.component.html';
import type { Localized } from '../../types';
declare const localized: Localized;
export const CheckoutFinalizeOrder: ng.IComponentOptions = {
bindings: {
acceptedPaymentTypes: '<',
billingAddress: '<',
extraFields: '<',
shippingAddress: '<',
order: '<',
selectedShippingMethod: '<',
isReadyToConfirm: '<',
isShippingSameAsBilling: '<',
},
controller: FinalizeOrderController,
require: {
checkoutCtrl: '^vfCheckout',
},
template,
};
FinalizeOrderController.$inject = ['Alerts', 'Checkout', 'Utils'];
function FinalizeOrderController(Alerts, Checkout: CheckoutService, Utils) {
const vm = this;
this.warningIcon = `${localized.dir.url}public/images/warning.svg`;
vm.$onInit = $onInit;
vm.isPopoversInit = false;
vm.confirmOrder = confirmOrder;
vm.isOrderConfirmed = false;
/**
* @function initPopover
*/
vm.initPopover = () => {
const el = jQuery('.prop65-popover');
if (!vm.isPopoversInit) {
el.popover({
trigger: 'hover focus',
html: true,
title: 'WARNING: ',
});
vm.isPopoversInit = true;
}
};
/**
*/
function $onInit() {
vm.pageUrls = {
cart: Utils.getPageUrl('cart'),
catalog: Utils.getPageUrl('catalog'),
};
vm.productSlug = localized.settings.general.product_slug || 'products';
checkPaymentGateways(vm.acceptedPaymentTypes);
const el = jQuery('a#checkout-review-tab');
el.on('shown.bs.tab', function () {
if (vm.isReadyToConfirm) {
confirmOrder();
}
});
}
vm.$onChanges = function (changes) {
if (changes.order && changes.order.currentValue) {
vm.returnUrl = `https://${window.location.hostname}/cc-return/?OrderID=${vm.order.order_id}`;
}
};
/**
* @param {Object} gateways Payment gateways
*/
function checkPaymentGateways(gateways) {
if (
!gateways.payfabric &&
!gateways.stripe &&
!gateways.squareup &&
!gateways.qualpay &&
!gateways.authnet &&
!gateways.paypal_checkout &&
!gateways.credit_line
) {
Alerts.warning('No Active Payment Gateways.');
}
}
/**
* @function confirmOrder
*/
function confirmOrder() {
enableNavWarning();
const params = {
selected_shipping_profile: {
shipping_id: vm.shippingAddress.shipping_id || 0,
},
selected_billing_profile: {
billing_id: vm.billingAddress?.billing_id || 0,
},
order: vm.order,
selected_shipping_method: vm.selectedShippingMethod,
shipping_first_name: vm.shippingAddress.first_name,
shipping_last_name: vm.shippingAddress.last_name,
shipping_email: vm.shippingAddress.email,
shipping_address1: vm.shippingAddress.address1,
shipping_address2: vm.shippingAddress.address2,
shipping_city: vm.shippingAddress.city,
shipping_state: vm.shippingAddress.state.id,
shipping_zip: vm.shippingAddress.zip,
shipping_phone: vm.shippingAddress.phone,
billing_first_name: vm.isShippingSameAsBilling
? vm.shippingAddress.first_name
: vm.billingAddress.first_name,
billing_last_name: vm.isShippingSameAsBilling
? vm.shippingAddress.last_name
: vm.billingAddress.last_name,
billing_email: vm.isShippingSameAsBilling
? vm.shippingAddress.email
: vm.billingAddress.email,
billing_address1: vm.isShippingSameAsBilling
? vm.shippingAddress.address1
: vm.billingAddress.address1,
billing_address2: vm.isShippingSameAsBilling
? vm.shippingAddress.address2
: vm.billingAddress.address2,
billing_city: vm.isShippingSameAsBilling
? vm.shippingAddress.city
: vm.billingAddress.city,
billing_state: vm.isShippingSameAsBilling
? vm.shippingAddress.state.id
: vm.billingAddress.state.id,
billing_zip: vm.isShippingSameAsBilling
? vm.shippingAddress.zip
: vm.billingAddress.zip,
billing_phone: vm.isShippingSameAsBilling
? vm.shippingAddress.phone
: vm.billingAddress.phone,
return_url: vm.returnUrl,
extraFields: getExtraFields(vm.checkoutCtrl.extraFields),
};
vm.isOrderConfirmed = false;
vm.confirmedOrder = {};
Checkout.confirmOrder(params)
.then((response) => response.data)
.then((data: any) => {
vm.confirmedOrder = data.order;
vm.priceAvailability = data.priceAvailability;
// If priceAvailability is returned, start the PA process before finishing confirmation, otherwise finish the confirmation
if (!vm.priceAvailability) {
finishConfirmation(data);
}
});
}
this.completePriceAvailability = (data: any) => {
const priceAvailabilityResponse = data;
const order = {
order: {
order_id: vm.order.order_id,
},
return_url: vm.returnUrl,
};
const reconfirm = true;
Checkout.priceAvailabilityResponse(
order,
priceAvailabilityResponse,
reconfirm
).then((response: any) => {
if (!response.data.errors.length) {
vm.confirmedOrder = response.data.order;
finishConfirmation(response.data);
}
});
};
/**
* @param {Object} data Data returned from confirmOrder
*/
function finishConfirmation(data) {
vm.setHasAdditionShipping(vm.confirmedOrder.items);
vm.confirmedItems = getConfirmedItems(vm.confirmedOrder.items);
vm.extraFields = processExtraFields(data.order);
vm.payfabricUrl = data.payfabric_url;
vm.isOrderConfirmed = true;
vm.paypalCreateOrder = data.paypal_create_order || null;
vm.qualpay = {
transientKey: data.qualpay_transient_key || null,
merchantId: data.qualpay_merchant_id || null,
};
}
/**
* @param {Object} extraFields Additional or Custom Checkout fields
* @return {Object} Fields with only values
*/
function getExtraFields(extraFields) {
return Object.fromEntries(
Object.entries(extraFields).map((element: any) => {
element[1] = element[1].value;
return element;
})
);
}
/**
* @param {Object} order Order data returned from confirmOrder
* @return {Array} Keyed array containing any extra fields with values.
*/
function processExtraFields(order) {
const fields = [];
const tempFields = {
Organization: order.organization,
'P.O. Number': order.rr_po_num,
'Issuing Office': order.issuing_office,
'Cost Center Code': order.cost_center_code,
Attention: order.attention,
Notes: order.notes,
};
Object.entries(tempFields).forEach((element) => {
const [key, value] = element;
if (value && value !== '') {
fields.push({
key,
value,
});
}
});
for (let i = 1; i < 7; i++) {
if (order[`f${i}_value`]) {
fields.push({
key: order[`f${i}_name`],
value: order[`f${i}_value`],
});
}
}
return fields;
}
/**
* Prevents the user from navigating away from the page without a warning.
*/
function enableNavWarning() {
window.onbeforeunload = function (e) {
e.preventDefault();
e.returnValue = '';
};
}
/**
* @param {Object} oldItems Products.
* @return {Array} Confirmed items.
*/
function getConfirmedItems(oldItems) {
return Object.values(oldItems).map((item: any) => {
if (item.prop65) {
item.prop65.warning = getProp65Warning(item.prop65.warning);
}
return item;
});
}
/**
* @param {string} warning Original warning message.
* @return {string} Formatted warning.
*/
function getProp65Warning(warning) {
warning = warning.replace(/(^warning:)/gi, '').trim(); // Strip 'Warning' since Cal law needs it bold.
warning = warning.replace(
/(www.p65warnings.ca.gov)/gi,
'$&'
);
return warning;
}
this.setHasAdditionShipping = (
items: { additional_shipping: boolean }[]
) => {
this.hasAdditionalShipping = Object.values(items).some(
(item) => item.additional_shipping
);
};
}