11 gru 2020

Jak najprościej do WooCommerce dodać InPost

Wordpress + WooCommerce
Jest to najprostszy sposób na dodanie paczkomatów InPost do sklepu - Woocommerce. Nie użyjemy tutaj żadnego dedykowanego pluginu. Przykład ten dodaje jedynie pole gdzie możemy wybrać, czy wyszukać nasz paczkomat. Dodamy te dane do zamówienia ale ich nie przeliczymy. Informacje o paczkomacie pojawiają się również w zamówieniu oraz mailu który jest wysyłany do właściciela sklepu.

Najpierw zaczniemy od wstawienia pola do formularza.
wstaw paczkomat

Ja do tego celu użyłem wtyczki, oczywiście można to pole dodać ręcznie ale wolałem użyć wtyczki bo za pomocą niej można w łatwy sposób modyfikować już istniejące elementy formularza. Wtyczka ta to woo-checkout-field-editor-pro. W zupełności wystarczy podstawowa wersja i nie trzeba kupować wersji pro.

Wtyczka po instalacji i przejściu do konfiguracji wygląda tak jak poniżej.
formularz dodawania pola
Aby dodać pole wystarczy kliknąć w przycisk + Add field. Pojawi się okno jak poniżej:
okno tworzenia elementu formularza
Najpierw typ formularza, nas interesuje "text", następnie ustawiamy "Name" jest to id pola text i to pole jest najważniejsze bo na podstawie tego id będziemy przekazywać informacje z mapy do tego pola.
W związku z tym że jest to pole opcjonalne, to wyłączyłem "Required".
Można w tym miejscu włączyć, dodanie informacji o InPost w wysyłanym mailu a także w podsumowaniu powiadomienia ale w związku z tym że niezbyt ładnie prezentuje się tekst w tych miejscach wolałem samodzielnie dodać te informacje i odpowiednio ostylować.
Po kliknięciu w "Save" pojawia się dodatkowe pole "InPost" w formularzu przy zamówieniu.

Dodanie tego pola skutkuje również tym że w zamówieniu, w sekcji własne pola pojawi się nasz inpost.
inpost własne pola

Teraz przechodzimy do najważniejszej chyba części a mianowicie dodanie skryptu który po kliknięciu w pole input otworzy popup z mapą oraz wyszukiwarką paczkomatów.

Najlepszym sposobem na modyfikacje jest postawienie lokalnie serwisu na dokerze z bazą danych + wordpress + woocommerce ze wszystkimi pluginami itd. Najłatwiej się zmienia lokalnie ale jeżeli nie masz takiej możliwości to wystarczy że zmodyfikujesz plik functions.php.
Jak go znaleźć, w panelu administracyjnym worpressa wystarczy że wejdziesz do "Wygląd → Edytor motywu → functions.php" klikamy i otwiera nam się okno z całą zawartością. Na samym końcu dopisujemy to co poniżej:

<?php
/* do sekcji head dodajemy cały poniższy kod */
add_action('wp_head', 'inpost_script_javascript', 9);
function inpost_script_javascript()
{
  /* sprawdzamy czy jesteśmy na stronie z zamówieniem */
  if (is_checkout()) {
?>

// najpierw dodajemy skrypt z inpostu
<script src="https://geowidget.easypack24.net/js/sdk-for-javascript.js"></script>
<script type="text/javascript">
function createOutput(e) {
  /* 
    pobieramy id naszego pola które ustawialiśmy w formularzu
    i wstawiamy do pola nasz adres który otrzymujemy od inpostu
  */
  var n = document.getElementById("inpost_place"),
    t = e.address,
    o = t.line1 + ", " + t.line2 + ", " + e.name;
  n.value = o
};
/*
  w miejscu uruchamiamy funkcję która otwiera popup,
  a także wywołujemy funkcję zamykająca popup
  na oficjalnej stornie inpost jest metoda do zamknięcia
  okna ale jest zbugowana
  a za pomocą tej funkcji createOutput wstawiamy dane 
  do pola inpost
*/
function openModal() {
  easyPack.modalMap(function(e, n) {
    document.getElementById("widget-modal").addEventListener("click", closeModalPopup), createOutput(e)
  }, {
    width: 500,
    height: 600
  })
};
// funkcja chowająca popup
function closeModalPopup() {
  var e = document.getElementById("widget-modal");
  e.parentNode.style.display = "none", e.removeEventListener("click", closeModalPopup)
}

window.easyPackAsyncInit = function() {
  easyPack.init({
    defaultLocale: "pl",
    mapType: "osm",
    searchType: "osm",
    points: {
      types: ["parcel_locker"]
    },
    map: {
      initialTypes: ["parcel_locker"]
    }
  })
};

// kliknięcie w pole inpost wywołuje uruchomienie funkcji openModal()
window.addEventListener("DOMContentLoaded", function() {
  document.getElementById("inpost_place").addEventListener("click", function() {
    openModal()
  })
});
</script>

<!-- na koniec oddajemy style które odpowiadają za wygląd popapu -->
<link rel="stylesheet" href="https://geowidget.easypack24.net/css/easypack.css" />
<?php }
}

Aby sprawdzić czy po kliknięciu wszystko działa, wystarczy że dodamy coś do koszyka i przejdziemy cały proces zamawiania. Klikamy na pole inpost i powinna pojawić się nam mapa w popupie.
A tak powinno to wyglądać po kliknięciu w pole Wybierz paczkomat
kliknięcie w pole input

Wyszukujemy nasz paczkomat.
wyszukujemy nasz paczkomat

Kliknięcie w "Wybierz" powinno skutkować tym że najważniejsze dane o adresie paczkomatu powinny zostać "wklejone" do pola "Wybierz paczkomat", a także powinien zamknąć się popup z mapą.
wybrany paczkomat inpost

Pod tym adresem znajdziesz całą dokumentacje, z różnymi metodami wyświetlania mapy z paczkomatami.

Teraz przydałoby się wstawienie informacji o paczkomacie w podsumowaniu zamówienia.
podsumowanie zamówienia

Dodajemy znowu do "functions.php" trochę php 😉

add_action('woocommerce_thankyou', 'inpost_display_order_data', 20);
add_action('woocommerce_view_order', 'inpost_display_order_data', 20);
function inpost_display_order_data($order_id)
{
  $custom_fields_inpost = get_post_meta($order_id, 'inpost_place', true);
  if (empty($custom_fields_inpost)) {
      return;
  }
  echo "<h2>InPost</h2><table class='shop_table shop_table_responsive additional_info'><tbody><tr><th>Wybrany paczkomat:</th><td>" . 
  $custom_fields_inpost . "</td></tr></tbody></table>";
}

Tutaj również używamy naszego id [inpost_place].
Zapomniałem wcześniej wspomnieć o tym że musimy za każdym razem sprawdzać czy pole inpost jest wypełnione. Oczywiście nie musimy tego robić jeżeli pole jest wymagane, ale tak na wszelki wypadek lepiej to robić za każdym razem 😉

Sprawdzamy czy nasze informacje pojawiły się w podsumowaniu zamówienia jeżeli tak to przechodzimy do dalszej modyfikacji. Tym razem będziemy dodawać informacje w zamówieniu a dokładnie zamówieniu w panelu administratora.

Tutaj również modyfikujemy plik "functions.php". Wspomnę tylko o tym, że najlepiej ten plik nie modyfikować wklejając cały kod, a jedynie dla każdej zmiany robimy osobny plik i dodajemy do pliku functions.

/**
 * InPost
 */
require get_template_directory() . '/inc/inpost.php';

W taki sposób mamy porządek w kodzie, oczywiście jeżeli nie mamy dostępu do plików to dodajemy tak jak poniżej bezpośrednio w pliku functions.

function custom_checkout_field_display_admin_order_meta($order)
{
  $custom_fields_inpost = get_post_meta($order->get_id(), 'inpost_place', true);
  if (empty($custom_fields_inpost)) {
      return;
  }
  echo '<p><strong>InPost:</strong> <br />' . $custom_fields_inpost . '</>';
}
add_action('woocommerce_admin_order_data_after_billing_address', 'custom_checkout_field_display_admin_order_meta', 10, 1);

Powyższy kod powinien dodać nam do zamówienia wpis o wypełnionym polu inpost.
szczegóły zamówienia inpost

Nadszedł czas na dodanie informacji do templatu maila, który jest wysyłany za każdym razem gdy klient złoży zamówienie. Do tego posłużymy się dedykowaną wtyczką Preview E-mails for WooCommerce. Wtyczka jest bardzo prosta a wygląda tak:
podgląd emaila
W niej wybieramy "Nowe zamówienie" oraz numer zamówienia i klikamy "Submit", wtedy generuje się nam strona z podglądem formularza zamówienia.
Aby dodać informacje w mailu o paczkomacie należy oczywiście w "functions.php" dodać następną porcję php 😉

add_action('woocommerce_email_order_meta', 'add_InPost_fields_to_email_order_meta', 10, 3);
function add_InPost_fields_to_email_order_meta($order, $sent_to_admin)
{
  $inpost = get_post_meta($order->get_id(), 'inpost_place', true);
  if (empty($inpost)) {
      return;
  }
  echo '<h2>Inpost</h2><p>' . $inpost . '</p><br />';
}

Sprawdzamy ponownie podgląd maila, tylko trzeba mieć pewność że zamówienie było wypełnione z opcją inpost 😉 A tak powinno się prezentować po naszych zmianach.
podgląd maila z inpostem

To chyba tyle. Oczywiście nie jest to optymalne rozwiązanie, ale sądzę że wystarczające dla małych sklepów.