في المقال السابق رأينا أن الحاسوب الذي تشتريه بأربعة عشر ألف ريال لا يظهر كله مصروفاً في شهر شرائه، وإنما يظهر منه كل شهر جزء صغير اسمه الإهلاك. وهذه الفكرة البسيطة هي أساس سؤال تسمعه في كل دورة ميزانية: هل هذا الصرف CapEx أم OpEx؟ والسؤال ليس شكلياً، فالإجابة تغير الربح الذي يظهر هذه السنة، ومن يوافق على الصرف، وأي ميزانية يخصم منها، ولهذا قد يرفض المدير المالي شراء سيرفرات بمئتي ألف ريال في شهر ثم يوافق على اشتراك سحابي يكلف أكثر منها في السنة نفسها، ولا يكون في ذلك تناقض كما سوف نرى.
المواضيع في السلسلة:
- المالية للتقنيين: اللغة التي يتحدث بها قسم المالية
- كيف تبني ميزانية التقنية بين CapEx وOpEx؟ (الموضوع الحالي)
- دورة الشراء Procure-to-Pay من الطلب إلى الدفع
- حساب العائد ROI والقيمة الحالية NPV لمشروعك التقني
وسوف نناقش في هذا المقال ما يلي:
- الفرق بين المصروفات الرأسمالية CapEx والمصروفات التشغيلية OpEx، ولماذا تهتم بها الإدارة.
- كيف غيرت السحابة طريقة صرف التقنية.
- متى تصبح التكلفة أصلاً، كما يشرحها المعياران IAS 16 وIAS 38 على مستوى المفهوم، وماذا عن تكلفة إعداد خدمات SaaS.
- الإهلاك والإطفاء وطرقهما، والعمر الإنتاجي والقيمة المتبقية.
- دورة الميزانية السنوية، والتوقع، وتحليل الانحراف.
- كيف تبني ميزانية تقنية المعلومات بنداً بنداً.
- مختبران: جدول إهلاك لأجهزة فريق تقني، وميزانية سنة مقابل الفعلي مع تقرير الانحراف، ونكسر كل واحد منهما.
ما الفرق بين CapEx وOpEx؟
المصروفات الرأسمالية Capital Expenditure، واختصاراً CapEx، هي ما تصرفه لشراء شيء تستفيد منه أكثر من سنة، مثل السيرفرات والأجهزة وبرنامج تطوره الشركة لنفسها، فيسجل أصلاً في قائمة المركز المالي ثم يتحول إلى مصروف تدريجياً على سنوات عمره. والمصروفات التشغيلية Operating Expenditure، واختصاراً OpEx، هي ما تصرفه لتشغيل العمل في الفترة نفسها، مثل الرواتب والاشتراكات وفاتورة السحابة والصيانة، فيظهر مصروفاً في قائمة الدخل في شهره. والصورة التالية تبين الطريقين بأرقام المختبر:

والجدول التالي يجمع الفروق التي تهمك عملياً:
| السؤال | المصروفات الرأسمالية CapEx | المصروفات التشغيلية OpEx |
|---|---|---|
| أين يسجل الصرف أولاً؟ | أصل في قائمة المركز المالي | مصروف في قائمة الدخل |
| متى يؤثر على الربح؟ | على سنوات العمر الإنتاجي بالإهلاك | في الشهر نفسه |
| متى يخرج النقد؟ | غالباً دفعة كبيرة عند الشراء | دفعات منتظمة، شهرية أو سنوية |
| من يوافق؟ | غالباً لجنة أو مستوى إداري أعلى وميزانية رأسمالية منفصلة | صاحب الميزانية التشغيلية حسب صلاحياته |
| أمثلة تقنية | سيرفرات، أجهزة شبكة، حواسيب فوق حد الرسملة، تطوير منتج داخلي يحقق شروط المعيار | رواتب، اشتراكات SaaS، فاتورة السحابة، عقود الدعم، التدريب |
وقد يتساءل البعض: إذا كانت التكلفة نفسها ستظهر في النهاية، فلماذا يهتم أحد بالتصنيف؟ والإجابة أن التوقيت يغير ثلاثة أشياء تراقبها الإدارة:
- ربح هذه السنة: شراء بمئة وثمانين ألفاً يظهر منه 32,400 فقط كل سنة، أما اشتراك بالمبلغ نفسه فيظهر كاملاً في سنته.
- مؤشر EBITDA: وهو الأرباح قبل الفوائد والضرائب والإهلاك والإطفاء Earnings Before Interest, Taxes, Depreciation and Amortization، ويستخدمه كثير من المستثمرين والبنوك لمقارنة الشركات، والإهلاك خارجه، فالشراء الرأسمالي لا ينقصه أبداً بينما ينقصه كل ريال من المصروف التشغيلي.
- النقد: الشراء الرأسمالي يخرج نقده كله في البداية تقريباً، والمصروف التشغيلي يتوزع، ولهذا تفضل الشركة التي ينقصها النقد الاشتراك حتى لو كان أغلى في مجموعه.
ولاحظ أن التصنيف لا يجعل الشيء أرخص أو أغلى، وإنما يغير متى وأين يظهر، فلا تقم بعرض الانتقال إلى السحابة على أنه «توفير» لأنه حول الصرف إلى OpEx، والسبب أن المدير المالي يعرف أن هذا تغيير في شكل الأرقام وليس في حجمها، ويحتاج منك مقارنة التكلفة الكاملة كما سنفعل في مقال دراسة الجدوى.
كيف غيرت السحابة الصورة؟
قبل السحابة كانت أغلب ميزانية البنية التحتية رأسمالية: تشتري السيرفرات والتخزين وأجهزة الشبكة كل ثلاث إلى خمس سنوات، ثم تهلكها. ومع السحابة أصبح أغلب هذا الصرف تشغيلياً يدفع حسب الاستخدام، وهذا غير ثلاثة أشياء في عمل الفرق التقنية:
- من يقرر الصرف: كان شراء سيرفر يحتاج موافقة لجنة، وأصبح المهندس يشغل سيرفراً بأمر واحد، فانتقل قرار الصرف من المالية إلى الفرق، وهذه هي المشكلة التي تحاول FinOps حلها كما شرحنا في مقال FinOps.
- قابلية التوقع: الإهلاك رقم ثابت تعرفه قبل خمس سنوات، أما فاتورة السحابة فتتغير كل شهر مع الحمل، ولهذا أصبح التوقع Forecast الشهري جزءاً من عمل الفريق التقني.
- الالتزامات: خطط التوفير Savings Plans والحجوزات Reservations التزام بالصرف لسنة أو ثلاث مقابل خصم، ورغم أنها تشبه الشراء الرأسمالي في أنها التزام طويل، فإنها تبقى في أغلب الحالات مصروفاً تشغيلياً، وقد يدفع جزء منها مقدماً فيسجل مدفوعاً مقدماً ويوزع على أشهره. وقد شرحنا هذه الخطط وأخطاءها في قسم الالتزامات.
وهذا لا يعني أن السحابة دائماً هي الخيار الأفضل مالياً، فالحمل الثابت الكبير قد يكون أرخص بكثير على سيرفرات تملكها، كما بينا في السحابة ليست دائماً الأرخص والتكاليف الخفية في السحابة، والقرار الصحيح يحتاج حساباً للسنوات كلها وليس للسنة الأولى.
متى تصبح التكلفة أصلاً؟
قرار الرسملة Capitalization، أي تسجيل التكلفة أصلاً بدلاً من مصروف، تحكمه المعايير المحاسبية، وفي المملكة تطبق الشركات المعايير الدولية IFRS المعتمدة من الهيئة السعودية للمراجعين والمحاسبين كما ذكرنا في المقال السابق. ومعياران منها يهمان الفرق التقنية أكثر من غيرهما، ونشرحهما هنا على مستوى المفهوم فقط، فالتفاصيل والحالات الحدية عمل المحاسب.
الأجهزة والسيرفرات: المعيار IAS 16
المعيار IAS 16 للممتلكات والمصانع والمعدات Property, Plant and Equipment يغطي الأصول الملموسة التي تستخدمها الشركة أكثر من فترة واحدة، ويضع شرطين لتسجيل التكلفة أصلاً:
- أن يكون من المرجح أن تحصل الشركة على منافع اقتصادية مستقبلية من هذا الأصل.
- أن تقاس تكلفته بشكل موثوق.
ويقاس الأصل عند شرائه بتكلفته، وهي حسب ملخص المعيار سعر الشراء بعد الخصومات مع الرسوم غير المستردة، والتكاليف المرتبطة مباشرة بتجهيزه للعمل، مثل الشحن والتركيب، والتكلفة التقديرية لفكه وإزالته إذا كانت الشركة ملزمة بها. ولهذا عندما تطلب سيرفرات فأرسل مع الطلب تكلفة الشحن والتركيب والتجهيز منفصلة، والسبب أن المحاسب قد يضيفها إلى تكلفة الأصل بدلاً من تسجيلها مصروفاً.
ولا يحدد المعيار مبلغاً أدنى للرسملة، ولهذا تكتب أغلب الشركات في سياستها المحاسبية حداً للرسملة Capitalization Threshold، فما تحته يسجل مصروفاً مباشرة حتى لو عاش سنوات، مثل الفأرة ولوحة المفاتيح، وما فوقه يسجل أصلاً. والحد يختلف من شركة إلى أخرى، فاسأل المراقب المالي عن الحد في شركتك قبل أن تبني ميزانيتك، لأنه يحدد أي بنود تضعها في الميزانية الرأسمالية.
البرامج والتطوير الداخلي: المعيار IAS 38
المعيار IAS 38 للأصول غير الملموسة Intangible Assets يغطي الأصول التي لا شكل مادي لها، مثل تراخيص البرامج الدائمة والبرامج التي تطورها الشركة لنفسها، وأهم ما فيه للمهندسين ما يلي:
- مرحلة البحث Research: مصروف دائماً، أي استكشاف الأفكار والبدائل قبل أن تثبت إمكانية المنتج.
- مرحلة التطوير Development: تسجل أصلاً فقط إذا حققت شروطاً محددة في المعيار، منها إمكانية إكماله تقنياً وقياس تكلفته بشكل موثوق.
- ما لا يسجل أصلاً أبداً إذا ولد داخلياً: العلامات التجارية وقوائم العملاء التي تبنيها الشركة بنفسها، لأن تكلفتها لا تنفصل عن تكلفة العمل اليومي.
- الإطفاء Amortization: الأصل غير الملموس ذو العمر المحدد يتحول إلى مصروف على عمره، وهو المقابل للإهلاك في الأصول الملموسة، أما ذو العمر غير المحدد فلا يطفأ ويختبر سنوياً للهبوط في قيمته.
وماذا يعني هذا لفريق يطور منتجاً داخلياً؟ يعني أن المالية قد تطلب منك تقسيم ساعات المهندسين حسب المشروع والمرحلة، لأن جزءاً من رواتبهم في مرحلة التطوير قد يرسمل، أما إصلاح الأخطاء والصيانة اليومية فمصروف. وقرار الرسملة نفسه للمراقب المالي والمراجع، ودورك أن تعطيهما بيانات واضحة، مثل سجل ساعات مرتبط بالمشروع والمرحلة، وليس أن تقرر بنفسك.
وماذا عن إعداد خدمات SaaS؟
هذا سؤال يتكرر مع كل نظام سحابي كبير، مثل نظام ERP أو CRM تدفع فيه الشركة اشتراكاً ثم تدفع لشركة استشارات مبلغاً كبيراً لإعداده وتخصيصه، فهل الإعداد أصل؟ وقد أجابت لجنة تفسيرات IFRS عن ذلك في قرار نشر في أبريل 2021، وخلاصته ما يلي:
- عقد SaaS الذي يعطيك حق الوصول إلى برنامج المورد هو في الغالب عقد خدمة، وليس أصلاً برمجياً تملكه.
- تكلفة الإعداد والتخصيص تسجل مصروفاً عندما تتلقى الخدمة، وإذا دفعتها قبل ذلك فهي مدفوعة مقدماً.
- قد ينشأ أصل غير ملموس فقط إذا نتج عن العمل شيء تتحكم فيه أنت، مثل كود إضافي منفصل يحقق شروط IAS 38.
والنتيجة العملية أن مشروع إعداد نظام SaaS كبير يظهر غالباً مصروفاً تشغيلياً في سنته، فإذا بنيت دراسة جدوى على افتراض أنه سيرسمل ويهلك على خمس سنوات فقد تفاجأ بأن ربح السنة الأولى أقل بكثير مما وعدت به الإدارة، ولهذا اسأل المراقب المالي عن المعالجة قبل أن تعرض الأرقام.
الإهلاك: كيف يتحول الأصل إلى مصروف
الإهلاك Depreciation هو توزيع تكلفة الأصل الملموس على سنوات استخدامه، والسبب أن الأصل يخدم الشركة كل هذه السنوات، فمن العدل أن تحمل كل سنة نصيبها منه. ويعتمد الحساب على ثلاثة أرقام:
- التكلفة Cost: ما دفعته لشراء الأصل وتجهيزه، كما رأينا.
- العمر الإنتاجي Useful Life: المدة التي تتوقع الشركة أن تستخدم فيها الأصل، وليس عمر الجهاز التقني الممكن، فالحاسوب قد يعمل سبع سنوات ولكن الشركة تجدده كل ثلاث، فعمره الإنتاجي عندها ثلاث سنوات.
- القيمة المتبقية Residual Value: ما تتوقع أن تحصل عليه من بيعه في نهاية عمره، وهي صفر غالباً للحواسيب، وقد تكون أعلى لبعض المعدات.
والقيمة الدفترية Net Book Value، واختصاراً NBV، هي التكلفة ناقص الإهلاك المتراكم حتى الآن، وهي قيمة الأصل في قائمة المركز المالي، ولا علاقة لها بسعره في السوق. ويذكر IAS 16 أكثر من طريقة للإهلاك، والصورة التالية تبين الطريقتين الأشهر على السيرفرين في مختبرنا:

| الطريقة | كيف تحسب | متى تناسب |
|---|---|---|
| القسط الثابت Straight-line | (التكلفة ناقص القيمة المتبقية) مقسومة على العمر، المبلغ نفسه كل سنة | أغلب الأجهزة التقنية، وهي الأكثر استخداماً لبساطتها |
| القسط المتناقص Diminishing Balance | نسبة ثابتة من القيمة الدفترية المتبقية، فيكبر الإهلاك في البداية ويصغر بعدها | أصل يفقد أغلب منفعته في أول سنواته |
| الوحدات المنتجة Units of Production | حسب الاستخدام الفعلي، مثل ساعات التشغيل أو عدد الصفحات | معدات يختلف استخدامها كثيراً من سنة إلى أخرى |
وتختار الشركة الطريقة التي تعكس طريقة استهلاك منفعة الأصل، ثم تطبقها باستمرار، ويمنع المعيار منذ تعديل 2014 الطرق المبنية على الإيراد كما يذكر ملخص IAS 16. وبعد ذلك تأتي حالتان يجب أن تعرفهما:
- الهبوط في القيمة Impairment: إذا فقد الأصل جزءاً كبيراً من قيمته فجأة، مثل سيرفرات توقف استخدامها بعد الانتقال إلى السحابة قبل نهاية عمرها، فقد تخفض قيمتها الدفترية دفعة واحدة، فيظهر مصروف كبير غير متوقع في قائمة الدخل، ولهذا أخبر المالية مبكراً بأي خطة لإيقاف أجهزة قبل نهاية عمرها.
- الاستبعاد Disposal: عند بيع الأصل أو إتلافه يخرج من الدفاتر، والفرق بين ما حصلت عليه وقيمته الدفترية ربح أو خسارة، وهذه هي الخطوة المالية المقابلة للإتلاف الذي شرحناه في دورة حياة أجهزة المؤسسة.
مختبر: جدول إهلاك لأجهزة فريق تقني
نستخدم ال Image نفسها التي بنيناها في مختبر المقال السابق، وهي Python 3.13.16 مع DuckDB 1.5.6. ولدينا ثلاث مجموعات من الأصول اشتريت في 2026، وكل أرقامها مصطنعة: عشرون حاسوباً بستة آلاف ريال لكل منها وعمرها ثلاث سنوات، وسيرفران بتسعين ألفاً لكل منهما وعمرهما خمس سنوات وقيمة متبقية 10%، وسويتش رئيسي Core Switch بأربعة وعشرين ألفاً وعمره خمس سنوات. والسياسة في مثالنا أن يبدأ الإهلاك من الشهر الذي يبدأ فيه استخدام الأصل:
"""Depreciation schedule for an IT team's assets (illustrative SAR amounts, invented for the exercise).
python depreciation.py straight-line, monthly, from the month the asset is put into use
python depreciation.py nocap break it: the spreadsheet formula that never stops depreciating
"""
import sys
import duckdb
BREAK = sys.argv[1] if len(sys.argv) > 1 else ""
con = duckdb.connect()
con.execute("""CREATE TABLE assets(tag TEXT, item TEXT, qty INT, unit_cost DECIMAL(12,2), residual_pct DECIMAL(5,2),
life_months INT, in_use DATE)""")
con.executemany("INSERT INTO assets VALUES (?, ?, ?, ?, ?, ?, ?)", [
("LAP-2026", "Laptops", 20, 6000, 0, 36, "2026-01-01"),
("SRV-2026", "Rack servers", 2, 90000, 10, 60, "2026-04-01"),
("NET-2026", "Core switch", 1, 24000, 0, 60, "2026-07-01"),
])
# One row per asset per month for 7 years. Monthly charge = (cost - residual) / useful life in months.
months_used = "date_diff('month', a.in_use, m.month) + 1"
charge = "(a.qty * a.unit_cost * (1 - a.residual_pct / 100)) / a.life_months"
if BREAK == "nocap": # the bug: no check that the asset is still inside its useful life
rule = f"CASE WHEN m.month >= a.in_use THEN {charge} ELSE 0 END"
else:
rule = f"CASE WHEN m.month >= a.in_use AND {months_used} <= a.life_months THEN {charge} ELSE 0 END"
con.execute(f"""CREATE TABLE schedule AS
SELECT a.tag, a.item, m.month, a.qty * a.unit_cost AS cost, round({rule}, 2) AS depreciation
FROM assets a, (SELECT unnest(generate_series(DATE '2026-01-01', DATE '2032-12-01', INTERVAL 1 MONTH))::DATE AS month) m""")
def show(title, sql):
rows = con.execute(sql).fetchall(); cols = [c[0] for c in con.description]
num = lambda v: type(v).__name__ in ("Decimal", "float")
cells = [[f"{v:,.2f}" if num(v) else str(v) for v in r] for r in rows]
w = [max([len(c)] + [len(r[i]) for r in cells]) for i, c in enumerate(cols)]
print(f"\n== {title}"); print(" ".join(c.ljust(x) for c, x in zip(cols, w)))
for r, raw in zip(cells, rows):
print(" ".join(s.rjust(x) if num(v) else s.ljust(x) for s, v, x in zip(r, raw, w)))
if not rows: print("(no rows)")
show("Monthly charge per asset group", f"""SELECT tag, item, qty * unit_cost AS cost, qty * unit_cost * residual_pct / 100 AS residual,
life_months, in_use, round({charge.replace('a.', '')}, 2) AS per_month FROM assets ORDER BY in_use""")
show("Depreciation expense per year (goes to the P&L)", """
PIVOT (SELECT tag, year(month) AS yr, depreciation FROM schedule) ON yr USING sum(depreciation) ORDER BY tag""")
show("Net book value at year end (cost - accumulated depreciation, stays on the balance sheet)", """
WITH acc AS (SELECT tag, month, cost, sum(depreciation) OVER (PARTITION BY tag ORDER BY month) AS accumulated FROM schedule)
PIVOT (SELECT tag, year(month) AS yr, cost - accumulated AS nbv FROM acc WHERE month(month) = 12) ON yr USING sum(nbv) ORDER BY tag""")
show("Check: assets depreciated below their residual value", """
WITH acc AS (SELECT s.tag, s.month, s.cost, sum(s.depreciation) OVER (PARTITION BY s.tag ORDER BY s.month) AS accumulated FROM schedule s)
SELECT acc.tag, min(acc.month) AS first_month_below, round(min(acc.cost - acc.accumulated), 2) AS lowest_nbv,
any_value(a.qty * a.unit_cost * a.residual_pct / 100) AS residual
FROM acc JOIN assets a USING (tag) WHERE acc.cost - acc.accumulated < a.qty * a.unit_cost * a.residual_pct / 100 - 0.01
GROUP BY acc.tag ORDER BY acc.tag""")
# Straight-line vs diminishing balance for the servers (annual view, residual 18,000, 5 years)
show("Servers: straight-line vs diminishing balance (40% a year, then switch to straight-line)", """
WITH RECURSIVE db(yr, opening, dep) AS (
SELECT 1, 180000.0, 180000.0 * 0.40
UNION ALL
SELECT yr + 1, opening - dep,
CASE WHEN yr + 1 = 5 THEN (opening - dep) - 18000 -- last year: down to the residual
ELSE greatest((opening - dep) * 0.40, ((opening - dep) - 18000) / (5 - yr)) END
FROM db WHERE yr < 5)
SELECT yr AS year_of_use, round((180000 - 18000) / 5.0, 2) AS straight_line, round(dep, 2) AS diminishing_balance,
round(opening - dep, 2) AS db_book_value_end FROM db ORDER BY yr""")docker run --name lab-fin2-dep -v "$PWD:/w" lab-fin2-duckdb:1 python depreciation.pyوالمخرج سوف يكون كما يلي:
== Monthly charge per asset group
tag item cost residual life_months in_use per_month
LAP-2026 Laptops 120,000.00 0.00 36 2026-01-01 3,333.33
SRV-2026 Rack servers 180,000.00 18,000.00 60 2026-04-01 2,700.00
NET-2026 Core switch 24,000.00 0.00 60 2026-07-01 400.00
== Depreciation expense per year (goes to the P&L)
tag 2026 2027 2028 2029 2030 2031 2032
LAP-2026 39,999.96 39,999.96 39,999.96 0.00 0.00 0.00 0.00
NET-2026 2,400.00 4,800.00 4,800.00 4,800.00 4,800.00 2,400.00 0.00
SRV-2026 24,300.00 32,400.00 32,400.00 32,400.00 32,400.00 8,100.00 0.00
== Net book value at year end (cost - accumulated depreciation, stays on the balance sheet)
tag 2026 2027 2028 2029 2030 2031 2032
LAP-2026 80,000.04 40,000.08 0.12 0.12 0.12 0.12 0.12
NET-2026 21,600.00 16,800.00 12,000.00 7,200.00 2,400.00 0.00 0.00
SRV-2026 155,700.00 123,300.00 90,900.00 58,500.00 26,100.00 18,000.00 18,000.00
== Check: assets depreciated below their residual value
tag first_month_below lowest_nbv residual
(no rows)
== Servers: straight-line vs diminishing balance (40% a year, then switch to straight-line)
year_of_use straight_line diminishing_balance db_book_value_end
1 32,400.00 72,000.00 108,000.00
2 32,400.00 43,200.00 64,800.00
3 32,400.00 25,920.00 38,880.00
4 32,400.00 15,552.00 23,328.00
5 32,400.00 5,328.00 18,000.00في المخرج أعلاه لاحظ التالي:
- السيرفران بدأ استخدامهما في أبريل، فمصروف 2026 منهما تسعة أشهر فقط: 24,300 ريال، والأشهر الثلاثة الباقية تظهر في 2031، وكذلك السويتش الذي بدأ في يوليو.
- الحواسيب تكلف قائمة الدخل نحو 40,000 ريال كل سنة لثلاث سنوات، بينما خرج نقدها كله، أي 120,000 ريال، في يناير 2026.
- القيمة الدفترية للحواسيب في نهاية 2028 هي 0.12 ريال وليست صفراً، والسبب أن 120,000 مقسومة على 36 شهراً تعطي 3,333.33 بعد التقريب، فيبقى من كل شهر ثلث هللة. وهذا خطأ حقيقي يظهر في كل جدول إهلاك يقرب كل شهر، والأنظمة المحاسبية تحله بتحميل الفرق على الشهر الأخير، وقد تركناه ظاهراً هنا عمداً حتى تراه.
- في المقارنة الأخيرة يهلك القسط المتناقص 72,000 ريال من السيرفرين في السنة الأولى مقابل 32,400 للقسط الثابت، ثم ينتهي الاثنان عند القيمة المتبقية نفسها 18,000.
نكسر الجدول: الإهلاك الذي لا يتوقف
أكثر خطأ نراه في جداول الإهلاك المكتوبة في جداول البيانات Spreadsheets هو المعادلة التي تضرب القسط الشهري في عدد الأشهر منذ الشراء، دون أن تتوقف عند نهاية العمر الإنتاجي. والوضع nocap في السكربت يطبق هذه المعادلة نفسها:
docker run --name lab-fin2-dep-nocap -v "$PWD:/w" lab-fin2-duckdb:1 python depreciation.py nocapوالمخرج طويل، لذلك ننقل منه الجداول الثلاثة التي تغيرت كما ظهرت:
== Depreciation expense per year (goes to the P&L)
tag 2026 2027 2028 2029 2030 2031 2032
LAP-2026 39,999.96 39,999.96 39,999.96 39,999.96 39,999.96 39,999.96 39,999.96
NET-2026 2,400.00 4,800.00 4,800.00 4,800.00 4,800.00 4,800.00 4,800.00
SRV-2026 24,300.00 32,400.00 32,400.00 32,400.00 32,400.00 32,400.00 32,400.00
== Net book value at year end (cost - accumulated depreciation, stays on the balance sheet)
tag 2026 2027 2028 2029 2030 2031 2032
LAP-2026 80,000.04 40,000.08 0.12 -39,999.84 -79,999.80 -119,999.76 -159,999.72
NET-2026 21,600.00 16,800.00 12,000.00 7,200.00 2,400.00 -2,400.00 -7,200.00
SRV-2026 155,700.00 123,300.00 90,900.00 58,500.00 26,100.00 -6,300.00 -38,700.00
== Check: assets depreciated below their residual value
tag first_month_below lowest_nbv residual
LAP-2026 2029-01-01 -159,999.72 0.00
NET-2026 2031-07-01 -7,200.00 0.00
SRV-2026 2031-04-01 -38,700.00 18,000.00الحواسيب تستمر في تحميل قائمة الدخل 40,000 ريال كل سنة بعد 2028، وقيمتها الدفترية تصبح سالبة، أي أن الشركة «تملك» حواسيب بقيمة سالب 160,000 ريال في 2032، وهذا مستحيل. والسيرفران ينزلان تحت قيمتهما المتبقية في أبريل 2031. والفحص الذي أضفناه في السكربت يكتشف الحالات الثلاث مع أول شهر حدث فيه الخطأ، ولهذا ضع في أي جدول إهلاك فحصاً بسيطاً واحداً: القيمة الدفترية لا تنزل أبداً تحت القيمة المتبقية.
دورة الميزانية السنوية
الميزانية Budget هي خطة الصرف والإيراد المعتمدة للسنة القادمة، وتمر في أغلب الشركات بدورة ثابتة تبدأ قبل السنة بأشهر، والصورة التالية تبين مثالاً لشركة سنتها المالية هي السنة الميلادية:

وفي هذه الدورة مصطلحات يجب أن تفرق بينها، لأن الخلط بينها يجعل تقريرك الشهري غير مفهوم للمالية:
| المصطلح | المعنى |
|---|---|
| الميزانية Budget | الخطة المعتمدة في بداية السنة، ولا تتغير عادة خلالها |
| الفعلي Actual | ما صرف فعلاً حسب الدفاتر |
| التوقع Forecast | أفضل تقدير اليوم لما سيكون عليه الصرف في نهاية السنة، ويتحدث كل شهر أو ربع سنة |
| التوقع المتجدد Rolling Forecast | توقع يغطي دائماً الاثني عشر شهراً القادمة، بدلاً من نهاية السنة المالية فقط |
| التوزيع الشهري Phasing | توزيع الميزانية السنوية على الأشهر حسب موعد الصرف المتوقع |
| من بداية السنة Year to Date | المجموع من أول السنة حتى الشهر الحالي، واختصاراً YTD |
| معدل التشغيل Run-rate | آخر شهر مضروباً في عدد الأشهر، وهو طريقة سريعة للتوقع لها حدودها كما سنرى |
| الانحراف Variance | الفرق بين الميزانية والفعلي، فإذا صرفت أقل فهو انحراف إيجابي Favourable، وإذا صرفت أكثر فهو سلبي Unfavourable |
وتحليل الانحراف Variance Analysis هو أن تشرح كل انحراف كبير بسببه، وليس أن ترسل الجدول فقط، والمالية لا تريد منك أن تكون الأرقام مطابقة للميزانية، فهذا لا يحدث أبداً، وإنما تريد أن تعرف السبب قبل أن يسألك عنه أحد، وهل هو مؤقت أم سيستمر، فالحاسوب الذي تأخر شراؤه شهرين انحراف في التوقيت يختفي وحده، أما فاتورة السحابة التي تزيد كل شهر فانحراف يكبر حتى نهاية السنة.
كيف تبني ميزانية تقنية المعلومات؟
ابدأ من البنود وليس من رقم السنة الماضية مع زيادة نسبة، والسبب أن ميزانية السنة الماضية فيها أخطاؤها ومشاريعها التي انتهت. والجدول التالي يبين البنود المعتادة لقسم تقنية، وطريقة تقدير كل منها، وأين يخطئ الناس فيه:
| البند | النوع غالباً | كيف تقدره | الخطأ الشائع |
|---|---|---|---|
| الموظفون People | OpEx | التكلفة الكاملة لكل وظيفة، أي الراتب والبدلات والتأمينات والتأمين الطبي، مع شهر بدء كل وظيفة جديدة | حساب الراتب الأساسي فقط، أو حساب الوظيفة الجديدة من يناير وهي تبدأ في يونيو |
| التراخيص والاشتراكات Licences and SaaS | OpEx | قائمة بكل اشتراك وعدد المستخدمين وتاريخ التجديد وزيادة السعر المتوقعة | نسيان النمو في عدد المستخدمين وزيادات الأسعار عند التجديد، وتسعير الاشتراكات بالدولار دون حساب ضريبة القيمة المضافة غير القابلة للاسترداد إن وجدت |
| السحابة Cloud | OpEx | الاستخدام الحالي مع النمو المتوقع لكل خدمة، والالتزامات التي ستشتريها | نسخ فاتورة آخر شهر مضروبة في اثني عشر، دون حساب النمو |
| تجديد الأجهزة Hardware Refresh | CapEx | من سجل الأجهزة: ما ينتهي عمره هذه السنة وما يحتاجه الموظفون الجدد | الاعتماد على الذاكرة بدلاً من سجل الأصول، وقد شرحنا التقرير المطلوب في قسم التجديد |
| عقود الدعم والصيانة Support Contracts | OpEx | العقود الحالية وتواريخ تجديدها، والأجهزة التي تخرج من الضمان | نسيان أن الجهاز الخارج من الضمان يحتاج عقد دعم جديداً |
| الاتصالات Telecom | OpEx | خطوط الإنترنت والهواتف والروابط بين الفروع | بند صغير يترك دون مراجعة لسنوات |
| التدريب والشهادات Training | OpEx | خطة لكل موظف أو مبلغ لكل شخص | أول بند يقص عند أي ضغط، ثم تصبح الفرق بلا تطوير |
| المشاريع Projects | CapEx أو OpEx | كل مشروع ببنوده، مفصولاً عن التشغيل الجاري | خلط المشروع بالتشغيل، فلا تعرف كم كلف المشروع فعلاً |
| الاحتياطي Contingency | OpEx | نسبة صغيرة تتفق عليها مع المالية للأمور غير المتوقعة | إخفاء الاحتياطي داخل كل بند، فتنتفخ البنود كلها ولا يثق أحد بالأرقام |
وبعد البنود تأتي خطوتان يغفل عنهما أغلب من يبني ميزانيته أول مرة:
- التوزيع على الأشهر حسب الاستحقاق: الميزانية التشغيلية تقارن عادة بقائمة الدخل، أي بأساس الاستحقاق، فالترخيص السنوي يوزع على أشهره، أما ميزانية النقد Cash Budget فتضع الدفعة في شهر دفعها، ويحتاجها قسم الخزينة. ولا تخلط بينهما، كما سوف نرى في المختبر.
- توزيع التكلفة على أصحابها: إذا كانت تقنية المعلومات تخدم كل الشركة، فاتفق مع المالية على طريقة توزيع تكلفتها على الأقسام والمنتجات، مثل عدد المستخدمين أو الاستخدام الفعلي، وهي فكرة التوزيع Allocation وعرض التكلفة Showback نفسها التي شرحناها في مقال FinOps، وأدواتها في أدوات FinOps.
مختبر: الميزانية مقابل الفعلي وتقرير الانحراف
الآن لدينا ميزانية تشغيلية مصطنعة لقسم تقنية في 2026، فيها سبعة بنود موزعة بالتساوي على الأشهر، وأرقام فعلية من يناير إلى سبتمبر، والسكربت يخرج أربعة تقارير: الانحراف من بداية السنة مع علامة على كل انحراف يحتاج تفسيراً، والمجموع، ومقارنة شهرية لبندين، والتوقع لنهاية السنة. والقاعدة في مثالنا أن الانحراف يحتاج تفسيراً إذا تجاوز 10% و5,000 ريال معاً:
"""IT operating budget for 2026 against actuals for January to September (illustrative SAR amounts, invented).
python budget.py budget and actuals on the same (accrual) basis
python budget.py cash break it: actuals taken from bank payments (cash) against an accrual budget
"""
import sys
import duckdb
BASIS = "cash" if len(sys.argv) > 1 and sys.argv[1] == "cash" else "accrual"
con = duckdb.connect()
# Annual budget per line, phased evenly over 12 months (the budget is on the P&L, i.e. accrual, basis)
BUDGET = {"People": 2160000, "Licences & SaaS": 480000, "Cloud": 600000, "Support contracts": 120000,
"Telecom": 96000, "Training": 60000}
BUDGET["Contingency (5%)"] = round(sum(BUDGET.values()) * 0.05)
M = range(1, 10) # actuals exist for January to September
accrual = {
"People": [180000] * 5 + [195000] * 4, # one hire from June
"Licences & SaaS": [40000] * 4 + [43000] * 5, # a new tool from May
"Cloud": [45000, 46500, 48000, 50000, 52000, 55000, 58000, 61000, 64000],
"Support contracts": [10000] * 9,
"Telecom": [7600] * 9,
"Training": [0, 0, 0, 12000, 0, 0, 0, 0, 15000],
"Contingency (5%)": [0] * 9,
}
cash = dict(accrual)
cash["Licences & SaaS"] = [240000 + 10000, 10000, 120000 + 10000, 10000] + [13000] * 5 # two annual renewals paid up front
cash["Support contracts"] = [0, 120000] + [0] * 7 # the annual support contract is paid in February
cash["Cloud"] = [44000] + accrual["Cloud"][:-1] # each bill is paid the month after
actuals = accrual if BASIS == "accrual" else cash
con.execute("CREATE TABLE budget(line TEXT, month INT, amount DECIMAL(12,2))")
con.execute("CREATE TABLE actual(line TEXT, month INT, amount DECIMAL(12,2))")
for line, annual in BUDGET.items():
con.executemany("INSERT INTO budget VALUES (?, ?, ?)", [(line, m, annual / 12) for m in range(1, 13)])
for line, values in actuals.items():
con.executemany("INSERT INTO actual VALUES (?, ?, ?)", [(line, m, v) for m, v in zip(M, values)])
def show(title, sql):
rows = con.execute(sql).fetchall(); cols = [c[0] for c in con.description]
num = lambda v: type(v).__name__ in ("Decimal", "float")
cells = [[f"{v:,.2f}" if num(v) else str(v) for v in r] for r in rows]
w = [max([len(c)] + [len(r[i]) for r in cells]) for i, c in enumerate(cols)]
print(f"\n== {title}"); print(" ".join(c.ljust(x) for c, x in zip(cols, w)))
for r, raw in zip(cells, rows):
print(" ".join(s.rjust(x) if num(v) else s.ljust(x) for s, v, x in zip(r, raw, w)))
if not rows: print("(no rows)")
print(f"Actuals basis: {BASIS}")
# Variance = budget - actual: positive is favourable (spent less), negative is unfavourable (spent more)
show("Year to date, January to September 2026", """
SELECT b.line, sum(b.amount) AS budget_ytd, coalesce(any_value(a.ytd), 0) AS actual_ytd,
sum(b.amount) - coalesce(any_value(a.ytd), 0) AS variance,
round(100 * (sum(b.amount) - coalesce(any_value(a.ytd), 0)) / sum(b.amount), 1) AS variance_pct,
CASE WHEN abs(sum(b.amount) - coalesce(any_value(a.ytd), 0)) > 5000
AND abs(sum(b.amount) - coalesce(any_value(a.ytd), 0)) > 0.10 * sum(b.amount)
THEN CASE WHEN sum(b.amount) < coalesce(any_value(a.ytd), 0) THEN 'EXPLAIN: over' ELSE 'EXPLAIN: under' END
ELSE '' END AS flag
FROM budget b LEFT JOIN (SELECT line, sum(amount) ytd FROM actual GROUP BY line) a USING (line)
WHERE b.month <= 9 GROUP BY b.line ORDER BY budget_ytd DESC""")
show("Total, year to date", """
SELECT (SELECT sum(amount) FROM budget WHERE month <= 9) AS budget_ytd, (SELECT sum(amount) FROM actual) AS actual_ytd,
(SELECT sum(amount) FROM budget WHERE month <= 9) - (SELECT sum(amount) FROM actual) AS variance""")
show("Month by month: Licences & SaaS and Cloud", """
SELECT b.month, max(CASE WHEN b.line = 'Licences & SaaS' THEN b.amount END) AS lic_budget,
max(CASE WHEN b.line = 'Licences & SaaS' THEN a.amount END) AS lic_actual,
max(CASE WHEN b.line = 'Cloud' THEN b.amount END) AS cloud_budget,
max(CASE WHEN b.line = 'Cloud' THEN a.amount END) AS cloud_actual
FROM budget b LEFT JOIN actual a USING (line, month) WHERE b.month <= 9 GROUP BY b.month ORDER BY b.month""")
# Full-year forecast: actuals so far + September's run-rate for October to December
show("Full-year forecast (actual Jan-Sep + September run-rate x 3) vs annual budget", """
SELECT b.line, sum(b.amount) AS annual_budget,
any_value(a.ytd) + 3 * any_value(a.sep) AS forecast,
sum(b.amount) - (any_value(a.ytd) + 3 * any_value(a.sep)) AS variance
FROM budget b JOIN (SELECT line, sum(amount) ytd, sum(amount) FILTER (WHERE month = 9) sep FROM actual GROUP BY line) a USING (line)
GROUP BY b.line ORDER BY annual_budget DESC""")docker run --name lab-fin2-budget -v "$PWD:/w" lab-fin2-duckdb:1 python budget.pyوالمخرج سوف يكون كما يلي:
Actuals basis: accrual
== Year to date, January to September 2026
line budget_ytd actual_ytd variance variance_pct flag
People 1,620,000.00 1,680,000.00 -60,000.00 -3.70
Cloud 450,000.00 479,500.00 -29,500.00 -6.60
Licences & SaaS 360,000.00 375,000.00 -15,000.00 -4.20
Contingency (5%) 131,850.00 0.00 131,850.00 100.00 EXPLAIN: under
Support contracts 90,000.00 90,000.00 0.00 0.00
Telecom 72,000.00 68,400.00 3,600.00 5.00
Training 45,000.00 27,000.00 18,000.00 40.00 EXPLAIN: under
== Total, year to date
budget_ytd actual_ytd variance
2,768,850.00 2,719,900.00 48,950.00
== Month by month: Licences & SaaS and Cloud
month lic_budget lic_actual cloud_budget cloud_actual
1 40,000.00 40,000.00 50,000.00 45,000.00
2 40,000.00 40,000.00 50,000.00 46,500.00
3 40,000.00 40,000.00 50,000.00 48,000.00
4 40,000.00 40,000.00 50,000.00 50,000.00
5 40,000.00 43,000.00 50,000.00 52,000.00
6 40,000.00 43,000.00 50,000.00 55,000.00
7 40,000.00 43,000.00 50,000.00 58,000.00
8 40,000.00 43,000.00 50,000.00 61,000.00
9 40,000.00 43,000.00 50,000.00 64,000.00
== Full-year forecast (actual Jan-Sep + September run-rate x 3) vs annual budget
line annual_budget forecast variance
People 2,160,000.00 2,265,000.00 -105,000.00
Cloud 600,000.00 671,500.00 -71,500.00
Licences & SaaS 480,000.00 504,000.00 -24,000.00
Contingency (5%) 175,800.00 0.00 175,800.00
Support contracts 120,000.00 120,000.00 0.00
Telecom 96,000.00 91,200.00 4,800.00
Training 60,000.00 72,000.00 -12,000.00في المخرج أعلاه لاحظ التالي:
- القسم كله تحت الميزانية بنحو 49,000 ريال، ولكن هذا الرقم يخدعك، لأن الاحتياطي غير المستخدم 131,850 ريال يغطي زيادة حقيقية في ثلاثة بنود.
- السحابة فوق الميزانية بنسبة 6.6% فقط من بداية السنة، فلم تصل إلى حد التفسير، ولكن الجدول الشهري يبين أنها تزيد كل شهر من 45,000 إلى 64,000، والتوقع لنهاية السنة يبين تجاوزاً بـ 71,500 ريال. وهذا هو الانحراف الأخطر في التقرير كله، رغم أن القاعدة لم تضع عليه علامة، ولهذا لا تكتف بالحد الثابت، وانظر إلى الاتجاه Trend أيضاً.
- الموظفون فوق الميزانية بستين ألفاً بسبب وظيفة بدأت في يونيو ولم تكن في الميزانية، وتوقع نهاية السنة يجعلها 105,000 ريال، وهذا انحراف تعرف سببه ويجب أن تكتبه في التقرير قبل أن يسألك عنه أحد.
- التدريب تحت الميزانية بنسبة 40% في بداية السنة، ولكن التوقع بمعدل التشغيل يقول إنه سيتجاوزها، لأن سبتمبر وحده كان فيه 15,000 ريال لدورة واحدة، فضرب الشهر في ثلاثة يفترض دورة كل شهر. وهذا حد معروف لطريقة Run-rate، فهي تصلح للبنود المنتظمة مثل السحابة والرواتب، ولا تصلح للبنود المتقطعة مثل التدريب والمشاريع.
نكسر التقرير: الفعلي من كشف البنك
الآن نفترض أن أحداً أخذ الأرقام الفعلية من كشف البنك بدلاً من الدفاتر، وهذا ما يحدث كثيراً عندما يبني مدير التقنية تقريره بنفسه من المدفوعات، فيقارن دفعات النقد بميزانية مبنية على الاستحقاق:
docker run --name lab-fin2-budget-cash -v "$PWD:/w" lab-fin2-duckdb:1 python budget.py cashوالمخرج سوف يكون كما يلي:
Actuals basis: cash
== Year to date, January to September 2026
line budget_ytd actual_ytd variance variance_pct flag
People 1,620,000.00 1,680,000.00 -60,000.00 -3.70
Cloud 450,000.00 459,500.00 -9,500.00 -2.10
Licences & SaaS 360,000.00 465,000.00 -105,000.00 -29.20 EXPLAIN: over
Contingency (5%) 131,850.00 0.00 131,850.00 100.00 EXPLAIN: under
Support contracts 90,000.00 120,000.00 -30,000.00 -33.30 EXPLAIN: over
Telecom 72,000.00 68,400.00 3,600.00 5.00
Training 45,000.00 27,000.00 18,000.00 40.00 EXPLAIN: under
== Total, year to date
budget_ytd actual_ytd variance
2,768,850.00 2,819,900.00 -51,050.00
== Month by month: Licences & SaaS and Cloud
month lic_budget lic_actual cloud_budget cloud_actual
1 40,000.00 250,000.00 50,000.00 44,000.00
2 40,000.00 10,000.00 50,000.00 45,000.00
3 40,000.00 130,000.00 50,000.00 46,500.00
4 40,000.00 10,000.00 50,000.00 48,000.00
5 40,000.00 13,000.00 50,000.00 50,000.00
6 40,000.00 13,000.00 50,000.00 52,000.00
7 40,000.00 13,000.00 50,000.00 55,000.00
8 40,000.00 13,000.00 50,000.00 58,000.00
9 40,000.00 13,000.00 50,000.00 61,000.00
== Full-year forecast (actual Jan-Sep + September run-rate x 3) vs annual budget
line annual_budget forecast variance
People 2,160,000.00 2,265,000.00 -105,000.00
Cloud 600,000.00 642,500.00 -42,500.00
Licences & SaaS 480,000.00 504,000.00 -24,000.00
Contingency (5%) 175,800.00 0.00 175,800.00
Support contracts 120,000.00 120,000.00 0.00
Telecom 96,000.00 91,200.00 4,800.00
Training 60,000.00 72,000.00 -12,000.00التقرير الآن يقول إن التراخيص فوق الميزانية بـ 105,000 ريال، وعقود الدعم فوقها بـ 30,000، ويضع على الاثنين علامة التفسير، والقسم كله فوق الميزانية بـ 51,000 ريال، بينما الحقيقة أن التراخيص فوقها بـ 15,000 فقط، والدعم مطابق تماماً. والسبب أن تجديدين سنويين دفعا في يناير ومارس، وعقد الدعم السنوي دفع في فبراير، فظهرت دفعات سنة كاملة في أشهر قليلة. وفي الاتجاه الآخر تبدو السحابة أفضل مما هي، لأن كل فاتورة تدفع في الشهر التالي، فيبقى شهر سبتمبر خارج الحساب.
والقاعدة هنا أن تقارن الشيء بمثله: الميزانية التشغيلية بالفعلي من الدفاتر، وميزانية النقد بالمدفوعات. وإذا أعطتك المالية الأرقام الفعلية من نظامها فاسأل عن أساسها قبل أن تكتب أي تفسير.
حذف المختبر
docker rm lab-fin2-dep lab-fin2-dep-nocap lab-fin2-budget lab-fin2-budget-cashواترك ال Image lab-fin2-duckdb:1 إذا كنت ستكمل السلسلة.
أخطاء شائعة
وفيما يلي أخطاء نراها كثيراً في ميزانيات التقنية، ومع كل خطأ سببه:
- عرض السحابة على أنها توفير لأنها OpEx: التصنيف يغير التوقيت وليس الحجم، والمالية تعرف ذلك.
- الضغط لرسملة ما هو تشغيلي: يجمل ميزانيتك هذه السنة ثم تكتشفه المراجعة، ويجعل أرقام السنوات القادمة تحمل إهلاكاً لا مقابل له.
- افتراض أن إعداد نظام SaaS أصل: المعالجة الغالبة أنه مصروف في سنته، فاسأل قبل أن تبني عليه دراسة الجدوى.
- الإهلاك بعمر تقني وليس بعمر الاستخدام: إذا كانت الشركة تجدد الحواسيب كل ثلاث سنوات فعمرها ثلاث، حتى لو كانت تعمل سبعاً.
- توزيع الميزانية بالتساوي دون التفكير في التوقيت: وظيفة تبدأ في يونيو أو مشروع في الربع الثالث يجب أن يظهر في أشهره.
- الاعتماد على حد الانحراف وحده: كما رأينا مع السحابة، البند الذي يزيد كل شهر قد لا يصل إلى الحد إلا بعد فوات الوقت.
- مقارنة النقد بالاستحقاق: تنتج انحرافات وهمية في أشهر التجديد، وتخفي الانحرافات الحقيقية في البنود التي تدفع متأخرة.
تدريب عملي
- أضف إلى
depreciation.pyتصحيح التقريب، بحيث يحمل الشهر الأخير من عمر كل أصل الفرق المتبقي، ثم تأكد أن القيمة الدفترية للحواسيب تصبح صفراً تماماً. - غير توقع نهاية السنة في
budget.pyليستخدم متوسط آخر ثلاثة أشهر بدلاً من سبتمبر وحده، وقارن نتيجة التدريب والسحابة بين الطريقتين. - غير توزيع ميزانية الموظفين بحيث تبدأ الوظيفة الجديدة في يونيو، ولاحظ كيف يختفي الانحراف الذي كان يحتاج تفسيراً.
الخلاصة
وصلنا لنهاية الموضوع، وأهم ما فيه:
- CapEx يسجل أصلاً ويصل إلى قائمة الدخل على سنوات بالإهلاك، وOpEx يصل إليها في شهره، والتصنيف يغير التوقيت ومؤشرات مثل EBITDA ولا يغير حجم الصرف.
- السحابة نقلت أغلب صرف البنية التحتية إلى OpEx، ونقلت معه قرار الصرف إلى الفرق التقنية.
- الرسملة تحكمها المعايير: IAS 16 للأجهزة، وIAS 38 للبرامج والتطوير، وإعداد خدمات SaaS يكون غالباً مصروفاً، والقرار للمراقب المالي والمراجع.
- الإهلاك يحتاج التكلفة والعمر الإنتاجي والقيمة المتبقية، والقيمة الدفترية لا تنزل تحت القيمة المتبقية أبداً.
- الميزانية خطة ثابتة، والتوقع يتحدث، والانحراف يحتاج سبباً مكتوباً، وانظر إلى الاتجاه وليس إلى الحد وحده.
- قارن الاستحقاق بالاستحقاق والنقد بالنقد، وإلا كتبت تفسيرات لانحرافات غير موجودة.
وفي المقال القادم بإذن الله سوف نتحدث عن دورة الشراء Procure-to-Pay: كيف يتحول طلبك إلى أمر شراء ثم إلى فاتورة مدفوعة، ولماذا ترفض المالية فاتورة لم تسجل استلامها.
سجل التحديثات
- أكتوبر 2026: كتابة المقال، والاطلاع على صفحات IAS 16 وIAS 38 وقرار لجنة تفسيرات IFRS عن تكاليف إعداد SaaS في موقع مؤسسة IFRS، ونص دعوى SEC على WorldCom، بتاريخ 14 أكتوبر 2026، وتشغيل المختبرين على Python 3.13.16 وDuckDB 1.5.6 ببيانات مصطنعة.