corregidos bugs de: ret, vs delivery, efectivo vs link, charsets, price query

This commit is contained in:
Lucas Tettamanti
2026-01-26 23:27:47 -03:00
parent 53293ce9b3
commit 493f26af17
13 changed files with 757 additions and 193 deletions

View File

@@ -72,6 +72,51 @@ function parsePrice(p) {
return Number.isFinite(n) ? n : null;
}
/**
* Decodifica HTML entities comunes (WooCommerce las usa en nombres de productos)
*/
function decodeHtmlEntities(str) {
if (!str || typeof str !== "string") return str;
// Solo procesar si hay entidades
if (!str.includes("&")) return str;
const entities = {
"&amp;": "&", "&lt;": "<", "&gt;": ">", "&quot;": '"', "&#39;": "'", "&apos;": "'",
"&nbsp;": " ", "&iexcl;": "¡", "&cent;": "¢", "&pound;": "£", "&curren;": "¤",
"&yen;": "¥", "&brvbar;": "¦", "&sect;": "§", "&uml;": "¨", "&copy;": "©",
"&ordf;": "ª", "&laquo;": "«", "&not;": "¬", "&shy;": "\u00AD", "&reg;": "®",
"&macr;": "¯", "&deg;": "°", "&plusmn;": "±", "&sup2;": "²", "&sup3;": "³",
"&acute;": "´", "&micro;": "µ", "&para;": "¶", "&middot;": "·", "&cedil;": "¸",
"&sup1;": "¹", "&ordm;": "º", "&raquo;": "»", "&frac14;": "¼", "&frac12;": "½",
"&frac34;": "¾", "&iquest;": "¿", "&Agrave;": "À", "&Aacute;": "Á", "&Acirc;": "Â",
"&Atilde;": "Ã", "&Auml;": "Ä", "&Aring;": "Å", "&AElig;": "Æ", "&Ccedil;": "Ç",
"&Egrave;": "È", "&Eacute;": "É", "&Ecirc;": "Ê", "&Euml;": "Ë", "&Igrave;": "Ì",
"&Iacute;": "Í", "&Icirc;": "Î", "&Iuml;": "Ï", "&ETH;": "Ð", "&Ntilde;": "Ñ",
"&Ograve;": "Ò", "&Oacute;": "Ó", "&Ocirc;": "Ô", "&Otilde;": "Õ", "&Ouml;": "Ö",
"&times;": "×", "&Oslash;": "Ø", "&Ugrave;": "Ù", "&Uacute;": "Ú", "&Ucirc;": "Û",
"&Uuml;": "Ü", "&Yacute;": "Ý", "&THORN;": "Þ", "&szlig;": "ß", "&agrave;": "à",
"&aacute;": "á", "&acirc;": "â", "&atilde;": "ã", "&auml;": "ä", "&aring;": "å",
"&aelig;": "æ", "&ccedil;": "ç", "&egrave;": "è", "&eacute;": "é", "&ecirc;": "ê",
"&euml;": "ë", "&igrave;": "ì", "&iacute;": "í", "&icirc;": "î", "&iuml;": "ï",
"&eth;": "ð", "&ntilde;": "ñ", "&ograve;": "ò", "&oacute;": "ó", "&ocirc;": "ô",
"&otilde;": "õ", "&ouml;": "ö", "&divide;": "÷", "&oslash;": "ø", "&ugrave;": "ù",
"&uacute;": "ú", "&ucirc;": "û", "&uuml;": "ü", "&yacute;": "ý", "&thorn;": "þ",
"&yuml;": "ÿ",
};
let result = str;
// Reemplazar entities nombradas usando iteración (más robusto que regex)
for (const [entity, char] of Object.entries(entities)) {
if (result.includes(entity)) {
result = result.split(entity).join(char);
}
}
// Reemplazar entities numéricas (&#123; o &#x7B;)
result = result.replace(/&#(\d+);/g, (_, num) => String.fromCharCode(parseInt(num, 10)));
result = result.replace(/&#x([0-9a-fA-F]+);/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
return result;
}
function normalizeAttributes(attrs) {
const out = {};
if (!Array.isArray(attrs)) return out;
@@ -90,7 +135,7 @@ function normalizeWooProduct(p) {
woo_id: p?.id,
type: p?.type || "simple",
parent_id: p?.parent_id || null,
name: p?.name || "",
name: decodeHtmlEntities(p?.name || ""),
slug: p?.slug || null,
status: p?.status || null,
catalog_visibility: p?.catalog_visibility || null,
@@ -114,7 +159,7 @@ function snapshotRowToItem(row) {
const raw = row?.raw || {};
return {
woo_product_id: row?.woo_id,
name: row?.name || "",
name: decodeHtmlEntities(row?.name || ""),
sku: raw?.SKU || raw?.sku || row?.slug || null,
slug: row?.slug || null,
price: row?.price_current != null ? Number(row.price_current) : null,