Produkty
W Odoo określenie „product” odnosi się zarówno do produktów własnych jak i kupowanych towarów. Podstawowe modele opisujące produkty to product.template i product.product. Można o nich myśleć jak o klasach (template) i obiektach klasy (product). Template to „szablon do stworzenia produktu”. Produkt jest więc wariantem klasy produktów (https://www.odoo.com/documentation/user/9.0/inventory/settings/products/variants.html) .
Jednemu wierszowi product.template odpowiada jeden wiersz tabeli product.product. Nie ma zatem możliwości usunięcia produktów z pozostawieniem ich wzorca. Z punktu widzenia bazy danych ten podział na dwie tabele jest nieco sztuczny. Jeśli usuniemy wiersze tylko z tabeli product.product – pojawi się pewna niespójność: lista produktów jest tworzona na podstawie product.template ale wybór produktu przy sprzedaży/zakupie następuje z tabeli product.product. Można to poprawić dokonując w Odoo archwiwizacji i przywrócenia produktu (po prywróceniu rekord w tabeli product pojawia się na nowo).
Jeśli ustawimy (Sprzedaż – Ustawienia) możliwość tworzenia produktów wariantami (na przykład różne kolory) – dodatkowo wykorzystywane będą modele product.attribute (atrybuty) oraz product.attribute.values (wartości atrybutów).
Z każdym atrybutem jest związana cena. W module sprzedaży internetowej możemy ustawić warianty atrybutu (dodatkowe pole do product.attribute) określające sposób wyboru opcji: Radio (jeden z wielu), Wybierz i Ukryty. Wartością domyślną jest Radio. Do zdefiniowania powiązań jeden do wielu (atrybut z wariantami produktu) służy model product_attribute_line.
Obrót magazynowy
Aby powiązać zakupy z magazynami, konieczne jest zainstalowanie modułu purchase (Zakupy). Wówczas można wystawiać fakturę zakupu do zamówienia. Powoduje to powstanie obrotów magazynowych stock.move. Podobnie ze sprzedażą (moduł sale_stock). Tyle, że tu najpierw wystawiamy sprzedaż a z tego dokumentu powstaje faktura i dokument obrotu magazynowego stock.move. Kolekcji pozycji stock.move odpowiada element ze stock.picking.
Obroty na magazynach:
SELECT m.product_id produkt, m.warehouse_id magazyn,
m.product_qty ilosc,
pt.code
FROM stock_move AS m
LEFT OUTER JOIN stock_picking_type AS pt ON
pt.id=m.picking_type_id;
Zakupy i wydania (bez przesunięć wewnętrznych i operacji MRP):
SELECT m.product_id produkt, m.warehouse_id magazyn,
(select sum(m1.product_qty) FROM stock_move AS m1
LEFT OUTER JOIN stock_picking_type AS pt1 ON
pt1.id=m1.picking_type_id
WHERE pt1.code='incoming'
AND m.product_id=m1.product_id
AND m.warehouse_id=m1.warehouse_id) przychod,
(select sum(m2.product_qty)
FROM stock_move AS m2
LEFT OUTER JOIN stock_picking_type AS pt2 ON
pt2.id=m2.picking_type_id
WHERE pt2.code='outgoing'
AND m.product_id=m2.product_id
AND m.warehouse_id=m2.warehouse_id) rozchod
FROM stock_move as m
GROUP BY m.product_id, m.warehouse_id;
Wyliczenie stanu z uwzględnieniem wszystkich aspektów nie jest proste - najlepiej sięgnąć po funkcję w Pythonie:
product = self.env['product.product']
for p in product.search([]):
print '%s: %s' % (p.name,p.qty_available)
Jednostki miary dla produktów (Unit of Measure) znajdują się w modelu product.uom.