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}"))