function idmGetGrossNetPrices({priceNode, name}){ return { gross: { value: priceNode?.getAttribute(`${name}`) !== null ? +priceNode?.getAttribute(`${name}`) : undefined, formatted: priceNode?.getAttribute(`${name}_formatted`), }, net: { value: priceNode?.getAttribute(`${name}_net`) !== null ? +priceNode?.getAttribute(`${name}_net`) : undefined, formatted: priceNode?.getAttribute(`${name}_net_formatted`), } } } function idmGetPriceFromNode(priceNode){ const priceObj = { price: { gross: { value: priceNode?.getAttribute("value") !== null ? +priceNode.getAttribute("value") : undefined, formatted: priceNode?.getAttribute("price_formatted"), }, net: { value: priceNode?.getAttribute("price_net") !== null ? +priceNode.getAttribute("price_net") : undefined, formatted: priceNode?.getAttribute("price_net_formatted"), } }, rebateCodeActive: priceNode?.getAttribute("rebate_code_active") === "y" ? true : false, omnibusPrice: { ...idmGetGrossNetPrices({priceNode, name: "omnibus_price"}) }, // depositPrice: {}, // depositPriceUnit: {}, // totalDepositPrice: {}, // totalDepositPriceUnit: {}, omnibusPriceDetails: { // unit: {}, youSave: { ...idmGetGrossNetPrices({priceNode, name: "omnibus_yousave"}) }, youSavePercent: priceNode?.getAttribute("price_net") !== null ? +priceNode.getAttribute("omnibus_yousave_percent") : undefined, omnibusPriceIsHigherThanSellingPrice: priceNode?.getAttribute("omnibus_price_is_higher_than_selling_price") === "true" ? true : false, // newPriceEffectiveUntil: {}, }, tax: { // worth: {}, vatPercent: priceNode?.getAttribute("tax") !== null ? +priceNode.getAttribute("tax") : undefined, // vatString: "" }, beforeRebate: { ...idmGetGrossNetPrices({priceNode, name: "beforerebate"}) }, // beforeRebateDetails: { // youSave: { // }, // youSavePercent: "", // unit: {} // }, // crossedPrice: {}, youSave: { ...idmGetGrossNetPrices({priceNode, name: "yousave"}) }, youSavePercent: priceNode?.getAttribute("yousave_percent") !== null ? +priceNode.getAttribute("yousave_percent") : undefined, // unit: {}, max: { ...idmGetGrossNetPrices({priceNode, name: "maxprice"}) }, // maxPriceUnit: {}, // suggested: {}, unitConvertedPrice: { ...idmGetGrossNetPrices({priceNode, name: "unit_converted_price"}) }, // rebateNumber: {}, lastPriceChangeDate: priceNode?.getAttribute("last_price_change_date"), // advancePrice: {}, promotionDuration: { promotionTill: { date: { date: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[2], month: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[1], year: priceNode?.getAttribute("last_price_change_date")?.split("-")?.[0], // weekDay: "", // formatted: "" }, time: { hour: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[0], minutes: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[1], seconds: priceNode?.getAttribute("promotiontillhour")?.split(":")?.[2], }, // timestamp: "" }, // discountTill: {}, // distinguishedTill: {}, // specialTill: {}, }, // subscriptionPrice: {}, }; return priceObj; } function idmGetTraitsFromNode(node){ const awardedParameters = []; node.querySelectorAll(":scope > trait").forEach(trait=>{ const currParameter = awardedParameters.find(param=>param.id === trait.getAttribute("groupid")) || { id: trait.getAttribute("groupid"), name: trait.getAttribute("groupdescription"), // description: "", values: [], // contextValue: "", // search: { // icon: "", // }, } currParameter.values.push({ id: trait.getAttribute("traitid"), name: trait.getAttribute("traitid"), link: trait.getAttribute("link"), // description: "", // search: { // icon: "" // } }) if(currParameter.values.length === 1) awardedParameters.push(currParameter); }); return awardedParameters; } async function idmGetGraphQLData(link){ try{ const res = await fetch(`${link}${link.includes("?") ? "&getProductXML=t" : "?getProductXML=t"}`); const str = await res.text(); const xml = new window.DOMParser().parseFromString(str, "text/xml"); const now = new Date(); const allProducts = xml.querySelectorAll("product"); if(allProducts.length === 0) throw new Error("Nie znaleziono produktów"); const data = []; allProducts.forEach(prod=>{ // NODES const priceNode = prod.querySelector(":scope >price"); const firmNode = prod.querySelector(":scope > firm"); const categoryNode = prod.querySelector(":scope > category"); const seriesNode = prod.querySelector(":scope > series"); const commentsNode = prod.querySelector(":scope > comments"); const sizesNode = prod.querySelector(":scope > sizes"); const versionsNode = prod.querySelector(":scope > versions"); // STREFY const zones = []; if(prod.getAttribute("promo") === "yes") zones.push("promotion"); if(prod.getAttribute("discount") === "yes") zones.push("discount"); if(prod.getAttribute("distinguished") === "yes") zones.push("distinguished"); if(prod.getAttribute("special") === "yes") zones.push("special"); if(prod.getAttribute("new") === "yes") zones.push("new"); if(prod.getAttribute("bestseller") === "yes") zones.push("bestseller"); if(prod.getAttribute("subscription") === "yes") zones.push("subscription"); // ZDJĘCIA const enclosuresImages = []; prod.querySelectorAll(":scope > enclosures > images > enclosure").forEach(img=>{ enclosuresImages.push({ position: img.getAttribute("position"), type: img.getAttribute("type"), typeSecond: img.getAttribute("type_second"), url: img.getAttribute("url"), urlSecond: img.getAttribute("url_second"), width: img.getAttribute("width"), height: img.getAttribute("height"), iconUrl: img.getAttribute("icon"), iconUrlSecond: img.getAttribute("icon_second"), iconWidth: img.getAttribute("icon_width"), iconHeight: img.getAttribute("icon_height"), mediumUrl: img.getAttribute("medium"), mediumUrlSecond: img.getAttribute("medium_second"), mediumWidth: img.getAttribute("medium_width"), mediumHeight: img.getAttribute("medium_height"), }) }) // SIZES const sizes = []; sizesNode.querySelectorAll(":scope > size").forEach(size=>{ const availabilityNode = size.querySelector(":scope > availability"); const shippingTimeNode = availabilityNode.querySelector(":scope > shipping_time"); const sizePriceNode = size.querySelector(":scope > price"); const weightNode = size.querySelector(":scope > weight"); sizes.push({ id: size?.getAttribute("type"), name: size?.getAttribute("name"), code: size?.getAttribute("code"), codeProducer: size?.getAttribute("code_producer"), codeExtern: size?.getAttribute("code_extern"), amount: size?.getAttribute("amount") !== null ? +size.getAttribute("amount") : undefined, amount_mo: size?.getAttribute("amount_mo") !== null ? +size.getAttribute("amount_mo") : undefined, amount_mw: size?.getAttribute("amount_mw") !== null ? +size.getAttribute("amount_mw") : undefined, amount_mp: size?.getAttribute("amount_mp") !== null ? +size.getAttribute("amount_mp") : undefined, weight: weightNode?.getAttribute("g") !== null ? +weightNode.getAttribute("g") : undefined, availability: { visible: availabilityNode?.getAttribute("visible") === "y" ? true : false, description: availabilityNode?.getAttribute("status_description"), status: availabilityNode?.getAttribute("status"), icon: availabilityNode?.getAttribute("status_gfx"), deliveryDate: shippingTimeNode?.getAttribute("today") === "true" ? `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate().toString().padStart(2, 0)}` : availabilityNode?.getAttribute("delivery_date"), minimumStockOfProduct: availabilityNode?.getAttribute("minimum_stock_of_product"), // descriptionTel: "", // iconTel: "", }, shipping: { today: shippingTimeNode?.getAttribute("today") === "true" ? true : false, }, price: idmGetPriceFromNode(sizePriceNode), // amountWholesale: "", }) }) // VERSIONS const versions = []; versionsNode.querySelectorAll(":scope > version").forEach(ver=>{ versions.push({ id: ver?.getAttribute("id") !== null ? +ver?.getAttribute("id") : undefined, name: ver?.getAttribute("name"), icon: ver?.getAttribute("gfx"), iconSecond: ver?.getAttribute("gfx_second"), iconSmall: ver?.getAttribute("gfx_small"), iconSmallSecond: ver?.getAttribute("gfx_small_second"), productIcon: ver?.getAttribute("icon"), productIconSecond: ver?.getAttribute("icon_second"), productIconSmall: ver?.getAttribute("icon_small"), productIconSmallSecond: ver?.getAttribute("icon_small_second"), link: ver?.getAttribute("link"), // parameterValues: [], }); }); // DATA const typeParts = prod.getAttribute("product_type")?.split("_"); data.push({ id: prod?.getAttribute("id") !== null ? +prod?.getAttribute("id") : undefined, type: typeParts[1] === "item" ? typeParts[0] : typeParts[1], code: prod?.getAttribute("code"), name: prod.querySelector(":scope > name")?.textContent, versionName: prod.querySelector(":scope > versions")?.getAttribute("name"), description: prod.querySelector(":scope > description")?.textContent, // longDescription: prod.querySelector("vlongdescription")?.textContent, // longDescriptionSections: "", link: prod?.getAttribute("link"), zones, icon: prod.querySelector(":scope > icon")?.textContent, iconSecond: prod.querySelector(":scope > icon_second")?.textContent, iconSmall: prod.querySelector(":scope > icon_small")?.textContent, iconSmallSecond: prod.querySelector(":scope > icon_small_second")?.textContent, price: idmGetPriceFromNode(priceNode), unit: { id: sizesNode?.getAttribute("unit_id"), // name: "", singular: sizesNode?.getAttribute("unit_single"), plural: sizesNode?.getAttribute("unit_plural"), fraction: sizesNode?.getAttribute("unit_fraction"), sellBy: sizesNode?.getAttribute("unit_sellby") !== null ? +sizesNode?.getAttribute("unit_sellby") : undefined, precision: sizesNode?.getAttribute("unit_precision") !== null ? +sizesNode?.getAttribute("unit_precision") : undefined, unitConvertedFormat: sizesNode?.getAttribute("unit_converted_format"), }, producer: { id: firmNode?.getAttribute("id") !== null ? +firmNode?.getAttribute("id") : undefined, name: firmNode?.getAttribute("name"), link: firmNode?.getAttribute("productslink"), searchIcons: { icon: firmNode?.getAttribute("icon"), }, // projectorIcons: {}, }, category: { id: categoryNode?.getAttribute("id") !== null ? +categoryNode?.getAttribute("id") : undefined, name: categoryNode?.getAttribute("name"), link: categoryNode?.getAttribute("productslink") }, group: { id: versionsNode?.getAttribute("id") !== null ? +versionsNode?.getAttribute("id") : undefined, name: versionsNode?.getAttribute("name"), displayAll: versionsNode?.getAttribute("display_all") === "true" ? true : false, link: versionsNode?.getAttribute("link"), versions, groupParameters: idmGetTraitsFromNode(versionsNode.querySelector(":scope > groupParameters")) }, opinion: { rating: commentsNode?.getAttribute("avg") !== null ? +commentsNode?.getAttribute("avg") : undefined, count: commentsNode?.getAttribute("count") !== null ? +commentsNode?.getAttribute("count") : undefined, link: commentsNode?.getAttribute("link") }, enclosuresImages, // enclosuresAttachments: [], series: { id: seriesNode?.getAttribute("id") !== null ? +seriesNode?.getAttribute("id") : undefined, name: seriesNode?.getAttribute("name"), link: seriesNode?.getAttribute("link") }, awardedParameters: idmGetTraitsFromNode(prod.querySelector(":scope > traits")), // parameteresWithContext: [], sizes, points: priceNode?.getAttribute("points") !== null ? +priceNode?.getAttribute("points") : undefined, pointsReceive: priceNode?.getAttribute("points_recive") !== null ? +priceNode?.getAttribute("points_recive") : undefined, // subscription: {}, // bundled: [], // responsibleEntity: {}, }) }) return data; }catch(err){ console.error(err); return null; } } // const testData = await idmGetGraphQLData("/pl/menu/perfumy/perfumy-meskie-944.html"); // console.log(testData);