import { CartBaseController } from "./cart_base_controller"; export default class extends CartBaseController { static targets = ["methods", "rates", "form"]; connect() { this.formTarget.addEventListener("formdata", (event) => this.processShippingAddress(event.formData) ); } async rates(event) { event.preventDefault(); event.stopPropagation(); if (!this.formTarget.checkValidity()) { this.adressTarget.classList.add("was-validated"); return; } this.formTarget.classList.remove("was-validated"); // FormDataEvent es muy reciente if (window.FormDataEvent) { // Esto lanza el evento formdata en el formulario new FormData(event.target); } else { // Fallback this.processShippingAddress(new FormData(event.target)); } } payment(event) { event.preventDefault(); event.stopPropagation(); // FormDataEvent es muy reciente if (window.FormDataEvent) { // Esto lanza el evento formdata en el formulario new FormData(event.target); } else { this.processShippingRate(new FormData(event.target)); } } async processShippingAddress(formData) { this.formDisabled = true; const email = this.email; const orderToken = this.token; const ship_address_attributes = this.formDataToObject(formData); const bill_address_attributes = ship_address_attributes; const response = await this.spree.checkout.orderUpdate( { orderToken }, { order: { email, ship_address_attributes, bill_address_attributes } } ); if (response.isFail()) { this.handleFailure(response); this.formDisabled = false; return; } const shippingMethods = await this.shippingMethods(orderToken); if (!shippingMethods) { this.formDisabled = false; return; } const shipping_rates = shippingMethods.included.filter( (x) => x.type == "shipping_rate" ); // XXX: No hay varios paquetes const shipping_method = shippingMethods.data[0]; const site = window.site; await this.render({ shipping_method, shipping_rates, site }); const nextStep = document.querySelector( `#${this.element.dataset.scrollTo}` ); if (nextStep) nextStep.scrollIntoView(); } async processShippingRate(formData) { const rate = this.formDataToObject(formData); const orderToken = this.token; // XXX: Deshabilitar el formulario después del evento FormData, de // lo contrario el objeto queda vacío. this.ratesTarget.elements.forEach((x) => (x.disabled = true)); const response = await window.spree.checkout.orderUpdate( { orderToken }, { order: { shipments_attributes: [{ ...rate }] } } ); if (response.isFail()) { this.handleFailure(response); return; } this.cart = response; // Continue to next step try { Turbolinks.visit(this.data.get("next")); } catch { window.location = this.data.get("next"); } } async render(data = {}) { const template = window.templates[this.data.get("template")]; this.methodsTarget.innerHTML = await this.engine.parseAndRender( template, data ); this.ratesTarget.addEventListener("formdata", (event) => this.processShippingRate(event.formData) ); } }