CC-485: Appointment Resource Status Logic

Enhancement: Appointment Resource Status Logic & Acceptance Workflow

We’ve introduced significant enhancements to the Appointment Resource Status logic in Maica to support better control over which Resources are considered approved to attend Appointments and to introduce a flexible, permissions-based acceptance workflow. These changes improve visibility, security, and data integrity across both individual and recurring Appointments.

What's Changed?

New Status Logic for Appointment Resources: The system now respects the Appointment Resource Status, enabling workflows based on statuses like Pending or Accepted. Default status can be configured via a new Setting. If no setting is defined, the system defaults to Accepted (to preserve backward compatibility).

New Restrictions for Unaccepted Resources: Resources who have not been marked as Accepted cannot: Check In/Out, Quick Complete or Cancel Appointments

Permission-Based Acceptance Actions: New permission sets introduced to control acceptance actions: Accept Own Resource and Accept All Resources. Additionally, the system now shows tailored messages based on whether the user has these permissions.

Visual Indicators and Acceptance UI: A warning icon and tooltip now appear for unaccepted Appointment Resources. Users with appropriate permissions can now accept resources directly via the Appointment Wizard or Manage Appointment modal. Messaging varies based on the user’s relationship to the resource:

  1. "You have not accepted this Appointment. Click the button below to confirm your availability."
  2. "The Resource has not accepted this Appointment. You can accept on their behalf by clicking the button below."
  3. “You do not have permission to accept this Appointment on their behalf.”

Recurring Appointments Now Inherit Status: When Recurring Appointments are created from a Master, the Appointment Resource Status is inherited from the Master Appointment. Updates to the Master Appointment status can cascade to scheduled Appointments, but only when triggered manually (e.g., by editing the Master).

Validation Enhancements: Appointments with Pending or Unaccepted Resources are displayed as Unfilled in the Planner. These can still be seen by the Resource and accepted provided the correct Permission Sets are assigned. Appointments now respect Resource-to-Participant ratios and ensure the correct number of Accepted Resources are assigned.

Improved Messaging & Tooltips: The system now shows clear, role-based messages explaining why a user can or cannot accept a Resource or perform an action. Messages dynamically switch between “Appointment” and “Shift” depending on the record type.

Compatibility & Upgrade Considerations: A post-install script ensures that existing Appointment Resources are set to Accepted if no default is defined—preserving historical behavior.

Example Scenarios:

  • A Resource is assigned to an Appointment but is still in Pending status: ❌ Cannot check in, complete, or cancel the Appointment.
  • A Scheduler has the Accept All permission: ✅ Can accept any Resource and update their status directly from the UI.
  • A Care Worker tries to accept their own resource without permission: ❌ System blocks the action with a clear message.
  • Recurring Appointment is generated from a Master with Accepted status: ✅ All linked Appointments inherit the Accepted status.
  • Scheduler adds a Resource via the Wizard and wants to approve on the spot: ✅ Can click the warning icon to approve directly.
  • A Resource attempts to check in for another Resource: ❌ Not allowed unless explicitly permitted.

CC-501: Checklist Item Not Persisting Correctly in the Manage Appointment Modal

Fix: Checklist Item Notes Now Persist Correctly in the Manage Appointment Modal

We resolved an issue where Notes entered against a Checklist Item within the Manage Appointment modal were not being retained after saving. Users found that notes were either missing or overwritten upon re-entry, causing confusion and potential loss of important information.

What's Changed?

Checklist Notes Now Persist After Save: When users complete a Checklist Item and add Notes, the system now saves and returns those values reliably. Users can exit and re-enter the Checklist modal, and the previously entered Notes will remain visible and unchanged.

Prevents Overwriting of Notes on Re-Entry: The bug causing new entries to overwrite previously saved Notes has been fixed. Users can now confidently add incremental updates or review historical context without losing data.

Applies to All Checklist Item Statuses: The fix supports all status values (e.g., Completed, In Progress, etc.) where Notes are captured, regardless of the Checklist Item’s current state.

CC-504: Timesheet Duration Not Updating When Unavailability Start/End Times Are Modified

Fix: Timesheet Duration Now Updates When Unavailability Start/End Times Are Modified

We resolved an issue where editing the Start and/or End Date/Time of an Unavailability record in the Planner did not correctly update the Duration (Minutes) on the related Timesheet Entry. This caused discrepancies in Timesheet calculations and required manual corrections by users.

What's Changed?

Duration Now Recalculates Automatically: When users edit the Start Date/Time or End Date/Time of an Unavailability entry, the system now automatically recalculates the Duration (Minutes) field on the corresponding Timesheet Entry. This ensures that the recorded duration always reflects the updated availability window.

Fix Applies to All Edited Unavailabilities: Whether users change just the start time, just the end time, or both — the calculated duration is now kept in sync. This applies to all Unavailability records where “Create Corresponding Timesheet = TRUE”.

No Additional Action Required by Users: The update is applied in real time when users submit changes through the Manage Unavailability modal in the Planner. No need to manually open and resave the Timesheet Entry to refresh the Duration.

NDIS-834: Incorrect Utilisation Calculations on Agreement Items

Fix: Utilisation Calculations on Agreement Items are now Corrected

We resolved an issue where Agreement Items displayed incorrect utilisation percentages and negative remaining balances due to inconsistencies in how Quantity and Unit Price were ratioed in relation to Invoice Line Item records. This fix ensures accurate financial calculations, preventing over-utilisation errors and incorrect funding balances.

What's Changed?

New Quantity Delivered Field for Accurate Roll-Ups: Introduced Quantity Delivered field on Delivery Activity. This field captures the actual ratioed quantity, ensuring correct utilization calculations. Roll-ups on Agreement Items now sum Quantity Delivered instead of Quantity.

Enhanced Handling of Ratio-Based Calculations: The system now correctly differentiates between Unit Price Ratioed and Quantity Ratioed Invoice Line Item records, ensuring that the Quantity Delivered field on the Agreement Item always respects your preferred method of ratio calculation set under Maica settings. If Unit Price or Quantity is ratioed, Maica applies the ratio to a new Quantity Delivered field on the Invoice Line Item, which the Agreement Item now uses to calculate Quantity Delivered. This prevents cases where the Quantity Delivered field on the Agreement Item displayed inflated, non-ratioed Quantities if your preferred method of ratio calculation was defined as Unit Price in Maica Settings. 

CC-512: Schedule frequency change resulting in creation of new Schedule also applied to original Schedule

Fix: Schedule Splitting Logic Now Preserves Original Schedule Values

We resolved an issue where editing an Appointment within an existing Schedule (not the Master) unintentionally updated both the original schedule and the newly created schedule during a schedule split. This resulted in incorrect recurrence patterns and unexpected additional Appointments, particularly when switching between weekly and fortnightly frequencies.

Issue Summary

When an Appointment within a schedule (not the Master) was edited, Maica attempted to split the schedule: The current Appointment became the Master of a new schedule & the previous schedule was supposed to end on the day before the updated Appointment.

However, all UI changes (e.g., Frequency updates) were incorrectly applied to both the original and new schedules, causing both to reflect the updated values. For example, changing a Fortnightly schedule to Weekly caused both schedules to become Weekly, which in turn led to duplicate Appointments being created for the original schedule beyond its intended end date.

What's Changed? 

Corrected Cloning Logic During Schedule Splits: The system now ensures that when splitting a schedule the original schedule retains its original values (e.g., Frequency, Interval) and only the End Date of the original schedule is updated to one day before the Appointment’s Scheduled Start.

New Schedule Now Uses Updated Values: The current Appointment becomes the Master of a new schedule, which begins on the Scheduled Start Date of that Appointment. The new Schedule inherits all UI changes, ensuring accurate recurrence going forward.

Pre-Split UI Changes Are No Longer Propagated Prematurely: UI changes are temporarily held until the system confirms a schedule split is required. This prevents incorrect values from being applied to the existing schedule.

Prevents Duplicate Appointment Creation: The updated logic ensures that the original schedule ends cleanly, preventing the system from generating extra Appointments based on the wrong Frequency.

Example Scenarios:

  • A user updates a Fortnightly Appointment within a schedule to be Weekly: ✅ The original schedule remains Fortnightly and ends correctly; a new Weekly schedule begins from the updated Appointment.
  • A schedule split occurs due to an update in location, Resource, or service frequency: ✅ Only the new schedule reflects the change; the old schedule ends with original values.
  • A user changes an Appointment without triggering a schedule split: ✅ No changes are made to the schedule unless a split is required.
Post Installation Scripts
If you require assistance with installing or running any script, please contact Maica Support for guidance.

NDIS-834: Required post-install script to update all Invoice Line Items to populate Quantity Delivered

View Code

new maica.vertic_UpdateRecordsBatch(maica__Invoice_Line_Item__c.SObjectType, 'Id != NULL').setOptAllOrNone(false).run();

NDIS-834: Required post-install script to update all Agreement Items to populate Quantity Delivered. Please ensure you run the Invoice Line Item script shown above to completion before running this script. You can track the progress of the Job in your Salesforce instance by going to Setup --> Apex Jobs.

View Code

new maica.vertic_UpdateRecordsBatch(maica__Agreement_Item__c.SObjectType, 'Id != NULL').setOptAllOrNone(false).run();

CC-504: Required script to reevaluate Duration on TSE related to Unavailability (updates only records where reevaluated value it different to one on the record, basically when Unavailability was changed):

View Code

List<maica__Timesheet_Entry__c> entries = [SELECT Id, maica__Duration_Minutes__c, maica__Start_Time__c, maica__End_Time__c FROM maica__Timesheet_Entry__c WHERE maica__Unavailability__c != NULL];
List<maica__Timesheet_Entry__c> recordsToUpdate = new List<maica__Timesheet_Entry__c>();
for (maica__Timesheet_Entry__c entry : entries) { Decimal newDuration = 0; if (entry.maica__Start_Time__c != null || entry.maica__End_Time__c != null) { Long dt1Long = entry.maica__Start_Time__c.getTime(); Long dt2Long = entry.maica__End_Time__c.getTime(); Long milliseconds = dt2Long - dt1Long; Long seconds = milliseconds / 1000; Long minutes = seconds / 60; newDuration = minutes.intValue(); } if (newDuration != entry.maica__Duration_Minutes__c) { entry.maica__Duration_Minutes__c = newDuration; recordsToUpdate.add(entry); }
}
update recordsToUpdate;

CC-485: Required script to set Default Appointment/Shift Status to Accepted if the field is EMPTY in the org:

View Code

if (String.isBlank(maica__Appointment_Setting__c.getOrgDefaults().maica__Default_Shift_Resource_Status__c)) { upsert new maica__Appointment_Setting__c(Id = maica__Appointment_Setting__c.getOrgDefaults()?.Id, maica__Default_Shift_Resource_Status__c = 'Accepted');
} if (String.isBlank(maica__Appointment_Setting__c.getOrgDefaults().maica__Default_Appointment_Resource_Status__c)) { upsert new maica__Appointment_Setting__c(Id = maica__Appointment_Setting__c.getOrgDefaults()?.Id, maica__Default_Appointment_Resource_Status__c = 'Accepted');
}

CC-485: Optional script that sets Appointment Resource Status to Accepted if the Default value in the settings is Accepted only for those records where Status is not Accepted yet for some reason.

View Code

if ('Accepted'.equalsIgnoreCase(maica__Appointment_Setting__c.getOrgDefaults().maica__Default_Appointment_Resource_Status__c)) { Map<Id, maica__Appointment_Resource__c> appointmentResourceMap = new Map<Id, maica__Appointment_Resource__c>([SELECT Id FROM maica__Appointment_Resource__c WHERE maica__Status__c != 'Accepted' AND maica__Appointment__r.RecordType.DeveloperName = 'Appointment']); for (maica__Appointment_Resource__c appRes : appointmentResourceMap.values()) { appRes.maica__Status__c = 'Accepted'; } new maica.vertic_UpdateRecordsBatch(maica__Appointment_Resource__c.SObjectType, appointmentResourceMap, null).setOptAllOrNone(false).run();
} if ('Accepted'.equalsIgnoreCase(maica__Appointment_Setting__c.getOrgDefaults().maica__Default_Shift_Resource_Status__c)) { Map<Id, maica__Appointment_Resource__c> appointmentResourceMap = new Map<Id, maica__Appointment_Resource__c>([SELECT Id FROM maica__Appointment_Resource__c WHERE maica__Status__c != 'Accepted' AND maica__Appointment__r.RecordType.DeveloperName = 'Shift']); for (maica__Appointment_Resource__c appRes : appointmentResourceMap.values()) { appRes.maica__Status__c = 'Accepted'; } new maica.vertic_UpdateRecordsBatch(maica__Appointment_Resource__c.SObjectType, appointmentResourceMap, null).setOptAllOrNone(false).run();
}