You can download the full release notes as a PDF above for detailed information on all updates and fixes included in this version.

If there are any post-install steps required, they will be listed below. In V.0.146, more detailed information on the Post Installation steps of the new Mobile Care Worker Experience are listed directly below in a seperate section.

Mobile Care Worker Experience App Post Installation Checklist

Apps & Navigation

  • Activate Maica: Client Delivery – Care Mobile for the right profiles/permission sets and add its Home tab to mobile navigation so the Planner cmp loads on launch.

Lightning Record Pages

  • Re-activate the packaged Appointment record page so the highlights panel exposes View in Planner, Generate Invoice (Completed), Confirm Completion (Under Review), and standard actions on both desktop and phone.
  • On the Contact record page, keep the Maica - Photo component with prefix Photo and variant container-filled so the mobile photo card renders properly.

Page layouts

  • Appointment (both layouts): surface Review Reason near Status and ensure the scheduling section retains the travel minute field for visibility.
  • Appointment Resource: include the new Travel Management and Travel Approval sections with origin/destination, actual/proposed travel metrics, and approval fields.
  • Appointment Service: add Participant Notes Requirement to the main section.
  • Client Goal: expose the Archived checkbox in system information.
  • Resource & Resource Asset layouts: place Roster Mode and Primary Experience with the core identity fields.
  • Unavailability: add the All Day checkbox near the date fields.

Fields, Picklists & Access:

  • Confirm the new picklists Participant Notes Requirement and Primary Experience (Mobile/Desktop) are available to the relevant record types and permission sets; adjust value visibility if subscriber orgs lock picklists.

Permission Sets: 

  • New permission sets that were added in this release, as listed below. These should be reviewed and assigned to Users appropriately by function. It is important to note that assigning them all would mean you will achieve what currently exists, as the below functions weren’t previously wrapped with the Permission Sets.
  • The following Permission Sets were added: 
  1. Maica - Global - Manage Participant Notes
  2. Maica - Global - Create Participant Notes
  3. Maica - Global - View Appointment
  4. Maica - Global - View Shift
  5. Maica - Global - Manage Appointment
  6. Maica - Global - Manage Shift
  7. Maica - Global - Create Appointment
  8. Maica - Global - Create Shift
  9. Maica - Global - Check In/Out on behalf of Others
  10. Maica - Planner - Appointment Optimiser
  11. Maica - Planner - Manage Appointment - Check In/Out
  12. Maica - Planner - Manage Shift - Check In/Out
  13. Maica - Planner - Manage Appointment - Enable Hyperlinks
  14. Maica - Planner - Manage Appointment - Manage Quantity
  15. Maica - Planner - Show Route
  16. Maica - Planner - Support Available
  • To learn about the details of each Permission Set, please refer to the following table

Settings & Reference Data

  • Update Planner Setting records so Manage Location remains in Quick Info actions and populate Start Day of Week (defaults to Monday).
  • Fill Support Email and Support Phone on General Setting to power the Need Help modal in the planner.
  • Review Travel Setting distance and duration tolerances to align with your approval thresholds.

Validation

  • Exercise the Confirm Completion quick action on appointments and verify button visibility rules on the highlights panel.
  • Open the Need Help flow from the planner and confirm the surfaced phone/email reflect your updated settings.

Data Migration Script (Anonymous Apex):

Distribute historic appointment-level travel totals across accepted Appointment Resources so the new rollups preserve existing figures. Run in smaller batches if needed.

/**
 * Anonymous Apex: redistribute appointment-level travel metrics to accepted Appointment Resources.
 */
List<maica__Appointment__c> appointments = [
        SELECT Id, maica__Travel_mins__c, maica__Travel_kms__c, maica__Travel_Proportion__c, maica__Travel_Proportion_kms__c,
        (SELECT Id, maica__Status__c FROM maica__Appointment_Resources__r)
        FROM maica__Appointment__c
        WHERE maica__Travel_mins__c != null
        OR maica__Travel_kms__c != null
        OR maica__Travel_Proportion__c != null
        OR maica__Travel_Proportion_kms__c != null
];

List<maica__Appointment_Resource__c> resourcesToUpdate = new List<maica__Appointment_Resource__c>();

for (maica__Appointment__c appointment : appointments) {
    List<maica__Appointment_Resource__c> accepted = new List<maica__Appointment_Resource__c>();
    for (maica__Appointment_Resource__c resource : appointment.maica__Appointment_Resources__r) {
        if ('Accepted'.equals(resource.maica__Status__c)) {
            accepted.add(resource);
        }
    }

    if (accepted.isEmpty()) {
        System.debug(LoggingLevel.WARN,
                'Appointment ' + appointment.Id + ' has travel totals but no accepted Appointment Resources.');
        continue;
    }

    Integer count = accepted.size();
    Decimal totalMins = appointment.maica__Travel_mins__c;
    Decimal totalKms = appointment.maica__Travel_kms__c;
    Decimal totalPropMins = appointment.maica__Travel_Proportion__c;
    Decimal totalPropKms = appointment.maica__Travel_Proportion_kms__c;

    Decimal shareMins = totalMins == null ? null
            : (totalMins / count).setScale(0, System.RoundingMode.DOWN);
    Decimal shareKms = totalKms == null ? null
            : (totalKms / count).setScale(2, System.RoundingMode.DOWN);
    Decimal sharePropMins = totalPropMins == null ? null
            : (totalPropMins / count).setScale(0, System.RoundingMode.DOWN);
    Decimal sharePropKms = totalPropKms == null ? null
            : (totalPropKms / count).setScale(2, System.RoundingMode.DOWN);

    Decimal distributedMins = 0, distributedKms = 0, distributedPropMins = 0, distributedPropKms = 0;

    for (Integer i = 0; i < accepted.size(); i++) {
        maica__Appointment_Resource__c updateRec = new maica__Appointment_Resource__c(Id = accepted[i].Id);
        Boolean touched = false;

        if (totalMins != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalMins - distributedMins)
                    : shareMins;
            value = value.setScale(0, System.RoundingMode.HALF_UP);
            distributedMins += value;
            updateRec.maica__Travel_mins__c = value;
            touched = true;
        }
        if (totalKms != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalKms - distributedKms)
                    : shareKms;
            value = value.setScale(2, System.RoundingMode.HALF_UP);
            distributedKms += value;
            updateRec.maica__Travel_kms__c = value;
            touched = true;
        }
        if (totalPropMins != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalPropMins - distributedPropMins)
                    : sharePropMins;
            value = value.setScale(0, System.RoundingMode.HALF_UP);
            distributedPropMins += value;
            updateRec.maica__Travel_Proportion_mins__c = value;
            touched = true;
        }
        if (totalPropKms != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalPropKms - distributedPropKms)
                    : sharePropKms;
            value = value.setScale(2, System.RoundingMode.HALF_UP);
            distributedPropKms += value;
            updateRec.maica__Travel_Proportion_kms__c = value;
            touched = true;
        }

        if (touched) {
            updateRec.maica__Travel_Approved__c = true;
            resourcesToUpdate.add(updateRec);
        }
    }
}

if (!resourcesToUpdate.isEmpty()) {
    update resourcesToUpdate;
}
11:46
added the namespace
New
11:46
for OEM:
/**
 * Anonymous Apex: redistribute appointment-level travel metrics to accepted Appointment Resources.
 */
List<maica_cc__Appointment__c> appointments = [
        SELECT Id, maica_cc__Travel_mins__c, maica_cc__Travel_kms__c, maica_cc__Travel_Proportion__c, maica_cc__Travel_Proportion_kms__c,
        (SELECT Id, maica_cc__Status__c FROM maica_cc__Appointment_Resources__r)
        FROM maica_cc__Appointment__c
        WHERE maica_cc__Travel_mins__c != null
        OR maica_cc__Travel_kms__c != null
        OR maica_cc__Travel_Proportion__c != null
        OR maica_cc__Travel_Proportion_kms__c != null
];

List<maica_cc__Appointment_Resource__c> resourcesToUpdate = new List<maica_cc__Appointment_Resource__c>();

for (maica_cc__Appointment__c appointment : appointments) {
    List<maica_cc__Appointment_Resource__c> accepted = new List<maica_cc__Appointment_Resource__c>();
    for (maica_cc__Appointment_Resource__c resource : appointment.maica_cc__Appointment_Resources__r) {
        if ('Accepted'.equals(resource.maica_cc__Status__c)) {
            accepted.add(resource);
        }
    }

    if (accepted.isEmpty()) {
        System.debug(LoggingLevel.WARN,
                'Appointment ' + appointment.Id + ' has travel totals but no accepted Appointment Resources.');
        continue;
    }

    Integer count = accepted.size();
    Decimal totalMins = appointment.maica_cc__Travel_mins__c;
    Decimal totalKms = appointment.maica_cc__Travel_kms__c;
    Decimal totalPropMins = appointment.maica_cc__Travel_Proportion__c;
    Decimal totalPropKms = appointment.maica_cc__Travel_Proportion_kms__c;

    Decimal shareMins = totalMins == null ? null
            : (totalMins / count).setScale(0, System.RoundingMode.DOWN);
    Decimal shareKms = totalKms == null ? null
            : (totalKms / count).setScale(2, System.RoundingMode.DOWN);
    Decimal sharePropMins = totalPropMins == null ? null
            : (totalPropMins / count).setScale(0, System.RoundingMode.DOWN);
    Decimal sharePropKms = totalPropKms == null ? null
            : (totalPropKms / count).setScale(2, System.RoundingMode.DOWN);

    Decimal distributedMins = 0, distributedKms = 0, distributedPropMins = 0, distributedPropKms = 0;

    for (Integer i = 0; i < accepted.size(); i++) {
        maica_cc__Appointment_Resource__c updateRec = new maica_cc__Appointment_Resource__c(Id = accepted[i].Id);
        Boolean touched = false;

        if (totalMins != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalMins - distributedMins)
                    : shareMins;
            value = value.setScale(0, System.RoundingMode.HALF_UP);
            distributedMins += value;
            updateRec.maica_cc__Travel_mins__c = value;
            touched = true;
        }
        if (totalKms != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalKms - distributedKms)
                    : shareKms;
            value = value.setScale(2, System.RoundingMode.HALF_UP);
            distributedKms += value;
            updateRec.maica_cc__Travel_kms__c = value;
            touched = true;
        }
        if (totalPropMins != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalPropMins - distributedPropMins)
                    : sharePropMins;
            value = value.setScale(0, System.RoundingMode.HALF_UP);
            distributedPropMins += value;
            updateRec.maica_cc__Travel_Proportion_mins__c = value;
            touched = true;
        }
        if (totalPropKms != null) {
            Decimal value = (i == accepted.size() - 1)
                    ? (totalPropKms - distributedPropKms)
                    : sharePropKms;
            value = value.setScale(2, System.RoundingMode.HALF_UP);
            distributedPropKms += value;
            updateRec.maica_cc__Travel_Proportion_kms__c = value;
            touched = true;
        }

        if (touched) {
            updateRec.maica_cc__Travel_Approved__c = true;
            resourcesToUpdate.add(updateRec);
        }
    }
}

if (!resourcesToUpdate.isEmpty()) {
    update resourcesToUpdate;
}

Run the block via Developer Console (Execute Anonymous). Adjust filtering or batching if your org has a large appointment volume.

If you require assistance or have any question around the above, please contact Maica Support for guidance.

Post Installation Scripts
If you require assistance with installing or running these scripts, please contact Maica Support for guidance.

Optional: Enable Total Committed Calculation in Client Care Settings -> General Settings.

View Code

Optional: Add the Calculate Total Committed QA on the Service Agreement/Agreement Item record pages.

View Code

Optional: Enable the Total Committed Calculation Scheduled Job in Client Care Settings -> Scheduled Jobs.

View Code

View Code

View Code