โ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)) )
})