124 lines
6.7 KiB
Python
124 lines
6.7 KiB
Python
from django.core.management.base import BaseCommand
|
|
from django_ledger.models.entity import EntityModel
|
|
from django_ledger.models.chart_of_accounts import ChartOfAccountModel
|
|
from django_ledger.models.accounts import AccountModel
|
|
from django_ledger.models.roles import RoleModel
|
|
from django_ledger.models.balance_types import BalanceTypeModel
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Create the chart of accounts for the ChatGPT entity'
|
|
|
|
def handle(self, *args, **options):
|
|
# Step 1: Retrieve or create the entity
|
|
entity, created = EntityModel.objects.get_or_create(name="chatgpt")
|
|
if created:
|
|
self.stdout.write(self.style.SUCCESS("Entity 'chatgpt' created."))
|
|
else:
|
|
self.stdout.write(self.style.WARNING("Entity 'chatgpt' already exists."))
|
|
|
|
# Step 2: Retrieve or create the default Chart of Accounts
|
|
if hasattr(entity, 'default_coa') and entity.default_coa:
|
|
coa = entity.default_coa
|
|
self.stdout.write(self.style.WARNING("Default Chart of Accounts already exists."))
|
|
else:
|
|
coa = ChartOfAccountModel.objects.create(name="Default CoA", entity=entity)
|
|
entity.default_coa = coa
|
|
entity.save()
|
|
self.stdout.write(self.style.SUCCESS("Default Chart of Accounts created."))
|
|
|
|
# Step 3: Define the accounts to be created
|
|
accounts = [
|
|
(1010, 'Cash on Hand', 'الصندوق', 'asset'),
|
|
(1020, 'Bank', 'البنك', 'asset'),
|
|
(1030, 'Accounts Receivable', 'العملاء', 'asset'),
|
|
(1040, 'Inventory (Cars)', 'مخزون السيارات', 'asset'),
|
|
(1045, 'Spare Parts Inventory', 'مخزون قطع الغيار', 'asset'),
|
|
(1050, 'Employee Advances', 'سُلف وأمانات الموظفين', 'asset'),
|
|
(1060, 'Prepaid Expenses', 'مصروفات مدفوعة مقدماً', 'asset'),
|
|
(1070, 'Notes Receivable', 'أوراق القبض', 'asset'),
|
|
(2010, 'Lands', 'أراضي', 'asset'),
|
|
(2011, 'Buildings', 'مباني', 'asset'),
|
|
(2012, 'Company Vehicles', 'سيارات الشركة', 'asset'),
|
|
(2013, 'Equipment & Tools', 'أجهزة ومعدات', 'asset'),
|
|
(2014, 'Furniture & Fixtures', 'أثاث وديكور', 'asset'),
|
|
(2015, 'Other Fixed Assets', 'أصول ثابتة أخرى', 'asset'),
|
|
(2020, 'Long-term Investments', 'استثمارات طويلة الأجل', 'asset'),
|
|
(2030, 'Intangible Assets', 'أصول غير ملموسة', 'asset'),
|
|
(3010, 'Accounts Payable', 'الموردين', 'liability'),
|
|
(3020, 'Notes Payable', 'أوراق الدفع', 'liability'),
|
|
(3030, 'Short-term Loans', 'قروض قصيرة الأجل', 'liability'),
|
|
(3040, 'Employee Payables', 'السلف المستحقة', 'liability'),
|
|
(3050, 'Accrued Expenses', 'مصروفات مستحقة', 'liability'),
|
|
(3060, 'Accrued Taxes', 'ضرائب مستحقة', 'liability'),
|
|
(3070, 'Provisions', 'مخصصات', 'liability'),
|
|
(4010, 'Long-term Bank Loans', 'قروض طويلة الأجل', 'liability'),
|
|
(4020, 'Lease Liabilities', 'التزامات تمويلية', 'liability'),
|
|
(4030, 'Other Long-term Liabilities', 'التزامات أخرى طويلة الأجل', 'liability'),
|
|
(5010, 'Capital', 'رأس المال', 'equity'),
|
|
(5020, 'Statutory Reserve', 'الاحتياطي القانوني', 'equity'),
|
|
(5030, 'Retained Earnings', 'احتياطي الأرباح', 'equity'),
|
|
(5040, 'Profit & Loss for the Period', 'أرباح وخسائر الفترة', 'equity'),
|
|
(6010, 'Car Sales', 'مبيعات السيارات', 'income'),
|
|
(6020, 'After-Sales Services', 'إيرادات خدمات ما بعد البيع', 'income'),
|
|
(6030, 'Car Rental Income', 'إيرادات تأجير سيارات', 'income'),
|
|
(6040, 'Other Income', 'إيرادات أخرى', 'income'),
|
|
(7010, 'Cost of Goods Sold', 'تكلفة البضاعة المباعة', 'expense'),
|
|
(7015, 'Spare Parts Cost Consumed', 'تكلفة قطع الغيار المستهلكة', 'expense'),
|
|
(7020, 'Salaries & Wages', 'رواتب وأجور', 'expense'),
|
|
(7030, 'Rent', 'إيجار', 'expense'),
|
|
(7040, 'Utilities', 'كهرباء ومياه', 'expense'),
|
|
(7050, 'Advertising & Marketing', 'دعاية وإعلان', 'expense'),
|
|
(7060, 'Maintenance', 'صيانة', 'expense'),
|
|
(7070, 'Operating Expenses', 'مصاريف تشغيلية', 'expense'),
|
|
(7080, 'Depreciation', 'استهلاك أصول ثابتة', 'expense'),
|
|
(7090, 'Fees & Taxes', 'رسوم وضرائب', 'expense'),
|
|
(7100, 'Bank Charges', 'مصاريف بنكية', 'expense'),
|
|
(7110, 'Other Expenses', 'مصاريف أخرى', 'expense'),
|
|
]
|
|
|
|
# Mapping for role and balance_type
|
|
role_mapping = {
|
|
'asset': 'ASSET',
|
|
'liability': 'LIABILITY',
|
|
'equity': 'EQUITY',
|
|
'income': 'INCOME',
|
|
'expense': 'EXPENSE',
|
|
}
|
|
|
|
balance_type_mapping = {
|
|
'ASSET': 'DEBIT',
|
|
'LIABILITY': 'CREDIT',
|
|
'EQUITY': 'CREDIT',
|
|
'INCOME': 'CREDIT',
|
|
'EXPENSE': 'DEBIT',
|
|
}
|
|
|
|
# Step 4: Delete existing accounts in the CoA
|
|
existing_accounts = AccountModel.objects.filter(coa_model=coa)
|
|
count_deleted = existing_accounts.count()
|
|
existing_accounts.delete()
|
|
self.stdout.write(self.style.SUCCESS(f"Deleted {count_deleted} existing accounts."))
|
|
|
|
# Step 5: Create new accounts
|
|
for code, name_en, name_ar, role_slug in accounts:
|
|
role = RoleModel.objects.get(slug=role_slug)
|
|
balance_type = BalanceTypeModel.objects.get(role=role)
|
|
parent = None # Set to None for root accounts
|
|
|
|
# Determine parent-child relationships
|
|
if code in [1040, 1045, 2012, 2013, 2014, 2015, 2020, 2030]:
|
|
parent_code = code - 10 # Example logic for determining parent code
|
|
parent = AccountModel.objects.get(coa_model=coa, code=parent_code)
|
|
|
|
account = AccountModel.objects.create(
|
|
coa_model=coa,
|
|
code=code,
|
|
name=name_en,
|
|
arabic_name=name_ar,
|
|
role=role,
|
|
balance_type=balance_type,
|
|
parent=parent,
|
|
depth=parent.depth + 1 if parent else 0,
|
|
)
|
|
self.stdout.write(self.style.SUCCESS(f"Account {name_en} ({code}) created."))
|