Bosanska lokalizacija "Odoo" open-source platforme: portiranje fiskalnog i modula za obračun PDV-a na verziju 19 (l10n_ba_edi, l10n_ba_pdv v16 => v19)


Portiranje bosanskohercegovačke lokalizacije na Odoo 19 je značajan korak naprijed. Moduli l10n_ba_edi (fiskalizacija) i l10n_ba_pdv (obračun PDV-a) su uspješno portirani sa verzije 16 na verziju 19.

Kontni plan

Bosanski kontni plan na Odoo 19 sa 494 konta:

Kontni plan

Porezne stope

Konfigurisane porezne stope za PDV (17%, 0%) sa oznakama za različite vrste prometa - prodaja, nabavke, carinske oznake (C15, C24-25, C27, CXX), kompenzacije (KP), avansi:

Porezne stope

Fiskalizacija (l10n_ba_edi)

Podešavanje fiskalnog servera

Modul l10n_ba_edi omogućava povezivanje sa EDI serverom za fiskalizaciju. Podešavanja uključuju parametre EDI servera (host URL, API key, PIN), vrstu fiskalnog sistema (OFS - Republika Srpska, FPrint - Federacija), te izbor fiskalnog režima - VP (Veleprodaja - Wholesale) ili MP (Maloprodaja - Retail):

Fiskalno podešavanje

Podešavanje dnevnika za EDI

Na dnevniku prodaje se aktivira opcija “Electronic Invoicing” sa provajderom “Fiskalizacija (BA)”:

Journal EDI podešavanje

Faktura sa fiskalnim statusom

Primjer proknjižene fakture IF/2026/00001 sa EDI statusom i dugmetom “RETRY EDI” za ponovni pokušaj slanja na fiskalni server:

Faktura fiskalni

Obračun PDV-a (l10n_ba_pdv)

PDV obračun wizard

Modul l10n_ba_pdv omogućava generisanje PDV obračuna za odabrani period. Wizard podržava generisanje XLSX izvještaja te CSV fajlova za enabavke i eisporuke:

PDV obračun

PDV CSV izvještaj - eisporuke

Generisani CSV sa podacima o eisporukama, uključujući poreski period, redni broj, datum fakture, broj fakture, podatke o kupcu, iznose sa i bez PDV-a:

PDV CSV eisporuke

Odoo 19 core bugfix: QwebJSON circular reference

Tokom portiranja na Odoo 19 otkriven je latentni bug u Odoo 19 core-u koji se manifestuje kao ValueError: Circular reference detected prilikom učitavanja web klijenta.

Problem

QWeb template web.webclient_bootstrap pada sa greškom na liniji:

<t t-out="json.dumps(session_info)"/>

Uzrok

Klasa QwebJSON u odoo/addons/base/models/ir_qweb.py ima default handler koji vraća neserijalizabilne objekte nepromijenjene:

# Originalni (pokvareni) kod
class QwebJSON(json.JSON):
    def dumps(self, *args, **kwargs):
        prev_default = kwargs.pop('default', lambda obj: obj)
        return super().dumps(*args, **kwargs, default=(
            lambda obj: prev_default(str(obj) if isinstance(obj, QwebContent) else obj)
        ))

Kada JSON encoder naiđe na neserijalizabilan tip (ReadonlyDict, lazy, datetime, bytes, Domain), poziva default handler. Handler vraća objekat nepromijenjen (jer nije QwebContent). Encoder ponovo pokuša serijalizaciju, dobije isti objekat nazad i prijavi “Circular reference detected.”

U vanilla Odoo-u se rijetko manifestuje jer su session_info vrijednosti tipično JSON-serijalizabilne. Međutim, svaki modul (OCA ili custom) koji unese neserijalizabilan tip u session_info ili bilo koji drugi QWeb JSON kontekst će izazvati ovaj bug.

Ispravka

Koristiti odoo.tools.json.json_default() kao fallback za objekte koji nisu QwebContent:

# Ispravljen kod
class QwebJSON(json.JSON):
    def dumps(self, *args, **kwargs):
        prev_default = kwargs.pop('default', lambda obj: obj)
        return super().dumps(*args, **kwargs, default=(
            lambda obj: prev_default(str(obj) if isinstance(obj, QwebContent) else json.json_default(obj))
        ))

Funkcija json_default() (iz odoo/tools/json.py) pravilno obrađuje: datetime, date, lazy, ReadonlyDict, bytes, Domain i ostale tipove.

Detalji ispravke: QWEBJSON_CIRCULAR_REFERENCE.md

Napomena

Većinu sadržaja ovog članka je napisao 🤖 Claude


Prethodni blog postovi o bosanskoj lokalizaciji: