124 lines
6.8 KiB
Python
124 lines
6.8 KiB
Python
from django.core.management.base import BaseCommand
|
|
from django_ledger.models import EntityModel, ChartOfAccountModel, AccountModel
|
|
from django.contrib.auth import get_user_model
|
|
|
|
User = get_user_model()
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Creates Chart of Accounts for Deepseek entity'
|
|
|
|
def handle(self, *args, **options):
|
|
# Get or create admin user
|
|
admin_user = User.objects.filter(is_superuser=True).first()
|
|
if not admin_user:
|
|
self.stdout.write(self.style.ERROR('No admin user found!'))
|
|
return
|
|
|
|
# Get or create Deepseek entity with minimal valid fields
|
|
entity, created = EntityModel.objects.get_or_create(
|
|
name='Deepseek',
|
|
defaults={
|
|
'admin': admin_user,
|
|
'fy_start_month': 1, # January fiscal year start
|
|
'accrual_method': True # Using accrual accounting
|
|
}
|
|
)
|
|
|
|
if created:
|
|
self.stdout.write(self.style.SUCCESS('Created Deepseek entity'))
|
|
else:
|
|
self.stdout.write(self.style.SUCCESS('Deepseek entity already exists'))
|
|
|
|
# Get or create Chart of Accounts
|
|
coa, created = ChartOfAccountModel.objects.get_or_create(
|
|
slug='deepseek-coa',
|
|
defaults={
|
|
'name': 'Deepseek Chart of Accounts',
|
|
'entity': entity,
|
|
'description': 'Standard COA for Deepseek automotive business'
|
|
}
|
|
)
|
|
|
|
if created:
|
|
self.stdout.write(self.style.SUCCESS('Created Chart of Accounts'))
|
|
else:
|
|
self.stdout.write(self.style.SUCCESS('Chart of Accounts already exists'))
|
|
|
|
# Account definitions with string role literals
|
|
ACCOUNTS = [
|
|
# Assets
|
|
('1010', 'Cash on Hand', 'الصندوق', 'asset_ca_cash'),
|
|
('1020', 'Bank', 'البنك', 'asset_ca_cash'),
|
|
('1030', 'Accounts Receivable', 'العملاء', 'asset_ca_receivable'),
|
|
('1040', 'Inventory (Cars)', 'مخزون السيارات', 'asset_ca_inventory'),
|
|
('1045', 'Spare Parts Inventory', 'مخزون قطع الغيار', 'asset_ca_inventory'),
|
|
('1050', 'Employee Advances', 'سُلف وأمانات الموظفين', 'asset_ca_other'),
|
|
('1060', 'Prepaid Expenses', 'مصروفات مدفوعة مقدماً', 'asset_ca_other'),
|
|
('1070', 'Notes Receivable', 'أوراق القبض', 'asset_ca_receivable'),
|
|
('2010', 'Lands', 'أراضي', 'asset_ppe_land'),
|
|
('2011', 'Buildings', 'مباني', 'asset_ppe_building'),
|
|
('2012', 'Company Vehicles', 'سيارات الشركة', 'asset_ppe_equipment'),
|
|
('2013', 'Equipment & Tools', 'أجهزة ومعدات', 'asset_ppe_equipment'),
|
|
('2014', 'Furniture & Fixtures', 'أثاث وديكور', 'asset_ppe_equipment'),
|
|
('2015', 'Other Fixed Assets', 'أصول ثابتة أخرى', 'asset_ppe_other'),
|
|
('2020', 'Long-term Investments', 'استثمارات طويلة الأجل', 'asset_lt_investments'),
|
|
('2030', 'Intangible Assets', 'أصول غير ملموسة', 'asset_lt_intangible'),
|
|
|
|
# Liabilities
|
|
('3010', 'Accounts Payable', 'الموردين', 'liability_cl_acc_payable'),
|
|
('3020', 'Notes Payable', 'أوراق الدفع', 'liability_cl_acc_payable'),
|
|
('3030', 'Short-term Loans', 'قروض قصيرة الأجل', 'liability_cl_debt'),
|
|
('3040', 'Employee Payables', 'السلف المستحقة', 'liability_cl_acc_payable'),
|
|
('3050', 'Accrued Expenses', 'مصروفات مستحقة', 'liability_cl_acc_expense'),
|
|
('3060', 'Accrued Taxes', 'ضرائب مستحقة', 'liability_cl_acc_expense'),
|
|
('3070', 'Provisions', 'مخصصات', 'liability_cl_acc_expense'),
|
|
('4010', 'Long-term Bank Loans', 'قروض طويلة الأجل', 'liability_lt_loans'),
|
|
('4020', 'Lease Liabilities', 'التزامات تمويلية', 'liability_lt_loans'),
|
|
('4030', 'Other Long-term Liabilities', 'التزامات أخرى طويلة الأجل', 'liability_lt_other'),
|
|
|
|
# Equity
|
|
('5010', 'Capital', 'رأس المال', 'equity_capital'),
|
|
('5020', 'Statutory Reserve', 'الاحتياطي القانوني', 'equity_retained'),
|
|
('5030', 'Retained Earnings', 'احتياطي الأرباح', 'equity_retained'),
|
|
('5040', 'Profit & Loss for the Period', 'أرباح وخسائر الفترة', 'equity_earnings'),
|
|
|
|
# Income
|
|
('6010', 'Car Sales', 'مبيعات السيارات', 'income_operating'),
|
|
('6020', 'After-Sales Services', 'إيرادات خدمات ما بعد البيع', 'income_operating'),
|
|
('6030', 'Car Rental Income', 'إيرادات تأجير سيارات', 'income_operating'),
|
|
('6040', 'Other Income', 'إيرادات أخرى', 'income_other'),
|
|
|
|
# Expenses
|
|
('7010', 'Cost of Goods Sold', 'تكلفة البضاعة المباعة', 'expense_cogs'),
|
|
('7015', 'Spare Parts Cost Consumed', 'تكلفة قطع الغيار المستهلكة', 'expense_cogs'),
|
|
('7020', 'Salaries & Wages', 'رواتب وأجور', 'expense_operating'),
|
|
('7030', 'Rent', 'إيجار', 'expense_operating'),
|
|
('7040', 'Utilities', 'كهرباء ومياه', 'expense_operating'),
|
|
('7050', 'Advertising & Marketing', 'دعاية وإعلان', 'expense_operating'),
|
|
('7060', 'Maintenance', 'صيانة', 'expense_operating'),
|
|
('7070', 'Operating Expenses', 'مصاريف تشغيلية', 'expense_operating'),
|
|
('7080', 'Depreciation', 'استهلاك أصول ثابتة', 'expense_depreciation'),
|
|
('7090', 'Fees & Taxes', 'رسوم وضرائب', 'expense_operating'),
|
|
('7100', 'Bank Charges', 'مصاريف بنكية', 'expense_operating'),
|
|
('7110', 'Other Expenses', 'مصاريف أخرى', 'expense_other'),
|
|
]
|
|
|
|
# Create accounts
|
|
created_count = 0
|
|
for code, name_en, name_ar, role in ACCOUNTS:
|
|
acc, created = AccountModel.objects.get_or_create(
|
|
coa=coa,
|
|
code=code,
|
|
defaults={
|
|
'name': name_en,
|
|
'name_ar': name_ar,
|
|
'role_default': role,
|
|
'active': True,
|
|
'balance_type': 'debit' if role.startswith(('asset', 'expense')) else 'credit'
|
|
}
|
|
)
|
|
if created:
|
|
created_count += 1
|
|
|
|
self.stdout.write(self.style.SUCCESS(f'Successfully created {created_count} accounts'))
|
|
self.stdout.write(self.style.SUCCESS(f'Total accounts in COA: {len(ACCOUNTS)}')) |