Metadata-Version: 2.4
Name: saransh-workflows
Version: 0.1.0
Summary: Indian financial statement parsers for CAMS, CDSL, and NSDL PDFs
Project-URL: Homepage, https://github.com/sagarchandagarwal/saransh-workflows
Project-URL: Repository, https://github.com/sagarchandagarwal/saransh-workflows
Project-URL: Issues, https://github.com/sagarchandagarwal/saransh-workflows/issues
License: MIT
Keywords: cams,cdsl,demat,finance,india,mutual-fund,nsdl,parser,statement
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Text Processing :: Markup
Requires-Python: >=3.11
Requires-Dist: cryptography>=3.1
Requires-Dist: pypdf>=6.0.0
Description-Content-Type: text/markdown

# saransh-workflows

Python parsers for Indian financial statement PDFs — CAMS Consolidated Account Statement, CDSL CAS, and NSDL e-CAS. Each parser extracts text from the PDF using [`pypdf`](https://pypdf.readthedocs.io/) and returns a fully structured JSON object.

---

## Installation

### From PyPI (once published)

```bash
pip install saransh-workflows
```

### From source (development)

```bash
git clone https://github.com/sagarchandagarwal/saransh-workflows.git
cd saransh-workflows
pip install -e .
```

---

## CLI Usage

After installation three commands are available on your `PATH`:

```bash
# CAMS parser
parse-cams path/to/cams_statement.pdf
parse-cams path/to/cams_statement.pdf --pretty -o output.json
parse-cams path/to/cams_statement.pdf --password your_pdf_password --pretty

# CDSL parser
parse-cdsl path/to/cdsl_cas.pdf
parse-cdsl path/to/cdsl_cas.pdf --pretty -o output.json
parse-cdsl path/to/cdsl_cas.pdf --password your_pdf_password --pretty

# NSDL parser
parse-nsdl path/to/nsdl_ecas.pdf
parse-nsdl path/to/nsdl_ecas.pdf --pretty -o output.json
parse-nsdl path/to/nsdl_ecas.pdf --password your_pdf_password --pretty
```

All three commands accept the same flags:

| Flag | Description |
|------|-------------|
| `input_pdf` | Path to the source PDF (required) |
| `-o / --output` | Output JSON path (default: same name as PDF with `.json` suffix) |
| `--pretty` | Pretty-print JSON with 2-space indentation |
| `--password` | Password for encrypted/password-protected PDF files |

---

## Python API

```python
from pathlib import Path
from saransh_workflows import parse_cams_pdf, parse_cdsl_pdf, parse_nsdl_pdf

cams_data  = parse_cams_pdf(Path("cams_statement.pdf"))
cdsl_data  = parse_cdsl_pdf(Path("cdsl_cas.pdf"))
nsdl_data  = parse_nsdl_pdf(Path("nsdl_ecas.pdf"))

# Encrypted PDFs
nsdl_encrypted = parse_nsdl_pdf(Path("nsdl_ecas.pdf"), password="your_pdf_password")
```

All three functions return a plain `dict` that can be serialised with `json.dumps`.

---

## Output JSON Schemas

### CAMS

```
{
  "source_file": str,
  "statement_period": {"from": str, "to": str} | null,
  "investor": {
    "email": str | null,
    "name": str | null,
    "address": [str],
    "phone_res": str | null,
    "mobile": str | null
  },
  "portfolio_summary": [
    {"fund_house": str, "cost_value_inr": float, "market_value_inr": float}
  ],
  "folios": [
    {
      "fund_house": str,
      "folio_no": str | null,
      "pan": str | null,
      "kyc": str | null,
      "holder_name": str | null,
      "scheme_code": str | null,
      "scheme_name": str | null,
      "isin": str | null,
      "registrar": str | null,
      "nominees": [str],
      "opening_unit_balance": float | null,
      "transactions": [
        {
          "date": str,
          "transaction": str,
          "amount_inr": float | null,
          "units": float | null,
          "price_inr": float | null,
          "unit_balance": float | null,
          "charges": [{"date": str, "amount_inr": float}]
        }
      ],
      "closing_unit_balance": float | null,
      "nav": {"date": str, "value_inr": float} | null,
      "total_cost_value_inr": float | null,
      "market_value": {"date": str, "value_inr": float} | null,
      "notes": [str]
    }
  ],
  "warnings": [str]
}
```

### CDSL

```
{
  "source_file": str,
  "cas_id": str | null,
  "statement_period": {"from": str, "to": str} | null,
  "investor": {"name": str, "pan": str, "address": [str]},
  "summary": {
    "accounts": [...],
    "total_portfolio_value_inr": float | null,
    "grand_total_inr": float | null,
    "monthly_portfolio_valuation": [...],
    "asset_allocation": [...]
  },
  "cdsl_accounts": [
    {
      "bo_id": str,
      "dp_name": str,
      "transactions": [...],
      "holdings": [...],
      "holding_sections": [...],
      "no_transaction": bool,
      "nil_holding": bool,
      "portfolio_values": [float]
    }
  ],
  "nsdl_accounts": [...],
  "mutual_fund_folios": [
    {
      "amc_name": str,
      "scheme_name": str,
      "scheme_code": str,
      "folio_no": str | null,
      "isin": str | null,
      "opening_balance": float | null,
      "closing_balance": float | null,
      "transactions": [...]
    }
  ]
}
```

### NSDL

```
{
  "source_file": str,
  "nsdl_id": str | null,
  "statement_period": {"from": str, "to": str} | null,
  "investor": {
    "name": str | null,
    "pan": str | null,
    "address": [str],
    "portfolio_value_inr": float | null
  },
  "summary": {
    "accounts": [...],
    "total_inr": float | null,
    "grand_total_inr": float | null,
    "portfolio_trend": [
      {
        "month": str,
        "portfolio_value_inr": float | null,
        "change_inr": float | null,
        "change_percent": float | null,
        "remark": str | null
      }
    ],
    "asset_composition": [
      {"asset_class": str, "value_inr": float, "percent": float}
    ]
  },
  "holdings": {
    "account": {...},
    "securities": [
      {
        "isin": str,
        "security": str,
        "current_balance": float,
        "free_balance": float,
        "value_inr": float,
        ...
      }
    ]
  },
  "transactions": {
    "account": {...},
    "isin_sections": [
      {
        "isin": str,
        "security": str,
        "opening_balance": float | null,
        "closing_balance": float | null,
        "transactions": [...]
      }
    ]
  }
}
```

---

## Project Structure

```
saransh-workflows/
├── saransh_workflows/        # Installable Python package
│   ├── __init__.py           # Public API re-exports
│   ├── cams.py               # CAMS parser
│   ├── cdsl.py               # CDSL parser
│   └── nsdl.py               # NSDL parser
├── cams-parser/
│   ├── parse_cams_pdf.py     # Standalone script (standalone usage)
│   └── requirements.txt
├── cdsl-parser/
│   ├── parse_cdsl_pdf.py     # Standalone script
│   └── requirements.txt
├── nsdl-parser/
│   ├── parse_nsdl_pdf.py     # Standalone script
│   └── requirements.txt
├── pyproject.toml            # Package metadata & build config
├── README.md
└── AGENTS.md                 # Development log & change history
```

---

## Publishing to PyPI

```bash
pip install build twine
python -m build
twine upload dist/*
```

---

## Requirements

- Python ≥ 3.11
- pypdf ≥ 6.0.0
- cryptography ≥ 3.1 (required for AES-encrypted PDFs)

---

## License

MIT
