Odoo-da paketlər, məsələn, aksesuarlar və quraşdırma ilə birlikdə ölçü cihazı, avadanlıq və sazlama ilə birlikdə iş yeri və ya bir neçə xidmətdən ibarət texniki xidmət paketi satanlara qiymət təklifində eyni vaxtda iki şey lazımdır: anbar, texniki heyət və hesab-fakturaları hazırlayanlar nəyin təhvil veriləcəyini bilsinlər deyə sifarişdə tərkib göstərilməlidir. Lakin müştəri üçün çap olunan sənəddə hər bir mövqenin ayrıca qiyməti ilə göstərilməsi hər zaman lazım olmur.
OCA-nın sale_product_set modulu məhsul dəstlərini (satış üçün tərkib siyahılarını) bir kliklə qiymət təklifinə əlavə etməyə imkan verir. Amma çap görünüşünü idarə etmir. Bunun üçün biz Sale Product Set Layout (sale_product_set_layout) modulunu hazırlamışıq. Modul Odoo 19 üçün yazılıb və AGPL-3 lisenziyası ilə azad proqram təminatı kimi GitHub-da pulsuz təqdim olunur:
github.com/Alex0176/odoo-sale-product-set-layout
Bu məqalənin məzmunu
- Problem: çap görünüşünü idarə etməyən məhsul dəstləri
- Modul nə edir
- Üç çap rejimi haqqında ətraflı
- Gizlədilən sətirlər və sabit qiymət
- Texniki reallaşdırma
- Arzuolunmaz yan təsirlər olmadan quraşdırma
- Addım-addım istifadə qaydası
- Testlər
- Məhdudiyyətlər və hüquqi qeyd
- Tez-tez verilən suallar
- Biricon IT Services dəstəyi
Problem: çap görünüşünü idarə etməyən məhsul dəstləri
Odoo-da məhsul dəsti məhsulların miqdarları ilə birlikdə əvvəlcədən hazırlanmış siyahısıdır. On məhsulu ayrı-ayrılıqda axtarmaq əvəzinə, qiymət təklifində Dəst əlavə et seçilir və bütün sətirlər bir dəfəyə əlavə olunur. Bu, vaxta qənaət edir və mövqelərin unudulmasının qarşısını alır. Bu repozitoriyadakı sale_product_set modulu OCA/sale-workflow məhz bunu edir; dəstlərin özü isə bu repozitoriyadakı product_set modulundan gəlir: OCA/product-attribute.
Praktikada üç çatışmazlıq qalır:
- Aydın qruplaşdırma yoxdur. Dəstin sətirləri qiymət təklifinə əlaqəsiz mövqelər kimi əlavə olunur. Əlavə edildikdən sonra hansı sətirlərin bir dəstə aid olduğu görünmür və dəstin ümumi məbləği heç yerdə göstərilmir.
- Çap görünüşünü idarə etmək olmur. Bəzən müştəri hər mövqeni qiyməti ilə, bəzən yalnız paket qiymətini, bəzən isə tək bir sətir görməlidir. Bu seçim hər dəst və ya müştəri üçün təyin olunmalıdır, hər qiymət təklifində yenidən əl ilə edilməməlidir.
- Qiymət düzəlişləri səliqəli görünmür. Paketə qiymət siyahısındakı qiymətlərin cəmindən fərqli sabit qiymət təyin etmək üçün düzəliş sətri lazımdır. Bu sətir hesablamada iştirak etməlidir, lakin müştərinin sənədində görünməsi həmişə lazım deyil.
Odoo 19 bunu səliqəli həll etmək üçün lazımi imkanları təqdim edir: qiymət təklifi sətirlərində Qiymətləri gizlət və Tərkibi gizlət seçimləri olan bölmələr və alt bölmələr (collapse_prices və collapse_composition sahələri). Modul ayrıca çap formatı yaratmaq əvəzinə məhsul dəstini bu standart seçimlərlə əlaqələndirir.
Modul nə edir
- Dəsti bölmə kimi əlavə etmək. Dəst əlavə et köməkçisi dəstin adı ilə, məsələn, 2 × Messkit Standard adlı bölmə sətri yaradır və dəstin sətirlərini onun altına yerləşdirir. Dəstin daxilindəki bölmələr alt bölmələrə çevrilir.
- Hər dəst üçün çap rejimi. Dəstin necə çap olunacağı onun özündə bir dəfə təyin edilir. Əlavə etmə zamanı köməkçidə rejimi yalnız həmin hal üçün dəyişmək olar.
- Sətirləri gizlətmək. Ayrı-ayrı sətirlər Çap etmə (dəstdə: Gizli) kimi işarələnə bilər. Onlar ümumi məbləğə daxil edilir, lakin nə çap olunur, nə də müştəri portalında göstərilir. Bu işarə qiymət təklifindən hesab-fakturaya ötürülür.
- Hər dəst sətri üçün sabit qiymət. Dəstin sətrinə qiymət siyahısındakı qiyməti əvəz edən sabit vahid qiyməti təyin etmək olar, məsələn, gizlədilmiş qiymət düzəlişi üçün.
Modul olmadan (yalnız sale_product_set) | sale_product_set_layout ilə |
|---|---|
| Dəstin sətirləri qruplaşdırılmamış ayrı mövqelər kimi | Dəstin adı ilə bölmə sətri, adda miqdar, altında dəstin sətirləri |
| Dəstdəki bölmələr bölmə olaraq qalır və strukturu pozur | Dəstdəki bölmələr alt bölmələrə çevrilir (line_subsection) |
| Çap görünüşü həmişə eynidir | Hər dəst üçün çap rejimi, əlavə etmə zamanı dəyişdirilə bilər |
| Qiymət düzəlişi qiymət təklifində və hesab-fakturada görünür | Sətri gizlətmək olar, lakin ümumi məbləğdə nəzərə alınır |
| Qiymət yalnız qiymət siyahısından götürülür | İstəyə görə hər dəst sətri üçün sabit qiymət |
| Tərtibat yalnız qiymət təklifinə tətbiq olunur | Tərtibat və gizlətmə qiymət təklifinə, sifarişə, hesab-fakturaya və müştəri portalına tətbiq olunur |
Üç çap rejimi haqqında ətraflı
Çap rejimi məhsul dəstindəki print_mode seçim sahəsidir. Dəst əlavə edilərkən bu rejim bölmə sətrinin iki standart parametrinə çevrilir. Bunun üçün modulda asan oxunan vahid uyğunluq cədvəli var:
# Çap rejimi -> bölmə sətrinin (collapse_prices, collapse_composition) parametrləri
PRINT_MODE_FLAGS = {
"detailed": (False, False),
"total_only": (True, False),
"summary": (False, True),
}
Rejim (print_mode) | Dəstdə göstərilmə | Odoo-da standart seçim | Çap görünüşü |
|---|---|---|---|
detailed | Hər sətir qiyməti ilə | yoxdur | Bölmə, bütün sətirlər məbləği ilə |
total_only | Sətirlər qiymətsiz, yalnız dəstin ümumi məbləği | collapse_prices (Qiymətləri gizlət) | Ümumi məbləğlə bölmə, sətirlərdə yalnız ad və miqdar |
summary | Dəstin ümumi məbləği ilə yalnız bir sətir | collapse_composition (Tərkibi gizlət) | Yalnız ümumi məbləğlə bölmə sətri |
Modul ayrıca çap formatından deyil, Odoo 19-un standart seçimlərindən istifadə etdiyi üçün qiymət təklifi, sifariş təsdiqi, hesab-faktura və müştəri portalı hesabat şablonları dəyişdirilmədən işləyir. Bölmə seçimlərini nəzərə alan fərdi hesabat şablonlarında da eyni davranış əldə olunur.
Gizlədilən sətirlər və sabit qiymət
Tez-tez rast gəlinən hal: paketin qiyməti ayrı-ayrı məhsulların qiymətlərinin cəmindən aşağıdır. Vahid qiymətlərini dəyişmək əvəzinə, sabit qiymətli düzəliş sətri (məsələn, hər dəst üçün −50,00 €) əlavə edilir və gizlədilir. İdarəetmə panelində hesablama aydın görünür, çap olunan sənəddə isə paket qiyməti göstərilir.
Bunu nəzərə almaq vacibdir: hide_in_report işarəsi hesablamada heç nəyi dəyişmir. Miqdar, qiymət, endirim, vergi, yekun məbləğlər və mühasibat yazılışları standart Odoo vasitəsilə əvvəlki qaydada hesablanır və yaradılır. Sətir yalnız çap olunan sənəddə və portalda göstərilmir.
- Məhsul dəstində: Gizli seçimi və istəyə görə Sabit qiymət seçimi ilə Vahid qiyməti olan dəst sətri.
- Qiymət təklifi və hesab-faktura sətirlərində: Çap etmə (
hide_in_report) sütunu, həmçinin dəstə aid olmayan adi sətirlər üçün. - Ötürülmə: Sifarişdən hesab-faktura yaradılarkən işarə hesab-faktura sətrinə ötürülür. Qiymət təklifi kopyalanarkən də saxlanılır.
Texniki reallaşdırma
Modul məqsədli şəkildə kiçik saxlanılıb: mövcud modelləri genişləndirir və yalnız Odoo-nun hansı sətirlərin çap olunacağını və dəstin necə əlavə ediləcəyini müəyyənləşdirdiyi hissələri əvəz edir. Yeni hesabat şablonları, yeni modellər və SQL müdaxilələri yoxdur.
Genişləndirilmiş modellər və sahələr
| Model | Əlavə |
|---|---|
product.set | insert_as_section (məntiqi tip, standart olaraq aktiv) və print_mode (seçim, məcburi sahə, standart dəyər detailed) sahələri |
product.set.line | hide_in_report, fixed_price, price_unit sahələri; prepare_sale_order_line_values() onları qiymət təklifi sətrinə ötürür |
sale.product.set.wizard | insert_as_section, section_name, print_mode sahələri; _prepare_order_lines() bölmə sətrini yaradır |
sale.order / sale.order.line | hide_in_report sahəsi (copy=True ilə); _get_order_lines_to_report() gizlədilmiş sətirləri nəzərə almır; _prepare_invoice_line() işarəni ötürür |
account.move / account.move.line | hide_in_report sahəsi; _get_move_lines_to_report(), _get_detailed_lines() və _get_subsection_lines() gizlədilmiş sətirləri süzgəcdən keçirərək çıxarır; _get_aml_vals() işarəni hesabat məlumatlarına əlavə edir |
Qiymət təklifində gizlətmə
Odoo 19 çap olunacaq qiymət təklifi sətirlərini _get_order_lines_to_report() metodunda müəyyənləşdirir. Modul həmin yerə filtr əlavə edir. Hesabat şablonuna müdaxilə lazım deyil: həm qiymət təklifinin hesabat şablonu (sale/report/ir_actions_report_templates.xml), həm də portal şablonu (sale/views/sale_portal_templates.xml) bu metodu çağırır:
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
)
Hesab-fakturaya ötürülmə
Qiymət təklifi sətrindən hesab-faktura sətri yaradılarkən (_prepare_invoice_line()) işarə kopyalanır. Odoo 19-da hesab-faktura sətirləri hesabata bir neçə yolla daxil olur: əsas siyahı, bölmənin sətirləri və alt bölmənin sətirləri vasitəsilə. Buna görə modul bir neçə yerdə filtrləmə aparır (sənəddə _get_move_lines_to_report(), sətirdə isə _get_detailed_lines() və _get_subsection_lines()). Əks halda gizlədilmiş sətir digər yollardan biri ilə yenidən görünə bilərdi:
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")]
Köməkçi: ayrı-ayrı sətirlər əvəzinə bölmə
sale_product_set modulundakı sale.product.set.wizard köməkçisi qiymət təklifi sətirlərini _prepare_order_lines() metodunda yaradır. Modul bu metodu əvəz edir. Bölmə kimi əlavə et seçimi deaktivdirsə, sadəcə ilkin metod çağırılır və davranış OCA modulundakı kimi qalır. Əks halda əvvəlcə iki standart parametri olan bölmə sətri yaradılır, sonra dəstin sətirləri əlavə olunur. Dəstin daxilindəki bölmələr əsas strukturu pozmamaq üçün alt bölmələrə çevrilir:
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
Görünməyən qərarlar
- Köməkçidə ayrı hesablama metodları. Bölmənin adı, çap rejimi və Bölmə kimi əlavə et sahələrinin hər birinin ayrıca
computemetodu var (store=True,readonly=False). Hər üçü eyni metoddan istifadə etsəydi, bir sahə üçün açıq şəkildə ötürülən dəyər digərlərinin dəyərlərini sıfırlayardı. Bu, xüsusən köməkçi koddan və ya testlərdən dəyərlərlə yaradıldıqda nəzərə çarpır. - Bölmənin adında miqdar. Miqdar 1-dən fərqli olduqda adda göstərilir (2 × Messkit Standard, onluq ayırıcı kimi vergüllə). Beləliklə, çap olunan sənəddə bunun ikiqat miqdarlı bir dəst deyil, iki dəst olduğu görünür.
- Sabit qiymət yalnız məhsul sətirlərində.
prepare_sale_order_line_values()yalnız dəstin sətri bölmə və ya qeyd sətri olmadıqdahide_in_reportvəprice_unitdəyərlərini təyin edir. - Fərdi həll əvəzinə standart Odoo. Çap rejimi və gizlətmə Odoo 19-un mövcud genişləndirmə nöqtələrindən və sahələrindən istifadə edir. Bu, yeniləmələri idarə etməyi asanlaşdırır: Odoo hesabat şablonunu dəyişdirsə də, metodlar mövcud olduğu müddətdə modul işlək qalır.
Arzuolunmaz yan təsirlər olmadan quraşdırma
Tələblər: Odoo 19.0, sale_product_set (OCA/sale-workflow, 19.0 budağı) və product_set (OCA/product-attribute, 19.0 budağı). Modulun özü sale_management, sale_product_set və account modullarından asılıdır.
OCA modullarında auto_install tələsi. Bir çox OCA repozitoriyasında auto_install parametrli modullar var. Onların asılı olduğu modullar mövcud olduqda, Odoo növbəti quraşdırma və ya yeniləmə zamanı onları da soruşmadan quraşdırır. Buna görə bütöv OCA repozitoriyasını istismarda olan sistemin addons_path yoluna əlavə edənlər heç kimin istəmədiyi modulları da əldə edə bilərlər. OCA/product-attribute repozitoriyasında buna, məsələn, purchase_product_template_tags aiddir. Bizim yanaşmamız:
- Hər iki OCA repozitoriyasını məhdud tarixçə ilə klonlayın (
git clone --depth 1 --branch 19.0). - Ayrıca qovluqda yalnız lazım olan iki modula simvolik keçid yaradın və
addons_pathparametrinə bütöv repozitoriyaları deyil, bu qovluğu əlavə edin. - Test verilənlər bazasında quraşdırın və bu zaman hansı modulların quraşdırılıb statusu aldığını yoxlayın.
- Yalnız bundan sonra işçi mühitdə quraşdırın. Əmrin işləyən xidmətlə eyni HTTP portuna iddia etməməsi üçün
--workers=0parametrindən istifadə edin.
odoo-bin -c /etc/odoo/odoo.conf -d <datenbank> -i sale_product_set_layout --stop-after-init
Quraşdırmadan sonra yeni sahələr və görünüşlər verilənlər bazasında olur. Xidmət çoxprosesli rejimdə işləyirsə, işçi proseslər verilənlər bazasından gələn siqnal vasitəsilə dəyişmiş reyestri yenidən yükləyir. Modulun Python fayllarındakı dəyişikliklər yalnız xidmət yenidən başladıldıqdan sonra qüvvəyə minir.
Addım-addım istifadə qaydası
- Dəst yaradın: Satış → Məhsullar → Məhsul dəstləri. Dəstə ad verin, Bölmə kimi əlavə et seçimini və Çap rejimini təyin edin, məhsulları miqdarları ilə daxil edin. Düzəliş sətirlərini Gizli və Sabit qiymət kimi işarələyin.
- Qiymət təklifində: Dəst əlavə et düyməsinə klikləyin, dəsti və miqdarı seçin. Əlavə etməzdən əvvəl bölmənin adını və çap rejimini dəyişmək mümkündür.
- Ayrı-ayrı sətirləri gizlədin: Qiymət təklifində və ya hesab-fakturada Çap etmə sütununu aktivləşdirin.
- Yoxlayın: Önizləməni və ya PDF-i açın. Müştərilər də portalda eyni görünüşü görürlər.
Testlər
Modula altı avtomatlaşdırılmış test daxildir. İşçi mühitə keçməzdən əvvəl onları test verilənlər bazasında icra edirik:
- Çap rejimi və alt bölmə daxil olmaqla bölmə kimi əlavə etmə
- Gizlədilmiş sətrin çap ediləcək sətirlər arasında olmaması
- Bir sətir rejimi (
summary) - Bölməsiz əlavə etmə, ilkin davranış
- Hesab-faktura
hide_in_reportişarəsini qəbul edir, sətir_get_move_lines_to_report()nəticəsində olmur, amma bölmənin yekun məbləğinə daxil edilir - Yalnız ümumi qiymət rejimində hesab-faktura gizli sətri bölmənin sətirləri arasında göstərmir, bölmənin yekun məbləği isə tam qalır
odoo-bin -d <testdatenbank> -i sale_product_set_layout \
--test-enable --test-tags=/sale_product_set_layout --stop-after-init
Alman dilinə tərcümə i18n/de.po faylındadır.
Məhdudiyyətlər və hüquqi qeyd
- Yalnız tərtibat. Modul Odoo-nun qiymətləri, endirimləri və vergiləri hesablama qaydasını dəyişmir. Yalnız çap olunan və portalda göstərilən məlumatları dəyişir.
- Gizlədilmiş sətirlər idarəetmə interfeysində görünür. Bu işarə çap və portala aiddir, əməkdaşların ekranda gördüyü görünüşə təsir etmir.
- Hesab-faktura məlumatlarını yoxlayın. Gizlədilmiş sətirlər yekun məbləğə daxil edilir, amma sənəddə göstərilmir. Bunun ölkənizdə hesab-fakturalara dair tələblərə, məsələn, təhvil verilmiş malların və ya göstərilmiş xidmətlərin məcburi təsvirinə uyğun olub-olmadığını hesab-fakturalarda istifadə etməzdən əvvəl vergi məsləhətçinizlə dəqiqləşdirin. Qiymət təkliflərində sətirlərin gizlədilməsi daha az problem yaradır. Bu məqalə hüquqi məsləhət deyil.
- Odoo 19 üçün sınaqdan keçirilib. Modulu Odoo 19.0 Community üçün hazırlamış və sınaqdan keçirmişik. O, Odoo 19-da bu formada mövcud olan bölmə seçimlərindən istifadə edir. Digər versiyalarda yoxlamamışıq.
Tez-tez verilən suallar
Odoo 19-da bölmələr artıq varsa, bu modul mənə nə üçün lazımdır?
Bölmə seçimləri Odoo-nun özündə var. Çatışmayan isə məhsul dəsti ilə əlaqə idi: dəst özündə saxlanmış çap rejimi ilə avtomatik olaraq bölmə kimi əlavə edilməli idi. Bu modul olmadan hər dəfə dəst əlavə etdikdən sonra bölmə sətrini əl ilə yaratmaq və sazlamaq lazımdır.
“Qiymətləri gizlət” və “Tərkibi gizlət” seçimləri arasında nə fərq var?
“Qiymətləri gizlət” (collapse_prices) sətirləri saxlayır, amma məbləğləri göstərmir; yalnız bölmənin yekun məbləği görünür. “Tərkibi gizlət” (collapse_composition) sətirləri tamamilə gizlədir, müştəri yalnız bölməni və onun yekun məbləğini görür.
Gizlədilmiş sətir hesab-fakturanın yekun məbləğinə daxil edilirmi?
Bəli. Gizlədilmiş sətirlər yekun məbləğdə, vergidə və mühasibat yazılışında qalır. Bu işarə yalnız çap sənədində və müştəri portalındakı görünüşə təsir edir.
Əlavə edərkən çap rejimini dəyişə bilərəmmi?
Bəli. İlkin rejim dəstdən götürülür, amma köməkçi pəncərədə həmin əlavəetmə üçün dəyişdirilə bilər. Dəstin özü isə dəyişməz qalır.
Bölmə kimi əlavə et seçimini söndürsəm, nə baş verər?
Bu halda köməkçi OCA-nın sale_product_set modulundakı kimi işləyir: dəstin sətirləri bölməsiz əlavə olunur.
Modul gözlənilmədən əlavə modullar quraşdırırmı?
Modulun özü bunu etmir. Amma OCA repozitoriyalarını bütövlükdə addons_path parametrinə əlavə etdikdə auto_install modulları quraşdırıla bilər. Buna görə yalnız lazım olan iki modula keçid yaradın (Quraşdırma bölməsinə baxın).
Modul Odoo Enterprise ilə işləyirmi?
Modul yalnız Community modullarından (sale_management, account) və iki OCA modulundan asılıdır. Biz onu Odoo 19 Community-də istifadə edirik. Enterprise-də sınaqdan keçirməmişik.
Modul hansı lisenziya ilə təqdim olunur?
AGPL-3 lisenziyası ilə. Dəyişikliklər eyni lisenziya altında qaldığı müddətdə ondan istifadə edə, onu uyğunlaşdıra və paylaşa bilərsiniz. Xətaları və təkmilləşdirmə təkliflərini Issue kimi bu ünvanda bildirməyinizi gözləyirik: GitHub repozitoriyası .
Biricon IT Services dəstəyi
Kiçik və orta müəssisələr üçün Odoo sistemlərinə xidmət göstəririk: tətbiqdən tutmuş uyğunlaşdırma və miqrasiyalara, eləcə də gündəlik istismara qədər. Odoo 19-da məhsul dəstlərini, qiymət təklifi şablonlarını və ya hesabatları iş proseslərinizə uyğunlaşdırmaq, yaxud bu cür modulu yoxlayıb işçi sisteminizə etibarlı şəkildə quraşdırmaq istəyirsinizsə, sizə məmnuniyyətlə kömək edərik. Öz hazırladığımız digər həlləri bloqumuzda tapa bilərsiniz, məsələn: Qaralama hesab-fakturaları birləşdirmək və Bank ödənişlərini avtomatik olaraq hesab-fakturalarla uyğunlaşdırmaq.
Son yenilənmə: 2 noyabr 2026. Modulun versiyası: 19.0.1.0.0. Şəkillərdəki nümunə məlumatlar şərtidir, məbləğlər vergilərsiz göstərilib.