دليل Jasper Reports الشامل لنظام Nama ERP
نظرة عامة (Overview)
يغطي هذا الدليل الشامل جميع جوانب تطوير Jasper Reports في نظام Nama ERP، بما فيها فئة NamaRep الأداتية القوية التي تمتد من ServerNamaRep. توفر NamaRep وظائف أساسية للترجمة والتوطين، واسترجاع البيانات، وربط الكيانات، وحسابات الأسعار، وغير ذلك.
البداية السريعة: إضافة شعار الشركة إلى التقارير
لعرض شعار الشركة في تقاريرك:
- أنشئ معاملاً باسم
loginLegalEntityLogoمن النوعjava.lang.Objectأوjava.io.InputStream - أضف مكوّن صورة إلى تقريرك
- اضبط تعبير الصورة على
$P{loginLegalEntityLogo}
يُوفَّر الشعار تلقائياً من قِبل النظام عند تشغيل التقرير.
إضافة أي مرفق أو صورة إلى التقارير
// لاسترجاع أي مرفق بواسطة معرّفه
NamaRep.getFile($F{attachmentId})
// أو
NamaRep.getAttachment($F{attachmentId})التقارير الفرعية (Subreports)
يمكنك تضمين تقارير فرعية داخل التقرير الرئيسي. يمكن أن يكون التقرير الفرعي تقريراً آخر موجوداً أو ملف تقرير خارجياً.
ربط التقارير الفرعية
لربط تقرير فرعي:
- أنشئ معاملاً بـ نفس معرّف التقرير الفرعي
- اضبط نوع المعامل على
java.io.InputStreamأوjava.lang.Object - سيمرّر النظام التقرير الفرعي إلى هذا المعامل تلقائياً
موارد إضافية (صور، ملفات)
يمكنك إرفاق موارد إضافية كالصور بتقرير:
- عرّف معاملاً بـ نفس معرّف المورد
- اضبط نوع المعامل على
java.lang.Object - سيكون المورد متاحاً من خلال هذا المعامل
مرجع NamaRep API
التوطين والترجمة الأساسية
اختيار الاسم بناءً على اللغة
// اختيار الاسم العربي أو الإنجليزي تلقائياً بحسب اللغة الحالية
NamaRep.name(name1, name2) // يُرجع name1 للعربية، name2 للإنجليزية
// مع الرجوع إلى الكود إذا كانت الأسماء فارغة
NamaRep.nameOrCode(code, name1, name2)
// اختيار اللغة مباشرةً
NamaRep.name(arabic, english) // حيث arabic = name1 أو code، و english = name2 أو altCodeدوال الترجمة
// ترجمة أي قيمة (نصوص، قيم منطقية، enums)
NamaRep.translate(value)
// ترجمة قيم enum
NamaRep.translate(enumValue)
// ترجمة القيم المنطقية إلى نص محلّي
NamaRep.translate(true) // يُرجع "Yes" أو "نعم" بحسب اللغة
// ترجمة معرّفات الحقول مع سياق الكيان
NamaRep.title(entityType, fieldId)
NamaRep.translate(entityType, fieldId)
// الترجمة مع بادئة
NamaRep.translate("prefix", "value") // يترجم "prefix.value"
// تقسيم النص المترجم بفاصل الأنبوب
NamaRep.head("header|subtitle") // يُرجع "header"
NamaRep.sub("header|subtitle") // يُرجع "subtitle"دوال التاريخ والوقت
أسماء الأيام
NamaRep.dayName($F{dateField}) // يُرجع اسم اليوم باللغة الحالية
NamaRep.arDayName($F{dateField}) // اسم اليوم بالعربية
NamaRep.enDayName($F{dateField}) // اسم اليوم بالإنجليزية
NamaRep.dayName(dayNumber) // 1=الأحد، 2=الاثنين، إلخ.دعم التقويم الهجري
// تحويل التاريخ الميلادي إلى هجري
NamaRep.toHijri($F{date}) // نص التاريخ الهجري الكامل
NamaRep.toHijriDate($F{date}) // كائن HijriDate
NamaRep.hijriDay($F{date}) // اليوم الهجري (مع حشو)
NamaRep.hijriMonth($F{date}) // الشهر الهجري (مع حشو)
NamaRep.hijriYear($F{date}) // السنة الهجرية
NamaRep.hijri_yyyyMMdd($F{date}) // التنسيق: yyyyMMdd
// تنسيق مخصص
NamaRep.hijriDay($F{date})+"/"+NamaRep.hijriMonth($F{date})+"/"+NamaRep.hijriYear($F{date})تحويل الوقت
// تحويل الساعات العشرية إلى تنسيق الوقت
NamaRep.decimalToTime(9.5) // يُرجع "09:30"
NamaRep.decimalToTimeWithSeconds(9.5) // يُرجع "09:30:00" (يتضمن الثواني)
NamaRep.decimalToTimeNullable(0) // يُرجع null بدلاً من "00:00"
NamaRep.decimalToTimeWithSecondsNullable(0) // يُرجع null بدلاً من "00:00:00"
// تحويل المللي ثانية إلى تنسيق الوقت
NamaRep.timeToString(9120000) // يُرجع "02:32"
NamaRep.timeToStringNullable(0) // يُرجع null بدلاً من "00:00"حسابات فترات التاريخ
// حساب الفترة بين تاريخين (سنوات، أشهر، أيام)
// 1. أنشئ متغيراً بنوع إعادة تعيين none وزيادة none
java.time.Period.between(
new java.util.Date($F{FromDate}.getTime()).toInstant()
.atZone(java.time.ZoneId.systemDefault()).toLocalDate(),
java.time.LocalDate.now()
)
// 2. الاستخدام في تعبير حقل نصي
$V{period}.getYears()+" سنة "+$V{period}.getMonths()+" شهر "+$V{period}.getDays()+" يوم"
// حساب الأشهر بين تاريخين
NamaRep.dateDiffInMonth(date1, date2)تنسيق الأرقام وتحويلها
الأرقام العربية
// تحويل الأرقام الغربية إلى أرقام عربية-هندية (٠،١،٢،٣،٤،٥،٦،٧،٨،٩)
NamaRep.arNumbers("123") // يُرجع "١٢٣"
NamaRep.arNumbers(value)مساعدات الحقول الرقمية
// عمليات آمنة من القيم الفارغة
NamaRep.zeroIfNull(fieldOrVariable) // يُرجع 0 إذا كانت null
NamaRep.oneIfZero(fieldOrVariable) // يُرجع 1 إذا كانت صفراً
NamaRep.nullIfZero(fieldOrVariable) // يُرجع null إذا كانت صفراً
// تحويل إلى BigDecimal
NamaRep.objectToDecimal(value) // تحويل آمن إلى BigDecimalرمز الريال السعودي
// يُرجع رمز SAR كـ InputStream لمكوّن الصورة
NamaRep.sar()التفقيط (تحويل الأرقام إلى كلمات)
// تحويل الأرقام إلى كلمات بلغات مختلفة
NamaRep.tafqeet(currencyCode, amount) // اللغة الحالية
NamaRep.tafqeetArabic(currencyCode, amount) // العربية
NamaRep.tafqeetEnglish(currencyCode, amount) // الإنجليزية
NamaRep.tafqeetFrench(currencyCode, amount) // الفرنسيةيمكن إيجاد إعداد تفقيط العملات في الإعداد العام تحت value.info.tafqeetInfo.currencyCode
حسابات الأسعار
استخدام حاسبة الأسعار
// حساب سعر الوحدة الأساسي
NamaRep.priceCalculator()
.item($F{item})
.uom($F{UOM})
.qty($F{Quantity})
.unitPriceOnly()
.price()إنشاء متغيرات الأسعار
يُرجع هذا التعبير كائن سعر كاملاً. يجب تخزينه في متغير:
- فئة المتغير:
java.lang.Object - الحساب:
No Calculation Function - نوع الزيادة:
None - نوع الإعادة:
None
دوال حاسبة الأسعار الكاملة
// جميع دوال البنّاء المتاحة
NamaRep.priceCalculator()
.item($F{itemIdOrCode})
.customer($F{customerIdOrCode})
.supplier($F{supplierIdOrCode})
.uom($F{uomIdOrCode})
.invoiceClassification($F{classificationIdOrCode})
.ic($F{classificationIdOrCode}) // اختصار invoiceClassification
.legalEntity($F{legalEntityIdOrCode})
.le($F{legalEntityIdOrCode}) // اختصار legalEntity
.sector($F{sectorIdOrCode})
.sc($F{sectorIdOrCode}) // اختصار sector
.branch($F{branchIdOrCode})
.br($F{branchIdOrCode}) // اختصار branch
.department($F{departmentIdOrCode})
.dep($F{departmentIdOrCode}) // اختصار department
.analysisSet($F{analysisSetIdOrCode})
.anset($F{analysisSetIdOrCode}) // اختصار analysisSet
.priceClassifier1($F{priceClassifier1IdOrCode})
.pc1($F{priceClassifier1IdOrCode}) // اختصار priceClassifier1
.priceClassifier2($F{priceClassifier2IdOrCode})
.pc2($F{priceClassifier2IdOrCode})
.priceClassifier3($F{priceClassifier3IdOrCode})
.pc3($F{priceClassifier3IdOrCode})
.priceClassifier4($F{priceClassifier4IdOrCode})
.pc4($F{priceClassifier4IdOrCode})
.priceClassifier5($F{priceClassifier5IdOrCode})
.pc5($F{priceClassifier5IdOrCode})
.revision($F{revision})
.color($F{colorCode})
.size($F{size})
.qty($F{qty})
.date($F{date})
.unitPriceOnly()
.price() // يجب أن يكون آخر عنصر في السلسلةالوصول إلى مكوّنات السعر
بعد تخزين السعر في المتغير $V{price}، الوصول إلى المكوّنات:
// القيم الرئيسية
$V{price}.unitPrice.primitiveValue
$V{price}.netValue.primitiveValue
$V{price}.custom.primitiveValue
$V{price}.totalCashShare.primitiveValue
$V{price}.totalPaymentMethodShare.primitiveValue
// مكوّنات الخصم (1-8 متاحة)
$V{price}.discount1.percentage.primitiveValue
$V{price}.discount1.value.primitiveValue
$V{price}.discount1.afterValue.primitiveValue
$V{price}.discount1.maxNormalPercent.primitiveValue
// خصم الرأسية (Header discount)
$V{price}.headerDicount.percentage.primitiveValue
$V{price}.headerDicount.value.primitiveValue
$V{price}.headerDicount.afterValue.primitiveValue
// مكوّنات الضريبة (1-4 متاحة)
$V{price}.tax1.percentage.primitiveValue
$V{price}.tax1.value.primitiveValue
$V{price}.tax1.afterValue.primitiveValue
$V{price}.tax1.maxNormalPercent.primitiveValueروابط الكيانات والتنقل
روابط الكيانات الأساسية
// رابط بسيط للكيان
NamaRep.link(entityType, id)
NamaRep.link(serverUrl, entityType, id)
// بنّاء روابط متقدم مع القائمة والعرض
NamaRep.link()
.entityType($F{entityType})
.id($F{id})
.viewName("theViewName")
.menuCode("abcMenu")
.url(serverUrl)
.toString()روابط المرفقات
// إنشاء رابط لمرفق/مستند
NamaRep.attachmentLink(id)
NamaRep.attachmentLink(serverUrl, attachmentId)روابط التقارير
// رابط لتقرير آخر بواسطة الكود
NamaRep.repLinkByCode($P{REPORT_PARAMETERS_MAP}, "ReportCode")
.p("p1 id").v(value expression)
.p("p2 id").v(value expression)
.copyParams() // نسخ جميع المعاملات المشتركة من التقرير الحالي
.toString()
// معاملات المرجع - تنسيقات متعددة متاحة
.p("param").v($F{id}, $F{entity}, $F{code}, $F{name1}, $F{name2})
.p("param").v($F{id}, $F{entity}, $F{code})
.p("param").ref($F{entityType}, $F{id})
.p("param").refCode($F{entityType}, $F{code})
// إذا كنت لا تريد إضافة عنوان URL الخادم (سيكون الرابط #rpt:xxx بدلاً من https://abc.namasoft.com/erp/#rpt:xxx) استخدم التالي
.directLink()أمثلة روابط التقارير
// المثال 1: كشف حساب
NamaRep.repLinkByCode($P{REPORT_PARAMETERS_MAP}, "Statement")
.copyParams()
.p("fromAccount").v($F{accountId}, $F{accountEntityType}, $F{accountCode})
.p("toAccount").v($F{accountId}, "Account", $F{accountCode})
.toString()
// المثال 2: ملخص أرباح المبيعات
NamaRep.repLinkByCode($P{REPORT_PARAMETERS_MAP}, "SalesProfitSummary")
.copyParams($P{REPORT_PARAMETERS_MAP})
.p("SalesInvoice").ref("SalesInvoice", $F{SSIid})
.p("cust").refCode("Customer", "Customer501")
.p("fromDate").v("23-04-2014")
.p("showDetails").v("true")
.toString()
// المثال 3: كشف حساب فرعي
NamaRep.repLinkByCode($P{REPORT_PARAMETERS_MAP}, "SubsidiaryAccountStatement")
.p("subsidiaryType").v($F{CustomerEntityType})
.p("fromSubsidiary").v($F{customerId}, $F{CustomerEntityType}, $F{customerCode})
.p("toSubsidiary").v($F{customerId}, $F{CustomerEntityType}, $F{customerCode})
.p("accuontType").v("mainAccount")
.toString()روابط التقارير العامة (بدون مصادقة)
لمشاركة رابط تقرير خارجياً (مثلاً مع العملاء) دون الحاجة إلى تسجيل دخول:
NamaRep.repLinkByCode($P{REPORT_PARAMETERS_MAP}, "ARG000046-report")
.p("Code_Equals").ref($F{entityType}, $F{id})
.toNoAuthResultLink()روابط عرض القائمة المفلترة
يمكنك إنشاء روابط تشعبية تفتح عرض قائمة مفلتراً لأي نوع كيان. وهذا مفيد عندما تريد أن ينقر المستخدمون على رابط في التقرير ليروا قائمة سجلات مُصفّاة مسبقاً.
الاستخدام الأساسي
NamaRep.listView()
.entityType("SalesInvoice")
.criteria($P{REPORT_SCRIPTLET}.tempo("""
customer.code,Equal,{customerCode},AND;
valueDate,GreaterThanOrEqual,{fromDate},AND;
"""))
.toString()
// لتفعيل الرابط المباشر لعرض القائمة، استخدم التالي
.directLink()دوال البنّاء
| الدالة | الوصف |
|---|---|
.entityType(String) | نوع الكيان للعرض (مثلاً "SalesInvoice"، "Customer") |
.criteria(String) | معايير الفلترة بتنسيق نصي (انظر أدناه) |
.listViewName(String) | اسم عرض القائمة المحدد للاستخدام |
.menuCode(String) | كود القائمة لفتح عرض القائمة فيه |
.orderBy(String) | الحقل للترتيب حسبه |
.ascending(Boolean) | اتجاه الترتيب (true = تصاعدي) |
.currentPage(Integer) | رقم الصفحة للعرض |
.pageSize(Integer) | عدد السجلات في الصفحة (-1 للكل) |
.showTree(Boolean) | العرض كشجرة |
.extraCriteriaId(String) | معرّف تعريف معايير إضافية |
استخدام Tempo للمعايير الديناميكية
الميزة الأقوى هي دمج بنّاء عرض القائمة مع صيغة Tempo لحقن قيم حقول التقرير ديناميكياً في المعايير:
$P{REPORT_SCRIPTLET}.tempo("""
field,Operator,{value},AND;
""")داخل الأقواس المعقوفة {...}، يمكنك الإشارة إلى:
- الحقول:
{fieldName}- استخدم أسماء الحقول مباشرةً دون$F{} - المعاملات:
{paramName}- استخدم أسماء المعاملات مباشرةً دون$P{} - المتغيرات:
{varName}- استخدم أسماء المتغيرات مباشرةً دون$V{}
مثال كامل
لنفترض أن لديك تقريراً يعرض العملاء وتريد إضافة رابط يفتح كل فواتير المبيعات لهذا العميل:
NamaRep.listView()
.entityType("SalesInvoice")
.criteria($P{REPORT_SCRIPTLET}.tempo("""
customer.code,Equal,{customerCode},AND;
valueDate,GreaterThanOrEqual,{fromDate},AND;
valueDate,LessThanOrEqual,{toDate},AND;
"""))
.listViewName("SalesInvoicesForCustomer")
.orderBy("valueDate")
.ascending(false)
.toString()يُنشئ هذا رابطاً قابلاً للنقر يفتح عرض قائمة فاتورة المبيعات مفلتراً بـ:
- كود العميل المطابق لحقل
customerCodeفي الصف الحالي - تاريخ القيمة بين معاملات
fromDateوtoDateفي التقرير
مرجع تنسيق المعايير
يتبع نص المعايير تنسيق معايير النص:
fieldID,operator,value,logic;العوامل المتاحة:
Equal،NotEqualGreaterThan،GreaterThanOrEqualLessThan،LessThanOrEqualStartsWith،NotStartsWithEndsWith،NotEndWithContains،NotContainIn،NotIn
روابط المنطق: AND، OR
تنسيق التاريخ: dd-MM-yyyy
تنسيق المرجع: id:entityType:code (الكود اختياري)
TIP
يمكنك استخدام شاشة Criteria Definition لبناء شروط الفلترة بصرياً، ثم النقر على Convert to Text للحصول على التنسيق النصي. يمكن بعد ذلك استخدام هذا النص كقالب لمعاييرك المدعومة بـ Tempo.
اختصار عناوين URL
يمكنك اختصار عناوين URL للتقارير باستخدام:
NamaRep.shortenURL(serverurl, signature, url)انظر قسم {shortenurl()} في وثائق Tempo لمزيد من المعلومات.
إنشاء الكيانات (Creators)
Creator الأساسي
// إنشاء كيان جديد بحقوله
NamaRep.newWithFields("ReceiptVoucher")
.f("term").value("POTermCode")
.f("book").value("POBook1")
.f("remarks").v("Auto Created")
.f("fromDoc#type").v("SalesInvoice")
.f("fromDoc#code").v($F{code})
.menuCode("NormalReceiptMenu")
.viewName("NormalReceipts")
.toString()
// صيغة بديلة
NamaRep.creator("ReceiptVoucher")
.field("supplier").value(supplierId)
.toString()Creator مع تفاصيل الأسطر
للتقارير ذات أحزمة التفاصيل التي تحتاج إلى إنشاء كيانات مع بنود:
- أنشئ المتغير
creatorLinkمع تعبير القيمة الأولية:
NamaRep.newWithFields("PurchaseOrder")
.field("term").value("P.Order.Term")
.root()- في حزمة التفاصيل، أضف بنود الأسطر:
$V{creatorLink}
.field("details.item.itemCode").value($F{code})
.field("details.quantity").value($F{qty})
.row($V{REPORT_COUNT})- أنشئ الرابط النهائي:
$V{creatorLink}.toString()نظام الموافقة
روابط موافقة المستندات
// الموافقة/الرفض/الإرجاع لجميع الأسطر
NamaRep.approveAllLink($P{REPORT_PARAMETERS_MAP})
NamaRep.rejectAllLink($P{REPORT_PARAMETERS_MAP})
NamaRep.returnAllLink($P{REPORT_PARAMETERS_MAP})
NamaRep.returnAllToPreviousStepLink($P{REPORT_PARAMETERS_MAP})
// مع معامل القرار
NamaRep.approveAllLink($P{REPORT_PARAMETERS_MAP}, decision) // decision: "Approve"، "Reject"، أو "Return"الموافقة لكل سطر (الأسطر المعنية)
للمستندات ذات الموافقات على مستوى الأسطر:
// الموافقة/الرفض لسطر محدد
NamaRep.approveLink($P{REPORT_PARAMETERS_MAP}, $F{lineNumber})
NamaRep.rejectLink($P{REPORT_PARAMETERS_MAP}, $F{lineNumber})
NamaRep.returnLink($P{REPORT_PARAMETERS_MAP}, $F{lineNumber})
NamaRep.returnToPreviousStepLink($P{REPORT_PARAMETERS_MAP}, $F{lineNumber})
// مع كود السبب
NamaRep.approveLink($P{REPORT_PARAMETERS_MAP}, $F{lineNumber}, reasonCodeOrId)
NamaRep.rejectLink($P{REPORT_PARAMETERS_MAP}, $F{lineNumber}, reasonCodeOrId)
// التحقق إذا كان السطر يحتاج إلى موافقة
NamaRep.isConcernedLine($P{REPORT_PARAMETERS_MAP}, $F{lineNumber})حوار موافقة JavaScript
// عرض حوار الموافقة في المتصفح
NamaRep.approveFromJS(entityType, entityId, nextStepName,
concernedLines, nextStepSeq, summary)وظائف الموظفين والموارد البشرية
أرصدة الإجازات
// أنواع الإجازات الافتراضية (1، 2، 3)
NamaRep.getVacation1RemainderBalance(empIdOrCode)
NamaRep.getVacation2RemainderBalance(empIdOrCode)
NamaRep.getVacation3RemainderBalance(empIdOrCode)
// نوع إجازة محدد
NamaRep.getVacationRemainderBalance(empCodeOrId, vacationTypeIdOrCode)
NamaRep.getVacationRemainderBalance(empCodeOrId, vacationTypeIdOrCode, atDate)
// معلومات الإجازة التفصيلية
NamaRep.getVacationAssignedConsumedRemainder(employeeId, vacationType)
NamaRep.getVacationAssignedConsumedRemainder(employeeId, vacationType, atDate)
// الرصيد لكل السنوات
NamaRep.getRemainderBalancePerYears(employeeId, atDate, yearsCount)نقاط المكافأة
نقاط ومبالغ المكافأة المتاحة
// الحصول على نقاط المكافأة المتاحة لكيان (مثلاً Customer، Supplier)
NamaRep.availableRewardPoints("Customer", $F{customerId})
NamaRep.availableRewardPoints("Customer", $F{customerCode})
// الحصول على مبلغ المكافأة المتاح لكيان
NamaRep.availableRewardAmount("Customer", $F{customerId})
NamaRep.availableRewardAmount("Customer", $F{customerCode})النقاط المكتسبة (المستندات)
// الحصول على النقاط المكتسبة من مستند (مثلاً SalesInvoice)
NamaRep.earnedPoints("SalesInvoice", $F{invoiceId})
NamaRep.earnedPoints("SalesInvoice", $F{invoiceCode})TIP
- تعمل
availableRewardPointsوavailableRewardAmountمع أي ملف رئيسي. - تعمل
earnedPointsفقط مع كيانات المستندات (مثلاً SalesInvoice، NamaPOSSalesInvoice). تُرجعnullللملفات الرئيسية. - تقبل الدوال الثلاث معرّفاً أو كوداً كمعامل ثانٍ.
عمليات قاعدة البيانات
تنفيذ استعلامات SQL
// تنفيذ استعلام SQL مع معاملات
NamaRep.runSQLQuery(sql, paramName, paramValue, paramName, paramValue)
// مثال مع معاملات مسمّاة
NamaRep.executeQuery(
"SELECT cast(w.name1 collate Arabic_CI_AI_KS_WS as varchar(250))
FROM warehouse w WHERE w.id = :wid",
"wid", $F{wid}
)
// تنسيق نتائج الاستعلام
NamaRep.formatQueryResult(results, "
", ",") // فاصل الصفوف، فاصل الأعمدةالوصول إلى إعداد الوحدة
// الحصول على قيمة الإعداد
NamaRep.getValueFromModuleConfig(moduleId, fieldId)
// مثال
NamaRep.getValueFromModuleConfig("basic", "value.info.useCurrentUserAsSalesMan")أسماء الوحدات المتاحة:
- accounting، basic، supplychain، fixedassets
- humanresource، dms، project، ecpa
- manufacturing، srvcenter، crm، contracting
- travel، realestate، housing، auditing
- education، namapos، mc
الأمان والصلاحيات
قيود الأمان للتقارير
كيفية التصفية حسب الشركة، أو القطاع، أو أي مُحدد آخر
نفترض أنك ترغب في تصفية البيانات بناءً على منشئ السجل، وصلاحيات التعديل أو العرض، وكذلك حسب الشركة أو القطاع أو الفرع أو غير ذلك من المُحددات ضمن سجل الحساب. للقيام بذلك، اتبع الخطوات التالية:
1. إنشاء المعامل المخفي SECURITY_CONSTRAINTS
أنشئ معامل String مع "Not For Prompting" والتعبير الافتراضي:
NamaRep.security()
.fieldEntityType("Account")
.tableAlias("acc")
.capabilities("firstAuthor", "viewCapability", "usageCapability",
"updateCapability", "legalEntity", "branch",
"sector", "department", "analysisSet")مكوّنات التعبير:
.fieldEntityType("Account")- يحدد نوع الكيان للتصفية الأمنية.tableAlias("acc")- الاسم المستعار للجدول في استعلام SQL.capabilities(...)- قائمة المحددات الأمنية للتصفية بها
القدرات المتاحة:
firstAuthor- التصفية حسب منشئ السجلviewCapability،updateCapability،usageCapability- التصفية المبنية على الصلاحياتlegalEntity،branch،sector،department،analysisSet- التصفية التنظيمية
2. الاستخدام في استعلام SQL
أدرج المعامل في جملة WHERE:
SELECT a, b, c
FROM Account acc
LEFT JOIN Table2 t2 ON t2.id = acc.someId
WHERE acc.code <> 'abc'
AND $P!{SECURITY_CONSTRAINTS}3. أمان جداول متعددة
للتصفية على جداول متعددة:
NamaRep.security()
.fieldEntityType("Account")
.tableAlias("Account")
.capabilities("firstAuthor", "viewCapability")
+ " AND " +
NamaRep.security()
.fieldEntityType("FiscalYear")
.tableAlias("FiscalYear")
.capabilities("legalEntity", "branch", "sector")ملخص
يُطبّق أسلوب التصفية الأمنية هذا قواعد رؤية البيانات وحقوق التعديل ديناميكياً بناءً على أدوار المستخدم والهيكل التنظيمي. يولّد النظام تلقائياً جمل WHERE المناسبة بناءً على صلاحيات المستخدم.
صلاحيات العرض
// التحقق إذا كان بإمكان المستخدم عرض المعامل/الحقل
NamaRep.canDisplay($P{param})الوظائف المساعدة
تحويل HTML إلى نص
NamaRep.htmlToText(htmlContent)الأرقام التسلسلية
// توسيع الأرقام التسلسلية المضغوطة
NamaRep.expandSerials(serials) // فاصل السطر الافتراضي
NamaRep.expandSerials(serials, separator) // فاصل مخصص
NamaRep.unzipSerials(serials) // يُرجع List<String>
NamaRep.unzipSerialsWithNewLines(serials)
NamaRep.unzipSerialsWithComma(serials)
NamaRep.unzipSerialsWithSeparator(serials, ";")
// ضغط نطاقات الأرقام التسلسلية
NamaRep.zipSerialsRange(serials)رموز QR لزاتكا (هيئة الزكاة والضريبة والجمارك)
// توليد رمز QR لزاتكا
NamaRep.genZATCAQR(sellerName, vatNumber, timestamp,
invoiceAmount, vatAmount)
// مع تواريخ القيمة والإنشاء المنفصلة
NamaRep.genZATCAQRWithCreationDate(sellerName, vatNumber,
valueDate, creationDate,
invoiceAmount, vatAmount)
// من كيان
NamaRep.genZatcaQrCodeFromEntity(entityType, idOrCode)
NamaRep.zatcaHashedInvoice(entityType, id)Mobile QR Integrator
// إنشاء رمز QR للمسح الضوئي بالجوال وإنشاء/تحديث الكيانات
// سيتم معالجة رمز QR بواسطة Mobile QR Integrator عند المسح
// رمز QR أساسي مع كود الـ integrator
NamaRep.mobileQr()
.code("IntegratorCode")
.toString()
// رمز QR مع معاملات
NamaRep.mobileQr()
.code("CustomerAttendance")
.addParam("customer", $F{customerCode})
.addParam("date", $F{valueDate})
.addParam("amount", $F{totalAmount})
.toString()
// رمز QR مشفّر (Base64 encoded)
NamaRep.mobileQr()
.code("SecureIntegrator")
.addParam("sensitive", $F{confidentialData})
.encrypted()
.toString()ملاحظات الاستخدام:
- يحتوي رمز QR على JSON مع كود/معرّف الـ integrator والمعاملات
- المعاملات متاحة في مسارات الكيان عبر
$map.paramName - يتم فك تشفير رموز QR المشفّرة تلقائياً بواسطة تطبيق الجوال
- يجب تهيئة الـ integrator في كيان MobileQRIntegrator
معاملات النظام في التقارير
جميع التقارير لديها إمكانية الوصول إلى هذه المعاملات:
انقر لرؤية جميع معاملات النظام
معلومات المستخدم وتسجيل الدخول
loginLanguage- اللغة الحالية (عربي/إنجليزي)originalLoginLanguage- لغة تسجيل الدخول الأصليةloginUserId،loginUserCode،loginUserName1،loginUserName2loginUserTreatAsAuthorIds- معرّفات المستخدمين المفوّضينloginEmployeeIdcurrentUser- كائن المستخدم الحالي
الهيكل التنظيمي
loginLegalEntityId،loginLegalEntityCode،loginLegalEntityName1،loginLegalEntityName2loginSectorId،loginSectorCode،loginSectorName1،loginSectorName2loginBranchId،loginBranchCode،loginBranchName1،loginBranchName2loginDepartmentId،loginDepartmentCode،loginDepartmentName1،loginDepartmentName2loginAnalysisSetId،loginAnalysisSetCode،loginAnalysisSetName1،loginAnalysisSetName2
معرّفات المنظمة العامة
publicLegalEntityId،publicSectorId،publicBranchIdpublicDepartmentId،publicAnalysisSetId
الشعارات والعلامة التجارية
loginLegalEntityLogo- الشعار الرئيسي (InputStream)loginLegalEntityLogo2حتىloginLegalEntityLogo5- شعارات إضافيةreportsFooterNote1،reportsFooterNote2- نص التذييل
سياق التقرير
formEntityType- نوع الكيان للنموذج (يمكن استخدامه للترجمة)reportCode،reportId،reportName1،reportName2namaReportInstance- كائن instance التقريرrunId- معرّف فريد للتشغيل
عناوين URL
guiServerURL- عنوان URL لخادم الواجهةexternalServerURL- عنوان URL للخادم الخارجيcurrentGUIURL- عنوان URL الحالي للواجهة
نظام الموافقة
concernedLines- الأسطر التي تحتاج إلى موافقةcandidateEmployeeId،candidateEmployeeCode،candidateEmployeeName1،candidateEmployeeName2approvedRecordId،approvedRecordType،approvedRecordCodeapprovalSecret،approvalStepSeq
الأمان والصلاحيات
allowedCapabilities،allowedEntities،allowedDocuments،allowedFilesnotAllowedEntities،notAllowedDocuments،notAllowedFilesaccessibleLegalEntityIds،accessibleSectorIds،accessibleBranchIdsaccessibleDepartmentIds،accessibleAnalysisSetIds
علامات الأمان
legalEntityNotUsedInSecurity،sectorNotUsedInSecuritybranchNotUsedInSecurity،departmentNotUsedInSecurityanalysisSetNotUsedInSecurity
أخرى
posShiftCode- كود وردية نقطة البيعcurrentReplicationSiteId،currentReplicationSiteCodecurrentReplicationSiteName1،currentReplicationSiteName2
معاملات التقرير
معاملات القائمة (التحديد المتعدد)
لتعريف معامل يدعم تحديدات متعددة:
اضبط الخاصية
list = trueللأنواع غير المرجعية، حدد الخاصية
listTypeالتقاط القيم المحددة للعرض:
<parameterName>_csv: القيم المترجمة كسلسلة CSV<parameterName>_codecsv: الأكواد كسلسلة CSV<parameterName>_name1csv: حقول Name1 كسلسلة CSV<parameterName>_name2csv: حقول Name2 كسلسلة CSV
لمنع العرض التلقائي للشبكة:
doNotAutoShowList = trueللتحكم في أداة العرض للقائمة، اضبط
listDisplayType:Default— إدخال التحديد المتعدد القياسي (يُستخدم عند حذف الخاصية)Dropdown— تُعرض القيم المحددة كشرائح قابلة للإزالة داخل إدخال؛ تفتح قائمة الخيارات الكاملة في قائمة منسدلة قابلة للبحث. مثالي عندما تكون مجموعة القيم كبيرةChips— تُعرض جميع القيم المسموحة كشرائح قابلة للنقر مع تبديل التحديد بالنقر. مثالي عند وجود خيارات قليلة فقط وتريد رؤيتها دون فتح قائمة
مثال:
xml<parameter name="MultiEmployee" class="java.util.List"> <property name="entityType" value="Employee"/> <property name="list" value="true"/> <property name="listDisplayType" value="Chips"/> </parameter>
مثال: معاملات التحديد المتعدد
<!-- معامل قائمة من نوع مرجعي -->
<parameter name="MultiEmployee" class="java.util.List">
<property name="entityType" value="Employee"/>
<property name="arabic" value="الموظفين"/>
<property name="english" value="Employees"/>
<property name="property" value="code"/>
<property name="list" value="true"/>
<property name="doNotAutoShowList" value="false"/>
</parameter>
<parameter name="MultiEmployee_csv" class="java.lang.String" isForPrompting="false"/>
<!-- معامل قائمة من نوع غير مرجعي -->
<parameter name="MultiDate" class="java.util.Date">
<property name="english" value="Dates"/>
<property name="arabic" value="التواريخ"/>
<property name="defaultValue" value="$monthStart()"/>
<property name="list" value="true"/>
<property name="listType" value="java.util.Date"/>
</parameter>
<parameter name="MultiDate_csv" class="java.lang.String" isForPrompting="false"/>معاملات نطاق التاريخ
عند تصفية المستخدمين للتقرير بنطاق تاريخ، يعمل تعريف معاملَي "من تاريخ" و"إلى تاريخ" منفصلَين، لكنه يشغل صفّي مطالبة ولا تكون العلاقة بينهما واضحة بصرياً. يتيح خيار showAsDateRange تقديم منتقٍ موحّد لنطاق التاريخ في واجهة المطالبة مع الإبقاء على معاملَي التاريخ الفعليَّين كما هما لاستخدامهما في استعلام SQL.
يعتمد النمط على ثلاثة معاملات تعمل معاً:
- معامل نصي تحكّمي مع
showAsDateRange = true. هذا ما يراه المستخدم ويتفاعل معه؛ لا يحمل قيمة خاصة به. - معامل "من تاريخ" مع
isForPrompting="false"— مُشار إليه بخاصيةfromDateIdللمعامل التحكّمي. - معامل "إلى تاريخ" مع
isForPrompting="false"— مُشار إليه بخاصيةtoDateIdللمعامل التحكّمي.
عندما يختار المستخدم نطاقاً، يكتب النظام التواريخ المختارة في معاملَي التاريخ الأساسيَّين. من منظور الاستعلام، لا شيء يتغير — تُشير إلى $P{FromValueDate} و$P{ToValueDate} تماماً كأي معامل تاريخ آخر.
- مثال
<parameter name="FromValueDate" class="java.util.Date" isForPrompting="false">
<property name="arabic" value="من التاريخ الفعلي"/>
<property name="english" value="From Value Date"/>
</parameter>
<parameter name="ToValueDate" class="java.util.Date" isForPrompting="false">
<property name="arabic" value="إلى التاريخ الفعلي"/>
<property name="english" value="To Value Date"/>
</parameter>
<parameter name="ValueDate" class="java.lang.String">
<property name="showAsDateRange" value="true"/>
<property name="fromDateId" value="FromValueDate"/>
<property name="toDateId" value="ToValueDate"/>
<property name="arabic" value="التاريخ الفعلي"/>
<property name="english" value="Value Date"/>
</parameter>ثم في استعلام SQL، أشر إلى معاملات التاريخ الأساسية مباشرةً:
WHERE valueDate >= $P{FromValueDate}
AND valueDate <= $P{ToValueDate}أو باستخدام صيغة $X
where $X{[BETWEEN],valueDate,FromValueDate,ToValueDate}- المتطلبات
- يجب أن يكون المعامل التحكّمي من النوع
java.lang.String. - يجب أن يضبط كلا معاملَي التاريخ
isForPrompting="false"حتى لا يظهرا كمطالبات منفصلة إلى جانب منتقي النطاق. - يجب أن تتطابق قيم
fromDateIdوtoDateIdمع أسماء معاملَي التاريخ بالضبط.
مرجع خصائص المعاملات
الخصائص الأساسية
list:true/false- تفعيل التحديد المتعددlistType: مطلوب للأنواع غير المرجعية (مثلاًjava.util.Date)listDisplayType: الأداة المستخدمة لعرض معامل القائمة. إحدىDefault،Dropdown،Chips.showAsDateRange:true/false- عرض معامل نصي كمنتقٍ موحّد لنطاق التاريخ. يُستخدم معfromDateIdوtoDateId. انظر معاملات نطاق التاريخ.fromDateId: اسم معامل "من تاريخ" الأساسي عند تفعيلshowAsDateRange.toDateId: اسم معامل "إلى تاريخ" الأساسي عند تفعيلshowAsDateRange.layout: تخطيط العرض (alone،spanned،normal،spanned2)required:true/false- وضع علامة إلزاميrequiredGroup: تجميع المعاملات حيث يجب ملء واحد على الأقلhijri:true/false- استخدام التقويم الهجري للتواريخnama-id: معرّف داخلي لوظائف Nama المحددة (معالج التقرير)
الاقتراحات للحقول النصية
suggestionquery: استعلام SQL للإكمال التلقائي- عمودان: الكود والعرض بالعربية
- ثلاثة أعمدة: الكود، العربية، والإنجليزية
-- مثال استعلام اقتراح
SELECT DISTINCT TOP 25 revisionId, revisionName
FROM ItemRevision
WHERE invItem_id = {fItem}
AND (revisionId LIKE '%' + {revision} + '%'
OR revisionName LIKE '%' + {revision} + '%')اختيار المرجع
entityType: الكيان للاختيار منهproperty: الحقل للاستخراج (code،name1،name2،startDate)
القائمة المنسدلة (Combo Box)
enumType: نوع enum للقيم المسموحةallowedValues: القيم المسموحة مفصولة بفواصل (تُعرض كـ combo box)allowedValuesAr: الترجمات العربية لقيم القائمة المنسدلة (مفصولة بفواصل، بنفس ترتيبallowedValues)allowedValuesEn: الترجمات الإنجليزية لقيم القائمة المنسدلة (مفصولة بفواصل، بنفس ترتيبallowedValues)
<parameter name="entityType" class="java.lang.String">
<property name="enumType" value="EntityTypeDF"/>
<property name="allowedValues" value="Employee,Supplier"/>
<property name="allowedValuesAr" value="موظف,مورد"/>
<property name="allowedValuesEn" value="Employee,Supplier"/>
</parameter>تصفية القيم
filter: صيغة تصفية الحقول:field,operator,value[,relation]- فلاتر متعددة مفصولة بفاصلة منقوطة
- العلاقة الافتراضية
AND - استخدم
${parameterId}للإشارة إلى معاملات أخرى
العوامل المتاحة:
Equal, EqualOrEmpty, NotEqual, NotEqualOrEmpty,
GreaterThan, GreaterThanOrEmpty, GreaterThanOrEqual, GreaterThanOrEqualOrEmpty,
LessThan, LessThanOrEmpty, LessThanOrEqual, LessThanOrEqualOrEmpty,
StartsWith, StartsWithOrEmpty, NotStartsWith, NotStartsWithOrEmpty,
EndsWith, EndsWithOrEmpty, NotEndWith, NotEndWithOrEmpty,
Contains, ContainsOrEmpty, NotContain, NotContainOrEmpty,
OpenBracket, CloseBracket, Inأمثلة:
forType,Equal,Department,AND;isLeaf,Equal,true
documentType,Equal,ReceiptVoucher
forType,Equal,${subsidiaryType}القيم الافتراضية
defaultValue: قيمة نصية بناءً على نوع المعامل- التاريخ:
dd-MM-yyyy - الوقت:
yyyy-MM-dd'T'HH:mm:ss.SSS - المرجع:
id:entityType:code
- التاريخ:
دوال الإعداد الافتراضي الديناميكية
$now() $today()
$monthStart() $monthEnd()
$yearStart() $yearEnd()
$quarterStart() $quarterEnd()
$thirdStart() $thirdEnd()
$halveStart() $halveEnd()
$previousMonthStart() $previousMonthEnd()
$nextMonthStart() $nextMonthEnd()
$previousYearStart() $previousYearEnd()
$nextYearStart() $nextYearEnd()
$currentFiscalPeriod() $currentUser()
$currentEmployee()
$todayPlusDays(n) $todayPlusWeeks(n)
$todayPlusMonths(n) $todayPlusYears(n)للمعاملات متعددة القيم، استخدم الفاصل @A=@X:
id:entityType:code@A=@Xid:entityType:code@A=@X...التحكم في العرض والتحقق
NamaRep.canDisplay($P{param}): استخدم فيprintWhenExpressionno-mirror = true: منع انعكاس العنصر
التحقق من النطاق
fromParam: ربط معامل "إلى" بمعامل "من"fromParamMaxGapInDays: الحد الأقصى للفجوة بالأيام بين التواريخ
<parameter name="toDate" class="java.util.Date">
<property name="arabic" value="إلى تاريخ"/>
<property name="english" value="To Date"/>
<property name="fromParam" value="fromDate"/>
<property name="fromParamMaxGapInDays" value="30"/>
</parameter>خصائص أخرى
arabic/english: تسميات العرضresource: مفتاح المورد للترجمةsrc: إعادة استخدام خاصية من معامل آخرignore: استبعاد من المطالبةtype: معالجة خاصة للقيم الفارغة أو نوع المقارنة (مثلاً لمقارنات التاريخ مع عوامل>،<)
خصائص التقرير
خصائص خاصة على مستوى التقرير (استشر فريق التطوير للاستخدام):
preRunUtil- أداة ما قبل التنفيذquestionsChangeUtil- معالج تغيير الأسئلةcomparisonType- إعداد نوع المقارنة
إنشاء تقارير بأحجام صفحات مختلفة
كيفية إنشاء تقرير يحتوي على تقارير فرعية بأحجام صفحات مختلفة باستخدام JasperReports
يمكنك تنفيذ هذا النوع من التقارير بسهولة باستخدام JasperReports من خلال الخطوات التالية:
استخدام تقارير Book لأحجام صفحات متعددة
- إنشاء تقرير Book: ابدأ بتقرير رئيسي من النوع Book Report
- إضافة استعلام SQL: اكتب استعلام SQL بسيطاً مع حقول للعرض الشرطي
- إضافة أجزاء التقرير: استخدم Add Part to Content لإضافة كل تقرير فرعي
- ضبط شروط الطباعة: استخدم Print When Expression لكل جزء
- تمرير المعاملات: عرّف جميع المعاملات المطلوبة ومررها إلى كل جزء
مثال: صفحات A4 و A3 مختلطة
أنشئ قالب طباعة بجزأين بأحجام صفحات مختلفة (A4 وA3)، يُعرض بناءً على شرط من حقل ملاحظات المستند. يمكن أن يحتوي كل جزء على تقاريره الفرعية.
مرجع: طلب تطوير SRDRQ05261
إيقاف التقارير التي تجاوزت وقت التنفيذ
إيقاف التقارير التي تجاوزت وقت تنفيذ معين
عند تشغيل تقارير كبيرة، قد يؤدي الضغط على النظام أحياناً إلى عدم قدرة المستخدمين الجدد على تسجيل الدخول. وفي بعض الحالات، نضطر إلى إيقاف خدمة Tomcat وإعادة تشغيلها لحل المشكلة.
لذا تم إنشاء أداة تقوم بإيقاف أي تقرير تجاوز وقت تنفيذ معين (مثلاً 10 أو 120 ثانية)، دون الحاجة لإعادة تشغيل الخادم.
خطوات الإعداد
- تعديل
nama.properties:
kill-reports-running-more-than-seconds=120الرقم 120 يمثل الحد الأقصى المسموح به من الثواني لتنفيذ التقرير.
- تطبيق الإعداد: انتقل إلى:
/basic-services/monitorlogin?reload-config-and-kill-running-reports=true
يُعيد هذا تحميل الإعداد ويوقف جميع التقارير التي تجاوزت الحد الزمني.
مرجع: طلب تطوير ECPADR00932
إضافة خطوط إضافية لطباعة PDF
يدعم نظام Nama ERP Times New Roman افتراضياً للنصوص العربية. لاستخدام خطوط تدعم العربية بشكل مختلف (Cairo، Amiri، Droid Arabic Naskh، إلخ):
1. إضافة الخط في Jaspersoft Studio
- افتح Jaspersoft Studio
- اذهب إلى
Window > Preferences - انتقل إلى
Jaspersoft Studio > Fonts - انقر على Add
2. إعداد خصائص الخط
في مربع حوار Font Family:
- اختر ملف (ملفات) الخط
.ttfأو.otf - ضع علامة ✅ على Embed this font in PDF documents
- اضبط PDF Encoding على:
Identity-H

- انقر على Finish
3. تصدير الخط كملف JAR
- بعد إضافة الخط، انقر على Export
- احفظ ملف
.jarالمولَّد
4. نشر ملف JAR للخط في Tomcat
- انسخ ملف
.jarالمصدَّر إلى مجلدtomcat/lib - أعد تشغيل خدمة Tomcat
لتطبيقات نقطة البيع (POS)
لتطبيقات POS، ارفع ملف JAR للخط المصدَّر إلى حقل Jasper Fonts في إعدادات واجهة نقطة البيع (POS UI Settings). سينشئ النظام تلقائياً ملف امتداد الخط في مجلد jasper-fonts-extension:
- عند بدء تشغيل تطبيق POS
- عند حفظ سجل إعدادات واجهة نقطة البيع
مهم: بعد تحديث أجهزة POS إلى إصدار يدعم jasper-fonts-extension، يجب إعادة حفظ سجل إعدادات واجهة نقطة البيع لتشغيل نشر ملف الخط على كل جهاز.
5. استخدام الخط في التقارير
- عيّن عائلة الخط الجديدة لحقول النص في ملفات
.jrxml - سيتم تضمين الخط وعرضه بشكل صحيح في ملفات PDF، بما فيها الأحرف العربية
أفضل الممارسات
1. إنشاء المتغيرات للكائنات المعقدة
عند العمل مع حسابات الأسعار أو روابط التقارير، أنشئ متغيرات:
<variable name="price" class="java.lang.Object" calculation="No Calculation Function">
<initialValueExpression>
NamaRep.priceCalculator().item($F{item}).qty($F{qty}).price()
</initialValueExpression>
</variable>2. الأمان من القيم الفارغة
استخدم دائماً الدوال الآمنة من القيم الفارغة عند التعامل مع قيم محتملة الفراغ:
NamaRep.zeroIfNull(value) // بدلاً من الوصول المباشر للقيمة
NamaRep.nameOrCode(code, name1, name2) // الرجوع إلى الكود3. التوطين
استخدم دائماً دوال الترجمة للنصوص التي يراها المستخدم:
NamaRep.translate(enumValue) // لقيم enum
NamaRep.name(arabic, english) // للحقول ثنائية اللغة4. تحسين الأداء
- خزّن الحسابات المعقدة في متغيرات
- استخدم
copyParams()عند ربط التقارير لتجنب تكرار المعاملات - جمّع استعلامات SQL عند الإمكان
5. قيود الأمان
طبّق دائماً قيود الأمان عند الاستعلام عن بيانات حساسة:
SELECT * FROM Account acc
WHERE acc.active = true
AND $P!{SECURITY_CONSTRAINTS}الترحيل من الدوال القديمة
الاستبدالات الشائعة عند تحديث التقارير القديمة:
| الدالة القديمة | الدالة الجديدة |
|---|---|
| الوصول المباشر للحقل | NamaRep.name(name1, name2) |
| تنسيق التاريخ يدوياً | NamaRep.datePattern() |
| استعلامات الأسعار المخصصة | NamaRep.priceCalculator() |
| الترجمة اليدوية | NamaRep.translate() |
استكشاف الأخطاء وإصلاحها
المشكلات الشائعة وحلولها
- النص العربي لا يظهر: تأكد من أن الخط يدعم العربية وأن ترميز PDF مضبوط على
Identity-H - استثناءات المؤشر الفارغ: استخدم الدوال الآمنة مثل
zeroIfNull() - حسابات الأسعار تُرجع قيمة فارغة: تحقق من توفير جميع المعاملات المطلوبة
- الروابط لا تعمل: تحقق من صحة نوع الكيان والمعرّف
- قيود الأمان لا تُطبَّق: تأكد من تطابق اسم المعامل تماماً في الاستعلام
- التحديد المتعدد لا يعمل: تحقق من ضبط خصائص
listوlistTypeبشكل صحيح - التقارير الفرعية لا تُحمَّل: تحقق من تطابق معرّف المعامل مع اسم التقرير الفرعي تماماً
مرجع الميزات المتقدمة
مسار المراجعة (سجل الإصدارات)
تتيح ميزة مسار المراجعة عرض سجل تغييرات مفصّل لأي سجل كيان في التقارير. هذا مفيد للامتثال وتتبع التعديلات وفهم كيفية تطور البيانات عبر الزمن.
دالة مسار المراجعة الأساسية
NamaRep.audit(entityType, id, versionNumber, actionType, language, outputFormat)المعاملات:
entityType- نوع الكيان (مثلاً "SalesInvoice"، "Customer")id- معرّف السجلversionNumber- رقم الإصدار للمقارنة (عادةً الإصدار الحالي)actionType- نوع الإجراء (عادةً "Update")language- لغة الإخراج:"arabic"أو"english"outputFormat- نوع التنسيق:"html"أو"text"
مثال - عرض مسار المراجعة بالعربية HTML:
NamaRep.audit($F{entityType}, $F{id}, $F{versionNumber}, "Update", "arabic", "html")مثال - عرض مسار المراجعة بالإنجليزية نصاً:
NamaRep.audit("Customer", $F{customerId}, $F{currentVersion}, "Update", "english", "text")ما يعرضه مسار المراجعة
يعرض مسار المراجعة:
- تغييرات الرأسية: تعديلات الحقول في السجل الرئيسي
- اسم الحقل
- القيمة القديمة
- القيمة الجديدة
- تغييرات أسطر التفاصيل: التغييرات على عناصر المجموعة (مثلاً أسطر الفاتورة)
- الأسطر المضافة
- الأسطر المحذوفة
- الأسطر المعدَّلة
- معلومات التعديل:
- من أجرى التغيير
- متى أُجري التغيير
تنسيقات الإخراج
تنسيق HTML:
- يُنتج جداول HTML منسقة مع تنسيق CSS
- يتضمن رؤوساً وأقساماً منظمة
- مثالي للعرض المضمّن في التقارير والبريد الإلكتروني
تنسيق النص:
- إخراج نصي عادي مع مسافة بادئة
- وصف التغيير سطراً بسطر
- مناسب للرسائل القصيرة SMS، والبريد الإلكتروني النصي، أو العروض البسيطة
خيارات اللغة
- العربية: جميع التسميات وأسماء الحقول بالعربية
- الإنجليزية: جميع التسميات وأسماء الحقول بالإنجليزية
ميزات متقدمة أخرى
للاطلاع على ميزات متقدمة إضافية، استشر فريق التطوير:
- تعبيرات التجميع:
NamaRep.groupExpression(field1, field2, field3) - بنّاء Order By للفرز المعقد
- أدوات التشفير وفك التشفير
- Values Holder للعمليات المعقدة
- مراجع التقرير مع الترتيب المخصص
- أدوات إنشاء الخرائط (Map)
- عمليات الملفات واسترجاعها
خلاصة
يوفر هذا الدليل تغطية شاملة لتطوير Jasper Reports في نظام Nama ERP. تقدم فئة NamaRep الأداتية أدوات قوية لإنشاء تقارير محلّية وآمنة وغنية بالميزات تتكامل بسلاسة مع نظام ERP. ارجع دائماً إلى هذا الدليل عند تطوير تقارير جديدة أو صيانة القائمة منها.
للحصول على دعم إضافي أو للاطلاع على ميزات غير موثقة، استشر فريق تطوير Nama ERP.