كيف أحسب أجر الموظف يومياً بحيث يتغيّر إجمالي الراتب حسب عدد أيام الشهر الفعلية (28 / 29 / 30 / 31)؟

Viewed 42

عندي عميل يريد أن يحتسب أجر الموظف يومياً بحيث:

  • أجر اليوم الواحد = الراتب الشهري ÷ 30 (ثابت طوال السنة)
  • إجمالي الراتب الشهري = أجر اليوم × عدد أيام الشهر الفعلية

أي أنّ موظفاً راتبه الأساسي 3000 ج يجب أن يقبض:

عدد أيام الشهر الإجمالي المستحق
28 يوماً 2800 ج
29 يوماً 2900 ج
30 يوماً 3000 ج
31 يوماً 3100 ج

والقاعدة لكل يوم: مأخوذ من الحضور — يوم العمل الفعلي يُحتسب يوماً، والإجازة الأسبوعية والعطلة الرسمية والإجازة العادية (المدفوعة) تُحتسب أياماً كذلك، أما الغياب والإجازة بدون مرتب فلا.

ما الطريقة المتّبعة في النظام لتطبيق هذه القاعدة دون أن تتأثر القيود المحاسبية ودون أن يرى الموظف مكوّناً جديداً في كشف راتبه؟

1 Answers

الفكرة الأساسية أن نُعرّف مفرد راتب يُمثّل الراتب الأساسي بصورة "أداة حساب" داخلية، ثم نربط معادلة تَضرب قيمته في عدد أيام الحضور الفعلية للموظف خلال الشهر، مقسومة على 30. وبذلك يصبح الراتب يومياً، ويتغيّر إجمالي الشهر تلقائياً مع تغيّر عدد أيامه.

ننفّذ ذلك على أربع خطوات.


الخطوة الأولى: تعريف مفرد راتب للأساسي بنوع «أخرى»

ننشئ مفرد راتب جديداً ونسمّيه مثلاً «الراتب الأساسي» ونختار نوعه أخرى (Other). السبب في اختيار «أخرى» تحديداً:

  • لا يُضاف إلى المجموع الذي يظهر للموظف في شاشة الراتب.
  • لا يُحتسب ضمن الإضافات أو الاستقطاعات في صافي الراتب.
  • لا يدخل ضمن الوعاء التأميني أو الضريبي.

ثم نضبط حساب المدين والدائن متطابقين في تعريف المفرد. الهدف من ذلك أن أي قيد محاسبي يُولَّد عن هذا المفرد سيُلغي نفسه (مدين = دائن لنفس الحساب)، فلا يكون له أي أثر على القيود المحاسبية.

💡 ملاحظة: هذا المفرد سيُستخدم فقط كمصدر لقيمة "الراتب الأساسي" داخل معادلات الحساب، وليس مكوّناً ظاهرياً في كشف الراتب.


الخطوة الثانية: إنشاء مؤشر أداء يحسب أيام الشهر الفعلية

ننشئ مؤشر أداء من نوع نظام (System) ومن نوع نظامي SQL يومي (DailySQL). الاستعلام يعمل على مستوى كل يوم في سجل الحضور اليومي للموظف، ويُرجع 1 إذا كان اليوم مستحقاً للأجر (عمل / إجازة أسبوعية / عطلة رسمية / إجازة مدفوعة) و0 فيما عدا ذلك.

عند جمع نتائج المؤشر على مدار الشهر نحصل على عدد أيام الشهر الفعلية (28 أو 29 أو 30 أو 31) لمن داوم بانتظام، وأقل من ذلك لمن غاب أيّاماً.

JSON جاهز للاستيراد لمؤشر الأداء:

{
  "code": "BS001001",
  "name1": "أيام العمل الشهرية",
  "indicatorType": "System",
  "indicatorOrder": 1,
  "systemIndicator": "DailySQL",
  "sqlStatment": "select case when {isWeekEnd} = 1 or {isHoliday} = 1 or {netWorkingHours} > 0 or {netMissionTime} > 1 or ({isVacation} = 1 and {withoutSalaryVacation} = 0) then 1 else 0 end"
}

شرح منطق الاستعلام:

الحالة الشرط في الاستعلام يُحتسب؟
إجازة أسبوعية isWeekEnd = 1 نعم
عطلة رسمية isHoliday = 1 نعم
حضور فعلي بساعات عمل netWorkingHours > 0 نعم
يوم مأمورية netMissionTime > 1 نعم
إجازة مدفوعة الأجر isVacation = 1 و withoutSalaryVacation = 0 نعم
غياب بدون عذر كل ما سبق = 0 لا
إجازة بدون مرتب isVacation = 1 و withoutSalaryVacation = 1 لا

💡 ملاحظة: الحقول بين الأقواس المعقوفة {...} تُستبدل وقت التنفيذ بأعمدة سجل الحضور اليومي، فلا داعي لكتابة أسماء جداول أو ربط (join) يدوياً.


الخطوة الثالثة: معادلة احتساب — معامل × قيمة المؤشر مرتبطة بالمفرد

ننشئ معادلة احتساب مكوّن من النوع مرتبطة بمؤشر أداء (RelatedToPerformanceIndecator) ونربطها بالمؤشر BS001001 من الخطوة السابقة.

الفكرة هنا أن نضرب قيمة الراتب الأساسي (مأخوذة من مفرد الخطوة الأولى) في عدد أيام العمل (من المؤشر) ثم نقسم على 30:

القيمة المستحقة = الراتب الأساسي × (أيام العمل ÷ 30)

نختار في المعادلة:

  • performanceFactor: قيمة الراتب الأساسي (المفرد الذي عرّفناه).
  • multiplyBy: 1
  • divideOn: 30
  • valueMethod: حسب المعامل وقيمة المؤشر.

JSON جاهز للاستيراد:

{
  "code": "BS001",
  "name1": "معادلة الراتب الأساسي اليومي",
  "formulaType": "RelatedToPerformanceIndecator",
  "calcMethod": "OnePercentage",
  "performanceIndicator": "BS001001",
  "applicabilityMethod": "Periodic",
  "performanceFactor": "RelatedComponentValue",
  "relatedComponent": "BASIC_SALARY_OTHER",
  "valueMethod": "FactorAndIndicator",
  "calculationLines": [
    {
      "multiplyBy": 1,
      "divideOn": 30,
      "rate": 1
    }
  ]
}

✏️ تذكَّر استبدال BASIC_SALARY_OTHER بكود مفرد الراتب الأساسي (من نوع «أخرى») الذي أنشأته في الخطوة الأولى.


الخطوة الرابعة: ربط المعادلة بمكوّن «الراتب الأساسي» الظاهر للموظف

نفتح نوع مكوّن الراتب الخاص بالراتب الأساسي (المكوّن الذي يظهر للموظف في كشف الراتب) ونربطه بالمعادلة BS001. هذا المكوّن من نوع إضافات عادي، وله أثر محاسبي طبيعي (مدين على مصروف الرواتب / دائن للموظف).

عند تشغيل مسير الرواتب الشهري:

  1. ينفّذ النظام مؤشر BS001001 على كل يوم في الفترة → يُنتج عدد أيام الشهر الفعلية للموظف.
  2. يقرأ قيمة مفرد «الراتب الأساسي - أخرى» للموظف (مثلاً 3000).
  3. تطبّق معادلة BS001 العملية: 3000 × (أيام العمل ÷ 30).
  4. في شهر 31 يوماً يخرج الناتج = 3100، وفي شهر 28 يوماً = 2800، وهكذا.
  5. تُسجَّل القيمة في مكوّن «الراتب الأساسي» الذي يراه الموظف، ومنه تنطلق القيود المحاسبية الطبيعية.

أما مفرد «الراتب الأساسي - أخرى» فيبقى مخفياً لا يراه الموظف، ولا يدخل في تجميع الإضافات أو الاستقطاعات، ولا يولّد أي قيد لأن المدين والدائن فيه متطابقان.


لماذا هذا الأسلوب؟

  • يلبّي الشرط حرفياً: أجر اليوم = الراتب ÷ 30، والإجمالي = أجر اليوم × أيام الشهر الفعلية. فيتغيّر صافي الراتب بين 2800 و3100 تلقائياً.
  • لا يكسر القيود المحاسبية: مفرد الأساسي الخفي مدينه = دائنه فلا أثر له على دفتر الأستاذ، والمكوّن الظاهر يحمل القيمة النهائية ويولّد القيد الصحيح.
  • شفّاف للموظف: يرى مكوّن «الراتب الأساسي» فقط بقيمته النهائية، ولا يرى ازدواجاً في كشف الراتب.
  • يحترم الحضور والإجازات: الغياب يُنقص الأيام، والإجازة بدون مرتب كذلك، أما الإجازات المدفوعة والإجازات الأسبوعية والعطلات الرسمية فتُحتسب أياماً عمل مدفوعة.
  • قابل لإعادة الاستخدام: نفس مؤشر BS001001 يمكن أن تستخدمه معادلات بدلات أخرى مرتبطة بأيام الحضور.