Το «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) και το πλήθος των ψηφίων ανά εταιρεία στην ενότητα Ρυθμίσεις → Αρίθμηση παραστατικών.
Καλύπτονται προσφορές, παραγγελίες πελατών, τιμολόγια και πιστωτικά τιμολόγια πελατών, δελτία αποστολής, παραλαβές εμπορευμάτων και παραγγελίες αγορών. Τα προθέματα στην εικόνα είναι απλώς παραδείγματα: 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. Οι ρυθμίσεις απορρίπτουν προθέματα που περιέχουν κενά ή τελειώνουν σε ψηφίο. - Μετάφραση. Περιλαμβάνεται γερμανική μετάφραση.
Εγκατάσταση και ρύθμιση
- Τοποθετήστε τον φάκελο
document_number_prefix_yearστη διαδρομή των πρόσθετων. - Ενημερώστε τη λίστα εφαρμογών και εγκαταστήστε το πρόσθετο. Απαιτούνται οι εφαρμογές Πωλήσεις, Αγορές, Αποθήκη και Λογιστική.
- Στην ενότητα Ρυθμίσεις → Αρίθμηση παραστατικών, ορίστε τα προθέματα, τη μορφή του έτους και το πλήθος των ψηφίων.
- Δοκιμάστε το πρώτα σε αντίγραφο. Ο αριθμός ενός παραστατικού δεν μπορεί να επανέλθει αυτόματα αργότερα στην προηγούμενη τιμή του, ενώ στα τιμολόγια συνδέεται με τις υποχρεώσεις διατήρησης αρχείων και ελέγχου.
περιορισμούς
- Οι προσφορές αριθμούνται κατά τη δημιουργία τους. Οι διαγραμμένες ή ακυρωμένες προσφορές αφήνουν κενά στην αρίθμηση. Το ίδιο ισχύει για κάθε παραγγελία πελάτη που δημιουργεί κάποιο άλλο πρόσθετο: τα καλάθια αγορών του ηλεκτρονικού καταστήματος (
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 για μικρές και μεσαίες επιχειρήσεις: από την εισαγωγή, τις προσαρμογές και τις μετεγκαταστάσεις μέχρι την τρέχουσα λειτουργία. Αν θέλετε να διατηρήσετε τους αριθμούς των παραστατικών σας κατά τη μετάβαση, να ελεγχθεί η απόδοση αριθμών υπό φορτίο ή να περάσετε με ασφάλεια ένα άρθρωμα σαν αυτό στην παραγωγική σας εγκατάσταση, θα βοηθήσουμε με χαρά. Περισσότερες δικές μας ανάπτυξεις: Εμπορικό μητρώο και έλεγχος διευθύνσεων για πελάτες στην Αυστρία, Σύνολα προϊόντων ως ενότητα στην προσφορά και τις Web RBL, η λίστα αποκλεισμού κακόβουλης κίνησης.
Τελευταία ενημέρωση: 3 Νοεμβρίου 2026. Έκδοση πρόσθετου 19.0.1.0.0. Όλοι οι αριθμοί στα παραδείγματα και στις εικόνες έχουν επιλεγεί αυθαίρετα.