diff --git a/booking_system/booking_system/doctype/booking/booking.py b/booking_system/booking_system/doctype/booking/booking.py index 13c48f8..a245888 100644 --- a/booking_system/booking_system/doctype/booking/booking.py +++ b/booking_system/booking_system/doctype/booking/booking.py @@ -5,6 +5,7 @@ from frappe.model.document import Document from frappe import _ from frappe.utils import get_datetime +import hashlib class Booking(Document): @@ -22,13 +23,45 @@ def autoname(self): def validate_booking(self): - if frappe.db.exists( - "Booking", - { - "resource": self.resource, - "start_time": self.start_time, - "end_time": self.end_time, - "status": "Approved", - }, - ): - frappe.throw(_("Resource {0} is already booked for this time slot").format(self.resource)) + overlapping = frappe.db.sql(""" + SELECT name + FROM `tabBooking` + WHERE resource = %(resource)s + AND status IN ('Approved', 'Pending') + AND name != %(name)s + AND ( + (start_time < %(end_time)s AND end_time > %(start_time)s) + ) + """, { + "resource": self.resource, + "start_time": self.start_time, + "end_time": self.end_time, + "name": self.name or "New Booking" + }, as_dict=True) + + if overlapping: + frappe.throw( + _("Resource {0} is already booked during this time slot").format(self.resource) + ) + + +@frappe.whitelist() +def get_booking_events(start, end, filters=None): + events = [] + booking_plans = frappe.get_all( + "Booking", + fields=["name", "type", "resource", "user", "start_time", "end_time", "posting_date"], + filters={"posting_date": ["between", [start, end]]} + ) + + for booking in booking_plans: + color = "#" + hashlib.md5(booking.type.encode()).hexdigest()[:6] + events.append({ + "id": booking.name, + "title": f"{booking.user} ({booking.type})", + "start": booking.start_time, + "end": booking.end_time, + "color": color + }) + + return events diff --git a/booking_system/hooks.py b/booking_system/hooks.py index b5d3160..4ed81ed 100644 --- a/booking_system/hooks.py +++ b/booking_system/hooks.py @@ -46,7 +46,7 @@ # doctype_js = {"doctype" : "public/js/doctype.js"} # doctype_list_js = {"doctype" : "public/js/doctype_list.js"} # doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"} -# doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"} +doctype_calendar_js = {"Booking" : "public/js/booking_calendar.js"} # Svg Icons # ------------------ diff --git a/booking_system/public/js/booking_calendar.js b/booking_system/public/js/booking_calendar.js new file mode 100644 index 0000000..fe8d401 --- /dev/null +++ b/booking_system/public/js/booking_calendar.js @@ -0,0 +1,16 @@ +frappe.views.calendar["Booking"] = { + field_map: { + "start": "start_time", + "end": "end_time", + "id": "name", + "title": "title" + }, + options: { + header: { + left: "prev,next today", + center: "title", + right: "month,agendaWeek,agendaDay" + } + }, + get_events_method: "booking_system.booking_system.doctype.booking.booking.get_booking_events" +};