Hotels (#11907)
* [new-module] hotels, start
* Multiple Changes
Hotel Settings Added
Make invoice on Hotel Reservation
* Hotel Room validation for overbooking
* Added test fixtures and test for Hotels
* Added Tests for Hotels
Overbooking
Pricing not set
* [WIP] Documentation
Hotel Room and Screenshot
* Added Calendar view for Hotel Room Reservation
* Added Report - Hotel Room Occupancy
* Added Hotel Reservation User in Hospitality domain
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index 7556083..3c18844 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -360,6 +360,14 @@
"hidden": 1
},
{
+ "module_name": "Hotels",
+ "color": "#EA81E8",
+ "icon": "fa fa-bed",
+ "type": "module",
+ "label": _("Hotels"),
+ "hidden": 1
+ },
+ {
"module_name": "Agriculture",
"color": "#8BC34A",
"icon": "octicon octicon-globe",
diff --git a/erpnext/docs/assets/img/hotels/hotel-room.png b/erpnext/docs/assets/img/hotels/hotel-room.png
new file mode 100644
index 0000000..7aad227
--- /dev/null
+++ b/erpnext/docs/assets/img/hotels/hotel-room.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/hospitality/hotel-room.md b/erpnext/docs/user/manual/en/hospitality/hotel-room.md
new file mode 100644
index 0000000..b788d1b
--- /dev/null
+++ b/erpnext/docs/user/manual/en/hospitality/hotel-room.md
@@ -0,0 +1,5 @@
+# Hotel Room
+
+Hotel Room is a master to create hotel rooms for reservation
+
+<img class="screenshot" alt="Hotel Room" src="/docs/assets/img/hotels/hotel-room.png">
diff --git a/erpnext/docs/user/manual/en/hospitality/index.md b/erpnext/docs/user/manual/en/hospitality/index.md
index efd7377..dc6c743 100644
--- a/erpnext/docs/user/manual/en/hospitality/index.md
+++ b/erpnext/docs/user/manual/en/hospitality/index.md
@@ -6,4 +6,8 @@
The Restaurant module in ERPNext will help you manage a chain of restaurants. You can create Restaurants, Menus, Tables, Reservations and a manage Order Entry and Billing.
+### Manage Hotels
+
+The Hotels module in ERPNext will help you manage creating Hotel Rooms, create Hotel Room Reservation. It will also help in creating Invoice from hotel room reservation
+
{index}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/hospitality/index.txt b/erpnext/docs/user/manual/en/hospitality/index.txt
index cbe6da0..0c909d8 100644
--- a/erpnext/docs/user/manual/en/hospitality/index.txt
+++ b/erpnext/docs/user/manual/en/hospitality/index.txt
@@ -1,4 +1,5 @@
restaurant
restaurant-menu
reservations
-order-entry
\ No newline at end of file
+order-entry
+hotel-room
diff --git a/erpnext/domains/hospitality.py b/erpnext/domains/hospitality.py
index bc55d9c..09b98c2 100644
--- a/erpnext/domains/hospitality.py
+++ b/erpnext/domains/hospitality.py
@@ -1,6 +1,7 @@
data = {
'desktop_icons': [
'Restaurant',
+ 'Hotels',
'Accounts',
'Buying',
'Stock',
@@ -9,7 +10,9 @@
'ToDo'
],
'restricted_roles': [
- 'Restaurant Manager'
+ 'Restaurant Manager',
+ 'Hotel Manager',
+ 'Hotel Reservation User'
],
'custom_fields': {
'Sales Invoice': [
diff --git a/erpnext/hotels/__init__.py b/erpnext/hotels/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/__init__.py
diff --git a/erpnext/hotels/doctype/__init__.py b/erpnext/hotels/doctype/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room/__init__.py b/erpnext/hotels/doctype/hotel_room/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room/hotel_room.js b/erpnext/hotels/doctype/hotel_room/hotel_room.js
new file mode 100644
index 0000000..76f22d5
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room/hotel_room.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Hotel Room', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/hotels/doctype/hotel_room/hotel_room.json b/erpnext/hotels/doctype/hotel_room/hotel_room.json
new file mode 100644
index 0000000..2567c07
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room/hotel_room.json
@@ -0,0 +1,175 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "prompt",
+ "beta": 1,
+ "creation": "2017-12-08 12:33:56.320420",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "hotel_room_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Hotel Room Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Hotel Room Type",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "capacity",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Capacity",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "extra_bed_capacity",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Extra Bed Capacity",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:10:50.670113",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Hotel Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room/hotel_room.py b/erpnext/hotels/doctype/hotel_room/hotel_room.py
new file mode 100644
index 0000000..8471aee
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room/hotel_room.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoom(Document):
+ def validate(self):
+ if not self.capacity:
+ self.capacity, self.extra_bed_capacity = frappe.db.get_value('Hotel Room Type',
+ self.hotel_room_type, ['capacity', 'extra_bed_capacity'])
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room/test_hotel_room.js b/erpnext/hotels/doctype/hotel_room/test_hotel_room.js
new file mode 100644
index 0000000..8b2b833
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room/test_hotel_room.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Hotel Room", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Hotel Room
+ () => frappe.tests.make('Hotel Room', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/hotels/doctype/hotel_room/test_hotel_room.py b/erpnext/hotels/doctype/hotel_room/test_hotel_room.py
new file mode 100644
index 0000000..00d3aea
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room/test_hotel_room.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+test_records = [
+ dict(doctype="Hotel Room", name="1001",
+ hotel_room_type="Basic Room"),
+ dict(doctype="Hotel Room", name="1002",
+ hotel_room_type="Basic Room"),
+ dict(doctype="Hotel Room", name="1003",
+ hotel_room_type="Basic Room"),
+ dict(doctype="Hotel Room", name="1004",
+ hotel_room_type="Basic Room"),
+ dict(doctype="Hotel Room", name="1005",
+ hotel_room_type="Basic Room"),
+ dict(doctype="Hotel Room", name="1006",
+ hotel_room_type="Basic Room")
+]
+
+class TestHotelRoom(unittest.TestCase):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_amenity/__init__.py b/erpnext/hotels/doctype/hotel_room_amenity/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_amenity/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_amenity/hotel_room_amenity.json b/erpnext/hotels/doctype/hotel_room_amenity/hotel_room_amenity.json
new file mode 100644
index 0000000..29a0407
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_amenity/hotel_room_amenity.json
@@ -0,0 +1,103 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-08 12:35:36.572185",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Item",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "billable",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Billable",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:05:07.125687",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Amenity",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_amenity/hotel_room_amenity.py b/erpnext/hotels/doctype/hotel_room_amenity/hotel_room_amenity.py
new file mode 100644
index 0000000..69da007
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_amenity/hotel_room_amenity.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoomAmenity(Document):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_package/__init__.py b/erpnext/hotels/doctype/hotel_room_package/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_package/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.js b/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.js
new file mode 100644
index 0000000..5b09ae5
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.js
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Hotel Room Package', {
+ hotel_room_type: function(frm) {
+ if (frm.doc.hotel_room_type) {
+ frappe.model.with_doc('Hotel Room Type', frm.doc.hotel_room_type, () => {
+ let hotel_room_type = frappe.get_doc('Hotel Room Type', frm.doc.hotel_room_type);
+
+ // reset the amenities
+ frm.doc.amenities = [];
+
+ for (let amenity of hotel_room_type.amenities) {
+ let d = frm.add_child('amenities');
+ d.item = amenity.item;
+ d.billable = amenity.billable;
+ }
+
+ frm.refresh();
+ });
+ }
+ }
+});
diff --git a/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.json b/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.json
new file mode 100644
index 0000000..57dad44
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.json
@@ -0,0 +1,215 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "prompt",
+ "beta": 1,
+ "creation": "2017-12-08 12:43:17.211064",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "hotel_room_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Hotel Room Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Hotel Room Type",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_4",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amenities",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amenities",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Hotel Room Amenity",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:10:31.111952",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Package",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.py b/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.py
new file mode 100644
index 0000000..8a62eea
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_package/hotel_room_package.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoomPackage(Document):
+ def validate(self):
+ if not self.item:
+ item = frappe.get_doc(dict(
+ doctype = 'Item',
+ item_code = self.name,
+ item_group = 'Products',
+ is_stock_item = 0,
+ stock_uom = 'Unit'
+ ))
+ item.insert()
+ self.item = item.name
diff --git a/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.js b/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.js
new file mode 100644
index 0000000..f1ebad4
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Hotel Room Package", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Hotel Room Package
+ () => frappe.tests.make('Hotel Room Package', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.py b/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.py
new file mode 100644
index 0000000..ebf7f2b
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+test_records = [
+ dict(doctype='Item', item_code='Breakfast',
+ item_group='Products', is_stock_item=0),
+ dict(doctype='Item', item_code='Lunch',
+ item_group='Products', is_stock_item=0),
+ dict(doctype='Item', item_code='Dinner',
+ item_group='Products', is_stock_item=0),
+ dict(doctype='Item', item_code='WiFi',
+ item_group='Products', is_stock_item=0),
+ dict(doctype='Hotel Room Type', name="Delux Room",
+ capacity=4,
+ extra_bed_capacity=2,
+ amenities = [
+ dict(item='WiFi', billable=0)
+ ]),
+ dict(doctype='Hotel Room Type', name="Basic Room",
+ capacity=4,
+ extra_bed_capacity=2,
+ amenities = [
+ dict(item='Breakfast', billable=0)
+ ]),
+ dict(doctype="Hotel Room Package", name="Basic Room with Breakfast",
+ hotel_room_type="Basic Room",
+ amenities = [
+ dict(item="Breakfast", billable=0)
+ ]),
+ dict(doctype="Hotel Room Package", name="Basic Room with Lunch",
+ hotel_room_type="Basic Room",
+ amenities = [
+ dict(item="Breakfast", billable=0),
+ dict(item="Lunch", billable=0)
+ ]),
+ dict(doctype="Hotel Room Package", name="Basic Room with Dinner",
+ hotel_room_type="Basic Room",
+ amenities = [
+ dict(item="Breakfast", billable=0),
+ dict(item="Dinner", billable=0)
+ ])
+]
+
+class TestHotelRoomPackage(unittest.TestCase):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_pricing/__init__.py b/erpnext/hotels/doctype/hotel_room_pricing/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.js b/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.js
new file mode 100644
index 0000000..87bb192
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Hotel Room Pricing', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.json b/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.json
new file mode 100644
index 0000000..0f5a776
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.json
@@ -0,0 +1,266 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "prompt",
+ "beta": 1,
+ "creation": "2017-12-08 12:51:47.088174",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "enabled",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Enabled",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "currency",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "from_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "From Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "to_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "To Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "items",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Items",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Hotel Room Pricing Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:10:41.559559",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Pricing",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Hotel Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.py b/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.py
new file mode 100644
index 0000000..8eee0f2
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing/hotel_room_pricing.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoomPricing(Document):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.js b/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.js
new file mode 100644
index 0000000..ba0d1fd
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Hotel Room Pricing", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Hotel Room Pricing
+ () => frappe.tests.make('Hotel Room Pricing', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.py b/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.py
new file mode 100644
index 0000000..2b7848b
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+test_records = [
+ dict(doctype="Hotel Room Pricing", enabled=1,
+ name="Winter 2017",
+ from_date="2017-01-01", to_date="2017-01-10",
+ items = [
+ dict(item="Basic Room with Breakfast", rate=10000),
+ dict(item="Basic Room with Lunch", rate=11000),
+ dict(item="Basic Room with Dinner", rate=12000)
+ ])
+]
+
+class TestHotelRoomPricing(unittest.TestCase):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_item/__init__.py b/erpnext/hotels/doctype/hotel_room_pricing_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_item/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_item/hotel_room_pricing_item.json b/erpnext/hotels/doctype/hotel_room_pricing_item/hotel_room_pricing_item.json
new file mode 100644
index 0000000..d6cd826
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_item/hotel_room_pricing_item.json
@@ -0,0 +1,103 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-08 12:50:13.486090",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Item",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Rate",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:04:58.641703",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Pricing Item",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_item/hotel_room_pricing_item.py b/erpnext/hotels/doctype/hotel_room_pricing_item/hotel_room_pricing_item.py
new file mode 100644
index 0000000..6bf01bf
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_item/hotel_room_pricing_item.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoomPricingItem(Document):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_package/__init__.py b/erpnext/hotels/doctype/hotel_room_pricing_package/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_package/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.js b/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.js
new file mode 100644
index 0000000..f6decd9
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Hotel Room Pricing Package', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.json b/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.json
new file mode 100644
index 0000000..92bd980
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.json
@@ -0,0 +1,162 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-08 12:50:13.486090",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "from_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "From Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "to_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "To Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "hotel_room_package",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Hotel Room Package",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Hotel Room Package",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Rate",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-08 12:52:01.743866",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Pricing Package",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.py b/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.py
new file mode 100644
index 0000000..9ae9fcf
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_package/hotel_room_pricing_package.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoomPricingPackage(Document):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.js b/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.js
new file mode 100644
index 0000000..73a561c
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Hotel Room Pricing Package", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Hotel Room Pricing Package
+ () => frappe.tests.make('Hotel Room Pricing Package', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.py b/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.py
new file mode 100644
index 0000000..fec1c86
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestHotelRoomPricingPackage(unittest.TestCase):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_reservation/__init__.py b/erpnext/hotels/doctype/hotel_room_reservation/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.js b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.js
new file mode 100644
index 0000000..2c9fd7b
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.js
@@ -0,0 +1,68 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Hotel Room Reservation', {
+ refresh: function(frm) {
+ if(frm.doc.docstatus == 1){
+ frm.add_custom_button(__("Make Invoice"), ()=> {
+ frm.trigger("make_invoice");
+ });
+ }
+ },
+ from_date: function(frm) {
+ frm.trigger("recalculate_rates");
+ },
+ to_date: function(frm) {
+ frm.trigger("recalculate_rates");
+ },
+ recalculate_rates: function(frm) {
+ if (!frm.doc.from_date || !frm.doc.to_date
+ || !frm.doc.items.length){
+ return;
+ }
+ frappe.call({
+ "method": "erpnext.hotels.doctype.hotel_room_reservation.hotel_room_reservation.get_room_rate",
+ "args": {"hotel_room_reservation": frm.doc}
+ }).done((r)=> {
+ for (var i = 0; i < r.message.items.length; i++) {
+ frm.doc.items[i].rate = r.message.items[i].rate;
+ frm.doc.items[i].amount = r.message.items[i].amount;
+ }
+ frappe.run_serially([
+ ()=> frm.set_value("net_total", r.message.net_total),
+ ()=> frm.refresh_field("items")
+ ]);
+ });
+ },
+ make_invoice: function(frm) {
+ frappe.model.with_doc("Hotel Settings", "Hotel Settings", ()=>{
+ frappe.model.with_doctype("Sales Invoice", ()=>{
+ let hotel_settings = frappe.get_doc("Hotel Settings", "Hotel Settings");
+ let invoice = frappe.model.get_new_doc("Sales Invoice");
+ invoice.customer = frm.doc.customer || hotel_settings.default_customer;
+ if (hotel_settings.default_invoice_naming_series){
+ invoice.naming_series = hotel_settings.default_invoice_naming_series;
+ }
+ for (let d of frm.doc.items){
+ let invoice_item = frappe.model.add_child(invoice, "items")
+ invoice_item.item_code = d.item;
+ invoice_item.qty = d.qty;
+ invoice_item.rate = d.rate;
+ }
+ if (hotel_settings.default_taxes_and_charges){
+ invoice.taxes_and_charges = hotel_settings.default_taxes_and_charges;
+ }
+ frappe.set_route("Form", invoice.doctype, invoice.name);
+ });
+ });
+ }
+});
+
+frappe.ui.form.on('Hotel Room Reservation Item', {
+ item: function(frm, doctype, name) {
+ frm.trigger("recalculate_rates");
+ },
+ qty: function(frm) {
+ frm.trigger("recalculate_rates");
+ }
+});
diff --git a/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.json b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.json
new file mode 100644
index 0000000..c65c4e1
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.json
@@ -0,0 +1,415 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "HRES.#######",
+ "beta": 1,
+ "creation": "2017-12-08 13:01:34.829175",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "guest_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Guest Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Customer",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "from_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "From Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "to_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "To Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "late_checkin",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Late Checkin",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_6",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Booked\nAdvance Paid\nInvoiced\nPaid\nCompleted\nCancelled",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_8",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "items",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Items",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Hotel Room Reservation Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "net_total",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Net Total",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Hotel Room Reservation",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:11:26.395419",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Reservation",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 1,
+ "apply_user_permissions": 0,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Hotel Reservation User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.py b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.py
new file mode 100644
index 0000000..f3f76a9
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe, json
+from frappe.model.document import Document
+from frappe import _
+from frappe.utils import date_diff, add_days, flt
+
+class HotelRoomUnavailableError(frappe.ValidationError): pass
+class HotelRoomPricingNotSetError(frappe.ValidationError): pass
+
+class HotelRoomReservation(Document):
+ def validate(self):
+ self.total_rooms = {}
+ self.set_rates()
+ self.validate_availability()
+
+ def validate_availability(self):
+ for i in xrange(date_diff(self.to_date, self.from_date)):
+ day = add_days(self.from_date, i)
+ self.rooms_booked = {}
+
+ for d in self.items:
+ if not d.item in self.rooms_booked:
+ self.rooms_booked[d.item] = 0
+
+ room_type = frappe.db.get_value("Hotel Room Package",
+ d.item, 'hotel_room_type')
+ rooms_booked = get_rooms_booked(room_type, day, exclude_reservation=self.name) \
+ + d.qty + self.rooms_booked.get(d.item)
+ total_rooms = self.get_total_rooms(d.item)
+ if total_rooms < rooms_booked:
+ frappe.throw(_("Hotel Rooms of type {0} are unavailable on {1}".format(d.item,
+ frappe.format(day, dict(fieldtype="Date")))), exc=HotelRoomUnavailableError)
+
+ self.rooms_booked[d.item] += rooms_booked
+
+ def get_total_rooms(self, item):
+ if not item in self.total_rooms:
+ self.total_rooms[item] = frappe.db.sql("""
+ select count(*)
+ from
+ `tabHotel Room Package` package
+ inner join
+ `tabHotel Room` room on package.hotel_room_type = room.hotel_room_type
+ where
+ package.item = %s""", item)[0][0] or 0
+
+ return self.total_rooms[item]
+
+ def set_rates(self):
+ self.net_total = 0
+ for d in self.items:
+ net_rate = 0.0
+ for i in xrange(date_diff(self.to_date, self.from_date)):
+ day = add_days(self.from_date, i)
+ if not d.item:
+ continue
+ day_rate = frappe.db.sql("""
+ select
+ item.rate
+ from
+ `tabHotel Room Pricing Item` item,
+ `tabHotel Room Pricing` pricing
+ where
+ item.parent = pricing.name
+ and item.item = %s
+ and %s between pricing.from_date
+ and pricing.to_date""", (d.item, day))
+
+ if day_rate:
+ net_rate += day_rate[0][0]
+ else:
+ frappe.throw(
+ _("Please set Hotel Room Rate on {}".format(
+ frappe.format(day, dict(fieldtype="Date")))), exc=HotelRoomPricingNotSetError)
+ d.rate = net_rate
+ d.amount = net_rate * flt(d.qty)
+ self.net_total += d.amount
+
+@frappe.whitelist()
+def get_room_rate(hotel_room_reservation):
+ """Calculate rate for each day as it may belong to different Hotel Room Pricing Item"""
+ doc = frappe.get_doc(json.loads(hotel_room_reservation))
+ doc.set_rates()
+ return doc.as_dict()
+
+def get_rooms_booked(room_type, day, exclude_reservation=None):
+ exclude_condition = ''
+ if exclude_reservation:
+ exclude_condition = 'and reservation.name != "{0}"'.format(frappe.db.escape(exclude_reservation))
+
+ return frappe.db.sql("""
+ select sum(item.qty)
+ from
+ `tabHotel Room Package` room_package,
+ `tabHotel Room Reservation Item` item,
+ `tabHotel Room Reservation` reservation
+ where
+ item.parent = reservation.name
+ and room_package.item = item.item
+ and room_package.hotel_room_type = %s
+ and reservation.docstatus = 1
+ {exclude_condition}
+ and %s between reservation.from_date
+ and reservation.to_date""".format(exclude_condition=exclude_condition),
+ (room_type, day))[0][0] or 0
diff --git a/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation_calendar.js b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation_calendar.js
new file mode 100644
index 0000000..7f7322c
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation/hotel_room_reservation_calendar.js
@@ -0,0 +1,9 @@
+frappe.views.calendar["Hotel Room Reservation"] = {
+ field_map: {
+ "start": "from_date",
+ "end": "to_date",
+ "id": "name",
+ "title": "guest_name",
+ "status": "status"
+ }
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.js b/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.js
new file mode 100644
index 0000000..2897139
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Hotel Room Reservation", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Hotel Room Reservation
+ () => frappe.tests.make('Hotel Room Reservation', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.py b/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.py
new file mode 100644
index 0000000..55c6311
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from erpnext.hotels.doctype.hotel_room_reservation.hotel_room_reservation import HotelRoomPricingNotSetError, HotelRoomUnavailableError
+test_dependencies = ["Hotel Room Pricing", "Hotel Room"]
+
+class TestHotelRoomReservation(unittest.TestCase):
+ def setUp(self):
+ frappe.db.sql("delete from `tabHotel Room Reservation`")
+ frappe.db.sql("delete from `tabHotel Room Reservation Item`")
+
+ def test_reservation(self):
+ reservation = make_reservation(
+ from_date="2017-01-01",
+ to_date="2017-01-03",
+ items=[
+ dict(item="Basic Room with Dinner", qty=2)
+ ]
+ )
+ reservation.insert()
+ self.assertEqual(reservation.net_total, 48000)
+
+ def test_price_not_set(self):
+ reservation = make_reservation(
+ from_date="2016-01-01",
+ to_date="2016-01-03",
+ items=[
+ dict(item="Basic Room with Dinner", qty=2)
+ ]
+ )
+ self.assertRaises(HotelRoomPricingNotSetError, reservation.insert)
+
+ def test_room_unavailable(self):
+ reservation = make_reservation(
+ from_date="2017-01-01",
+ to_date="2017-01-03",
+ items=[
+ dict(item="Basic Room with Dinner", qty=2),
+ ]
+ )
+ reservation.insert()
+
+ reservation = make_reservation(
+ from_date="2017-01-01",
+ to_date="2017-01-03",
+ items=[
+ dict(item="Basic Room with Dinner", qty=20),
+ ]
+ )
+ self.assertRaises(HotelRoomUnavailableError, reservation.insert)
+
+def make_reservation(**kwargs):
+ kwargs["doctype"] = "Hotel Room Reservation"
+ if not "guest_name" in kwargs:
+ kwargs["guest_name"] = "Test Guest"
+ doc = frappe.get_doc(kwargs)
+ return doc
diff --git a/erpnext/hotels/doctype/hotel_room_reservation_item/__init__.py b/erpnext/hotels/doctype/hotel_room_reservation_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation_item/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_reservation_item/hotel_room_reservation_item.json b/erpnext/hotels/doctype/hotel_room_reservation_item/hotel_room_reservation_item.json
new file mode 100644
index 0000000..2b7931e
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation_item/hotel_room_reservation_item.json
@@ -0,0 +1,195 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "",
+ "beta": 0,
+ "creation": "2017-12-08 12:58:21.733330",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Item",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "qty",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Qty",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "currency",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Rate",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:04:34.562956",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Reservation Item",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_reservation_item/hotel_room_reservation_item.py b/erpnext/hotels/doctype/hotel_room_reservation_item/hotel_room_reservation_item.py
new file mode 100644
index 0000000..3406fae
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_reservation_item/hotel_room_reservation_item.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoomReservationItem(Document):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_type/__init__.py b/erpnext/hotels/doctype/hotel_room_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_type/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.js b/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.js
new file mode 100644
index 0000000..d73835d
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Hotel Room Type', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.json b/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.json
new file mode 100644
index 0000000..3d26413
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.json
@@ -0,0 +1,204 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "prompt",
+ "beta": 1,
+ "creation": "2017-12-08 12:38:29.485175",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "capacity",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Capacity",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "extra_bed_capacity",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Extra Bed Capacity",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_3",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amenities",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amenities",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Hotel Room Amenity",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:10:23.355486",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Type",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Hotel Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.py b/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.py
new file mode 100644
index 0000000..1fc1303
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_type/hotel_room_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelRoomType(Document):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.js b/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.js
new file mode 100644
index 0000000..e2dd578
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Hotel Room Type", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Hotel Room Type
+ () => frappe.tests.make('Hotel Room Type', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.py b/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.py
new file mode 100644
index 0000000..3b243e9
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestHotelRoomType(unittest.TestCase):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_settings/__init__.py b/erpnext/hotels/doctype/hotel_settings/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_settings/__init__.py
diff --git a/erpnext/hotels/doctype/hotel_settings/hotel_settings.js b/erpnext/hotels/doctype/hotel_settings/hotel_settings.js
new file mode 100644
index 0000000..0b4a2c3
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_settings/hotel_settings.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Hotel Settings', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/hotels/doctype/hotel_settings/hotel_settings.json b/erpnext/hotels/doctype/hotel_settings/hotel_settings.json
new file mode 100644
index 0000000..d9f5572
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_settings/hotel_settings.json
@@ -0,0 +1,175 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 1,
+ "creation": "2017-12-08 17:50:24.523107",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_customer",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Default Customer",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_taxes_and_charges",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Taxes and Charges",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Sales Taxes and Charges Template",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_invoice_naming_series",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Invoice Naming Series",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 1,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-09 12:11:12.857308",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Settings",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Hotel Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Hospitality",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hotels/doctype/hotel_settings/hotel_settings.py b/erpnext/hotels/doctype/hotel_settings/hotel_settings.py
new file mode 100644
index 0000000..d78bca1
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_settings/hotel_settings.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class HotelSettings(Document):
+ pass
diff --git a/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.js b/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.js
new file mode 100644
index 0000000..bc0b7f8
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Hotel Settings", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Hotel Settings
+ () => frappe.tests.make('Hotel Settings', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.py b/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.py
new file mode 100644
index 0000000..a081acc
--- /dev/null
+++ b/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestHotelSettings(unittest.TestCase):
+ pass
diff --git a/erpnext/hotels/report/__init__.py b/erpnext/hotels/report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/report/__init__.py
diff --git a/erpnext/hotels/report/hotel_room_occupancy/__init__.py b/erpnext/hotels/report/hotel_room_occupancy/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hotels/report/hotel_room_occupancy/__init__.py
diff --git a/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.js b/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.js
new file mode 100644
index 0000000..81efb2d
--- /dev/null
+++ b/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Hotel Room Occupancy"] = {
+ "filters": [
+ {
+ "fieldname":"from_date",
+ "label": __("From Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.now_date(),
+ "reqd":1
+ },
+ {
+ "fieldname":"to_date",
+ "label": __("To Date"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.now_date(),
+ "reqd":1
+ }
+ ]
+}
diff --git a/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.json b/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.json
new file mode 100644
index 0000000..782a48b
--- /dev/null
+++ b/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.json
@@ -0,0 +1,26 @@
+{
+ "add_total_row": 1,
+ "apply_user_permissions": 1,
+ "creation": "2017-12-09 14:31:26.306705",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2017-12-09 14:31:26.306705",
+ "modified_by": "Administrator",
+ "module": "Hotels",
+ "name": "Hotel Room Occupancy",
+ "owner": "Administrator",
+ "ref_doctype": "Hotel Room Reservation",
+ "report_name": "Hotel Room Occupancy",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "System Manager"
+ },
+ {
+ "role": "Hotel Reservation User"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.py b/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.py
new file mode 100644
index 0000000..aebeb45
--- /dev/null
+++ b/erpnext/hotels/report/hotel_room_occupancy/hotel_room_occupancy.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import add_days, date_diff
+
+from erpnext.hotels.doctype.hotel_room_reservation.hotel_room_reservation import get_rooms_booked
+
+def execute(filters=None):
+ columns = get_columns(filters)
+ data = get_data(filters)
+ return columns, data
+
+def get_columns(filters):
+ columns = [
+ dict(label=_("Room Type"), fieldname="room_type"),
+ dict(label=_("Rooms Booked"), fieldtype="Int")
+ ]
+ return columns
+
+def get_data(filters):
+ out = []
+ for room_type in frappe.get_all('Hotel Room Type'):
+ total_booked = 0
+ for i in xrange(date_diff(filters.to_date, filters.from_date)):
+ day = add_days(filters.from_date, i)
+ total_booked += get_rooms_booked(room_type.name, day)
+
+ out.append([room_type.name, total_booked])
+
+ return out
\ No newline at end of file
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index 42f0f0b..d469145 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -20,4 +20,5 @@
Restaurant
Agriculture
ERPNext Integrations
-Non Profit
\ No newline at end of file
+Non Profit
+Hotels
\ No newline at end of file
diff --git a/erpnext/restaurant/doctype/restaurant/restaurant.json b/erpnext/restaurant/doctype/restaurant/restaurant.json
index f4ecba7..8572687 100644
--- a/erpnext/restaurant/doctype/restaurant/restaurant.json
+++ b/erpnext/restaurant/doctype/restaurant/restaurant.json
@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "prompt",
- "beta": 0,
+ "beta": 1,
"creation": "2017-09-15 12:40:41.546933",
"custom": 0,
"docstatus": 0,
@@ -269,7 +269,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-10-05 17:41:14.422242",
+ "modified": "2017-12-09 12:13:10.185496",
"modified_by": "Administrator",
"module": "Restaurant",
"name": "Restaurant",
diff --git a/erpnext/restaurant/doctype/restaurant_menu/restaurant_menu.json b/erpnext/restaurant/doctype/restaurant_menu/restaurant_menu.json
index 264634b..1b1610d 100644
--- a/erpnext/restaurant/doctype/restaurant_menu/restaurant_menu.json
+++ b/erpnext/restaurant/doctype/restaurant_menu/restaurant_menu.json
@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "prompt",
- "beta": 0,
+ "beta": 1,
"creation": "2017-09-15 12:48:29.818715",
"custom": 0,
"docstatus": 0,
@@ -207,7 +207,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-09-21 11:04:20.671542",
+ "modified": "2017-12-09 12:13:13.684500",
"modified_by": "Administrator",
"module": "Restaurant",
"name": "Restaurant Menu",
diff --git a/erpnext/restaurant/doctype/restaurant_reservation/restaurant_reservation.json b/erpnext/restaurant/doctype/restaurant_reservation/restaurant_reservation.json
index 6a2ffa1..0698758 100644
--- a/erpnext/restaurant/doctype/restaurant_reservation/restaurant_reservation.json
+++ b/erpnext/restaurant/doctype/restaurant_reservation/restaurant_reservation.json
@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "REST.######",
- "beta": 0,
+ "beta": 1,
"creation": "2017-09-15 13:05:51.063661",
"custom": 0,
"docstatus": 0,
@@ -297,7 +297,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-09-15 14:40:56.759315",
+ "modified": "2017-12-09 12:13:20.027942",
"modified_by": "Administrator",
"module": "Restaurant",
"name": "Restaurant Reservation",
diff --git a/erpnext/restaurant/doctype/restaurant_table/restaurant_table.json b/erpnext/restaurant/doctype/restaurant_table/restaurant_table.json
index da1bcde..5fc6e62 100644
--- a/erpnext/restaurant/doctype/restaurant_table/restaurant_table.json
+++ b/erpnext/restaurant/doctype/restaurant_table/restaurant_table.json
@@ -4,7 +4,7 @@
"allow_import": 0,
"allow_rename": 0,
"autoname": "",
- "beta": 0,
+ "beta": 1,
"creation": "2017-09-15 12:45:24.717355",
"custom": 0,
"docstatus": 0,
@@ -116,7 +116,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-09-15 13:18:05.254106",
+ "modified": "2017-12-09 12:13:24.382345",
"modified_by": "Administrator",
"module": "Restaurant",
"name": "Restaurant Table",