← الأساسيات / حزم تطوير البرمجيات (SDK)
الترحيل من نظام آخر
انقل الدفاتر المحاسبية للشركة في استدعاء واحد - دليل الحسابات، الشركاء، أرصدة الافتتاح أو السجل التاريخي الكامل، الفواتير المفتوحة، الأصول الثابتة، والمخزون.
عندما تنتقل أي شركة إلى Nordlet من برنامج محاسبي آخر، فإن دفاترها لا تبدأ من الصفر. تأخذ أداة استيراد الدفاتر التاريخية كل ما يتركه لك النظام القديم وتكتبه في استدعاء واحد ومعاملة قاعدة بيانات واحدة (database transaction): فإذا فشل صف واحد في أي تحقق، فلن يتم تخزين أي شيء. ويمكن تشغيل الحزمة نفسها عبر نقطة نهاية مخصصة للتحقق أولاً، والتي تقوم بتنفيذ عمليات التحقق كافة والتراجع عنها عند وجود خطأ.
POST /v1/migration/books/validate # يتحقق من كل شيء، ولا يكتب شيئاً
POST /v1/migration/books/import # يكتب كل شيء أو لا يكتب شيئاً
يحتوي تطبيق الويب على الزرين نفسيهما ضمن الحساب (Account) ← الترحيل (Migration) (حيث يمكنك لصق كود JSON أو رفع ملف). يحتاج مفتاح واجهة برمجة التطبيقات (API key) إلى صلاحية ledger:write بالإضافة إلى نطاق الكتابة (write scope) الخاص بكل قسم تقوم تضمينه (partners:write، catalog:write، sales:write، purchases:write، assets:write، inventory:write). تقبل كلتا نقطتي النهاية حثيث طلبات بحجم يصل إلى 32 ميغابايت.
تاريخ التحويل (Cut-over date)
اختر تاريخ التحويل (cut-over date): وهو اليوم الأول الذي تبدأ فيه إدارة الشركة على نظام Nordlet. كل ما يسبق هذا التاريخ يظل في النظام القديم (أو يتم جلبه كسجل تاريخي، انظر أدناه)، وكل ما يأتي بدءاً من ذلك اليوم يتم إدخاله في Nordlet عبر نقاط النهاية العادية. جميع المبالغ الواردة في حزمة البيانات تعتبر "كما في اليوم السابق لتاريخ التحويل": ميزان المراجعة الختامي، الفواتير التي لم تسدد بعد، المخزون الموجود على الأرفف، والأصول المثبتة في السجلات.
قبل إجراء الاستيراد، قم بتنفيذ الخطوات التالية في Nordlet:
- أنشئ الشركة وطبق نموذج دليل الحسابات (
ledger/accounts/apply-template)، أو اذكر الحسابات التي تحتاجها في قسمaccountsالخاص بالحزمة. - أنشئ مستودعاً واحداً على الأقل (
inventory/warehouses/create) إذا كنت ستستورد مخزوناً. - قم بتشغيل الحزمة عبر
migration/books/validateإلى أن تُظهر أن النطاق خالي من الأخطاء وتقوم بقبول تحذيراتها.
الحزمة (Package)
كل قسم اختياري؛ قم بتضمين الأقسام التي تملك بياناتها. تعتمد كافة المراجع بين الأقسام على الرمز (code) (رمز الحساب، رمز الشريك، رمز الصنف، رمز مجموعة الأصول، رمز المستودع)، ويمكن أن يشير الرمز إما إلى سجل موجود مسبقاً في Nordlet أو سجل تم إنشاؤه بواسطة قسم سابق في الحزمة نفسها.
{
"cutoverDate": "2026-01-01",
"source": "Rivilė GAMA",
"accounts": [
{ "code": "6210", "name": "Advertising expenses", "type": "expense", "parentCode": "6" }
],
"partners": [
{ "code": "301111222", "name": "UAB Klientas", "vatCode": "LT100001112223", "isCustomer": true },
{ "code": "302222333", "name": "UAB Tiekėjas", "isCustomer": false, "isSupplier": true }
],
"items": [
{ "code": "SKU-1", "name": "Widget", "type": "product", "unit": "vnt", "vatRatePercent": "21" }
],
"assetGroups": [
{ "code": "TRANSP", "name": "Vehicles", "assetAccountCode": "1230", "depreciationAccountCode": "1239",
"defaultUsefulLifeMonths": 60 }
],
"openingBalances": {
"balancingAccountCode": "3410",
"entries": [
{ "accountCode": "2710", "debit": "5000.00" },
{ "accountCode": "2410", "debit": "1500.00" },
{ "accountCode": "2040", "debit": "300.00" },
{ "accountCode": "1230", "debit": "12000.00" },
{ "accountCode": "1239", "credit": "2400.00" },
{ "accountCode": "4430", "credit": "700.00" },
{ "accountCode": "3010", "credit": "10000.00" }
]
},
"openReceivables": [
{ "partnerCode": "301111222", "number": "SF-1050", "issueDate": "2025-12-10", "dueDate": "2026-01-09",
"grossTotal": "1210.00", "vatTotal": "210.00" },
{ "partnerCode": "301111222", "number": "SF-1049", "issueDate": "2025-11-20",
"grossTotal": "500.00", "outstanding": "290.00" }
],
"openPayables": [
{ "partnerCode": "302222333", "documentNumber": "T-77", "documentDate": "2025-12-15", "grossTotal": "700.00" }
],
"fixedAssets": [
{ "groupCode": "TRANSP", "code": "CAR-1", "name": "Delivery van", "acquisitionDate": "2025-01-01",
"acquisitionCost": "12000.00", "accumulatedDepreciation": "2400.00", "depreciatedMonths": 12 }
],
"stock": [
{ "itemCode": "SKU-1", "quantity": "30", "unitCost": "10" }
]
}
المبالغ عبارة عن نصوص عشرية (decimal strings)، تماماً كما هو الحال في كافة أجزاء واجهة برمجة التطبيقات. الحقل source هو تسمية حرة تظهر في وصف قيد الافتتاح وفي ملاحظات الفواتير المرحلة.
حقل accounts
صفوف دليل الحسابات: code (الرمز)، name (الاسم)، type (النوع: asset [أصل]، liability [التزام]، equity [حقوق ملكية]، income [إيراد]، expense [مصروف])، بالإضافة إلى الحقلين الاختياريين parentCode (رمز الحساب الأب) وisPostable (قابل للترحيل). تُترك الحسابات الموجودة مسبقاً دون تغيير ويُحتسب عددها كـ existing. استخدم هذا الخيار عندما يختلف دليل حسابات النظام القديم عن النموذج، أو تخطه وطبق النموذج أولاً.
الحقلان partners و items
العملاء، الموردون، وأصناف الكتالوج، وتتم جدولتها باستخدام الحقل code. في ليتوانيا، يكون رمز الشريك عادةً هو رقم تسجيل الشركة؛ أما بالنسبة للأفراد فيمكن استخدام أي رمز فريد داخل الشركة. يتم تخطي الرموز الموجودة مسبقاً دون تحديثها. تقبل الأصناف الحقول الآتية: type (النوع: product [منتج] أو service [خدمة])، unit (الوحدة)، barcode (الباركود)، vatRatePercent (نسبة ضريبة القيمة المضافة)، salePriceExclVat (سعر البيع غير شامل ضريبة القيمة المضافة)، وpurchasePriceExclVat (سعر الشراء غير شامل ضريبة القيمة المضافة).
حقل openingBalances
ميزان المراجعة الختامي للنظام القديم، صف واحد لكل حساب: accountCode مع إما debit (مدين) أو credit (دائن). تُرحل الصفوف في شكل قيد يومية واحد مؤرخ بالتاريخ openingBalances.date (الافتراضي هو تاريخ التحويل) مع نوع مستند migration_opening. يجب أن تشير الصفوف إلى حسابات قابلة للترحيل (postable accounts).
يجب أن يكون القيد متوازناً. إذا كان ميزان المراجعة للنظام القديم غير متوازن - بسبب التقريب، أو وجود أرباح لم تُقفل قط في حقوق الملكية، أو حساب مفقود - فقم بتوفير balancingAccountCode (غالباً ما يكون الأرباح المحتجزة، 3410 في النموذج الليتواني) وسيتم ترحيل الفرق إليه؛ وتعرض الاستجابة المبلغ تحت اسم balancingAmount.
يمكن السماح بوجود قيد افتتاح واحد فقط لكل شركة. سيتم رفض أي عملية استيراد ثانية تحتوي على openingBalances (برمز خطأ 409). أما التصحيحات اللاحقة فتتم عبر قيود يومية يدوية عادية (ledger/journal/transactions/create)؛ ونظراً لأن القيود المرحلة غير قابلة للتعديل (immutable)، فإن القيد الأصلي يظل كما تم استيراده.
حقل journal - السجل التاريخي الكامل بدلاً من الأرصدة أو بالإضافة إليها
إذا كنت تريد جلب معاملات النظام القديم إلى Nordlet (حتى تعمل التقارير الخاصة بالفترات السابقة)، فأرسلها هنا: كائن واحد لكل معاملة يتضمن date (التاريخ)، ووصفاً اختيارياً description ومرجعاً reference، بالإضافة إلى entries تتكون من accountCode + debit/credit. يجب أن تكون كل معاملة متوازنة بذاتها. ويتم ترحيلها بنوع مستند migration.
يجب أن تكون تواريخ المعاملات قبل تاريخ التحويل. وعندما تحتوي الحزمة أيضاً على openingBalances، يجب أن يكون تاريخ السجل التاريخي في أو بعد openingBalances.date - والنمط المعتاد هو وضع الأرصدة في بداية السنة المالية السابقة مضافاً إليها معاملات تلك السنة، مع جعل تاريخ التحويل في اليوم الأول من السنة الحالية. لا ترسل الأرصدة والسجل التاريخي لنفس الفترة معاً: وإلا سيتم احتساب الأرصدة مرتين.
يجب أن يكون كل شهر تتأثر به أرصدة الافتتاح أو السجل التاريخي فترة محاسبية مفتوحة (وإلا سيظهر الخطأ 409).
الحقلان openReceivables و openPayables
الفواتير التي ظلت غير مسددة (كلياً أو جزئياً) وقت إجراء التحويل. يتم إنشاء هذه الفواتير كفواتير مبيعات مصدرة (issued) وفواتير مشتريات مسجلة (registered) بحيث تكون paidAmount = grossTotal − outstanding، لكي تعمل ميزة مطابقة الحسابات البنكية (bank/transactions/match، bank/transactions/suggest-matches)، وتقرير أعمار الديون، وخطافات ويب المدفوعات (payment webhooks) عليها تماماً مثل أي فاتورة أخرى.
- القيمة الافتراضية للحقل
outstandingهيgrossTotal؛ والقيمة الافتراضية لـvatTotalهي0(ويتم استنتاج الصافي). - القيمة الافتراضية لـ
dueDateهي تاريخ المستند. - القيمة الافتراضية للعملة
currencyهي عملة الفواتير الخاصة بالشركة. بالنسبة لأي عملة أخرى غير عملة الأساس للشركة، فإن الحقلfxRateمطلوب - وهو يمثل وحدات تلك العملة مقابل وحدة واحدة من عملة الأساس، بنفس الاصطلاح المتبع في باقي واجهة برمجة التطبيقات - ويتم تخزينه على الفاتورة لكي تقوم المدفوعات اللاحقة بحساب فرق أسعار الفائدة والصرف المحقق بشكل صحيح. - رقم فاتورة المبيعات
numberهو الرقم الكامل في النظام القديم ويجب أن يكون فريداً داخل الشركة. أما فواتير المشتريات فتكون فريدة لكل شريك ولكلdocumentNumber. - لا يتم ترحيل الفواتير مرة أخرى: فرصد المدينين/الدائنين الخاص بها يشكل بالفعل جزءاً من أرصدة الافتتاح. وهي مرتبطة بقيد الافتتاح، ولهذا السبب يتطلب الحقل
openPayablesوجود الحقلopeningBalancesفي الحزمة نفسها. - لا يتم استيراد تفاصيل بنود الفاتورة؛ بل تحمل الفاتورة الإجماليات فقط. ويظل النظام القديم هو المصدر لتفاصيل البنود ولسجلات ضريبة القيمة المضافة للفترات السابقة لتاريخ التحويل.
إذا كان النظام القديم يتتبع أرصدة العملاء بدون بنود فواتير مفتوحة، فأنشئ فاتورة واحدة لكل شريك تمثل الرصيد (على سبيل المثال برقم OB-301111222) حتى يمكن تسويتها.
استمرار الترقيم. عندما يكون رقم فاتورة المبيعات المستوردة على الصيغة PREFIX-N ويقع تاريخ إصدارها في سنة التحويل، يتم تعيين تسلسل الأرقام لتلك البادئة وتلك السنة إلى N + 1 (ولا يتم تخفيضها أبداً). تعرض الاستجابة حقل numberSeries الناتج؛ أما بالنسبة للحالات الأخرى فيمكنك تعيين التسلسل بنفسك باستخدام reference/series/create ({ documentType: "sale_invoice", prefix, year, startAt }).
الحقلان assetGroups و fixedAssets
تنتقل الأصول الثابتة مع إهلاكها حتى تاريخه: acquisitionCost (تكلفة الاستحواذ)، salvageValue (القيمة التخريدية)، accumulatedDepreciation (مجمع الإهلاك)، depreciatedMonths (الأشهر المهلكة) و usefulLifeMonths (العمر الإنتاجي بالأشهر، أو القيمة الافتراضية للمجموعة). تستمر عملية القسط الثابت (assets/depreciation/post) من القيمة المتبقية على مدى الأشهر المتبقية. والأصول التي يساوي فيها مجمع الإهلاك قيمة الإهلاك القابلة للاستهلاك يتم إنشاؤها بحالة fully_depreciated (مهلكة بالكامل). لا يتم ترحيل أي شيء - حيث تشكل التكلفة ومجمع الإهلاك جزءاً من أرصدة الافتتاح.
تتم جدوللة المجموعات باستخدام code وتحتاج إلى assetAccountCode (حساب الأصل) و depreciationAccountCode (حساب الإهلاك، وحسابه الافتراضي للمصروف هو 6206).
حقل stock
المخزون المتوفر لكل صنف: itemCode، quantity (الكمية)، unitCost (تكلفة الوحدة باليورو) واختيارياً warehouseCode (المستودع الافتراضي)، بالإضافة إلى lotNumber (رقم التشغيلة) و expiryDate (تاريخ الانتهاء) للأصناف التي يتم تتبعها بالتشغيلات أو الأرقام التسلسلية. يصبح كل صف حركة مخزون واردة مؤرخة في تاريخ التحويل بنوع مستند migration ويبدأ تطبيق طبقة الوارد أولاً يصرف أولاً (FIFO) بتلك التكلفة. لا يتم ترحيل أي شيء - فقيمة المخزون هي جزء من أرصدة الافتتاح.
عمليات التحقق والتحذيرات (Checks and warnings)
تفشل نقطة نهاية التحقق (برمز خطأ 422) في حالة وجود حسابات مفقودة، حسابات غير قابلة للترحيل، قيود غير متوازنة، رموز شريك/صنف/مجموعة/مستودع غير معروفة، رموز أو أرماج مكررة داخل الحزمة، مبالغ مستحقة تتجاوز الإجمالي الإجمالي، مجمع إهلاك يتجاوز القيمة القابلة للإهلاك، أو غياب أسعار الصرف. الأرقام أو الرموز الموجودة مسبقاً في Nordlet تعطي خطأ 409.
علاوة على ذلك، تقوم كلتا نقطتي النهاية بمقارنة الدفاتر الفرعية بمدخلات الدفتر العام الواردة في الحزمة نفسها وإرجاع الاختلافات في شكل warnings (تحذيرات) وليست أخطاء:
- إجمالي المبالغ المستحقة في
openReceivablesمقابل الرصيد الموجود في حساب المدينين (قاعدة الترحيلsales.receivable، و2410افتراضياً)؛ - إجمالي المبالغ المستحقة في
openPayablesمقابل حساب الدائنين (purchases.payables، و4430افتراضياً)؛ - إجمالي تكلفة
stockمقابل حساب المخزون (inventory.stock، و2040افتراضياً)؛ - لكل مجموعة أصول، مقارنة تكلفة الأصول مقابل حساب أصول المجموعة ومجمع إهلاكها مقابل حساب الإهلاك.
يعني وجود تحذير أن الدفتر الفرعي والدفتر العام للنظام القديم غير متطابقين. قم بإصلاح الحزمة (أو قبول الفرق عن وعي) قبل إجراء الاستيراد.
الاستجابة (The response)
{
"dryRun": false,
"cutoverDate": "2026-01-01",
"accounts": { "created": 1, "existing": 0 },
"partners": { "created": 2, "existing": 0 },
"items": { "created": 1, "existing": 0 },
"assetGroups": { "created": 1, "existing": 0 },
"openingBalances": { "journalTransactionId": "…", "date": "2026-01-01", "entries": 8,
"debitTotal": "18800.00", "creditTotal": "18800.00", "balancingAmount": "5700.00" },
"journal": { "transactions": 0, "entries": 0 },
"openReceivables": { "created": 2, "outstandingTotal": "1500.00" },
"openPayables": { "created": 1, "outstandingTotal": "700.00" },
"fixedAssets": { "created": 1, "costTotal": "12000.00", "accumulatedDepreciationTotal": "2400.00" },
"stock": { "movements": 1, "costTotal": "300.00" },
"numberSeries": [],
"warnings": []
}
تشير القيمة dryRun: true إلى تشغيل عملية تحقق تجريبية؛ حيث تكون قيمة journalTransactionId في هذه الحالة null. يتم تسجيل عملية الاستيراد في سجل التدقيق (audit log) تحت اسم migration.imported مع نفس الملخص.
بعد الاستيراد (After the import)
- قم بإغلاق الفترات السابقة لتاريخ التحويل (
ledger/periods/lock) حتى لا يتم ترحيل أي شيء إلى السجل التاريخي المرحل عن طريق الخطأ. - تحقق من ميزان المراجعة والميزانية العمومية اعتباراً من تاريخ التحويل مقارنة بالتقارير الختامية للنظام القديم.
- استمر في سير العمل العادي: إصدار الفواتير، استيراد كشوفات الحسابات البنكية، مطابقة المدفوعات - حيث تتم تسوية الفواتير المفتوحة المرحلة تماماً مثل أي فاتورة أخرى.
الأمور التي لا تغطيها أداة الاستيراد: بنود الفواتير وسجلات ضريبة القيمة المضافة للفترات السابقة (احتفظ بها في النظام القديم أو أرشيفه)، سجل الرواتب والأجور، والمستندات بخلاف الفواتير (طلبات الشراء، بوليصات الشحن، العقود).