UX-led design · Odoo 19 · Open sourceتصميمٌ بقيادة التجربة · Odoo 19 · مفتوح المصدر● Live · LGPL-3.0حيّ · LGPL-3.0
Smart Expense Manager — approvals at the speed of one click.Smart Expense Manager — موافقاتٌ بسرعة نقرةٍ واحدة.
An Odoo 19 custom module that replaces paper-based expense flows. Token-secured email approvals route via the hr.employee hierarchy — no login required. Auto-generated journal entries on finance sign-off; monthly PDF reports emailed by cron.وحدة Odoo 19 مخصّصة تحلّ محلّ تدفّقات النفقات الورقية. موافقاتٌ بريديّة مؤمّنة برمز تُوجَّه عبر تسلسل hr.employee — دون الحاجة لتسجيل الدخول. قيودٌ محاسبية مُولّدة تلقائياً عند اعتماد المالية؛ وتقارير PDF شهرية تُرسَل بالبريد عبر cron.
- Yearالسنة
- 2026 — Present2026 — حتى الآن
- Roleالدور
- UX-led design + Sole developerتصميمٌ بقيادة التجربة + مطوّرة وحيدة
- Stackالتقنيات
- PythonOdoo 19 ORMPostgreSQLQWebOWLXMLBootstrap
§ Overviewنظرة عامة
What it does, and what I owned.ما الذي يفعله، وما الذي تولّيته.
Employee submits a receipt from mobile. Manager approves with one click from email. Finance posts with one click from email. The journal entry is generated automatically and a monthly department digest is mailed by cron — no logins along the way.الموظّف يقدّم إيصالاً من الجوال. المدير يوافق بنقرةٍ واحدة من البريد. المالية تُرحّل بنقرةٍ واحدة من البريد. يُولَّد القيد المحاسبي تلقائياً ويُرسَل ملخّصٌ شهري للقسم عبر cron — دون أي تسجيل دخولٍ في الطريق.
- Roleالدور
- UX + sole developerتجربة المستخدم + مطوّرة وحيدة
- Timelineالإطار الزمني
- 2026 — present2026 — حتى الآن
- Module typeنوع الوحدة
- Odoo 19 customOdoo 19 مخصّصة
- Usersالمستخدمون
- Employees · managers · financeموظفون · مديرون · مالية
- Auth patternنمط المصادقة
- Token-secured URLرابطٌ مؤمّن برمز
- Licenseالترخيص
- LGPL-3.0 · open sourceLGPL-3.0 · مفتوح المصدر
§ Problemالمشكلة
Paper-based expense workflows in small businesses are quietly broken.تدفّقات النفقات الورقية في الشركات الصغيرة معطّلةٌ بصمت.
In a typical small business in Damascus, an employee buys something for work, keeps the receipt in a desk drawer for two weeks, hands it to a manager who signs a paper form, walks it to finance who types it into a ledger — and at every stage someone is the bottleneck. Receipts get lost. Numbers get re-typed. The whole loop is invisible to the company until month-end.في شركةٍ صغيرة نموذجية بدمشق، يشتري موظّفٌ شيئاً للعمل، ويحتفظ بالإيصال في درج مكتبٍ أسبوعين، ثم يسلّمه لمديرٍ يوقّع نموذجاً ورقياً، ويمشي به إلى المالية التي تكتبه في دفترٍ — وفي كل مرحلةٍ يكون أحدٌ هو عنق الزجاجة. تضيع الإيصالات. تُعاد كتابة الأرقام. وتبقى الحلقة كلّها غير مرئيةٍ للشركة حتى نهاية الشهر.
Existing Odoo expense modules require everyone in the chain to log into the system. In practice, managers don't log in. Approvals stall. The system goes unused. I needed a flow that works for people who never open Odoo.تتطلّب وحدات نفقات Odoo الموجودة أن يسجّل كلّ من في السلسلة دخوله إلى النظام. وعملياً، المديرون لا يسجّلون الدخول. تتعثّر الموافقات. ولا يُستخدَم النظام. احتجتُ تدفّقاً يعمل لأناسٍ لا يفتحون Odoo أبداً.
§ Users & personasالمستخدمون والـ Personas
Who has to actually use it.من عليه أن يستخدمه فعلاً.
The flow crosses three roles, and the one who decides whether the system lives or dies is the manager who never logs in. Each role became a persona with a one-line story and the friction that kept the old paper loop alive.يعبر التدفّق ثلاثة أدوار، ومن يقرّر حياة النظام أو موته هو المدير الذي لا يسجّل الدخول أبداً. صار كلّ دورٍ persona بقصةٍ من سطرٍ والاحتكاك الذي أبقى الحلقة الورقية القديمة حيّة.
Omar — employeeعمر — موظّف
Submits the expenseيقدّم النفقة
“I just want to snap the receipt and get reimbursed — not babysit a paper form through the building.أريد فقط أن ألتقط صورة الإيصال وأُعوَّض — لا أن أرافق نموذجاً ورقياً عبر المبنى.”
Goalsالأهداف
Frustrationsالإحباطات
Nour — line managerنور — مديرة مباشِرة
Approves · the make-or-break userتوافق · المستخدمة الحاسمة
“I want to approve in one tap from my inbox — I'm not going to log into yet another system to click yes.أريد أن أوافق بنقرةٍ واحدة من بريدي — لن أسجّل الدخول إلى نظامٍ آخر فقط لأنقر «نعم».”
Goalsالأهداف
Frustrationsالإحباطات
Farah — financeفرح — المالية
Posts to the ledgerتُرحّل إلى دفتر الأستاذ
“I want a clean ledger — only real, approved liabilities, never entries I have to reverse.أريد دفتر أستاذٍ نظيفاً — التزاماتٌ حقيقية معتمدة فقط، لا قيوداً أُضطرّ لعكسها.”
Goalsالأهداف
Frustrationsالإحباطات
§ Design strategyاستراتيجية التصميم
Optimize for the approval that actually happens.حسّن من أجل الموافقة التي تحدث فعلاً.
A module that's technically complete but never used is a failure. The whole strategy was to remove every reason a manager might not approve — starting with the login.وحدةٌ مكتملة تقنياً لكن لا تُستخدَم أبداً هي فشل. كانت الاستراتيجية كلّها إزالة كل سببٍ قد يجعل المدير لا يوافق — بدءاً من تسجيل الدخول.
- Goalالهدف
- Approvals that actually get done, fastموافقاتٌ تُنجَز فعلاً، وبسرعة
- Hypothesisالفرضية
- Email-as-UI removes the stall that kills adoption«البريد كواجهة» يزيل التعثّر الذي يقتل التبنّي
- Priorityالأولوية
- Friction reduction over feature surfaceتقليل الاحتكاك قبل اتّساع الميزات
- Tradeoffالمفاضلة
- Token-security burden for a zero-login flowعبء تأمين الرمز مقابل تدفّقٍ بلا تسجيل دخول
§ Approachالمقاربة
Email is the UI.البريد هو الواجهة.
The module attaches a unique token to each expense request when it's sent to a manager. The approval email contains two links: Approve and Reject. Each link is a one-time URL bound to the token, the request ID, and the manager's hr.employee record. Clicking it triggers a state transition — no Odoo login required.تُرفق الوحدة رمزاً فريداً بكل طلب نفقةٍ عند إرساله إلى المدير. ويحوي بريد الموافقة رابطين: موافقة ورفض. كلّ رابطٍ عنوانٌ يُستخدَم مرّةً واحدة مرتبطٌ بالرمز، ومعرّف الطلب، وسجلّ hr.employee للمدير. والنقر عليه يُطلق انتقال حالة — دون الحاجة لتسجيل الدخول إلى Odoo.
▦ Architectureالبنية · Smart Expense Manager — approval flowSmart Expense Manager — مسار الموافقة
SVG
Approval email
Visual placeholder · add exportصورة مؤقتة · أضف التصدير
§ Technical architectureالبنية التقنية
Three trade-offs that shaped the build.ثلاث مفاضلاتٍ شكّلت البناء.
Token-secured URLs over OAuth approval flows.روابط مؤمّنة برمز بدل تدفّقات موافقة OAuth.
Contextالسياق
Decisionالقرار
Consequencesالنتائج
Journal entries on finance approval, not on submission.القيود المحاسبية عند موافقة المالية، لا عند التقديم.
Contextالسياق
Decisionالقرار
account.move is only generated on the finance-approval transition. Until then, the request is just an HR record.لا يُولَّد account.move إلا عند انتقال موافقة المالية. حتى ذلك الحين، يبقى الطلب مجرّد سجلّ موارد بشرية.Consequencesالنتائج
RBAC at the record-rule layer, not the menu layer.تحكّمٌ بالوصول في طبقة قواعد السجلات، لا طبقة القوائم.
Contextالسياق
Decisionالقرار
Consequencesالنتائج
§ Bilingual by defaultثنائي اللغة افتراضياً
Full EN/AR translations — not an afterthought.ترجمةٌ كاملة بالإنجليزية والعربية — لا فكرةً لاحقة.
Every field, label, status, email template, and PDF report ships with full Arabic and English translations. The approval emails detect the recipient's preferred language from their res.users.lang setting, and QWeb-generated PDF reports pick up the same locale automatically.كلّ حقلٍ وتسمية وحالة وقالب بريدٍ وتقرير PDF يُطلق بترجمةٍ كاملة بالعربية والإنجليزية. وتكتشف رسائل الموافقة لغة المستلِم المفضّلة من إعداد res.users.lang الخاص به، وتلتقط تقارير PDF المُولّدة بـQWeb المنطقة نفسها تلقائياً.
In a Damascus-based SME, this is what makes the difference between a module that gets installed and one that gets used.في شركةٍ صغيرة بدمشق، هذا ما يصنع الفرق بين وحدةٍ تُثبَّت وأخرى تُستخدَم.
§ Outcomesالنتائج
A pattern worth open-sourcing.نمطٌ يستحقّ أن يُفتَح مصدره.
Smart Expense is live and open source under LGPL-3.0 — the token-secured approval flow turns a multi-day paper loop into a one-click action that managers complete from their inbox, with access enforced at the ORM layer and a clean ledger downstream.Smart Expense حيّ ومفتوح المصدر تحت LGPL-3.0 — يحوّل تدفّق الموافقة المؤمّن بالرمز حلقةً ورقية تستغرق أياماً إلى إجراءٍ بنقرةٍ واحدة يُنجزه المديرون من بريدهم، بوصولٍ مفروضٍ في طبقة ORM ودفتر أستاذٍ نظيف تالياً.
- Reusable. The token-secured approval pattern generalizes far beyond expense reports.قابل لإعادة الاستخدام. نمط الموافقة المؤمّن بالرمز يتعمّم إلى ما هو أبعد بكثير من تقارير النفقات.
- Auditable. An Odoo 19 module signed with my name lives longer than a CV bullet.قابل للتدقيق. وحدة Odoo 19 موقّعةٌ باسمي تعيش أطول من سطرٍ في سيرةٍ ذاتية.
- Low IP risk. The module is mechanical, not strategic — sharing it costs nothing and helps the Odoo community.مخاطر ملكيةٍ فكرية منخفضة. الوحدة آليّة، لا استراتيجية — مشاركتها لا تكلّف شيئاً وتُفيد مجتمع Odoo.
§ Validationالتحقّق
The real test is adoption.الاختبار الحقيقي هو التبنّي.
For an internal tool, the success metric isn't a satisfaction score — it's whether managers actually approve. I'd validate with a short usability study on the one-click email path, then watch the token logs (which already record every transition) as the affinity-style signal for where the flow stalls, and prioritize from there.بالنسبة لأداةٍ داخلية، مقياس النجاح ليس درجة رضا — بل ما إذا كان المديرون يوافقون فعلاً. سأتحقّق بدراسة قابلية استخدامٍ قصيرة على مسار البريد بنقرةٍ واحدة، ثم أراقب سجلّات الرمز (التي تُسجّل كل انتقالٍ أصلاً) كإشارةٍ — على غرار التقارب — لأين يتعثّر التدفّق، وأرتّب الأولويات من هناك.
- P0The one-click Approve / Reject must work reliably across the email clients managers actually use — if it breaks once, trust in the link is gone.«موافقة / رفض» بنقرةٍ واحدة يجب أن يعمل بثباتٍ عبر عملاء البريد التي يستخدمها المديرون فعلاً — إن تعطّل مرّةً، ذهبت الثقة بالرابط.
- P1The Arabic and English approval emails must render identically well, since recipients act straight from the inbox.بريدا الموافقة بالعربية والإنجليزية يجب أن يُعرَضا بجودةٍ متطابقة، لأن المستلِمين يتصرّفون مباشرةً من البريد.
- P2A lightweight audit dashboard surfacing the token logs — proving adoption from data that already exists.لوحة تدقيقٍ خفيفة تُظهر سجلّات الرمز — لإثبات التبنّي من بياناتٍ موجودةٍ أصلاً.
§ Reflectionتأمّل
What I'd carry forward.ما سأحمله معي.
The win here was a product insight, not a technical one: meeting people where they already are (their inbox) beats any amount of in-app polish they'll never see. I'll keep reaching for the lowest-friction surface before building a new screen.كان الفوز هنا استنتاجاً عن المنتج، لا تقنياً: لقاء الناس حيث هم أصلاً (بريدهم) يتفوّق على أي قدرٍ من الصقل داخل التطبيق لن يروه أبداً. وسأظلّ أمدّ يدي إلى أقلّ السطوح احتكاكاً قبل بناء شاشةٍ جديدة.
Next, I'd add usage analytics and a lightweight audit dashboard — the token model already logs every transition, so the data to prove adoption is there to surface.تالياً، سأضيف تحليلات استخدامٍ ولوحة تدقيقٍ خفيفة — نموذج الرمز يُسجّل كلّ انتقالٍ أصلاً، فالبيانات اللازمة لإثبات التبنّي موجودةٌ وجاهزة للعرض.
