← Modules

Module

Membership Manager

Membership, roster, dues, status, and member self-service management for DivisionDesk organizations.

About

Centralized membership management for organizations using DivisionDesk. Manage member records, organizational scope, membership status, dues and renewal information, imports, saved views, member self-service, reporting, and integrations with other DivisionDesk packages.

Features

  • Member and roster management
  • National, Division, and Camp membership levels
  • Member status and life membership tracking
  • Dues and renewal management
  • CSV, TSV, XLS, and XLSX imports
  • Saved views and advanced member filtering
  • Member self-service portal
  • Role and organization-aware access
  • DivisionDesk Finance integration
  • Membership reporting

What's New in 1.3.24

Adds roster sorting by name, camp, or status; repairs authorized CSV export to use complete member fields; and adds printable PDF roster export while preserving scope and export permissions.

View full package changelog
# Membership Manager 1.3.24

- Adds Events create/edit/publish/delete access to the standard Camp Commander and Camp Adjutant DivisionDesk role presets. Events 1.1.25 enforces Camp ownership server-side, so these permissions do not grant authority over other Camps or Division events.
- Preserves roster column sorting and CSV/PDF export fixes from 1.3.23.

# 1.3.23 QA
- Replaces the roster Sort dropdown with clickable Member, Camp, and Status column headings.
- Clicking the active column toggles ascending/descending order with ASCII-style up/down arrows; clicking another sortable column immediately changes the sort.
- Preserves 1.3.22 CSV/PDF export fixes and all existing roster filtering, scope, dues, role, and Finance behavior.

# 1.3.22 QA
- Added roster sorting by Name, Camp, or Status.
- Fixed CSV export by exporting complete authorized member rows instead of the lean on-screen list projection.
- Added authorized printable PDF roster export.
- Preserved existing scope enforcement and `rosters.export` permission checks for both formats.

# Changelog

## 1.3.21 - suEXEC-Safe Public Endpoint Permissions

- Changes generated public PHP endpoint permissions from `0664` to `0644` so Apache suEXEC does not reject them as writable by others.
- Changes the generated Rosters API directory mode from `0775` to `0755` for the same shared-hosting compatibility reason.
- Keeps the 1.3.20 create-if-missing behavior so normal bootstrap/heartbeat requests do not rewrite existing Membership Manager endpoint shims.

## 1.3.20 - Public Endpoint Self-Repair
- Ensures Membership Manager public endpoint shims during `Addon::register()` so missing `membership-*.php` files are recreated on a normal module bootstrap.
- Existing endpoint files are no longer rewritten merely because the addon is registered or the scheduler runs.
- Keeps explicit write verification/errors when a missing endpoint actually needs to be created.
- Root `.htaccess` is only rewritten when the Rosters API block is genuinely absent.
- Preserves the v1.3.18 MySQL reserved-word compatibility fixes and the v1.3.19 endpoint repair migration.

## 1.3.19 - QA
- Ensures Membership Manager public endpoint shims are generated from migration 008, covering install/reinstall paths that run migrations but skip the optional module lifecycle hook.
- Makes critical PublicEndpoints writes fail explicitly with the exact path instead of silently suppressing filesystem errors.
- Verifies all required membership endpoint shims exist after generation.
- Retains the v1.3.18 MySQL reserved-word compatibility fixes.

# Membership Manager Changelog

## 1.3.18 QA
- Fixed a second modern-MySQL install failure caused by the SQL keyword `sensitive` in `roster_custom_fields`.
- Quoted `required` and `sensitive` consistently in custom-field schema creation and INSERT/UPDATE SQL to prevent further reserved-word parser failures.
- Retains the v1.3.17 `rank` compatibility fix for ancestor schema and writes.
- No roster data is purged or reset by this repair.

## 1.3.17 QA
- Fixed modern MySQL installation failure caused by the reserved SQL keyword `rank` in `roster_ancestors`.
- Quoted ancestor column identifiers in both schema DDL and ancestor INSERT/UPDATE statements so ancestor writes remain compatible after install.
- Restores the normal installation/update path so `PublicEndpoints::ensure()` can create the Membership Manager endpoint shims after migrations complete.
- No roster data is purged or reset by this repair.

## 1.3.16 — 2026-09-13
- Normalize Core `level_1`..`level_4` organization levels through `Terminology::legacyKey()` before applying SCV National/Division/Camp DNR access rules.
- Preserve existing Membership Manager membership levels, role keys, stored scope types, APIs, dues behavior, and database schema.
- Minimum Core is now 4.6.39, the neutral hierarchy compatibility baseline.

## 1.3.15 — 2026-09-06
- Requires Core 4.6.21 security-schema repair.
- Role/permission readers use DISTINCT/grouped database queries so damaged legacy security tables cannot exhaust PHP memory.

## 1.3.14

- Fixes Roles & Offices modal submission so disabling the button no longer disables/omits all POST fields, including the CSRF token.
- Fresh-CSRF retry now updates the actual FormData payload before retrying.
- Refreshes the current effective session after any role assignment/end so an Administrator assignment to the uniquely linked current member takes effect immediately.

## 1.3.13
- Adds exact, unambiguous administrator-email-to-member identity resolution for Core's unified effective-role refresh.
- Ensures an organizational Administrator role grants full roster scope even if a browser session was stale, while refusing ambiguous duplicate-email auto-linking.
- Keeps Membership Manager as the authoritative member-role assignment store; no dues, status, import, portal, or payment behavior is changed.

## 1.3.12
- Makes Membership Manager `Roles & Offices` the single authoritative member-role assignment store when paired with Core 4.6.17+.
- Migrates successfully mappable legacy Core `member_role_assignments` into roster role assignments during install/update, deleting only rows that were successfully migrated.
- Preserves unknown/unmappable legacy rows rather than deleting data; standard DivisionDesk presets and custom access roles are mapped conservatively.
- Stops the roster role provider from re-merging the legacy Core assignment store after migration.
- Automatically retries a member-modal role assignment once with a freshly rendered CSRF token after a 419/stale-session response; a failed CSRF check still performs no write.
- Refreshes the current member session immediately when that member's role is assigned/ended.
- Does not change dues, member status, search, import/export, Finance, or member-portal behavior.

## 1.3.11
- Repairs Membership Manager Settings role/permission administration without changing dues, status, import, search or member portal behavior.
- Adds preset `Administrator` organizational role mapped to Core `organization_administrator` full control.
- Role definition list is defensively de-duplicated by role key.
- Permission editing now opens one office at a time instead of rendering every role × permission combination on a single page.
- Requires Core 4.6.16 for the full-control Administrator access role and repaired Access pages.

## 1.3.9
- Adds `RoleProvider::memberByScvId()` for authorized runtime integrations such as Events registration auto-fill.
- Returns current member identity, address/contact and camp number directly from the authoritative roster.
- Retains all 1.3.8 late-fee and DNR/status behavior.

## 1.3.8
- Late-fee eligibility derives from the member's actual paid-through date.
- Paid through 2026-07-31 + late after 08-31 correctly applies the configured fee after 2026-08-31.
- Handles year-crossing late-fee schedules.
- Retains 1.3.7 DNR/status and donation-fund work.

## 1.3.7
- Yearly / life / DNR controls are now editable directly from the common member-detail Membership tab for authorized users.
- Active/Inactive is derived from deceased status, any DNR status, or National yearly dues being more than the configured number of months overdue.
- Adds a configurable overdue threshold (default 12 months), daily reconciliation, and update-time cleanup of inconsistent seeded/manual Active flags.
- Donation options are now mapped to active Finance funds and carry that fund through checkout/accounting.
- Retains the 1.3.6 late-fee cycle-date correction and itemization.

## 1.3.6
- Fixes renewal-cycle late-fee dates. A 2027 renewal with a 07-31 expiration and an 08-31 late-fee cutoff now becomes late after 2026-08-31, rather than incorrectly waiting until 2027-08-31.
- Handles year-crossing late-fee schedules correctly (for example, a 12-31 expiration with a 01-31 late-fee cutoff uses 01-31 of the renewal year).
- Makes member-facing late fees explicit in the dashboard coverage card, Payments breakdown, review/checkout, bulk calculated checkout, and receipts.
- Retains independent National / Division / Camp late-fee amounts and dates, DNR hierarchy, life-member rules, donations-while-current behavior, and Finance completion reconciliation.

## 1.3.5
- Adds independent National / Division / Camp status controls for Yearly, NLM/DLM/CLM life membership, and permanent DNR.
- Enforces downward DNR propagation for dues and member login eligibility: National DNR blocks all lower levels; Division DNR blocks Division/Camp; Camp DNR blocks Camp only.
- Life membership is permanent unless changed to DNR and cannot revert to yearly. DNR cannot be reversed through normal editing.
- Stores full paid-through dates using configurable per-level expiration month/day instead of relying on year alone.
- Adds independent National, Division and Camp late-fee dates and amounts, with explicit checkout/receipt itemization.
- Keeps optional donation checkout available even when required dues are fully paid.
- Makes Finance completion acknowledgement explicit so failed cross-module completion can be retried rather than silently requiring the member to visit Payments.
- Extends API/report/import behavior for DNR, life status, full paid-through dates, and effective collectibility.

# 1.3.4.c

- Completes paid Finance transactions back into member dues through the Core Integration SDK, reconciles previously completed Finance payments, adds payment-page return/receipt UX support, clarifies donation configuration, and centers the member-modal close control.

# Membership Manager 1.3.4.b

## 1.3.4.b — Clean member route + exact caret preservation + mockup fidelity

- Fixed the `/my-membership` redirect loop by removing the conflicting physical `my-membership.php` shim; the clean route now renders through Core's module-page router and the photo stream uses a dedicated endpoint.
- Live roster search now preserves the member's latest caret/selection position while typing during an in-flight fetch; it never restores an older cursor position captured at request start.
- Revalidated the approved member-portal mockup as the visual acceptance target for Overview, Profile, Payments, Events, Documents and Directory surfaces.

- Keeps the live roster search field interactive during fetch, aborts stale requests, and preserves focus/caret position.
- Implements the approved member navigation: logged out shows **Login**; logged in shows the member first name and stored photo when available, with Membership Overview, My Profile, Dues & Payments, My Events, Documents & Forms, optional Member Directory, and Logout in one dropdown.
- Removes the redundant top-level Logout link while logged in.
- Brings My Membership dashboard structure to the approved mockup: Member Since, membership-standing card, total due card, payment-coverage visualization, recent payments, and upcoming events.
- Refines Profile & Account into real Profile / Preferences / Account & Security tabs.
- Keeps optional member photos truly optional and uses the stored photo in member navigation only when present.
- Rewords member-facing empty states to avoid implementation/integration jargon.
- Retains the 1.3.3 live filtering, Saved Views repair, Finance configuration gating, API simplification, calculated dues, donation checkout, and member-directory controls.

- Fixed live roster search so an in-flight fetch never disables or blocks the Search field.
- Search now preserves focus and caret position after AJAX result refreshes.
- Older in-flight roster requests continue to be aborted when a newer query/filter request starts.
- Search debounce tuned to 350 ms while remaining fully interactive.


- Streamlined the Members workspace: removed Dues and Paid Through from the filter bar, removed the Filter button, removed duplicate Add Member / Import / Export title actions, and removed Search and API from the left navigation.
- Filters now refresh automatically: debounced text search plus immediate Status, Camp, Role and results-per-page changes. Fetch/AJAX updates do not rewrite the browser URL.
- Fixed Saved Views so they actually restore the saved search/filter/page-size state, remain AJAX-driven, and can be deleted from the Saved Views area.
- Moved API tooling out of the everyday navigation and into Settings → Integrations & Developer Access. Reworked the developer page with plain-language explanations and collapsed advanced sections.
- Online Pay / Pay Selected controls now require DivisionDesk Finance to be both installed and configured with a payment provider. If Finance is installed but not configured, dues remain visible but no working-looking payment action is shown.
- Hardened API payment operations to reject payment creation/completion until Finance is configured.

# Membership Manager 1.3.2

- Completed the member-facing portal inside the active client site header/navigation/footer.
- Added one My Membership public navigation parent with dropdown children for Payments & Receipts, Events, Documents & Forms, Profile & Account, and optional Member Directory.
- Replaced member-selected dues levels with calculated National/Division/Camp obligations and one payable total with explicit included/not-included status.
- Added admin-configured optional donation funds with descriptions, Learn More links, preset/custom amounts, ordering, and all choices unchecked by default.
- Added combined dues + donation checkout/receipt metadata and calculated multi-member officer checkout.
- Added configurable Member Directory visibility (disabled, officers only, all active members), audience, and visible fields.
- Added graceful image MIME validation fallback when PHP Fileinfo is unavailable.
- Reworked member portal pages into dashboard/payments/events/documents/profile/directory views instead of one long form.
- Preserved Finance-aware payment visibility, member self-service security boundaries, Smart Import, APIs, audit, and scoped permissions.

# DivisionDesk Rosters / Membership Manager 1.3.1

- Mockup-conformance UX pass across the Membership Manager admin surface.
- Added a compact module navigation rail while retaining the Core global admin shell.
- Moved results-per-page to the roster footer with 25/50/100/250 choices and a 50 default.
- Added numbered AJAX pagination and preserved user page-size preference.
- Tightened roster density, actions, modal sizing, edit scrolling, card hierarchy and responsive behavior.
- Member photos remain absent unless a real stored photo exists.
- Existing Smart Import, self-service member portal, Finance-aware payment visibility, APIs, permissions, scope enforcement and bulk dues functionality are retained.

# Membership Manager / Rosters Changelog

## 1.3.0 — Completion release

- Added member-facing **My Membership** self-service portal at `/my-membership.php` using the existing Core member-login session when available.
- Members can review National/Division/Camp membership status and DivisionDesk dues transaction history.
- Members can update only permitted self-service fields: preferred name, address, email, phones/SMS, opt-out preferences, optional photo, and member-supplied social links.
- Authoritative SCV ID, camp, membership status, roles, dues state, internal notes, and lifecycle fields remain officer/admin controlled.
- Added self-service photo streaming and profile-save auditing without exposing administrative controls.
- Added self-pay checkout handoff when Finance is installed. Payment buttons remain hidden when Finance is absent.
- Admin **Pay Dues / Pay Selected** controls are hidden when Finance is not installed; **Mark Paid** remains available to authorized officers.
- Payment API creation/completion now also refuses online-payment operations when Finance is absent.
- Checkout now supports either an authorized administrator or the authenticated member who owns a self-service payment request.
- Added a Finance bridge that safely detects Finance/configuration and delegates checkout only through an exposed Finance checkout URL contract; Rosters never handles raw card/bank data.
- Added user-selectable roster page sizes: **25 / 50 / 100 / 250**, default **50**, remembered in the browser.
- Improved primary roster search so multi-word searches are tokenized across name, SCV ID, email, phones and camp (for example `James Adkins`, `Baggett 1864`).
- Retained fetch/AJAX filtering, pagination, loaders, duplicate-click prevention, row-click member workspace, bulk selection, smart import, export, APIs, audit history, roles, ancestors, photos/social links and SQLite performance optimizations.
- Continued use of Core/global admin UI variables for Membership Manager colors and surfaces.
- Raised the release baseline to Core 4.4.1 for the production completion pass.


## 1.2.5 - 2026-08-24

- Production-polished Membership Manager UI aligned with the approved DivisionDesk mockup and global admin styling.
- Canonical AJAX member workspace/modal with in-modal editing.
- Permission-aware checkbox bulk actions for dues workflows.
- `Pay Selected` now enters a review/checkout workflow; when no payment provider is configured, no charge occurs and no member is marked paid.
- `Mark Paid` remains a separate authorized administrative action for payments received elsewhere.
- Hardened permission/scope validation, payment completion validation, and member-edit data integrity.
- Member photo storage is supported but no placeholder image/icon is shown when a photo is absent; social profile links can be stored.
- Production QA and deployment acceptance checklist refreshed.

# Membership Manager Changelog

## 1.2.4
- Polished Membership Manager roster based on the approved DivisionDesk v1.2.4 workflow without copying National's visual design.
- Added checkbox selection for members plus permission-aware bulk dues actions.
- Added **Mark Paid** for National/Division/Camp dues and **Pay Selected** payment-request creation for payment integrations.
- Added `rosters.dues.mark_paid` and `rosters.dues.pay` capabilities; all bulk actions also enforce organizational scope.
- Added optional member-photo storage (JPEG/PNG/WebP, max 5 MB). No photo, icon, or placeholder is displayed unless a photo is actually stored.
- Added member-supplied social-media profile links with platform, handle, and URL fields.
- Added photo/social information to member detail views only when present and authorized.
- Expanded roster search to phone and SMS fields.
- Expanded REST API v1: member create/update, membership summary, social-link read/update, bulk mark-paid, payment-request lookup/completion endpoints.
- API service accounts continue to enforce both capability and organizational scope per action.
- Added `dues.payment.requested` and `dues.payment.completed` integration events and persistent payment-request records. Creating a request never falsely marks a payment complete.

## 1.2.3
- Roster filters and pagination now update with fetch/AJAX instead of full-page reloads.
- Added visible loading overlay/spinner while roster results are loading.
- Entire member rows are clickable and keyboard accessible.
- Redesigned member detail modal with reliable tab labels, compact information cards, status display, responsive layout, and footer actions.


## 1.2.2 — Conservative Email Repair
- Smart Import now treats common placeholders such as `NO EMAIL`, `none`, and `N/A` as an intentionally blank email without warning or row failure.
- Obvious missing-dot mistakes on a conservative list of well-known domains (for example `GMAILCOM` and `HOTMAILCOM`) are repaired automatically and reported as corrections.
- Ambiguous malformed values are never guessed. The member still imports, the email is left blank, and the warning shows the exact original value for administrator cleanup.
- Email quality problems never reject an otherwise valid member row.
- Includes the v1.2.1 SQLite bulk-import, roster-query, AJAX modal, country-default, and warning improvements.

## 1.2.1 — Performance & Import Resilience
- Wrapped Smart Import writes in a single transaction, dramatically reducing SQLite commit overhead.
- Preloaded SCV-ID matches for imports and replaced heavyweight per-row profile loads with lightweight identity lookups.
- Cached audit settings and webhook subscriptions for the request instead of re-querying them on every member change.
- Blank country values now safely default to `USA`, including updates, preventing NOT NULL import failures.
- Invalid email addresses no longer discard otherwise valid member rows; the member imports with a visible warning and blank email.
- Roster list queries now select only visible columns and batch-load role/membership badges for the current page.
- Added SQLite/MySQL indexes for common roster browsing and current-role lookup paths.
- Clicking a member in the roster now opens a lazy-loaded AJAX detail modal; heavy profile data is fetched only when requested.
- Full edit pages remain available from the modal for administrative changes.

## 1.2.0 — Universal File Import
- Added native `.xlsx`, `.xlsm`, `.xltx`, and `.xltm` workbook import using the first worksheet.
- Added native `.ods` OpenDocument spreadsheet import.
- Added Excel 2003 XML / SpreadsheetML and HTML-table spreadsheet import.
- Added automatic detection for comma, tab, semicolon, and pipe-delimited text files, regardless of extension.
- Added UTF-8 BOM and UTF-16 LE/BE text decoding for common Excel exports.
- Added content-based format detection so mislabeled `.xls`/`.csv` exports can still be recognized.
- True legacy binary Excel 97–2003 `.xls` files are supported automatically when PhpSpreadsheet is available; otherwise the importer provides a clear conversion instruction instead of a generic failure.
- XLSX date-formatted cells are converted from Excel serial dates before the existing field normalizers run.
- Smart mapping, learned mappings, custom-field creation, normalization, scope enforcement, and row-level error reporting continue to apply to every supported format.

## 1.1.0 — Smart Import
- Fixed CSV header normalization that could strip uppercase letters before matching.
- Added guided smart column mapping with exact, alias, learned, and high-confidence fuzzy matching.
- Unknown columns now require an administrator choice: map to a standard field, map to an existing custom field, create a custom field, or ignore.
- Confirmed source-header mappings are persisted and reused on later imports.
- Added broader aliases for Salesforce-style and common membership roster headings.
- Added safe import normalization for names, phones, dates, email addresses, state names/abbreviations, ZIP codes, salutations, suffixes, country values, addresses, and booleans.
- Added National membership effective/expiration date import support and equivalent Division/Camp mapping targets.
- Added camp-number inference from values such as `FORT BLAKELEY CAMP 1864` when a dedicated camp-number column is absent.
- Added visible row-level import errors instead of only reporting an error count.
- Preserved SCV ID upsert behavior and scope enforcement.

## 1.0.1
- Security and registry integration revision.

### 1.2.4 production-polish revision — 2026-08-24
- Aligned Membership Manager screens with the approved v1.2.4 mockup while inheriting Core/global admin color variables.
- Retained fetch-based roster filtering/pagination and made loading/busy states consistent.
- Member workspace is the canonical everyday view; editing now opens and saves inside the AJAX modal.
- Member photos remain optional and are rendered only when an actual photo is stored.
- Added member-supplied social link editing/storage to the modal workflow.
- `Pay Selected` now opens a review/checkout page instead of ending at an internal request key.
- Checkout clearly shows selected members, dues level/year, per-member amount and total.
- When no payment provider is configured, checkout explicitly performs no charge and does not mark members paid.
- `Mark Paid` remains a separate permission-checked path for payments completed outside DivisionDesk.
- Added protected `membership-checkout.php` endpoint and retained the pending request object as the integration handoff underneath checkout.
- Display-name rendering now cleans legacy all-uppercase/all-lowercase name parts without rewriting stored source data.

## 1.3.10 — 2026-09-05

### Added
- Exposes Assign Role / Office directly from the member Roles & Offices modal.
- Adds editable Roles & Permissions presets in Membership Manager Settings, backed by existing Core role/capability tables.
- Adds missing standard SCV office definitions/mappings (Camp Webmaster, Lt. Brigade Commander, Division Communications Chairman) without replacing local custom roles.

### Safety
- Preset seeding is additive only. Existing role assignments, custom role definitions and administrator-edited permissions are not removed or reset during update.
- Camp/Brigade/Division scope is derived from the member hierarchy for standard offices and checked against the assigning administrator's existing data scope.
- Dues, status derivation, member import/search, Finance and portal logic are unchanged.

Release History

1.3.24 development published
2026-09-25T21:33:57+00:00

Adds roster sorting by name, camp, or status; repairs authorized CSV export to use complete member fields; and adds printable PDF roster export while preserving scope and export permissions.

1.3.23 development published
2026-09-25T21:11:47+00:00

Adds roster sorting by name, camp, or status; repairs authorized CSV export to use complete member fields; and adds printable PDF roster export while preserving scope and export permissions.

1.3.22 development published
2026-09-25T21:06:18+00:00

Adds roster sorting by name, camp, or status; repairs authorized CSV export to use complete member fields; and adds printable PDF roster export while preserving scope and export permissions.

1.3.21 development published
2026-09-14T09:08:59+00:00

Public endpoint self-repair: Membership Manager now ensures missing admin/API endpoint shims during addon registration, matching the proven DivisionDesk module pattern. Existing endpoint files are left untouched so normal requests and scheduler runs do not rewrite them every minute. Preserves all v1.3.18 MySQL compatibility fixes and v1.3.19 endpoint validation.

1.3.20 development published
2026-09-14T08:50:57+00:00

Public endpoint self-repair: Membership Manager now ensures missing admin/API endpoint shims during addon registration, matching the proven DivisionDesk module pattern. Existing endpoint files are left untouched so normal requests and scheduler runs do not rewrite them every minute. Preserves all v1.3.18 MySQL compatibility fixes and v1.3.19 endpoint validation.

1.3.19 development published
2026-09-14T08:34:51+00:00

Installer endpoint repair: preserves the v1.3.18 MySQL reserved-word compatibility fixes and moves Membership Manager public endpoint generation onto the guaranteed migration path. Required endpoint writes are now verified and fail with an explicit error instead of being silently suppressed.

1.3.18 development published
2026-09-14T08:27:51+00:00

MySQL compatibility repair: quotes reserved/keyword-sensitive identifiers used by Rosters schema and DML, including `rank`, `required`, and `sensitive`, so fresh installs and reinstalls complete on modern MySQL. This allows the normal install lifecycle to reach PublicEndpoints::ensure() and recreate the Membership Manager endpoint shims.

1.3.17 development published
2026-09-14T08:24:27+00:00

MySQL compatibility repair: quotes the reserved ancestor column `rank` in schema creation and ancestor INSERT/UPDATE SQL so fresh installs and reinstalls complete on modern MySQL. This also allows the normal Rosters install lifecycle to reach PublicEndpoints::ensure() and recreate the Membership Manager public endpoint shims.

1.3.16 development published
2026-09-13T06:32:36+00:00

Hierarchy compatibility release: normalizes Core neutral organization levels through Terminology while preserving existing SCV membership and role/scope keys.