βOct 01, 2020 11:12 AM
I have a scheduling base for Volunteers helping at Non-Profits. I am wondering if it is possible accomplish these with a formula?
I have attached a generic base to give you an idea of what i am looking for. I have entered the answers into the fields as an Example via text.
#1. Volunteering with -
If multiple volunteers are on the (same date, same location, same start time, same stop time), I would like column " :raising_hand_man: Volunteering with :raising_hand_man: " to show the names of each volunteer on the same detail.
#2. Double Booked -
If a volunteer is signed up for multiple details the same day I would like a column β :eyes: Double Booked/Overlapping Shifts :eyes: β, if they are double booked or have overlapping shifts.
#3. Relieving/Relieved by -
I would like two columns " :handshake: Relieving Volunteer :handshake: " & " :handshake: Relieved By Volunteer :handshake: " to list the names of those volunteers if applicable (ie. If one shift ends and another one starts. Shift one is 8:00am-10:00am, shift two is 10:00am-2:00pm, shift three is 2:00pm-4:00pm, etc.)
Thanks for any help you can provide!
βOct 02, 2020 11:37 AM
Awesome thanks Kamille! I am just starting to dig into learning to script :slightly_smiling_face:
P.S. Do you also do custom scripting for hire? If so, I may need to hire you for some other upcoming challenges I run into.
Thanks again
βOct 02, 2020 11:41 AM
The answer 9/10 is no. Sometimes if thereβs a fun use case within my capability Iβll consider it, but most times I do not. There are several highly talented consultants lurking in the forum that you can consider however.
βOct 02, 2020 11:46 AM
Well I do appreciate all the help, I just feel bad asking a ton of questions with really no compensation :slightly_smiling_face: They need some sort of tip button in the forum for the people so dedicated to help others :slightly_smiling_face:
βOct 02, 2020 01:29 PM
@Kamille_Parks Sorry, another question if you get time.
Would it be hard to add these to the original script?
For Double Booked/Overlapping Shifts:
If shift date & hours are the same display βDouble Bookedβ & If shift date & hours only overlap display βOverlapβ otherwise βNoβ
For Volunteering,:
If same shift does not have a volunteer assigned yet display βTBDβ in place of Volunteer Name.
*this could be accomplished using a formula field IF(volunteer="",TBD,volunteer) but think would make sense to have in the script instead?
For Relieving Volunteer & Relieved By Volunteer:
Same idea - If same shift does not have a volunteer assigned yet display βTBDβ in place of Volunteer Name.
Thanks again
βOct 02, 2020 01:40 PM
For TBD you could replace the part of the script inside .updateRecordAsync()
using this format:
'Name of Field': value ? value : 'TBD'
Replace value
with whatever the script currently has there.
As for editing the double booking part: Yes its possible, no I donβt want to do it.
βOct 06, 2020 12:57 PM
I have been fine tuning this script for my needs and thought I would post the updates in case it can benefit anyone else.
@Kamille_Parks - Thanks again for getting me going on this. It has been fun to learn how scripting works and look forward to learning more.
This is the first time I have ever worked with scripting, so my modifications may have not been the best way, but they seem to work :slightly_smiling_face:
Changes Made:
For Double Booked/Overlapping Shifts: If shift date & hours are the same display βDouble Bookedβ & If shift date & hours only overlap display βOverlapβ otherwise βNoβ
For Volunteering: If same shift does not have a volunteer assigned yet display βTBDβ in place of Volunteer Name. I also created another field so I could separate the volunteers assigned to same location/same hours & volunteers assigned to same location/overlapping hours.
For Relieving Volunteer & Relieved By Volunteer: Same idea - If same shift does not have a volunteer assigned yet display βTBDβ in place of Volunteer Name.
Code:
const scheduleT = base.getTable('Schedule') const scheduleQ = await scheduleT.selectRecordsAsync() const scheduleR = scheduleQ.records const trigger = await input.recordAsync('Which schedule record do you want to gather info about?', scheduleT) const triggerValues = { id: trigger.id, volunteer: trigger.getCellValueAsString('Volunteer'), start: new Date(trigger.getCellValue('Start')), stop: new Date(trigger.getCellValue('Stop')), location: trigger.getCellValue('Location'), } const shiftRecords = scheduleR.map(x => {return ( { id: x.id, volunteer: x.getCellValueAsString('Volunteer') ? x.getCellValueAsString('Volunteer'):'TBD', start: new Date(x.getCellValue('Start')), stop: new Date(x.getCellValue('Stop')), location: x.getCellValue('Location'), } )}) const sameShiftRecordsexact = shiftRecords.filter(x => { return ( ((triggerValues.start <= x.start && triggerValues.stop >= x.stop)) && (x.location == triggerValues.location) ) }) const sameShiftRecordsoverlap = shiftRecords.filter(x => { return ( ((triggerValues.start > x.start && triggerValues.start < x.stop) || x.start > triggerValues.start && x.start < triggerValues.stop) && (x.location == triggerValues.location) ) }) const isDoubleBooked = (shiftRecords.filter(x => { return ( (x.id !== triggerValues.id) && (x.volunteer == triggerValues.volunteer) && ((triggerValues.start <= x.start && triggerValues.stop >= x.stop)) ) }).length > 0) ? 'π« Double Booked' : (shiftRecords.filter(x => { return ( (x.id !== triggerValues.id) && (x.volunteer == triggerValues.volunteer) && ((triggerValues.start > x.start && triggerValues.start < x.stop) || x.start > triggerValues.start && x.start < triggerValues.stop) ) }).length > 0) ? 'β Overlap': 'β No' const prevShiftRecords = shiftRecords.filter(x => { return (x.stop.toISOString() == triggerValues.start.toISOString()&& (x.location == triggerValues.location)) }) const nextShiftRecords = shiftRecords.filter(x => { return (x.start.toISOString() == triggerValues.stop.toISOString()&& (x.location == triggerValues.location)) }) output.table({ ['Volunteer']: triggerValues.volunteer, ['Start']: triggerValues.start, ['Stop']: triggerValues.stop, ['Volnteering (same shift)']: Array(...(sameShiftRecordsexact.map(x => x.volunteer))).join(', '), ['Volnteering (overlapping shift)']: Array(...(sameShiftRecordsoverlap.map(x => x.volunteer))).join(', '), ['Double Booked?']: isDoubleBooked, ['Relieving']: Array(...(prevShiftRecords.map(x => x.volunteer))).join(', '), ['Relieved By']: Array(...(nextShiftRecords.map(x => x.volunteer))).join(', '), }) await scheduleT.updateRecordAsync(triggerValues.id, { 'EXAMPLE πββοΈVolunteering (exact shifts) πββοΈ': Array(...(sameShiftRecordsexact.map(x => x.volunteer))).join(', '), 'EXAMPLE πββοΈVolunteering with (overlapping shifts) πββοΈ': Array(...(sameShiftRecordsoverlap.map(x => x.volunteer))).join(', '), 'EXAMPLE π Double Booked/Overlapping Shifts π': isDoubleBooked.toString(), 'EXAMPLE π€Relieving Volunteerπ€': Array(...(prevShiftRecords.map(x => x.volunteer))).join(', '), 'EXAMPLE π€Relieved By Volunteerπ€': Array(...(nextShiftRecords.map(x => x.volunteer))).join(', ') })
βOct 06, 2020 10:02 PM
Ok, I just found a little hiccup in the code and am having a tough time finding a solution.
For my βsameShiftRecordsexactβ it is pulling in data if the chosen shift is within another shift and not just exactly the same.
I thought this part
((triggerValues.start <= x.start && triggerValues.stop >= x.stop)) &&
would just need
==
instead of
<=
but that didnβt work :frowning: Any help is greatly appreciated :slightly_smiling_face:
βOct 07, 2020 12:53 AM
Did you set both <=
and >=
to ==
?
βOct 07, 2020 09:04 AM
Yeah, when I change them both to ==
it is not recognizing anything for the βsameShiftRecordsExactβ.
((triggerValues.start == x.start && triggerValues.stop == x.stop)) &&
βOct 07, 2020 03:15 PM
Disregard. I finally figured it out :slightly_smiling_face: Had to change this block of code to with the βtoISOStringβ
Thanks again.
const sameShiftRecordsExact = shiftRecords.filter(x => {
return (x.start.toISOString() == triggerValues.start.toISOString()&& (x.stop.toISOString() == triggerValues.stop.toISOString()&& (x.location == triggerValues.location)) )
})