تخطي للذهاب إلى المحتوى

أرقام المستندات في Odoo 19 من بادئة وسنة وعدّاد – وحدة document_number_prefix_year ومشكلة الإنشاء المتزامن

3 نوفمبر 2026 | Odoo 19 Community | تطوير خاص
3 نوفمبر 2026 بواسطة
أرقام المستندات في Odoo 19 من بادئة وسنة وعدّاد – وحدة document_number_prefix_year ومشكلة الإنشاء المتزامن

وحدة document_number_prefix_year في Odoo 19: أرقام مستندات من بادئة وسنة وعدّاد

يخبرنا «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. وهي متاحة على GitHub كبرمجية حرة بموجب ترخيص LGPL-3:

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. فتُثبَّت حالة قاعدة البيانات التي تراها المعاملة عند تنفيذ أول استعلام فيها. ويكون المستخدم B قد حصل على هذه الحالة قبل انتهاء A. فإذا انتظر B القفل بعد ذلك ثم حصل عليه، فسيقرأ «أعلى رقم = 0» من الحالة القديمة التي لديه، ويُخصّص الرقم مرة ثانية. لقد نظّم القفل ترتيب التنفيذ، لكنه لم يحدّث البيانات المرئية.

الحل هو إجراء قراءة ثانية عبر اتصال مستقل وقصير الأمد بقاعدة البيانات، يرى جميع الصفوف التي ثُبّتت معاملاتها بالفعل. وتُعتمد القيمة الأكبر من القيمتين. وتظل القراءة الأولى ضرورية، لأنها وحدها ترى الأرقام التي خصّصتها المعاملة نفسها ولم تُثبَّت بعد، مثلما يحدث عند استيراد عدة مستندات دفعة واحدة.

تحققنا من ذلك باستخدام معاملتين، وتأكدنا من أن الثانية قد أخذت لقطة حالتها قبل تثبيت الأولى، ثم انتظرت القفل. ومن دون القراءة الثانية، حصل أمرا البيع على الرقم نفسه؛ ومعها حصلا على الرقمين 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 في مسار الإضافات.
  2. حدّث قائمة التطبيقات وثبّت الوحدة. يلزم تثبيت المبيعات والمشتريات والمخزون والمحاسبة مسبقًا.
  3. أدخل البادئات وتنسيق السنة وعدد الخانات ضمن الإعدادات → ترقيم المستندات.
  4. جرّب على نسخة أولًا. لا يمكن التراجع عن رقم المستند تلقائيًا لاحقًا، كما يرتبط رقم الفاتورة بمتطلبات الاحتفاظ بالسجلات والتدقيق.

الحدود

ستة حدود للوحدة: سلال التسوق، وتنسيق السنة، وتسلسل واحد لكل شركة، وقواعد البادئات، وقلة الاختبارات، والاقتصار على المستندات المذكورة

  • تُرقَّم عروض الأسعار عند إنشائها. تترك عروض الأسعار المحذوفة أو الملغاة فجوات في التسلسل. وينطبق الأمر نفسه على كل أمر بيع عميل تنشئه وحدة أخرى: إذ إن سلال التسوق في المتجر الإلكتروني (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. جميع الأرقام الواردة في الأمثلة والرسوم توضيحية ومختارة اعتباطًا.