128 lines
9.7 KiB
Python
128 lines
9.7 KiB
Python
from django.core.management.base import BaseCommand, CommandError
|
|
from django_ledger.models import AccountModel, EntityModel, AccountRole, AccountType # تم التعديل هنا
|
|
|
|
class Command(BaseCommand):
|
|
help = 'ينشئ أو يحدث حسابات Django Ledger المحددة لكيان معين.'
|
|
|
|
def add_arguments(self, parser):
|
|
# إضافة وسيط لتحديد اسم الكيان
|
|
parser.add_argument(
|
|
'--entity_name',
|
|
type=str,
|
|
default='qemini', # اسم الكيان الافتراضي
|
|
help='اسم الكيان الذي سيتم ربط الحسابات به (افتراضي: qemini).'
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
entity_name = options['entity_name']
|
|
|
|
# البحث عن الكيان بناءً على الاسم المقدم
|
|
try:
|
|
entity = EntityModel.objects.get(name__iexact=entity_name)
|
|
self.stdout.write(self.style.SUCCESS(f"تم العثور على الكيان: {entity.name}"))
|
|
except EntityModel.DoesNotExist:
|
|
raise CommandError(f"لم يتم العثور على كيان باسم '{entity_name}'. يرجى التأكد من وجوده.")
|
|
except Exception as e:
|
|
raise CommandError(f"حدث خطأ أثناء جلب الكيان '{entity_name}': {e}")
|
|
|
|
# قائمة الحسابات المراد إنشاؤها
|
|
accounts_data = [
|
|
# الأصول (مدين)
|
|
{'code': '1010', 'name': 'Cash on Hand', 'role': AccountRole.CASH, 'balance_type': AccountType.DEBIT},
|
|
{'code': '1020', 'name': 'Bank', 'role': AccountRole.CASH, 'balance_type': AccountType.DEBIT},
|
|
{'code': '1030', 'name': 'Accounts Receivable', 'role': AccountRole.RECEIVABLE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '1040', 'name': 'Inventory (Cars)', 'role': AccountRole.INVENTORY, 'balance_type': AccountType.DEBIT},
|
|
{'code': '1045', 'name': 'Spare Parts Inventory', 'role': AccountRole.INVENTORY, 'balance_type': AccountType.DEBIT},
|
|
{'code': '1050', 'name': 'Employee Advances', 'role': AccountRole.OTHER_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '1060', 'name': 'Prepaid Expenses', 'role': AccountRole.OTHER_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '1070', 'name': 'Notes Receivable', 'role': AccountRole.RECEIVABLE, 'balance_type': AccountType.DEBIT},
|
|
|
|
{'code': '2010', 'name': 'Lands', 'role': AccountRole.FIXED_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '2011', 'name': 'Buildings', 'role': AccountRole.FIXED_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '2012', 'name': 'Company Vehicles', 'role': AccountRole.FIXED_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '2013', 'name': 'Equipment & Tools', 'role': AccountRole.FIXED_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '2014', 'name': 'Furniture & Fixtures', 'role': AccountRole.FIXED_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '2015', 'name': 'Other Fixed Assets', 'role': AccountRole.FIXED_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '2020', 'name': 'Long-term Investments', 'role': AccountRole.OTHER_ASSET, 'balance_type': AccountType.DEBIT},
|
|
{'code': '2030', 'name': 'Intangible Assets', 'role': AccountRole.INTANGIBLE_ASSET, 'balance_type': AccountType.DEBIT},
|
|
|
|
# الخصوم (دائن)
|
|
{'code': '3010', 'name': 'Accounts Payable', 'role': AccountRole.PAYABLE, 'balance_type': AccountType.CREDIT},
|
|
{'code': '3020', 'name': 'Notes Payable', 'role': AccountRole.PAYABLE, 'balance_type': AccountType.CREDIT},
|
|
{'code': '3030', 'name': 'Short-term Loans', 'role': AccountRole.OTHER_LIABILITY, 'balance_type': AccountType.CREDIT},
|
|
{'code': '3040', 'name': 'Employee Payables', 'role': AccountRole.OTHER_LIABILITY, 'balance_type': AccountType.CREDIT},
|
|
{'code': '3050', 'name': 'Accrued Expenses', 'role': AccountRole.OTHER_LIABILITY, 'balance_type': AccountType.CREDIT},
|
|
{'code': '3060', 'name': 'Accrued Taxes', 'role': AccountRole.OTHER_LIABILITY, 'balance_type': AccountType.CREDIT},
|
|
{'code': '3070', 'name': 'Provisions', 'role': AccountRole.PROVISION, 'balance_type': AccountType.CREDIT},
|
|
|
|
{'code': '4010', 'name': 'Long-term Bank Loans', 'role': AccountRole.LONG_TERM_DEBT, 'balance_type': AccountType.CREDIT},
|
|
{'code': '4020', 'name': 'Lease Liabilities', 'role': AccountRole.LONG_TERM_DEBT, 'balance_type': AccountType.CREDIT},
|
|
{'code': '4030', 'name': 'Other Long-term Liabilities', 'role': AccountRole.LONG_TERM_DEBT, 'balance_type': AccountType.CREDIT},
|
|
|
|
# حقوق الملكية (دائن)
|
|
{'code': '5010', 'name': 'Capital', 'role': AccountRole.EQUITY, 'balance_type': AccountType.CREDIT},
|
|
{'code': '5020', 'name': 'Statutory Reserve', 'role': AccountRole.RETAINED_EARNINGS, 'balance_type': AccountType.CREDIT},
|
|
{'code': '5030', 'name': 'Retained Earnings', 'role': AccountRole.RETAINED_EARNINGS, 'balance_type': AccountType.CREDIT},
|
|
{'code': '5040', 'name': 'Profit & Loss for the Period', 'role': AccountRole.RETAINED_EARNINGS, 'balance_type': AccountType.CREDIT},
|
|
|
|
# الإيرادات (دائن)
|
|
{'code': '6010', 'name': 'Car Sales', 'role': AccountRole.SALES, 'balance_type': AccountType.CREDIT},
|
|
{'code': '6020', 'name': 'After-Sales Services', 'role': AccountRole.SALES, 'balance_type': AccountType.CREDIT},
|
|
{'code': '6030', 'name': 'Car Rental Income', 'role': AccountRole.SALES, 'balance_type': AccountType.CREDIT},
|
|
{'code': '6040', 'name': 'Other Income', 'role': AccountRole.OTHER_INCOME, 'balance_type': AccountType.CREDIT},
|
|
|
|
# المصروفات (مدين)
|
|
{'code': '7010', 'name': 'Cost of Goods Sold', 'role': AccountRole.COST_OF_GOODS_SOLD, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7015', 'name': 'Spare Parts Cost Consumed', 'role': AccountRole.COST_OF_GOODS_SOLD, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7020', 'name': 'Salaries & Wages', 'role': AccountRole.OPERATING_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7030', 'name': 'Rent', 'role': AccountRole.OPERATING_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7040', 'name': 'Utilities', 'role': AccountRole.OPERATING_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7050', 'name': 'Advertising & Marketing', 'role': AccountRole.OPERATING_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7060', 'name': 'Maintenance', 'role': AccountRole.OPERATING_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7070', 'name': 'Operating Expenses', 'role': AccountRole.OPERATING_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7080', 'name': 'Depreciation', 'role': AccountRole.DEPRECIATION_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7090', 'name': 'Fees & Taxes', 'role': AccountRole.OTHER_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7100', 'name': 'Bank Charges', 'role': AccountRole.OTHER_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
{'code': '7110', 'name': 'Other Expenses', 'role': AccountRole.OTHER_EXPENSE, 'balance_type': AccountType.DEBIT},
|
|
]
|
|
|
|
created_count = 0
|
|
updated_count = 0
|
|
|
|
for acc_data in accounts_data:
|
|
try:
|
|
# البحث عن الحساب الموجود أو إنشاء حساب جديد
|
|
account, created = AccountModel.objects.get_or_create(
|
|
entity=entity,
|
|
code=acc_data['code'],
|
|
defaults={
|
|
'name': acc_data['name'],
|
|
'role': acc_data['role'], # تم التعديل هنا
|
|
'balance_type': acc_data['balance_type'] # تم التعديل هنا
|
|
}
|
|
)
|
|
|
|
if created:
|
|
created_count += 1
|
|
self.stdout.write(self.style.SUCCESS(f"تم إنشاء الحساب: {account.code} - {account.name}"))
|
|
else:
|
|
# إذا كان الحساب موجودًا، نقوم بتحديث اسمه ودوره ونوع رصيده إذا كان مختلفًا
|
|
if (account.name != acc_data['name'] or
|
|
account.role != acc_data['role'] or # تم التعديل هنا
|
|
account.balance_type != acc_data['balance_type']): # تم التعديل هنا
|
|
account.name = acc_data['name']
|
|
account.role = acc_data['role']
|
|
account.balance_type = acc_data['balance_type']
|
|
account.save()
|
|
updated_count += 1
|
|
self.stdout.write(self.style.WARNING(f"تم تحديث الحساب: {account.code} - {account.name}"))
|
|
else:
|
|
self.stdout.write(f"الحساب موجود بالفعل ولم يتطلب تحديث: {account.code} - {account.name}")
|
|
|
|
except Exception as e:
|
|
self.stdout.write(self.style.ERROR(f"خطأ في معالجة الحساب {acc_data['code']} - {acc_data['name']}: {e}"))
|
|
|
|
self.stdout.write(self.style.SUCCESS(f"\nعملية إنشاء/تحديث الحسابات اكتملت."))
|
|
self.stdout.write(self.style.SUCCESS(f"عدد الحسابات التي تم إنشاؤها حديثًا: {created_count}"))
|
|
self.stdout.write(self.style.SUCCESS(f"عدد الحسابات التي تم تحديثها: {updated_count}"))
|