Initial commit: standalone Django accounting API with admin JWT authorization
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
103
accounting/seeding.py
Normal file
103
accounting/seeding.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""Default chart of accounts and company settings (zeroed opening balances).
|
||||
|
||||
Shared by the initial data migration and the runtime "reset" endpoint so both
|
||||
produce an identical clean starting point with no demo business data.
|
||||
"""
|
||||
|
||||
# (code, name, type, is_group, parent_code)
|
||||
DEFAULT_ACCOUNTS = [
|
||||
('10', 'داراییهای جاری', 'asset', True, None),
|
||||
('1001', 'صندوق', 'asset', False, '10'),
|
||||
('1002', 'بانک ملت', 'asset', False, '10'),
|
||||
('1003', 'بانک سامان', 'asset', False, '10'),
|
||||
('1004', 'حسابهای دریافتنی (مشتریان)', 'asset', False, '10'),
|
||||
('1005', 'موجودی کالا', 'asset', False, '10'),
|
||||
('1006', 'پیشپرداختها', 'asset', False, '10'),
|
||||
|
||||
('15', 'داراییهای ثابت', 'asset', True, None),
|
||||
('1501', 'اموال و تجهیزات', 'asset', False, '15'),
|
||||
('1502', 'استهلاک انباشته', 'asset', False, '15'),
|
||||
|
||||
('20', 'بدهیهای جاری', 'liability', True, None),
|
||||
('2001', 'حسابهای پرداختنی (تأمینکنندگان)', 'liability', False, '20'),
|
||||
('2002', 'مالیات بر ارزش افزوده پرداختنی', 'liability', False, '20'),
|
||||
('2003', 'حقوق پرداختنی', 'liability', False, '20'),
|
||||
('2004', 'بیمه پرداختنی', 'liability', False, '20'),
|
||||
('2005', 'بدهی به مالکان (کیف پول)', 'liability', False, '20'),
|
||||
('2006', 'بدهی به مشتریان (کیف پول)', 'liability', False, '20'),
|
||||
|
||||
('30', 'حقوق صاحبان سهام', 'equity', True, None),
|
||||
('3001', 'سرمایه', 'equity', False, '30'),
|
||||
('3002', 'سود انباشته', 'equity', False, '30'),
|
||||
|
||||
('40', 'درآمدها', 'income', True, None),
|
||||
('4001', 'درآمد فروش', 'income', False, '40'),
|
||||
('4002', 'درآمد خدمات', 'income', False, '40'),
|
||||
|
||||
('50', 'هزینهها', 'expense', True, None),
|
||||
('5001', 'بهای تمامشده کالای فروشرفته', 'expense', False, '50'),
|
||||
('5002', 'هزینه حقوق و دستمزد', 'expense', False, '50'),
|
||||
('5003', 'هزینه اجاره', 'expense', False, '50'),
|
||||
('5004', 'هزینه آب، برق و گاز', 'expense', False, '50'),
|
||||
('5005', 'هزینه تبلیغات', 'expense', False, '50'),
|
||||
('5006', 'هزینه استهلاک', 'expense', False, '50'),
|
||||
('5007', 'سهم مالکان از فروش', 'expense', False, '50'),
|
||||
]
|
||||
|
||||
DEFAULT_SETTINGS = {
|
||||
'name': 'مجموعه تفریحی فانزون',
|
||||
'economic_code': '',
|
||||
'fiscal_year': '1404',
|
||||
'base_currency': 'تومان',
|
||||
'tax_rate': 10,
|
||||
'address': '',
|
||||
'phone': '',
|
||||
}
|
||||
|
||||
# Mapping of CompanySettings FK attribute -> account code.
|
||||
SETTINGS_ACCOUNT_MAP = {
|
||||
'bank_account_id': '1002',
|
||||
'owner_payable_account_id': '2005',
|
||||
'customer_payable_account_id': '2006',
|
||||
'owner_share_account_id': '5007',
|
||||
'sales_income_account_id': '4001',
|
||||
}
|
||||
|
||||
|
||||
def create_default_accounts(Account):
|
||||
"""Creates the standard chart of accounts with zeroed balances.
|
||||
|
||||
Returns a dict mapping account code -> created Account instance.
|
||||
"""
|
||||
by_code = {}
|
||||
# First pass: create all accounts without parents.
|
||||
for code, name, type_, is_group, _parent in DEFAULT_ACCOUNTS:
|
||||
by_code[code] = Account.objects.create(
|
||||
code=code, name=name, type=type_, is_group=is_group, opening_balance=0,
|
||||
)
|
||||
# Second pass: wire up parents.
|
||||
for code, _name, _type, _is_group, parent_code in DEFAULT_ACCOUNTS:
|
||||
if parent_code:
|
||||
account = by_code[code]
|
||||
account.parent = by_code[parent_code]
|
||||
account.save(update_fields=['parent'])
|
||||
return by_code
|
||||
|
||||
|
||||
def ensure_company_settings(CompanySettings, accounts_by_code):
|
||||
"""Creates (or resets) the singleton settings with the default mapping."""
|
||||
defaults = dict(DEFAULT_SETTINGS)
|
||||
for attr, code in SETTINGS_ACCOUNT_MAP.items():
|
||||
account = accounts_by_code.get(code)
|
||||
defaults[attr] = account.id if account else None
|
||||
CompanySettings.objects.update_or_create(id=1, defaults=defaults)
|
||||
|
||||
|
||||
def seed_default_data(Account, CompanySettings):
|
||||
"""Seeds chart of accounts + settings if no accounts exist yet."""
|
||||
if Account.objects.exists():
|
||||
accounts_by_code = {a.code: a for a in Account.objects.all()}
|
||||
else:
|
||||
accounts_by_code = create_default_accounts(Account)
|
||||
ensure_company_settings(CompanySettings, accounts_by_code)
|
||||
return accounts_by_code
|
||||
Reference in New Issue
Block a user