Merge branch 'develop' of https://github.com/0Pranav/erpnext into develop
diff --git a/erpnext/crm/doctype/appointment/appointment.json b/erpnext/crm/doctype/appointment/appointment.json
index 356cbea..b2fe7b9 100644
--- a/erpnext/crm/doctype/appointment/appointment.json
+++ b/erpnext/crm/doctype/appointment/appointment.json
@@ -11,7 +11,9 @@
   "customer_name",
   "customer_phone_number",
   "customer_skype",
-  "customer_details"
+  "customer_details",
+  "lead",
+  "calender_event"
  ],
  "fields": [
   {
@@ -56,9 +58,23 @@
    "label": "Status",
    "options": "Open\nClosed",
    "reqd": 1
+  },
+  {
+   "fieldname": "lead",
+   "fieldtype": "Link",
+   "label": "Lead",
+   "options": "Lead",
+   "reqd": 1
+  },
+  {
+   "fieldname": "calender_event",
+   "fieldtype": "Link",
+   "label": "Calender Event",
+   "options": "Event",
+   "reqd": 1
   }
  ],
- "modified": "2019-09-10 11:17:20.200603",
+ "modified": "2019-09-12 10:42:47.841841",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Appointment",
diff --git a/erpnext/crm/doctype/appointment/appointment.py b/erpnext/crm/doctype/appointment/appointment.py
index cce6a1d..4c95c6e 100644
--- a/erpnext/crm/doctype/appointment/appointment.py
+++ b/erpnext/crm/doctype/appointment/appointment.py
@@ -3,6 +3,7 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+from datetime import timedelta
 import frappe
 from frappe.model.document import Document
 
@@ -12,4 +13,15 @@
 		settings = frappe.get_doc('Appointment Booking Settings')
 		if(number_of_appointments_in_same_slot>=settings.number_of_agents):
 			frappe.throw('Time slot is not available')
+	
+	def before_insert(self):
+		appointment_event = frappe.new_doc('Event')
+		appointment_event.subject = 'Appointment with ' + self.customer_name
+		appointment_event.starts_on = self.scheduled_time
+		appointment_event.status = 'Open'
+		appointment_event.type = 'Private'
+		settings = frappe.get_doc('Appointment Booking Settings')
+		appointment_event.ends_on = self.scheduled_time + timedelta(minutes=settings.appointment_duration)
+		appointment_event.insert()
+		self.calender_event = appointment_event.name
 
diff --git a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
index 11820b9..6ef0070 100644
--- a/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
+++ b/erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
@@ -7,8 +7,9 @@
   "availability_of_slots",
   "number_of_agents",
   "holiday_list",
+  "appointment_duration",
   "email_reminders",
-  "appointment_duration"
+  "advance_booking_days"
  ],
  "fields": [
   {
@@ -19,6 +20,7 @@
    "reqd": 1
   },
   {
+   "default": "1",
    "fieldname": "number_of_agents",
    "fieldtype": "Int",
    "in_list_view": 1,
@@ -34,21 +36,28 @@
    "reqd": 1
   },
   {
+   "default": "60",
+   "fieldname": "appointment_duration",
+   "fieldtype": "Int",
+   "label": "Appointment Duration (In Minutes)",
+   "reqd": 1
+  },
+  {
    "default": "0",
    "fieldname": "email_reminders",
    "fieldtype": "Check",
    "label": "Email Reminders"
   },
   {
-   "default": "60",
-   "fieldname": "appointment_duration",
+   "default": "7",
+   "fieldname": "advance_booking_days",
    "fieldtype": "Int",
-   "label": "Appointment Duration",
+   "label": "Number of days appointments can be booked in advance",
    "reqd": 1
   }
  ],
  "issingle": 1,
- "modified": "2019-09-10 15:02:39.969131",
+ "modified": "2019-09-12 10:52:25.931931",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Appointment Booking Settings",
diff --git a/erpnext/crm/doctype/timezone/timezone.py b/erpnext/crm/doctype/timezone/timezone.py
index f0da6e3..2c77023 100644
--- a/erpnext/crm/doctype/timezone/timezone.py
+++ b/erpnext/crm/doctype/timezone/timezone.py
@@ -12,3 +12,6 @@
         if self.offset > 720 or self.offset < -720:
             frappe.throw(
                 'Timezone offsets must be between -720 and +720 minutes')
+        if frappe.db.exists({'doctype':'Timezone','offset':self.offset}):
+            frappe.throw(
+                'Timezone offsets need to be unique')
\ No newline at end of file
diff --git a/erpnext/www/book-appointment/index.html b/erpnext/www/book-appointment/index.html
index f407427..2e03213 100644
--- a/erpnext/www/book-appointment/index.html
+++ b/erpnext/www/book-appointment/index.html
@@ -13,7 +13,7 @@
     <div id="select-date-time">
         <div class="text-center mb-5">
             <h3>Book an appointment</h3>
-            <p class="lead text-muted">Select the date and your timezone</p>
+            <p class="lead text-muted" id="lead-text">Select the date and your timezone</p>
         </div>
         <div class="row justify-content-center mt-3">
             <div class="col-md-6 align-self-center ">
@@ -51,9 +51,14 @@
                 placeholder="Contact Number" required>
             <input class="form-control mt-3" type="text" name="customer_skype" id="customer_skype" placeholder="Skype"
                 required>
+            <input class="form-control mt-3"type="email" name="customer_email" id="customer_email" 
+                placeholder="Email Address">
             <textarea class="form-control mt-3" name="customer_notes" id="customer_notes" cols="30" rows="10"
                 placeholder="Notes"></textarea>
-            <button class="btn btn-primary form-control mt-3" onclick="submit()" id="submit-button">Submit</button>
+            <div class="row mt-3 ">
+                <div class="col-md"><button class="btn btn-dark form-control" onclick="initialise_select_date()">Go back</button></div>
+                <div class="col-md"><button class="btn btn-primary form-control " onclick="submit()" id="submit-button">Submit</button></div>
+            </div>
         </div>
     </div>
 </div>
diff --git a/erpnext/www/book-appointment/index.js b/erpnext/www/book-appointment/index.js
index 61ea8e4..96ad66a 100644
--- a/erpnext/www/book-appointment/index.js
+++ b/erpnext/www/book-appointment/index.js
@@ -5,7 +5,7 @@
 window.holiday_list = [];
 
 async function initialise_select_date() {
-    document.getElementById('enter-details').style.display = 'none';
+    navigate_to_page(1);
     await get_global_variables();
     setup_date_picker();
     setup_timezone_selector();
@@ -43,7 +43,8 @@
     let date_picker = document.getElementById('appointment-date');
     let today = new Date();
     date_picker.min = today.toISOString().substr(0, 10);
-    date_picker.max = window.holiday_list.to_date;
+    today.setDate(today.getDate() + window.appointment_settings.advance_booking_days);
+    date_picker.max = today.toISOString().substr(0,10);
 }
 
 function hide_next_button(){
@@ -69,6 +70,8 @@
     window.selected_date = date_picker.value;
     window.selected_timezone = timezone.value;
     update_time_slots(date_picker.value, timezone.value);
+    let lead_text = document.getElementById('lead-text');
+    lead_text.innerHTML = "Select Time"
 }
 
 async function get_time_slots(date, timezone) {
@@ -113,7 +116,6 @@
         timeslot_container.appendChild(timeslot_div);
     });
     set_default_timeslot();
-    show_next_button();
 }
 
 function clear_time_slots() {
@@ -144,6 +146,7 @@
     window.selected_time = this.id
     selected_element.classList.remove("selected");
     this.classList.add("selected");
+    show_next_button();
 }
 
 function set_default_timeslot() {
@@ -157,11 +160,25 @@
     }
 }
 
-function setup_details_page(){
+function navigate_to_page(page_number){
     let page1 = document.getElementById('select-date-time');
     let page2 = document.getElementById('enter-details');
-    page1.style.display = 'none';
-    page2.style.display = 'block';
+    switch(page_number){
+        case 1: 
+            page1.style.display = 'block';
+            page2.style.display = 'none';
+            break;
+        case 2:
+            page1.style.display = 'none';
+            page2.style.display = 'block';
+            break;
+        default:
+            console.log("That's not a valid page")
+    }
+}
+
+function setup_details_page(){
+    navigate_to_page(2)
     let date_container = document.getElementsByClassName('date-span')[0];
     let time_container = document.getElementsByClassName('time-span')[0];
     date_container.innerHTML = moment(window.selected_date).format("MMM Do YYYY");
@@ -194,6 +211,7 @@
     contact.number = document.getElementById('customer_number').value;
     contact.skype = document.getElementById('customer_skype').value;
     contact.notes = document.getElementById('customer_notes').value;
+    contact.email = document.getElementById('customer_email').value;
     window.contact = contact
     console.log({ date, time, contact });
 }
diff --git a/erpnext/www/book-appointment/index.py b/erpnext/www/book-appointment/index.py
index 1b87b86..530445f 100644
--- a/erpnext/www/book-appointment/index.py
+++ b/erpnext/www/book-appointment/index.py
@@ -94,8 +94,16 @@
     appointment.customer_skype = contact['skype']
     appointment.customer_details = contact['notes']
     appointment.status = 'Open'
+    appointment.lead = find_lead_by_email(contact['email']).name
     appointment.insert()
 
+def find_lead_by_email(email):
+    if frappe.db.exists({
+        'doctype':'Lead',
+        'email_id':email
+    }):
+        return frappe.get_list('Lead',filters={'email_id':email})[0]
+    frappe.throw('Email ID not associated with any Lead. Please make sure to use the email address you got this mail on')
 
 # Helper Functions
 def filter_timeslots(date, timeslots):