Skip to Content

Αριθμοί παραστατικών Odoo 19 από πρόθεμα, έτος και μετρητή – το άρθρωμα document_number_prefix_year και η παγίδα της ταυτόχρονης δημιουργίας

3 Νοεμβρίου 2026 | Odoo 19 Community | Δική μας ανάπτυξη
3 Νοεμβρίου 2026 από
Αριθμοί παραστατικών Odoo 19 από πρόθεμα, έτος και μετρητή – το άρθρωμα document_number_prefix_year και η παγίδα της ταυτόχρονης δημιουργίας

Άρθρωμα Odoo 19 document_number_prefix_year: αριθμοί παραστατικών από πρόθεμα, έτος και μετρητή

Το «AN26000001» λέει περισσότερα από το «S00001»: είναι προσφορά, προέρχεται από το 2026 και είναι η πρώτη. Πολλές επιχειρήσεις, ιδίως όσες μεταβαίνουν από παλαιότερο σύστημα στο Odoo, θέλουν να διατηρήσουν τους αριθμούς παραστατικών τους ακριβώς έτσι. Το ίδιο το Odoo αριθμεί προσφορές, παραγγελίες και δελτία αποστολής με δικές του ακολουθίες (S00001, WH/OUT/00001, P00001) και τιμολόγια με το πρόθεμα του ημερολογίου και το έτος (INV/2026/00001).

Γι' αυτό γράψαμε το άρθρωμα Document Numbering by Prefix and Year (document_number_prefix_year) για το Odoo 19. Διατίθεται ως ελεύθερο λογισμικό υπό την άδεια LGPL-3 στο GitHub:

github.com/Alex0176/odoo-document-number-prefix-year

Μια ειλικρινής τοποθέτηση εκ των προτέρων: Το άρθρωμα δεν το χρησιμοποιούμε στην Biricon IT Services. Το δημοσιεύουμε επειδή είναι έτοιμο, τεκμηριωμένο και εφοδιασμένο με δοκιμές και μπορεί να εξοικονομήσει δουλειά σε άλλους. Όποιος το χρησιμοποιήσει πρέπει να διαβάσει τις ενότητες για τα Όρια και Δοκιμές .

Το σχήμα αρίθμησης

Κάθε αριθμός αποτελείται από τρία μέρη: ένα πρόθεμα ανά είδος παραστατικού, το έτος και έναν μετρητή με σταθερό αριθμό ψηφίων. Το πρόθεμα, τη μορφή του έτους (26 ή 2026) και τον αριθμό ψηφίων τα ορίζετε ανά εταιρεία στο Ρυθμίσεις → Αρίθμηση παραστατικών.

Δομή του αριθμού παραστατικού AN26000001 από πρόθεμα, έτος και μετρητή, με πίνακα των ειδών παραστατικών

Καλύπτονται προσφορές, παραγγελίες πελατών, τιμολόγια πελατών και πιστωτικά, δελτία αποστολής, παραλαβές αγαθών και παραγγελίες αγορών. Τα προθέματα στην εικόνα είναι μόνο παραδείγματα: AN, AU, RE, GU, LI, WE, BE. Όποιος αφήσει ένα πρόθεμα κενό, διατηρεί για αυτό το είδος παραστατικού την τυπική αρίθμηση του Odoo. Το άρθρωμα δεν κάνει λοιπόν τίποτα μέχρι να το ρυθμίσετε.

Πώς συμπεριφέρονται οι αριθμοί

  • Κάθε έτος από την αρχή. Ο μετρητής ξεκινά ξανά από το 1 με την αλλαγή του έτους.
  • Συνέχεια μετά από εισαγμένους αριθμούς. Το άρθρωμα αναζητά τον υψηλότερο υπάρχοντα αριθμό του ίδιου προθέματος και έτους, ανεξάρτητα από το μήκος του. Αν από το παλιό σύστημα υπάρχει στη βάση δεδομένων το AN26119, η επόμενη προσφορά είναι AN26000120. Αυτός είναι ο λόγος για τον οποίο το άρθρωμα ενδείκνυται για μεταβάσεις: τα παλιά παραστατικά εισάγονται με τους αρχικούς αριθμούς τους και τα νέα συνεχίζουν απρόσκοπτα.
  • Νέος αριθμός παραγγελίας κατά την επιβεβαίωση. Μια επιβεβαιωμένη προσφορά λαμβάνει, κατόπιν επιθυμίας, αριθμό από την ακολουθία παραγγελιών. Ο αριθμός προσφοράς διατηρείται στο πεδίο Αριθμός προσφοράς της παραγγελίας και είναι ορατός στη φόρμα, στη λίστα και στην αναζήτηση.
  • Τιμολόγια κατά την καταχώριση. Τα τιμολόγια πελατών και τα πιστωτικά λαμβάνουν τον αριθμό τους μόνο κατά την καταχώριση και όχι κατά τη δημιουργία. Τα διαγραμμένα προσχέδια δεν αφήνουν επομένως κενό. Το έτος προέρχεται από την ημερομηνία τιμολογίου: ένα τιμολόγιο της 30.12.2025 που καταχωρίζεται στις 2.1.2026 ονομάζεται RE25….
  • Όλα τα υπόλοιπα παραμένουν. Τα τιμολόγια προμηθευτών, οι πληρωμές, οι λογιστικές εγγραφές και οι εντολές παραγωγής διατηρούν τις τυπικές ακολουθίες του Odoo. Τα υπάρχοντα ονόματα δεν ξαναγράφονται ποτέ, ακόμη και αν απενεργοποιήσετε ξανά το άρθρωμα.

Το λεπτό σημείο: δύο χρήστες ταυτόχρονα

Μια δική μας απόδοση αριθμών φαίνεται απλή: βρες τον υψηλότερο αριθμό, πρόσθεσε ένα. Δεν είναι, μόλις δύο χρήστες δημιουργήσουν την ίδια στιγμή μια προσφορά. Και οι δύο διαβάζουν «υψηλότερος αριθμός = 0», και οι δύο αποδίδουν το AN26000001. Το Odoo διαθέτει γι' αυτό ακολουθίες βάσης δεδομένων στις δικές του σειρές. Σε έναν αριθμό που κατασκευάζεται μόνος του αυτό λείπει, και για προσφορές και παραγγελίες αγορών το Odoo δεν διαθέτει επιπλέον έλεγχο μοναδικότητας στο όνομα: δύο παραστατικά με τον ίδιο αριθμό απλώς αποθηκεύονται.

Η προφανής προστασία είναι ένα κλείδωμα. Το άρθρωμα εφαρμόζει ανά εταιρεία, πρόθεμα και έτος ένα κλείδωμα της βάσης δεδομένων (PostgreSQL Advisory Lock), που διαρκεί μέχρι το τέλος της συναλλαγής. Ο δεύτερος χρήστης περιμένει μέχρι να τελειώσει ο πρώτος. Αυτό όμως δεν αρκεί, και το ανακαλύψαμε με μια δοκιμή σε αντίγραφο της παραγωγικής βάσης δεδομένων:

Χρονική εξέλιξη δύο χρηστών: χωρίς δεύτερη ανάγνωση και οι δύο αποδίδουν τον ίδιο αριθμό, με δεύτερη ανάγνωση ο δεύτερος λαμβάνει τον επόμενο αριθμό

Το Odoo λειτουργεί με το επίπεδο απομόνωσης REPEATABLE READ. Η κατάσταση της βάσης δεδομένων που βλέπει μια συναλλαγή παγώνει στο πρώτο της ερώτημα. Ο χρήστης Β έχει ήδη αυτή την κατάσταση προτού τελειώσει ο Α. Αν ο Β περιμένει στη συνέχεια το κλείδωμα και το αποκτήσει, διαβάζει με την παλιά του κατάσταση «υψηλότερος αριθμός = 0» και αποδίδει τον αριθμό για δεύτερη φορά. Το κλείδωμα ρύθμισε τη σειρά, αλλά δεν ενημέρωσε τη γνώση.

Η λύση είναι μια δεύτερη ανάγνωση μέσω ξεχωριστής, βραχύβιας σύνδεσης με τη βάση δεδομένων, που βλέπει όλες τις γραμμές που έχουν ήδη επιβεβαιωθεί. Κερδίζει η μεγαλύτερη από τις δύο τιμές. Η πρώτη ανάγνωση παραμένει απαραίτητη, διότι μόνο αυτή γνωρίζει αριθμούς που η ίδια συναλλαγή έχει ήδη αποδώσει, αλλά δεν έχει ακόμη επιβεβαιώσει, για παράδειγμα κατά την εισαγωγή πολλών παραστατικών με τη μία.

Το ελέγξαμε με δύο συναλλαγές, στις οποίες η δεύτερη αποδεδειγμένα πήρε την κατάστασή της πριν από το commit της πρώτης και στη συνέχεια περίμενε το κλείδωμα. Χωρίς τη δεύτερη ανάγνωση και οι δύο παραγγελίες έλαβαν τον ίδιο αριθμό, με αυτήν τους αριθμούς 1 και 2.

Σημαντικό για την τοποθέτηση: Αυτή η δοκιμή είναι χειροκίνητος έλεγχος. Δεν αποτελεί μέρος των αυτόματων δοκιμών, επειδή απαιτεί δύο πραγματικές συνδέσεις βάσης δεδομένων, τις οποίες το περιβάλλον δοκιμών του Odoo (μία μόνο συναλλαγή ανά δοκιμή) δεν παρέχει.

Τεχνική υλοποίηση

ΠαραστατικόΣημείο σύνδεσης
Προσφοράsale.order.create, όταν το όνομα είναι κενό, / ή New
Παραγγελία πελάτηsale.order.action_confirm, πριν από την τυπική επιβεβαίωση
Τιμολόγιο, πιστωτικόaccount.move._set_next_sequence, καλείται κατά την καταχώριση
Δελτίο αποστολής, παραλαβή αγαθώνstock.picking.create ανά τύπο λειτουργίας
Παραγγελία αγοράςpurchase.order.create
  • Μετρητής. Τον υψηλότερο αριθμό τον βρίσκει μια κανονική έκφραση (^<Stamm>([0-9]{1,15})$, η ρίζα διαφυλάσσεται) ανά εταιρεία, συμπεριλαμβανομένων των ονομάτων χωρίς εταιρεία.
  • Τιμολόγια. Η _set_next_sequence γράφει το όνομα και καλεί την _compute_split_sequence, ώστε η λογική ακολουθίας του Odoo (πρόθεμα, αριθμός, αναγνώριση έτους για το επόμενο τιμολόγιο του ημερολογίου) να παραμένει συνεπής.
  • Ρυθμίσεις. Τα πεδία εταιρείας document_number_* αντικατοπτρίζονται στο res.config.settings. Οι ρυθμίσεις απορρίπτουν προθέματα με κενό ή με ψηφίο στο τέλος.
  • Μετάφραση. Περιλαμβάνεται γερμανική μετάφραση.

Εγκατάσταση και ρύθμιση

  1. Τοποθετήστε τον φάκελο document_number_prefix_year στη διαδρομή των addons.
  2. Ενημερώστε τη λίστα εφαρμογών, εγκαταστήστε το άρθρωμα. Προϋποθέσεις είναι οι εφαρμογές Πωλήσεις, Αγορές, Αποθήκη και Λογιστική.
  3. Στο Ρυθμίσεις → Αρίθμηση παραστατικών καταχωρίστε προθέματα, μορφή έτους και αριθμό ψηφίων.
  4. Δοκιμάστε πρώτα σε αντίγραφο. Ο αριθμός ενός παραστατικού δεν μπορεί να αναιρεθεί αυτόματα αργότερα, και στα τιμολόγια ο αριθμός συνδέεται με την υποχρέωση διατήρησης και ελέγχου.

Όρια

Έξι όρια του αρθρώματος: καλάθια αγορών, μορφή έτους, μία σειρά ανά εταιρεία, κανόνες προθεμάτων, λίγες δοκιμές, μόνο τα αναφερόμενα παραστατικά

  • Οι προσφορές αριθμούνται κατά τη δημιουργία. Οι διαγραμμένες ή ακυρωμένες προσφορές αφήνουν κενά. Το ίδιο ισχύει για κάθε παραγγελία πελάτη που δημιουργεί ένα άλλο άρθρωμα: τα καλάθια αγορών του webshop (website_sale) είναι παραγγελίες σε κατάσταση Προσφορά και καταναλώνουν από έναν αριθμό. Χωρίς κενά είναι μόνο τα τιμολόγια και τα πιστωτικά, επειδή αριθμούνται κατά την καταχώριση.
  • Μην αλλάζετε τη μορφή έτους κατά τη λειτουργία. Με τη ρίζα AN26 το άρθρωμα διαβάζει ένα υπάρχον AN2026000001 ως μετρητή 26000001. Ορίστε τη μορφή πριν από το πρώτο παραστατικό.
  • Μετρητής το πολύ 15 ψηφία. Μεγαλύτερες ακολουθίες ψηφίων μετά τη ρίζα αγνοούνται κατά την αναζήτηση του υψηλότερου αριθμού.
  • Καμία χωριστή σειρά ανά ημερολόγιο ή αποθήκη. Ο μετρητής ισχύει ανά εταιρεία, πρόθεμα και έτος. Περισσότερα ημερολόγια πωλήσεων μοιράζονται τον μετρητή τιμολογίων.
  • Τα προθέματα δεν επιτρέπεται να περιέχουν κενό ούτε να τελειώνουν σε ψηφίο, διαφορετικά το πρόθεμα, το έτος και ο μετρητής δεν μπορούν πλέον να διαχωριστούν.
  • Μόνο τα αναφερόμενα είδη παραστατικών καλύπτονται.

Δοκιμές

Το άρθρωμα περιλαμβάνει δέκα αυτόματες δοκιμές. Ελέγχουν:

  • Προσφορά και επιβεβαίωση: αριθμός προσφοράς και παραγγελίας, διατήρηση του αριθμού προσφοράς
  • Συνέχιση της μέτρησης μετά από εισαγμένο αριθμό (AN26119 → AN26000120)
  • καμία εκ των υστέρων επαναρίθμηση υπαρχόντων παραστατικών
  • Τιμολόγιο, πιστωτικό και αλλαγή έτους βάσει ημερομηνίας τιμολογίου
  • Παραγγελία αγοράς και δελτία αποστολής
  • κενό πρόθεμα: παραμένει ο τυπικός αριθμός του Odoo
  • τετραψήφιο έτος
  • Πρόθεμα με ειδικούς χαρακτήρες
  • πολλοί αριθμοί σε μία συναλλαγή
  • πολύ μεγάλες ακολουθίες ψηφίων αγνοούνται

Εκτέλεση:

odoo-bin -d <Testdatenbank> -i document_number_prefix_year --test-enable --test-tags=/document_number_prefix_year --stop-after-init

Οι δοκιμές εκτελούνται με συνήθεις συναλλαγές. Η συμπεριφορά κατά την ταυτόχρονη δημιουργία από δύο χρήστες δεν περιλαμβάνεται, ελέγχθηκε χειροκίνητα σε αντίγραφο βάσης δεδομένων, όπως περιγράφεται παραπάνω. Όποιος χρησιμοποιεί το άρθρωμα σε σύστημα με πολλούς ταυτόχρονους χρήστες, θα πρέπει να επαναλάβει αυτή τη δοκιμή στη δική του βάση δεδομένων.

Νομική επισήμανση για τον αριθμό τιμολογίου

Τα τιμολόγια πρέπει κατά το § 11 UStG να φέρουν έναν διαδοχικό αριθμό, ο οποίος αποδίδεται άπαξ για την αναγνώριση του τιμολογίου. Το άρθρωμα αριθμεί τα τιμολόγια κατά την καταχώριση και με δικό του μετρητή ανά πρόθεμα και έτος, κάτι που ταιριάζει σε αυτό. Το κατά πόσο η συγκεκριμένη ρύθμισή σας (πολλά ημερολόγια, πιστωτικά με δικό τους πρόθεμα, αλλαγή έτους) πληροί τις απαιτήσεις του φοροτεχνικού σας συμβούλου, πρέπει να το διευκρινίσετε μαζί του. Αυτό το άρθρο δεν αποτελεί νομική συμβουλή.

Συχνές ερωτήσεις

Γιατί να μην προσαρμόσουμε απλώς τις ακολουθίες του Odoo;

Για τα τιμολόγια αυτό γίνεται μέσω του προθέματος του ημερολογίου. Για προσφορές, παραγγελίες, δελτία αποστολής και παραγγελίες αγορών όμως δεν υπάρχει κοινό σχήμα από πρόθεμα, έτος και μετρητή με αλλαγή έτους, και ο μετρητής δεν γνωρίζει εισαγμένους παλιούς αριθμούς. Εκεί παρεμβαίνει το άρθρωμα.

Αντικαθίσταται η υπάρχουσα αρίθμηση;

Όχι. Το άρθρωμα αποδίδει μόνο νέους αριθμούς. Τα ήδη αποθηκευμένα ονόματα παραμένουν αμετάβλητα, ακόμη και κατά την απενεργοποίηση.

Πώς το απενεργοποιώ ξανά;

Αδειάστε το πρόθεμα του είδους παραστατικού. Τότε το Odoo το αριθμεί πάλι μόνο του. Ούτε η απεγκατάσταση αλλάζει αριθμούς που έχουν ήδη αποδοθεί.

Το χρησιμοποιείτε εσείς οι ίδιοι;

Όχι. Σε εμάς λειτουργούν οι τυπικοί αριθμοί του Odoo. Ελέγξαμε το άρθρωμα με τις αυτόματες δοκιμές και τον περιγραφόμενο χειροκίνητο έλεγχο, αλλά όχι σε παραγωγική λειτουργία με πολλούς χρήστες.

Λειτουργεί με το Odoo 17 ή 18;

Το δοκιμάσαμε μόνο με το Odoo 19.0 Community. Για άλλες εκδόσεις μπορεί να ταιριάζει ή όχι, δεν το έχουμε ελέγξει.

Υπό ποια άδεια διατίθεται;

Υπό την LGPL-3. Σφάλματα και βελτιώσεις είναι ευπρόσδεκτα ως issue στο αποθετήριο GitHub .

Υποστήριξη από την Biricon IT Services

Αναλαμβάνουμε εγκαταστάσεις Odoo για μικρές και μεσαίες επιχειρήσεις: από την εισαγωγή, τις προσαρμογές και τις μετεγκαταστάσεις μέχρι την τρέχουσα λειτουργία. Αν θέλετε να διατηρήσετε τους αριθμούς των παραστατικών σας κατά τη μετάβαση, να ελεγχθεί η απόδοση αριθμών υπό φορτίο ή να περάσετε με ασφάλεια ένα άρθρωμα σαν αυτό στην παραγωγική σας εγκατάσταση, θα βοηθήσουμε με χαρά. Περισσότερες δικές μας ανάπτυξεις: Firmenbuch και έλεγχος διευθύνσεων για αυστριακούς πελάτες, Σετ προϊόντων στην προσφορά ως ενότητα και Web RBL, η λίστα αποκλεισμού για κίνηση επιθέσεων.

Επικοινωνήστε μαζί μας τώρα

Κατάσταση: 3 Νοεμβρίου 2026. Έκδοση αρθρώματος 19.0.1.0.0. Όλοι οι αριθμοί στα παραδείγματα και στις εικόνες είναι τυχαία επιλεγμένοι.