Releases: imCodePartnerAB/KOHASS12000
Version 1.90
v1.90 Release Notes
New Features
This release adds two new plugin settings that allow administrators to handle edge cases where valid users were previously skipped during sync.
"Ignore cancelled flag"
A new dropdown setting in the plugin configuration:
- No (default): Cancelled enrolments are skipped (existing behavior)
- Yes: Cancelled enrolments are processed if start/end dates are valid
The $ignore_cancelled parameter is passed as a boolean to get_current_enrolment(), so the filtering logic becomes:
($ignore_cancelled || !$_->{cancelled})
When a user is imported via a cancelled enrolment, their opacnote will include (enrolment cancelled) for staff visibility:
Added by SS12000: plugin 20260319 v1.90 at 2026-03-19 (enrolment cancelled)
"Use default for unmapped"
A new dropdown setting for handling students from schools not present in the branch mapping table:
- No (default): Users from unmapped schools are skipped (existing behavior)
- Yes: After the normal sync, an additional pass runs without organisation filtering — unmapped users are assigned the default branchcode
This ensures:
- Mapped schools still use their configured branchcode
- Unmapped schools use the default branchcode instead of being skipped
Both settings default to No, preserving existing behaviour for current installations.
Changes
ExportUsers.pm
- Added
ignore_cancelled_flaganduse_default_for_unmappedto configuration handling (install, configure, save) - Modified
get_current_enrolment()to accept$ignore_cancelledas a boolean parameter - Updated filtering logic:
($ignore_cancelled || !$_->{cancelled}) - Added
$enrolment_cancelledtracking through toaddOrUpdateBorrower() - Updated all opacnote SQL statements to include
(enrolment cancelled)suffix where applicable - Added additional sync pass in
_cronjob_inner()whenuse_default_for_unmappedis enabled - Version bump: 1.89 → 1.90
config.tt
- Added UI dropdowns for both new settings with help text
.gitignore
- Added
*.kpzto prevent build artifacts from being committed - Removed previously tracked
.kpzfile
Testing
Ignore cancelled flag
- Set "Ignore cancelled flag" to "Yes" in plugin settings
- Run sync with students that have
cancelled: trueenrolments but valid dates - Verify students are imported with
(enrolment cancelled)in opacnote - Set to "No" and verify cancelled students are skipped as before
Use default for unmapped
- Set "Use default for unmapped" to "Yes" in plugin settings
- Ensure there are students from schools NOT in the branch mapping
- Run sync and verify these students are imported with the default branchcode
- Set to "No" and verify students are skipped as before
Version 1.89
fix: handle 410 Gone for expired pageTokens in fetchDataFromAPI
Version 1.88
Summary
This PR ensures that ALL users previously processed by the SS12000 plugin have their opacnote field updated to reflect their current status. Previously, some users could slip through without updated comments.
Problem
Users processed by the plugin in previous runs were not having their opacnote updated if:
- They existed in the API but had cancelled/expired enrolments
- They existed in the API with active enrolments but weren't part of main sync
- They had no changes detected during sync
This made it difficult to track which users were still valid and which had issues.
Solution
1. New function: mark_missing_users_from_api
Runs after the main sync completes and:
- Queries all users with SS12000 opacnote not updated today
- Verifies each user against the API using
/persons?civicNo={cardnumber}&expand=enrolments - Updates opacnote based on verification result:
| Status | opacnote text |
|---|---|
| Not in API | No update: user no longer in API |
| Enrolments cancelled | No update: enrolment cancelled |
| Enrolments expired | No update: dateexpiry exceeded |
| No enrolments | No update: no enrolments in API |
| Active enrolments | verified (active enrolment, not in sync) |
2. Skip reason tracking in main sync
- Tracks why users are skipped during main iteration
- Updates opacnote for skipped users with specific reason
- Covers: empty duty role, cancelled enrolments, expired enrolments
3. Timestamp update for 'No changes' users
- Previously these users retained old opacnote dates
- Now updates timestamp to mark user as processed today
4. Enhanced logging in get_current_enrolment
- Provides detailed reason when no valid enrolment found
- Logs whether enrolments are cancelled, outside date range, or missing
5. API verification improvements
- Uses
expand=enrolmentsparameter for full enrolment data - Retry logic (2 attempts) for transient API errors
- Progress logging every 50 users
- Distinguishes between not_found, found, and error states
Technical Notes
- All opacnote updates use SQL CASE statements to handle existing format variations
- Date filtering (
NOT LIKE '%YYYY-MM-DD%') prevents redundant API calls - Sync logic (
addOrUpdateBorrower) remains completely unchanged - Only opacnote/comment handling is affected
Testing
Verified that:
- Users not in API get marked correctly
- Users with cancelled enrolments get proper status
- Users with active enrolments but not synced get verified status
- No changes to actual user data import/update logic
Version 1.87
v1.87: fix fork child PID, shared lock file for cron+http, page_completed status, fix TT numeric comparison warnings in pagination
Version 1.87-1
Summary
When a user is skipped during sync (e.g., due to cancelled enrolment), the plugin now updates the opacnote field to explain why.
Changes
Track skip reason: Added $skip_reason variable to track why a user is being skipped
Update opacnote for skipped users: When $not_import = 1, update the borrower's opacnote with the reason (e.g., 'No update: enrolment cancelled')
Detailed logging in get_current_enrolment(): Now explains specifically why no valid enrolment was found (cancelled, outside date range, etc.)
Dynamic version in create.sh: Package name now automatically extracts version from ExportUsers.pm
Version 1.83
v1.82
Refactor dateexpiry fallback: replace if/elsif chain with hash dispatcher
Fix: read dateexpiry config once per batch, not per user
v1.83
Add dateexpiry field tracking to borrowers change log trigger
Version 1.81
Fix dateexpiry not saved, version string in opacnote, SQL comment syntax
- Validate enrolment_end_date format (YYYY-MM-DD) before passing to SQL to ensure dateexpiry is correctly saved instead of being silently ignored
- Pass version_info as bind parameter instead of interpolating in SQL string to fix stale version (e.g. v1.76) appearing in opacnote after upgrades
- Remove inline Perl comment from SQL statement (flags = -1) that caused potential SQL syntax error when archiving duplicate borrowers
- Pre-build changed_fields_str once instead of calling join/map 4 times in execute() for cleaner and more reliable opacnote update
Version 1.8
fix: resolve organisationCode via parent org for child orgs without organisationCode
In fetchBorrowers, when the enroledAt organisation has no organisationCode
(e.g. Skolenhet with only schoolUnitCode), fall back to looking up the
parentOrganisation and use its organisationCode for branches_mapping matching.
Version 1.78
Fix: Add fallback for NULL dateexpiry in UPDATE query
Version 1.76
Fix: Sync user dateexpiry with IST enrolment periods
- Extract enrolment.endDate from IST API
- Update dateexpiry on user INSERT and UPDATE operations
- Use COALESCE(NULLIF(?, ''), DATE_ADD(...)) for null/empty handling
- Resolves issue where students cannot borrow beyond stale expiry dates
Fixes incorrect dateexpiry values (e.g., 2026-02-07) that don't match actual enrolment periods