Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2026, efeone and contributors
// For license information, please see license.txt

frappe.ui.form.on('Communication Log', {
onload: function(frm) {
set_logged_in_employee(frm);
}
});

/*
* Populate the "Logged By" field with the Employee linked to the current session user.
*/
function set_logged_in_employee(frm) {
if (!frm.doc.logged_by) {
frappe.db.get_value('Employee', {
user_id: frappe.session.user
}, 'name').then(r => {
if (r.message && r.message.name) {
frm.set_value('logged_by', r.message.name);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "CML-.YYYY.-.####",
"creation": "2026-04-08 13:44:29.225107",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"communication_type",
"subject",
"from_party",
"to_party",
"column_break_stha",
"communication_date",
"logged_by",
"reference_doctype",
"reference_name",
"attachments",
"section_break_sqts",
"remarks"
],
"fields": [
{
"fieldname": "communication_type",
"fieldtype": "Select",
"label": "Communication Type",
"options": "Letter\nNotice\nCircular\nEmail\nMemo"
},
{
"fieldname": "subject",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Subject",
"reqd": 1
},
{
"fieldname": "from_party",
"fieldtype": "Data",
"label": "From Party",
"reqd": 1
},
{
"fieldname": "to_party",
"fieldtype": "Data",
"label": "To Party",
"reqd": 1
},
{
"fieldname": "column_break_stha",
"fieldtype": "Column Break"
},
{
"default": "Today",
"fieldname": "communication_date",
"fieldtype": "Date",
"label": "Communication Date",
"reqd": 1
},
{
"fieldname": "logged_by",
"fieldtype": "Link",
"label": "Logged By",
"options": "Employee",
"read_only": 1
},
{
"fieldname": "reference_doctype",
"fieldtype": "Link",
"label": "Reference Doctype",
"options": "DocType"
},
{
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"label": "Reference Name",
"options": "reference_doctype"
},
{
"fieldname": "attachments",
"fieldtype": "Attach",
"label": "Attachments"
},
{
"fieldname": "section_break_sqts",
"fieldtype": "Section Break"
},
{
"fieldname": "remarks",
"fieldtype": "Small Text",
"label": "Remarks"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2026-04-08 13:44:29.225107",
"modified_by": "admin@example.com",
"module": "General Administration Management System",
"name": "Communication Log",
"naming_rule": "Expression",
"owner": "admin@example.com",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"row_format": "Dynamic",
"rows_threshold_for_grid_search": 20,
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2026, efeone and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class CommunicationLog(Document):
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2026, efeone and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestCommunicationLog(FrappeTestCase):
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) 2026, efeone and contributors
// For license information, please see license.txt

frappe.ui.form.on('Meeting Room Booking', {
onload: function(frm) {
set_meeting_room_filter(frm);
set_logged_in_employee(frm);
}
});

/**
* Ensures only rooms with status = "Active"
* are available for selection
*/
function set_meeting_room_filter(frm) {
frm.set_query('meeting_room', function() {
return {
filters: {
status: 'Active'
}
};
});
}

/*
* Populate the "booked_by" field with the Employee linked to the current session user.
*/
function set_logged_in_employee(frm) {
if (!frm.doc.booked_by) {

// Get current logged-in user
const user = frappe.session.user;

if (!user) {
console.log("Session user not found");
return;
}

// Fetch Employee linked to user
frappe.db.get_value('Employee', {
user_id: user
}, 'name').then(r => {
if (r.message && r.message.name) {
frm.set_value('booked_by', r.message.name);
} else {
frappe.msgprint("No Employee linked to this user");
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "RBK-.YYYY.-.####",
"creation": "2026-04-08 13:43:45.894498",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"meeting_room",
"booked_by",
"employee_name",
"column_break_xgfu",
"booking_date",
"from_time",
"to_time",
"section_break_tmdv",
"description",
"status",
"section_break_fwch",
"attendees"
],
"fields": [
{
"fieldname": "meeting_room",
"fieldtype": "Link",
"label": "Meeting Room",
"options": "Room",
"reqd": 1
},
{
"fieldname": "booked_by",
"fieldtype": "Link",
"label": "Booked By",
"options": "Employee",
"reqd": 1
},
{
"fetch_from": "booked_by.employee_name",
"fieldname": "employee_name",
"fieldtype": "Data",
"label": "Employee Name",
"read_only": 1
},
{
"fieldname": "column_break_xgfu",
"fieldtype": "Column Break"
},
{
"default": "Today",
"fieldname": "booking_date",
"fieldtype": "Date",
"label": "Booking Date"
},
{
"fieldname": "from_time",
"fieldtype": "Time",
"in_list_view": 1,
"label": "From Time",
"reqd": 1
},
{
"fieldname": "to_time",
"fieldtype": "Time",
"in_list_view": 1,
"label": "To Time",
"reqd": 1
},
{
"fieldname": "section_break_tmdv",
"fieldtype": "Section Break"
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"label": "Description",
"reqd": 1
},
{
"fieldname": "status",
"fieldtype": "Select",
"label": "Status",
"options": "Pending\nApproved\nRejected\nCancelled"
},
{
"fieldname": "section_break_fwch",
"fieldtype": "Section Break"
},
{
"fieldname": "attendees",
"fieldtype": "Table",
"label": "Attendees",
"options": "Resource Booking Attendee"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2026-04-08 13:43:45.894498",
"modified_by": "admin@example.com",
"module": "General Administration Management System",
"name": "Meeting Room Booking",
"naming_rule": "Expression",
"owner": "admin@example.com",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"row_format": "Dynamic",
"rows_threshold_for_grid_search": 20,
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright (c) 2026, efeone and contributors
# For license information, please see license.txt

import frappe
from frappe.model.document import Document
from frappe.utils import getdate, nowdate, get_time

class MeetingRoomBooking(Document):

def validate(self):
self.validate_time()
self.validate_date()
self.validate_room_availability()

def validate_time(self):
if self.from_time and self.to_time:
if self.to_time <= self.from_time:
frappe.throw("To Time must be greater than From Time")

def validate_date(self):
if self.booking_date:
if getdate(self.booking_date) < getdate(nowdate()):
frappe.throw("Booking Date cannot be in the past")

def validate_room_availability(self):
Comment thread
ZakkiyathLulu marked this conversation as resolved.
"""
Ensure booking is within room's available time window
"""

if not self.meeting_room:
return

room = frappe.get_doc("Room", self.meeting_room)

from_time = get_time(self.from_time)
to_time = get_time(self.to_time)
available_from = get_time(room.availability_from)
available_to = get_time(room.availability_to)

if from_time < available_from or to_time > available_to:
frappe.throw(
f"Booking not permitted outside room availability hours "
f"({available_from} - {available_to})"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2026, efeone and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestMeetingRoomBooking(FrappeTestCase):
pass
Loading
Loading