Skip to Content

Odoo 19 Community: faktura-zirriborroak bateratzea — gure Merge Draft Invoices kode irekiko modulua

2026(e)ko irailakren 18(a) by
Odoo 19 Community: faktura-zirriborroak bateratzea — gure Merge Draft Invoices kode irekiko modulua
Alexander Biringer | Biricon IT Services GmbH

Odoo-n eskaeretatik, Helpdesk tiketetatik eta denbora-erregistrotik fakturatzen duenak emaitza ezagutzen du: bezero batek hilaren amaieran ez du faktura bakarra jasotzen, bost baizik. Bakoitza eskaera edo tiketa desberdin batetik dator, bakoitza teknikoki zuzena da – eta, hala ere, bezeroak galdetzen du ea ez ote zen dokumentu bakarrean sartuko.

Hain zuzen ere, Odoo 19 Community bertsioak ez du horretarako irtenbide egokirik. OCAren account_invoice_merge modulu ezaguna oraindik ez dago Odoo 19rako argitaratuta, eta arazoa konpontzeko erabiltzen duen moduak arrisku larria dakar zerbitzu-emaileentzat: lerro berdinak bateratzen ditu, eta, horren ondorioz, eskaerarekiko, zereginarekiko eta erregistratutako denborarekiko lotura galtzen da.

Horregatik, gure Odoo 19 Community instalaziorako Merge Draft Invoices modulua garatu dugu. Arazo honek guri bakarrik eragiten ez digunez, GitHuben doan jarri dugu eskuragarri, AGPL-3 lizentzia librearekin.

Proiektua GitHuben:

Odoo 19 Merge Draft Invoices

Zergatik garatu modulu propio bat OCAren irtenbidea erabili beharrean?

OCAk urte asko daramatza account_invoice_merge modulua mantentzen OCA/account-invoicing biltegian. Artikulu hau idazteko unean, 19.0 bertsiorako migrazioa oraindik irekita dagoen pull request bat da, eta ez argitaratutako modulu bat.

Dena den, garrantzitsuagoa da bi moduluek gauza desberdinak egiten dituztela:


OCA account_invoice_mergeMerge Draft Invoices
Emaitzahautatutako fakturetako batean bateratzen dabeti faktura berri bat
Lerroaklerro berdinak elkartu eta kopuruak batu egiten diralerro bakoitza bere horretan kopiatzen da
Jatorriainvoice_origin / payment_reference goiburuan kateatzen diralerro bakoitzeko jatorri-eremuak Odooren _copy_data_extend_business_fields hook propioaren bidez kopiatzen dira
Denbora-erregistroaez da kontuan hartzentimesheet_invoice_id faktura berriarekin lotzen da
Bezeroarentzat irakurgarriaezer ezjatorri bakoitzeko lerroen gainean izenburu bat jartzen da, eskaera eta ticketa adierazita
Jatorrizko fakturakezeztatu egiten diraezeztatu (lehenetsia), ezabatu edo mantendu; aukera bakoitzaren ondorioak argi adierazten dira

Lerro berdinak elkartzea da funtsezko aldea. Elkartuta geratzen den lerro batek jatorri bakarra izan dezake. Bi eskaera desberdinetako bi lerrok itxura bera dutenean, fakturatik eskaerara, zereginera eta denbora-erregistrora itzultzeko lotura galdu egiten da. Fakturazioa ticketa → denbora-erregistroa → faktura katearen bidez egiten duen zerbitzu-enpresa batean, horrek esan nahi du ordu berak bi aldiz fakturatzen direla edo desagertu egiten direla.

Horregatik, gure moduluak ez du inoiz lerrorik elkartzen. Bateratutako fakturak jatorrizko faktura guztiek batera dituzten lerro kopuru bera du, zehatz-mehatz.

Ez da OCA moduluko koderik erabili. Bi moduluek AGPL-3 lizentzia dute.

Zer egiten du moduluak

Fakturen zerrenda-ikuspegian, hautatu bi zirriborro edo gehiago eta aukeratu Bateratu faktura-zirriborroak ekintzen menuan. Morroi batek hautaketa, egiaztapenak eta jatorrizko fakturentzako aukerak erakusten ditu. Berretsi ondoren, faktura berria irekitzen da zuzenean.

Bateratu aurretik, moduluak honako puntu hauek egiaztatzen ditu, denak batera, zuzenketa bakoitzaren ondoren hurrengo errorea agertzen ez joateko:

  • gutxienez bi faktura hautatu direla
  • guztiak Zirriborroa egoeran daudela
  • bat ere ez dela inoiz kontabilizatu (zirriborro-egoerara itzulitako dokumentu batek kontabilizazio-historia gordetzen du, eta baztertu egiten da)
  • bat ere ez dela aurretik bateratu
  • guztiak bezero-fakturak, hornitzaile-fakturak, abonu-fakturak edo ordainagiriak direla; ez kontabilitate-idazpen hutsak
  • guztiek bazkide, dokumentu mota, enpresa, moneta eta egunkari bera dituztela

Ordainketa-baldintzetan, zerga-posizioan, entrega-helbidean, banku-kontuan edo saltzailean dauden desberdintasunek ez dute bateratzea eragozten. Morroiak abisua ematen du eta hautatutako fakturarik zaharrenaren balioa hartzen du.

Zer mantentzen da

Moduluaren funtsa da faktura-lerro bakoitzak jatorriarekin dituen lotura guztiak faktura berrian ere mantentzea:

LoturaTratamendua
Salmenta-eskaeraren lerroak (sale_line_ids)lerroz lerro kopiatzen dira, Odooren _copy_data_extend_business_fields bidez
Erosketa-eskaeraren lerroak (purchase_line_id)modu berean
Kostu-zentroen araberako banaketa (analytic_distribution)lerroz lerro kopiatzen da
lerro bakoitzeko beste jatorri-eremu batzukautomatikoki, eremuak gehitzen dituen moduluak dokumentatutako Odoo hooka inplementatzen badu
Jatorria eta erreferentzia fakturaren goiburuanbateratu egiten dira, bikoiztuak kentzen dira eta morroian editatu daitezke
Salmenta-eskaera: invoice_ids, invoice_status, qty_invoicedlerroetatik kalkulatzen dira; eskaerak berez ezagutzen du faktura berria
Denbora-erregistroa (timesheet_invoice_id)faktura berriarekin berriz lotzen da, jatorrizko fakturak baliogabetu aurretik
Helpdesk ticketadenbora-erregistroarekin lotuta dagoenez, automatikoki egiten dio erreferentzia faktura berriari
Chatterfaktura berrian jatorrizko faktura guztiak biltzen dituen mezu bat; jatorrizko faktura bakoitzean, berrirako esteka duen mezu bat
merged_into_move_id / merged_from_move_idsbi noranzkoetan gordetako lotura

Zergen, ordainketa-baldintzen, biribiltzeen eta goiz ordaintzeagatiko deskontuen lerroak ez dira kopiatzen: Odook berriz kalkulatzen ditu edukitik abiatuta. Beraz, bateratutako fakturak zerga-lerro bat du zerga-tasa bakoitzeko, ez jatorrizko faktura bakoitzeko. Zenbakirik gabeko zirriborro gisa sortzen da; bateratzeak berak ez du dokumentu-zenbakirik kontsumitzen.

Izenburuak: bezeroak lerro bakoitza nondik datorren ikusten du

Eguneroko lanean aldea egiten duen funtzioa da hau. Jatorrizko faktura bakoitzaren lerroen gainean, moduluak atal-lerro bat jartzen du; Odook berak «Aurrerakinak» atalerako erabiltzen duen elementu bera:

BE10181                                     <- Izenburua
  22,500 x Teknikari-ordua        3.577,50
                    Guztizko partziala 3.577,50
BE10182 · Ticketa: HT00219                   <- Izenburua
   3,000 x Teknikari-ordua          477,00
                    Guztizko partziala   477,00
                      ZENBATEKO GARBIA 4.054,50

Izenburua bezeroak jasotzen duen dokumentuan inprimatzen da, eta Odooren faktura-txosten estandarrak berez gehitzen du atal bakoitzaren guztizko partziala. Horrela, bezeroak zati bakoitzak zenbat balio izan duen ere ikusten du.

Etiketa osatzeko, jatorrizko fakturak benetan duen informazioa erabiltzen da:

  1. eskaerak, lerroen loturetatik zuzenean hartuta; horrela, izenak zehatzak dira. Eskaera-loturarik ez badago, invoice_origin eremuko testu librea erabiltzen da
  2. ticketak, denbora-erregistroaren bidez aurkituta; «Ticketa: HT00219» edo «Ticketak: …» gisa erakusten dira, gehienez bost adierazita eta, gehiago badaude, «eta beste N» gehituta
  3. bietakorik ez badago: jatorrizko fakturaren zenbakia, eta, halakorik ezean, haren erreferentzia
  4. ezer ez badago: «Beste lerro batzuk» izenburu neutroa, jatorrizko faktura baten lerroak aurreko blokean oharkabean gal ez daitezen

Falta dena ez da jartzen; ez da ezer asmatzen. Ticketa bere zenbakiarekin inprimatzen da —helpdesk_mgmt zenbakia, Enterprise-ticket_ref edo modeloaren bistaratze-izena—, inoiz ez datu-baseko IDarekin.

Izenburuak bezeroaren hizkuntzan idazten dira, Odook eskaeretatik fakturak sortzean egiten duen bezala. Chatterreko mezuak erabiltzailearen hizkuntzan mantentzen dira.

Izenburu batek ez du produkturik, kopururik, preziorik, zergarik, konturik edo kostu-zentroen araberako banaketarik. Ezin du eraginik izan guztizkoetan, zerga-oinarrian edo kostuen kontabilitatean. Morroian izenburuak desaktibatzen badira, funtzio hori gabe sortuko litzatekeen faktura berbera lortzen da; proba batek bi emaitzak zentimoraino alderatzen ditu.

Zer gertatzen da jatorrizko fakturekin

Morroiak hiru aukera eskaintzen ditu:

  • Ezeztatu (lehenetsia, gomendatua). Zirriborro bat ezeztatzeak ez du ondoriorik: ez dago dokumentu-zenbakirik, ezta kontabilizaziorik ere. Fakturak datu-basean geratzen dira, ezeztatutako dokumentu gisa, Chatter eta faktura berrirako esteka gordeta. Salmenta-eskaeraren qty_invoiced eremuak ez ditu ezeztatutako dokumentuak kontuan hartzen, eta ez da ezer bi aldiz zenbatzen. Aukera honekin, sei hilabete geroago ere argi ikusi ahal izango da zer egin zen.
  • Ezabatu. Atzera bueltarik gabe. Chatter eta atzeranzko lotura erregistroarekin batera desagertzen dira; faktura berriko mezua baino ez da geratzen. Egokia da beste inork ikusi behar ez dituen behin-behineko zirriborroetarako.
  • Zirriborro gisa utzi. Jatorrizko fakturak irekita geratzen dira. Haien salmenta-eskaerek jatorrizko faktura eta faktura berria hartzen dituzte fakturatutzat; beraz, lana bi aldiz fakturatu dela dirudi, norbaitek zirriborroak eskuz garbitu arte. Erabakia hartu aurretik alderaketa egin nahi den kasu bakanetarako pentsatuta dago. Proba batek berariaz egiaztatzen du zenbaketa bikoitz hori, inor ezustean harrapa ez dezan.

Mugak: moduluak nahita egiten ez duena

Irakurri produkzioan erabili aurretik:

  • Zirriborroak soilik. Kontabilizatutako fakturak ez dira bateratzen. Horretarako abonu-fakturak erabili behar dira; ez da kopiatze-eragiketa bat.
  • Kontabilizatu ondoren zirriborro-egoerara itzulitako fakturak baztertu egiten dira. Zenbakia eta kontabilizazio-historia dituzte; informazio hori beste dokumentu batean ezkutatzea ez da multzokako ekintza batek isilean egin beharko lukeen zerbait.
  • Ez dira bateratzen bazkide, moneta, enpresa edo egunkari desberdinetako fakturak. Ez dago guztientzat egokia den balio bakarrik; beraz, moduluak eskaera baztertzen du, asmatu beharrean.
  • payment_reference ez da kopiatzen. Ordainketa-erreferentzia egituratuek dokumentu bat identifikatzen dute; bi elkartuta, ez datoz bat bankuko ezerekin. Faktura berriak bere erreferentzia jasotzen du kontabilizatzean.
  • Aurrerakin-lerroak gainerako lerroak bezala kopiatzen dira. Jatorrizko fakturek sale moduluko aurrerakin-lerroak badituzte, emaitza egiaztatu behar da kontabilizatu aurretik.
  • timesheet_invoice_id baino ez da automatikoki berriz lotzen. account.move modelorako Many2one eremua duen beste edozein modelok (fakturazio-prozesu propioak, harpidetza-loturak, EDI bidalketak) jatorrizko fakturari egiten dio erreferentzia oraindik. Horretarako dago _merge_draft_relink hooka.
  • Lerro berdinak ez dira elkartzen, nahita. Faktura labur eta txukun bat nahi duenarentzat hau ez da modulu egokia: hori lortzeko, jatorriarekiko loturak galduko lituzke.
  • Izenburuak bateratzean sortzen dira, behin bakarrik. Hortik aurrera, atal-lerro arruntak dira: editatu eta ezabatu daitezke, eta ez dira eguneratzen gero eskaerari edo ticketari izena aldatzen bazaio.
  • Izenburuak jatorrizko faktura osoko ticketak aipatzen ditu, ez lerro bakoitzarenak.

Instalazioa Odoo 19 Communityn

Odooren ohiko modulu osagarri bat bezala instalatzen da:

  1. Kopiatu moduluaren direktorioa konfiguratutako gehigarrien bide batera.
  2. Eguneratu Odooko aplikazioen zerrenda.
  3. Instalatu account_invoice_merge_draft modulua.

Moduluak account baino ez du mendekotasun gisa. sale, purchase, project, hr_timesheet, sale_timesheet edo Helpdesk modulu bati buruz behar duen informazio guztia exekuzioan lortzen du; beraz, fakturaziorako soilik erabiltzen den datu-base batean ere instalatu eta erabil daiteke.

Ondoren: Kontabilitatea → Bezeroak → Fakturak (edo Hornitzaileak → Fakturak); hautatu bi zirriborro edo gehiago, eta joan engranajearen menura → Bateratu faktura-zirriborroak. Ekintza Fakturazioa / Fakturatzea taldeko erabiltzaile guztientzat dago erabilgarri.

Moduluaren aurreko bertsio batetik eguneratzen dutenek behin exekutatu beharko lukete eguneratzea -u account_invoice_merge_draft --i18n-overwrite aukerekin, aldatutako eremu-izenak alemanezko itzulpenean ere eguneratzeko. Horrek ez die instalazio berriei eragiten.

Garatzaileentzat: APIa eta hookak

Bateratzea norberaren kodetik ere dei daiteke:

python

merged = draft_moves.merge_draft_moves(
    extra_vals={"invoice_date": date(2026, 3, 31), "ref": "Q1"},
    source_handling="cancel",   # "delete" edo "keep"
    add_source_sections=True,   # Izenburuak; lehenetsia True
)

Hautatutako fakturak ezin badira bateratu, merge_draft_moves metodoak UserError bat jaurtitzen du, baztertzeko arrazoi guztiekin. _merge_draft_get_errors() metodoak arrazoi berak zerrenda gisa itzultzen ditu, salbuespenik jaurti gabe.

account.move modelora itzultzeko lotura propioak dituztenek _merge_draft_relink gainidatzi behar dute:

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}
        )

Atzeranzko lotura faktura-lerroan dutenek ez dute modulu hau behar: Odooren account.move.line._copy_data_extend_business_fields hook propioa nahikoa da, eta eremua berdin kopiatzen da bateratzean, ezeztatzean eta bikoiztean. Beste Helpdesk modulu batzuetarako edo izenburuak beste modu batera idazteko, _merge_draft_get_source_tickets() eta _merge_draft_section_name() daude.

Produkzioko datuekin erabili aurretik probatua

48 probak honako hauek hartzen dituzte barne: egoera desberdinetako fakturak; bazkide, moneta eta dokumentu mota desberdinak; salmenta- edo erosketa-eskaera duten eta ez duten lerroak; zergak; atalak eta oharrak; kostu-zentroen araberako banaketak; denbora-erregistroak berriz lotzea; jatorrizko fakturentzako hiru aukerak; morroia; eta izenburuak. Azken horiei dagokienez, egiaztatzen da lehenespenez aktibatuta daudela, desaktibatzean aurreko emaitza zentimoraino erreproduzitzen dela, izenburu batek ez duela zenbatekorik edo konturik, jatorrizko faktura bakoitzaren lerroak elkarrekin mantentzen direla eta ticketa bere zenbakiarekin agertzen dela, inoiz ez datu-baseko IDarekin.

Probetako datuak enpresa aktiboak lehendik duen kontu-planean oinarritzen dira, AccountTestInvoicingCommon erabili beharrean. Izan ere, laguntzaile hori sarritan ez da abiarazten migratutako produkzioko datu-baseetan, eta hain zuzen ere horrelakoetan funtzionatu behar du moduluak.

odoo-bin -d <db> -u account_invoice_merge_draft --test-enable \
         --test-tags /account_invoice_merge_draft --stop-after-init

Kontabilitateko edozein hedapenekin bezala, instalazioa lehenik proba-ingurune batean egiaztatzea gomendatzen dugu, norberaren datu-basearen kopia bat erabiliz.

Doakoa eta kode irekikoa, Odoo Communityrentzat

Biricon IT Services GmbHn, gure jarduerako behar zehatzei erantzuteko garatzen ditugu irtenbideak lehenik. Hortik erabilera orokorreko modulu bat sortzen bada, ez dugu instalazio bakar batean ezkutatuta utzi nahi.

Horregatik, Merge Draft Invoices doan dago eskuragarri, kode irekiko proiektu gisa. Iturburu-kodea ikusi, aztertu, egokitu eta garatzen jarrai daiteke, AGPL-3 lizentziaren baldintzen barruan.

Gure helburua zen faktura bat sortzea, urtebete geroago ere lerro bakoitzetik bere eskaerara, ticketera eta denbora-erregistrora itzultzeko aukera emango zuena, ahalik eta fakturarik laburrena lortzea baino.

Proiektua, iturburu-kodea eta parte-hartzea

Iturburu-kode osoa, instalatzeko argibideak eta dokumentazio teknikoa GitHuben daude eskuragarri:

Ireki Odoo 19 Merge Draft Invoices GitHuben

Pozik jasoko ditugu Odoo Communityren erabilera-esperientziak, errore-jakinarazpenak, hobetzeko proposamenak eta ekarpenak.

Doan. Jarraigarria. Kode irekia. Odoo 19 Community-rako.