Example Suggestion Function for Dynamic Scheduling

Hi, I’m trying to implement a Suggestion Function to control where pucks can be placed. When I run my function right now I’m getting “Failed to execute the suggestion function” when I load the widget. I have some Tasks that need to be scheduled in a specific order, based on the predecessors and successors so I’m hoping the suggestion function can enforce that.

Does anyone have a working suggestion function?

Also if I create some more unscheduled objects in my scenario with an action after the gantt widget has loaded that means I can’t use a suggestion function, right?

thanks.

Hi @tdw0 !

I have two examples for you. These examples show how to highlight a vertical slice of time and how to highlight a horizontal slice of time. You could of course have a suggestion function that does a mix of both. Let me know if you run into trouble!

Re:

Also if I create some more unscheduled objects in my scenario with an action after the gantt widget has loaded that means I can’t use a suggestion function, right?

No, the suggestion function will not be aware of these new objects

EXAMPLE 1:

This suggestion function is used to make sure that users are only changing the production line an order is scheduled on (vertical slice). This is achieved by taking a pucks’s scheduled start date and highlighting only that day across all production lines.

@Function()
public suggestOrderPlacement(scheduleObjectPrimaryKeys: string[], domainStart: Timestamp, domainEnd: Timestamp): FunctionsMap<string, FunctionsMap<string, Array<{ domain: { start: Long, end: Long }, rating: Float }>>> {
    const orders = Objects.search().legolasProductionOrder().filter(o => o.orderNumber.exactMatch(...scheduleObjectPrimaryKeys)).all();

    const suggestions: ISuggestionResult = new FunctionsMap<string, ISlotMappings>();

    orders.forEach(o => {
        if (o.scheduledStartDate && o.durationMs) {
            const allRowsMapping: ISlotMappings = new FunctionsMap<string, IValidSlots>();
            const startTime = o.scheduledStartDate.valueOf();
            allRowsMapping.set(ALL_ROWS_ID, [{
                domain: {
                    start: startTime,
                    end: startTime + o.durationMs,
                },
                rating: 1,
            }]);
            suggestions.set(o.orderNumber, allRowsMapping);
        }
    });

    return suggestions;
}

EXAMPLE 2:
This suggestion function is used to make sure that users are only changing the time of events and not who the event is assigned to (horizontal slice).

@Function()
public suggestScheduleBlocks(scheduleObjectPrimaryKeys: string[], domainStart: Timestamp, domainEnd: Timestamp): FunctionsMap<string, FunctionsMap<string, Array<{ domain: { start: Long, end: Long }, rating: Float }>>> {  
    const schSpec = Objects.search().conferenceSchedule().filter(s => s.scheduleId.exactMatch(...scheduleObjectPrimaryKeys));
    const events = schSpec.searchAroundConferenceEvent().all();
    const schedules = schSpec.all();

    const eventByEventId = keyBy(events, e => e.eventId);

    const suggestions: ISuggestionV2Result = new FunctionsMap<string, ISlotMappings>();
    schedules.forEach(sch => {
        const event = sch.eventId ? eventByEventId[sch.eventId] : undefined;
        if (event && event.startTime && event.endTime) {
            if (sch.eventType?.startsWith("Breakout Group")) {
                const allRowsMapping: ISlotMappings = new FunctionsMap<string, IValidSlots>();
                allRowsMapping.set(ALL_ROWS_ID, [{
                    domain: {
                        start: event.startTime.getTime(),
                        end: event.endTime.getTime(),
                    },
                    rating: 1,
                }]);
                suggestions.set(sch.scheduleId, allRowsMapping);
            } else if (sch.attendeeId) {
                const singleRowMapping: ISlotMappings = new FunctionsMap<string, IValidSlots>(); 
                singleRowMapping.set(sch.attendeeId, [{
                    domain: {
                        start: domainStart.getTime(),
                        end: domainEnd.getTime(),
                    },
                    rating: 1,
                }]);
                suggestions.set(sch.scheduleId, singleRowMapping);
            }
        }
    });

    return suggestions;
}