woocommerce-paypal-payments/modules/ppcp-button/resources/js/modules/ActionHandler/SingleProductActionHandler.js

229 lines
7.7 KiB
JavaScript

import Product from '../Entity/Product';
import BookingProduct from "../Entity/BookingProduct";
import onApprove from '../OnApproveHandler/onApproveForContinue';
import {payerData} from "../Helper/PayerData";
import {PaymentMethods} from "../Helper/CheckoutMethodState";
import CartHelper from "../Helper/CartHelper";
import FormHelper from "../Helper/FormHelper";
class SingleProductActionHandler {
constructor(
config,
updateCart,
formElement,
errorHandler
) {
this.config = config;
this.updateCart = updateCart;
this.formElement = formElement;
this.errorHandler = errorHandler;
this.cartHelper = null;
}
subscriptionsConfiguration(subscription_plan) {
return {
createSubscription: (data, actions) => {
return actions.subscription.create({
'plan_id': subscription_plan
});
},
onApprove: (data, actions) => {
fetch(this.config.ajax.approve_subscription.endpoint, {
method: 'POST',
credentials: 'same-origin',
body: JSON.stringify({
nonce: this.config.ajax.approve_subscription.nonce,
order_id: data.orderID,
subscription_id: data.subscriptionID
})
}).then((res)=>{
return res.json();
}).then(() => {
const products = this.getSubscriptionProducts();
fetch(this.config.ajax.change_cart.endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'same-origin',
body: JSON.stringify({
nonce: this.config.ajax.change_cart.nonce,
products,
})
}).then((result) => {
return result.json();
}).then((result) => {
if (!result.success) {
console.log(result)
throw Error(result.data.message);
}
location.href = this.config.redirect;
})
});
},
onError: (err) => {
console.error(err);
}
}
}
getSubscriptionProducts()
{
const id = document.querySelector('[name="add-to-cart"]').value;
return [new Product(id, 1, this.variations(), this.extraFields())];
}
configuration()
{
return {
createOrder: this.createOrder(),
onApprove: onApprove(this, this.errorHandler),
onError: (error) => {
this.refreshMiniCart();
if (this.isBookingProduct() && error.message) {
this.errorHandler.clear();
this.errorHandler.message(error.message);
return;
}
this.errorHandler.genericError();
},
onCancel: () => {
// Could be used for every product type,
// but only clean the cart for Booking products for now.
if (this.isBookingProduct()) {
this.cleanCart();
} else {
this.refreshMiniCart();
}
}
}
}
getProducts()
{
if ( this.isBookingProduct() ) {
const id = document.querySelector('[name="add-to-cart"]').value;
return [new BookingProduct(id, 1, FormHelper.getPrefixedFields(this.formElement, "wc_bookings_field"), this.extraFields())];
} else if ( this.isGroupedProduct() ) {
const products = [];
this.formElement.querySelectorAll('input[type="number"]').forEach((element) => {
if (! element.value) {
return;
}
const elementName = element.getAttribute('name').match(/quantity\[([\d]*)\]/);
if (elementName.length !== 2) {
return;
}
const id = parseInt(elementName[1]);
const quantity = parseInt(element.value);
products.push(new Product(id, quantity, null, this.extraFields()));
})
return products;
} else {
const id = document.querySelector('[name="add-to-cart"]').value;
const qty = document.querySelector('[name="quantity"]').value;
const variations = this.variations();
return [new Product(id, qty, variations, this.extraFields())];
}
}
extraFields() {
return FormHelper.getFilteredFields(
this.formElement,
['add-to-cart', 'quantity', 'product_id', 'variation_id'],
['attribute_', 'wc_bookings_field']
);
}
createOrder()
{
this.cartHelper = null;
return (data, actions, options = {}) => {
this.errorHandler.clear();
const onResolve = (purchase_units) => {
this.cartHelper = (new CartHelper()).addFromPurchaseUnits(purchase_units);
const payer = payerData();
const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?
this.config.bn_codes[this.config.context] : '';
return fetch(this.config.ajax.create_order.endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'same-origin',
body: JSON.stringify({
nonce: this.config.ajax.create_order.nonce,
purchase_units,
payer,
bn_code:bnCode,
payment_method: PaymentMethods.PAYPAL,
funding_source: window.ppcpFundingSource,
context:this.config.context
})
}).then(function (res) {
return res.json();
}).then(function (data) {
if (!data.success) {
console.error(data);
throw Error(data.data.message);
}
return data.data.id;
});
};
return this.updateCart.update(onResolve, this.getProducts(), options.updateCartOptions || {});
};
}
variations()
{
if (! this.hasVariations()) {
return null;
}
return [...this.formElement.querySelectorAll("[name^='attribute_']")].map(
(element) => {
return {
value:element.value,
name:element.name
}
}
);
}
hasVariations()
{
return this.formElement.classList.contains('variations_form');
}
isGroupedProduct()
{
return this.formElement.classList.contains('grouped_form');
}
isBookingProduct()
{
// detection for "woocommerce-bookings" plugin
return !!this.formElement.querySelector('.wc-booking-product-id');
}
cleanCart() {
this.cartHelper.removeFromCart().then(() => {
this.refreshMiniCart();
}).catch(error => {
this.refreshMiniCart();
});
}
refreshMiniCart() {
jQuery(document.body).trigger('wc_fragment_refresh');
}
}
export default SingleProductActionHandler;