如何为允许在 google 日历上进行 3d 冲突检测的事件分配标签?

How to assign a tag to an event that would allow for 3d conflict detection on a google calendar?

我正在尝试创建一个资源管理系统,允许我办公室的成员通过表格预订房间,在 public 日历上创建日历事件。

我在创建过程中面临的问题围绕着冲突检查的复杂性,因为我希望所有日历事件都位于每个办公室的一个日历上。结果是一个日历上有多个资源,我的冲突检查脚本不仅要检查冲突事件,还要评估事件所在的房间。

理想情况下,我需要脚本先检查是否有任何冲突,如果有,然后检查冲突事件的房间名称。如果事件在不同的房间,它将批准事件创建。否则,它将被拒绝,表单响应者将收到一封电子邮件。我已经仔细阅读了文档,但由于我对语言和编码的一般知识有限,我一直无法找到好的解决方案。

起初,我以为我可以比较活动描述,我会根据表单提交的输入将其设置为房间名称。当我在开始和结束时间内调用所有冲突时,我将使用要创建的事件的描述来评估它们的描述,并从那里进行检查。不幸的是,根据我的测试,无法处理多个冲突事件。

然后我得到了我在这里列出的内容,其中我有一系列过去提交的房间,来自表格所附的电子表格,它会检查它们。这里的问题是它只考虑房间名称的开始和结束时间。

我的主要问题是,有没有一种方法可以在创建时为我的事件分配某种标签,然后我可以在我的脚本的冲突检查部分中回调。理想情况下,我可以自己分配这个标签,然后使用新的表单提交数据进行评估。我认为最好的方法是邀请房间资源参加活动,但我也不知道该怎么做。

function getConflicts(request){
  var conflicts = request.calendar.getEvents(request.dateTime, request.edateTime);
  //var description = conflicts.getDescription(); 
  if(conflicts.length >= 1){
        Logger.log(conflicts.length);

    for (var i=0; i<conflicts.length; i++) {
  if (request.room != request.slroom[i]) {

    request.status = "Approve";
  } else if (request.room == request.slroom[i]) {
    request.status = "Conflict";

  }
}}
else     request.status = "Approve";

}

完整脚本:

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var lastColumn = sheet.getLastColumn();

var calendarb = CalendarApp.getCalendarById("link");

function Submission(){
  var row = lastRow;
  var slrow = (lastRow-1);
  this.timestamp = sheet.getRange(row, 1).getValue();
  this.name = sheet.getRange(row , 3).getValue() + ": " + sheet.getRange(row, 5).getValue();
  this.email = sheet.getRange(row, 2).getValue();
  this.dateTime = sheet.getRange(row, 6).getValue();
  this.edateTime = sheet.getRange(row,7).getValue();
  this.room = sheet.getRange(row, 5).getValue();
  this.slroom = sheet.getRange(2, 5, (lastRow-1)).getValues();
  this.roomstart =sheet.getRange(2, 6, (lastRow-1)).getValues();
  this.roomend = sheet.getRange(2, 7, (lastRow-1)).getValues();


  //this.roomInt = this.room.replace(/\D+/g, '');
  //this.status;
  this.calendar = calendarb;
  return this;
  var event;
}



function getConflicts(request){
  var conflicts = request.calendar.getEvents(request.dateTime, request.edateTime);
  //var description = conflicts.getDescription(); 
  if(conflicts.length >= 1){
        Logger.log(conflicts.length);


    for (var i=0; i<conflicts.length; i++) {
  if (request.room != request.slroom[i]) {

    request.status = "Approve";
  } else if (request.room == request.slroom[i]) {
    request.status = "Conflict";

  }
}}
else     request.status = "Approve";

}


function draftEmail(request){
  request.buttonLink = "link";
  request.buttonText = "New Request";
  switch (request.status) {
    case "Approve":
      request.subject = "Confirmation: " + request.room + " Reservation for " + request.dateTime + "-" + request.edateTime;
      request.header = "Confirmation";
      request.message = "Your room reservation has been scheduled.";
      break;
    case "Conflict":
      request.subject = "Conflict with " + request.room + " Reservation for " + request.dateTime + "-" + request.edateTime;
      request.header = "Conflict";
      request.message = "There is a scheduling conflict. Please pick another room or time."
      request.buttonText = "Reschedule";
      break;
  }
}

function updateCalendar(request){

  var event = {
    summary: request.name,
    location: 'Location',
    description: request.room,
    start: {
      dateTime: request.dateTime.toISOString()
    },
    end: {
      dateTime: request.edateTime.toISOString()
    },
    attendees: [
      {email: request.email}
    ],
    tag: request.room

  };
  event = Calendar.Events.insert(event, "Calandar ID");
  // request.calendar.addSmsReminder(10);
    Logger.log('Event Tag: ' + event.description);

  Logger.log('Event ID: ' + event.id);
   }
  



function sendEmail(request){
  MailApp.sendEmail({
    to: request.email,
    subject: request.header,
    htmlBody: makeEmail(request)
  })
  sheet.getRange(lastRow, 8).setValue("Sent: " + request.status);
}


function main(){
  var request = new Submission();
  getConflicts(request);
  draftEmail(request);
  if (request.status == "Approve") updateCalendar(request);
  sendEmail(request);
}

我的电子表格是按此顺序设置的

A:时间戳 B:电子邮件地址 C:姓名 D:位置 E:房间 F:开始日期和时间 G:结束日期和时间

Sample Sheet

根据您的代码,您将 room 详细信息存储在活动描述中。为什么不使用冲突事件的描述来检查房间是否仍然可用?以这种方式,我们不需要标记我们的事件。

我还修改了一些行以提高整个脚本的效率。请参阅下面的更改。

代码:

function Submission() {
  // get values by bulk
  var rowValues = sheet.getRange(lastRow, 1, 1, 7).getValues().flat();
  // avoid using this as that contains another values you don't need
  // create a request variable instead
  var request = {};
  request.timestamp = rowValues[0];
  request.name = rowValues[2] + ": " + rowValues[4];
  request.email = rowValues[1];
  request.dateTime = rowValues[5];
  request.edateTime = rowValues[6];
  request.room = rowValues[4];
  request.calendar = calendarb;
  // No need to store previous lists of rooms and their time. 
  // See getConflicts for clarification
  return request;
}

function getConflicts(request) {
  var conflicts = request.calendar.getEvents(request.dateTime, request.edateTime);
  // Since you stored the room into the description
  // Filter the conflicts by comparing conflicts' descriptions to the room
  if(conflicts.filter(conflict => conflict.getDescription() == request.room).length > 0)
    request.status = "Conflict";
  else
    request.status = "Approve";
}

变化:

  • 批量获取行值。
  • 创建 request 变量而不是使用 this。后者包含您不需要的其他值。
  • 删除了获取其他事件的过去房间和日期时间值。
  • 利用冲突的描述并通过将其与您的房间进行比较来过滤它们。