Skip to content

feat: add an Ellucian CRM Advance gift export reader (ingest preset) #241

Description

@shivamlalakiya

What's needed

Same pattern as the other CRM bridges in philanthropy.ingest (CiviCRM, Raiser's Edge, NPSP): a thin, CRM-specific header-alias map plus a commitment/payment exclusion filter, delegating the roll-up to the shared aggregator in philanthropy/ingest/_civicrm.py. This issue adds the bridge for Ellucian CRM Advance (higher-education advancement CRM, formerly "Advance"/"Advance Web") — a different vendor from every bridge in this repo so far, with its own object model (a gift is typically a "Designation"-linked transaction against a constituent record). Confirm the actual field names and vocabulary from Ellucian's own docs; nothing here should be assumed from the existing bridges.

Where to look

File Purpose
philanthropy/ingest/_raisers_edge.py Closest existing example of the pattern (structure only — a different vendor and data model, not a source of field names)
philanthropy/ingest/_civicrm.py The shared aggregator (civicrm_contributions_to_features, read_civicrm_contributions) and its private helpers
tests/test_raisers_edge.py The test depth expected of your new tests/test_ellucian_advance.py
philanthropy/cli.py _FEATURE_SOURCES and the features --source dispatch — wire your new source in the same shape, unless the read_gifts preset registry (a separate, in-flight PR) has already landed, in which case register there instead

What to build

  1. philanthropy/ingest/_ellucian_advance.py: a header-alias map from Ellucian CRM Advance's real export labels and API field names onto the canonical contact_id / receive_date / total_amount / gift_type names; a documented default exclusion parameter for whatever this product's pledge-vs-payment split actually is; a ellucian_advance_gifts_to_features(...) function (name it for what the product actually calls the record once you've checked); and a read_ellucian_advance_gifts(path) reader delegating to read_civicrm_contributions.
  2. Verify every field name and every commitment/payment vocabulary term against Ellucian's own public documentation before writing it down. Cite the doc URLs you actually used in your PR body, the way PR #233 does for NPSP. This issue does not assert any field name as fact — confirm everything yourself.
  3. Export the new names from philanthropy/ingest/__init__.py (__all__, alphabetical) and add a stability-tier row to docs/reference/index.md (Tier 2/Beta — a test enforces every public symbol has a row).
  4. tests/test_ellucian_advance.py at the depth of tests/test_raisers_edge.py: header aliasing from every spelling the docs name, the commitment/payment double-count trap and its exclusion, the exclusion set being documented/overridable/disabled by None, currency parsing, schema/dtypes, empty input, missing required columns.
  5. CHANGELOG.md entry under ## [Unreleased], and add yourself to CONTRIBUTORS.md if you'd like.

Hard constraints (same as the rest of this ingest series)

  • Dependencies stay scikit-learn/pandas/numpy/joblib only — no new package, no API client, no network code anywhere in philanthropy/. File-export reader only, never a live API connector.
  • No new estimator class.
  • Build the exclusion logic from Ellucian's own public docs only — never from an institution's actual configuration or data.
  • Follow AGENTS.md's order: implement, export, verify with python -c "...", then write tests, then make ci.

Verifying

python -m pip install -e ".[dev]"
python -c "from philanthropy.ingest import ellucian_advance_gifts_to_features, read_ellucian_advance_gifts; print('OK')"
make ci
make riskcov

Claim this issue with a comment before starting; a maintainer assigns within 24 hours.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions