// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var REQUEST_NOTIFICATION_EMAIL = 'it-requests@example.com';

var AVAILABLE_LAPTOPS = [
  '15" high Performance Laptop (OS X)',
  '15" high Performance Laptop (Windows)',
  '15" high performance Laptop (Linux)',
  '13" lightweight laptop (Windows)',
];
var AVAILABLE_DESKTOPS = [
  'Standard workstation (Windows)',
  'Standard workstation (Linux)',
  'High performance workstation (Windows)',
  'High performance workstation (Linux)',
  'Mac Pro (OS X)',
];
var AVAILABLE_MONITORS = [
  'Single 27"',
  'Single 32"',
  'Dual 24"',
];

// Form field titles, used for creating the form and as keys when handling
// responses.
/**
 * Add custom menu items when opening the sheet.
 */
function onOpen() {
  SpreadsheetApp.getUi().createMenu('Equipment requests')
      .addItem('Set up', 'setup_')
      .addItem('Clean up', 'cleanup_')
      .addToUi();
}

/**
 * Set up the form and triggers for the workflow.
 */
function setup_() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  if (ss.getFormUrl()) {
    var msg = 'Form already exists. Unlink the form and try again.';
    SpreadsheetApp.getUi().alert(msg);
    return;
  }
  var form = FormApp.create('Equipment Requests')
      .setCollectEmail(true)
      .setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId())
      .setLimitOneResponsePerUser(false);
  form.addTextItem().setTitle('Employee name').setRequired(true);
  form.addTextItem().setTitle('Desk location').setRequired(true);
  form.addDateItem().setTitle('Due date').setRequired(true);
  form.addListItem().setTitle('Laptop').setChoiceValues(AVAILABLE_LAPTOPS);
  form.addListItem().setTitle('Desktop').setChoiceValues(AVAILABLE_DESKTOPS);
  form.addListItem().setTitle('Monitor').setChoiceValues(AVAILABLE_MONITORS);

  // Hide the raw form responses.
  ss.getSheets().forEach(function(sheet) {
    if (sheet.getFormUrl() == ss.getFormUrl()) {
      sheet.hideSheet();
    }
  });
  // Start workflow on each form submit
  ScriptApp.newTrigger('onFormSubmit_')
      .forForm(form)
      .onFormSubmit()
      .create();
  // Archive completed items every 5m.
  ScriptApp.newTrigger('processCompletedItems_')
      .timeBased()
      .everyMinutes(5)
      .create();
}

/**
 * Cleans up the project (stop triggers, form submission, etc.)
 */
function cleanup_() {
  var formUrl = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
  if (!formUrl) {
    return;
  }
  ScriptApp.getProjectTriggers().forEach(function(trigger) {
    ScriptApp.deleteTrigger(trigger);
  });
  FormApp.openByUrl(formUrl)
      .deleteAllResponses()
      .setAcceptingResponses(false);
}

/**
 * Handle new form submissions to trigger the workflow.
 *
 * @param {Object} event - Form submit event
 */
function onFormSubmit_(event) {
  var response = mapResponse_(event.response);
  sendNewEquipmentRequestEmail_(response);
  var equipmentDetails = Utilities.formatString('%s\n%s\n%s',
      response['Laptop'],
      response['Desktop'],
      response['Monitor']);
  var row = ['New',
    '',
    response['Desk location'],
    response['Employee name'],
    response['Desk location'],
    equipmentDetails,
    response['email']];
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Pending requests');
  sheet.appendRow(row);
}

/**
 * Sweeps completed events, notifying the requestors and archiving them
 * to the completed
 *
 * @param {Object} event
 */
function processCompletedItems_() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var pending = ss.getSheetByName('Pending requests');
  var completed = ss.getSheetByName('Completed requests');
  var rows = pending.getDataRange().getValues();
  rows.forEach(function(row, index) {
    var status = row[0];
    if (status === 'Completed' || status == 'Cancelled') {
      pending.deleteRow(index + 1);
      completed.appendRow(row);
      sendEquipmentRequestCompletedEmail_({
        'Employee name': row[3],
        'Desk location': row[4],
        'email': row[6],
      });
    }
  });
}

/**
 * Sends email notifying team a new equipment request has been submitted.
 *
 * @param {Object} request - Request details
 */
function sendNewEquipmentRequestEmail_(request) {
  var template = HtmlService.createTemplateFromFile('new-equipment-request.html');
  template.request = request;
  template.sheetUrl = SpreadsheetApp.getActiveSpreadsheet().getUrl();
  var msg = template.evaluate();
  MailApp.sendEmail({
    to: REQUEST_NOTIFICATION_EMAIL,
    subject: 'New equipment request',
    htmlBody: msg.getContent(),
  });
}

/**
 * Sends email notifying requestor that the equipment has been provided.
 *
 * @param {Object} request - Request details
 */
function sendEquipmentRequestCompletedEmail_(request) {
  var template = HtmlService.createTemplateFromFile('request-complete.html');
  template.request = request;
  var msg = template.evaluate();
  MailApp.sendEmail({
    to: request.email,
    subject: 'Equipment request completed',
    htmlBody: msg.getContent(),
  });
}

/**
 * Converts a form response to an object keyed by the item titles. Allows easier
 * access to response values.
 *
 * @param {FormResponse} response
 * @return {Object} Form values keyed by question title
 */
function mapResponse_(response) {
  var initialValue = {
    email: response.getRespondentEmail(),
    timestamp: response.getTimestamp(),
  };
  return response.getItemResponses().reduce(function(obj, itemResponse) {
    var key = itemResponse.getItem().getTitle();
    obj[key] = itemResponse.getResponse();
    return obj;
  }, initialValue);
}


@@ -3426,142 +3426,277 @@
 var 
-equipmentDetails = Utilities.formatString('%25s%5Cn%25s%5Cn%25s',%0A      response%5B'Laptop'%5D,%0A      response%5B'Desktop'%5D,%0A      response%5B'M
+laptop = response%5B'Laptop'%5D %7C%7C 'Laptop not requested';%0A  var desktop = response%5B'Desktop'%5D %7C%7C 'Desktop not requested';%0A  var monitor = response%5B'Monitor'%5D %7C%7C 'Monitor not requested';%0A  var equipmentDetails = Utilities.formatString('%25s%5Cn%25s%5Cn%25s', laptop, desktop, m
 onitor
-'%5D
 );%0A 

Fix error on form submit when no equipment picked. (#146)