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.
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
- Pobierz archiwum
DfOdooConnector-v1.0.0.zipze swojego konta klienta. - W administracji Shopware: Rozszerzenia → Moje rozszerzenia → Prześlij rozszerzenie.
- Wybierz ZIP, a następnie kliknij Zainstaluj.
- 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
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.
- W Odoo: Ustawienia → Użytkownicy i firmy → Użytkownicy.
- Utwórz użytkownika o nazwie na przykład
Shopware Bridge. - 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
- Zaloguj się do Odoo tym nowym użytkownikiem.
- Kliknij awatar w prawym górnym rogu → Preferencje.
- Zakładka Konto → Klucze API → Nowy klucz API.
- Nadaj opisową nazwę (na przykład
Shopware Connector) i skopiuj wygenerowaną wartość.
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.
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↔ Odoodefault_code. - ID Odoo: opiera się wyłącznie na trwałej tabeli mapowania. Przydatne, jeśli Twoje SKU bywają zmienne.
- Kod kreskowy (EAN): Shopware
ean↔ Odoobarcode. 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.
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 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 ztype='delivery'. - VAT wewnątrzwspólnotowym: przenoszonym do pola
vatpartnera 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_idrozwiązanym przez mapowanie klienta.order_linew składni krotek Odoo:[0, 0, {name, product_uom_qty, price_unit, product_id}].- Dodatkową linią na koszty transportu, jeśli
totalPricewysyłki jest większe od zera. company_id,warehouse_id,pricelist_idzgodnie ze skonfigurowanymi wartościami domyślnymi.
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_confirmnasale.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 typuinvoice.
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
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.
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_mappingidf_odoo_logsą 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 jakodiscountOdoo. - Metody płatności i wysyłki Shopware nie są mapowane na
journal_idOdoo: 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.