Skip to content

feat(Supporting Membership): replace checkbox with yearly records (LAN-910)#340

Open
barredterra wants to merge 8 commits into
version-15-hotfixfrom
lan-910
Open

feat(Supporting Membership): replace checkbox with yearly records (LAN-910)#340
barredterra wants to merge 8 commits into
version-15-hotfixfrom
lan-910

Conversation

@barredterra

@barredterra barredterra commented Jul 7, 2026

Copy link
Copy Markdown
Member

Replace the is_supporting_member checkbox on LANDA Member with a Supporting Membership DocType keyed by member and year. Add mutual exclusion validation with Yearly Fishing Permit, update Member Data Import and the "Current Member Data" report, and schedule yearly status updates.

Existing data is deliberately dropped. Data migration is not desired.

To do:

  • update translations before merge

…N-910)

Replace the `is_supporting_member` checkbox on **LANDA Member** with a
**Supporting Membership** DocType keyed by member and year. Add mutual
exclusion validation with **Yearly Fishing Permit**, update member data
import and the current member data report, and schedule daily status
updates.
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge; all core validation paths are correct and the two findings are minor quality improvements.

The new DocType, its validation logic, the mutual-exclusion checks, and the report changes all behave as intended. The two findings are a style preference (replace assert with frappe.throw in the bulk endpoint) and a missing set_only_once on the year field — neither affects correctness of the happy path.

supporting_membership.py (bulk_create assert statements) and supporting_membership.json (year field missing set_only_once).

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant UI as Browser / List View
    participant BC as bulk_create (whitelisted)
    participant MDI as MemberDataImport.submit
    participant SM as SupportingMembership.validate
    participant YFP as YearlyFishingPermit.validate
    participant MPV as membership_permit_validation
    participant Sched as Scheduler (Jan 1)

    UI->>BC: xcall bulk_create(year, members[])
    BC->>SM: frappe.new_doc + insert()
    SM->>SM: before_validate → get_status()
    SM->>SM: check duplicate (member+year)
    SM->>MPV: validate_no_active_yearly_fishing_permit (if Active)
    MPV-->>SM: throws if submitted YFP exists
    SM-->>BC: DuplicateEntryError / ValidationError → skip

    MDI->>MDI: create_supporting_membership()
    MDI->>SM: frappe.new_doc + insert()
    SM->>SM: before_validate → get_status()
    SM->>MPV: validate_no_active_yearly_fishing_permit (if Active)

    YFP->>MPV: validate_no_active_supporting_membership(member, year)
    MPV-->>YFP: throws if any SM exists for member+year

    Sched->>SM: update_supporting_membership_statuses()
    SM->>SM: get_supporting_memberships_to_update (year-1..year+1)
    SM->>SM: doc.save() if status changed
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant UI as Browser / List View
    participant BC as bulk_create (whitelisted)
    participant MDI as MemberDataImport.submit
    participant SM as SupportingMembership.validate
    participant YFP as YearlyFishingPermit.validate
    participant MPV as membership_permit_validation
    participant Sched as Scheduler (Jan 1)

    UI->>BC: xcall bulk_create(year, members[])
    BC->>SM: frappe.new_doc + insert()
    SM->>SM: before_validate → get_status()
    SM->>SM: check duplicate (member+year)
    SM->>MPV: validate_no_active_yearly_fishing_permit (if Active)
    MPV-->>SM: throws if submitted YFP exists
    SM-->>BC: DuplicateEntryError / ValidationError → skip

    MDI->>MDI: create_supporting_membership()
    MDI->>SM: frappe.new_doc + insert()
    SM->>SM: before_validate → get_status()
    SM->>MPV: validate_no_active_yearly_fishing_permit (if Active)

    YFP->>MPV: validate_no_active_supporting_membership(member, year)
    MPV-->>YFP: throws if any SM exists for member+year

    Sched->>SM: update_supporting_membership_statuses()
    SM->>SM: get_supporting_memberships_to_update (year-1..year+1)
    SM->>SM: doc.save() if status changed
Loading

Reviews (3): Last reviewed commit: "fix(member_data_import): skip existing s..." | Re-trigger Greptile

Comment thread landa/patches.txt
Comment thread landa/organization_management/membership_permit_validation.py
…check

Treat active Supporting Membership records like Yearly Fishing Permits
when determining magazine eligibility, so Fördermitglieder are not
excluded from mailing when they have no permit.
Mirror the Yearly Fishing Permit bulk-create workflow so Vereinsnutzer
can create supporting memberships for multiple members at once.
other unrelated changes are auto-generated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant