File size: 10,816 Bytes
c79824c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
import logging
from typing import List, Dict, Any, Optional
from pydantic import BaseModel, Field

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class BalanceSheetItem(BaseModel):
    section: str
    category: str
    subcategory: Optional[str] = ""
    name: str
    note: str
    indent_level: int = 1
    is_total_row: bool = False
    is_section_header: bool = False
    is_category_header: bool = False

class FormattingRules(BaseModel):
    header: Dict[str, Any]
    sections: Dict[str, Dict[str, Any]]
    categories: Dict[str, Dict[str, Any]]
    subcategories: Dict[str, Dict[str, Any]]
    totals: Dict[str, Dict[str, Any]]

class BalanceSheetTemplate:
    """
    Provides the structure, formatting, and field mappings for a standard Balance Sheet.
    """

    def __init__(self):
        # Complete Balance Sheet Structure Template
        self.template_structure: List[Dict[str, Any]] = [
            BalanceSheetItem(section="EQUITY AND LIABILITIES", category="Shareholders' funds", subcategory="", name="Share capital", note="2").dict(),
            BalanceSheetItem(section="EQUITY AND LIABILITIES", category="Shareholders' funds", subcategory="", name="Reserves and surplus", note="3").dict(),
            BalanceSheetItem(section="EQUITY AND LIABILITIES", category="Non-Current liabilities", subcategory="", name="Long term borrowings", note="4").dict(),
            BalanceSheetItem(section="EQUITY AND LIABILITIES", category="Non-Current liabilities", subcategory="", name="Deferred Tax Liability (Net)", note="5").dict(),
            BalanceSheetItem(section="EQUITY AND LIABILITIES", category="Current liabilities", subcategory="", name="Trade payables", note="6").dict(),
            BalanceSheetItem(section="EQUITY AND LIABILITIES", category="Current liabilities", subcategory="", name="Other current liabilities", note="7").dict(),
            BalanceSheetItem(section="EQUITY AND LIABILITIES", category="Current liabilities", subcategory="", name="Short term provisions", note="8").dict(),
            BalanceSheetItem(section="ASSETS", category="Non-current assets", subcategory="Fixed assets", name="Tangible assets", note="9", indent_level=2).dict(),
            BalanceSheetItem(section="ASSETS", category="Non-current assets", subcategory="Fixed assets", name="Intangible assets", note="9", indent_level=2).dict(),
            BalanceSheetItem(section="ASSETS", category="Non-current assets", subcategory="", name="Long Term Loans and Advances", note="10").dict(),
            BalanceSheetItem(section="ASSETS", category="Current assets", subcategory="", name="Inventories", note="11").dict(),
            BalanceSheetItem(section="ASSETS", category="Current assets", subcategory="", name="Trade receivables", note="12").dict(),
            BalanceSheetItem(section="ASSETS", category="Current assets", subcategory="", name="Cash and bank balances", note="13").dict(),
            BalanceSheetItem(section="ASSETS", category="Current assets", subcategory="", name="Short-term loans and advances", note="14").dict(),
            BalanceSheetItem(section="ASSETS", category="Current assets", subcategory="", name="Other current assets", note="15").dict()
        ]

        # Formatting rules for display
        self.formatting_rules: FormattingRules = FormattingRules(
            header={
                "title": "Balance Sheet as at March 31, 2024",
                "currency_note": "(In Lakhs)",
                "column_headers": ["", "Notes", "March 31, 2024", "March 31, 2023"]
            },
            sections={
                "EQUITY AND LIABILITIES": {"display_name": "EQUITY AND LIABILITIES", "order": 1},
                "ASSETS": {"display_name": "ASSETS", "order": 2}
            },
            categories={
                "Shareholders' funds": {"display_name": "Shareholders' funds", "show_total": True, "total_label": "", "order": 1},
                "Non-Current liabilities": {"display_name": "Non-Current liabilities", "show_total": True, "total_label": "", "order": 2},
                "Current liabilities": {"display_name": "Current liabilities", "show_total": True, "total_label": "", "order": 3},
                "Non-current assets": {"display_name": "Non-current assets", "show_total": True, "total_label": "", "order": 4},
                "Current assets": {"display_name": "Current assets", "show_total": True, "total_label": "", "order": 5}
            },
            subcategories={
                "Fixed assets": {"display_name": "Fixed assets", "show_total": True, "total_label": "", "parent_category": "Non-current assets"}
            },
            totals={
                "TOTAL_EQUITY_LIABILITIES": {"display_name": "TOTAL", "position": "after_equity_liabilities", "is_grand_total": True},
                "TOTAL_ASSETS": {"display_name": "TOTAL", "position": "after_assets", "is_grand_total": True}
            }
        )

        # Field mapping patterns for data extraction
        self.field_mappings: Dict[str, List[str]] = {
            'share_capital': ['share capital', 'equity share', 'paid up', 'issued shares', 'authorised shares', 'subscribed', 'fully paid'],
            'reserves_surplus': ['reserves and surplus', 'reserves', 'surplus', 'retained earnings', 'profit and loss', 'general reserves', 'closing balance'],
            'long_term_borrowings': ['long term borrowings', 'long-term borrowings', 'borrowings', 'debt', 'loans', 'financial corporation', 'bank loan'],
            'deferred_tax': ['deferred tax', 'tax liability', 'deferred tax liability'],
            'trade_payables': ['trade payables', 'payables', 'creditors', 'sundry creditors', 'capital expenditure', 'other expenses'],
            'other_current_liabilities': ['other current liabilities', 'current maturities', 'outstanding liabilities', 'statutory dues', 'accrued expenses'],
            'short_term_provisions': ['short term provisions', 'provisions', 'provision for taxation', 'tax provision'],
            'tangible_assets': ['tangible assets', 'property plant', 'fixed assets', 'buildings', 'plant', 'equipment', 'net carrying value'],
            'intangible_assets': ['intangible assets', 'software', 'goodwill', 'intangible'],
            'long_term_loans_advances': ['long term loans', 'security deposits', 'long term advances'],
            'inventories': ['inventories', 'stock', 'consumables', 'raw materials'],
            'trade_receivables': ['trade receivables', 'receivables', 'debtors', 'outstanding', 'other receivables'],
            'cash_bank': ['cash and bank', 'cash', 'bank balances', 'current accounts', 'cash on hand', 'fixed deposits'],
            'short_term_loans_advances': ['short term loans', 'prepaid expenses', 'other advances', 'advance tax', 'statutory authorities'],
            'other_current_assets': ['other current assets', 'accrued income', 'interest accrued']
        }

    def get_template_structure(self) -> List[Dict[str, Any]]:
        """Return the complete template structure."""
        return self.template_structure.copy()

    def get_formatting_rules(self) -> FormattingRules:
        """Return the formatting rules."""
        return self.formatting_rules.copy()

    def get_field_mappings(self) -> Dict[str, List[str]]:
        """Return the field mapping patterns."""
        return self.field_mappings.copy()

    def get_categories(self) -> List[str]:
        """Get unique categories from template."""
        categories = []
        seen = set()
        for item in self.template_structure:
            cat = item["category"]
            if cat not in seen:
                categories.append(cat)
                seen.add(cat)
        return categories

    def get_items_by_category(self, category: str) -> List[Dict[str, Any]]:
        """Get all items for a specific category."""
        return [item for item in self.template_structure if item["category"] == category]

    def get_items_by_section(self, section: str) -> List[Dict[str, Any]]:
        """Get all items for a specific section."""
        return [item for item in self.template_structure if item["section"] == section]

    def get_subcategories(self, category: str) -> List[str]:
        """Get subcategories for a specific category."""
        subcats = set()
        for item in self.template_structure:
            if item["category"] == category and item["subcategory"]:
                subcats.add(item["subcategory"])
        return list(subcats)

# For backward compatibility - alias the class
BalanceSheet = BalanceSheetTemplate

# Module level constants for quick access
BALANCE_SHEET_SECTIONS: List[str] = ["EQUITY AND LIABILITIES", "ASSETS"]

BALANCE_SHEET_CATEGORIES: List[str] = [
    "Shareholders' funds",
    "Non-Current liabilities",
    "Current liabilities",
    "Non-current assets",
    "Current assets"
]

STANDARD_NOTES_MAPPING: Dict[str, str] = {
    "Share capital": "2",
    "Reserves and surplus": "3",
    "Long term borrowings": "4",
    "Deferred Tax Liability (Net)": "5",
    "Trade payables": "6",
    "Other current liabilities": "7",
    "Short term provisions": "8",
    "Tangible assets": "9",
    "Intangible assets": "9",
    "Long Term Loans and Advances": "10",
    "Inventories": "11",
    "Trade receivables": "12",
    "Cash and bank balances": "13",
    "Short-term loans and advances": "14",
    "Other current assets": "15"
}

SIMPLE_TEMPLATE: List[Dict[str, Any]] = [
    {"category": "Shareholders' funds", "name": "Share capital", "note": "2"},
    {"category": "Shareholders' funds", "name": "Reserves and surplus", "note": "3"},
    {"category": "Non-Current liabilities", "name": "Long term borrowings", "note": "4"},
    {"category": "Non-Current liabilities", "name": "Deferred Tax Liability (Net)", "note": "5"},
    {"category": "Current liabilities", "name": "Trade payables", "note": "6"},
    {"category": "Current liabilities", "name": "Other current liabilities", "note": "7"},
    {"category": "Current liabilities", "name": "Short term provisions", "note": "8"},
    {"category": "Non-current assets", "subcategory": "Fixed assets", "name": "Tangible assets", "note": "9"},
    {"category": "Non-current assets", "subcategory": "Fixed assets", "name": "Intangible assets", "note": "9"},
    {"category": "Non-current assets", "name": "Long Term Loans and Advances", "note": "10"},
    {"category": "Current assets", "name": "Inventories", "note": "11"},
    {"category": "Current assets", "name": "Trade receivables", "note": "12"},
    {"category": "Current assets", "name": "Cash and bank balances", "note": "13"},
    {"category": "Current assets", "name": "Short-term loans and advances", "note": "14"},
    {"category": "Current assets", "name": "Other current assets", "note": "15"}
]