mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-15 19:19:17 +00:00
[added] hospitality domain (#11020)
* [added] hospitality domain * [tests] wip * [tests] for restaurant * [fix] tests for new naming * [docs] added restaurant docs * [docs] added restaurant docs
This commit is contained in:
0
erpnext/restaurant/__init__.py
Normal file
0
erpnext/restaurant/__init__.py
Normal file
0
erpnext/restaurant/doctype/__init__.py
Normal file
0
erpnext/restaurant/doctype/__init__.py
Normal file
0
erpnext/restaurant/doctype/restaurant/__init__.py
Normal file
0
erpnext/restaurant/doctype/restaurant/__init__.py
Normal file
10
erpnext/restaurant/doctype/restaurant/restaurant.js
Normal file
10
erpnext/restaurant/doctype/restaurant/restaurant.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Restaurant', {
|
||||
refresh: function(frm) {
|
||||
frm.add_custom_button(__('Order Entry'), () => {
|
||||
frappe.set_route('Form', 'Restaurant Order Entry');
|
||||
});
|
||||
}
|
||||
});
|
||||
309
erpnext/restaurant/doctype/restaurant/restaurant.json
Normal file
309
erpnext/restaurant/doctype/restaurant/restaurant.json
Normal file
@@ -0,0 +1,309 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "prompt",
|
||||
"beta": 0,
|
||||
"creation": "2017-09-15 12:40:41.546933",
|
||||
"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": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Image",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"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": "company",
|
||||
"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": "Company",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Company",
|
||||
"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_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": "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": "invoice_series_prefix",
|
||||
"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": "Invoice Series Prefix",
|
||||
"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": "column_break_4",
|
||||
"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": "active_menu",
|
||||
"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": "Active Menu",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Restaurant Menu",
|
||||
"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_tax_template",
|
||||
"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 Tax Template",
|
||||
"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": "address",
|
||||
"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": "Address",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Address",
|
||||
"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_field": "image",
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-10-05 17:41:14.422242",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Restaurant",
|
||||
"name": "Restaurant",
|
||||
"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
|
||||
}
|
||||
10
erpnext/restaurant/doctype/restaurant/restaurant.py
Normal file
10
erpnext/restaurant/doctype/restaurant/restaurant.py
Normal file
@@ -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 Restaurant(Document):
|
||||
pass
|
||||
@@ -0,0 +1,16 @@
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'restaurant',
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Setup'),
|
||||
'items': ['Restaurant Menu', 'Restaurant Table']
|
||||
},
|
||||
{
|
||||
'label': _('Operations'),
|
||||
'items': ['Restaurant Reservation', 'Sales Invoice']
|
||||
}
|
||||
]
|
||||
}
|
||||
37
erpnext/restaurant/doctype/restaurant/test_restaurant.js
Normal file
37
erpnext/restaurant/doctype/restaurant/test_restaurant.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Restaurant", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(2);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Restaurant
|
||||
() => {
|
||||
return frappe.tests.make('Restaurant', [
|
||||
// values to be set
|
||||
{__newname: 'Test Restaurant 1'},
|
||||
{company: 'Test Company'},
|
||||
{invoice_series_prefix: 'Test-Rest-1-Inv-'}
|
||||
])
|
||||
},
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.company, 'Test Company');
|
||||
},
|
||||
() => {
|
||||
return frappe.tests.make('Restaurant', [
|
||||
// values to be set
|
||||
{__newname: 'Test Restaurant 2'},
|
||||
{company: 'Test Company'},
|
||||
{invoice_series_prefix: 'Test-Rest-3-Inv-'}
|
||||
]);
|
||||
},
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.company, 'Test Company');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
17
erpnext/restaurant/doctype/restaurant/test_restaurant.py
Normal file
17
erpnext/restaurant/doctype/restaurant/test_restaurant.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# -*- 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='Restaurant', name='Test Restaurant 1', company='_Test Company 1',
|
||||
invoice_series_prefix='Test-Rest-1-Inv-', defaut_customer='_Test Customer 1'),
|
||||
dict(doctype='Restaurant', name='Test Restaurant 2', company='_Test Company 1',
|
||||
invoice_series_prefix='Test-Rest-2-Inv-', defaut_customer='_Test Customer 1'),
|
||||
]
|
||||
|
||||
class TestRestaurant(unittest.TestCase):
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Restaurant Menu', {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch('item', 'standard_rate', 'rate');
|
||||
},
|
||||
});
|
||||
247
erpnext/restaurant/doctype/restaurant_menu/restaurant_menu.json
Normal file
247
erpnext/restaurant/doctype/restaurant_menu/restaurant_menu.json
Normal file
@@ -0,0 +1,247 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "prompt",
|
||||
"beta": 0,
|
||||
"creation": "2017-09-15 12:48:29.818715",
|
||||
"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": "restaurant",
|
||||
"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": "Restaurant",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Restaurant",
|
||||
"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,
|
||||
"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": 1,
|
||||
"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": "column_break_3",
|
||||
"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": "price_list",
|
||||
"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": "Price List (Auto created)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Price List",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"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
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "items_section",
|
||||
"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,
|
||||
"label": "Items",
|
||||
"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": "Restaurant Menu 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-09-21 11:04:20.671542",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Restaurant",
|
||||
"name": "Restaurant Menu",
|
||||
"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": "Restaurant 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
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
# -*- 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 RestaurantMenu(Document):
|
||||
def validate(self):
|
||||
for d in self.items:
|
||||
if not d.rate:
|
||||
d.rate = frappe.db.get_value('Item', d.item, 'standard_rate')
|
||||
|
||||
def on_update(self):
|
||||
'''Sync Price List'''
|
||||
self.make_price_list()
|
||||
|
||||
def on_trash(self):
|
||||
'''clear prices'''
|
||||
self.clear_item_price()
|
||||
|
||||
def clear_item_price(self, price_list=None):
|
||||
'''clear all item prices for this menu'''
|
||||
if not price_list:
|
||||
price_list = self.get_price_list().name
|
||||
frappe.db.sql('delete from `tabItem Price` where price_list = %s', price_list)
|
||||
|
||||
def make_price_list(self):
|
||||
# create price list for menu
|
||||
price_list = self.get_price_list()
|
||||
self.db_set('price_list', price_list.name)
|
||||
|
||||
# delete old items
|
||||
self.clear_item_price(price_list.name)
|
||||
|
||||
for d in self.items:
|
||||
frappe.get_doc(dict(
|
||||
doctype = 'Item Price',
|
||||
price_list = price_list.name,
|
||||
item_code = d.item,
|
||||
price_list_rate = d.rate
|
||||
)).insert()
|
||||
|
||||
def get_price_list(self):
|
||||
'''Create price list for menu if missing'''
|
||||
price_list_name = frappe.db.get_value('Price List', dict(restaurant_menu=self.name))
|
||||
if price_list_name:
|
||||
price_list = frappe.get_doc('Price List', price_list_name)
|
||||
else:
|
||||
price_list = frappe.new_doc('Price List')
|
||||
price_list.restaurant_menu = self.name
|
||||
price_list.price_list_name = self.name
|
||||
|
||||
price_list.enabled = 1
|
||||
price_list.selling = 1
|
||||
price_list.save()
|
||||
|
||||
return price_list
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Restaurant Menu", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
let items = {
|
||||
"Food Item 1": [
|
||||
{item_code: "Food Item 1"},
|
||||
{item_group: "Products"},
|
||||
{is_stock_item: 1},
|
||||
],
|
||||
"Food Item 2": [
|
||||
{item_code: "Food Item 2"},
|
||||
{item_group: "Products"},
|
||||
{is_stock_item: 1},
|
||||
],
|
||||
"Test Product 3": [
|
||||
{item_code: "Food Item 3"},
|
||||
{item_group: "Products"},
|
||||
{is_stock_item: 1},
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
// number of asserts
|
||||
assert.expect(0);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Restaurant Menu
|
||||
() => frappe.tests.setup_doctype('Item', items),
|
||||
() => {
|
||||
return frappe.tests.make("Restaurant Menu", [
|
||||
{__newname: 'Restaurant Menu 1'},
|
||||
{restaurant: "Test Restaurant 1"},
|
||||
{items: [
|
||||
[
|
||||
{"item": "Food Item 1"},
|
||||
{"rate": 100}
|
||||
],
|
||||
[
|
||||
{"item": "Food Item 2"},
|
||||
{"rate": 90}
|
||||
],
|
||||
[
|
||||
{"item": "Food Item 3"},
|
||||
{"rate": 80}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => {
|
||||
return frappe.tests.make("Restaurant Menu", [
|
||||
{__newname: 'Restaurant Menu 2'},
|
||||
{restaurant: "Test Restaurant 2"},
|
||||
{items: [
|
||||
[
|
||||
{"item": "Food Item 1"},
|
||||
{"rate": 105}
|
||||
],
|
||||
[
|
||||
{"item": "Food Item 3"},
|
||||
{"rate": 85}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => frappe.set_route('Form', 'Restaurant', 'Test Restaurant 1'),
|
||||
() => cur_frm.set_value('active_menu', 'Restaurant Menu 1'),
|
||||
() => cur_frm.save(),
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
# -*- 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='Food Item 1',
|
||||
item_group='Products', is_stock_item=0),
|
||||
dict(doctype='Item', item_code='Food Item 2',
|
||||
item_group='Products', is_stock_item=0),
|
||||
dict(doctype='Item', item_code='Food Item 3',
|
||||
item_group='Products', is_stock_item=0),
|
||||
dict(doctype='Item', item_code='Food Item 4',
|
||||
item_group='Products', is_stock_item=0),
|
||||
dict(doctype='Restaurant Menu', restaurant='Test Restaurant 1', name='Test Restaurant 1 Menu 1',
|
||||
items = [
|
||||
dict(item='Food Item 1', rate=400),
|
||||
dict(item='Food Item 2', rate=300),
|
||||
dict(item='Food Item 3', rate=200),
|
||||
dict(item='Food Item 4', rate=100),
|
||||
]),
|
||||
dict(doctype='Restaurant Menu', restaurant='Test Restaurant 1', name='Test Restaurant 1 Menu 2',
|
||||
items = [
|
||||
dict(item='Food Item 1', rate=450),
|
||||
dict(item='Food Item 2', rate=350),
|
||||
])
|
||||
]
|
||||
|
||||
class TestRestaurantMenu(unittest.TestCase):
|
||||
def test_price_list_creation_and_editing(self):
|
||||
menu1 = frappe.get_doc('Restaurant Menu', 'Test Restaurant 1 Menu 1')
|
||||
menu1.save()
|
||||
|
||||
menu2 = frappe.get_doc('Restaurant Menu', 'Test Restaurant 1 Menu 2')
|
||||
menu2.save()
|
||||
|
||||
self.assertTrue(frappe.db.get_value('Price List', 'Test Restaurant 1 Menu 1'))
|
||||
self.assertEquals(frappe.db.get_value('Item Price',
|
||||
dict(price_list = 'Test Restaurant 1 Menu 1', item_code='Food Item 1'), 'price_list_rate'), 400)
|
||||
self.assertEquals(frappe.db.get_value('Item Price',
|
||||
dict(price_list = 'Test Restaurant 1 Menu 2', item_code='Food Item 1'), 'price_list_rate'), 450)
|
||||
|
||||
menu1.items[0].rate = 401
|
||||
menu1.save()
|
||||
|
||||
self.assertEquals(frappe.db.get_value('Item Price',
|
||||
dict(price_list = 'Test Restaurant 1 Menu 1', item_code='Food Item 1'), 'price_list_rate'), 401)
|
||||
|
||||
menu1.items[0].rate = 400
|
||||
menu1.save()
|
||||
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2017-09-15 12:49:36.072636",
|
||||
"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": "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,
|
||||
"options": "",
|
||||
"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-09-15 14:18:55.145088",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Restaurant",
|
||||
"name": "Restaurant Menu 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
|
||||
}
|
||||
@@ -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 RestaurantMenuItem(Document):
|
||||
pass
|
||||
@@ -0,0 +1,162 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Restaurant Order Entry', {
|
||||
setup: function(frm) {
|
||||
let get_item_query = () => {
|
||||
return {
|
||||
query: 'erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry.item_query_restaurant',
|
||||
filters: {
|
||||
'table': frm.doc.restaurant_table
|
||||
}
|
||||
};
|
||||
};
|
||||
frm.set_query('item', 'items', get_item_query);
|
||||
frm.set_query('add_item', get_item_query);
|
||||
},
|
||||
onload_post_render: function(frm) {
|
||||
if(!this.item_selector) {
|
||||
this.item_selector = new erpnext.ItemSelector({
|
||||
frm: frm,
|
||||
item_field: 'item',
|
||||
item_query: 'erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry.item_query_restaurant',
|
||||
get_filters: () => {
|
||||
return {table: frm.doc.restaurant_table};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let $input = frm.get_field('add_item').$input;
|
||||
|
||||
$input.on('keyup', function(e) {
|
||||
if (e.which===13) {
|
||||
if (frm.clear_item_timeout) {
|
||||
clearTimeout (frm.clear_item_timeout);
|
||||
}
|
||||
|
||||
// clear the item input so user can enter a new item
|
||||
frm.clear_item_timeout = setTimeout (() => {
|
||||
frm.set_value('add_item', '');
|
||||
}, 1000);
|
||||
|
||||
let item = $input.val();
|
||||
|
||||
if (!item) return;
|
||||
|
||||
var added = false;
|
||||
(frm.doc.items || []).forEach((d) => {
|
||||
if (d.item===item) {
|
||||
d.qty += 1;
|
||||
added = true;
|
||||
}
|
||||
});
|
||||
|
||||
return frappe.run_serially([
|
||||
() => {
|
||||
if (!added) {
|
||||
return frm.add_child('items', {item: item, qty: 1});
|
||||
}
|
||||
},
|
||||
() => frm.get_field("items").refresh()
|
||||
]);
|
||||
}
|
||||
});
|
||||
},
|
||||
refresh: function(frm) {
|
||||
frm.disable_save();
|
||||
frm.add_custom_button(__('Update'), () => {
|
||||
return frm.trigger('sync');
|
||||
});
|
||||
frm.add_custom_button(__('Clear'), () => {
|
||||
return frm.trigger('clear');
|
||||
});
|
||||
frm.add_custom_button(__('Bill'), () => {
|
||||
return frm.trigger('make_invoice');
|
||||
});
|
||||
},
|
||||
clear: function(frm) {
|
||||
frm.doc.add_item = '';
|
||||
frm.doc.grand_total = 0;
|
||||
frm.doc.items = [];
|
||||
frm.refresh();
|
||||
frm.get_field('add_item').$input.focus();
|
||||
},
|
||||
restaurant_table: function(frm) {
|
||||
// select the open sales order items for this table
|
||||
if (!frm.doc.restaurant_table) {
|
||||
return;
|
||||
}
|
||||
return frappe.call({
|
||||
method: 'erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry.get_invoice',
|
||||
args: {
|
||||
table: frm.doc.restaurant_table
|
||||
},
|
||||
callback: (r) => {
|
||||
frm.events.set_invoice_items(frm, r);
|
||||
}
|
||||
});
|
||||
},
|
||||
sync: function(frm) {
|
||||
return frappe.call({
|
||||
method: 'erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry.sync',
|
||||
args: {
|
||||
table: frm.doc.restaurant_table,
|
||||
items: frm.doc.items
|
||||
},
|
||||
callback: (r) => {
|
||||
frm.events.set_invoice_items(frm, r);
|
||||
frappe.show_alert({message: __('Saved'), indicator: 'green'});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
make_invoice: function(frm) {
|
||||
frm.trigger('sync').then(() => {
|
||||
frappe.prompt([
|
||||
{
|
||||
fieldname: 'customer',
|
||||
label: __('Customer'),
|
||||
fieldtype: 'Link',
|
||||
reqd: 1,
|
||||
options: 'Customer',
|
||||
'default': frm.invoice.customer
|
||||
},
|
||||
{
|
||||
fieldname: 'mode_of_payment',
|
||||
label: __('Mode of Payment'),
|
||||
fieldtype: 'Link',
|
||||
reqd: 1,
|
||||
options: 'Mode of Payment',
|
||||
'default': frm.mode_of_payment || ''
|
||||
}
|
||||
], (data) => {
|
||||
// cache this for next entry
|
||||
frm.mode_of_payment = data.mode_of_payment;
|
||||
return frappe.call({
|
||||
method: 'erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry.make_invoice',
|
||||
args: {
|
||||
table: frm.doc.restaurant_table,
|
||||
customer: data.customer,
|
||||
mode_of_payment: data.mode_of_payment
|
||||
},
|
||||
callback: (r) => {
|
||||
frm.set_value('last_sales_invoice', r.message);
|
||||
frm.trigger('clear');
|
||||
}
|
||||
});
|
||||
},
|
||||
__("Select Customer"));
|
||||
});
|
||||
},
|
||||
set_invoice_items: function(frm, r) {
|
||||
let invoice = r.message;
|
||||
frm.doc.items = [];
|
||||
(invoice.items || []).forEach((d) => {
|
||||
frm.add_child('items', {item: d.item_code, qty: d.qty, rate: d.rate});
|
||||
});
|
||||
frm.set_value('grand_total', invoice.grand_total);
|
||||
frm.set_value('last_sales_invoice', invoice.name);
|
||||
frm.invoice = invoice;
|
||||
frm.refresh();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,280 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 1,
|
||||
"creation": "2017-09-15 15:10:24.530365",
|
||||
"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": "restaurant_table",
|
||||
"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": "Restaurant Table",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Restaurant Table",
|
||||
"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,
|
||||
"depends_on": "restaurant_table",
|
||||
"description": "Click Enter To Add",
|
||||
"fieldname": "add_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": "Add 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": "column_break_3",
|
||||
"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": "grand_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": "Grand Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"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
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "last_sales_invoice",
|
||||
"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": "Last Sales Invoice",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"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
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "restaurant_table",
|
||||
"fieldname": "current_order",
|
||||
"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,
|
||||
"label": "Current Order",
|
||||
"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,
|
||||
"depends_on": "restaurant_table",
|
||||
"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": "Restaurant Order Entry 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
|
||||
}
|
||||
],
|
||||
"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-10-04 17:06:20.926999",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Restaurant",
|
||||
"name": "Restaurant Order Entry",
|
||||
"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": "Restaurant 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
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
# -*- 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 erpnext.controllers.queries import item_query
|
||||
|
||||
class RestaurantOrderEntry(Document):
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_invoice(table):
|
||||
'''returns the active invoice linked to the given table'''
|
||||
invoice_name = frappe.get_value('Sales Invoice', dict(restaurant_table = table, docstatus=0))
|
||||
restaurant, menu_name = get_restaurant_and_menu_name(table)
|
||||
if invoice_name:
|
||||
invoice = frappe.get_doc('Sales Invoice', invoice_name)
|
||||
else:
|
||||
invoice = frappe.new_doc('Sales Invoice')
|
||||
invoice.naming_series = frappe.db.get_value('Restaurant', restaurant, 'invoice_series_prefix')
|
||||
invoice.is_pos = 1
|
||||
default_customer = frappe.db.get_value('Restaurant', restaurant, 'default_customer')
|
||||
if not default_customer:
|
||||
frappe.throw(_('Please set default customer in Restaurant Settings'))
|
||||
invoice.customer = default_customer
|
||||
|
||||
invoice.taxes_and_charges = frappe.db.get_value('Restaurant', restaurant, 'default_tax_template')
|
||||
invoice.selling_price_list = frappe.db.get_value('Price List', dict(restaurant_menu=menu_name, enabled=1))
|
||||
|
||||
return invoice
|
||||
|
||||
@frappe.whitelist()
|
||||
def sync(table, items):
|
||||
'''Sync the sales order related to the table'''
|
||||
invoice = get_invoice(table)
|
||||
items = json.loads(items)
|
||||
|
||||
invoice.items = []
|
||||
invoice.restaurant_table = table
|
||||
for d in items:
|
||||
invoice.append('items', dict(
|
||||
item_code = d.get('item'),
|
||||
qty = d.get('qty')
|
||||
))
|
||||
|
||||
invoice.save()
|
||||
return invoice.as_dict()
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_invoice(table, customer, mode_of_payment):
|
||||
'''Make table based on Sales Order'''
|
||||
restaurant, menu = get_restaurant_and_menu_name(table)
|
||||
invoice = get_invoice(table)
|
||||
invoice.customer = customer
|
||||
invoice.restaurant = restaurant
|
||||
invoice.calculate_taxes_and_totals()
|
||||
invoice.append('payments', dict(mode_of_payment=mode_of_payment, amount=invoice.grand_total))
|
||||
invoice.save()
|
||||
invoice.submit()
|
||||
|
||||
frappe.msgprint(_('Invoice Created'), indicator='green', alert=True)
|
||||
|
||||
return invoice.name
|
||||
|
||||
def item_query_restaurant(doctype='Item', txt='', searchfield='name', start=0, page_len=20, filters=None, as_dict=False):
|
||||
'''Return items that are selected in active menu of the restaurant'''
|
||||
restaurant, menu = get_restaurant_and_menu_name(filters['table'])
|
||||
items = frappe.db.get_all('Restaurant Menu Item', ['item'], dict(parent = menu))
|
||||
del filters['table']
|
||||
filters['name'] = ('in', [d.item for d in items])
|
||||
|
||||
return item_query('Item', txt, searchfield, start, page_len, filters, as_dict)
|
||||
|
||||
def get_restaurant_and_menu_name(table):
|
||||
if not table:
|
||||
frappe.throw(_('Please select a table'))
|
||||
|
||||
restaurant = frappe.db.get_value('Restaurant Table', table, 'restaurant')
|
||||
menu = frappe.db.get_value('Restaurant', restaurant, 'active_menu')
|
||||
|
||||
if not menu:
|
||||
frappe.throw(_('Please set an active menu for Restaurant {0}').format(restaurant))
|
||||
|
||||
return restaurant, menu
|
||||
@@ -0,0 +1,53 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Restaurant Order Entry", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(5);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Restaurant Order Entry
|
||||
() => frappe.set_route('Form', 'Restaurant Settings'),
|
||||
() => cur_frm.set_value('default_customer', 'Test Customer 1'),
|
||||
() => cur_frm.save(),
|
||||
() => frappe.set_route('Form', 'Restaurant Order Entry'),
|
||||
() => frappe.click_button('Clear'),
|
||||
() => frappe.timeout(2),
|
||||
() => cur_frm.set_value('restaurant_table', 'Test-Restaurant-1-01'),
|
||||
() => cur_frm.set_value('add_item', 'Food Item 1'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => {
|
||||
var e = $.Event( "keyup", {which: 13} );
|
||||
$('input[data-fieldname="add_item"]').trigger(e);
|
||||
return frappe.timeout(0.5);
|
||||
},
|
||||
() => cur_frm.set_value('add_item', 'Food Item 1'),
|
||||
() => {
|
||||
var e = $.Event( "keyup", {which: 13} );
|
||||
$('input[data-fieldname="add_item"]').trigger(e);
|
||||
return frappe.timeout(0.5);
|
||||
},
|
||||
() => cur_frm.set_value('add_item', 'Food Item 2'),
|
||||
() => {
|
||||
var e = $.Event( "keyup", {which: 13} );
|
||||
$('input[data-fieldname="add_item"]').trigger(e);
|
||||
return frappe.timeout(0.5);
|
||||
},
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.items[0].item, 'Food Item 1');
|
||||
assert.equal(cur_frm.doc.items[0].qty, 2);
|
||||
assert.equal(cur_frm.doc.items[1].item, 'Food Item 2');
|
||||
assert.equal(cur_frm.doc.items[1].qty, 1);
|
||||
},
|
||||
() => frappe.click_button('Update'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.grand_total, 290);
|
||||
}
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe, json
|
||||
import unittest
|
||||
|
||||
from erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry \
|
||||
import (sync, make_invoice, item_query_restaurant)
|
||||
|
||||
class TestRestaurantOrderEntry(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# save the menus as Price List is deleted before tests...
|
||||
frappe.get_doc('Restaurant Menu', 'Test Restaurant 1 Menu 1').save()
|
||||
frappe.get_doc('Restaurant Menu', 'Test Restaurant 1 Menu 2').save()
|
||||
|
||||
if not frappe.db.get_value('Restaurant', 'Test Restaurant 1', 'active_menu'):
|
||||
restaurant = frappe.get_doc('Restaurant', 'Test Restaurant 1')
|
||||
restaurant.active_menu = 'Test Restaurant 1 Menu 1'
|
||||
restaurant.save()
|
||||
|
||||
def test_update_order(self):
|
||||
table = frappe.db.get_value('Restaurant Table', dict(restaurant = 'Test Restaurant 1'))
|
||||
invoice = sync(table,
|
||||
json.dumps([dict(item='Food Item 1', qty = 10), dict(item='Food Item 2', qty = 2)]))
|
||||
|
||||
self.assertEquals(invoice.get('restaurant_table'), table)
|
||||
self.assertEquals(invoice.get('items')[0].get('item_code'), 'Food Item 1')
|
||||
self.assertEquals(invoice.get('items')[1].get('item_code'), 'Food Item 2')
|
||||
self.assertEquals(invoice.get('net_total'), 4600)
|
||||
|
||||
return table
|
||||
|
||||
def test_billing(self):
|
||||
table = self.test_update_order()
|
||||
invoice_name = make_invoice(table, '_Test Customer', 'Cash')
|
||||
|
||||
sales_invoice = frappe.get_doc('Sales Invoice', invoice_name)
|
||||
|
||||
self.assertEquals(sales_invoice.grand_total, 4600)
|
||||
self.assertEquals(sales_invoice.items[0].item_code, 'Food Item 1')
|
||||
self.assertEquals(sales_invoice.items[1].item_code, 'Food Item 2')
|
||||
self.assertEquals(sales_invoice.payments[0].mode_of_payment, 'Cash')
|
||||
self.assertEquals(sales_invoice.payments[0].amount, 4600)
|
||||
|
||||
def test_item_query(self):
|
||||
table = frappe.db.get_value('Restaurant Table', dict(restaurant = 'Test Restaurant 1'))
|
||||
result = item_query_restaurant(filters=dict(table=table))
|
||||
items = [d[0] for d in result]
|
||||
self.assertTrue('Food Item 1' in items)
|
||||
self.assertTrue('_Test Item 1' not in items)
|
||||
@@ -0,0 +1,163 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-09-15 15:11:50.313241",
|
||||
"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": 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": "served",
|
||||
"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": "Served",
|
||||
"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": "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
|
||||
}
|
||||
],
|
||||
"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-09-21 08:39:27.232175",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Restaurant",
|
||||
"name": "Restaurant Order Entry 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
|
||||
}
|
||||
@@ -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 RestaurantOrderEntryItem(Document):
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Restaurant Reservation', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,337 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "REST.######",
|
||||
"beta": 0,
|
||||
"creation": "2017-09-15 13:05:51.063661",
|
||||
"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": "status",
|
||||
"fieldtype": "Select",
|
||||
"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": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Open\nWaitlisted\nCancelled\nNo Show\nSuccess",
|
||||
"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": "restaurant",
|
||||
"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": "Restaurant",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Restaurant",
|
||||
"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": "no_of_people",
|
||||
"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": "No of People",
|
||||
"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": "reservation_time",
|
||||
"fieldtype": "Datetime",
|
||||
"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": "Reservation Time",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"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": "reservation_end_time",
|
||||
"fieldtype": "Datetime",
|
||||
"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": "Reservation End Time",
|
||||
"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_4",
|
||||
"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": "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": "customer_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Customer 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": "contact_number",
|
||||
"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": "Contact Number",
|
||||
"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-09-15 14:40:56.759315",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Restaurant",
|
||||
"name": "Restaurant 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": "Restaurant 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
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# -*- 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
|
||||
from datetime import timedelta
|
||||
from frappe.utils import get_datetime
|
||||
|
||||
class RestaurantReservation(Document):
|
||||
def validate(self):
|
||||
if not self.reservation_end_time:
|
||||
self.reservation_end_time = get_datetime(self.reservation_time) + timedelta(hours=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_events(start, end, filters=None):
|
||||
"""Returns events for Gantt / Calendar view rendering.
|
||||
|
||||
:param start: Start date-time.
|
||||
:param end: End date-time.
|
||||
:param filters: Filters (JSON).
|
||||
"""
|
||||
from frappe.desk.calendar import get_event_conditions
|
||||
conditions = get_event_conditions("Restaurant Reservation", filters)
|
||||
|
||||
data = frappe.db.sql("""select name, reservation_time,
|
||||
reservation_end_time, customer_name, status, no_of_people
|
||||
from
|
||||
`tabRestaurant Reservation`
|
||||
where
|
||||
((ifnull(reservation_time, '0000-00-00')!= '0000-00-00') \
|
||||
and (reservation_time <= %(end)s) \
|
||||
or ((ifnull(reservation_end_time, '0000-00-00')!= '0000-00-00') \
|
||||
and reservation_end_time >= %(start)s))
|
||||
{conditions}""".format(conditions=conditions), {
|
||||
"start": start,
|
||||
"end": end
|
||||
}, as_dict=True, update={"allDay": 0})
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,18 @@
|
||||
frappe.views.calendar["Restaurant Reservation"] = {
|
||||
field_map: {
|
||||
"start": "reservation_time",
|
||||
"end": "reservation_end_time",
|
||||
"id": "name",
|
||||
"title": "customer_name",
|
||||
"allDay": "allDay",
|
||||
},
|
||||
gantt: true,
|
||||
filters: [
|
||||
{
|
||||
"fieldtype": "Data",
|
||||
"fieldname": "customer_name",
|
||||
"label": __("Customer Name")
|
||||
}
|
||||
],
|
||||
get_events_method: "erpnext.restaurant.doctype.restaurant_reservation.restaurant_reservation.get_events"
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Restaurant Reservation", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Restaurant Reservation
|
||||
() => frappe.tests.make('Restaurant Reservation', [
|
||||
// values to be set
|
||||
{restaurant: 'Gokul - JP Nagar'},
|
||||
{customer_name: 'test customer'},
|
||||
{reservation_time: frappe.datetime.now_date() + " 19:00:00"},
|
||||
{no_of_people: 4},
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.reservation_end_time,
|
||||
frappe.datetime.now_date() + ' 20:00:00');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -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 TestRestaurantReservation(unittest.TestCase):
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Restaurant Table', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2017-09-15 12:45:24.717355",
|
||||
"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": "restaurant",
|
||||
"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": "Restaurant",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Restaurant",
|
||||
"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": "no_of_seats",
|
||||
"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": "No of Seats",
|
||||
"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,
|
||||
"default": "1",
|
||||
"fieldname": "minimum_seating",
|
||||
"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": "Minimum Seating",
|
||||
"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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-09-15 13:18:05.254106",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Restaurant",
|
||||
"name": "Restaurant Table",
|
||||
"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": "Restaurant 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
|
||||
}
|
||||
@@ -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, re
|
||||
from frappe.model.document import Document
|
||||
from frappe.model.naming import make_autoname
|
||||
|
||||
class RestaurantTable(Document):
|
||||
def autoname(self):
|
||||
prefix = re.sub('-+', '-', self.restaurant.replace(' ', '-'))
|
||||
self.name = make_autoname(prefix + '-.##')
|
||||
@@ -0,0 +1,41 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Restaurant Table", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(0);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Restaurant Table
|
||||
() => frappe.tests.make('Restaurant Table', [
|
||||
// values to be set
|
||||
{restaurant: 'Test Restaurant 1'},
|
||||
{no_of_seats: 4},
|
||||
]),
|
||||
() => frappe.tests.make('Restaurant Table', [
|
||||
// values to be set
|
||||
{restaurant: 'Test Restaurant 1'},
|
||||
{no_of_seats: 5},
|
||||
]),
|
||||
() => frappe.tests.make('Restaurant Table', [
|
||||
// values to be set
|
||||
{restaurant: 'Test Restaurant 1'},
|
||||
{no_of_seats: 2},
|
||||
]),
|
||||
() => frappe.tests.make('Restaurant Table', [
|
||||
// values to be set
|
||||
{restaurant: 'Test Restaurant 1'},
|
||||
{no_of_seats: 2},
|
||||
]),
|
||||
() => frappe.tests.make('Restaurant Table', [
|
||||
// values to be set
|
||||
{restaurant: 'Test Restaurant 1'},
|
||||
{no_of_seats: 6},
|
||||
]),
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- 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(restaurant='Test Restaurant 1', no_of_seats=5, minimum_seating=1),
|
||||
dict(restaurant='Test Restaurant 1', no_of_seats=5, minimum_seating=1),
|
||||
dict(restaurant='Test Restaurant 1', no_of_seats=5, minimum_seating=1),
|
||||
dict(restaurant='Test Restaurant 1', no_of_seats=5, minimum_seating=1),
|
||||
]
|
||||
|
||||
class TestRestaurantTable(unittest.TestCase):
|
||||
pass
|
||||
Reference in New Issue
Block a user