| رقم الأوردر | رقم التتبع | نوع بوسطة | حالة بوسطة | الحالة الحالية | التحديث المطلوب | تحديث شوبيفاي |
|---|
| التاريخ | الوقت | الموظف | الأوردر | الماكينة | التحديث | النتيجة | التتبع |
|---|---|---|---|---|---|---|---|
📋 لا يوجد سجل | |||||||
الهدف: مسح أرقام تتبع بوسطة اللي رجعت فعليًا للمخزن، والتحقق
من نوع الشحنة عند بوسطة وحالة الأوردر الحالية على شوبيفاي (S1/S2 +
returnStatus) قبل السماح بتحديث الحالة إلى Returned — من غير أي
انتظار لتحديث حالة بوسطة نفسها، لأن فعل المسح هو التأكيد الفعلي للاستلام
بالمخزن.
المستخدمون المستهدفون: موظفو المخزن المسؤولون عن استلام الشحنات الراجعة (RTO ومرتجعات ما بعد التسليم).
orderType = Send → رفض فوري (النوع ده شحن أصلي، مش من اختصاص أداة المرتجعات)orderCancel، استرجاع للمخزون) ثم يكتب custom.manual_status = ReturnedIN_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) |
dispositions اتسجّلت على اللوكيشن الصحorderCancel بيرجّع job (غير متزامن) — الأداة بتتأكد بعد الدفعة إن cancelledAt اتسجّل فعلاً وإن فيه دليل استرجاع مخزونمفيش أي تاج بيتكتب على شوبيفاي — التحديث بيروح مباشرة على الميتافيلد، بالإضافة لأكشن شوبيفاي واحد إضافي حسب المسار (إلغاء الأوردر لمسار RTO، أو استرجاع المخزون لمسار المرتجع بعد التسليم) — نفس الأكشنز المستخدمة في أداة Order Status Updater.
| 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 }. الصفوف لوحدها كانت بتخلي الواجهة تقول "تم التصدير ✓" على ملف مقصوص عند السقف |
§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 — تهريب أي نص جاي من بوسطة/شوبيفاي قبل ما يتحط في innerHTMLshared/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 ببانر التقصّcurrentEmployee — { username, displayName } جاي من sessionStorage عبر requireSession()، أبدًا في localStoragewarehouse_ops_center (الهب) بدل bosta_return — أفعال الأداة ما اتغيّرتشextra.sourceTool = 'bosta_orders_returned_scanner' — يفلتر سجل هذه الأداة داخل tool = 'metafields_change' المشتركTOOL_VERSION (shell) — نسخة الهب كله، مصدر واحد لكل الصفحات عبر renderVersionUI()doneInSession — علامة على الصف اللي اتنفّذ في الجلسة دي؛ بتمنع إعادة إرساله وبتتحافظ عليها عبر إعادة الاستعلامextra.result — success / warning / error / rejected / alreadyextra.stage — للصف المرفوض: lookup أو write (كان متوافق واتوقف وقت التنفيذ — سباق بين موظفين)TN_MIN_LEN / TN_MAX_LEN — حدود طول رقم التتبع (٨–١٣)WOC_API_TIMEOUT_MS (shell) — مهلة ٩٠ ثانية على كل نداء (AbortController)WOC_WORKERS.returned.min (shell) — أقل نسخة Worker الواجهة بتشتغل معاها. مالهاش أي علاقة بـ TOOL_VERSIONWOC_WORKERS.returned.url (shell) — ثابت في الكود، مش حقل إعدادات ولا localStorageLS_SECRET = 'warehouse_ops_worker_secret' (shell) — مفتاح مجموعة warehouse_ops، قيمة واحدة للست Workerstool = metafields_change. أحداث الدخول/الخروج تفضل تحت tool = bosta_return بدون تغيير.orderCancel) إجراء لا رجعة فيه، والفشل الجزئي لازم يبان في السجل.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 من الإعدادات بعد أي تغيير في التطبيق.orderCancel بترجّع Job، والقراءة الفورية بعدها بتفشل دايمًا تقريبًا فكل إلغاء ناجح كان بيطلع أصفر. دلوقتي backoff متصاعد + فحص job(id){ done } نفسه ووقوف على أول تأكيد، و{ jobDone, attempts, waitedMs } بترجع في الرد وفي D1.Send (قرار مقصود) — حراسات S1/S2/returnStatus هي اللي بترفض اللي مالوش مسار صحيح، لأن قايمة أنواع بوسطة بتتوسّع من غير إشعار.logged:false وبيظهر تنبيه — مش بيتبلع.bosta-returned.html لـBosta-Orders-Returned-Scanner.html، مطابقة حرفيًا لاسم ريبو الـ Worker المنفصل (نفس قاعدة Bosta-Orders-Shipped-Scanner.html في v1.34.0). ⚠️ الرابط القديم ما بقاش شغّال — حدّث أي بوكمارك على أجهزة المخزن.bosta-returned.html. ⚠️ الرابط القديم ما بقاش شغّال — حدّث أي بوكمارك على أجهزة المخزن.Returned في أداة تحديث الحالة، وهي نفس الحالة اللي الأداة دي بتكتبها على شوبيفاي. ⚠️ الأحمر ما ضاعش: نافذة التأكيد قبل الإلغاء وزرار التنفيذ وصفوف الرفض كلهم زي ما هم — البني chrome، والأحمر فعل.shared/shell.jswarehouse_ops (warehouse_ops_worker_secret) بدل مفتاح خاص بالأداة — قيمة واحدة للست Workerswarehouse_ops_center في D1 بدل bosta_return — أفعال الأداة ما اتغيّرتش ولسه تحت metafields_change بنفس extra.sourceTool، فالتاريخ ما اتكسرشrunDiag() القديمة كانت بتقرا متغيّر UI_VERSION مش موجود أصلاً — يعني الفحص كان بيقع عند أول سطر ويطلّع «فشل الفحص» بدل النتيجة. الفحص دلوقتي من الـ shell، وبيعرض سطر «إزاي تصلّحها» تحت الفحص الفاشل بسالاسم ✕)Returned بقى ليه بادج محايد وعدّاد مستقل ورسالة بالعربي، بدل شرح تقني بطول ٢٠٠ حرف بلون فشلtype = rejected) بالسبب المحسوب وقت التسجيل — سؤال "ليه المرتجع ده ما اتقفلش؟" بقى ليه إجابة بعد ما الشاشة تتقفل0 / 63 طول ٤٠-٦٠ ثانيةextra تالف كان بيوقّع تاب السجل كله (JSON.parse من غير حراسة) — دلوقتي الصف بيعدّي والباقي بيتعرضe.notes (سبب الفشل الكامل) كان بيتحط في .tracking-num (مصمّمة لنص قصير سطر واحد، white-space: nowrap موروثة من الجدول) بدل .reject-reason (بتلف وعندها max-width) المستخدمة أصلًا لنفس الغرض في جدول النتائج. عمود واحد طويل كان بيمدّد الجدول لعرض أكبر بكتير من الشاشة (اتقاس: ٢٣٣٤px بدل ٩٠٠px في نفس الحاوية)، فالموظف كان لسه محتاج يمرّر مسافة كبيرة عشان يشوف "النتيجة"/"التتبع" — بس الاتجاه اتقلب بدل ما يتحل. دلوقتي النص بيلف جوّه ٢٣٠px زي عمود الرفض في جدول النتائج بالظبطdirection: ltr عشان ترتيب الأعمدة يفضل ثابت، وحاوية السكرول (.table-wrap/.log-table-wrap) كانت بترث الـ RTL من الصفحة من غير ما تتحدد. النتيجة: أول ما الجدول يبقى أعرض من الشاشة، السكرول الأفقي بيفتح افتراضيًا من اليمين البصري، اللي بيوافق آخر الأعمدة (التحديث/النتيجة/التتبع في السجل) — والموظف بيشوف بس دول من غير أي إشارة إنه لازم يمرّر عشان يشوف التاريخ/الوقت/الموظف/الأوردر/الماكينة. الحاوية بقت direction: ltr صراحةً زي الجدول جواهاorderCancel بترجّع Job، والتحقق كان بينام مدد ثابتة ويقرا الأوردر من غير ما يبص على الـ Job نفسه، فالقراءة بتسبق التأكيد. دلوقتي backoff متصاعد + فحص job(id){ done } مجمّع + وقوف على أول تأكيد، و{ jobDone, attempts, waitedMs } بترجع في الرد وفي السجلMIN_WORKER_VERSIONWORKER SECRET بسInvalid disposition quantity بقت "مسترجَع قبل كده" بدل فشل، ودليل الاسترجاع في الإلغاء بقى بنافذة زمنية ضيقة بدل ٢ دقيقة قبل العمليةwrite_returns، وشوبيفاي كانت بترجّع الخطأ كـ GraphQL error علوي (data:null) والكود كان بيقرا userErrors بس (فاضية في الحالة دي) ويسجّل reverseDispose×N كأنه نجح. الاسترجاع الحقيقي كان بيعمله الـ Flow — واللي خفى العطل تمامًاshopifyGQL() بقت ترمي خطأ على كل أنواع الفشل: HTTP status، رد مش JSON، أخطاء GraphQL عليا، وdata فاضية — مفيش نداء شوبيفاي واحد ممكن يعدّي وهو فاشل. + إعادة محاولة تلقائية على THROTTLEDtotalQuantity − Σ dispositions) مش totalQuantity الأعمى — الـ reverseFulfillmentOrder بيفضل OPEN حتى بعد الاسترجاع الكامل، فالشرط القديم ماكانش بيمنع الاسترجاع المزدوج ولا بيفرّق بين "مسترجَع قبل كده" و"فشل"dispositions على اللوكيشن الصحorderCancel بيرجّع job غير متزامن، فالأداة بتتأكد إن cancelledAt اتسجّل فعلاً وإن فيه دليل استرجاع مخزون قبل ما تقول "تم"?action=diag + زرار 🩺 فحص النظام في الإعدادات — بيفحص المتغيرات وأسماءها، صلاحيات تطبيق شوبيفاي، الـ LOCATION_ID، بوسطة، D1، والـ Origin. بدون أي كتابة. الفحص ده كان هيكشف العطل ده في ثوانيget_config) — تحذير فوري لو النسخة المنشورة مش المتوقعة (Promote ناقص / Worker شبح)catch فاضي وبيتحول لـ"غير موجود ببوسطة" على كل الأرقام. دلوقتي بانر أحمر + وسم "تعذّر الاستعلام" على الأرقام المتأثرةlogged:false + تنبيه) بدل ما يتبلعLOCATION_ID) بيوقف العملية برسالة باسمه — قبل كده كان بيتحوّل لـ Location/undefined ويفشل بصمتreturnStatus = RETURN_REQUESTED بقى مرفوض — المرتجع لسه محتاج approve من CS، وقبله مفيش reverseFulfillmentOrder يترجع منه مخزون.main-tabs-bar بعرض كامل، نوافذ About/Changelog على .eco-modal بعرض 90% وهيدر ثابت، زرار إغلاق ✕ موحّد بإطار أحمر في كل النوافذsettingsModal اتسمى settingsOverlay (الاسم المعتمد)playBeep()orderCancel، استرجاع للمخزون) *قبل* كتابة الميتافيلد — نفس الأكشن المستخدم في Order Status Updater لحظة الوصول لـ ReturnedreverseFulfillmentOrderDispose) بعد كتابة الميتافيلد — نفس أكشن Order Status Updater►►Returned◄◄ / Returned بتحديث ميتافيلد S1/S2 مباشرة، بعد التحقق من الحالة الحالية + returnStatus على شوبيفاي (نفس نمط Bosta Orders Shipped Scanner)tool = metafields_change بدل bosta_return / returned — مع ضم السجل القديم في تاب السجل عشان ميختفيش