Odoo 19 · Python · Open sourceOdoo 19 · Python · مفتوح المصدر
● Live, LGPL-3.0حيّ، LGPL-3.0Smart Expense Manager: an approval that takes one click.Smart Expense Manager: موافقة بنقرة واحدة.
A custom Odoo 19 module that replaces the paper expense loop. Approval emails carry a single-use token and route through the hr.employee hierarchy, so nobody has to log in. Finance sign-off generates the journal entry, and a cron job emails a monthly PDF report.وحدة Odoo 19 مخصّصة تحلّ محلّ حلقة النفقات الورقية. رسائل الموافقة تحمل رمزاً يُستخدَم مرة واحدة وتُوجَّه عبر تسلسل hr.employee، فلا يحتاج أحد إلى تسجيل الدخول. واعتماد المالية يولّد القيد المحاسبي، ومهمّة cron ترسل تقرير PDF شهرياً.
- Yearالسنة
- 2026 to now2026 حتى الآن
- Roleالدور
- Designed and wrote it on my ownصمّمتها وكتبتها وحدي
- Stackالتقنيات
- PythonOdoo 19 ORMPostgreSQLQWebOWLXMLBootstrap
§ Overviewنظرة عامة
What it does, and what I owned.ما الذي يفعله، وما الذي تولّيته.
An employee submits a receipt from their phone. A manager approves with one click from email. Finance posts with one click from email. The journal entry is generated automatically, and a cron job mails a monthly department digest. Nobody logs in anywhere along the way.يقدّم الموظّف إيصالاً من جوّاله. ويوافق المدير بنقرة واحدة من البريد. وتُرحّل المالية بنقرة واحدة من البريد. ويُولَّد القيد المحاسبي تلقائياً، وترسل مهمّة cron ملخّصاً شهرياً للقسم. ولا يسجّل أحد دخوله في أي موضع من الطريق.
- Roleالدور
- Designed it and wrote all of itصمّمتها وكتبتها كلها
- Timelineالإطار الزمني
- 2026 to now2026 حتى الآن
- 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, then walks it to finance who types it into a ledger. At every stage somebody is the bottleneck. Receipts get lost. Numbers get re-typed. And 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 person who decides whether the system lives or dies is the manager who never logs in. Each role became a persona with a short story and the friction that kept the old paper loop alive.يعبر التدفّق ثلاثة أدوار، ومن يقرّر حياة النظام أو موته هو المدير الذي لا يسجّل الدخول أبداً. وصار كل دور persona بقصة قصيرة والاحتكاك الذي أبقى الحلقة الورقية القديمة حيّة.
Omar, an employeeعمر، موظّف
Submits the expenseيقدّم النفقة
“I want to photograph the receipt and get reimbursed, not walk a paper form around the building.أريد أن أصوّر الإيصال وأُعوَّض، لا أن أتنقّل بنموذج ورقي في المبنى.”
Goalsالأهداف
Frustrationsالإحباطات
Nour, a line managerنور، مديرة مباشِرة
Approves, and makes or breaks the systemتوافق، وعليها يقوم النظام أو يسقط
“I want to approve in one tap from my inbox. I am not logging into another system just to click yes.أريد أن أوافق بنقرة واحدة من بريدي. ولن أسجّل الدخول إلى نظام آخر فقط لأنقر «نعم».”
Goalsالأهداف
Frustrationsالإحباطات
Farah, in financeفرح، في المالية
Posts to the ledgerتُرحّل إلى دفتر الأستاذ
“I want a clean ledger with real approved liabilities in it, and nothing I have to reverse later.أريد دفتر أستاذ نظيفاً فيه التزامات حقيقية معتمدة، ولا شيء أُضطرّ لعكسه لاحقاً.”
Goalsالأهداف
Frustrationsالإحباطات
§ Design strategyاستراتيجية التصميم
Optimize for the approval that actually happens.حسّن من أجل الموافقة التي تحدث فعلاً.
A module that is technically complete and never used has failed. So 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الفرضية
- Putting the action in email removes the stall that kills adoptionوضع الإجراء في البريد يزيل التعثّر الذي يقتل التبنّي
- Priorityالأولوية
- Less friction ahead of more featuresاحتكاك أقل قبل ميزات أكثر
- Tradeoffالمفاضلة
- Carrying token security to get a login-free flowحمل عبء تأمين الرمز لنيل تدفّق بلا تسجيل دخول
§ Approachالمقاربة
Email is the UI.البريد هو الواجهة.
The module attaches a unique token to an expense request when it goes out to a manager. The approval email carries two links, Approve and Reject, each a one-time URL bound to that token, the request ID and the manager's hr.employee record. Clicking one moves the request to its next state, with no Odoo login anywhere in it.ترفق الوحدة رمزاً فريداً بطلب النفقة عند إرساله إلى المدير. ويحمل بريد الموافقة رابطين، موافقة ورفض، كل واحد عنوان يُستخدَم مرة واحدة مرتبط بذلك الرمز ومعرّف الطلب وسجلّ hr.employee للمدير. والنقر على أحدهما ينقل الطلب إلى حالته التالية، دون أي تسجيل دخول إلى Odoo فيه.
▦ Architectureالبنية · Smart Expense Manager: the 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ثنائي اللغة افتراضياً
Arabic and English, both complete.العربية والإنجليزية، كلتاهما كاملة.
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 SME, that is 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 a manager finishes 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 rather than strategic, so sharing it costs nothing and helps the Odoo community.مخاطر ملكية فكرية منخفضة. الوحدة آليّة أكثر منها استراتيجية، فمشاركتها لا تكلّف شيئاً وتفيد مجتمع Odoo.
§ Validationالتحقّق
The real test is adoption.الاختبار الحقيقي هو التبنّي.
For an internal tool the success metric is not a satisfaction score. It is whether managers actually approve. I would validate with a short usability study on the one-click email path, then read the token logs, which already record every transition, to see where the flow stalls, and prioritize from there.بالنسبة لأداة داخلية، مقياس النجاح ليس درجة رضا. بل ما إذا كان المديرون يوافقون فعلاً. سأتحقّق بدراسة قابلية استخدام قصيرة على مسار البريد بنقرة واحدة، ثم أقرأ سجلّات الرمز، التي تسجّل كل انتقال أصلاً، لأرى أين يتعثّر التدفّق، وأرتّب الأولويات من هناك.
- P0The one-click approve and reject links have to work reliably in the email clients managers actually use. If it breaks once, nobody trusts the link again.على رابطَي الموافقة والرفض بنقرة واحدة أن يعملا بثبات في عملاء البريد التي يستخدمها المديرون فعلاً. وإن تعطّل مرة، لن يثق أحد بالرابط بعدها.
- P1The Arabic and English approval emails must render identically well, since recipients act straight from the inbox.بريدا الموافقة بالعربية والإنجليزية يجب أن يُعرَضا بجودةٍ متطابقة، لأن المستلِمين يتصرّفون مباشرةً من البريد.
- P2A lightweight audit dashboard over 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 would add usage analytics and a lightweight audit dashboard. The token model already logs every transition, so the data that proves adoption is already there waiting to be shown.تالياً سأضيف تحليلات استخدام ولوحة تدقيق خفيفة. نموذج الرمز يسجّل كل انتقال أصلاً، فالبيانات اللازمة لإثبات التبنّي موجودة وجاهزة للعرض.
