Kes arveldab Odoos tellimuste, Helpdesk'i piletite ja ajaarvestuse alusel, tunneb tulemust: klient saab kuu lõpus mitte ühe arve, vaid viis. Iga arve pärineb eri tellimusest või piletist, iga arve on sisuliselt õige – ja siiski küsib klient, kas see ei mahuks ühele dokumendile.
Just selleks ei ole Odoo 19 Communitys puhast lahendust. Tuntud OCA moodul account_invoice_merge ei ole Odoo 19 jaoks veel vabastatud ja see lahendab probleemi viisil, mis kujutab teenusepakkujatele tõsist riski: samasugused read liidetakse kokku ning sellega kaob seos tagasi tellimuse, ülesande ja registreeritud ajani.
Oma Odoo 19 Community paigalduse jaoks töötasime seetõttu välja mooduli Merge Draft Invoices. Kuna see probleem ei puuduta ainult meid, pakume seda tasuta GitHubis vaba AGPL-3 litsentsi all.
Projekti juurde GitHubis:
Miks oma moodul OCA lahenduse asemel?
OCA haldab account_invoice_merge'i juba aastaid hoidlas OCA/account-invoicing. Selle postituse ajal on migreerimine versioonile 19.0 seal veel avatud Pull Request, 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 | samasugused read liidetakse kokku, kogused summeeritakse | iga rida võetakse üle üks ühele |
| Päritolu | invoice_origin / payment_reference ühendatakse päises kokku | päritoluväljad kopeeritakse ridade kaupa Odoo enda _copy_data_extend_business_fields konksu kaudu |
| Ajaarvestus | ei võeta arvesse | timesheet_invoice_id suunatakse ümber uuele arvele |
| Kliendile loetav | mitte midagi | pealkiri iga allika ridade kohal koos tellimuse ja piletiga |
| Lähtearved | tühistatakse | tühistada (vaikimisi), kustutada või säilitada – selgelt nimetatud tagajärgedega |
Samasuguste ridade kokkuliitmine on otsustav erinevus. Kokkuliidetud rida saab kanda ainult ühte päritolu. Niipea kui kaks rida kahest eri tellimusest näevad välja ühesugused, on seos arvelt tagasi tellimuse, ülesande ja ajabroneeringuni kadunud. Teenusepakkujas, kus arveldus käib ülesehitusega pilet → ajaarvestus → arve, tähendab see: samad tunnid arveldatakse topelt või kaovad.
Meie moodul seetõttu põhimõtteliselt midagi kokku ei liida. Ühendatud arvel on täpselt sama palju ridu kui tema allikatel kokku.
OCA moodulist ei ole koodi üle võetud. Mõlemad moodulid on AGPL-3 all.
Mida moodul teeb
Märkige arvete loendivaates kaks või rohkem mustandit, valige toimingute menüüst Mustandarvete ühendamine – viisard näitab valikut, kontrolle ja lähtearvete suvandeid. Kinnitamise järel jõuate otse uuele arvele.
Enne ühendamist moodul kontrollib, ja seda kõiki punkte korraga, et iga parandusega ei ilmuks järgmine viga:
- valitud vähemalt kaks arvet
- kõik olekus Mustand
- ühtegi ei ole kunagi kantud (mustandiks tagasi pandud dokument säilitab oma kandeajaloo ja lükatakse tagasi)
- ühtegi ei ole juba ühendatud
- kõik on müügiarve, ostuarve, kreeditarve või dokument – mitte puhtalt kandelaused
- sama partner, dokumenditüüp, ettevõte, valuuta ja päevik
Erinevused maksetingimustes, maksude vastendamises, tarneaadressis, pangakontos või müüjas ei blokeeri. Viisard hoiatab ja võtab üle vanima valitud arve väärtuse.
Mis säilib
Mooduli tuum on see, et iga seos, mis arverealt on oma päritoluni, on olemas ka uuel arvel:
| Seos | Käsitlus |
|---|---|
| Müügitellimuse read (sale_line_ids) | kopeeritakse ridade kaupa Odoo _copy_data_extend_business_fields kaudu |
| Ostutellimuse read (purchase_line_id) | samamoodi |
| Kuluallika jaotus (analytic_distribution) | kopeeritakse ridade kaupa |
| muud päritoluväljad rea kohta | automaatselt, kui pakkuv moodul rakendab dokumenteeritud Odoo konksu |
| Päritolu ja viide arve päises | ühendatud, duplikaatidest puhastatud, viisardis muudetav |
| Müügitellimus: invoice_ids, invoice_status, qty_invoiced | arvutatakse ridade põhjal – tellimus tunneb uue arve ise ära |
| Ajaarvestus (timesheet_invoice_id) | suunatakse ümber uuele arvele, enne kui allikad muutuvad kehtetuks |
| Helpdesk'i pilet | on seotud ajaarvestusega ja viitab seega automaatselt uuele arvele |
| Chatter | sõnum uuel arvel koos kõigi allikatega, sõnum igal allikal koos lingiga uuele |
| merged_into_move_id / merged_from_move_ids | salvestatud seos mõlemas suunas |
Maksuridu, maksetingimuste ridu, ümardus- ja allahindlusridu ei kopeerita, vaid Odoo arvutab need sisu põhjal uuesti. Ühendatud arvel on seega üks maksurida maksumäära kohta, mitte üks allika kohta. See luuakse nummerdamata mustandina; ühendamine ise ei kuluta dokumendinumbrit.
Pealkirjad: klient näeb, kust iga rida pärineb
See on funktsioon, mis teeb igapäevaelus vahet. Iga lähtearve ridade kohale lisab moodul jaotisrea – sama elemendi, mida Odoo ise kasutab jaotise „Ettemaksed“ jaoks:
BE10181 <- Pealkiri
22,500 x Tehnikutund 3.577,50
Vahesumma 3.577,50
BE10182 · Pilet: HT00219 <- Pealkiri
3,000 x Tehnikutund 477,00
Vahesumma 477,00
NETOSUMMA 4.054,50
Pealkiri trükitakse dokumendile, mille klient saab, ja Odoo standardne arvearuanne lisab iseenesest jaotise kohta vahesumma. Nii näeb klient ka seda, mis iga osa maksis.
Silt koostatakse sellest, mis allikal tegelikult on:
- tellimused, otse ridade seostest – nimed on seega täpsed; kui tellimuse seosed puuduvad, kasutatakse invoice_origin vabatekstina
- piletid, tuvastatud ajaarvestuse kaudu – väljastatakse kujul Pilet: HT00219 või Piletid: …, piiratud viiega pluss „ja N veel“
- kui kumbagi ei ole: lähtearve number, seejärel selle viide
- kui midagi ei ole: neutraalne „Muud read“, et ühe allika read ei kaoks kunagi vaikimisi ülemisse plokki
Mis puudub, jäetakse ära, mitte ei mõelda välja. Pilet trükitakse oma numbriga – helpdesk_mgmt number, Enterprise'i ticket_ref või mudeli kuvanimi – mitte kunagi andmebaasi ID-ga.
Pealkirjad kirjutatakse kliendi keeles, nagu Odoo teeb arvete loomisel tellimustest. Chatter jääb kasutaja keelde.
Pealkiri ei kanna toodet, kogust, hinda, maksu, kontot ega kuluallika jaotust. See ei saa mõjutada summasid, maksubaasi ega kuluarvestust. Kes viisardis pealkirjad välja lülitab, saab täpselt selle arve, mis tekiks ilma selle funktsioonita – test võrdleb mõlemat tulemust sendi täpsusega.
Mis saab lähtearvetest
Viisard pakub kolme suvandit:
- Tühistada (vaikimisi, soovitatav). Mustandi tühistamisel ei ole tagajärgi: ei dokumendinumbrit ega kannet. Arved jäävad andmebaasi tühistatud dokumentidena koos Chatteri ja lingiga uuele arvele. qty_invoiced müügitellimusel jätab tühistatud dokumendid vahele, midagi ei loeta topelt. See on suvand, mis on jälgitav ka kuue kuu pärast.
- Kustutada. Pöördumatult. Chatter ja tagasiviide kaovad koos kirjega; alles jääb ainult sõnum uuel arvel. Mõttekas ühekordsete mustandite jaoks, mida keegi enam näha ei tohiks.
- Jätta mustandiks. Allikad jäävad avatuks. Nende müügitellimused loevad siis allika ja uue arve arveldatuks – töö näeb välja topeltarveldatuna, kuni keegi mustandid käsitsi puhastab. Mõeldud harvaks juhuks, kui enne otsustamist soovitakse võrrelda. Test fikseerib just selle topeltlugemise, et see kedagi üllatama ei paneks.
Piirid – mida moodul teadlikult ei tee
Palun lugege enne tootmiskasutust:
- Ainult mustandid. Kantud arveid ei ühendata. See on kreeditarvete ülesanne, mitte kopeerimistoiming.
- Korra kantud, tagasi pandud mustandid lükatakse tagasi. Neil on number ja kandeajalugu; selle peitmine teise dokumenti ei ole midagi, mida hulgitoiming vaikselt tegema peaks.
- Partnerite, valuutade, ettevõtete ega päevikute üleselt ei ühendata. Selleks puudub mõistlik üksikväärtus, mistõttu moodul lükkab tagasi, mitte ei oska arvata.
- payment_reference'it ei võeta üle. Struktureeritud maksoviited identifitseerivad dokumendi; kaks kokku aetud viidet ei sobi pangas millegagi. Uus arve saab kandmisel oma viite.
- Ettemaksuread kopeeritakse nagu iga teine rida. Kui allikad sisaldavad sale-i ettemaksuridu, tuleb tulemust enne kandmist kontrollida.
- Automaatselt suunatakse ümber ainult timesheet_invoice_id. Iga muu mudel, millel on Many2one väli account.move'ile (oma arveldustsüklid, tellimuste seosed, EDI-edastused), viitab edasi allikale. Selleks on olemas konks _merge_draft_relink.
- Samasuguseid ridu ei liideta kokku – teadlikult. Kes soovib lühikest, korrastatud arvet, on siin valel teel ja maksaks selle eest päritoluseostega.
- Pealkirjad luuakse ühendamisel ühekordselt. Pärast seda on need tavalised jaotiserid: muudetavad, kustutatavad ja neid ei uuendata, kui tellimust või piletit hiljem ümber nimetatakse.
- Pealkiri nimetab kogu lähtearve piletid, mitte üksiku rea omad.
Paigaldus Odoo 19 Communitysse
Paigaldus toimub nagu tavalise Odoo lisamooduli puhul:
- Kopeerige moodulikaust seadistatud addons-teele.
- Uuendage 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: Raamatupidamine → Kliendid → Arved (või Tarnijad → Arved), märkige kaks või rohkem mustandit, hammasrattamenüü → Mustandarvete ühendamine. Toiming on saadaval kõigile kasutajatele, kellel on rühm Arveldus / Faktureerimine.
Kes uuendab mooduli varasemast versioonist, peaks ühekordselt tegema uuenduse käsuga -u account_invoice_merge_draft --i18n-overwrite, et muudetud väljanimed jõuaksid saksa tõlkesse. Uuspaigaldust see ei puuduta.
Arendajatele: API ja konksud
Ühendamist saab kutsuda välja 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; vaikimisi True
)
merge_draft_moves viskab UserError'i koos kõigi tagasilükkamise põhjustega, kui valikut ei saa ühendada. _merge_draft_get_errors() tagastab samad põhjused loendina ilma erandita.
Kes on loonud oma tagasiviited account.move'ile, kirjutab üle _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}
)
Kellel on tagasiviide arvereal, ei vaja seda moodulit üldse: Odoo enda konks account.move.line._copy_data_extend_business_fields on piisav ning väli võetakse üle nii ühendamisel, tühistamisel kui ka dubleerimisel. Teiste Helpdesk'i moodulite või pealkirjade teistsuguse sõnastuse jaoks on olemas _merge_draft_get_source_tickets() ja _merge_draft_section_name().
Testitud enne, kui see tootmisandmetel töötab
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 tuginevad aktiivse ettevõtte olemasolevale kontoplaanile, mitte AccountTestInvoicingCommon'ile – see abiklass ei käivitu migreeritud tootmisandmebaasidel sageli ja just sellistel peab moodul töötama.
odoo-bin -d <db> -u account_invoice_merge_draft --test-enable \
--test-tags /account_invoice_merge_draft --stop-after-init
Nagu iga raamatupidamisvaldkonna laienduse 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.
Merge Draft Invoices on seetõttu tasuta kättesaadav avatud lähtekoodiga projektina. Lähtekoodi saab vaadata, kontrollida, kohandada ja AGPL-3 litsentsi raames edasi arendada.
Meie eesmärk ei olnud kõige lühem võimalik arve, vaid arve, mille puhul viib iga rida ka aasta pärast tagasi oma tellimuse, piletini ja ajabroneeringuni.
Projekt, lähtekood ja kaastöö
Täielik lähtekood, paigaldusjuhised ja tehniline dokumentatsioon on kättesaadavad GitHubis:
Ava Odoo 19 Merge Draft Invoices GitHubis
Ootame hea meelega praktilisi kogemusi, veateateid, parendusettepanekuid ja kaastööd Odoo kogukonnalt.
Tasuta. Jälgitav. Avatud lähtekoodiga. Odoo 19 Communityle.