diff --git a/account_utils.py b/account_utils.py index ed781c9..8eba3e0 100644 --- a/account_utils.py +++ b/account_utils.py @@ -190,26 +190,51 @@ def migrate_account_name(old_name: str, account_type: AccountType) -> str: # Default chart of accounts with hierarchical names DEFAULT_HIERARCHICAL_ACCOUNTS = [ # Assets - ("Assets:Cash", AccountType.ASSET, "Cash on hand"), ("Assets:Bank", AccountType.ASSET, "Bank account"), - ("Assets:Lightning:Balance", AccountType.ASSET, "Lightning Network balance"), + ("Assets:Bitcoin", AccountType.ASSET, "Bitcoin holdings"), + ("Assets:Bitcoin:Lightning", AccountType.ASSET, "Lightning Network balance"), + ("Assets:Bitcoin:OnChain", AccountType.ASSET, "On-chain Bitcoin wallet"), + ("Assets:Cash", AccountType.ASSET, "Cash on hand"), + ("Assets:FixedAssets:Equipment", AccountType.ASSET, "Equipment and machinery"), + ("Assets:FixedAssets:FarmEquipment", AccountType.ASSET, "Farm equipment"), + ("Assets:FixedAssets:Network", AccountType.ASSET, "Network infrastructure"), + ("Assets:FixedAssets:ProductionFacility", AccountType.ASSET, "Production facilities"), + ("Assets:Inventory", AccountType.ASSET, "Inventory and stock"), + ("Assets:Livestock", AccountType.ASSET, "Livestock and animals"), ("Assets:Receivable", AccountType.ASSET, "Money owed to the Castle"), + ("Assets:Tools", AccountType.ASSET, "Tools and hand equipment"), # Liabilities ("Liabilities:Payable", AccountType.LIABILITY, "Money owed by the Castle"), # Equity - ("Equity:MemberEquity", AccountType.EQUITY, "Member contributions"), - ("Equity:RetainedEarnings", AccountType.EQUITY, "Accumulated profits"), + ("Equity", AccountType.EQUITY, "Owner's equity and member contributions"), # Revenue (Income in Beancount terminology) - ("Income:Accommodation", AccountType.REVENUE, "Revenue from stays"), + ("Income:Accommodation:Guests", AccountType.REVENUE, "Revenue from guest accommodation"), ("Income:Service", AccountType.REVENUE, "Revenue from services"), ("Income:Other", AccountType.REVENUE, "Other revenue"), # Expenses - ("Expenses:Utilities", AccountType.EXPENSE, "Electricity, water, internet"), - ("Expenses:Food:Supplies", AccountType.EXPENSE, "Food and supplies"), - ("Expenses:Maintenance", AccountType.EXPENSE, "Repairs and maintenance"), - ("Expenses:Other", AccountType.EXPENSE, "Miscellaneous expenses"), + ("Expenses:Administrative", AccountType.EXPENSE, "Administrative expenses"), + ("Expenses:Construction:Materials", AccountType.EXPENSE, "Construction materials"), + ("Expenses:Furniture", AccountType.EXPENSE, "Furniture and furnishings"), + ("Expenses:Garden", AccountType.EXPENSE, "Garden supplies and materials"), + ("Expenses:Gas:Kitchen", AccountType.EXPENSE, "Kitchen gas"), + ("Expenses:Gas:Vehicle", AccountType.EXPENSE, "Vehicle gas and fuel"), + ("Expenses:Groceries", AccountType.EXPENSE, "Groceries and food"), + ("Expenses:Hardware", AccountType.EXPENSE, "Hardware and tools"), + ("Expenses:Housewares", AccountType.EXPENSE, "Housewares and household items"), + ("Expenses:Insurance", AccountType.EXPENSE, "Insurance premiums"), + ("Expenses:Kitchen", AccountType.EXPENSE, "Kitchen supplies and equipment"), + ("Expenses:Maintenance:Car", AccountType.EXPENSE, "Car maintenance and repairs"), + ("Expenses:Maintenance:Garden", AccountType.EXPENSE, "Garden maintenance"), + ("Expenses:Maintenance:Property", AccountType.EXPENSE, "Property maintenance and repairs"), + ("Expenses:Membership", AccountType.EXPENSE, "Membership fees"), + ("Expenses:Supplies", AccountType.EXPENSE, "General supplies"), + ("Expenses:Tools", AccountType.EXPENSE, "Tools and equipment"), + ("Expenses:Utilities:Electric", AccountType.EXPENSE, "Electricity"), + ("Expenses:Utilities:Internet", AccountType.EXPENSE, "Internet service"), + ("Expenses:WebHosting:Domain", AccountType.EXPENSE, "Domain registration"), + ("Expenses:WebHosting:Wix", AccountType.EXPENSE, "Wix hosting service"), ] diff --git a/migrations.py b/migrations.py index 80bd0c5..a170a73 100644 --- a/migrations.py +++ b/migrations.py @@ -452,3 +452,37 @@ async def m011_account_permissions(db): WHERE expires_at IS NOT NULL; """ ) + + +async def m012_update_default_accounts(db): + """ + Update default chart of accounts to include more detailed hierarchical structure. + Adds new accounts for fixed assets, livestock, equity contributions, and detailed expenses. + Only adds accounts that don't already exist. + """ + import uuid + from .account_utils import DEFAULT_HIERARCHICAL_ACCOUNTS + + for name, account_type, description in DEFAULT_HIERARCHICAL_ACCOUNTS: + # Check if account already exists + existing = await db.fetchone( + """ + SELECT id FROM accounts WHERE name = :name + """, + {"name": name} + ) + + if not existing: + # Create new account + await db.execute( + f""" + INSERT INTO accounts (id, name, account_type, description, created_at) + VALUES (:id, :name, :type, :description, {db.timestamp_now}) + """, + { + "id": str(uuid.uuid4()), + "name": name, + "type": account_type.value, + "description": description + } + ) diff --git a/templates/castle/permissions.html b/templates/castle/permissions.html index 74d327b..85a7214 100644 --- a/templates/castle/permissions.html +++ b/templates/castle/permissions.html @@ -1,3 +1,4 @@ + {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} @@ -41,21 +42,21 @@ - - + + - +
- +
- +

No permissions granted yet

@@ -63,14 +64,14 @@
- + User: {% raw %}{{ userId }}{% endraw %}
- + @@ -112,11 +113,11 @@
- +
- +

No permissions granted yet

@@ -124,14 +125,14 @@
- + {% raw %}{{ getAccountName(accountId) }}{% endraw %}
- + @@ -196,7 +197,7 @@ :rules="[val => !!val || 'User ID is required']" > @@ -215,7 +216,7 @@ :rules="[val => !!val || 'Account is required']" > @@ -234,7 +235,7 @@ :rules="[val => !!val || 'Permission type is required']" >