Skip to content

Instantly share code, notes, and snippets.

@matiaslopezd
Last active February 14, 2020 01:05
Show Gist options
  • Save matiaslopezd/24f3e04d5ae7ea2bdcd8858918aed57d to your computer and use it in GitHub Desktop.
Save matiaslopezd/24f3e04d5ae7ea2bdcd8858918aed57d to your computer and use it in GitHub Desktop.
Quotation script for atm.cl
const BigLoader = {
create: () => {
const loader = document.createElement('div');
loader.classList.add('big-loader');
const spinner = document.createElement('div');
spinner.classList.add('spin');
loader.appendChild(spinner);
document.body.appendChild(loader);
},
toggle: (x = document.querySelector('.big-loader')) => (x.classList.contains('show')) ? x.classList.remove('show') : x.classList.add('show'),
};
class Quotation {
constructor({ idProduct, quantity, url }, debug){
this.quoted = false;
this.base_url = url || window.top.location.origin;
this.product = idProduct || 0;
this.qty = quantity || 1;
this.body = new FormData();
this.valid = window.top.location.pathname.includes('tienda') || window.top.location.pathname.includes('store');
this.debug = debug;
}
init(key = 'postid') {
this.Debug('log', 'Obteniendo ID del producto');
// Create modal
BigLoader.create();
this.Debug('log', 'Creando big loader');
let id = 0;
this.Debug('log', 'Validando que la URL sea válida: ', this.valid);
if (this.valid) {
this.Debug('log', 'La URL es válida');
// Add link to buttons
this.addQuoteLink();
this.addQuoteCartLink();
// Get the classes of body that contain product id
const ListClasses = document.querySelector('body').classList;
this.Debug('log', 'Buscando ID del producto');
if (this.debug) console.group('Clases evaluadas');
// Set the ProductID
ListClasses.forEach(node => {
if (node.includes(key)) id = node.split('-')[1];
this.Debug('log', 'Clase ', node, ' incluye ', key, ' ?: ', node.includes(key));
});
if (this.debug) console.groupEnd('Clases evaluadas');
}
this.Debug('log', 'El ID del producto es ', id);
this.product = Math.floor(id);
this.checkIsQuoted();
if (this.quoted) this.toggleButtons({ result: 'exists' });
}
getBody() {
this.Debug('log', 'Gerenado body de la petición');
// Create the form
let payload = {
quantity: this.qty,
context: 'frontend',
action: 'yith_ywraq_action',
ywraq_action: 'add_item',
product_id: this.product,
"yith-add-to-cart": this.product,
};
// Append key and value to form data
Object.keys(payload).map(key => this.body.append(key, payload[key]));
this.Debug('log', 'El body de la petición es ', payload);
return this.body;
}
async sendQuote() {
this.Debug('log', 'Enviando cotización');
return await fetch(`${this.base_url}?wc-ajax=yith_ywraq_action`, { method: 'POST', body: this.getBody() })
.then(response => {
this.Debug('log', 'La respuesta a la cotización es ', response);
if (response.ok) return response.json();
else throw new Error('Error en la petición POST');
})
.then(data => data)
.catch((error) => {
this.Debug('log', 'Se ha generado un error en la petición');
BigLoader.toggle();
if (this.debug) console.log(error);
alert('Lo sentimos, no se ha podido procesar la cotización, inténtelo más tarde.');
});
}
async quote () {
this.Debug('log', 'Generando cotización');
BigLoader.toggle();
this.Debug('log', 'Ha cambiado el estado de big loader');
if (!this.quoted) this.processResult(await this.sendQuote());
else this.toggleButtons('exists');
}
processResult(data) {
this.Debug('log', 'La respuesta de la petición es', data);
this.toggleButtons(data);
if (this.debug) console.log(data);
}
toggleButtons(data) {
const { result } = data;
if (!this.quoted) BigLoader.toggle();
if (result === 'true') {
this.Debug('log', 'El producto fue añadido con éxito');
document.querySelectorAll('.go-to-quote').forEach(node => node.classList.add('show'));
document.querySelectorAll('.go-to-quote > strong').forEach(node => node.onclick = () => window.location.href = `${this.base_url}/request-quote/`);
this.quoted = true;
}
else if (result === 'exists') {
this.Debug('log', 'El producto ya estaba en la cotización');
document.querySelectorAll('.exist-product').forEach(node => node.classList.add('show'));
document.querySelectorAll('.exist-product > strong').forEach(node => node.onclick = () => window.location.href = `${this.base_url}/request-quote/`);
document.querySelectorAll('.btn-cotizar').forEach(node => node.classList.add('block'));
}
else {
console.error('Something goes wrong with server, check the next log of response');
console.log(data);
}
this.saveInSession(this.product);
}
addQuoteLink() {
this.Debug('log', 'Añadiendo evento click a los botones de cotizar');
const self = this;
const buttons = document.querySelectorAll('.btn-cotizar');
buttons.forEach((node, index) => {
self.Debug('log', 'Se onclick al botón ', index + 1);
node.onclick = function (e) {
e.preventDefault();
self.Debug('log', 'Se hizo click en el botón de cotizar número ', index + 1);
self.quote();
};
node.childNodes[0].removeAttribute('href');
self.Debug('log', 'Se eliminó el atributo href del botón ', index + 1);
});
}
addQuoteCartLink() {
this.Debug('log', 'Añadiendo enlace a carro de cotización en la página');
document.querySelectorAll( ".available-quote" ).forEach( node => {
node.innerHTML = "";
const element = document.createElement( "p" );
element.classList.add("exist-product");
element.innerText = "Producto añadido en el cotizador.";
const link = document.createElement( "strong" );
link.innerText = "Haga clic para ir al cotizador.";
element.appendChild(link);
node.appendChild(element);
});
}
parseQuotedList(list = sessionStorage.getItem('quoted-list')) {
return (!list) ? JSON.parse('[]') : JSON.parse(list);
}
saveInSession(product) {
const array = this.parseQuotedList();
array.push(product);
sessionStorage.setItem('quoted-list', JSON.stringify(array));
}
checkIsQuoted() {
const array = this.parseQuotedList();
this.quoted = array.includes(this.product);
}
Debug(type = 'log', msg = '', ...args) {
if (this.debug) console[type](msg, ...args);
}
};
const BigLoader={create:()=>{const e=document.createElement("div");e.classList.add("big-loader");const t=document.createElement("div");t.classList.add("spin"),e.appendChild(t),document.body.appendChild(e)},toggle:(e=document.querySelector(".big-loader"))=>e.classList.contains("show")?e.classList.remove("show"):e.classList.add("show")};class Quotation{constructor({idProduct:e,quantity:t,url:o},s){this.quoted=!1,this.base_url=o||window.top.location.origin,this.product=e||0,this.qty=t||1,this.body=new FormData,this.valid=window.top.location.pathname.includes("tienda")||window.top.location.pathname.includes("store"),this.debug=s}init(e="postid"){this.Debug("log","Obteniendo ID del producto"),BigLoader.create(),this.Debug("log","Creando big loader");let t=0;if(this.Debug("log","Validando que la URL sea válida: ",this.valid),this.valid){this.Debug("log","La URL es válida"),this.addQuoteLink(),this.addQuoteCartLink();const o=document.querySelector("body").classList;this.Debug("log","Buscando ID del producto"),this.debug&&console.group("Clases evaluadas"),o.forEach(o=>{o.includes(e)&&(t=o.split("-")[1]),this.Debug("log","Clase ",o," incluye ",e," ?: ",o.includes(e))}),this.debug&&console.groupEnd("Clases evaluadas")}this.Debug("log","El ID del producto es ",t),this.product=Math.floor(t),this.checkIsQuoted(),this.quoted&&this.toggleButtons({result:"exists"})}getBody(){this.Debug("log","Gerenado body de la petición");let e={quantity:this.qty,context:"frontend",action:"yith_ywraq_action",ywraq_action:"add_item",product_id:this.product,"yith-add-to-cart":this.product};return Object.keys(e).map(t=>this.body.append(t,e[t])),this.Debug("log","El body de la petición es ",e),this.body}async sendQuote(){return this.Debug("log","Enviando cotización"),await fetch(`${this.base_url}?wc-ajax=yith_ywraq_action`,{method:"POST",body:this.getBody()}).then(e=>{if(this.Debug("log","La respuesta a la cotización es ",e),e.ok)return e.json();throw new Error("Error en la petición POST")}).then(e=>e).catch(e=>{this.Debug("log","Se ha generado un error en la petición"),BigLoader.toggle(),this.debug&&console.log(e),alert("Lo sentimos, no se ha podido procesar la cotización, inténtelo más tarde.")})}async quote(){this.Debug("log","Generando cotización"),BigLoader.toggle(),this.Debug("log","Ha cambiado el estado de big loader"),this.quoted?this.toggleButtons("exists"):this.processResult(await this.sendQuote())}processResult(e){this.Debug("log","La respuesta de la petición es",e),this.toggleButtons(e),this.debug&&console.log(e)}toggleButtons(e){const{result:t}=e;this.quoted||BigLoader.toggle(),"true"===t?(this.Debug("log","El producto fue añadido con éxito"),document.querySelectorAll(".go-to-quote").forEach(e=>e.classList.add("show")),document.querySelectorAll(".go-to-quote > strong").forEach(e=>e.onclick=(()=>window.location.href=`${this.base_url}/request-quote/`)),this.quoted=!0):"exists"===t?(this.Debug("log","El producto ya estaba en la cotización"),document.querySelectorAll(".exist-product").forEach(e=>e.classList.add("show")),document.querySelectorAll(".exist-product > strong").forEach(e=>e.onclick=(()=>window.location.href=`${this.base_url}/request-quote/`)),document.querySelectorAll(".btn-cotizar").forEach(e=>e.classList.add("block"))):(console.error("Something goes wrong with server, check the next log of response"),console.log(e)),this.saveInSession(this.product)}addQuoteLink(){this.Debug("log","Añadiendo evento click a los botones de cotizar");const e=this;document.querySelectorAll(".btn-cotizar").forEach((t,o)=>{e.Debug("log","Se onclick al botón ",o+1),t.onclick=function(t){t.preventDefault(),e.Debug("log","Se hizo click en el botón de cotizar número ",o+1),e.quote()},t.childNodes[0].removeAttribute("href"),e.Debug("log","Se eliminó el atributo href del botón ",o+1)})}addQuoteCartLink(){this.Debug("log","Añadiendo enlace a carro de cotización en la página"),document.querySelectorAll(".available-quote").forEach(e=>{e.innerHTML="";const t=document.createElement("p");t.classList.add("exist-product"),t.innerText="Producto añadido en el cotizador.";const o=document.createElement("strong");o.innerText="Haga clic para ir al cotizador.",t.appendChild(o),e.appendChild(t)})}parseQuotedList(e=sessionStorage.getItem("quoted-list")){return e?JSON.parse(e):JSON.parse("[]")}saveInSession(e){const t=this.parseQuotedList();t.push(e),sessionStorage.setItem("quoted-list",JSON.stringify(t))}checkIsQuoted(){const e=this.parseQuotedList();this.quoted=e.includes(this.product)}Debug(e="log",t="",...o){this.debug&&console[e](t,...o)}}
@matiaslopezd
Copy link
Author

matiaslopezd commented Feb 14, 2020

Script de cotización compatible con Woocommerce

Permitido el uso comercial o personal, mientras se respeten los derechos de autor y referencie a este mismo Gist o perfil de Github.

Requisitos

Se requieren estos dos plugins:

  • Woocommerce
  • Yith Woocommerce Request a Quote Premium

Uso

const quote = new Quotation({ idProduct, quantity, url }, debug);
quote.init();
  • idProduct: Corresponde al id del producto (Opcional)
  • quantity: Corresponde a la cantidad del producto a cotizar (Opcional)
  • url: Corresponde a la URL base donde generar la cotización (Opcional) (Ej. https://mipagina.com)
  • debug: Activar logs de desarrollo (Opcional)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment