1let lockerMap, 2 lockerCluster, 3 lockerPoints = [], 4 lockerMapLoaded = false; 5 6const fanboxIcon = L.icon({ 7 iconUrl: `/assets/images/fanboxlockericon.png?v=${Date.now()}`, 8 iconSize: [64, 96], 9 iconAnchor: [32, 96], 10 popupAnchor: [0, -96], 11}); 12 13const easyboxIcon = L.icon({ 14 iconUrl: `/assets/images/easyboxlockericon.png?v=${Date.now()}`, 15 iconSize: [62, 80], 16 iconAnchor: [31, 80], 17 popupAnchor: [0, -80], 18}); 19 20const dpdLockerIcon = L.icon({ 21 iconUrl: `/assets/images/dpdlockericon.png?v=${Date.now()}`, 22 iconSize: [62, 80], 23 iconAnchor: [31, 80], 24 popupAnchor: [0, -80], 25}); 26 27function resetLockerMapView() { 28 if (!lockerMap) return; 29 lockerMap.setView([44.4268, 26.1025], 13, {animate: false}); 30} 31 32function openSelectedLockerPopupIfAny() { 33 const pickupInput = document.querySelector(".pickup-point"); 34 const selectedValue = (pickupInput?.value || "").trim(); 35 if (!selectedValue) return; 36 37 const parts = selectedValue.split("|||"); 38 const routing = (parts[0] || "").trim(); 39 const pickedId = (parts.length >= 4 ? parts[3] || "" : "").trim(); 40 41 let selectedSlug = ""; 42 let selectedType = ""; 43 try { 44 const parsed = JSON.parse( 45 document.getElementById("shipping-locker-unic")?.value || "{}" 46 ); 47 selectedSlug = parsed?.courierSlug || ""; 48 selectedType = parsed?.courierType || ""; 49 } catch (e) { 50 } 51 52 let found = null; 53 54 if (pickedId && selectedSlug) { 55 found = lockerPoints.find( 56 (p) => 57 p.curier_slug === selectedSlug && 58 String(p.curier_external_id || p.pickup_point_id || p.id || "") === 59 String(pickedId) 60 ); 61 } 62 63 if (!found && routing && selectedSlug) { 64 found = lockerPoints.find( 65 (p) => 66 p.curier_slug === selectedSlug && 67 String(p.curier_routing_location || "").trim() === routing 68 ); 69 } 70 71 if (!found && routing) { 72 found = lockerPoints.find( 73 (p) => String(p.curier_routing_location || "").trim() === routing 74 ); 75 } 76 77 if (!found) return; 78 79 if (!found._marker) { 80 const mk = createLockerMarker(found); 81 if (!mk) return; 82 addPopupToMarker(mk, found); 83 found._marker = mk; 84 lockerCluster.addLayer(mk); 85 } 86 87 const lat = parseFloat(found.curier_latitude); 88 const lng = parseFloat(found.curier_longitude); 89 if (!isFinite(lat) || !isFinite(lng)) return; 90 91 lockerMap.setView([lat, lng], 19, {animate: false}); 92 found._marker.openPopup(); 93} 94 95const lockerModal = document.getElementById("lockerMapModal"); 96lockerModal.addEventListener("shown.bs.modal", async () => { 97 const loader = document.getElementById("locker-loader"); 98 const searchInput = document.getElementById("lockerSearch"); 99 100 if (!lockerMapLoaded) { 101 loader.style.display = "block"; 102 if (searchInput) searchInput.classList.add("d-none"); 103 } 104 105 let activeTab = document.querySelector(".courier-tab.active"); 106 107 const pickupInput = document.querySelector(".pickup-point"); 108 const selectedValue = pickupInput?.value.trim(); 109 110 let slugFromInput = ""; 111 let typeFromInput = ""; 112 113 if (selectedValue) { 114 const lockerInput = document.getElementById("shipping-locker-unic"); 115 if (lockerInput && lockerInput.value) { 116 try { 117 const parsed = JSON.parse(lockerInput.value); 118 slugFromInput = parsed?.courierSlug || ""; 119 typeFromInput = parsed?.courierType || ""; 120 } catch (err) { 121 console.warn("JSON parse fail", err); 122 } 123 } 124 } 125 126 if (activeTab) { 127 currentCourierSlug = activeTab.dataset.slug; 128 currentCourierType = activeTab.dataset.type; 129 lockerPoints = await fetchLockersForCourier( 130 currentCourierSlug, 131 currentCourierType 132 ); 133 } else { 134 if (slugFromInput) { 135 currentCourierSlug = slugFromInput; 136 currentCourierType = 137 typeFromInput || (slugFromInput === "fancourier" ? "fanbox" : "locker"); 138 139 lockerPoints = await fetchLockersForCourier( 140 currentCourierSlug, 141 currentCourierType 142 ); 143 } else { 144 currentCourierSlug = "sameday"; 145 currentCourierType = "locker"; 146 147 lockerPoints = await fetchLockersForCourier( 148 currentCourierSlug, 149 currentCourierType 150 ); 151 } 152 } 153 154 if (!lockerMap) { 155 lockerMap = L.map("lockerMap").setView([44.4268, 26.1025], 13); 156 L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo( 157 lockerMap 158 ); 159 lockerCluster = L.markerClusterGroup(); 160 lockerMap.addLayer(lockerCluster); 161 L.control 162 .locate({ 163 position: "topleft", 164 flyTo: true, 165 }) 166 .addTo(lockerMap); 167 } 168 169 lockerCluster.clearLayers(); 170
171 lockerPoints.forEach((p) => { 172 if (p.curier_slug !== currentCourierSlug) return; 173 174 if (!p._marker) { 175 p._marker = createLockerMarker(p); 176 } 177 if (!p._marker) return; 178 179 addPopupToMarker(p._marker, p); 180 lockerCluster.addLayer(p._marker); 181 }); 182 183 loader.style.display = "none"; 184 if (searchInput) searchInput.classList.remove("d-none"); 185 186 lockerMapLoaded = true; 187 lockerMap.invalidateSize(); 188 189 setTimeout(() => { 190 openSelectedLockerPopupIfAny(); 191 }, 150); 192}); 193 194document.getElementById("lockerSearch").addEventListener("input", async () => { 195 const searchInput = document.getElementById("lockerSearch"); 196 const val = searchInput.value.trim(); 197 198 if (val === "") { 199 document.getElementById("lockerSuggestions").innerHTML = ""; 200 201 const activeTab = document.querySelector(".courier-tab.active"); 202 if (!activeTab) { 203 lockerCluster.clearLayers(); 204 const allCurieri = [ 205 {slug: "fancourier", type: "fanbox"}, 206 {slug: "sameday", type: "locker"}, 207 {slug: "dpd", type: "locker"}, 208 ]; 209 lockerPoints = []; 210 for (const c of allCurieri) { 211 const result = await fetchLockersForCourier(c.slug, c.type); 212 lockerPoints = lockerPoints.concat(result); 213 } 214 lockerPoints.forEach((p) => { 215 const marker = createLockerMarker(p); 216 if (!marker) return; 217 addPopupToMarker(marker, p); 218 lockerCluster.addLayer(marker); 219 }); 220 } 221 } 222}); 223 224async function fetchLockersForCourier(slug, type) { 225 const response = await fetch( 226 `/api-couriers/v2/api-get-courier-pickup-points.php?slug=${slug}&type=${type}` 227 ); 228 const data = await response.json(); 229 const points = data.pickup_points || []; 230 231 points.forEach((p) => { 232 p.curier_slug = slug; 233 p.curier_type = type; 234 }); 235 236 const unique = {}; 237 points.forEach((p) => { 238 const uid = String( 239 p.curier_external_id || 240 p.pickup_point_id || 241 p.id || 242 p.curier_routing_location 243 ); 244 unique[`${slug}::${type}::${uid}`] = p; 245 }); 246 return Object.values(unique); 247} 248 249function addPopupToMarker(marker, p) { 250 p._marker = marker; 251 252 const pickupInput = document.querySelector(".pickup-point"); 253 const selectedValue = pickupInput?.value.trim() || ""; 254 let isAlreadySelected = false; 255 256 if (selectedValue) { 257 const parts = selectedValue.split("|||"); 258 const selectedRouting = (parts[0] || "").trim(); 259 const selectedId = (parts.length >= 4 ? parts[3] || "" : "").trim(); 260 261 let selectedSlug = ""; 262 try { 263 const parsed = JSON.parse( 264 document.getElementById("shipping-locker-unic")?.value || "{}" 265 ); 266 selectedSlug = parsed?.courierSlug || ""; 267 } catch (e) { 268 } 269 270 const pId = String(p.curier_external_id || p.pickup_point_id || p.id || ""); 271 const pRouting = String(p.curier_routing_location || "").trim(); 272 273 if (selectedId && selectedSlug && pId) { 274 isAlreadySelected = 275 p.curier_slug === selectedSlug && pId === String(selectedId); 276 } else { 277 isAlreadySelected = pRouting === selectedRouting; 278 } 279 } 280 281 const btnLabel = isAlreadySelected ? "Locker ales" : "Alege acest Locker"; 282 const btnClass = isAlreadySelected ? "btn-success" : "btn-primary"; 283 284 const popupContent = ` 285 <div style="font-size: 14px; line-height: 1.4;"> 286 <strong>${p.curier_name}</strong><br> 287 ${p.curier_address_street || ""} Nr. ${p.curier_address_street_no || ""}<br> 288 ${p.curier_address_locality}, ${p.curier_address_county}<br> 289 <a href="https://www.google.com/maps/search/?api=1&query=${ 290 p.curier_latitude 291 },${ 292 p.curier_longitude 293 }" target="_blank" style="font-size:12px;color:#007bff;">
293Deschide în Google Maps</a><br> 294 <button class="btn btn-sm ${btnClass} select-locker-btn"> 295 ${btnLabel} 296 </button> 297 </div> 298`; 299 300 marker.bindPopup(popupContent); 301 marker.off("popupopen"); 302 marker.on("popupopen", () => { 303 const popupEl = marker.getPopup().getElement(); 304 const btn = popupEl?.querySelector(".select-locker-btn"); 305 if (btn) { 306 btn.onclick = null; 307 btn.onclick = () => { 308 const pickupInput = document.querySelector(".pickup-point"); 309 const countyLocalityInput = document.querySelector( 310 ".pickup-county-locality" 311 ); 312 313 let value = ""; 314 315 if (p.curier_slug === "sameday" && p.curier_type === "locker") { 316 value = `${p.curier_routing_location}|||${p.curier_address_zip}|||${p.curier_address_locality}|||${p.curier_external_id}`; 317 } else if (p.curier_slug === "dpd" && p.curier_type === "locker") { 318 const dpdId = String( 319 p.curier_external_id || p.pickup_point_id || p.id || "" 320 ); 321 const routing = 322 String(p.curier_routing_location || "").trim() || dpdId; 323 value = `${routing}|||${p.curier_address_zip || ""}|||${ 324 p.curier_address_locality || "" 325 }|||${dpdId}`; 326 } else { 327 value = `${p.curier_routing_location}|||${p.curier_address_zip}`; 328 } 329 330 pickupInput.value = value; 331 if (countyLocalityInput) { 332 countyLocalityInput.value = `${p.curier_address_county || ""}|||${ 333 p.curier_address_locality || "" 334 }`; 335 } 336 const lockerFullAddress = ` 337 ${p.curier_name || ""} 338 ${p.curier_address_street || ""} Nr. ${p.curier_address_street_no || ""}, 339 ${p.curier_address_locality || ""}, ${p.curier_address_county || ""} 340` 341 .replace(/\s+/g, " ") 342 .trim(); 343 344 document.getElementById("lockerAddressHidden").value = 345 lockerFullAddress; 346 347 const finalSlug = p.curier_slug ? p.curier_slug : currentCourierSlug; 348 const finalType = p.curier_type ? p.curier_type : currentCourierType; 349 350 const selectedCourier = window.couriers.find( 351 (c) => c.slug === finalSlug 352 ); 353 354 let selectedService = null; 355 if (selectedCourier) { 356 selectedService = selectedCourier.services.find( 357 (s) => 358 (finalSlug === "sameday" && String(s.service_id) === "15") || 359 (finalSlug === "fancourier" && 360 ["27", "4", "20"].includes(String(s.service_id))) || 361 (finalSlug === "dpd" && String(s.service_id) !== "2505") 362 ); 363 364 if ( 365 !selectedService && 366 selectedCourier.services && 367 selectedCourier.services.length 368 ) { 369 selectedService = selectedCourier.services[0]; 370 } 371 } 372 373 if (!selectedService && p.curier_service_id) { 374 selectedService = { 375 id: p.curier_service_id, 376 service_id: p.curier_service_id, 377 name_code: p.curier_service_name_code || "", 378 name: p.curier_service_name || "", 379 }; 380 } 381 382 const lockerInput = document.getElementById("shipping-locker-unic"); 383 384 // console.log("LOCKER SELECTED", { 385 // courierSlug: finalSlug, 386 // serviceId: selectedService?.id || "", 387 // serviceCode: selectedService?.service_id || "",
388 // serviceNameCode: selectedService?.name_code || "", 389 // courierType: finalType, 390 // serviceName: `Ridicare personalÄ ${selectedCourier?.name || ""}`, 391 // }); 392 393 lockerInput.value = JSON.stringify({ 394 courierSlug: finalSlug, 395 serviceId: selectedService?.id || "", 396 serviceCode: selectedService?.service_id || "", 397 serviceNameCode: selectedService?.name_code || "", 398 courierType: finalType, 399 serviceName: `Ridicare personalÄ ${selectedCourier?.name || ""}`, 400 }); 401 402 lockerInput.checked = true; 403 lockerInput.dispatchEvent(new Event("change", {bubbles: true})); 404 hasUserSelectedCourier = true; 405 togglePaymentMethods(true); 406 407 document.querySelector(".selected-pickup-point").innerHTML = ` 408 <strong>${p.curier_name}</strong><br> 409 ${p.curier_address_street || ""} Nr. ${ 410 p.curier_address_street_no || "" 411 } 412 ${p.curier_address_locality}, ${p.curier_address_county} 413 `; 414 415 bootstrap.Modal.getInstance(lockerModal).hide(); 416 updateLockerButtonText(); 417 updateCourierPrices(); 418 }; 419 } 420 }); 421 422 if (!p._marker) p._marker = marker; 423} 424 425document.getElementById("lockerSearch").addEventListener("input", function () { 426 const q = this.value.toLowerCase().trim(); 427 lockerCluster.clearLayers(); 428 const suggestions = document.getElementById("lockerSuggestions"); 429 suggestions.innerHTML = ""; 430 431 let matches = []; 432 433 if (q === "") { 434 matches = lockerPoints.filter( 435 (p) => p.curier_address_locality.toLowerCase() === "bucuresti" 436 ); 437 if (matches.length) { 438 lockerMap.setView([44.4268, 26.1025], 13); 439 } 440 } else { 441 matches = lockerPoints.filter( 442 (p) => 443 p.curier_name.toLowerCase().includes(q) || 444 p.curier_address_locality.toLowerCase().includes(q) || 445 `${p.curier_name} ${p.curier_address_street} ${p.curier_address_street_no} ${p.curier_address_locality}` 446 .toLowerCase() 447 .includes(q) 448 ); 449 } 450 451 matches.forEach((p) => { 452 const marker = p._marker || createLockerMarker(p); 453 if (!marker) return; 454 455 lockerCluster.addLayer(marker); 456 457 const item = document.createElement("button"); 458 item.type = "button"; 459 item.className = "list-group-item list-group-item-action"; 460 item.textContent = `${p.curier_name} - ${p.curier_address_locality}`; 461 462 item.addEventListener("click", () => { 463 lockerCluster.clearLayers(); 464 const marker = p._marker || createLockerMarker(p); 465 if (!marker) return; 466 addPopupToMarker(marker, p); 467 p._marker = marker; 468 lockerCluster.addLayer(marker); 469 470 lockerMap.setView( 471 [parseFloat(p.curier_latitude), parseFloat(p.curier_longitude)], 472 19, 473 {animate: false} 474 ); 475 marker.openPopup(); 476 477 suggestions.innerHTML = ""; 478 document.getElementById( 479 "lockerSearch" 480 ).value = `${p.curier_name} ${p.curier_address_locality}`; 481 482 const pickupInput = document.querySelector(".pickup-point"); 483 const countyLocalityInput = document.querySelector( 484 ".pickup-county-locality" 485 ); 486 487 let value = ""; 488 489 if (p.curier_slug === "sameday" && p.curier_type === "locker") { 490 value = `${p.curier_routing_location}|||${p.curier_address_zip}|||${p.curier_address_locality}|||${p.curier_external_id}`; 491 } else if (p.curier_slug === "dpd" && p.curier_type === "locker") { 492 const dpdId = String( 493 p.curier_external_id || p.pickup_point_id || p.id || "" 494 ); 495 const routing = String(p.curier_routing_location || "").trim() || dpdId; 496 value = `${routing}|||${p.curier_address_zip || ""}|||${ 497 p.curier_address_locality || "" 498 }|||${dpdId}`; 499 } else { 500 value = `${p.curier_routing_location}|||${p.curier_address_zip}`; 501 } 502 503 pickupInput.value = value; 504 if (countyLocalityInput) { 505 countyLocalityInput.value = `${p.curier_address_county || ""}|||${ 506 p.curier_address_locality || "" 507 }`; 508 } 509 510 const lockerFullAddress = ` 511 ${p.curier_name || ""} 512 ${p.curier_address_street || ""} Nr. ${p.curier_address_street_no || ""}, 513 ${p.curier_address_locality || ""}, ${p.curier_address_county || ""} 514` 515 .replace(/\s+/g, " ") 516 .trim(); 517 518 document.getElementById("lockerAddressHidden").value = lockerFullAddress; 519 520 const finalSlug = p.curier_slug; 521 const finalType = p.curier_type; 522 523 const selectedCourier = window.couriers.find((c) => c.slug === finalSlug); 524 525 let selectedService = null; 526 if (selectedCourier) { 527 selectedService = selectedCourier.services.find( 528 (s) => 529 (finalSlug === "sameday" && String(s.service_id) === "15") || 530 (finalSlug === "fancourier" && 531 ["27", "4", "20"].includes(String(s.service_id))) || 532 (finalSlug === "dpd" && String(s.service_id) !== "2505") 533 ); 534 535 if (!selectedService && selectedCourier.services?.length) { 536 selectedService = selectedCourier.services[0]; 537 } 538 } 539 540 if (!selectedService && p.curier_service_id) { 541 selectedService = { 542 id: p.curier_service_id, 543 service_id: p.curier_service_id, 544 name_code: p.curier_service_name_code || "", 545 name: p.curier_service_name || "", 546 }; 547 } 548 549 const lockerInput = document.getElementById("shipping-locker-unic"); 550 551 // console.log("LOCKER SELECTED", { 552 // courierSlug: selectedCourier?.slug, 553 // serviceId: selectedService?.id || "", 554 // serviceCode: selectedService?.service_id || "",
555 // serviceNameCode: selectedService?.name_code || "", 556 // courierType: finalType, 557 // serviceName: `Ridicare personalÄ ${selectedCourier?.name || ""}`, 558 // }); 559 560 lockerInput.value = JSON.stringify({ 561 courierSlug: selectedCourier?.slug, 562 serviceId: selectedService?.id || "", 563 serviceCode: selectedService?.service_id || "", 564 serviceNameCode: selectedService?.name_code || "", 565 courierType: finalType, 566 serviceName: `Ridicare personalÄ ${selectedCourier?.name || ""}`, 567 }); 568 569 lockerInput.checked = true; 570 lockerInput.dispatchEvent(new Event("change", {bubbles: true})); 571 hasUserSelectedCourier = true; 572 573 document.querySelector(".selected-pickup-point").innerHTML = ` 574 <strong>${p.curier_name}</strong><br> 575 ${p.curier_address_street || ""} Nr. ${p.curier_address_street_no || ""}<br> 576 ${p.curier_address_locality}, ${p.curier_address_county} 577 `; 578 579 updateLockerButtonText(); 580 updateCourierPrices(); 581 bootstrap.Modal.getInstance(lockerModal).hide(); 582 togglePaymentMethods(true); 583 }); 584 585 suggestions.appendChild(item); 586 }); 587 588 if (matches.length === 1 && q.length > 5) { 589 const p = matches[0]; 590 const marker = p._marker || createLockerMarker(p); 591 lockerCluster.clearLayers(); 592 if (!marker) return; 593 addPopupToMarker(marker, p); 594 p._marker = marker; 595 lockerCluster.addLayer(marker); 596 597 lockerMap.setView( 598 [parseFloat(p.curier_latitude), parseFloat(p.curier_longitude)], 599 19, 600 {animate: false} 601 ); 602 marker.openPopup(); 603 604 suggestions.innerHTML = ""; 605 } 606}); 607 608document.getElementById("lockerSearch").addEventListener("paste", function (e) { 609 const input = this; 610 setTimeout(() => { 611 const event = new Event("input", {bubbles: true}); 612 input.dispatchEvent(event); 613 }, 50); 614}); 615 616function createLockerMarker(p) { 617 const slug = p.curier_slug || currentCourierSlug; 618 const type = p.curier_type || currentCourierType; 619 620 if (!p.curier_latitude || !p.curier_longitude) return null; 621 622 let icon = null; 623 624 if (slug === "fancourier" && type === "fanbox") { 625 icon = fanboxIcon; 626 } else if (slug === "sameday" && type === "locker") { 627 icon = easyboxIcon; 628 } else if (slug === "dpd" && type === "locker") { 629 icon = dpdLockerIcon; 630 } else { 631 return null; 632 } 633 634 const marker = L.marker( 635 [parseFloat(p.curier_latitude), parseFloat(p.curier_longitude)], 636 {icon: icon} 637 ); 638 639 return marker; 640} 641 642document.querySelectorAll(".courier-tab").forEach((btn) => { 643 btn.addEventListener("click", async () => { 644 document 645 .querySelectorAll(".courier-tab") 646 .forEach((b) => b.classList.remove("active")); 647 btn.classList.add("active"); 648 649 currentCourierSlug = btn.dataset.slug; 650 currentCourierType = btn.dataset.type; 651 652 lockerCluster.clearLayers(); 653 resetLockerMapView(); 654 lockerMap.eachLayer((layer) => { 655 if (layer instanceof L.Marker && !(layer instanceof L.MarkerCluster)) { 656 lockerMap.removeLayer(layer); 657 } 658 }); 659 660 lockerPoints.forEach((p) => { 661 p._marker = null; 662 }); 663 664 const response = await fetch( 665 `/api-couriers/v2/api-get-courier-pickup-points.php?slug=${currentCourierSlug}&type=${currentCourierType}` 666 ); 667 const data = await response.json(); 668 669 lockerPoints = (data.pickup_points || []).map((p) => { 670 p.curier_slug = currentCourierSlug; 671 p.curier_type = currentCourierType; 672 p._marker = null; 673 return p; 674 }); 675 676 lockerPoints.forEach((p) => { 677 const marker = createLockerMarker(p); 678 if (!marker) return; 679 addPopupToMarker(marker, p); 680 p._marker = marker; 681 lockerCluster.addLayer(marker); 682 }); 683 684 document.getElementById("lockerSearch").value = ""; 685 document.getElementById("lockerSuggestions").innerHTML = ""; 686 });
687}); 688 689function capitalizeFirst(str) { 690 str = str.trim().replace(/^_+/, ""); 691 return str.charAt(0).toUpperCase() + str.slice(1); 692} 693 694let currentCourierSlug = ""; 695let currentCourierType = ""; 696let hasUserSelectedCourier = false; 697 698let globalLowestPrice = Infinity; 699let globalCheapestServiceId = null; 700let globalCheapestCourierSlug = null; 701 702let couriers = []; 703currentCourierSlug = "sameday"; 704currentCourierType = "locker"; 705 706function moneyToNumber(s) { 707 s = String(s || "") 708 .trim() 709 .replace(/[^\d.,-]/g, ""); 710 const hasC = s.includes(","), 711 hasD = s.includes("."); 712 if (hasC && hasD) { 713 const dec = s.lastIndexOf(",") > s.lastIndexOf(".") ? "," : "."; 714 const thou = dec === "," ? "." : ","; 715 return parseFloat(s.split(thou).join("").replace(dec, ".")) || 0; 716 } 717 if (hasC) return parseFloat(s.replace(/\./g, "").replace(",", ".")) || 0; 718 return parseFloat(s.replace(/,/g, "")) || 0; 719} 720 721function getOrderAmountNoShipping() { 722 const finalTxt = 723 ( 724 document.getElementById("total-final") || 725 document.querySelector(".cart-summary-total") 726 )?.textContent || "0"; 727 728 const shipEl = 729 document.getElementById("total-shipping-tax") || 730 document.getElementById("total-transport") || 731 document.querySelector('.cart-summary-item-value[id*="shipping"]') || 732 document.querySelector(".cart-summary-shipping"); 733 734 const shipTxt = shipEl?.textContent || "0"; 735 736 const subtotal = Math.max( 737 moneyToNumber(finalTxt) - moneyToNumber(shipTxt), 738 0 739 ); 740 return subtotal; 741} 742 743async function loadCouriers() { 744 const container = document.querySelector(".shipping-methods"); 745 if (!container) return; 746 container.innerHTML = ""; 747 const isDifferent = document.querySelector("#isDifferentShipping")?.checked; 748 749 let county = ""; 750 let locality = ""; 751 752 if (isDifferent) { 753 county = document.querySelector("#countyInputShipping")?.value || ""; 754 locality = document.querySelector("#localityInputShipping")?.value || ""; 755 } else { 756 county = document.querySelector("#countyInput")?.value || ""; 757 locality = document.querySelector("#localityInput")?.value || ""; 758 } 759 const payload = { 760 weight: (() => { 761 const inputWeight = document.getElementById("cart-total-weight"); 762 return inputWeight ? parseFloat(inputWeight.value) || 1 : 1; 763 })(), 764 order_amount: getOrderAmountNoShipping(), 765 payment_method: (() => { 766 const selectedPayment = document.querySelector( 767 'input[name="payment-method"]:checked' 768 ); 769 return selectedPayment ? selectedPayment.value : "1"; 770 })(), 771 county, 772 locality, 773 }; 774 775 const response = await fetch("/api-couriers/v2/api-get-couriers.php", { 776 method: "POST", 777 headers: {"Content-Type": "application/json"}, 778 body: JSON.stringify(payload), 779 }); 780 781 const data = await response.json(); 782 const couriers = data.couriers; 783 window.couriers = couriers; 784 785 let cheapestCourier = null; 786 let cheapestService = null; 787 let lowestPrice = Infinity; 788 789 couriers.forEach((courier) => { 790 courier.services.forEach((service) => { 791 const isHome = 792 (courier.slug === "fancourier" && service.service_id == 1) || 793 (courier.slug === "sameday" && service.service_id == 7) || 794 courier.slug === "bookurier" || 795 (courier.slug === "dpd" && service.service_id == 2505); 796 797 let price = parseFloat(service.estimated_price ?? service.price); 798 if (isNaN(price)) price = Infinity; 799 800 if (isHome && price < lowestPrice) { 801 lowestPrice = price; 802 cheapestCourier = courier; 803 cheapestService = service; 804 } 805 }); 806 }); 807 808 if (!cheapestCourier || !cheapestService) { 809 cheapestCourier = 810 couriers.find((c) => c.slug === "bookurier") || 811 couriers.find((c) => c.slug === "fancourier") || 812 couriers.find((c) => c.slug === "sameday") || 813 couriers[0]; 814 815 if (cheapestCourier) { 816 cheapestService = 817 cheapestCourier.services.find( 818 (s) => 819 (cheapestCourier.slug === "fancourier" && s.service_id == 1) || 820 (cheapestCourier.slug === "sameday" && s.service_id == 7) || 821 cheapestCourier.slug === "bookurier" 822 ) || cheapestCourier.services[0]; 823 } 824 } 825 826 if (cheapestCourier && cheapestService) { 827 const shippingId = `shipping-${cheapestCourier.slug}-${cheapestService.service_id}`; 828 const wrap = document.createElement("div"); 829 wrap.className = "shipping-method-wrap mb-2"; 830 831 const inputDiv = document.createElement("div"); 832 inputDiv.className = "form-check"; 833 834 const input = document.createElement("input"); 835 input.className = "form-check-input"; 836 input.type = "radio"; 837 input.id = shippingId; 838 input.name = "shipping-method"; 839 input.value = JSON.stringify({ 840 courierSlug: cheapestCourier.slug, 841 serviceId: cheapestService.id, 842 serviceCode: cheapestService.service_id, 843 serviceNameCode: cheapestService.name_code, 844 serviceName: "La domiciliu prin curier", 845 }); 846 input.checked = true; 847 848 const label = document.createElement("label"); 849 label.className = "form-check-label"; 850 label.setAttribute("for", shippingId); 851 const priceLabel = 852 lowestPrice < Infinity && lowestPrice > 0 853 ? `${lowestPrice.toFixed(2)} lei` 854 : ""; 855 label.innerHTML = `Livrare la domiciliu prin curier ${priceLabel}`; 856 857 inputDiv.appendChild(input); 858 inputDiv.appendChild(label); 859 wrap.appendChild(inputDiv); 860 container.appendChild(wrap); 861 862 input.addEventListener("change", () => { 863 document.querySelectorAll(".payment-method-wrap").forEach((method) => { 864 method.classList.remove("d-none"); 865 }); 866 }); 867 } 868 869 const lockerWrap = document.createElement("div"); 870 lockerWrap.className = "shipping-method-wrap mb-2"; 871 872 const lockerInputDiv = document.createElement("div"); 873 lockerInputDiv.className = "form-check"; 874 875 const lockerInput = document.createElement("input"); 876 lockerInput.className = "form-check-input"; 877 lockerInput.type = "radio"; 878 lockerInput.id = "shipping-locker-unic"; 879 lockerInput.name = "shipping-method"; 880 lockerInput.value = ""; 881 882 const lockerLabel = document.createElement("label"); 883 lockerLabel.className = "form-check-label"; 884 lockerLabel.setAttribute("for", "shipping-locker-unic"); 885 lockerLabel.innerHTML = ` 886 Ridicare personalÄ din locker 887 <span class="selected-pickup-point"></span><br> 888 <input type="hidden" name="pickup-point" class="pickup-point" value=""> 889 <input type="hidden" class="pickup-county-locality" name="pickup-county-locality" value=""> 890 <input type="hidden" name="locker_address" id="lockerAddressHidden" value=""> 891 <button type="button" id="open-locker-modal" class="btn btn-link p-0"> 892 Click Èi alege locker preferat 893 </button> 894`; 895 lockerInputDiv.appendChild(lockerInput); 896 lockerInputDiv.appendChild(lockerLabel); 897 lockerWrap.appendChild(lockerInputDiv); 898 container.appendChild(lockerWrap); 899 900 document.getElementById("open-locker-modal").addEventListener("click", () => { 901 const selectedCourier = window.couriers.find( 902 (c) => c.slug === currentCourierSlug 903 ); 904 if (!selectedCourier) { 905 alert("Nu existÄ locker disponibil!"); 906 return; 907 } 908 909 /* 910 const selectedService = 911 selectedCourier.services && selectedCourier.services[0] 912 ? selectedCourier.services[0] 913 : null; 914 */ 915 916 let selectedService = null; 917 918 if (selectedCourier?.services?.length) { 919 selectedService = selectedCourier.services.find( 920 (s) => 921 (selectedCourier.slug === "sameday" && String(s.service_id) === "15") || 922 (selectedCourier.slug === "fancourier" && 923 ["27", "4", "20"].includes(String(s.service_id))) || 924 (selectedCourier.slug === "dpd" && 925 String(s.service_id) !== "2505") 926 ); 927 928 if (!selectedService) { 929 selectedService = selectedCourier.services[0]; 930 } 931 } 932 933 if (!selectedService) { 934 alert("Nu existÄ servicii disponibile pentru acest curier!"); 935 return; 936 } 937 938 const lockerTypeFromTab = 939 document.querySelector(".courier-tab.active")?.dataset?.type || ""; 940 const resolvedLockerType = 941 lockerTypeFromTab || 942 (selectedCourier.slug === "fancourier" ? "fanbox" : "locker"); 943 944 currentCourierSlug = selectedCourier.slug; 945 currentCourierType = resolvedLockerType; 946 947 const lockerInput = document.getElementById("shipping-locker-unic"); 948 949 // console.log("LOCKER SELECTED", { 950 // courierSlug: selectedCourier.slug, 951 // serviceId: selectedService.id, 952 // serviceCode: selectedService.service_id, 953 // serviceNameCode: selectedService.name_code, 954 // courierType: currentCourierType, 955 // serviceName: `Ridicare personalÄ ${selectedCourier.name}`, 956 // }); 957 958 lockerInput.value = JSON.stringify({ 959 courierSlug: selectedCourier.slug, 960 serviceId: selectedService.id, 961 serviceCode: selectedService.service_id, 962 serviceNameCode: selectedService.name_code, 963 courierType: currentCourierType, 964 serviceName: `Ridicare personalÄ ${selectedCourier.name}`, 965 }); 966 967 lockerInput.checked = true; 968 lockerInput.dispatchEvent(new Event("change")); 969 970 const myModal = new bootstrap.Modal(
971 document.getElementById("lockerMapModal") 972 ); 973 myModal.show(); 974 }); 975 976 updateCourierPrices(); 977 togglePaymentMethods(false); 978} 979 980function togglePaymentMethods(isLocker) { 981 const ramburs = document.querySelector(".method-ramburs"); 982 const card = document.querySelector(".method-card"); 983 984 if (!ramburs || !card) return; 985 986 if (isLocker) { 987 ramburs.classList.add("d-none"); 988 const netopia = document.querySelector("#payment-netopia-card"); 989 if (netopia) { 990 netopia.checked = true; 991 netopia.dispatchEvent(new Event("change")); 992 } 993 } else { 994 ramburs.classList.remove("d-none"); 995 } 996} 997 998function updateLockerButtonText() { 999 const pickupInput = document.querySelector(".pickup-point"); 1000 const openBtn = document.getElementById("open-locker-modal"); 1001 if (pickupInput && pickupInput.value.trim()) { 1002 openBtn.textContent = "SchimbÄ locker"; 1003 } else { 1004 openBtn.textContent = "Click Èi alege locker preferat"; 1005 } 1006} 1007 1008async function updateCourierPrices() { 1009 globalLowestPrice = Infinity; 1010 globalCheapestCourierSlug = null; 1011 globalCheapestServiceId = null; 1012 1013 document.querySelectorAll(".best-price-badge").forEach((b) => b.remove()); 1014 1015 const allInputs = Array.from( 1016 document.querySelectorAll('input[name="shipping-method"]') 1017 ); 1018 if (!allInputs.length) return; 1019 1020 const paymentMethod = (() => { 1021 const selected = document.querySelector( 1022 'input[name="payment-method"]:checked' 1023 ); 1024 return selected ? selected.value : "1"; 1025 })(); 1026 const orderAmount = getOrderAmountNoShipping(); 1027 1028 for (const input of allInputs) { 1029 if (!input.value) continue; 1030 1031 1032 const selected = JSON.parse(input.value); 1033 const selectedServiceCode = String(selected.serviceCode); 1034 const courierSlug = selected.courierSlug; 1035 1036 if (!["fancourier", "sameday", "bookurier", "dpd"].includes(courierSlug)) 1037 continue; 1038 1039 const inputContainer = input.closest(".shipping-method-wrap"); 1040 1041 let county = ""; 1042 let locality = ""; 1043 let pickupPoint = ""; 1044 1045 const isLockerRadio = input.id === "shipping-locker-unic"; 1046 1047 const isHomeDelivery = 1048 !isLockerRadio && 1049 ((courierSlug === "fancourier" && selectedServiceCode === "1") ||
1050 (courierSlug === "sameday" && selectedServiceCode === "7") || 1051 courierSlug === "bookurier" || 1052 (courierSlug === "dpd" && selectedServiceCode === "2505")); 1053 1054 if (isHomeDelivery) { 1055 const isDifferentShipping = document.querySelector( 1056 "#isDifferentShipping" 1057 )?.checked; 1058 if (isDifferentShipping) { 1059 county = document.querySelector("#countyInputShipping")?.value || ""; 1060 locality = 1061 document.querySelector("#localityInputShipping")?.value || ""; 1062 } else { 1063 county = document.querySelector("#countyInput")?.value || ""; 1064 locality = document.querySelector("#localityInput")?.value || ""; 1065 if (county.toLowerCase() === "bucuresti") { 1066 const sectorSelect = document.querySelector("#sectorInput"); 1067 if (sectorSelect && sectorSelect.value) { 1068 locality = "Sector " + sectorSelect.value; 1069 } else { 1070 continue; 1071 } 1072 } 1073 } 1074 } else { 1075 pickupPoint = document.querySelector(".pickup-point")?.value || ""; 1076 1077 const countyLocality = 1078 document.querySelector(".pickup-county-locality")?.value || ""; 1079 if (countyLocality.includes("|||")) { 1080 const parts = countyLocality.split("|||"); 1081 if (parts.length === 2) { 1082 county = parts[0].trim(); 1083 locality = parts[1].trim(); 1084 } 1085 } 1086 1087 if (!county) county = "N/A"; 1088 if (!locality && pickupPoint.includes("|||")) { 1089 const parts = pickupPoint.split("|||"); 1090 if (parts.length >= 3) { 1091 locality = parts[2].trim(); 1092 } 1093 } 1094 } 1095 1096 if (isHomeDelivery && (county === "" || locality === "")) continue; 1097 1098 const isLockerShipment = 1099 input.id === "shipping-locker-unic" || selected.courierType === "locker"; 1100 1101 if (isLockerShipment && pickupPoint === "") continue; 1102 1103 const finalWeight = (() => { 1104 const inputWeight = document.getElementById("cart-total-weight"); 1105 return inputWeight ? parseFloat(inputWeight.value) || 1 : 1; 1106 })(); 1107 1108 const payload = { 1109 courierSlug, 1110 serviceCode: selectedServiceCode, 1111 county, 1112 locality, 1113 weight: finalWeight, 1114 order_amount: orderAmount, 1115 payment_method: paymentMethod, 1116 is_locker: Number(!isHomeDelivery) 1117 }; 1118 1119 if (["27", "4", "20"].includes(selectedServiceCode)) { 1120 payload.pickup_county = county; 1121 payload.pickup_locality = locality; 1122 if (pickupPoint) payload.pickup_point = pickupPoint.split("|||")[0]; 1123 } 1124 1125 if (selectedServiceCode === "15") { 1126 const parts = pickupPoint.trim().split("|||"); 1127 const lockerId = parts.at(-1)?.trim(); 1128 if (!lockerId || !/^[a-zA-Z0-9]+$/.test(lockerId)) { 1129 console.warn("Locker ID lipsÄ sau invalid:", pickupPoint); 1130 input.setAttribute("data-price", "0"); 1131 continue; 1132 } 1133 payload.pickup_point = lockerId; 1134 } 1135 1136 try { 1137 const response = await fetch( 1138 "/api-couriers/v2/api-get-courier-price.php", 1139 { 1140 method: "POST", 1141 headers: {"Content-Type": "application/json"}, 1142 body: JSON.stringify(payload), 1143 } 1144 ); 1145 1146 if (!response.ok) continue; 1147 1148 const data = await response.json(); 1149 const price = parseFloat(data.price); 1150 1151 input.setAttribute("data-estimated-price", data.estimated_price ?? ""); 1152 input.setAttribute("data-price", !isNaN(price) ? price.toFixed(2) : "0"); 1153 1154 const isLockerRadio = input.id === "shipping-locker-unic"; 1155 const label = isLockerRadio 1156 ? document.querySelector('label[for="shipping-locker-unic"]') 1157 : document.querySelector(`label[for="shipping-${courierSlug}-${selectedServiceCode}"]`); 1158
1159 input.setAttribute("data-estimated-price", data.estimated_price ?? ""); 1160 1161 if (input.checked) { 1162 const estimatedPriceInput = document.getElementById( 1163 "estimatedPriceInput" 1164 ); 1165 if (estimatedPriceInput) { 1166 estimatedPriceInput.value = data.estimated_price ?? ""; 1167 } 1168 } 1169 1170 if (label) { 1171 label 1172 .querySelectorAll(".free-shipping-badge") 1173 .forEach((b) => b.remove()); 1174 1175 const isLocker = input.id === "shipping-locker-unic"; 1176 1177 if (!isNaN(price)) { 1178 if (isLocker) { 1179 const pickupPointSpan = label.querySelector( 1180 ".selected-pickup-point" 1181 ); 1182 let badgeSpan = label.querySelector(".locker-price-badge"); 1183 if (pickupPointSpan) { 1184 if (badgeSpan) { 1185 badgeSpan.textContent = ` (${price.toFixed(2)} lei)`; 1186 } else { 1187 pickupPointSpan.insertAdjacentHTML( 1188 "afterend", 1189 ` <span class="locker-price-badge">(${price.toFixed( 1190 2 1191 )} lei)</span>` 1192 ); 1193 } 1194 } 1195 set_shipping_tax(price.toFixed(2)); 1196 } else { 1197 label.innerHTML = `${selected.serviceName} (${price.toFixed( 1198 2 1199 )} lei)`; 1200 } 1201 1202 if (price < globalLowestPrice) { 1203 globalLowestPrice = price; 1204 globalCheapestCourierSlug = courierSlug; 1205 globalCheapestServiceId = selectedServiceCode; 1206 } 1207 } else { 1208 if (!isLocker) { 1209 label.innerHTML = `${selected.serviceName}`; 1210 } 1211 } 1212 1213 if (data.is_free_shipping || price === 0) { 1214 const freeBadge = document.createElement("span"); 1215 freeBadge.className = "badge bg-success ms-2 free-shipping-badge"; 1216 freeBadge.setAttribute( 1217 "title", 1218 data.free_delivery_threshold 1219 ? `Transport gratuit peste ${parseFloat( 1220 data.free_delivery_threshold 1221 ).toFixed(2)} lei` 1222 : "Transport gratuit activat" 1223 ); 1224 freeBadge.textContent = "Transport gratuit"; 1225 label.appendChild(freeBadge); 1226 new bootstrap.Tooltip(freeBadge); 1227 } 1228 } 1229 } catch (err) { 1230 console.warn("Eroare la estimare preÈ:", err); 1231 } 1232 } 1233 1234 if ( 1235 !hasUserSelectedCourier && 1236 globalCheapestCourierSlug && 1237 globalCheapestServiceId 1238 ) { 1239 const cheapestInput = document.querySelector( 1240 `#shipping-${globalCheapestCourierSlug}-${globalCheapestServiceId}` 1241 ); 1242 if (cheapestInput && !cheapestInput.checked) { 1243 cheapestInput.checked = true; 1244 cheapestInput.dispatchEvent(new Event("change")); 1245 } 1246 const isLocker = ["15", "27", "4", "20"].includes( 1247 String(globalCheapestServiceId) 1248 ); 1249 if (!isLocker) { 1250 const newPrice = cheapestInput?.dataset.price || "0"; 1251 set_shipping_tax(newPrice); 1252 } 1253 } 1254} 1255 1256document.addEventListener("DOMContentLoaded", async () => { 1257 await loadCouriers(); 1258 hasUserSelectedCourier = false; 1259 await updateCourierPrices(); 1260 1261 document 1262 .querySelector("#countyInput") 1263 ?.addEventListener("change", updateCourierPrices); 1264 1265 document 1266 .querySelector("#localityInput") 1267 ?.addEventListener("change", async function () { 1268 await updateCourierPrices(); 1269 const selectedInput = document.querySelector( 1270 'input[name="shipping-method"]:checked' 1271 ); 1272 if (selectedInput && selectedInput.dataset.price) { 1273 set_shipping_tax(selectedInput.dataset.price); 1274 } 1275 }); 1276 1277 document 1278 .querySelector("#countyInputShipping") 1279 ?.addEventListener("change", updateCourierPrices); 1280 1281 document 1282 .querySelector("#localityInputShipping") 1283 ?.addEventListener("change", async function () { 1284 await updateCourierPrices(); 1285 const selectedInput = document.querySelector( 1286 'input[name="shipping-method"]:checked' 1287 ); 1288 if (selectedInput && selectedInput.dataset.price) { 1289 set_shipping_tax(selectedInput.dataset.price); 1290 } 1291 }); 1292 1293 document 1294 .querySelector("#isDifferentShipping") 1295 ?.addEventListener("change", updateCourierPrices); 1296}); 1297 1298function populateCountySelect(selectElement) { 1299 if (!window.COUNTIES || !Array.isArray(window.COUNTIES)) { 1300 return; 1301 } 1302 1303 window.COUNTIES.forEach(({name, nice_name}) => { 1304 const opt = document.createElement("option"); 1305 opt.value = nice_name; 1306 opt.textContent = name; 1307 selectElement.appendChild(opt); 1308 });
1309} 1310 1311const requiredFieldsByMethod = { 1312 fancourier: { 1313 4: [".county-sediu", ".locality-sediu"], 1314 20: [".county-sediu", ".locality-sediu"], 1315 27: [".pickup-county", ".pickup-locality", ".pickup-point"], 1316 }, 1317 sameday: { 1318 15: [".pickup-county", ".pickup-locality", ".pickup-point"], 1319 }, 1320}; 1321 1322function set_shipping_tax(shippingPrice) { 1323 $.ajax({ 1324 method: "POST", 1325 url: "/", 1326 data: { 1327 action: "set-shipping-tax-courier", 1328 shipping_price: shippingPrice, 1329 }, 1330 success: function (response) { 1331 if (response.success) { 1332 if (response.result) { 1333 $.each(response.result, function (key, value) { 1334 const htmlEl = key.replaceAll("_", "-"); 1335 if (key === "total_discounts") { 1336 toggle_reducere_box(htmlEl, value); 1337 } else { 1338 if (key === "total_final") { 1339 $("#" + htmlEl).html( 1340 response.result.total_products_no_discounts + " lei" 1341 ); 1342 } else { 1343 $("#" + htmlEl).html(value + " lei"); 1344 } 1345 } 1346 }); 1347 } 1348 } 1349 }, 1350 error: function (xhr) { 1351 console.error( 1352 "Eroare AJAX set_shipping_tax:", 1353 xhr.status, 1354 xhr.responseText 1355 ); 1356 }, 1357 }); 1358} 1359 1360function resetShippingSelection() { 1361 const selected = document.querySelector( 1362 'input[name="shipping-method"]:checked' 1363 ); 1364 if (selected) { 1365 selected.checked = false; 1366 } 1367 1368 document.querySelectorAll('label[for^="shipping-"]').forEach((label) => { 1369 label.querySelectorAll(".badge, small").forEach((el) => el.remove()); 1370 1371 const originalText = label.textContent.split("(")[0].trim(); 1372 label.innerHTML = `${originalText}`; 1373 }); 1374 1375 document 1376 .querySelectorAll('input[name="shipping-method"]') 1377 .forEach((input) => { 1378 input.removeAttribute("data-price"); 1379 }); 1380 1381 set_shipping_tax(0); 1382 1383 hasUserSelectedCourier = false; 1384} 1385 1386document 1387 .querySelector(".shipping-methods") 1388 ?.addEventListener("change", function (event) { 1389 const target = event.target; 1390 if (target && target.matches('input[name="shipping-method"]')) { 1391 const selectedInput = target; 1392 1393 const isLocker = selectedInput.id === "shipping-locker-unic"; 1394 togglePaymentMethods(isLocker); 1395 1396 const price = selectedInput.dataset.price || "0"; 1397 set_shipping_tax(price); 1398 1399 const estimatedPrice = selectedInput.dataset.estimatedPrice || ""; 1400 const estimatedPriceInput = document.getElementById( 1401 "estimatedPriceInput" 1402 ); 1403 if (estimatedPriceInput) { 1404 estimatedPriceInput.value = estimatedPrice; 1405 } 1406 } 1407 }); 1408 1409document.addEventListener("DOMContentLoaded", () => { 1410 document.querySelectorAll('input[name="payment-method"]').forEach((el) => { 1411 el.addEventListener("change", async () => { 1412 const isLockerSelected = document.querySelector( 1413 "#shipping-locker-unic" 1414 )?.checked; 1415 1416 if (!isLockerSelected) { 1417 await loadCouriers(); 1418 } 1419 1420 await updateCourierPrices(); 1421 1422 const selectedInput = document.querySelector( 1423 'input[name="shipping-method"]:checked' 1424 ); 1425 if (selectedInput && selectedInput.dataset.price) { 1426 set_shipping_tax(selectedInput.dataset.price); 1427 } 1428 }); 1429 }); 1430 1431 document.addEventListener("change", function (e) { 1432 if (e.target && e.target.matches('input[name="shipping-method"]')) { 1433 hasUserSelectedCourier = true; 1434 } 1435 });
1436 document 1437 .querySelector("#sectorInput") 1438 ?.addEventListener("change", async () => { 1439 await updateCourierPrices(); 1440 const selectedInput = document.querySelector( 1441 'input[name="shipping-method"]:checked' 1442 ); 1443 if (selectedInput && selectedInput.dataset.price) { 1444 set_shipping_tax(selectedInput.dataset.price); 1445 } 1446 }); 1447 1448 document 1449 .querySelector("#countyInput") 1450 ?.addEventListener("change", async () => { 1451 await loadCouriers(); 1452 hasUserSelectedCourier = false; 1453 await updateCourierPrices(); 1454 }); 1455 1456 document 1457 .querySelector("#localityInput") 1458 ?.addEventListener("change", async () => { 1459 await loadCouriers(); 1460 hasUserSelectedCourier = false; 1461 await updateCourierPrices(); 1462 }); 1463 1464 document 1465 .querySelector("#countyInputShipping") 1466 ?.addEventListener("change", async () => { 1467 await loadCouriers(); 1468 hasUserSelectedCourier = false; 1469 await updateCourierPrices(); 1470 }); 1471 1472 document 1473 .querySelector("#localityInputShipping") 1474 ?.addEventListener("change", async () => { 1475 await loadCouriers(); 1476 hasUserSelectedCourier = false; 1477 await updateCourierPrices(); 1478 }); 1479 1480 document 1481 .querySelector("#isDifferentShipping") 1482 ?.addEventListener("change", async () => { 1483 await loadCouriers(); 1484 hasUserSelectedCourier = false; 1485 await updateCourierPrices(); 1486 }); 1487 1488 document 1489 .querySelector("#localityInputShipping") 1490 ?.addEventListener("blur", function () { 1491 this.dispatchEvent(new Event("change")); 1492 }); 1493});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.