الخطوة 1 — مسح أرقام التتبع

0 أوردر
🔍
لم يتم مسح أي أرقام بعد
▲
الموظف
تحديد الكل
النتيجة
تحديد الكل
الماكينة
تحديد الكل
🔍
فترة سريعة
اليوم✓
أمس✓
آخر 3 أيام✓
آخر 7 أيام✓
آخر 30 يوم✓
آخر 90 يوم✓
الشهر الحالي✓
الشهر السابق✓
الربع الحالي✓
العام الحالي✓
العام السابق✓
من تاريخ
إلى تاريخ
▲
النتائج: —
التاريخ الوقت الموظف الأوردر الماكينة التحديث النتيجة التتبع
📋
لا يوجد سجل
ℹ️ عن الأداة — قسم مرتجعات بوسطة (مركز عمليات المخزن)
📋 وصف الأداة وطريقة العمل

الهدف: مسح أرقام تتبع بوسطة اللي رجعت فعليًا للمخزن، والتحقق من نوع الشحنة عند بوسطة وحالة الأوردر الحالية على شوبيفاي (S1/S2 + returnStatus) قبل السماح بتحديث الحالة إلى Returned — من غير أي انتظار لتحديث حالة بوسطة نفسها، لأن فعل المسح هو التأكيد الفعلي للاستلام بالمخزن.

المستخدمون المستهدفون: موظفو المخزن المسؤولون عن استلام الشحنات الراجعة (RTO ومرتجعات ما بعد التسليم).

كيف تعمل — Workflow

  1. الموظف يمسح أرقام تتبع بوسطة (سكانر أو يدوي)
  2. الأداة تستعلم بوسطة، وتجيب S1/S2/returnStatus من شوبيفاي لكل أوردر
  3. تتحقق من جدول القرار (تحت) وتعرض النتيجة — متوافق أو مرفوض مع السبب
  4. الموظف يراجع ويحدد الأوردرات المتوافقة، ثم يضغط "تحديث شوبيفاي"
  5. الأداة تعيد التحقق دفاعيًا لحظة الكتابة، ثم تنفذ لكل أوردر لوحده

منطق القرار (Decision Table)

  • orderType = Send → رفض فوري (النوع ده شحن أصلي، مش من اختصاص أداة المرتجعات)
  • مسار RTO: S1 ∈ {Shipped, In-Return} + S2 فاضي + returnStatus = NO_RETURN → يلغي الأوردر على شوبيفاي (orderCancel، استرجاع للمخزون) ثم يكتب custom.manual_status = Returned
  • مسار مرتجع بعد التسليم: S1 = Delivered + S2 ∈ {Shipped, In-Return} + returnStatus = IN_PROGRESS → يكتب custom.status_2_r_e = Returned ثم يسترجع كل قطعة راجعة فعليًا للمخزون (reverseFulfillmentOrderDispose) — بالكمية المتبقية فقط
  • returnStatus = RETURN_REQUESTED → مرفوض (من v3.2.0): المرتجع لسه محتاج approve من CS، وقبله شوبيفاي ما بتنشئش أي reverseFulfillmentOrder — يعني الحالة كانت هتتكتب والمخزون ما يرجعش
  • غير كده → رفض هذا الأوردر فقط مع سبب مفصّل، وباقي الأوردرات المحددة تتحدث عادي

⚙️ نتيجة كل صف — أربع حالات

الحالةمعناها
✓ تمالفعل تم واتأكد من رد شوبيفاي (الإلغاء مؤكَّد بـ cancelledAt، والاسترجاع بقراءة تحقق)
⚠ تم جزئيًاالفعل الأساسي تم بس فيه حاجة ما اتأكدتش — ممنوع تتحسب نجاح، والسبب معروض تحت البادج
✗ فشلالفعل ما تمّش — والسبب معروض. لو الإلغاء تم وكتابة الحالة فشلت، ده بيبان في سطر "ما تم فعليًا"
⏭ خلاص متعملحالة الأوردر هي الحالة المستهدفة أصلاً (Returned) — لا نجاح ولا فشل ولا رفض: مفيش حاجة كانت مطلوبة. بتتسجّل بـ extra.result = 'already' بعدّاد مستقل
⛔ مرفوضالانتقال مكانش مسموح — مفيش أي تنفيذ اتحاول. الصف بيتسجّل بالسبب، وextra.stage بيقول اترفض من الاستعلام (lookup) ولا اتوقف وقت التنفيذ (write)

التحقق بعد التنفيذ (v3.2.0)

  • الاسترجاع: العدّ بيتم من رد شوبيفاي نفسه، وبعدها قراءة تحقق بتأكد إن الـ dispositions اتسجّلت على اللوكيشن الصح
  • الإلغاء: orderCancel بيرجّع job (غير متزامن) — الأداة بتتأكد بعد الدفعة إن cancelledAt اتسجّل فعلاً وإن فيه دليل استرجاع مخزون
  • أي عملية ما اتأكدتش بتظهر صفراء (تم جزئيًا) مع سبب واضح — مش خضراء

مفيش أي تاج بيتكتب على شوبيفاي — التحديث بيروح مباشرة على الميتافيلد، بالإضافة لأكشن شوبيفاي واحد إضافي حسب المسار (إلغاء الأوردر لمسار RTO، أو استرجاع المخزون لمسار المرتجع بعد التسليم) — نفس الأكشنز المستخدمة في أداة Order Status Updater.

الـ Endpoints الرئيسية

actionالوصف
lookupبوسطة + شوبيفاي (S1/S2/returnStatus) + التحقق من الانتقال
updateإعادة تحقق دفاعي، ثم لكل أوردر لوحده: (RTO) orderCancel → metafieldsSet | (مرتجع بعد التسليم) metafieldsSet → reverseFulfillmentOrderDispose + D1 log. وبياخد كمان rejected[] فيسجّلها بنوع rejected من غير أي تنفيذ
diagجديد v3.2.0 — فحص ذاتي بدون أي كتابة: متغيرات الـ Worker وأسماؤها، صلاحيات تطبيق شوبيفاي (write_returns…)، الـ LOCATION_ID، بوسطة، D1، والـ Origin
get_configجديد v3.2.0 — نسخة الـ Worker؛ الواجهة بتقارنها بنسختها وبتحذّر لو مختلفين
get_logs / _countسجل هذه الأداة فقط (جديد + قديم) — فلترة server-side بقوايم: employees · results · machines + search + dateFrom/dateTo، وصفحة 100 صف
get_logs_exportاتغيّر v3.3.0 — بيرجّع { entries, cap, total, truncated }. الصفوف لوحدها كانت بتخلي الواجهة تقول "تم التصدير ✓" على ملف مقصوص عند السقف
🔧 تشريح الكود

FEATURE MAP

  • §STYLES — توكنز :root (الثيم الأحمر = override للـ accent بس) + كل CSS
  • §TOOL-JS::refreshRow / mergeLookupResults — إعادة الاستعلام بتستبدل الصف مش بتتخطّاه
  • §TOOL-JS::recheckBeforeUpdate — إعادة استعلام إجبارية قبل أي تنفيذ + بانر "اتغيّر إيه"
  • §TOOL-JS::confirmDanger (askConfirm) — نافذة تأكيد بتسمّي الأثر (كام إلغاء نهائي · كام استرجاع مخزون)
  • §TOOL-JS::chunkedUpdate — تقسيم الدفعة على مجموعات ١٠ + تقدّم حقيقي + نزع سلاح الصف (doneInSession)
  • §TOOL-JS::resultModal — نافذة ملخّص ما بعد التنفيذ (خمس حالات + تفاصيل المرفوض و"خلاص متعمل" في قايمتين منفصلتين)
  • §TOOL-JS::pendingRejected — المرفوض اللي لسه ما اتسجلش بالسبب ده (حارس التكرار في السجل)
  • §UPDATE::logRejectedItems (Worker) — إعادة تحقق من المرفوض وقت التسجيل + صف D1 بنوع rejected
  • §CONFIG::esc — تهريب أي نص جاي من بوسطة/شوبيفاي قبل ما يتحط في innerHTML
  • shared/shell.js — الهوية (requireSession) والهيدر الموحّد والإعدادات والتوست وحارس النسخة والفحص الذاتي 🩺، نسخة واحدة مضمّنة للهب كله
  • §SHELL-JS::freezeOnScroll — الهيدر وشريط التابات جوّه .sticky-header-wrap بعتبة مقيسة (measureSticky) + chip التاب
  • §LOGIN / §AUTH-JS — اتشالوا: الدخول بيحصل مرة واحدة في الشاشة الرئيسية للهب
  • PAGE_DIAG_LABELS — أسماء عربية لفحوصات ?action=diag (الـ Worker ده بيرجّع checks ككائن بمفاتيح إنجليزية)
  • §SCAN — سكانر جن + إضافة يدوية لأرقام التتبع
  • §TOOL-JS — lookup · جدول النتائج · startUpdate (٣ حالات) · تصدير النتائج
  • §LOG-JS — تاب السجل: القسم الموحّد (فلاتر multi-select + مدى تاريخ + ترتيب ٣ حالات + صف النتائج) و pagination وتصدير XLSX ببانر التقصّ

KEY VARIABLES

  • currentEmployee — { username, displayName } جاي من sessionStorage عبر requireSession()، أبدًا في localStorage
  • الدخول/الخروج بقوا تحت warehouse_ops_center (الهب) بدل bosta_return — أفعال الأداة ما اتغيّرتش
  • extra.sourceTool = 'bosta_orders_returned_scanner' — يفلتر سجل هذه الأداة داخل tool = 'metafields_change' المشترك
  • TOOL_VERSION (shell) — نسخة الهب كله، مصدر واحد لكل الصفحات عبر renderVersionUI()
  • doneInSession — علامة على الصف اللي اتنفّذ في الجلسة دي؛ بتمنع إعادة إرساله وبتتحافظ عليها عبر إعادة الاستعلام
  • extra.result — success / warning / error / rejected / already
  • extra.stage — للصف المرفوض: lookup أو write (كان متوافق واتوقف وقت التنفيذ — سباق بين موظفين)
  • TN_MIN_LEN / TN_MAX_LEN — حدود طول رقم التتبع (٨–١٣)
  • WOC_API_TIMEOUT_MS (shell) — مهلة ٩٠ ثانية على كل نداء (AbortController)
  • WOC_WORKERS.returned.min (shell) — أقل نسخة Worker الواجهة بتشتغل معاها. مالهاش أي علاقة بـ TOOL_VERSION
  • WOC_WORKERS.returned.url (shell) — ثابت في الكود، مش حقل إعدادات ولا localStorage
  • LS_SECRET = 'warehouse_ops_worker_secret' (shell) — مفتاح مجموعة warehouse_ops، قيمة واحدة للست Workers

الـ Workers اللي الصفحة دي بتناديهم

—

NOTES

  • D1 logging: العمليات الجديدة تحت tool = metafields_change. أحداث الدخول/الخروج تفضل تحت tool = bosta_return بدون تغيير.
  • أي أوردر توصّل لمرحلة التنفيذ الفعلي (نجح أو فشل) بيتسجل في D1 دايمًا — عشان الإلغاء (orderCancel) إجراء لا رجعة فيه، والفشل الجزئي لازم يبان في السجل.
  • v3.2.0 — قاعدة "مفيش نجاح من غير دليل": shopifyGQL() في الـ Worker بترمي خطأ على كل أنواع الفشل (HTTP status، رد مش JSON، أخطاء GraphQL عليا بـ data:null). قبل كده أخطاء الصلاحيات كانت بتعدّي كنجاح لأن userErrors بتبقى فاضية لما data ترجع null.
  • الاسترجاع بيتم بالكمية المتبقية (totalQuantity − Σ dispositions) — الـ reverseFulfillmentOrder بيفضل OPEN حتى بعد الاسترجاع الكامل، فشرط OPEN لوحده مش بيمنع الاسترجاع المزدوج.
  • الصلاحيات المطلوبة على تطبيق شوبيفاي: read_orders · write_orders · read_returns · write_returns · read_inventory · write_inventory · read_locations. شغّل diag من الإعدادات بعد أي تغيير في التطبيق.
  • v3.3.0 — التحقق من الإلغاء بيستنى، مايقراش فورًا: orderCancel بترجّع Job، والقراءة الفورية بعدها بتفشل دايمًا تقريبًا فكل إلغاء ناجح كان بيطلع أصفر. دلوقتي backoff متصاعد + فحص job(id){ done } نفسه ووقوف على أول تأكيد، و{ jobDone, attempts, waitedMs } بترجع في الرد وفي D1.
  • v3.3.0 — رقمين تتبع لنفس الأوردر: الـ Worker بيتخطى التكرار في نفس الدفعة بدل ما يلغي الأوردر مرتين على لقطة حالة قديمة.
  • الأداة بتقبل أي نوع شحنة من بوسطة غير Send (قرار مقصود) — حراسات S1/S2/returnStatus هي اللي بترفض اللي مالوش مسار صحيح، لأن قايمة أنواع بوسطة بتتوسّع من غير إشعار.
  • فشل الكتابة في D1 بيرجع في الرد كـ logged:false وبيظهر تنبيه — مش بيتبلع.
⚠️ تأكيد
✅ تم التحديث
📋 سجل التحديثات
v1.35.1 25-09-2026
  • تغيير🔴 الصفحة اتسمّت تاني — من bosta-returned.html لـBosta-Orders-Returned-Scanner.html، مطابقة حرفيًا لاسم ريبو الـ Worker المنفصل (نفس قاعدة Bosta-Orders-Shipped-Scanner.html في v1.34.0). ⚠️ الرابط القديم ما بقاش شغّال — حدّث أي بوكمارك على أجهزة المخزن.
v1.25.0 14-09-2026
  • تغيير🔴 اسم الأداة بقى «قسم مرتجعات بوسطة» والصفحة اتنقلت لـbosta-returned.html. ⚠️ الرابط القديم ما بقاش شغّال — حدّث أي بوكمارك على أجهزة المخزن.
  • تغيير🎨 ثيم الصفحة بقى بنّي — نفس لون حالة Returned في أداة تحديث الحالة، وهي نفس الحالة اللي الأداة دي بتكتبها على شوبيفاي. ⚠️ الأحمر ما ضاعش: نافذة التأكيد قبل الإلغاء وزرار التنفيذ وصفوف الرفض كلهم زي ما هم — البني chrome، والأحمر فعل.
v1.22.0 10-09-2026
  • جديد الأداة بقت صفحة جوّه مركز عمليات المخزن. الموظف بيدخل مرة واحدة من الشاشة الرئيسية وبيتنقّل بين الطباعة والتغليف وسكانر المرتجعات من غير ما يدخل تاني. شاشة الدخول والهيدر والإعدادات والتوست وحارس النسخة كلهم بقوا من shared/shell.js
  • تغيير السر بقى سر مجموعة warehouse_ops (warehouse_ops_worker_secret) بدل مفتاح خاص بالأداة — قيمة واحدة للست Workers
  • تغيير لون التفاعل بقى أزرق الهب بدل الأحمر. كتلة التوكنز الحمرا اتشالت (توكنز في صفحة = التوكنز اتفرّقت). والتحذير ما ضاعش: الأحمر بقى في اللي بيحذّر فعلاً — نافذة التأكيد قبل الإلغاء وزرار الخطر وصفوف الرفض ومربع الأداة في الشاشة الرئيسية
  • تغيير الدخول والخروج بيتسجّلوا تحت warehouse_ops_center في D1 بدل bosta_return — أفعال الأداة ما اتغيّرتش ولسه تحت metafields_change بنفس extra.sourceTool، فالتاريخ ما اتكسرش
  • إصلاح زرار الفحص الذاتي 🩺 كان بيرمي. runDiag() القديمة كانت بتقرا متغيّر UI_VERSION مش موجود أصلاً — يعني الفحص كان بيقع عند أول سطر ويطلّع «فشل الفحص» بدل النتيجة. الفحص دلوقتي من الـ shell، وبيعرض سطر «إزاي تصلّحها» تحت الفحص الفاشل بس
  • إصلاح فلتر الموظف في تاب السجل بقى ليه نداء خاص بيه. كان بيتملّى كأثر جانبي لشاشة الدخول، ومن غيرها كان هيفضل فاضي بلا أي خطأ
  • جديد زرار 🏠 الرئيسية في نص الهيدر، وزرار الموظف بقى هو زرار الخروج (الاسم ✕)
v3.4 07-09-2026
  • إصلاح الصف اللي اتنفّذ بيتنزع سلاحه فورًا. قبل كده بعد دفعة ناجحة بالكامل الصفوف كانت بتفضل مختارة والزرار بيفضل مكتوب عليه نفس العدد ومفيش نافذة ملخّص — يعني الشاشة بعد النجاح شكلها زي قبل الضغط بالظبط، فالموظف بيضغط تاني. الأثر المقيس من السجل: ٥٩ من ٦١ صف فشل (٩٧٪) كانوا على أوردرات نجحت قبلها، بعضها بفارق ٨ ثواني. دلوقتي الصف بيتشال من الاختيار وبيتقفل وحالته في الجدول بتتحدّث
  • جديد نافذة تأكيد قبل التنفيذ — بتقول الأثر بالاسم: كام أوردر هيتلغي نهائيًا (مفيش رجوع) وكام هيرجّع مخزون. قبل كده الضغطة الواحدة كانت بتنفّذ على طول، بينما تسجيل الخروج كان له تأكيد
  • جديد إعادة استعلام إجبارية قبل التنفيذ — لو أي أوردر مختار اتغيّرت حالته أو ما اتأكدتش، الدفعة كلها بتتوقف من غير أي تنفيذ، الجدول بيتحدّث، وبانر بيقول اتغيّر إيه بالظبط
  • إصلاح زرار "استعلام بوسطة" بقى بيعمل إعادة استعلام حقيقية — الرقم الموجود في الجدول كان بيتخطّى، فالزرار يبان إنه استعلم وهو بيعرض حالة اتقرأت من ٢٠ دقيقة
  • جديد نافذة ملخّص بعد التنفيذ (ناجح · محتاج مراجعة · فشل · خلاص متعمل · مرفوض) مع تفاصيل كل أوردر — بدل توست بيختفي في ٣ ثواني
  • جديد حالة ⏭ خلاص متعمل — أوردر حالته بالفعل Returned بقى ليه بادج محايد وعدّاد مستقل ورسالة بالعربي، بدل شرح تقني بطول ٢٠٠ حرف بلون فشل
  • جديد تسجيل الأوردر المرفوض في السجل (type = rejected) بالسبب المحسوب وقت التسجيل — سؤال "ليه المرتجع ده ما اتقفلش؟" بقى ليه إجابة بعد ما الشاشة تتقفل
  • جديد التنفيذ بيتقسّم على مجموعات (١٠ أوردرات) والجدول بيتلوّن أول بأول وشريط التقدّم بقى حقيقي — قبل كده الشاشة كانت بتقول 0 / 63 طول ٤٠-٦٠ ثانية
  • إصلاح صف واحد بـ extra تالف كان بيوقّع تاب السجل كله (JSON.parse من غير حراسة) — دلوقتي الصف بيعدّي والباقي بيتعرض
  • إصلاح الترتيب في السجل بقى على السجل كله مش على الصفحة المعروضة بس، وأسماء الموظفين بقت بتظهر بالاسم المعروض مش بالـ username
  • إصلاح السكانر: شرط التسريع ماكانش بيتحقق أبدًا فالتأخير كان دايمًا ٤٠٠ms، وبقى فيه حارس على طول الرقم بيمسك الباركودين اللي بيتلزقوا في رقم واحد
  • جديد مهلة ٩٠ ثانية على كل نداء + رسايل شوبيفاي المتكررة بقت بالعربي جنب النص الأصلي
v3.3.2 05-09-2026
  • إصلاح عمود "التحديث" في السجل كان بيوسّع الجدول كله لعرض هائل لما يحتوي سبب رفض طويل — إصلاح v3.3.1 (اتجاه السكرول) صحّح مين الأعمدة اللي بتفتح افتراضيًا، بس ما لمسش السبب الحقيقي: نص e.notes (سبب الفشل الكامل) كان بيتحط في .tracking-num (مصمّمة لنص قصير سطر واحد، white-space: nowrap موروثة من الجدول) بدل .reject-reason (بتلف وعندها max-width) المستخدمة أصلًا لنفس الغرض في جدول النتائج. عمود واحد طويل كان بيمدّد الجدول لعرض أكبر بكتير من الشاشة (اتقاس: ٢٣٣٤px بدل ٩٠٠px في نفس الحاوية)، فالموظف كان لسه محتاج يمرّر مسافة كبيرة عشان يشوف "النتيجة"/"التتبع" — بس الاتجاه اتقلب بدل ما يتحل. دلوقتي النص بيلف جوّه ٢٣٠px زي عمود الرفض في جدول النتائج بالظبط
v3.3.1 05-09-2026
  • إصلاح جدول السجل وجدول النتائج كانا بيفتحوا على آخر أعمدتهم بدل أولها — الصفحة كلها RTL، بس الجدولين متعمول عليهم direction: ltr عشان ترتيب الأعمدة يفضل ثابت، وحاوية السكرول (.table-wrap/.log-table-wrap) كانت بترث الـ RTL من الصفحة من غير ما تتحدد. النتيجة: أول ما الجدول يبقى أعرض من الشاشة، السكرول الأفقي بيفتح افتراضيًا من اليمين البصري، اللي بيوافق آخر الأعمدة (التحديث/النتيجة/التتبع في السجل) — والموظف بيشوف بس دول من غير أي إشارة إنه لازم يمرّر عشان يشوف التاريخ/الوقت/الموظف/الأوردر/الماكينة. الحاوية بقت direction: ltr صراحةً زي الجدول جواها
v3.3.0 05-09-2026
  • إصلاح كل إلغاء ناجح كان بيطلع أصفر "مش مؤكَّد" — orderCancel بترجّع Job، والتحقق كان بينام مدد ثابتة ويقرا الأوردر من غير ما يبص على الـ Job نفسه، فالقراءة بتسبق التأكيد. دلوقتي backoff متصاعد + فحص job(id){ done } مجمّع + وقوف على أول تأكيد، و{ jobDone, attempts, waitedMs } بترجع في الرد وفي السجل
  • إصلاح تصدير السجل كان بيتقص عند السقف في السكوت — الأداة كانت بتقول "تم التصدير ✓" على ملف ناقص. دلوقتي فيه بانر ثابت فوق الجدول بالرقمين (المصدَّر / الإجمالي)، ورسالة النجاح بتظهر بس لو الملف كامل
  • إصلاح رقمين تتبع لنفس الأوردر كانوا بيلغوه مرتين على لقطة حالة قديمة — التكرار بقى بيتخطى في نفس الدفعة برسالة واضحة
  • تغيير تاب السجل بقى قسم موحّد بالمعيار: كل الفلاتر اختيار متعدد (الموظف · النتيجة · الماكينة) + فلتر فترة (بدون افتراضي) + بحث + chips + صف "النتائج" + ترتيب ٣ حالات على الأعمدة + طي الفلاتر والجدول. الفلترة كلها server-side
  • تغيير حارس نسخة الـ Worker بقى حد أدنى بدل تطابق حرفي — الرقمين مستقلين بالتصميم، فالتطابق كان بيولّع تحذير كاذب دايم والموظف بيتعوّد يتجاهله. دلوقتي بيولّع بس لو الـ Worker أقدم من MIN_WORKER_VERSION
  • تغيير WORKER URL و ADMIN WORKER URL اتشالوا من الإعدادات — بقوا ثوابت في الكود؛ الإعدادات فيها WORKER SECRET بس
  • جديد الهيدر وشريط التابات بيتقفلوا مع السكرول (Freeze on Scroll) بعتبة مقيسة مش رقم ثابت، ومعاهم chip بيبدّل التابات وإنت نازل
  • تغيير صيغة التاريخ والوقت بقت موحّدة (📅 يوم/شهر/سنة 🕐 وقت)، والتاريخ والوقت عمودين منفصلين في السجل. وعرض الأداة بقى 1200px
  • إصلاح رسالة Invalid disposition quantity بقت "مسترجَع قبل كده" بدل فشل، ودليل الاسترجاع في الإلغاء بقى بنافذة زمنية ضيقة بدل ٢ دقيقة قبل العملية
v3.2.0 23-08-2026
  • إصلاح الاسترجاع للمخزون ماكانش بيحصل أصلاً في مسار [S-2] — التطبيق ماكانش واخد صلاحية write_returns، وشوبيفاي كانت بترجّع الخطأ كـ GraphQL error علوي (data:null) والكود كان بيقرا userErrors بس (فاضية في الحالة دي) ويسجّل reverseDispose×N كأنه نجح. الاسترجاع الحقيقي كان بيعمله الـ Flow — واللي خفى العطل تمامًا
  • إصلاح shopifyGQL() بقت ترمي خطأ على كل أنواع الفشل: HTTP status، رد مش JSON، أخطاء GraphQL عليا، وdata فاضية — مفيش نداء شوبيفاي واحد ممكن يعدّي وهو فاشل. + إعادة محاولة تلقائية على THROTTLED
  • إصلاح الاسترجاع بقى بالكمية المتبقية (totalQuantity − Σ dispositions) مش totalQuantity الأعمى — الـ reverseFulfillmentOrder بيفضل OPEN حتى بعد الاسترجاع الكامل، فالشرط القديم ماكانش بيمنع الاسترجاع المزدوج ولا بيفرّق بين "مسترجَع قبل كده" و"فشل"
  • إصلاح العدّاد بقى بيعدّ اللي شوبيفاي أكدته مش اللي إحنا طلبناه — وبعده قراءة تحقق بتأكد الـ dispositions على اللوكيشن الصح
  • جديد تحقق من الإلغاء بعد الدفعة — orderCancel بيرجّع job غير متزامن، فالأداة بتتأكد إن cancelledAt اتسجّل فعلاً وإن فيه دليل استرجاع مخزون قبل ما تقول "تم"
  • جديد حالة ثالثة ⚠ تم جزئيًا (صفراء) — الميتافيلد اتكتب بس فيه حاجة محتاجة عينك (ما اترجعش مخزون / ما اتأكدناش من الإلغاء / القطع كانت مسترجَعة قبل كده). قبل كده الحالات دي كانت بتبان خضراء
  • جديد ?action=diag + زرار 🩺 فحص النظام في الإعدادات — بيفحص المتغيرات وأسماءها، صلاحيات تطبيق شوبيفاي، الـ LOCATION_ID، بوسطة، D1، والـ Origin. بدون أي كتابة. الفحص ده كان هيكشف العطل ده في ثواني
  • جديد مقارنة نسخة الواجهة بنسخة الـ Worker (get_config) — تحذير فوري لو النسخة المنشورة مش المتوقعة (Promote ناقص / Worker شبح)
  • إصلاح أخطاء بوسطة بقت تظهر — أي فشل في نداء البحث كان بيتبلع في catch فاضي وبيتحول لـ"غير موجود ببوسطة" على كل الأرقام. دلوقتي بانر أحمر + وسم "تعذّر الاستعلام" على الأرقام المتأثرة
  • إصلاح التحقق من اسم الأوردر الراجع من بحث شوبيفاي — أي اسم غير مطابق بيترفض بدل ما تتكتب الحالة على أوردر تاني
  • إصلاح فشل الكتابة في D1 بقى بيبان (logged:false + تنبيه) بدل ما يتبلع
  • إصلاح متغير ناقص (زي LOCATION_ID) بيوقف العملية برسالة باسمه — قبل كده كان بيتحوّل لـ Location/undefined ويفشل بصمت
  • تغيير returnStatus = RETURN_REQUESTED بقى مرفوض — المرتجع لسه محتاج approve من CS، وقبله مفيش reverseFulfillmentOrder يترجع منه مخزون
  • تغيير CORS اتحوّل لقائمة نطاقات مسموحة (Option B) — الأداة بقت بتلغي أوردرات وبتحرّك مخزون، يعني أداة كتابة
  • جديد عمود النتيجة في تاب السجل + أعمدة جديدة في تصدير XLSX (النتيجة · قطع للمخزن · التحذيرات)
v3.1.1 19-08-2026
  • تغيير ترقية الواجهة بالكامل لمعايير UI Standard v2: شاشة دخول بخطوتين مع كيبورد + صوت + اهتزاز عند الخطأ، تابات .main-tabs-bar بعرض كامل، نوافذ About/Changelog على .eco-modal بعرض 90% وهيدر ثابت، زرار إغلاق ✕ موحّد بإطار أحمر في كل النوافذ
  • تغيير settingsModal اتسمى settingsOverlay (الاسم المعتمد)
  • تغيير جداول النتائج والسجل بقت كل خلاياها في المنتصف مع خطوط فاصلة رأسية خفيفة (معيار الجداول الموحّد)
  • جديد زرار الإعدادات في شاشة الدخول بقى بيتلوّن أخضر/أحمر حسب اكتمال الإعدادات
  • جديد أصوات تنبيه (دخول ناجح/فشل، مسح ناجح) عبر playBeep()
v3.1.0 19-08-2026
  • جديد مسار RTO (S1 → Returned) بقى بيلغي الأوردر على شوبيفاي (orderCancel، استرجاع للمخزون) *قبل* كتابة الميتافيلد — نفس الأكشن المستخدم في Order Status Updater لحظة الوصول لـ Returned
  • جديد مسار المرتجع بعد التسليم ([S-2] → Returned) بقى بيسترجع كل قطعة راجعة فعليًا للمخزون (reverseFulfillmentOrderDispose) بعد كتابة الميتافيلد — نفس أكشن Order Status Updater
  • تغيير تحديث شوبيفاي بقى بيتم أوردر أوردر بالتتابع (مش batched) عشان الإلغاء/الاسترجاع يترابطوا صح مع كل أوردر لوحده
  • تغيير أي أوردر توصل لمرحلة التنفيذ (نجح أو فشل) بقى بيتسجل في السجل دايمًا — قبل كده الفشل ماكانش بيتسجل، وده كان بيضيع أثر أي فشل جزئي (مثلاً: الإلغاء نجح والميتافيلد فشل)
v3.0.0 18-08-2026
  • جديد استبدال تاجات ►►Returned◄◄ / Returned بتحديث ميتافيلد S1/S2 مباشرة، بعد التحقق من الحالة الحالية + returnStatus على شوبيفاي (نفس نمط Bosta Orders Shipped Scanner)
  • جديد جدول قرار: مسار RTO يكتب S1 = Returned، ومسار المرتجع بعد التسليم يكتب S2 = Returned — بدون انتظار حالة بوسطة
  • جديد إعادة تحقق دفاعية لحظة الكتابة (defensive re-validate) قبل أي تعديل فعلي
  • جديد رقم الأوردر أصبح هايبرلينك مباشر لصفحة الأوردر على شوبيفاي
  • جديد نافذة "عن الأداة" (ℹ️)
  • تغيير D1 logging انتقل لـ tool = metafields_change بدل bosta_return / returned — مع ضم السجل القديم في تاب السجل عشان ميختفيش
  • تغيير جدول النتائج فيه أعمدة جديدة: الحالة الحالية (S1/S2) والتحديث المطلوب/سبب الرفض
v2.0.0 قديم — نظام التاجات · 13-05-2025
  • جديد نسخة كاملة مبنية على الحساب الجديد (ecommoda-dev) مع D1
  • جديد نظام Login بـ PIN عبر Universal D1 Auth
  • جديد سجل العمليات في D1 مع pagination وتصدير XLSX
  • جديد Worker URL كـ query params بدل path-based routing
  • تغيير نمط السكانر محسّن — Bosta Warehouse Return v1 → v2