SW Shopware 6 Średnio zaawansowany

DataFirefly Odoo Connector: przewodnik instalacji i konfiguracji

Połącz Shopware 6.6 / 6.7 z Odoo 12 → 18 przez natywne XML-RPC. Instalacja, konfiguracja klucza API, kierunki synchronizacji, zadania cykliczne i rozwiązywanie problemów.

Zaktualizowano Wersja modułu 1.0.0

Ten przewodnik obejmuje instalację, konfigurację i eksploatację pluginu DataFirefly Odoo Connector dla Shopware 6.6 i 6.7. Na koniec Twój sklep będzie synchronizował produkty, stany magazynowe, klientów i zamówienia z Twoją instancją Odoo przez natywne XML-RPC, bez żadnej zewnętrznej zależności i bez dopłat za API firm trzecich.

Wprowadzenie

Plugin buduje dwukierunkowy most między Shopware a Odoo, mówiąc bezpośrednio protokołem XML-RPC Odoo (stabilnym od wersji 8). Żadnego modułu do instalacji po stronie Odoo, żadnego płatnego middleware, żadnego pośredniczącego SaaS.

Encja Odoo → Shopware (pull) Shopware → Odoo (push)
Produkty (product.template)
Stany magazynowe (qty_available / free_qty)
Kategorie (product.category)
Klienci (res.partner) ✅ z adresami podrzędnymi
Zamówienia (sale.order) ✅ z opcjonalnym potwierdzeniem i fakturą

Wymagania

  • Shopware 6.6.x albo 6.7.x (wszystkie wersje pomocnicze).
  • PHP 8.2, 8.3 albo 8.4.
  • Rozszerzenia PHP: curl, xml, simplexml (obecne domyślnie u niemal wszystkich hostingów).
  • Odoo 12, 13, 14, 15, 16, 17 albo 18, w wersji Community albo Enterprise. Odoo.sh, Odoo Online (SaaS) i instancje self-hosted działają identycznie.
  • Użytkownik Odoo dedykowany do API (zalecane) z prawami odczytu i zapisu na używanych modelach (product.template, product.product, res.partner, sale.order, stock.warehouse, product.category, res.country, account.tax).

Instalacja

Przez przesłanie w administracji

  1. Pobierz archiwum DfOdooConnector-v1.0.0.zip ze swojego konta klienta.
  2. W administracji Shopware: Rozszerzenia → Moje rozszerzenia → Prześlij rozszerzenie.
  3. Wybierz ZIP, a następnie kliknij Zainstaluj.
  4. Aktywuj rozszerzenie, klikając przełącznik.

Przez konsolę SSH

cd /path/to/shopware
cp DfOdooConnector-v1.0.0.zip custom/plugins/
cd custom/plugins && unzip DfOdooConnector-v1.0.0.zip
sudo -u www-data setsid php bin/console plugin:refresh
sudo -u www-data setsid php bin/console plugin:install --activate DfOdooConnector
sudo -u www-data setsid php bin/console cache:clear

Rekompilacja administracji, aby załadować moduł Vue 3:

sudo -u www-data setsid php bin/build-administration.sh
Uwaga: instalacja tworzy dwie tabele: df_odoo_mapping (trwałe powiązania Shopware ↔ Odoo) i df_odoo_log (dziennik operacji). Żadna istniejąca tabela nie jest modyfikowana.

Konfiguracja po stronie Odoo

Utworzenie dedykowanego użytkownika

Zdecydowanie zalecamy utworzenie użytkownika Odoo dedykowanego integracji, zamiast używania osobistego konta administratora. Pozwala to precyzyjnie audytować działania konektora i odbierać mu dostęp niezależnie.

  1. W Odoo: Ustawienia → Użytkownicy i firmy → Użytkownicy.
  2. Utwórz użytkownika o nazwie na przykład Shopware Bridge.
  3. Nadaj mu wymagane uprawnienia: Magazyn (użytkownik), Sprzedaż (administrator dokumentów), Fakturowanie (użytkownik, jeśli włączasz tworzenie faktur), Kontakty (użytkownik).

Wygenerowanie klucza API

  1. Zaloguj się do Odoo tym nowym użytkownikiem.
  2. Kliknij awatar w prawym górnym rogu → Preferencje.
  3. Zakładka KontoKlucze APINowy klucz API.
  4. Nadaj opisową nazwę (na przykład Shopware Connector) i skopiuj wygenerowaną wartość.
Ważne: klucz API wyświetla się tylko raz. Jeśli go zgubisz, trzeba będzie wygenerować nowy. Zapisz go w menedżerze haseł przed zamknięciem okna.

Konfiguracja po stronie Shopware

Uzupełnienie połączenia

W administracji Shopware: Ustawienia → System → Pluginy → Df Odoo → Ustawienia albo bezpośrednio przez menu boczne Ustawienia → Df Odoo → Ustawienia.

  • Adres URL Odoo: pełny adres Twojej instancji bez końcowego ukośnika, na przykład https://mojekonto.odoo.com.
  • Nazwa bazy: widoczna w adresie Odoo po ?db= albo w Ustawienia → Techniczne → Baza danych.
  • Użytkownik: login dedykowanego użytkownika, zwykle jego adres e-mail.
  • Klucz API Odoo: wartość skopiowana w poprzednim kroku.
  • Limit czasu: domyślnie 30 sekund, wystarczające w większości przypadków.

Test połączenia

Kliknij przycisk Testuj połączenie w prawym górnym rogu. Jeśli wszystko jest poprawne, zielone powiadomienie pokazuje wersję Odoo i identyfikator użytkownika (uid). Jeśli połączenie się nie powiedzie, komunikat błędu zwrócony przez Odoo jest wyświetlany bez zmian.

Wskazówka: test połączenia można też wywołać z konsoli, aby oskryptować weryfikację:
curl -X POST -H "Authorization: Bearer ADMIN_TOKEN" https://twojshopware.com/api/_action/df-odoo/test-connection

Kierunki synchronizacji

Każda encja ma niezależny selektor: wyłączone, Odoo → Shopware (pull), Shopware → Odoo (push) albo dwukierunkowo. Wartości domyślne to:

  • Produkty: dwukierunkowo
  • Stany magazynowe: Odoo → Shopware (Odoo jest źródłem prawdy)
  • Klienci: Shopware → Odoo
  • Zamówienia: Shopware → Odoo
  • Kategorie: wyłączone (do włączenia ręcznie, zależnie od Twojej organizacji)

Synchronizacja produktów

Strategie dopasowania

Do skonfigurowania są trzy strategie:

  • SKU (zalecane): Shopware productNumber ↔ Odoo default_code.
  • ID Odoo: opiera się wyłącznie na trwałej tabeli mapowania. Przydatne, jeśli Twoje SKU bywają zmienne.
  • Kod kreskowy (EAN): Shopware ean ↔ Odoo barcode. Wymaga uzupełnionych EAN po obu stronach.

Po powiązaniu dwa produkty pozostają sparowane przez tabelę df_odoo_mapping, nawet jeśli SKU później się zmieni.

Pull z Odoo

Zadanie cykliczne czyta rekordy product.template zmodyfikowane od ostatniego uruchomienia (pole write_date) i tworzy albo aktualizuje odpowiadające produkty po stronie Shopware. Synchronizowane pola to: nazwa, SKU, cena sprzedaży, cena zakupu, krótki opis, długi opis, waga, objętość, status aktywności, kategoria, podatki.

Push do Odoo

Aktywne produkty główne Shopware (z parentId = null) są wysyłane do Odoo jako product.template typu product (artykuł magazynowy). Warianty Shopware są przekazywane pod ich produktem nadrzędnym.

Wykrywanie zmian: przed każdym zapisem hash SHA-1 treści jest porównywany z tym zapamiętanym w mapowaniu. Jeśli nic się nie zmieniło, zapis jest pomijany, a operacja logowana jako skipped. To zapobiega zapychaniu Odoo przy kolejnych cronach.

Synchronizacja stanów magazynowych

Stan magazynowy jest zawsze pobierany z Odoo (nigdy odwrotnie). Co 15 minut zadanie cykliczne czyta warianty product.product partiami po 100 według identyfikatora nadrzędnego szablonu, agreguje qty_available albo free_qty (konfigurowalne globalnie), a następnie aktualizuje pole stock każdego produktu Shopware jednym zapytaniem DAL.

qty_available a free_qty: qty_available odzwierciedla fizyczny stan obecny w magazynie. free_qty odejmuje ilości już zarezerwowane na niezrealizowanych zamówieniach. free_qty jest zwykle lepszym wyborem dla sklepu, bo zapobiega nadsprzedaży.

Synchronizacja kategorii

Domyślnie wyłączona. Włącz ją, jeśli Twoje drzewo kategorii ma pozostawać zsynchronizowane z drzewem Odoo. Hierarchia parent_id jest zachowywana po obu stronach. Podobnie jak przy produktach, hash treści zapobiega zbędnym zapisom.

Synchronizacja klientów

Klienci Shopware są wysyłani jako res.partner Odoo wraz z:

  • Deduplikacją po e-mailu: przed każdym utworzeniem wyszukiwany jest istniejący partner o tym samym e-mailu i parent_id = false. Jeśli istnieje, jest aktualizowany zamiast duplikowany.
  • company_type: company, jeśli pole firmy w adresie rozliczeniowym jest uzupełnione, w przeciwnym razie person.
  • Adresami podrzędnymi: domyślny adres rozliczeniowy powstaje jako partner podrzędny z type='invoice', adres dostawy jako partner podrzędny z type='delivery'.
  • VAT wewnątrzwspólnotowym: przenoszonym do pola vat partnera głównego.
  • Krajem i regionem: rozwiązywanymi po kodzie ISO, z cache w pamięci w obrębie żądania.

Synchronizacja zamówień

W czasie rzeczywistym przy checkoucie

Jeśli opcja Wysyłaj każde zamówienie zaraz po zatwierdzeniu jest włączona, event subscriber nasłuchuje CheckoutOrderPlacedEvent i natychmiast po finalizacji checkoutu wysyła zamówienie do Odoo. Klient jest w razie potrzeby tworzony w Odoo (przez synchronizację klientów), a następnie zamówienie powstaje jako sale.order z:

  • partner_id rozwiązanym przez mapowanie klienta.
  • order_line w składni krotek Odoo: [0, 0, {name, product_uom_qty, price_unit, product_id}].
  • Dodatkową linią na koszty transportu, jeśli totalPrice wysyłki jest większe od zera.
  • company_id, warehouse_id, pricelist_id zgodnie ze skonfigurowanymi wartościami domyślnymi.
Checkout nigdy nie jest blokowany: jeśli Odoo jest niedostępne, błąd trafia do df_odoo_log, a zamówienie zostanie podjęte w ciągu 10 minut przez zadanie cykliczne df_odoo.order_sync, które skanuje zamówienia z ostatnich 7 dni jeszcze niezmapowane.

Filtr statusu

Filtr Status zamówień pozwala zawęzić wysyłane zamówienia:

  • Wszystkie: wysyłane jest każde zatwierdzone zamówienie (zalecane w B2C z płatnością natychmiastową).
  • Tylko opłacone: wysyłane są wyłącznie zamówienia o statusie płatności paid. Zapobiega przekazywaniu porzuconych koszyków z płatnością ręczną.
  • Opłacone albo wysłane: dokłada do powyższych zamówienia wysłane przed opłaceniem (B2B z terminami).

Automatyczne potwierdzenie i faktura

Dwie opcje sterują tym, co dzieje się po stronie Odoo po utworzeniu zamówienia:

  • Potwierdź zamówienie: wywołuje action_confirm na sale.order, które przechodzi wtedy od razu w stan zamówienie potwierdzone zamiast pozostawać ofertą.
  • Utwórz fakturę: wywołuje _create_invoices, aby natychmiast wygenerować zatwierdzoną fakturę. Identyfikator utworzonej faktury jest zapamiętywany jako mapowanie typu invoice.

Wiele sales channels

Wszystkie ustawienia pluginu można nadpisać per kanał sprzedaży. U góry strony Ustawienia natywny selektor Shopware pozwala przełączać się między Wszystkimi kanałami a konkretnym kanałem.

Typowe zastosowania:

  • Kanał B2C wysyłający do głównego Odoo i kanał B2B wysyłający do odrębnego Odoo.
  • Kanał produkcyjny z kierunkiem push i kanał stagingowy z kierunkiem wyłączonym.
  • Różne identyfikatory Odoo (warehouse, sales team, pricelist) zależnie od kanału.

Zadania cykliczne

Nazwa wewnętrzna Częstotliwość Działanie
df_odoo.product_sync 1 godzina Pull, a następnie push produktów zgodnie ze skonfigurowanym kierunkiem. Pull analizuje wyłącznie karty zmodyfikowane od -2 h.
df_odoo.stock_sync 15 minut Pull stanów magazynowych z Odoo dla wszystkich już zmapowanych produktów.
df_odoo.customer_sync 1 godzina Push aktywnych klientów jeszcze niezmapowanych (maks. 100 na wykonanie).
df_odoo.order_sync 10 minut Push zamówień z ostatnich 7 dni jeszcze niezmapowanych (maks. 50 na wykonanie).

Wymuszenie wykonania zadania z konsoli:

sudo -u www-data setsid php bin/console scheduled-task:run-single df_odoo.product_sync
Worker Shopware: aby zadania cykliczne uruchamiały się automatycznie, musi działać worker messengera Shopware (cron messenger:consume albo zadanie systemd). Sprawdź w Ustawienia → System → Kolejka, czy scheduled_task jest regularnie konsumowane.

Moduł administracji

W Ustawienia → Pluginy pojawia się sekcja Df Odoo z czterema stronami.

Pulpit

Liczniki na żywo (aktywne mapowania per encja, aktywność z ostatnich 24 h per status), przyciski ręcznej synchronizacji per encja (pull i push), pasek stanu połączenia, lista ostatnich błędów i skróty do pozostałych stron.

Ustawienia

Kompletny formularz z selektorem kanału sprzedaży. Przyciski Testuj połączenie i Zapisz na pasku akcji.

Dziennik

Wszystkie operacje są zapisywane w df_odoo_log wraz ze statusem (success, error, warning, skipped), kierunkiem, daną encją, czasem trwania w milisekundach i pełnym komunikatem. Filtry łączone po statusie, typie encji i kierunku. Stronicowanie po stronie serwera.

Tryb debug: operacje skipped trafiają do dziennika tylko wtedy, gdy w ustawieniach włączono tryb debug. Używaj go doraźnie do diagnozowania zachowania i wyłączaj w produkcji, aby nie zapchać tabeli.

Powiązania

Widok odczytu tabeli df_odoo_mapping z wyszukiwaniem, filtrem po typie encji i sortowaniem po dacie ostatniej synchronizacji. Praktyczny do sprawdzenia, czy dany produkt jest zmapowany do oczekiwanego ID Odoo.

REST API administracji

Wszystkie endpointy wymagają standardowego uwierzytelnienia administracji (Bearer token).

Metoda Endpoint Parametry
POST /api/_action/df-odoo/test-connection salesChannelId (opcjonalny)
POST /api/_action/df-odoo/sync/products direction=pull|push, salesChannelId
POST /api/_action/df-odoo/sync/stock salesChannelId
POST /api/_action/df-odoo/sync/customers salesChannelId
POST /api/_action/df-odoo/sync/orders salesChannelId, limit (1-500)
POST /api/_action/df-odoo/sync/categories direction=pull|push
GET /api/_action/df-odoo/stats
GET /api/_action/df-odoo/logs status, entityType, direction, page, perPage

Przykład wywołania wymuszającego push produktów:

curl -X POST 
  -H "Authorization: Bearer ADMIN_TOKEN" 
  -d "direction=push" 
  https://twojshopware.com/api/_action/df-odoo/sync/products

Tabele i przechowywane dane

Plugin tworzy dwie tabele MySQL:

  • df_odoo_mapping: trwałe powiązania (identyfikator Shopware ↔ identyfikator Odoo) z hashem synchronizacji i opcjonalnym payloadem. Wiersz jest unikalny na parze (typ encji, identyfikator Shopware) oraz (typ encji, identyfikator Odoo).
  • df_odoo_log: dziennik operacji ze statusem, czasem trwania, komunikatem, payloadem i identyfikatorem kanału sprzedaży.

Żadna standardowa tabela Shopware nie jest modyfikowana.

Odinstalowanie

Z administracji: Rozszerzenia → Moje rozszerzenia → Df Odoo → Odinstaluj.

Okno dialogowe proponuje dwie opcje:

  • Zachowaj dane użytkownika zaznaczone: tabele df_odoo_mapping i df_odoo_log są zachowywane, podobnie jak ustawienia systemowe. Praktyczne przy późniejszej ponownej instalacji.
  • Zachowaj dane użytkownika odznaczone: obie tabele są usuwane (DROP TABLE) przy odinstalowaniu. Instancja Odoo nigdy nie jest ruszana.

Rozwiązywanie problemów

“Niekompletna konfiguracja Odoo” przy teście połączenia

Jedno z czterech obowiązkowych pól (adres URL, baza, użytkownik, klucz API) jest puste. Sprawdź, czy przed zapisem wybrano właściwy kanał sprzedaży.

“401 Unauthorized” albo “access denied”

Klucz API został odwołany po stronie Odoo albo użytkownik nie ma wymaganych uprawnień na docelowym modelu. Wygeneruj nowy klucz API i sprawdź uprawnienia użytkownika w Odoo (zwłaszcza Magazyn → Użytkownik i Sprzedaż → Administrator dokumentów).

“Połączenie odrzucone” albo timeout

Adres URL Odoo nie jest osiągalny z serwera Shopware. Sprawdź, czy firewall zezwala na wychodzące połączenia HTTPS do domeny Odoo. Zwiększ limit czasu, jeśli Twoja instancja Odoo odpowiada wolno.

Produkty się nie synchronizują

Sprawdź dziennik (strona Dziennik) pod kątem wpisów z błędami. Włącz tryb debug, aby logować także operacje skipped i ustalić, czy hash treści nie sprawia, że faktycznie nic się nie zmienia.

Zamówienia nie wychodzą przy checkoucie

Sprawdź, czy opcja Wysyłaj każde zamówienie zaraz po zatwierdzeniu jest zaznaczona i czy kierunek Zamówienia jest ustawiony na Shopware → Odoo. Jeśli filtr statusu jest ustawiony na Tylko opłacone, a płatność jest asynchroniczna, zamówienie wysyła zadanie cykliczne kilka minut po zaksięgowaniu.

Znane ograniczenia

  • Atrybuty wariantów Odoo (product.attribute) nie są jeszcze mapowane automatycznie. Warianty Shopware są przekazywane jako produkty nadrzędne Odoo (product.template). Warianty Odoo utworzone ręcznie pozostają poprawnie powiązane przez swój szablon nadrzędny. Natywna obsługa jest przewidziana w wersji 1.1.
  • Rabaty w liniach zamówienia są przenoszone jako skorygowane price_unit, a nie jako discount Odoo.
  • Metody płatności i wysyłki Shopware nie są mapowane na journal_id Odoo: używane są wartości domyślne Odoo.

Wsparcie

W razie pytań skontaktuj się z zespołem DataFirefly przez formularz kontaktowy na datafirefly.com. Pamiętaj, aby dołączyć eksport dziennika (strona Dziennik → przycisk eksportu w przygotowaniu) albo przynajmniej zrzut wiersza z błędem oraz dokładne wersje Shopware, PHP i Odoo.

Czy ta strona była pomocna?

Nadal utknąłeś? Napisz do wsparcia