Továbbugrás a tartalomhoz

Odoo 19 Community: termékkészletek az ajánlatban szakaszként – nyílt forráskódú Sale Product Set Layout modulunk

2026. november 2. | Odoo 19 Community | Saját fejlesztés
2026. november 2. által
Odoo 19 Community: termékkészletek az ajánlatban szakaszként – nyílt forráskódú Sale Product Set Layout modulunk

Odoo 19 Sale Product Set Layout modul: termékkészletek szakaszként az ajánlatban nyomtatási móddal, elrejtett sorokkal és fix árral

Aki az Odoóban csomagokat ad el, például egy mérőműszert tartozékokkal és szereléssel, egy munkahelyet hardverrel és beüzemeléssel, vagy több szolgáltatásból álló karbantartási csomagot, az ajánlatban egyszerre két dologra van szüksége: Az összetételnek szerepelnie kell a megrendelésben, hogy a raktár, a műszaki részleg és a számlázás tudja, mit kell szállítani. Az ügyfélnek szánt nyomtatványon viszont nem minden esetben szerepeljen minden egyes tétel minden egyes egységárral.

Az OCA sale_product_set modulja lehetővé teszi, hogy termékkészleteket (értékesítési darabjegyzékeket) egy kattintással beillesszünk egy ajánlatba. A nyomtatási képről azonban nem dönt. Erre fejlesztettük ki a Sale Product Set Layout modult (sale_product_set_layout). Az Odoo 19-hez készült, és szabad szoftverként az AGPL-3 licenc alatt ingyenesen elérhető a GitHubon:

github.com/Alex0176/odoo-sale-product-set-layout

A probléma: a termékkészletek nincsenek hatással a nyomtatási képre

Az Odoóban a termékkészlet előre elkészített terméklista mennyiségekkel. Ahelyett, hogy tíz cikket egyenként keresnénk, az ajánlatban a Készlet hozzáadása lehetőséget választjuk, és az összes sor egyszerre megjelenik. Ez időt takarít meg, és megakadályozza, hogy tételek kimaradjanak. A sale_product_set modul a következő tárolóból OCA/sale-workflow pontosan ezt teszi; maguk a készletek a product_set modulból származnak, amely a következő tárolóban található: OCA/product-attribute.

A gyakorlatban három hiányosság marad:

  • Nincs felismerhető csoportosítás. A készlet sorai laza tételekként kerülnek az ajánlatba. A beillesztés után már nem látszik, hogy mely sorok tartoznak össze, és a készlet végösszege sehol sem szerepel.
  • Nincs hatással a nyomtatványra. Néha az ügyfél minden tételt árral együtt lásson, néha csak a csomagárat, néha csak egyetlen sort. Ez készletenként vagy ügyfelenként eldöntendő kérdés, nem pedig ajánlatonként kézzel újra megoldandó feladat.
  • Az árkorrekciók csúnyák. Ha egy csomagnak fix ára van, amely eltér a listaárak összegétől, korrekciós sorra van szükség. Ez a számításba tartozik, de nem feltétlenül az ügyfél papírjára.

Az Odoo 19 tartalmazza az építőelemeket a tiszta megoldáshoz: az ajánlatsorokban szakaszok és alszakaszok az Árak elrejtése és az Összetétel elrejtése beállításokkal (collapse_prices és collapse_composition mezők). A modul a termékkészletet ezekkel a szabványos beállításokkal köti össze ahelyett, hogy saját nyomtatási formátumot találna ki.

Mit csinál a modul

  1. Készlet beillesztése szakaszként. A Készlet hozzáadása varázsló egy szakaszsort hoz létre a készlet nevével, például 2 × Messkit Standard, és alá helyezi a készlet sorait. A készleten belüli szakaszok alszakaszokká válnak.
  2. Nyomtatási mód készletenként. A készletben egyszer kell megadni, hogyan nyomtatódjon. Beillesztéskor a mód a varázslóban az adott esetre módosítható.
  3. Sorok elrejtése. Az egyes sorok Ne nyomtassa (a készletnél: Rejtett) jelöléssel láthatók el. Beleszámítanak az összegbe, de sem nyomtatásra, sem az ügyfélportálon való megjelenítésre nem kerülnek. A jelölés az ajánlatról átkerül a számlára.
  4. Fix ár készletsoronként. Egy készletsor fix egységárat viselhet, amely felváltja az árlistából származó árat, például egy elrejtett árkorrekcióhoz.
A modul nélkül (csak sale_product_set)A sale_product_set_layout modullal
A készlet sorai laza tételekkéntSzakaszsor a készlet nevével, a mennyiség a névben, alatta a sorok
A készleten belüli szakaszok szakaszok maradnak, és széttördelik a szerkezetetA készleten belüli szakaszok alszakaszokká válnak (line_subsection)
A nyomtatási kép mindig ugyanazNyomtatási mód készletenként, beillesztéskor módosítható
Az árkorrekció látható az ajánlaton és a számlánA sor elrejthető, de beleszámít az összegbe
Az ár kizárólag az árlistából származikOpcionálisan fix ár készletsoronként
A kialakítás az ajánlatnál véget érA kialakítás és az elrejtés az ajánlatra, a megrendelésre, a számlára és az ügyfélportálra is érvényes

A három nyomtatási mód részletesen

A nyomtatási mód a termékkészlet print_mode választómezője. Beillesztéskor a szakaszsor két szabványos kapcsolójára fordítódik le. Erre a modulban egyetlen, könnyen olvasható hozzárendelés szolgál:

# Druckmodus -> (collapse_prices, collapse_composition) der Abschnittszeile
PRINT_MODE_FLAGS = {
    "detailed":   (False, False),
    "total_only": (True,  False),
    "summary":    (False, True),
}

Ugyanazon termékkészlet három nyomtatási képe: minden sor árral, csak a végösszeg, egyetlen sor

Mód (print_mode)Megjelenítés a készletbenSzabványos opció az OdoóbanNyomtatási kép
detailedMinden sor árralnincsSzakasz, minden sor összeggel
total_onlySorok ár nélkül, csak a készlet összegecollapse_prices (Árak elrejtése)Szakasz összeggel, a sorok csak megnevezéssel és mennyiséggel
summaryCsak egy sor a készlet összegévelcollapse_composition (Összetétel elrejtése)Csak a szakaszsor az összeggel

Mivel a modul az Odoo 19 szabványos beállításait használja, és nem saját nyomtatási formátumot, az ajánlat, a megrendelés-visszaigazolás, a számla és az ügyfélportál módosított jelentéssablonok nélkül is működik. Aki saját jelentéssablonokat használ, amelyek figyelembe veszik a szakaszbeállításokat, ugyanezt a viselkedést kapja.

Elrejtett sorok és fix ár

Gyakori eset: egy csomag csomagára alacsonyabb az egyes árak összegénél. Az egyes árak elferdítése helyett fix árú korrekciós sort veszünk fel (például −50,00 € készletenként), és elrejtjük. A háttérrendszerben a számla követhető, a nyomtatványon pedig a csomagár szerepel.

Az árkorrekció a háttérrendszerben látható és jelölt, az ajánlat nyomtatványán, a PDF-ben, a számlán és a portálon nem látható, az összeg azonos

A megértéshez fontos: a hide_in_report jelölés semmit sem változtat a számításon. A mennyiség, az ár, a kedvezmény, az adó, az összegek és a könyvelési tételek változatlanul a szabványos Odoo révén jönnek létre. A sor csak a nyomtatványról és a portálról hiányzik.

  • A termékkészletnél: készletsor Rejtett beállítással és opcionálisan Fix ár az Egységárral együtt.
  • Az ajánlat- és számlasorokon: Ne nyomtassa oszlop (hide_in_report), a készlet nélküli normál sorokhoz is.
  • Átadás: A számla megrendelésből történő létrehozásakor a jelölés átkerül a számlasorra. Az ajánlat másolásakor megmarad.

Technikai megvalósítás

A modul szándékosan kicsi: meglévő modelleket bővít, és csak azokat a pontokat írja felül, ahol az Odoo eldönti, hogy mely sorok kerülnek nyomtatásra és hogyan kerül beillesztésre egy készlet. Nincsenek új jelentéssablonok, új modellek és SQL-beavatkozások.

Adatfolyam: termékkészlet, Készlet hozzáadása varázsló, ajánlatsorok, számlasorok, PDF és ügyfélportál

Bővített modellek és mezők

ModellKiegészítés
product.setinsert_as_section mezők (logikai, alapértelmezés szerint bekapcsolva) és print_mode (választó, kötelező mező, alapértelmezés detailed)
product.set.linehide_in_report, fixed_price, price_unit mezők; a prepare_sale_order_line_values() továbbadja őket az ajánlatsornak
sale.product.set.wizardinsert_as_section, section_name, print_mode mezők; a _prepare_order_lines() építi fel a szakaszsort
sale.order / sale.order.linehide_in_report mező (copy=True beállítással); a _get_order_lines_to_report() átugorja az elrejtett sorokat; a _prepare_invoice_line() továbbadja a jelölést
account.move / account.move.linehide_in_report mező; a _get_move_lines_to_report(), a _get_detailed_lines() és a _get_subsection_lines() kiszűrik az elrejtett sorokat; a _get_aml_vals() beviszi a jelölést a jelentés adataiba

Elrejtés az ajánlatban

Az Odoo 19 a nyomtatandó ajánlatsorokat a _get_order_lines_to_report() metódusban határozza meg. A modul itt egy szűrőt fűz hozzá. A jelentéssablon módosítására nincs szükség: mind az ajánlat jelentéssablonja (sale/report/ir_actions_report_templates.xml), mind a portálsablon (sale/views/sale_portal_templates.xml) ezt a metódust hívja meg:

class SaleOrder(models.Model):
    _inherit = "sale.order"

    def _get_order_lines_to_report(self):
        return super()._get_order_lines_to_report().filtered(
            lambda line: not line.hide_in_report
        )

Átadás a számlára

Amikor a számlasor az ajánlatsorból létrejön (_prepare_invoice_line()), a jelölés átmásolódik. A számla oldalán az Odoo 19-ben több útvonalon keresztül kerülnek sorok a jelentésbe: a főlista, egy szakasz sorai és egy alszakasz sorai. Ezért a modul több helyen szűr (_get_move_lines_to_report() a bizonylaton, _get_detailed_lines() és _get_subsection_lines() a soron), különben egy elrejtett sor egy másik úton ismét felbukkanhatna:

class AccountMoveLine(models.Model):
    _inherit = "account.move.line"

    hide_in_report = fields.Boolean(string="Hidden in report")

    def _get_aml_vals(self, hide_taxes):
        res = super()._get_aml_vals(hide_taxes)
        res["hide_in_report"] = self.hide_in_report
        return res

    def _get_detailed_lines(self, children_lines, direct_children_lines, subsection_lines):
        res = super()._get_detailed_lines(children_lines, direct_children_lines, subsection_lines)
        return [vals for vals in res if not vals.get("hide_in_report")]

    def _get_subsection_lines(self, subsection_line, children_lines):
        res = super()._get_subsection_lines(subsection_line, children_lines)
        return [vals for vals in res if not vals.get("hide_in_report")]

A varázsló: szakasz laza sorok helyett

A sale_product_set modul sale.product.set.wizard varázslója a _prepare_order_lines() metódusban állítja elő az ajánlatsorokat. A modul felülírja ezt a metódust. Ha a Beillesztés szakaszként ki van kapcsolva, egyszerűen az eredeti metódust hívja meg, a viselkedés ilyenkor megegyezik az OCA-modulével. Ellenkező esetben először a két szabványos kapcsolóval ellátott szakaszsor jön létre, majd a készlet sorai következnek. A készleten belüli szakaszok alszakaszokká válnak, hogy ne törjék szét a fő szerkezetet:

def _prepare_order_lines(self):
    if not self.insert_as_section:
        return super()._prepare_order_lines()
    sequence = self._get_max_sequence() + 1
    collapse_prices, collapse_composition = PRINT_MODE_FLAGS[self.print_mode or "detailed"]
    order_lines = [Command.create({
        "display_type": "line_section",
        "name": self.section_name or self.product_set_id.name,
        "sequence": sequence,
        "collapse_prices": collapse_prices,
        "collapse_composition": collapse_composition,
    })]
    for set_line in self._get_lines():
        sequence += 1
        values = set_line.prepare_sale_order_line_values(self.order_id, self.quantity, sequence)
        if values.get("display_type") == "line_section":
            values["display_type"] = "line_subsection"
        order_lines.append(Command.create(values))
    return order_lines

Döntések, amelyeket nem látni

  • Különálló számítási metódusok a varázslóban. A szakasz neve, a nyomtatási mód és a Beillesztés szakaszként mind külön compute metódust kap (store=True, readonly=False). Ha mindhárom ugyanazt a metódust használná, az egyik mezőnek kifejezetten átadott érték visszaállítaná a többit. Ez főleg akkor tűnik fel, ha a varázslót kódból vagy tesztekből hozzák létre értékekkel.
  • Szakasznév a mennyiséggel. Ha a mennyiség nem 1, szerepel a névben (2 × Messkit Standard, tizedesvesszővel), hogy a nyomtatványon látszódjon: két készletről van szó, és nem egy kétszeres mennyiségű készletről.
  • Fix ár csak a termékes soroknál. A prepare_sale_order_line_values() csak akkor állítja be a hide_in_report és a price_unit értékét, ha a készletsor nem szakasz- vagy megjegyzéssor.
  • Szabványos Odoo saját építés helyett. A nyomtatási mód és az elrejtés az Odoo 19 meglévő kapcsait és mezőit használja. Ez kezelhetővé teszi a frissítéseket: ha az Odoo megváltoztatja a jelentéssablont, a modul érvényes marad, amíg a metódusok léteznek.

Telepítés nem kívánt mellékhatások nélkül

Előfeltételek: Odoo 19.0, sale_product_set (OCA/sale-workflow, 19.0 ág) és product_set (OCA/product-attribute, 19.0 ág). Maga a modul a sale_management, a sale_product_set és az account moduloktól függ.

Az auto_install csapda az OCA-moduloknál. Sok OCA-tároló tartalmaz auto_install beállítású modulokat. Amint a függőségeik rendelkezésre állnak, az Odoo a következő telepítéskor vagy frissítéskor kérdés nélkül telepíti őket. Aki ezért a teljes OCA-tárolót egy éles példány addons_path útvonalára teszi, könnyen olyan modulokat kaphat, amelyeket senki sem akart. Az OCA/product-attribute esetében ez például a purchase_product_template_tags modult érinti. Az eljárásunk:

  1. A két OCA-tárolót sekélyen klónozzuk (git clone --depth 1 --branch 19.0).
  2. Egy saját könyvtárban csak a két szükséges modult linkeljük szimbolikus hivatkozással, és ezt a könyvtárat vesszük fel az addons_path útvonalba, nem a teljes tárolókat.
  3. Tesztadatbázison telepítjük, és ellenőrizzük, mely modulok kapnak eközben telepítve állapotot.
  4. Csak ezután telepítjük élesben, a --workers=0 kapcsolóval, hogy a hívás ne versenyezzen a futó szolgáltatással a HTTP-portért.
odoo-bin -c /etc/odoo/odoo.conf -d <datenbank> -i sale_product_set_layout --stop-after-init

Az új mezők és nézetek a telepítés után az adatbázisban vannak. Ha a szolgáltatás többfolyamatos üzemmódban fut, a workerek az adatbázis-jelzés révén újratöltik a megváltozott registryt. A modul Python-fájljainak módosításai csak a szolgáltatás újraindítása után lépnek érvénybe.

Használat lépésről lépésre

  1. Készlet létrehozása: Értékesítés → Termékek → Termékkészletek. Nevezze el a készletet, válassza a Beillesztés szakaszként és a Nyomtatási mód beállítást, írja be a termékeket mennyiségekkel. A korrekciós sorokat lássa el Rejtett és Fix ár beállítással.
  2. Az ajánlatban: Kattintson a Készlet hozzáadása gombra, válassza ki a készletet és a mennyiséget. A szakasz neve és a nyomtatási mód beillesztés előtt módosítható.
  3. Egyes sorok elrejtése: Az ajánlatban vagy a számlán aktiválja a Ne nyomtassa oszlopot.
  4. Ellenőrzés: Nyissa meg az előnézetet vagy a PDF-et. Ugyanezt a megjelenítést látják az ügyfelek a portálon.

Tesztek

A modul hat automatizált tesztet tartalmaz, amelyeket tesztadatbázison futtatunk, mielőtt bármi élesbe kerül:

  • Beillesztés szakaszként, a nyomtatási móddal és az alszakasszal együtt
  • Az elrejtett sor hiányzik a nyomtatandó sorok közül
  • Egy sor mód (summary)
  • Beillesztés szakasz nélkül, az eredeti viselkedés
  • A számla átveszi a hide_in_report jelölést, a sor hiányzik a _get_move_lines_to_report() eredményéből, a szakaszösszeg továbbra is tartalmazza
  • A Csak végösszeg módú számla az elrejtett sort nem mutatja a szakaszsorokban, a szakaszösszeg teljes marad
odoo-bin -d <testdatenbank> -i sale_product_set_layout \
         --test-enable --test-tags=/sale_product_set_layout --stop-after-init

A német fordítás az i18n/de.po fájlban található.

Korlátok és jogi megjegyzés

  • Csak kialakítás. A modul nem változtatja meg, hogyan számolja az Odoo az árakat, a kedvezményeket vagy az adókat. Csak azt módosítja, ami nyomtatásra kerül és megjelenik a portálon.
  • Az elrejtett sorok a háttérrendszerben láthatók. A jelölés a nyomtatványt és a portált érinti, nem a munkatársak képernyőnézetét.
  • Ellenőrizze a számlaadatokat. Az elrejtett sorok beleszámítanak az összegbe, de nem szerepelnek a bizonylaton. Hogy ez összeegyeztethető-e az Ön országában a számlákra vonatkozó követelményekkel, például a szállított tárgyak vagy teljesített szolgáltatások előírt leírásával, azt a számlákon való használat előtt tisztázza adótanácsadójával. Az ajánlatokon az elrejtés kevésbé problémás. A cikk nem jogi tanácsadás.
  • Odoo 19-re tesztelve. A modult az Odoo 19.0 Communityhez fejlesztettük és teszteltük. Olyan szakaszbeállításokat használ, amelyek ebben a formában az Odoo 19-ben léteznek. Más verziókon nem ellenőriztük.

Gyakori kérdések

Mire kell nekem a modul, ha az Odoo 19 már tud szakaszokat?

A szakaszbeállítások az Odoóban megvannak. Hiányzott a kapcsolat a termékkészlettel: a készletnek automatikusan szakaszként kellene beillesztődnie, a készletben megadott nyomtatási móddal. A modul nélkül minden beillesztés után kézzel kell létrehozni és beállítani a szakaszsort.

Miben különbözik az „Árak elrejtése” és az „Összetétel elrejtése”?

Az „Árak elrejtése” (collapse_prices) meghagyja a sorokat, de nem mutat összegeket, csak a szakasz összegét. Az „Összetétel elrejtése” (collapse_composition) teljesen elrejti a sorokat, az ügyfél csak a szakaszt látja az összeggel.

Beleszámít-e az elrejtett sor a számla összegébe?

Igen. Az elrejtett sorok megmaradnak az összegben, az adóban és a könyvelésben. A jelölés csak a nyomtatványon és az ügyfélportálon való megjelenítést érinti.

Beillesztéskor még módosíthatom a nyomtatási módot?

Igen. A mód alapértelmezésként a készletből származik, a varázslóban az adott beillesztéshez módosítható. A készlet maga ilyenkor változatlan marad.

Mi történik, ha kikapcsolom a Beillesztés szakaszként beállítást?

Ekkor a varázsló úgy viselkedik, mint az OCA sale_product_set modulban: a készlet sorai szakasz nélkül kerülnek beillesztésre.

Telepít-e a modul váratlanul további modulokat?

Maga a modul nem. Az OCA-tárolóknál azonban előfordulhatnak auto_install modulok, ha teljes tárolókat teszünk az addons_path útvonalra. Ezért csak a két szükséges modult linkelje (lásd a Telepítés című szakaszt).

Fut-e a modul az Odoo Enterprise-zal?

A modul csak Community modulokra (sale_management, account) és a két OCA-modulra épül. Mi az Odoo 19 Communityn használjuk. Enterprise-on nem teszteltük.

Milyen licenc alatt áll a modul?

Az AGPL-3 alatt. Használhatja, módosíthatja és terjesztheti, amennyiben a módosítások ugyanazon licenc alatt maradnak. A hibákat és a fejlesztési javaslatokat issue-ként szívesen fogadjuk a következő helyen: GitHub-tároló .

A Biricon IT Services támogatása

Kis- és középvállalkozások Odoo-telepítéseit gondozzuk: a bevezetéstől a testreszabásokon és migrációkon át a folyamatos üzemeltetésig. Ha a termékkészleteket, ajánlatsablonokat vagy jelentéseket az Odoo 19-ben a saját folyamataihoz szeretné igazítani, vagy ha egy ilyen modult szeretne ellenőriztetni és biztonságosan élesbe vinni, szívesen támogatjuk. További saját fejlesztéseinket blogunkban találja, például: Piszkozatszámlák összevonása és Banki fizetések automatikus hozzárendelése számlákhoz.

Lépjen velünk kapcsolatba

Állapot: 2026. november 2. Modulverzió: 19.0.1.0.0. Az ábrákon szereplő példaadatok szabadon választottak, az összegek nettó értékek.