Wstęp
W Odoo modele określają strukturę i sposób przechowywania danych w bazie. Wszystkie elementy operacyjne — zamówienia sprzedaży, zapasy, produkty — są reprezentowane przez rekordy w konkretnych modelach.
Zrozumienie modeli Odoo jest kluczowe zarówno dla programistów, jak i konsultantów funkcjonalnych. To właśnie modele definiują pola, powiązania między rekordami oraz logikę biznesową, na której opiera się cały system.
Ten tekst koncentruje się na jednym z kluczowych modeli: product.product. Jeśli konfigurujesz katalog produktów, tworzysz integracje czy rozwijasz moduły rozszerzające sprzedaż lub magazyn, prędzej czy później trafisz na ten model.
Czym jest model product.product
Model product.product opisuje konkretne warianty produktów — rzeczywiste jednostki handlowe pojawiające się w zamówieniach, dostawach i ruchach magazynowych.
W Odoo rozdziela się wspólne cechy produktu i jego warianty. product.template przechowuje cechy wspólne, a product.product reprezentuje poszczególne kombinacje atrybutów. Dla prostego produktu bez wariantów mamy jeden wariant na szablon; dla produktu z wariantami (np. koszulka — rozmiar/kolor) każdy wariant to osobny rekord product.product.
Model znajduje się w module product i jest wykorzystywany przez moduły sprzedaży, zakupu, magazynu oraz sklep internetowy. Gdy dodajesz pozycję do oferty lub przyjmujesz towar, operujesz na rekordach product.product.
Mechanizm użyty w Odoo pozwala przejmować część pól ze szablonu do wariantu przez dziedziczenie delegacyjne. Dzięki temu dane wspólne trzyma się w jednym miejscu, a indywidualne cechy wariantów można nadpisywać.
Najważniejsze pola w modelu
Poniżej omówione są kluczowe pola modelu product.product — znajomość ich znaczenia ułatwia pracę z wariantami i integracjami.
1. name
Typ: Char. Nazwa wariantu, widoczna na listach i dokumentach. Dla produktów bez wariantów równa się nazwie szablonu; przy wariantach często zawiera dodatkowe wartości atrybutów (np. „Koszulka — niebieska / M”).
2. product_tmpl_id
Typ: Many2one (product.template). Łączy wariant ze szablonem. To podstawowe powiązanie — każdy wariant należy do jednego template. Stosuj je zawsze, gdy musisz odwołać się do cech wspólnych produktu.
3. default_code
Typ: Char. Wewnętrzny kod lub SKU. Przydatny przy wyszukiwaniu, skanowaniu i integracjach zewnętrznych — każdy wariant może mieć własny kod.
4. barcode
Typ: Char. Kod kreskowy (EAN, UPC itp.). Używany w POS i magazynie przy skanowaniu. Powinien być unikalny, jeśli jest ustawiony.
5. create_date
Typ: Datetime. Data utworzenia rekordu. Pole automatyczne, przydatne w audycie i raportach.
6. write_date
Typ: Datetime. Data ostatniej modyfikacji. Również zarządzane automatycznie — pomaga śledzić zmiany.
7. active
Typ: Boolean. Flaga archiwizacji. Gdy False, produkt jest ukryty w standardowych widokach, ale zapis historii pozostaje nietknięty.
8. type
Typ: Selection. Typ produktu: Consumable, Service lub Storable Product. Określa, czy produkt jest śledzony w magazynie, czy to usługa i jakie procesy mają do niego zastosowanie.
9. categ_id
Typ: Many2one (product.category). Kategoria produktu — istotna dla raportów, reguł cenowych i organizacji katalogu. Kategorie mogą tworzyć hierarchię.
10. list_price
Typ: Float. Cena sprzedaży domyślna, wyświetlana w ofertach. Może być nadpisana przez cennik klienta.
11. standard_price
Typ: Float. Cena zakupu/koszt. Wykorzystywana do wyceny zapasów i kalkulacji marż.
12. uom_id
Typ: Many2one (uom.uom). Jednostka miary dla sprzedaży i zapasów (szt., kg, l itp.).
13. uom_po_id
Typ: Many2one (uom.uom). Jednostka miary używana przy zakupach — może różnić się od uom_id (np. kupujemy w kartonach, sprzedajemy na sztuki).
14. description_sale
Typ: Html. Opis sprzedażowy widoczny w ofertach i fakturach — może zawierać formatowanie i szczegóły produktu.
15. description_purchase
Typ: Html. Opis używany w zamówieniach zakupu i u dostawcy — przydatny do komunikacji z vendorami.
16. sale_ok
Typ: Boolean. Czy produkt może być sprzedany. Gdy False, produkt nie pojawia się w sprzedaży i sklepie internetowym.
17. purchase_ok
Typ: Boolean. Czy produkt może być kupiony. Gdy False, nie jest dostępny do zamawiania u dostawców.
18. image_1920
Typ: Binary. Obraz produktu w pełnej rozdzielczości. Odoo tworzy też mniejsze rozmiary do wyświetlania w różnych miejscach.
19. weight
Typ: Float. Waga produktu — użyteczna przy obliczaniu kosztów wysyłki i logistyce.
20. volume
Typ: Float. Objętość produktu — ważna przy planowaniu przestrzeni magazynowej i wysyłkach volumetrycznych.
21. company_id
Typ: Many2one (res.company). W konfiguracjach wielofirmowych określa właściciela produktu i wpływa na widoczność oraz zapasy.
22. currency_id
Typ: Many2one (res.currency). Waluta używana dla list_price i standard_price — zwykle waluta firmy, cenniki mogą konwertować wartości.
23. qty_available
Typ: Float. Ilość dostępna fizycznie. Pole obliczane z quants — tylko do odczytu, kluczowe dla sprawdzania dostępności.
24. virtual_available
Typ: Float. Prognozowana ilość (stan + przychody - rozchody). Pole obliczane, pomocne przy planowaniu uzupełnień.
25. product_template_attribute_value_ids
Typ: Many2many. Powiązania z wartościami atrybutów definiującymi wariant (np. Kolor=Niebieski, Rozmiar=M). Służy do konfiguracji wariantów i filtrowania.
26. sequence
Typ: Integer. Kolejność wyświetlania — mniejsze wartości pojawiają się wyżej w listach i konfiguratorach.
27. display_name
Typ: Char. Pole obliczane łączące nazwę z wartościami atrybutów — używane w dropdownach i wyszukiwaniu.
28. responsible_id
Typ: Many2one (res.users). Osoba odpowiedzialna za produkt — wykorzystywana przy regułach zamawiania i wewnętrznym przydziale zadań.
Jak model wykorzystuje się w procesach biznesowych
1. Sprzedaż i oferty
Przy tworzeniu oferty handlowiec wybiera konkretny wariant product.product. Domyślna cena, opis sprzedażowy i jednostka miary są kopiowane do wiersza oferty; cenniki mogą modyfikować cenę. Wyświetlane są tylko produkty z aktywnym sale_ok.
2. Zakupy i dostawcy
Zamówienia zakupu i faktury dostawców odnoszą się do konkretnych wariantów. Standard_price często aktualizuje się na podstawie kosztów zakupu. Umożliwia to zamawianie w jednostkach określonych przez uom_po_id.
3. Magazyn i zapasy
Ruchy magazynowe, pickingi i quants operują na rekordach product.product. To qty_available i virtual_available decydują o dostępności. Tylko produkty typu storable są śledzone, a szybkie wyszukiwanie można robić po barcode.
4. Sklep internetowy i strona WWW
Sklep wyświetla warianty jako opcje (rozmiar, kolor). Zdjęcia, opisy i ceny pobierane są z modelu; widoczność kontroluje pole sale_ok.
5. Produkcja i MRP
BOM-y odnoszą się do konkretnych wariantów zarówno jako komponentów, jak i produktów finalnych. Typ produktu wpływa na to, czy jest planowany do produkcji, a poziomy zapasów napędzają harmonogramy produkcji.
Jak programiści rozszerzają ten model
Programiści rozszerzają product.product kilkoma sprawdzonymi podejściami, wykorzystując mechanizmy dziedziczenia i rozszerzeń Odoo.
Dziedziczenie modelu
W kodzie używasz _inherit = 'product.product', aby dodać pola, nadpisać metody lub dodać ograniczenia. Dzięki temu modyfikacje są zamknięte w module i łatwiejsze do utrzymania przy aktualizacjach. Wybieraj product.product, gdy pole dotyczy konkretnego wariantu; product.template, gdy chodzi o całą rodzinę produktów.
Dodawanie pól
W rozszerzonym modelu deklarujesz nowe pola (Char, Many2one, Boolean, Integer, Text, Selection). Zastanów się, czy pole powinno być współdzielone na poziomie template, czy specyficzne dla wariantu — np. indywidualny SKU czy nadpisany barcode trafiają do product.product.
Rozszerzenia w Pythonie
Możesz nadpisać create, write lub unlink, dodając własną logikę, ale zawsze wywołuj super(). Staraj ostrożnie się z polami obliczanymi i ich zależnościami — model product.product ma wiele pól wyliczanych przez moduły zapasów i sprzedaży.
Odoo Studio
Odoo Studio pozwala na szybkie dodawanie pól bez kodu — dobre do szybkich zmian. Jednak dla złożonej logiki i długoterminowej utrzymalności warto tworzyć moduły. API Odoo (XML-RPC/JSON-RPC) daje pełny dostęp do modelu product.product dla integracji.
Dobre praktyki
- W integracjach zewnętrznych mapuj po default_code lub barcode; utrzymuj ich unikalność i spójność.
- Ustaw właściwy typ produktu (Consumable / Storable / Service) — to decyduje o tym, które procesy i moduły będą stosowane.
- W API używaj product.product dla linii zamówień i operacji magazynowych; product.template przy operacjach dotyczących katalogu jako całości.
- Dla własnych pól stosuj prefiks x_ lub prefiks modułu, by uniknąć konfliktów z przyszłymi wersjami Odoo.
- Gdy pole dotyczy całej rodziny produktów (np. marka), dodawaj je na product.template; gdy dotyczy tylko wariantu (np. wariantowy barcode), dodawaj na product.product.
Częste błędy
- Nie dziedzicz z product.template, jeśli potrzebujesz zachowania per-wariant — wybierz product.product, gdy logika ma działać na poziomie pojedynczego wariantu.
- Tworzenie wariantów ręcznie zamiast przez konfigurator może prowadzić do niespójności — dla produktów z wieloma kombinacjami lepiej używać konfiguratora produktów.
- Zapominanie o ustawieniu sale_ok lub purchase_ok — w niektórych konfiguracjach produkty domyślnie bywają ukryte w sprzedaży lub zakupach.
- Nadpisywanie metod core bez wywołania super() — to częsty błąd, który może łamać zachowanie innych modułów lub utrudniać aktualizacje.
- Używanie product.product w filtrach tam, gdzie pasowałby product.template — np. filtrowanie po kategorii powinno często odnosić się do template, by objąć całą rodzinę produktów.
Podsumowanie
Model product.product jest centralnym elementem architektury produktowej w Odoo. Reprezentuje rzeczywiste, handlowe jednostki; zrozumienie jego pól i relacji z product.template ułatwia konfigurację, rozszerzanie i integrację systemu.
Niezależnie od roli — konsultant przygotowujący katalog czy deweloper tworzący moduły — dobra znajomość product.product oszczędza czas i minimalizuje błędy.
Potrzebujesz pomocy przy wdrożeniu Odoo?
Dasolo wspiera firmy we wdrożeniach, dostosowaniach i optymalizacji Odoo. Specjalizujemy się w integracjach API i rozwoju modułów, ze szczególnym naciskiem na praktyczne wykorzystanie modeli i architektury danych.
Jeśli potrzebujesz wsparcia przy wdrożeniu Odoo, tworzeniu modułów lub integracji — chętnie pomożemy. Umów demo aby omówić Twój projekt.