توثيق إثبات التسليم الإلكتروني وإرسال التوصيل لأودو
دليل إثبات التسليم الإلكتروني وإرسال التوصيل لأودو: تثبيت الوحدة وبناء تطبيق السائق والرحلات والمحسّن وإثبات التسليم ورموز العملاء والتسليم الفاشل والأوامر المتبقية والدفع عند التسليم والتسوية والتقارير والأدوار والإعدادات والواجهة البرمجية.
يشرح الإصدار 1.0.0حُدّث في 29 أكتوبر 2026
ابدأ من هنا
ببساطة: تقدّم لك هذه الحزمة نظاماً متكاملاً لـإثبات التسليم الإلكتروني (ePOD) وإدارة التوصيل للميل الأخير على Odoo Community: وحدة Odoo (
taqnix_epod_core) للمُرسِل والمكتب، والشيفرة المصدرية بـ Flutter لـتطبيق سائق يعمل دون اتصال أولاً على أندرويد وآيفون. تخطّط الوحدة الرحلات اليومية، وتحسّن ترتيب المحطات، وتستقبل إثبات كل عملية تسليم (GPS والوقت، الصور، التوقيع، رمز التحقق)، وتعتمد أمر التسليم، وتنشئ الأمر المتبقي (Backorder) للبضاعة التي لم تُسلَّم، وتسوّي النقد الذي حصّله السائق.نصيحة: لا حاجة إلى أي تطبيق من Odoo Enterprise. تستخدم الوحدة المخزون (Inventory) وأسطول المركبات (Fleet) والفوترة (Invoicing) والموقع الجغرافي لجهات الاتصال، وتربط بـ Google Maps أو OpenStreetMap بروابط عادية (دون شراء مفتاح خرائط).
محتويات الحزمة
| العنصر | ما هو |
|---|---|
taqnix_epod_core.zip | وحدة Odoo 19: الرحلات (قوائم المسار) والمحطات، ومحسّن المسار، والوصول ضمن النطاق الجغرافي، وإثبات التسليم، ورموز التحقق، وأسباب الاستثناء، والدفع عند التسليم، وتسوية السائق مع الدفعات التلقائية، والتقارير، وواجهة REST API للتطبيق، والترجمة العربية، و217 اختباراً آلياً. |
flutter-app-source.zip | مشروع Flutter لتطبيق السائق (أندرويد وiOS): قاعدة بيانات دون اتصال وصندوق صادر، ومزامنة في الخلفية، ومراحل المحطة، وكاميرا بعلامة مائية، ولوحة توقيع، وروابط مباشرة إلى تطبيقات الملاحة. |
documentation/ | هذا الدليل بالإنجليزية (index.html) والعربية (index-ar.html) مع ملفات PDF، وملف API.md للمطوّرين. |
licensing/ | الترخيص (OPL-1: شراء واحد = شركة واحدة، مع التحديثات). |
preview-images/ | لقطات شاشة لشاشات Odoo وللتطبيق. |
changelog.txt | سجل الإصدارات. |
كيف يسير اليوم
| الوقت | من | ماذا يحدث | في Odoo |
|---|---|---|---|
| الصباح | المُرسِل | ينشئ الرحلة: السائق والمركبة والتاريخ، ويضيف أوامر التسليم الجاهزة. يضغط تحسين الترتيب ثم تأكيد. | رحلة في حالة مؤكدة بمحطات مرتبة. العملاء الذين تتجاوز قيمة طلبهم الحد المحدد يستلمون رمز التسليم بالبريد الإلكتروني. |
| على الطريق | السائق | يفتح التطبيق ويرى المحطات بالترتيب، ويضغط بدء الملاحة (Google Maps أو Waze أو Apple Maps) ثم يعود إلى التطبيق. | المحطة في الطريق؛ والرحلة قيد التنفيذ. |
| عند الباب | السائق | يرصد التطبيق الوصول داخل النطاق الجغرافي. يمسح السائق الطرود ويلتقط الصور ويأخذ التوقيع أو رمز التحقق ويستلم النقد ثم ينهي المحطة. | المحطة تم التسليم مع الإثبات؛ ويُعتمد أمر التسليم؛ والكمية الناقصة تنشئ أمراً متبقياً. |
| لا أحد في المنزل | السائق | يختار سبباً (العميل غير موجود، الوصول مقيّد، رفض الاستلام...) ويلتقط الصورة المطلوبة. | المحطة فشل؛ ويصل المُرسِل مهمة لإعادة الجدولة. |
| العودة إلى نقطة الانطلاق | السائق وأمين الصندوق | يُعلن السائق النقد حسب طريقة الدفع؛ ويعدّه أمين الصندوق. | ورقة تسوية في حالة مرسلة. |
| المساء | المدير | يعتمد التسوية. | دفعة عميل واحدة لكل تحصيل، مرحَّلة ومسوّاة مع الفواتير المفتوحة. |
ببساطة: العمل دون اتصال أولاً. كل ما يفعله السائق يُحفظ على الهاتف أولاً ثم يُرسل إلى Odoo عند توفر الشبكة. لكل استدعاء معرّف فريد، فلا يؤدي ضياع الرد أو إعادة المحاولة إلى اعتماد التسليم مرتين (الفصل 29). والتسليم الذي حدث فعلاً لا يرفضه الخادم أبداً: المشكلات تتحول إلى تنبيهات للمُرسِل (الفصل 20).
ما تحتاج إليه
| العنصر | التفاصيل |
|---|---|
| Odoo | الإصدار 19.0 Community أو Enterprise. تُثبَّت تلقائياً مع الوحدة تطبيقات المخزون وأسطول المركبات والفوترة والموقع الجغرافي لجهات الاتصال والنقاش (Discuss). تطبيق المبيعات اختياري: عند تثبيته يُقرأ النقد المطلوب تحصيله من أمر البيع. |
| الدليل المحاسبي | دليل حسابات، وللتسوية يومية واحدة لكل طريقة دفع (نقد، شيك، بطاقة، تحويل)؛ ويمكن أن تكون اليومية نفسها. |
| البريد الصادر | خادم بريد صادر لرموز التسليم ورسائل الإثبات (الإعدادات، التقنية، خوادم البريد الصادر). |
| محرك PDF | wkhtmltopdf كما في أي Odoo (تقارير ePOD وورقة الرحلة والتسوية). |
| العنوان | عنوان https عام لـ Odoo: يجب أن تصل إليه الهواتف. |
| الهواتف | أندرويد أو آيفون مع GPS وكاميرا. لبناء تطبيق آيفون تحتاج إلى جهاز Mac مع Xcode. |
تثبيت وحدة Odoo
- فُكّ ضغط الحزمة. بداخلها
taqnix_epod_core.zip؛ فُكّ ضغطه لتحصل على المجلدtaqnix_epod_core. - انسخ المجلد إلى أحد مجلدات
addons_pathفي خادم Odoo ثم أعد تشغيل Odoo. - سجّل الدخول كمسؤول، وفعّل وضع المطوّر، وافتح التطبيقات واضغط تحديث قائمة التطبيقات.
- أزل عامل تصفية التطبيقات، وابحث عن ePOD واضغط تثبيت.
- افتح الإعدادات، المستخدمون وامنح الأشخاص أدوار ePOD Dispatch / السائق أو المُرسِل أو المدير (الفصل 22).
# or from the command line ./odoo-bin -c odoo.conf -d YOUR_DATABASE -i taqnix_epod_core --stop-after-init
نصيحة: جرّب أولاً على نسخة من قاعدة بياناتك. تضيف الوحدة حقولاً إلى أوامر التسليم وجهات الاتصال (جميعها تبدأ بـ
epod_) ولا تغيّر أي بيانات موجودة.بناء تطبيق السائق وتثبيته
ببساطة: التطبيق مشروع Flutter (Taqnix ePOD Driver، وFlutter 3.41 مع Dart 3.11، وأندرويد 7.0 أو أحدث (API 24)، وXcode 16 مع CocoaPods لآيفون). يُسلَّم شيفرةً مصدرية ليحمل اسمك وأيقونتك ولونك. لا حاجة إلى ملف Firebase ولا إلى ملف خدمات Google.
- فُكّ ضغط
flutter-app-source.zipوافتح الطرفية في المجلد. - نزّل الحزم:
flutter pub get. شيفرة قاعدة البيانات (Drift) وملفات الترجمة مولَّدة ومضمَّنة مسبقاً؛ شغّلdart run build_runner buildفقط بعد أن تغيّر الجداول، وflutter gen-l10nفقط بعد أن تغيّر النصوص. - افحص المشروع:
flutter analyze(دون أي ملاحظات) وflutter test(356 اختباراً). - شغّله على هاتف أو محاكٍ:
flutter run --dart-define=SITE_URL=https://odoo.example.com.SITE_URLاختياري: بدونه تعرض شاشة تسجيل الدخول حقل عنوان الخادم وتتذكر ما تكتبه. - ابنِ ملف أندرويد:
flutter build apk --release --dart-define=SITE_URL=https://odoo.example.com، أوflutter build appbundle --release ...لمتجر Play. - ابنِ تطبيق آيفون على جهاز Mac:
flutter build ios --release --dart-define=SITE_URL=https://odoo.example.com، ثم أنشئ الأرشيف وارفعه عبر Xcode. - افتح التطبيق وسجّل الدخول باسم المستخدم وكلمة المرور لمستخدم لديه دور ePOD Dispatch / السائق (الفصل 22). ينزّل التطبيق الإعدادات ورحلة اليوم.
| الإعداد | أين |
|---|---|
معرّف التطبيق / معرّف الحزمة com.taqnix.epoddriver، والاسم المعروض «Taqnix ePOD Driver» | android/app/build.gradle.kts وandroid/app/src/main/res/values/strings.xml وios/Runner/Info.plist ومشروع Xcode. أبقِ معرّف مهمة الخلفية في iOS (<bundle id>.sync) متوافقاً مع lib/core/services/background_sync.dart. |
| لون العلامة | AppConfig.seedColorValue في lib/core/constants/app_config.dart |
| الأيقونة وشاشة البداية | استبدل assets/branding/*.png، ثم شغّل dart run flutter_launcher_icons وdart run flutter_native_splash:create |
| توقيع الإصدار (أندرويد) | أنشئ android/key.properties (storeFile وstorePassword وkeyAlias وkeyPassword). بدونه يُوقَّع بناء الإصدار بمفتاح التصحيح (debug). |
| الإذن | الاستخدام |
|---|---|
| الموقع (أثناء الاستخدام، دائماً) | المسافة إلى المحطات، والوصول ضمن النطاق الجغرافي، والإحداثيات المختومة على الصور، ومسار GPS. «دائماً» يتيح رصد الوصول والشاشة مطفأة. |
| الكاميرا | صور الإثبات وماسح الباركود. |
| الإشعارات | إشعار «وصلت إلى...» وإشعار الخدمة الأمامية في أندرويد. |
| الشبكة | التواصل مع Odoo. |
نصيحة: دون خادم Odoo يمكنك تجربة التطبيق على الخادم الوهمي الصغير المرفق بالمصدر:
python3 tool/fake_server.py --port 8197 (مكتبة بايثون القياسية فقط، وسائق واحد وست محطات في دبي).مهم: استخدم عنوان
https: ترفض الهواتف http العادي في الأنظمة الحديثة. يطلب Google Play إقراراً بشأن الموقع في الخلفية (يستخدمه التطبيق فقط ما دامت لدى السائق محطات مفتوحة: رصد الوصول) وتطلب Apple شرحه في ملاحظات المراجعة. لا إعلانات في التطبيق ولا تحليلات ولا أي SDK يرسل بيانات إلى أي جهة سوى Odoo الخاص بك.الإعداد الأول في عشر دقائق
- افتح ePOD Dispatch، الإعداد، الإعدادات. تحقق من نصف قطر النطاق الجغرافي (الافتراضي 100 م) وقواعد الإثبات (الفصل 23).
- في الشاشة نفسها اختر اليوميات الخاصة بالنقد والشيك والبطاقة والتحويل: يحتاج اعتماد التسوية إليها.
- أنشئ السائقين كمستخدمين داخليين بدور ePOD Dispatch / السائق وكلمة مرور. اربط كل سائق بمركبة في أسطول المركبات (حقل السائق).
- تأكد أن لعملائك موقعاً: افتح جهة الاتصال، تبويب التسليم (ePOD)، واضغط تحديد الموقع الجغرافي (الفصل 8).
- أنشئ أول رحلة (الفصل 9)، وأكّدها، وسجّل الدخول من هاتف.
العملاء: الموقع ورمز البوابة والنافذة الزمنية
ببساطة: يحتاج فحص الوصول وروابط الملاحة إلى خط العرض وخط الطول للعميل. تعيد الوحدة استخدام حقول الموقع الجغرافي لجهات الاتصال في Odoo وتضيف ما يحتاجه السائق عند الباب.
| الحقل | الاستخدام |
|---|---|
| رمز البوابة / الباب | يظهر للسائق على المحطة (البوابة، الإنتركوم، دخول المبنى). |
| نافذة التسليم | مثلاً 09:00-12:00. تظهر للسائق؛ وهي معلومة وليست قاعدة ملزمة. |
| تعليمات التسليم | أين يوقف السيارة، أي مدخل، بمن يتصل. |
| نصف قطر النطاق الجغرافي | يتجاوز نصف قطر الشركة لهذا العنوان (0 = إعداد الشركة). |
| تحديد الموقع الجغرافي | يبحث عن العنوان لدى مزوّد الموقع الجغرافي في Odoo ويملأ خطي العرض والطول. إن لم يُعثر على شيء تظهر رسالة ويمكنك كتابة الإحداثيات يدوياً. |
نصيحة: المحطة التي لا يملك عميلها موقعاً تعمل أيضاً: لا يستطيع الخادم فحص الوصول (يُستخدم فحص التطبيق نفسه) وتنتقل المحطة إلى النهاية عند التحسين.
الرحلات: الإنشاء والتعبئة
ببساطة: الرحلة (قائمة المسار) هي سائق واحد ومركبة واحدة ويوم واحد وقائمة مرتبة من المحطات؛ وكل محطة هي أمر تسليم واحد. تُرقَّم الرحلات هكذا
RUN/2026/0001.- افتح العمليات، الرحلات واضغط جديد. اختر التاريخ والسائق والمركبة (اختيار المركبة يملأ سائقها). اترك نقطة الانطلاق فارغة للبدء من عنوان الشركة.
- اضغط أضف توصيلات: يعرض المعالج أوامر التسليم الصادرة الجاهزة في الشركة (كل المخزون محجوز) وغير الموجودة على محطة مفتوحة. حدّدها واضغط إضافة إلى الرحلة. إعادة التشغيل لا تكرّر أي محطة.
- يمكنك أيضاً تحديد أوامر التسليم في المخزون، أوامر التسليم واستخدام الإجراء إضافة إلى رحلة ePOD، أو الزر إضافة إلى رحلة على أمر التسليم.
- اسحب المحطات من المقبض على اليسار لتغيير الترتيب، أو استخدم تحسين الترتيب (الفصل 10).
- اضغط تأكيد.
تحسين ترتيب المحطات
ببساطة: يحسب تحسين الترتيب مساراً قصيراً: يبدأ من نقطة الانطلاق، ويذهب دائماً إلى أقرب عميل تالٍ (الجار الأقرب)، ثم يحسّن النتيجة بمرور 2-opt. يستخدم المسافة المستقيمة بين الإحداثيات (معادلة هافرساين)؛ وهو حتمي، فالمحطات نفسها تعطي الترتيب نفسه دائماً.
| القاعدة | التفاصيل |
|---|---|
| محطات بلا موقع | تأتي أخيراً بترتيبها الحالي. |
| المحطات المسلَّمة والفاشلة | تحتفظ بمكانها في الأعلى؛ ولا يُعاد ترتيب إلا المحطات المفتوحة. |
| نقطة انطلاق بلا موقع | تبقى أول محطة لها موقع في المقدمة. |
| التطبيق | اضغط تطبيق هذا الترتيب؛ تُعاد ترقيم التسلسل 10 و20 و30... ويمكنك بعدها سحب المحطات. |
مهم: المسافة المستقيمة ليست مسافة الطريق. إنه ترتيب أول جيد وليس مساراً يراعي حركة المرور: المُرسِل يعرف المدينة أفضل.
التأكيد والبدء والإغلاق وإعادة الإسناد وإعادة الجدولة
| الإجراء | ماذا يفعل |
|---|---|
| تأكيد | يحتاج إلى سائق بدور السائق ومحطة معلّقة واحدة على الأقل. يحدّث النقد المطلوب تحصيله من الفواتير، وينشئ رموز العملاء ويرسلها بالبريد الإلكتروني. |
| بدء الرحلة | اختياري: تبدأ الرحلة أيضاً من تلقاء نفسها عندما يضغط السائق على المحطة الأولى. |
| إغلاق الرحلة | ينهي الرحلة؛ وتُلغى المحطات التي ما زالت مفتوحة ويُبلَّغ السائق. وتُغلق الرحلة أيضاً من تلقاء نفسها عند إغلاق آخر محطة. |
| إعادة فتح | تعود رحلة منتهية (عمرها أقل من أسبوع) إلى قيد التنفيذ لاستقبال محطة متأخرة. |
| إعادة إسناد السائق | يعطي المحطات المفتوحة لسائق آخر (ومركبة أخرى). يفقدها الهاتف القديم ويستلمها الجديد؛ ويبقى النقد المحصَّل لدى السائق الذي أخذه. |
| إلغاء | يلغي الرحلة عندما لم يُسلَّم شيء بعد. |
| إعادة الجدولة | على محطة فاشلة: ينشئ محطة جديدة في رحلة أخرى (أو رحلة جديدة). تبقى المحطة الفاشلة فاشلة مع إثباتها. |
ببساطة: يمكن أن تكون المحطة معلّقة أو في الطريق أو وصل أو تم التسليم أو تسليم جزئي أو فشل أو ملغاة. لا يغيّر الحالة إلا تطبيق السائق والأزرار أعلاه؛ ولا يستطيع أحد كتابتها في نموذج.
الوصول ضمن النطاق الجغرافي
ببساطة: يراقب التطبيق موقع السائق. عندما يدخل الهاتف النطاق الجغرافي للمحطة (100 م افتراضياً) تنتقل المحطة من في الطريق إلى وصل، ويُحفظ وقت الوصول والمسافة. ويعيد الخادم حساب المسافة من موقع العميل؛ وتُحفظ المسافة التي أبلغ عنها الهاتف بجانبها.
| الحقل في المحطة | المعنى |
|---|---|
| وصل في | أول ختم وصول (إشارة وصول ثانية لا تغيّره). |
| المسافة عند الوصول | الأمتار بين الهاتف والعميل، يحسبها الخادم. |
| وصل داخل النطاق الجغرافي | صحيح عندما تكون المسافة ضمن نصف القطر. |
| تم رصد الوصول بواسطة | النطاق الجغرافي (تلقائي) أو نقرة السائق. |
نصيحة: يستطيع السائق أيضاً الضغط على وصل يدوياً. إن كان بعيداً عن العنوان تحصل المحطة على التنبيه خارج النطاق الجغرافي للمُرسِل.
إثبات التسليم
ببساطة: تحفظ كل محطة مكتملة إثباتاً متعدد النقاط. افتحه من العمليات، المحطات، أو من الرحلة، أو من زر إثبات التسليم على أمر التسليم.
| النقطة | ما يُحفظ |
|---|---|
| GPS والوقت | الموقع والدقة ووقت الإتمام والمسافة من العنوان وما إذا كان داخل النطاق الجغرافي. |
| الصور | تسليم عند عتبة الباب، فتح الصندوق / الرقم التسلسلي، طرد تالف، مكان التسليم. تُحفظ كمرفقات مع وقتها وموقعها وحجمها وبصمة SHA-256؛ ويُفحص المحتوى (WebP أو JPEG أو PNG فقط). |
| التوقيع | صورة PNG للتوقيع مع الاسم المطبوع للمستلم وصلته (المستلم، جار، موظف الاستقبال، موظف الاستقبال في المبنى، أخرى) والوقت. |
| رمز العميل | هل فُحص الرمز على الهاتف أم على الخادم (الفصل 14). |
| البضائع | الكمية المطلوبة والمسلَّمة لكل سطر، وأرقام الدفعات والأرقام التسلسلية، وسبب كل سطر ناقص. |
| النقد | كل دفعة استُلمت عند الباب (الفصل 17). |
ببساطة: لا يمكن تعديل الإثبات. حتى المدير لا يستطيع تغيير صورة أو توقيع أو كمية من الشاشات أو عبر RPC: تُكتب فقط عبر سير عمل التطبيق. إن كان هناك خطأ فأضف ملاحظة في سجل الرسائل (chatter).
رمز العميل (كلمة المرور لمرة واحدة)
ببساطة: في عمليات التسليم ذات القيمة العالية يستلم العميل رمزاً من 4 إلى 6 أرقام بالبريد الإلكتروني ويعطيه للسائق عند الباب. ينشئ الخادم الرمز عند تأكيد الرحلة.
| التفصيل | كيف يعمل |
|---|---|
| متى | تحتاج المحطة إلى رمز عندما تبلغ قيمة الطلب على الأقل قيمة الإعداد كلمة المرور لمرة واحدة من قيمة الطلب هذه (0 = أبداً)، أو عندما تفعّل اطلب رمز العميل دائماً على المحطة. |
| ما يُحفظ | بصمات فقط: بصمة من جهة الخادم (HMAC-SHA256 بمفتاح سري لا يغادر الخادم) يستخدمها الخادم في كل فحص، وبصمة مملّحة منفصلة للهاتف. لا يُحفظ الرمز نفسه أبداً؛ يوجد فقط في البريد الإلكتروني الذي يرسله النظام، وهو غير مرتبط بالمحطة، ولا يستطيع السائقون قراءته ولا يظهر في سجل الرسائل (chatter). |
| مستويات الضمان | فُحص عبر الخادم (الأفضل): تحقق الخادم من الأرقام عبر الإنترنت، أو كان الإعداد فحص الرمز على الهاتف دون اتصال معطّلاً وتطابقت الأرقام المكتوبة عند الباب عند إتمام المحطة. فُحص على الهاتف: كان لدى الهاتف بصمة للرمز، فيُسجَّل الإثبات على الهاتف (دون اتصال) مع التنبيه الرمز مفحوص على الهاتف فقط. |
| إعداد فحص الرمز دون اتصال | مفعّل (الافتراضي): يستلم التطبيق الملح والبصمة ويستطيع فحص الرمز دون شبكة. معطّل: لا يستلم التطبيق أي بصمة إطلاقاً؛ يفحص عبر الإنترنت عندما يستطيع، أو يرسل الأرقام عند إتمام المحطة ويتحقق منها الخادم. |
| المحاولات الخاطئة | 5 رموز خاطئة تقفل المحطة 10 دقائق؛ ولا يُصفَّر العدّاد بإعادة الإرسال، وبعد 15 رمزاً خاطئاً على مدى عمر المحطة لا يستطيع فتحها إلا المُرسِل (زر فتح قفل الرمز). لا تُسجَّل المحطة المقفلة أبداً على أنها محقَّقة: يُرفع التنبيه الرمز مقفل. |
| إعادة الإرسال | يستطيع السائق أو المُرسِل إرسال رمز جديد (يبطل القديم) حتى 3 مرات لكل محطة، فقط ما دامت الرحلة مؤكدة أو قيد التنفيذ والرمز غير مقفل. |
| الصلاحية | إعداد صلاحية (دقائق)، الافتراضي 24 ساعة. تمسح مهمة كل ساعة البصمات المنتهية؛ اطلب رمزاً جديداً إن حدث ذلك (التنبيه الرمز منتهي إن كان الوقت قد فات). |
| قنوات أخرى | الدالة _epod_send_otp في المحطة نقطة ربط: يمكن لوحدة أخرى إرسال رسالة SMS أو WhatsApp بدل البريد الإلكتروني. |
مهم: الخطر المتبقي. الرمز المكوّن من 4 إلى 6 أرقام له مليون قيمة على الأكثر. إذا كان لدى الهاتف بصمة مملّحة له (الإعداد مفعّل) فمن يحمل الهاتف يستطيع إيجاد الرمز في ثوانٍ، ولا يستطيع الخادم التمييز بين ذلك وعميل أعطى الرمز فعلاً. لذلك يوسَم هذا الإثبات بأنه فُحص على الهاتف ويُنبَّه عليه. وللحصول على إثبات أقوى عطّل الفحص دون اتصال (يحتاج السائق إلى شبكة أو إلى فحص الخادم عند الإتمام) أو تحقق عبر الإنترنت أولاً. وأياً كان الإعداد، فالرمز وسيلة حماية من الأخطاء النزيهة والاحتيال العابر، وليس من مهاجم مصمّم.
التسليمات الفاشلة وأسباب الاستثناء
ببساطة: عندما لا يستطيع السائق التسليم يختار سبب استثناء. المحطة الفاشلة لا تعتمد أمر التسليم، الذي يبقى جاهزاً للمحاولة التالية.
| النوع | المعنى | أمثلة |
|---|---|---|
| محطة فاشلة | لم يُسلَّم شيء. | العميل غير موجود، الوصول مقيّد، عنوان خاطئ أو ناقص، غير آمن للتسليم |
| سطر | بضاعة مرفوضة أو تالفة في محطة تم تسليمها. | تضرر أثناء النقل، سُلِّم صنف خاطئ، صنف ناقص في السيارة |
| كلاهما | يمكن استخدامه للحالتين. | رفضه العميل، العميل لم يطلبه |
ببساطة: يحدد كل سبب ما إذا كانت الصورة والملاحظة مطلوبتين وما إذا كان على المُرسِل إعادة الجدولة. يستطيع المديرون إضافة الأسباب أو تعديلها؛ وتُثبَّت الأسباب الأربعة الواردة في المواصفات (not_home وaccess وdamaged وrefused) مع ترجماتها.
التسليم الجزئي والأوامر المتبقية
ببساطة: عندما يأخذ العميل أقل من الكمية المطلوبة، يدخل السائق الكمية المسلَّمة للسطر والسبب. يعتمد الخادم أمر التسليم بالكميات التي سُلّمت فعلاً، وينشئ Odoo تلقائياً أمراً متبقياً (Backorder) للباقي.
| الحالة | النتيجة |
|---|---|
| كل السطور مكتملة | المحطة تم التسليم، وأمر التسليم منجز. |
| سطر ناقص | المحطة تسليم جزئي (التنبيه تسليم جزئي)، وأمر التسليم منجز، وأمر متبقٍ بالكمية المتبقية، ومهمة لوضعه في رحلة جديدة. |
| كمية أكبر من المطلوب أو سالبة أو ليست رقماً | يرفضها الخادم (بيانات مشوّهة). |
| الأرقام التسلسلية والدفعات | يعرض التطبيق الدفعات المحجوزة على السطر ويختارها افتراضياً، وللسائق أن يسمّي دفعات أخرى (تُطابَق دون اعتبار حالة الأحرف أو الفراغات). وإذا لم تُسمَّ دفعة سُلّمت الدفعات المحجوزة. أما الاسم غير الموجود فلا يُرفض: يُسجَّل التسليم وتعرض المحطة الدفعات الصالحة للاختيار. |
| يرفض Odoo الاعتماد | مثلاً رقم تسلسلي غير معروف. يبقى الإثبات والتسليم مسجَّلين، وتعرض المحطة المشكلة مع التنبيه فشل الاعتماد، ويحاول الزر اعتماد أمر التسليم مرة أخرى بعد أن تصلح المشكلة. |
الدفع عند التسليم
ببساطة: تعرف الوحدة لكل محطة المبلغ المطلوب تحصيله: المبلغ المفتوح من فواتير العميل المرحَّلة الخاصة بالتسليم (يُعثر عليها عبر أمر البيع أو عبر مصدر الفاتورة)، أو إجمالي الطلب عندما لا توجد فاتورة بعد (يحتاج إلى المبيعات). تُهمل الإشعارات الدائنة والفواتير المدفوعة.
| الحقل | المعنى |
|---|---|
| المبلغ المطلوب تحصيله | من الفواتير المفتوحة / الطلب (تلقائي)، أو المبلغ الذي حدده المُرسِل، أو بدون دفع عند التسليم. |
| التحصيلات | كل دفعة أخذها السائق: نقد، شيك، بطاقة / نقطة بيع، أو تحويل بنكي / محفظة، مع مرجع للطرق الثلاث الأخيرة. |
| الفرق | المحصَّل ناقص المتوقع؛ والفرق يرفع التنبيه فرق النقد لكنه لا يرفض التسليم أبداً. |
تسوية السائق
ببساطة: في نهاية الوردية يُعلن السائق النقد الذي يسلّمه، حسب الطريقة. يعدّه أمين الصندوق في المركز ويعتمد المدير. تقارن الوحدة كل شيء بما سجّله التطبيق.
- يرسل السائق الإعلان من التطبيق (أو ينشئ المُرسِل الورقة تحت النقد، تسويات السائقين ويضغط قدّم). تعرض الورقة المبلغ المتوقع لكل طريقة، مأخوذاً من تحصيلات ذلك السائق وذلك اليوم. يصبح الإعلان بعدها مقفلاً.
- يعدّ أمين الصندوق المال، ويصحّح عمود المعدود إن اختلف عن الإعلان، ويضغط النقد المعدود. تُكتب المبالغ المُعلَنة والمعدودة في سجل الرسائل.
- إذا كان الفرق بين المعدود والمتوقع أكبر من السماحية في الإعدادات تصبح الملاحظة إلزامية.
- يضغط المدير (وليس السائق نفسه) اعتماد وتسجيل الدفعات. يُرفض الاعتماد حتى يُعدّ النقد وما دام لدى السائق محطات مفتوحة في ذلك اليوم.
| عند الاعتماد | التفاصيل |
|---|---|
| الدفعات | دفعة عميل واحدة مرحَّلة لكل تحصيل، بالمبلغ الذي دفعه العميل، في يومية طريقته، بتاريخ يوم الرحلة، مع رقمي التسليم والشيك في البيان. |
| التسوية المحاسبية | تُسوّى كل دفعة مع الفواتير المفتوحة للمحطة، الأقدم أولاً. تُترك الفواتير بعملة أخرى مفتوحة ويُشار إليها في سجل الرسائل؛ والدفعة بلا فاتورة مفتوحة تبقى رصيداً دائناً للعميل. |
| العجز أو الفائض | الفرق بين النقد المعدود والنقد المحصَّل يُقيَّد في قيد يومية واحد: العجز يجعل حساب عجز السائق مديناً (الشريك: السائق) ويجعل حساب السيولة في يومية الطريقة دائناً؛ والفائض بالعكس. اختر اليومية والحساب في الإعدادات. إذا لم يُضبطا فلا يمكن اعتماد فرق يتجاوز السماحية إلا إذا كتب المدير ملاحظة وفعّل قبول الفرق دون قيده؛ ويُسجَّل هذا الاختيار. |
| الأمان | الاعتماد مرتين لا ينشئ شيئاً؛ ولا يمكنك اعتماد تسويتك الخاصة؛ والورقة المعتمدة مقفلة. |
| رفض | يعيد الورقة: يعلن السائق من جديد. |
| التحصيلات المتأخرة | التحصيل الذي يصل إلى الخادم بعد إرسال ورقة اليوم أو اعتمادها (هاتف كان دون اتصال، أو رحلة أُعيد فتحها) يذهب إلى ورقة متابعة لليوم نفسه (الورقة 2 و3...) ويحصل المُرسِل على مهمة. يعلنه السائق من التطبيق كما أعلن الأول. |
التقارير القابلة للطباعة
| التقرير | أين | المحتوى |
|---|---|---|
| إثبات التسليم (ePOD) | اطبعه من محطة أو من أمر تسليم، أو يُرسل بالبريد الإلكتروني إلى العميل | العميل والرحلة والسائق، والوصول والإتمام مع الوقت والمكان، ونتيجة رمز العميل، والبضائع، والمستلم، والتوقيع، والصور، والتنبيهات. |
| ورقة الرحلة | اطبعها من رحلة | المحطات بالترتيب مع العنوان والتعليمات والرمز المطلوب والنقد المطلوب تحصيله، وسطور للتوقيع. |
| تسوية السائق | اطبعها من تسوية | المتوقع والمُعلَن والفرق، والتحصيلات، وسطور للتوقيع. |
ببساطة: عند تفعيل إرسال إثبات التسليم إلى العميل بالبريد الإلكتروني (الإعدادات) يستلم العميل تقرير ePOD بصيغة PDF عند إتمام المحطة، بلغة العميل.
محطات للمراجعة (التنبيهات)
ببساطة: لا يرفض الخادم أبداً تسليماً حدث فعلاً. عندما يبدو شيء غير سليم فإنه يسجّل المحطة على أي حال ويرفع تنبيهات، إضافة إلى مهمة لمُرسِل الرحلة.
| التنبيه | يُرفع عندما |
|---|---|
| خارج النطاق الجغرافي | تكون المسافة عند الوصول أو الإتمام أكبر من نصف القطر. |
| دقة GPS منخفضة / GPS مفقود | تكون الدقة أسوأ من الإعداد، أو لم يصل أي موقع مع المحطة. |
| الرمز مفقود / غير مطابق / منتهي / مقفل | تحتاج المحطة إلى رمز العميل ولم يُدخل أي رمز، أو أُدخل رمز خاطئ أو منتهي، أو قُفلت المحطة بعد محاولات خاطئة كثيرة. |
| الرمز مفحوص على الهاتف فقط | طابق الرمز لكن كان لدى الهاتف بصمة له: إثبات أضعف (الفصل 14). |
| التوقيع / الصورة مفقودة | تحتاج المحطة إليهما ولم يُرسلا. |
| فرق النقد | المحصَّل ليس ما كان متوقعاً. |
| مزامنة متأخرة | وصل الإثبات بعد أكثر من 6 ساعات من التسليم (كان الهاتف دون اتصال). |
| تسليم جزئي | كان أحد السطور ناقصاً؛ ويوجد أمر متبقٍ. |
| المرجع مفقود | دفعة بشيك أو بطاقة أو تحويل بلا مرجع. |
| فشل الاعتماد | رفض Odoo اعتماد أمر التسليم. |
| لإعادة الجدولة | محطة فاشلة يطلب سببها محاولة جديدة. |
ببساطة: اضغط تعليم التنبيهات كمراجَعة على المحطة عندما تعالج الأمر؛ فتخرج المحطة من قائمة المراجعة.
لوحة المعلومات والتتبع
ببساطة: تعرض التقارير، لوحة المعلومات المحطات حسب الحالة واليوم كرسم بياني وكجدول محوري (حسب السائق، مع نسبة التسليم في الموعد والنقد المحصَّل). والتسليم في الموعد هو نسبة المحطات المسلَّمة التي أُتمّت في يوم الرحلة أو قبله.
الأدوار وصلاحيات الوصول
| الدور | ما يستطيع فعله |
|---|---|
| السائق | يسجّل الدخول إلى التطبيق. وفي Odoo لا يرى إلا رحلاته ومحطاته وتحصيلاته وتسوياته، للقراءة فقط. |
| المُرسِل | يرى كل ما في الشركة: ينشئ الرحلات ويؤكدها، ويضيف التسليمات، ويحسّن الترتيب، ويعيد الإسناد والجدولة، ويراجع التنبيهات، ويعدّ النقد. لا يستطيع تغيير الإثبات أو اعتماد التسويات. يشمل صلاحيات مستخدم المخزون ومستخدم أسطول المركبات. |
| المدير | كل ما يفعله المُرسِل إضافة إلى: اعتماد التسويات أو رفضها، والإعدادات، وأسباب الاستثناء، والتنبيهات، والأجهزة، وسجل المزامنة. |
ببساطة: القواعد: كل سجل ينتمي إلى شركة ولا يرى المستخدمون إلا شركاتهم (آمن لتعدد الشركات)؛ وصلاحيات السائق مقصورة على رحلته بقواعد السجلات، حتى على الصور والتحصيلات والسطور؛ وأزرار سير العمل تتحقق من الدور على الخادم؛ ولا يمكن كتابة حقول الحالة والإثبات من الشاشات أو عبر RPC.
الإعدادات
| الإعداد | الافتراضي | المعنى |
|---|---|---|
| نصف قطر النطاق الجغرافي | 100 م | يُفحص الوصول والإتمام مقابل هذه المسافة (من 10 إلى 5000 م). يمكن لجهة اتصال تجاوزها. |
| أسوأ دقة GPS | 60 م | الموقع الأسوأ يرفع تنبيه الدقة المنخفضة. |
| الصورة مطلوبة / الحد الأدنى / الحد الأقصى | نعم / 1 / 12 | قواعد الإثبات المرسلة إلى التطبيق؛ والصور الناقصة ترفع تنبيهات فقط. |
| الحد الأقصى لحجم الصورة | 3 MB | تُرفض الصور الأكبر (413). |
| الضلع الأطول للصورة / الجودة | 1600 px / 70 | يُرسل إلى التطبيق لضغط WebP. |
| التوقيع مطلوب من قيمة | 0 (دائماً) | التوقيع مطلوب في المحطات التي تساوي هذه القيمة أو تزيد. |
| كلمة المرور لمرة واحدة من قيمة / الخانات / الصلاحية | 500 / 6 / 1440 دقيقة | راجع الفصل 14. |
| فحص الرمز على الهاتف دون اتصال | مفعّل | معطّل = لا يستلم الهاتف أبداً بصمة للرمز (الفصل 14). |
| إرسال الإثبات بالبريد | معطّل | إرسال ملف ePOD بصيغة PDF إلى العميل. |
| اليوميات حسب الطريقة | - | تُستخدم في اعتماد التسوية. |
| حد التسامح في التسوية | 1.00 | الفرق حتى هذا الحد لكل طريقة لا يحتاج إلى ملاحظة. |
| يومية وحساب العجز | - | حيث يُقيَّد الفرق بين النقد المعدود والمحصَّل (الفصل 18). |
| الاحتفاظ بمسار GPS | 30 يوماً | تُحذف النقاط الأقدم بمهمة يومية. |
| نسيان الأجهزة بعد | 180 يوماً | الهواتف التي لم تظهر منذ هذه المدة يجب أن تسجّل الدخول من جديد. |
تطبيق السائق: تسجيل الدخول والرحلة والملاحة
ببساطة: صُمّم Taqnix ePOD Driver للكابينة وعتبة الباب: أهداف لمس كبيرة، واستخدام بيد واحدة، وتباين عالٍ، وألوان للحالات (قيد الانتظار كهرماني، في الطريق برتقالي، وصلت أزرق، تم التسليم أخضر، فشل أحمر)، وأيقونات من Fluent UI System Icons. لا شيء مكتوب ثابتاً في الشيفرة: نصف القطر وقواعد الإثبات والأسباب وطرق الدفع تأتي من إعدادات Odoo لديك.
| الشاشة | ماذا يفعل السائق |
|---|---|
| تسجيل الدخول | عنوان الخادم (عندما لا يحمل البناء عنواناً ثابتاً)، واسم المستخدم (البريد) وكلمة المرور، وتذكّرني على هذا الهاتف. مفتاح اللغة على الشاشة. |
| مسار اليوم | رحلة اليوم: الرقم والمركبة واللوحة وشريط التقدم والأعداد (المحطات، المسلّمة، الفاشلة، المتبقية) والنقد المحصّل مقابل النقد المتوقع. وتحتها قائمة المطلوب بالترتيب مع إبراز المحطة التالية، وعلامات المسافة بالأمتار أو الكيلومترات، وفترة التسليم، والمبلغ المطلوب تحصيله. |
| ترتيبي | يتيح مقبض السحب للسائق إعادة ترتيب المحطات لنفسه. هذا محلي فقط: لا يوجد في API استدعاء لإعادة الترتيب، ولا يُرسل شيء إلى Odoo، وإعادة ترتيب المُرسِل تصل من تلقاء نفسها. |
| تفاصيل المحطة | العميل والعنوان وفترة التسليم وزر اتصال وتعليمات البوابة والدخول من جهة الاتصال (مع زر نسخ) والأصناف بكمياتها، والإثباتات التي تحتاجها هذه المحطة (صورة، توقيع، رمز لمرة واحدة، مسح). |
ببساطة: الملاحة. يفتح السهم على المحطة تطبيق الملاحة لدى السائق بإحداثيات العميل: Google Maps أو Waze أو Apple Maps أو أي تطبيق يتعامل مع رابط
geo:. يختار السائق في المرة الأولى (ويمكنه تفعيل استخدم هذا التطبيق دائماً)؛ وفي الإعدادات يستطيع تغييره، ويمكن أن يأتي الافتراضي من Odoo. لا توجد إرشادات منعطفاً بمنعطف داخل التطبيق. عندما يعود السائق من تطبيق الملاحة تسأل ورقة سفلية مرحباً بعودتك: هل وصلت؟ مع نعم، لقد وصلت وافتح المحطة وليس بعد.ببساطة: الوصول ضمن النطاق الجغرافي. ما دامت لدى السائق محطات مفتوحة يراقب التطبيق الموقع (خدمة أمامية في أندرويد مع إشعار ظاهر، أو الموقع في الخلفية في iOS). عندما يدخل الهاتف نصف قطر محطة تصبح المحطة وصلت من تلقاء نفسها، مع الوقت والمسافة والدقة والمُشغِّل GPS، ويعرض شريط تنبيه فتح المحطة. وزر لقد وصلت اليدوي موجود دائماً. يُختم الوصول على الهاتف أولاً، فيعمل دون شبكة.
تطبيق السائق: إثبات التسليم في ست خطوات
ببساطة: فتح المحطة والضغط على إتمام التسليم يبدأ معالجاً من ست خطوات: الوصول، المسح، الصور، توقيع / OTP، النقد، إنهاء. تعرض كل خطوة مطلوب أو تم؛ ويستطيع السائق التنقل ذهاباً وإياباً. لا يرفض الخادم أبداً تسليماً حدث فعلاً: الإثبات الناقص يرفع تنبيهاً للمُرسِل فقط، وتسرد الخطوة الأخيرة ما سيُبلَّغ به المُرسِل.
| الخطوة | ماذا تفعل |
|---|---|
| 1 الوصول | تؤكد الوصول (تلقائياً بالنطاق الجغرافي أو يدوياً) وتسجّل الوقت والمسافة. |
| 2 المسح | امسح طرداً بالكاميرا أو اكتب الرمز، أو تحديد الكل كمسلَّم. يعرض كل سطر الكمية المطلوبة وعدّاداً للكمية المسلَّمة: الكمية الأقل تطلب سبباً وتجعل التسليم جزئياً. |
| 3 الصور | تعرض الكاميرا العلامة المائية مباشرة (خط العرض وخط الطول والدقة والوقت ورقم التسليم) وتدمجها في الصورة. أنواع الصور: التسليم عند الباب، صندوق مفتوح / تسلسلي، طرد تالف، مكان التسليم. وعند غياب الكاميرا المباشرة يمكن استخدام كاميرا النظام أو المعرض. تُرمَّز الصور بصيغة WebP عبر flutter_image_compress؛ وإذا عجز الجهاز عن ذلك تُحفظ الصورة بصيغة JPEG وتذكر الشاشة ذلك (يقبل الخادم WebP وJPEG وPNG). |
| 4 توقيع / OTP | يوقّع المستلم على اللوحة (خطوط مصقولة، مسح)، مع اسمه المطبوع وصلته (المستلم نفسه، جار، موظف الاستقبال، حارس البناية، آخر). وعندما تحتاج المحطة إلى رمز العميل يكتبه السائق ويضغط تحقق من الرمز؛ وإعادة إرسال الرمز تطلب رمزاً جديداً من Odoo. |
| 5 النقد | المبلغ المتوقع وإجمالي المستلم وطرق الدفع (نقداً، شيك، بطاقة / نقطة بيع، تحويل بنكي / محفظة) مع المبلغ والمرجع حيث تحتاج الطريقة إلى مرجع. ويظهر التحصيل الناقص بالأحمر. |
| 6 إنهاء | الملخص (الأسطر المتحقق منها، الصور، التوقيع، المستلم، النقد) والتحذيرات، ثم إتمام التسليم. |
ببساطة: رمز العميل. عندما يكون إعدادك فحص الرمز على الهاتف دون اتصال مفعّلاً يستلم الهاتف بصمة مملّحة ويفحص الأرقام دون شبكة؛ ويتحقق منها الخادم مرة أخرى وينبّه عند عدم التطابق. وعندما يكون معطّلاً يفحص الهاتف عبر الإنترنت إن استطاع، أو يرسل الأرقام فقط ليتحقق منها الخادم. بعد خمسة أرقام خاطئة تُقفل المحطة عشر دقائق (الفصل 14)؛ وتذكر الشاشة ذلك. والرمز نفسه لا يصل إلى الهاتف أبداً.
ببساطة: الدفعات والأرقام التسلسلية. للسطر المتتبَّع يعرض التطبيق الدفعات / الأرقام التسلسلية مع الدفعات المحجوزة في Odoo وكميتها، ويختار السائق ما سلّمه فعلاً. وإن لم يختر شيئاً سُلّمت الدفعات المحجوزة.
تطبيق السائق: المحطات الفاشلة والصادر وتسوية النقد
ببساطة: تعذّر التسليم. من المحطة يفتح السائق تعذّر التسليم: يختار أحد الأسباب المضبوطة في Odoo (العميل غير موجود، الوصول مقيّد، عنوان خاطئ، رفض الاستلام...)، ويلتقط الصورة إن كان السبب يتطلبها، ويكتب الملاحظة إن كان السبب يتطلبها، ويضغط إنهاء كفاشل. يبقى أمر التسليم جاهزاً في Odoo ويحصل المُرسِل على مهمة لإعادة الجدولة.
ببساطة: الصادر. يُكتب كل إجراء في قاعدة بيانات محلية أولاً ثم يُرسل بالترتيب بمعرّفه الفريد. يعرض تبويب الصادر ما لم يصل إلى الخادم بعد (إثباتات المحطات، ونقاط GPS، والتسوية)، وزر مزامنة، وشارة تمت المزامنة أو غير متصل، وسجل المزامنة. وتحاول مهمة في الخلفية إرسال الطابور كل 15 دقيقة تقريباً (والنظام هو من يقرر). ينبّه تسجيل الخروج إذا كانت هناك عمليات ما زالت بالانتظار، ويحذف البيانات المحلية.
ببساطة: تسوية النقد. يسرد تبويب النقد ما حصّله السائق اليوم حسب الطريقة، وينبّه إذا كانت محطات ما زالت مفتوحة، ويتيح له كتابة ما يسلّمه لكل طريقة (يملؤه زر استخدم المتوقع). يرسل الإرسال الإعلان؛ ويعدّه أمين الصندوق في المركز ويعتمده المدير في Odoo (الفصل 18). تعرض الشاشة حالة الورقة، وورقة متابعة عندما تحتاج إليها التحصيلات المتأخرة.
تطبيق السائق: الإعدادات واللغات والمظاهر
ببساطة: تعرض الإعدادات السائق والمركبة واللوحة والشركة، وتتيح له اختيار اللغة (الإنجليزية أو العربية، مع تخطيط كامل من اليمين إلى اليسار)، والمظهر (النظام أو فاتح أو داكن)، والتباين العالي (أسود وأبيض بحدود سميكة لضوء الشمس)، وتطبيق الملاحة، وحجم الصورة (صور أصغر أو أكبر)، وبطاقة إذن الموقع التي تشرح سبب الحاجة إلى «السماح دائماً». وعلى الجهاز اللوحي يتحول التخطيط إلى شريط تنقل جانبي.
السلوك دون اتصال
| الحالة | ماذا يحدث |
|---|---|
| لا شبكة عند الباب | تُحفظ تغييرات الحالة والصور والتوقيع والرمز والنقد والنتيجة في طابور قاعدة بيانات محلية على الهاتف. |
| عودة الشبكة | يُرسل الطابور بالترتيب؛ تُضغط الصور بصيغة WebP وتُبثّ؛ ويحمل كل استدعاء معرّفاً فريداً. |
| ضاع الرد | يعيد التطبيق الاستدعاء؛ ويجيب الخادم بالنتيجة المحفوظة ولا يُنفَّذ شيء مرتين. |
| يعدّل المُرسِل الرحلة في الأثناء | تصل إعادة الترتيب وإعادة الإسناد والإلغاء إلى الهاتف مع التحديث التالي (كل دقيقتين افتراضياً). |
| محطة أُغلقت بالفعل | يُرفض إتمام ثانٍ لمحطة مغلقة (409). |
| يوم واحد في كل مرة | يحتفظ الهاتف برحلة اليوم. وعمليات الأمس التي لم تُرسل تُرسل أيضاً. والمحطة التي يزيلها المُرسِل بعد أن عمل السائق عليها تبقى على الهاتف مع علامة، فلا يضيع العمل الموجود في الطابور. |
ببساطة: واقع الميدان هو الغالب. لا يُرفض إلا البيانات المشوّهة والسجلات المجهولة أو الغريبة والمحطات المغلقة. وكل ما عدا ذلك يُقبل ويُنبَّه عليه.
واجهة API (للمطوّرين)
ببساطة: يتحدث التطبيق مع
/api/v1/epod: ping وlogin وlogout وconfig وmanifest وstatus وlocation وotp/verify وotp/resend وcomplete وsettlement وchanges. المصادقة برمز Bearer (يُحفظ مشفّراً)؛ وتسجيل الدخول يستبدل رمز الجهاز نفسه. ملف API.md في الحزمة هو العقد الكامل.# is the server reachable?
curl https://odoo.example.com/api/v1/epod/ping
# {"ok": true, "api_version": 1, "server_time": "2026-10-28T06:00:00Z"}
# sign in (returns a token, the vehicle and the configuration)
curl -X POST https://odoo.example.com/api/v1/epod/login -H 'Content-Type: application/json' \
-d '{"login": "omar@atlas-trading.example", "password": "...", "device": {"id": "abc", "name": "Pixel 7", "platform": "android", "app_version": "1.0.0"}}'
# today's run of the driver
curl https://odoo.example.com/api/v1/epod/manifest -H "Authorization: Bearer $TOKEN"
# complete a stop (multipart: the JSON payload and the photo files; every call has an op_uuid, repeating it is safe)
curl -X POST https://odoo.example.com/api/v1/epod/complete -H "Authorization: Bearer $TOKEN" \
-F 'payload={"op_uuid": "5f0e2c1a-8d7b-4c10-9a55-0d6a1b2c3d4e", "local_seq": 12, "stop_id": 101, "outcome": "delivered", "completed_at": "2026-10-28T09:30:00Z",
"location": {"lat": 25.2, "lng": 55.27, "accuracy": 7.5}, "receiver": {"name": "Sara Ali", "relationship": "self"},
"media": [{"field": "photo_0", "kind": "doorstep"}], "signature": {"field": "signature", "strokes": 41}}' \
-F 'photo_0=@door.webp' -F 'signature=@signature.png'| القاعدة | التفاصيل |
|---|---|
| عدم التكرار (Idempotency) | لكل استدعاء يغيّر الحالة op_uuid وlocal_seq. التكرار يجيب 200 مع duplicate: true والنتيجة المحفوظة. ويمكن إعادة إرسال استدعاء مرفوض بالمعرّف نفسه. |
| الأخطاء | حالة HTTP إضافة إلى {error: {code, message}}: 400 invalid_payload، 401 unauthorized، 403 forbidden / not_driver / otp_locked، 404 not_found، 409 stop_closed / conflict / settlement_closed، 413 too_large. |
| اللغة | يحدد Accept-Language لغة نصوص الخادم. |
| الملكية | لا يستطيع السائق لمس إلا محطاته؛ وتُرفض محطة سائق آخر أو معرّف عمليته بالرمز 403. |
ملاحظات الأمان
| الموضوع | ما تفعله الوحدة |
|---|---|
| الرموز المميزة (Tokens) | تُحفظ كبصمات SHA-256؛ وتُلغى عند تسجيل الخروج؛ والأجهزة مدرجة ويستطيع المدير إيقافها فقط (لا يمكن إعادة كتابة الرمز المميز والمستخدم). |
| رموز العملاء | بصمة بمفتاح من جهة الخادم + بصمة مملّحة منفصلة للهاتف؛ لا يُحفظ الرمز أبداً ولا يستطيع السائقون قراءة البريد الإلكتروني الذي يحمله؛ 5 محاولات لكل نافذة و15 في المجموع، وإعادة الإرسال محدودة بـ 3. |
| الرفع | تُفحص الصور والتوقيعات بمحتواها (WebP وJPEG وPNG) وحجمها بالبايت وأبعادها بالبكسل (12000 px على الأكثر للضلع الواحد و40 ميغابكسل) وعددها لكل محطة. |
| سير العمل | لا يكتب حقول الحالة والإثبات إلا سير العمل بالدور المناسب؛ وتستخدم الفحوص المستخدم والمجموعات، لا قيمة يرسلها العميل. |
| الأدلة | لا يمكن تعديل الصور والتوقيعات والسطور والتحصيلات أو حذفها عبر الشاشات أو RPC. |
| الخصوصية | لا يرى المحطة إلا سائق الرحلة والمُرسِلون؛ ويُحذف مسار GPS بعد مدة الاحتفاظ. |
الحدود وما لم يُتحقق منه
ببساطة: يرجى قراءة هذا قبل أن تعد عملاءك بأي شيء.
| الموضوع | الحد |
|---|---|
| SMS | لا توجد قناة SMS أو WhatsApp مدمجة: يُرسل الرمز بالبريد الإلكتروني. تتيح نقطة الربط _epod_send_otp للمطوّر إضافة قناة أخرى. |
| فحص الرمز دون اتصال | يمكن لمن يحمل الهاتف اختراق فحص البصمة على الهاتف بالتجربة المتكررة. يُسجَّل هذا الإثبات على أنه فُحص على الهاتف ويُنبَّه عليه؛ ولا يستطيع الخادم جعله أقوى. عطّل الإعداد للحصول على إثبات من جهة الخادم (الفصل 14). |
| الملاحة | لا إرشادات منعطفاً بمنعطف داخل التطبيق: يفتح Google Maps أو Waze أو Apple Maps عبر روابط. |
| تحسين المسار | مسافة مستقيمة، والجار الأقرب، و2-opt؛ دون حركة المرور ودون نوافذ زمنية ودون سعة المركبة. |
| النقد المطلوب تحصيله | يُقرأ من الفواتير المرحَّلة، ومع المبيعات من الطلب. الطلب الذي دُفع مسبقاً عبر الإنترنت دون فاتورة سيظهر كنقد مطلوب تحصيله: اضبط بدون دفع عند التسليم على المحطة. |
| التسوية | تُنشأ الدفعات بعملة الشركة؛ ولا تُسوّى الفواتير بعملة أخرى تلقائياً. ويُقيَّد العجز على حساب السيولة في يومية الطريقة، وهذا تبسيط إن كانت طرق الدفع لديك تستخدم حسابات معلّقة (outstanding). |
| المخزون الجاهز | لا يمكن وضع إلا أوامر التسليم الجاهزة التي حُجز مخزونها كاملاً في رحلة. إذا اختفى الحجز قبل الوصول إلى الباب يُسجَّل التسليم لكن لا يُطلب من Odoo اعتماده (لا مخزون سالب): تعرض المحطة المشكلة. |
| ما اختُبر هنا | للوحدة 217 اختباراً آلياً على قاعدة بيانات جديدة (عُرضت التقارير بصيغة HTML داخلها؛ واختُبر البريد الإلكتروني حتى طابور الإرسال). وللتطبيق 356 اختبار Dart، وflutter analyze نظيف، وشُغّل على محاكي iOS مقابل هذه الوحدة بموقع GPS مبرمج. |
| لا جهاز فعلي | لم يُشغَّل التطبيق على هاتف فعلي ولا على محاكي أندرويد: لم يُتحقق إلا من بناء التصحيح (debug) لأندرويد؛ وأُجريت كل فحوص التشغيل على محاكي iOS. لقطات الشاشة في هذا الدليل مأخوذة من المحاكي. |
| الكاميرا والماسح الحقيقيان | لا كاميرا في المحاكيات: لم تُجرَّب المعاينة المباشرة ولا الفلاش ولا تبديل الكاميرا ولا كاميرا النظام ولا ماسح الباركود بكاميرا حقيقية (جاءت الصور من صورة تجريبية في وضع التصحيح ومن مسار المعرض؛ أما الإدخال اليدوي للرمز ومنطق المطابقة فمُختبران). |
| النطاق الجغرافي في الخلفية | لم يُتحقق من النطاق الجغرافي والشاشة مطفأة على جهاز حقيقي (خدمة أندرويد الأمامية، وإذن «دائماً» في iOS)، ولا من الإشعار في الخلفية، ولا من مسار إذن «طوال الوقت» في أندرويد. المنطق مختبَر بالاختبارات الوحدوية وجرى المسار الأمامي بموقع GPS مبرمج. وفي الأقبية أو المرائب يذكر التطبيق أن الموقع غير متاح ويحصل المُرسِل على التنبيه GPS مفقود. |
| تطبيقات الملاحة | تم التحقق من Apple Maps (الرابط المباشر والعودة ومرحباً بعودتك) على المحاكي؛ أما Google Maps وWaze ونوايا geo: في أندرويد فلم تُفتح على جهاز. |
| بناء الإصدار والأجهزة اللوحية | لم تُنجز بناءات الإصدار (التوقيع، والتقليص، وأرشيف App Store)، ويغطي تخطيط الجهاز اللوحي اختبار واجهات (widget test) فقط. |
| اختبارات وحدوية فقط | ورقة التسوية الإضافية في التطبيق، والرد 413 للصورة الكبيرة جداً، وotp_expired، وفتح القفل من المُرسِل: غُطّيت باختبارات وحدوية واختبارات واجهات، ولم تُشغَّل مقابل الخادم من التطبيق. |
| فترات طويلة دون اتصال | لم تُجرَّب مئات الصور في الصادر؛ ولا يحدّ الطابور إلا مساحة تخزين الهاتف. |
| البريد الحقيقي وPDF | لم يكن خادم بريد حقيقي ولا محرك PDF لخادم Odoo إنتاجي جزءاً من اختبارات الوحدة. |
استكشاف الأخطاء وإصلاحها
| المشكلة | ما يجب فحصه |
|---|---|
| لا يستطيع السائق تسجيل الدخول | يحتاج إلى مستخدم داخلي بدور السائق (وإلا يظهر الخطأ not_driver) وكلمة المرور الصحيحة؛ ولا تستطيع الحسابات ذات المصادقة الثنائية استخدام التطبيق. |
| لا محطات على الهاتف | يجب أن تكون الرحلة مؤكدة أو قيد التنفيذ ويجب أن يكون تاريخها اليوم بالمنطقة الزمنية للسائق. افحص المنطقة الزمنية للمستخدم. |
| لا يعمل رصد الوصول أبداً | يحتاج العميل إلى موقع؛ افحص نصف القطر؛ وتأكد أن الهاتف يسمح بالموقع طوال الوقت. |
| لم يُعتمد أمر التسليم | افتح المحطة: الرسالة الحمراء تذكر السبب (مثلاً رقم تسلسلي غير معروف). أصلحه واضغط اعتماد أمر التسليم. |
| لم يستلم العميل الرمز | تحتاج جهة الاتصال إلى بريد إلكتروني ويحتاج Odoo إلى خادم بريد صادر. تعرض المحطة أين أُرسل الرمز. |
| يطلب الاعتماد اختيار يومية | الإعدادات، الدفع عند التسليم والتسوية، اختر اليوميات. |
| الصور مرفوضة | أكبر من الحد، أو ليست WebP/JPEG/PNG، أو أكثر من الحد الأقصى لكل محطة. |
| معرفة ما أرسله الهاتف | الإعداد، سجل المزامنة يعرض كل استدعاء مع رده. |
التحديث إلى إصدار جديد
خذ نسخة احتياطية من قاعدة بياناتك، واستبدل مجلد الوحدة بالإصدار الجديد، وأعد تشغيل Odoo وشغّل -u taqnix_epod_core. تبقى الرحلات والإثباتات والتسويات والإعدادات. أعد بناء التطبيق من المصدر الجديد عندما يذكر سجل التغييرات أن API تغيّرت.
الدعم
المساعدة في التثبيت وإصلاح الأخطاء مشمولان لمدة 6 أشهر مع تحديثات مدى الحياة. تواصل معنا عبر صفحة السوق التي اشتريت منها الوحدة أو راسل support@taqnix.com مع إصدار أودو ولقطة شاشة.