Kes koostab Odoos arveid tellimuste, kasutajatoe pöördumiste ja ajaarvestuse põhjal, teab tulemust: kuu lõpus saab klient ühe arve asemel viis. Igaüks pärineb eri tellimusest või pöördumisest ja on sisuliselt korrektne – ometi küsib klient, kas need ei võiks mahtuda ühele dokumendile.
Just selle jaoks puudub Odoo 19 Communitys korralik lahendus. Tuntud OCA moodul account_invoice_merge ei ole Odoo 19 jaoks veel välja antud ning lahendab probleemi viisil, mis kujutab teenusepakkujatele tõsist riski: ühesugused read liidetakse kokku ning sellega kaob seos tellimuse, ülesande ja registreeritud tööajaga.
Seetõttu arendasime oma Odoo 19 Community paigalduse jaoks mooduli Merge Draft Invoices. Kuna see probleem ei puuduta ainult meid, avaldame mooduli GitHubis tasuta vaba AGPL-3 litsentsi alusel.
Projekt GitHubis:
Miks oma moodul OCA lahenduse asemel?
OCA on moodulit account_invoice_merge hoidlas OCA/account-invoicing hooldanud juba aastaid. Selle postituse kirjutamise ajal on üleviimine versioonile 19.0 seal veel avatud muudatustaotlus, mitte avaldatud moodul.
Olulisem on aga see, et need kaks moodulit teevad eri asju:
| OCA account_invoice_merge | Merge Draft Invoices | |
|---|---|---|
| Tulemus | ühendatakse üheks valitud arvetest | alati uus arve |
| Read | ühesugused read liidetakse kokku ja kogused summeeritakse | iga rida kantakse üle üks ühele |
| Päritolu | invoice_origin / payment_reference liidetakse arve päises kokku | iga rea päritoluväljad kopeeritakse Odoo enda _copy_data_extend_business_fields-laienduspunkti kaudu |
| Ajaarvestus | ei arvestata | timesheet_invoice_id suunatakse ümber uuele arvele |
| Kliendile arusaadav | puudub | iga lähtearve ridade kohal on pealkiri tellimuse ja pöördumisega |
| Lähtearved | tühistatakse | tühistamine (vaikimisi), kustutamine või säilitamine – tagajärjed on selgelt välja toodud |
Otsustav erinevus on ühesuguste ridade kokkuliitmine. Kokku liidetud real saab olla ainult üks päritolu. Niipea kui kaks eri tellimustest pärinevat rida näevad ühesugused välja, kaob seos arve ning tellimuse, ülesande ja ajakande vahel. Teenindusettevõttes, kus arveldamine käib ahelas pöördumine → ajaarvestus → arve, tähendab see, et samade tundide eest esitatakse arve kaks korda või jäävad need üldse arvelt välja.
Seetõttu ei liida meie moodul ühtegi rida kokku. Ühendatud arvel on täpselt sama palju ridu kui lähtearvetel kokku.
OCA moodulist ei ole koodi üle võetud. Mõlemad moodulid kasutavad AGPL-3 litsentsi.
Mida moodul teeb
Märkige arvete loendivaates vähemalt kaks mustandit ja valige toimingumenüüst Ühenda arvete mustandid – viisard näitab valitud arveid, kontrolle ja lähtearvete käsitlemise valikuid. Pärast kinnitamist avaneb kohe uus arve.
Enne ühendamist kontrollib moodul kõiki tingimusi korraga, et pärast iga parandust ei ilmuks alles järgmine viga:
- valitud on vähemalt kaks arvet
- kõik on olekus Mustand
- ühtegi pole kunagi konteeritud (tagasi mustandiks muudetud dokumendi konteerimisajalugu säilib ja seda ei lubata ühendada)
- ühtegi pole juba ühendatud
- kõik on müügiarved, ostuarved, kreeditarved või kviitungid – mitte tavalised raamatupidamiskanded
- sama partner, dokumenditüüp, ettevõte, valuuta ja andmik
Erinevused maksetingimustes, maksupositsioonis, tarneaadressis, pangakontos või müügiesindajas ühendamist ei takista. Viisard kuvab hoiatuse ja kasutab vanima valitud arve väärtust.
Mis säilib
Mooduli põhimõte on säilitada ka uuel arvel kõik seosed, mis seovad arverea selle päritoluga:
| Seos | Käsitlemine |
|---|---|
| Müügitellimuse read (sale_line_ids) | kopeeritakse iga rea kohta Odoo _copy_data_extend_business_fields kaudu |
| Ostutellimuse read (purchase_line_id) | samamoodi |
| Jaotus kulukohtade vahel (analytic_distribution) | kopeeritakse iga rea kohta |
| muud reapõhised päritoluväljad | automaatselt, kui pakkuv moodul rakendab dokumenteeritud Odoo konksu |
| Päritolu ja viide arve päises | ühendatakse, duplikaadid eemaldatakse, viisardis muudetavad |
| Müügitellimus: invoice_ids, invoice_status, qty_invoiced | arvutatakse ridade põhjal – tellimus tuvastab uue arve ise |
| Ajaarvestus (timesheet_invoice_id) | suunatakse ümber uuele arvele enne, kui lähtearved kehtetuks muutuvad |
| Kasutajatoe pöördumine | on seotud ajaarvestusega ja viitab seetõttu automaatselt uuele arvele |
| Chatter | uuel arvel teade kõigi lähtearvetega, igal lähtearvel teade koos lingiga uuele arvele |
| merged_into_move_id / merged_from_move_ids | mõlemas suunas salvestatud seos |
Maksuridu, maksetingimuste ridu ning ümardus- ja maksesoodustuse ridu ei kopeerita, vaid Odoo arvutab need sisu põhjal uuesti. Seega on ühendatud arvel iga maksumäära kohta üks maksurida, mitte üks iga lähtearve kohta. Uus arve luuakse numbrita mustandina; ühendamine ise dokumendinumbrit ei kasuta.
Pealkirjad: klient näeb iga rea päritolu
See on funktsioon, millest on igapäevatöös tõesti kasu. Iga lähtearve ridade kohale lisab moodul jaotise rea – sama elemendi, mida Odoo ise kasutab jaotises „Ettemaksed“:
BE10181 <- Pealkiri
22,500 x Tehniku töötund 3.577,50
Vahesumma 3.577,50
BE10182 · Pöördumine: HT00219 <- Pealkiri
3,000 x Tehniku töötund 477,00
Vahesumma 477,00
NETOSUMMA 4.054,50
Pealkiri trükitakse kliendile saadetavale dokumendile ja Odoo standardne arvearuanne lisab automaatselt iga jaotise vahesumma. Nii näeb klient ka iga osa maksumust.
Pealkiri koostatakse lähtearvel tegelikult olemas olevate andmete põhjal:
- tellimused otse arveridade seostest – nii on nimed täpsed; kui tellimustega seosed puuduvad, kasutatakse välja invoice_origin vabateksti
- pöördumised, mis leitakse ajaarvestuse kaudu – kuvatakse kujul Pöördumine: HT00219 või Pöördumised: …, kuni viis pöördumist ja lisaks „ning veel N“
- kui kumbagi pole: lähtearve number, selle puudumisel viide
- kui midagi pole: neutraalne „Muud read“, et ühe lähtearve read ei sulanduks märkamatult eelmise plokiga
Puuduvad andmed jäetakse välja, neid ei mõelda juurde. Pöördumine trükitakse selle enda numbriga – helpdesk_mgmt number, Enterprise’i ticket_ref või mudeli kuvatav nimi –, mitte kunagi andmebaasi ID-ga.
Pealkirjad koostatakse kliendi keeles, nagu Odoo teeb tellimustest arvete loomisel. Chatter jääb kasutaja keelde.
Pealkirjal pole toodet, kogust, hinda, maksu, kontot ega jaotust kulukohtade vahel. See ei saa mõjutada summasid, maksubaasi ega kuluarvestust. Kui pealkirjad viisardis välja lülitada, saadakse täpselt sama arve, mis tekiks ilma selle funktsioonita – test võrdleb mõlemat tulemust sendi täpsusega.
Mis saab lähtearvetest
Viisard pakub kolme valikut:
- Tühista (vaikimisi, soovitatav). Mustandi tühistamisel pole raamatupidamislikke tagajärgi: ei dokumendinumbrit ega kannet. Arved jäävad andmebaasi tühistatud dokumentidena koos Chatteri ja uuele arvele viiva lingiga. Müügitellimuse qty_invoiced jätab tühistatud dokumendid arvestamata, midagi ei loeta topelt. See valik võimaldab toimunust aru saada ka kuue kuu pärast.
- Kustuta. Pöördumatu. Koos kirjega kaovad Chatter ja tagasiviide; alles jääb ainult uuel arvel olev teade. Sobib ajutistele mustanditele, mida pole enam vaja näha.
- Jäta mustandiks. Lähtearved jäävad avatuks. Nende müügitellimused arvestavad siis arveldatuks nii lähtearve kui ka uue arve – töö näib olevat topelt arveldatud, kuni keegi mustandid käsitsi korrastab. See on mõeldud harvadeks juhtudeks, kui enne otsustamist soovitakse arveid võrrelda. Test kontrollib just seda topeltarvestust, et see ei tuleks kellelegi üllatusena.
Piirangud – mida moodul teadlikult ei tee
Palun lugege enne töökeskkonnas kasutuselevõttu:
- Ainult mustandid. Konteeritud arveid ei ühendata. Selleks tuleb kasutada kreeditarveid, mitte kopeerimist.
- Varem konteeritud ja seejärel mustandiks tagasi muudetud arveid ei lubata ühendada. Neil on number ja konteerimisajalugu; nende peitmine teise dokumenti ei tohiks toimuda märkamatult hulgitoimingu käigus.
- Eri partnerite, valuutade, ettevõtete või andmike arveid ei ühendata. Neile ei saa määrata ühte põhjendatud ühist väärtust, seega keeldub moodul ühendamisest ega hakka oletama.
- payment_reference ei kanta üle. Struktureeritud makseviited tuvastavad ühe dokumendi; kahe viite kokkuliitmisel pole pangas tulemusel vastet. Uus arve saab konteerimisel oma viite.
- Ettemaksuread kopeeritakse nagu kõik teised read. Kui lähtearved sisaldavad moodulist sale pärinevaid ettemaksuridu, tuleb tulemust enne konteerimist kontrollida.
- Automaatselt seotakse ümber ainult timesheet_invoice_id. Kõik muud mudelid, millel on Many2one-seos mudeliga account.move (kohandatud arveldusprotsessid, tellimuste seosed, EDI-edastused), viitavad endiselt lähtearvele. Nende jaoks on laiendusmeetod _merge_draft_relink.
- Ühesuguseid arveridu ei koondata – see on teadlik valik. Kui soovite lühikest ja kompaktset arvet, ei sobi see moodul teile: sellise arve hind oleks seoste kaotamine algandmetega.
- Pealkirjad luuakse ühekordselt ühendamise käigus. Seejärel on need tavalised jaotiseread: neid saab muuta ja kustutada ning need ei uuene, kui tellimuse või pöördumise nime hiljem muudetakse.
- Pealkirjas loetletakse kogu lähtearvega seotud pöördumised, mitte üksiku arvereaga seotud pöördumised.
Paigaldamine Odoo 19 Communitysse
Paigaldamine käib nagu tavalise Odoo lisamooduli puhul:
- Kopeerige mooduli kataloog seadistatud lisamoodulite otsinguteele.
- Värskendage Odoos rakenduste loendit.
- Paigaldage moodul account_invoice_merge_draft.
Moodul sõltub ainult account'ist. Kõik, mida see teab sale, purchase, project, hr_timesheet, sale_timesheet või mõne Helpdesk'i mooduli kohta, tuvastatakse käitusajal – see paigaldub ja töötab ka puhtal arveldusandmebaasil.
Seejärel avage Raamatupidamine → Kliendid → Arved (või Tarnijad → Arved), valige vähemalt kaks mustandit ja seejärel hammasrattamenüüst → Ühenda arvemustandid. Toiming on saadaval kõigile kasutajatele, kes kuuluvad gruppi Arveldamine / Arvete koostamine.
Mooduli varasemalt versioonilt uuendamisel tuleks üks kord kasutada käsku -u account_invoice_merge_draft --i18n-overwrite, et muudetud väljanimed jõuaksid saksakeelsesse tõlkesse. Uut paigaldust see ei puuduta.
Arendajatele: API ja laiendusmeetodid
Ühendamise saab käivitada ka oma koodist:
python
merged = draft_moves.merge_draft_moves(
extra_vals={"invoice_date": date(2026, 3, 31), "ref": "Q1"},
source_handling="cancel", # "delete" või "keep"
add_source_sections=True, # Pealkirjad; vaikeväärtus True
)
Kui valitud arveid ei saa ühendada, tekitab merge_draft_moves erindi UserError, milles on loetletud kõik keeldumise põhjused. _merge_draft_get_errors() tagastab samad põhjused loendina, erindit tekitamata.
Kui teie kohandatud mudelites on tagasiviiteid mudelile account.move, kirjutage üle meetod _merge_draft_relink:
python
class AccountMove(models.Model):
_inherit = "account.move"
def _merge_draft_relink(self, new_move):
super()._merge_draft_relink(new_move)
if "my_move_id" not in self.env["my.model"]._fields:
return
self.env["my.model"].search([("my_move_id", "in", self.ids)]).write(
{"my_move_id": new_move.id}
)
Kui tagasiviide asub arvereal, pole seda moodulit üldse vaja: piisab Odoo enda laiendusmeetodist account.move.line._copy_data_extend_business_fields ning väli kantakse üle nii ühendamisel, tühistamisel kui ka paljundamisel. Teiste kasutajatoe moodulite või pealkirjade teistsuguse sõnastuse jaoks on meetodid _merge_draft_get_source_tickets() ja _merge_draft_section_name().
Testitud enne pärisandmetel kasutamist
48 testi katavad segaolekud, erinevad partnerid, valuutad ja dokumenditüübid, read koos müügi- või ostutellimusega ja ilma, maksud, jaotised ja märkmed, kuluallika jaotused, ajaarvestuse ümbersuunamise, kõik kolm lähtearvete suvandit, viisardi ja pealkirjad – et need on vaikimisi aktiivsed, et nende väljalülitamine reprodutseerib vana tulemuse sendi täpsusega, et pealkiri ei kanna summasid ega kontosid, et ühe allika read jäävad kokku, et pilet ilmub oma numbriga ja mitte kunagi andmebaasi ID-ga.
Testandmed põhinevad aktiivse ettevõtte olemasoleval kontoplaanil, mitte abiklassil AccountTestInvoicingCommon – see abiklass ei käivitu migreeritud tootmisandmebaasides sageli üldse, kuid moodul peab töötama just sellistes andmebaasides.
odoo-bin -d <db> -u account_invoice_merge_draft --test-enable \
--test-tags /account_invoice_merge_draft --stop-after-init
Nagu iga raamatupidamise lisamooduli puhul, soovitame paigaldust esmalt kontrollida testkeskkonnas oma andmebaasi koopiaga.
Tasuta ja avatud lähtekoodiga Odoo kogukonnale
Meie Biricon IT Services GmbH-s töötame lahendusi välja esmalt oma ettevõtte konkreetsete nõuete jaoks. Kui sellest tekib üldiselt kasutatav moodul, ei soovi me seda ühes paigalduses peita.
Seetõttu on Merge Draft Invoices saadaval tasuta avatud lähtekoodiga projektina. Lähtekoodiga saab tutvuda, seda kontrollida, kohandada ja AGPL-3 litsentsi tingimustel edasi arendada.
Meie eesmärk polnud võimalikult lühike arve, vaid arve, mille iga rea juurest jõuab ka aasta pärast tagasi vastava tellimuse, pöördumise ja ajakandeni.
Projekt, lähtekood ja kaastöö
Kogu lähtekood, paigaldusjuhised ja tehniline dokumentatsioon on saadaval GitHubis:
Ava Odoo 19 Merge Draft Invoices GitHubis
Ootame Odoo kogukonnalt kasutuskogemusi, veateateid, parendusettepanekuid ja kaastööd.
Tasuta. Läbipaistev. Avatud lähtekoodiga. Odoo 19 Community jaoks.