Merge pull request #14920 from codingCoffee/split_issue
Split a given Issue into 2
diff --git a/.gitignore b/.gitignore
index 2b52a49..68272c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,9 +9,6 @@
dist/
erpnext/docs/current
*.swp
-<<<<<<< HEAD
*.swo
__pycache__
*~
-=======
->>>>>>> master
diff --git a/README.md b/README.md
index c5363e8..61860e0 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
Includes: Accounting, Inventory, Manufacturing, CRM, Sales, Purchase, Project Management, HRMS. Requires MariaDB.
-ERPNext is built on the [Frappé](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
+ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
- [User Guide](https://erpnext.org/docs/user)
- [Discussion Forum](https://discuss.erpnext.com/)
@@ -39,7 +39,7 @@
GNU/General Public License (see LICENSE.txt)
-The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappé Technologies Pvt Ltd (Frappé) and Contributors.
+The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
---
@@ -55,19 +55,19 @@
## Logo and Trademark
-The brand name ERPNext and the logo are trademarks of Frappé Technologies Pvt. Ltd.
+The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd.
### Introduction
-Frappé Technologies Pvt. Ltd. (Frappé) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
+Frappe Technologies Pvt. Ltd. (Frappe) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
- We’d like to make it easy for anyone to use the ERPNext name or logo for community-oriented efforts that help spread and improve ERPNext.
- We’d like to make it clear how ERPNext-related businesses and projects can (and cannot) use the ERPNext name and logo.
- We’d like to make it hard for anyone to use the ERPNext name and logo to unfairly profit from, trick or confuse people who are looking for official ERPNext resources.
-### Frappé Trademark Usage Policy
+### Frappe Trademark Usage Policy
-Permission from Frappé is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
+Permission from Frappe is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
We will grant permission to use the ERPNext name and logo for projects that meet the following criteria:
@@ -78,7 +78,7 @@
Use of the ERPNext name and logo is additionally allowed in the following situations:
-All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappé Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
+All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappe Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
Similarly, it’s OK to use the ERPNext logo as part of a page that describes your products or services, but it is not OK to use it as part of your company or product logo or branding itself. Under no circumstances is it permitted to use ERPNext as part of a top-level domain name.
@@ -86,6 +86,6 @@
Please note that it is not the goal of this policy to limit commercial activity around ERPNext. We encourage ERPNext-based businesses, and we would love to see hundreds of them.
-When in doubt about your use of the ERPNext name or logo, please contact Frappé Technologies for clarification.
+When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification.
(inspired by WordPress)
diff --git a/attributions.md b/attributions.md
index 21a44fb..9cd6eb8 100644
--- a/attributions.md
+++ b/attributions.md
@@ -1,6 +1,6 @@
## ERPNext includes these public works
-For Frappé Framework, please see attributions.md at https://github.com/frappe/frappe/
+For Frappe Framework, please see attributions.md at https://github.com/frappe/frappe/
#### Images
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 356e9af..2dfd6e1 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '10.1.42'
+__version__ = '10.1.43'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 421d756..771ec8d 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -298,8 +298,7 @@
if not (cost_center and expense_account):
for doctype in ['Item Group', 'Company']:
- data = get_expense_cost_center(doctype,
- args.get(frappe.scrub(doctype)))
+ data = get_expense_cost_center(doctype, args)
if not cost_center and data:
cost_center = data[0]
@@ -312,8 +311,11 @@
return cost_center, expense_account
-def get_expense_cost_center(doctype, value):
- fields = (['default_cost_center', 'default_expense_account']
- if doctype == 'Item Group' else ['cost_center', 'default_expense_account'])
-
- return frappe.db.get_value(doctype, value, fields)
+def get_expense_cost_center(doctype, args):
+ if doctype == 'Item Group':
+ return frappe.db.get_value('Item Default',
+ {'parent': args.get(frappe.scrub(doctype)), 'company': args.get('company')},
+ ['buying_cost_center', 'expense_account'])
+ else:
+ return frappe.db.get_value(doctype, args.get(frappe.scrub(doctype)),\
+ ['cost_center', 'default_expense_account'])
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
index 92da787..a00aebe 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
@@ -109,3 +109,14 @@
new_fy.insert(ignore_permissions=True)
except frappe.NameError:
pass
+
+def get_from_and_to_date(fiscal_year):
+ from_and_to_date_tuple = frappe.db.sql("""select year_start_date, year_end_date
+ from `tabFiscal Year` where name=%s""", (fiscal_year))[0]
+
+ from_and_to_date = {
+ "from_date": from_and_to_date_tuple[0],
+ "to_date": from_and_to_date_tuple[1]
+ }
+
+ return from_and_to_date
diff --git a/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py b/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py
index a5cf765..87a0cb8 100644
--- a/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py
+++ b/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py
@@ -5,6 +5,262 @@
import frappe
import unittest
+from frappe.utils import today, cint, flt, getdate
+from erpnext.accounts.doctype.loyalty_program.loyalty_program import get_loyalty_program_details
class TestLoyaltyProgram(unittest.TestCase):
- pass
+ @classmethod
+ def setUpClass(self):
+ # create relevant item, customer, loyalty program, etc
+ create_records()
+
+ def test_loyalty_points_earned_single_tier(self):
+ # create a new sales invoice
+ si_original = create_sales_invoice_record()
+ si_original.insert()
+ si_original.submit()
+
+ customer = frappe.get_doc('Customer', {"customer_name": "Test Loyalty Customer"})
+ earned_points = get_points_earned(si_original)
+
+ lpe = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer})
+
+ self.assertEqual(si_original.get('loyalty_program'), customer.loyalty_program)
+ self.assertEqual(lpe.get('loyalty_program_tier'), customer.loyalty_program_tier)
+ self.assertEqual(lpe.loyalty_points, earned_points)
+
+ # add redemption point
+ si_redeem = create_sales_invoice_record()
+ si_redeem.redeem_loyalty_points = 1
+ si_redeem.loyalty_points = earned_points
+ si_redeem.insert()
+ si_redeem.submit()
+
+ earned_after_redemption = get_points_earned(si_redeem)
+
+ lpe_redeem = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'redeem_against': lpe.name})
+ lpe_earn = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'name': ['!=', lpe_redeem.name]})
+
+ self.assertEqual(lpe_earn.loyalty_points, earned_after_redemption)
+ self.assertEqual(lpe_redeem.loyalty_points, (-1*earned_points))
+
+ # cancel and delete
+ for d in [si_redeem, si_original]:
+ d.cancel()
+ frappe.delete_doc('Sales Invoice', d.name)
+
+ def test_loyalty_points_earned_multiple_tier(self):
+ # assign multiple tier program to the customer
+ customer = frappe.get_doc('Customer', {"customer_name": "Test Loyalty Customer"})
+ customer.loyalty_program = frappe.get_doc('Loyalty Program', {'loyalty_program_name': 'Test Multiple Loyalty'}).name
+ customer.save()
+
+ # create a new sales invoice
+ si_original = create_sales_invoice_record()
+ si_original.insert()
+ si_original.submit()
+
+ earned_points = get_points_earned(si_original)
+
+ lpe = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer})
+
+ self.assertEqual(si_original.get('loyalty_program'), customer.loyalty_program)
+ self.assertEqual(lpe.get('loyalty_program_tier'), customer.loyalty_program_tier)
+ self.assertEqual(lpe.loyalty_points, earned_points)
+
+ # add redemption point
+ si_redeem = create_sales_invoice_record()
+ si_redeem.redeem_loyalty_points = 1
+ si_redeem.loyalty_points = earned_points
+ si_redeem.insert()
+ si_redeem.submit()
+
+ customer = frappe.get_doc('Customer', {"customer_name": "Test Loyalty Customer"})
+ earned_after_redemption = get_points_earned(si_redeem)
+
+ lpe_redeem = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'redeem_against': lpe.name})
+ lpe_earn = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_redeem.name, 'name': ['!=', lpe_redeem.name]})
+
+ self.assertEqual(lpe_earn.loyalty_points, earned_after_redemption)
+ self.assertEqual(lpe_redeem.loyalty_points, (-1*earned_points))
+ self.assertEqual(lpe_earn.loyalty_program_tier, customer.loyalty_program_tier)
+
+ # cancel and delete
+ for d in [si_redeem, si_original]:
+ d.cancel()
+ frappe.delete_doc('Sales Invoice', d.name)
+
+ def test_cancel_sales_invoice(self):
+ ''' cancelling the sales invoice should cancel the earned points'''
+ # create a new sales invoice
+ si = create_sales_invoice_record()
+ si.insert()
+ si.submit()
+
+ lpe = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si.name, 'customer': si.customer})
+ self.assertEqual(True, not (lpe is None))
+
+ # cancelling sales invoice
+ si.cancel()
+ lpe = frappe.db.exists('Loyalty Point Entry', lpe.name)
+ self.assertEqual(True, (lpe is None))
+
+ def test_sales_invoice_return(self):
+ # create a new sales invoice
+ si_original = create_sales_invoice_record(2)
+ si_original.conversion_rate = flt(1)
+ si_original.insert()
+ si_original.submit()
+
+ earned_points = get_points_earned(si_original)
+ lpe_original = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer})
+ self.assertEqual(lpe_original.loyalty_points, earned_points)
+
+ # create sales invoice return
+ si_return = create_sales_invoice_record(-1)
+ si_return.conversion_rate = flt(1)
+ si_return.is_return = 1
+ si_return.return_against = si_original.name
+ si_return.insert()
+ si_return.submit()
+
+ # fetch original invoice again as its status would have been updated
+ si_original = frappe.get_doc('Sales Invoice', lpe_original.sales_invoice)
+
+ earned_points = get_points_earned(si_original)
+ lpe_after_return = frappe.get_doc('Loyalty Point Entry', {'sales_invoice': si_original.name, 'customer': si_original.customer})
+ self.assertEqual(lpe_after_return.loyalty_points, earned_points)
+ self.assertEqual(True, (lpe_original.loyalty_points > lpe_after_return.loyalty_points))
+
+ # cancel and delete
+ for d in [si_return, si_original]:
+ try:
+ d.cancel()
+ except frappe.TimestampMismatchError:
+ frappe.get_doc('Sales Invoice', d.name).cancel()
+ frappe.delete_doc('Sales Invoice', d.name)
+
+def get_points_earned(self):
+ def get_returned_amount():
+ returned_amount = frappe.db.sql("""
+ select sum(grand_total)
+ from `tabSales Invoice`
+ where docstatus=1 and is_return=1 and ifnull(return_against, '')=%s
+ """, self.name)
+ return abs(flt(returned_amount[0][0])) if returned_amount else 0
+
+ lp_details = get_loyalty_program_details(self.customer, company=self.company,
+ loyalty_program=self.loyalty_program, expiry_date=self.posting_date)
+ if lp_details and getdate(lp_details.from_date) <= getdate(self.posting_date) and \
+ (not lp_details.to_date or getdate(lp_details.to_date) >= getdate(self.posting_date)):
+ returned_amount = get_returned_amount()
+ eligible_amount = flt(self.grand_total) - cint(self.loyalty_amount) - returned_amount
+ points_earned = cint(eligible_amount/lp_details.collection_factor)
+
+ return points_earned or 0
+
+def create_sales_invoice_record(qty=1):
+ # return sales invoice doc object
+ return frappe.get_doc({
+ "doctype": "Sales Invoice",
+ "customer": frappe.get_doc('Customer', {"customer_name": "Test Loyalty Customer"}).name,
+ "company": '_Test Company',
+ "due_date": today(),
+ "posting_date": today(),
+ "taxes_and_charges": "",
+ "debit_to": "Debtors - _TC",
+ "taxes": [],
+ "items": [{
+ 'doctype': 'Sales Invoice Item',
+ 'item_code': frappe.get_doc('Item', {'item_name': 'Loyal Item'}).name,
+ 'qty': qty,
+ 'income_account': 'Sales - _TC',
+ 'cost_center': 'Main - _TC',
+ 'expense_account': 'Cost of Goods Sold - _TC'
+ }]
+ })
+
+def create_records():
+ # create a new loyalty Account
+ frappe.get_doc({
+ "doctype": "Account",
+ "account_name": "Loyalty",
+ "parent_account": "Direct Expenses - _TC",
+ "company": "_Test Company",
+ "is_group": 0,
+ "account_type": "Expense Account",
+ }).insert()
+
+ # create a new loyalty program Single tier
+ frappe.get_doc({
+ "doctype": "Loyalty Program",
+ "loyalty_program_name": "Test Single Loyalty",
+ "auto_opt_in": 1,
+ "from_date": today(),
+ "loyalty_program_type": "Single Tier Program",
+ "conversion_factor": 1,
+ "expiry_duration": 10,
+ "company": "_Test Company",
+ "cost_center": "Main - _TC",
+ "expense_account": "Loyalty - _TC",
+ "collection_rules": [{
+ 'tier_name': 'Silver',
+ 'collection_factor': 1000,
+ 'min_spent': 1000
+ }]
+ }).insert()
+
+ # create a new customer
+ frappe.get_doc({
+ "customer_group": "_Test Customer Group",
+ "customer_name": "Test Loyalty Customer",
+ "customer_type": "Individual",
+ "doctype": "Customer",
+ "territory": "_Test Territory"
+ }).insert()
+
+ # create a new loyalty program Multiple tier
+ frappe.get_doc({
+ "doctype": "Loyalty Program",
+ "loyalty_program_name": "Test Multiple Loyalty",
+ "auto_opt_in": 1,
+ "from_date": today(),
+ "loyalty_program_type": "Multiple Tier Program",
+ "conversion_factor": 1,
+ "expiry_duration": 10,
+ "company": "_Test Company",
+ "cost_center": "Main - _TC",
+ "expense_account": "Loyalty - _TC",
+ "collection_rules": [
+ {
+ 'tier_name': 'Silver',
+ 'collection_factor': 1000,
+ 'min_spent': 10000
+ },
+ {
+ 'tier_name': 'Gold',
+ 'collection_factor': 1000,
+ 'min_spent': 19000
+ }
+ ]
+ }).insert()
+
+ # create an item
+ item = frappe.get_doc({
+ "doctype": "Item",
+ "item_code": "Loyal Item",
+ "item_name": "Loyal Item",
+ "item_group": "All Item Groups",
+ "company": "_Test Company",
+ "is_stock_item": 1,
+ "opening_stock": 100,
+ "valuation_rate": 10000,
+ }).insert()
+
+ # create item price
+ frappe.get_doc({
+ "doctype": "Item Price",
+ "price_list": "Standard Selling",
+ "item_code": item.item_code,
+ "price_list_rate": 10000
+ }).insert()
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 97c2be2..490f2b4 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -193,7 +193,7 @@
"from_date": frm.doc.posting_date,
"to_date": frm.doc.posting_date,
"company": frm.doc.company,
- group_by_voucher: 0
+ group_by: ""
};
frappe.set_route("query-report", "General Ledger");
}, "fa fa-table");
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.js b/erpnext/accounts/doctype/payment_request/payment_request.js
index afc3804..8820161 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.js
+++ b/erpnext/accounts/doctype/payment_request/payment_request.js
@@ -31,7 +31,7 @@
});
});
}
-
+
if(!frm.doc.payment_gateway_account && frm.doc.status == "Initiated") {
frm.add_custom_button(__('Make Payment Entry'), function(){
frappe.call({
@@ -49,3 +49,25 @@
}
});
+frappe.ui.form.on("Payment Request", "is_a_subscription", function(frm) {
+ frm.toggle_reqd("payment_gateway_account", frm.doc.is_a_subscription);
+ frm.toggle_reqd("subscription_plans", frm.doc.is_a_subscription);
+
+ if (frm.doc.is_a_subscription) {
+ frappe.call({
+ method: "erpnext.accounts.doctype.payment_request.payment_request.get_subscription_details",
+ args: {"reference_doctype": frm.doc.reference_doctype, "reference_name": frm.doc.reference_name},
+ freeze: true,
+ callback: function(data){
+ if(!data.exc) {
+ $.each(data.message || [], function(i, v){
+ var d = frappe.model.add_child(frm.doc, "Subscription Plan Detail", "subscription_plans");
+ d.qty = v.qty;
+ d.plan = v.plan;
+ });
+ frm.refresh_field("subscription_plans");
+ }
+ }
+ });
+ }
+});
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json
index e21afa4..4148dce 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.json
+++ b/erpnext/accounts/doctype/payment_request/payment_request.json
@@ -15,6 +15,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -42,11 +43,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -73,11 +75,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -106,11 +109,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -137,11 +141,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -168,11 +173,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -198,11 +204,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -230,11 +237,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -262,11 +270,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -295,11 +304,44 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "is_a_subscription",
+ "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": "Is a Subscription",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -328,11 +370,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -360,11 +403,79 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "collapsible_depends_on": "",
+ "columns": 0,
+ "depends_on": "eval:doc.is_a_subscription",
+ "fieldname": "subscription_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": "Subscription Section",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "subscription_plans",
+ "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": "Subscription Plans",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Subscription Plan Detail",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -390,11 +501,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -421,11 +533,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -453,11 +566,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -484,11 +598,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -515,11 +630,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -547,16 +663,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "payment_gateway_account.payment_gateway",
+ "fetch_from": "payment_gateway_account.payment_gateway",
"fieldname": "payment_gateway",
"fieldtype": "Read Only",
"hidden": 0,
@@ -580,16 +697,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "payment_gateway_account.payment_account",
+ "fetch_from": "payment_gateway_account.payment_account",
"fieldname": "payment_account",
"fieldtype": "Read Only",
"hidden": 0,
@@ -613,11 +731,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -644,11 +763,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -676,11 +796,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -708,11 +829,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -739,7 +861,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -753,7 +875,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-16 22:43:28.136835",
+ "modified": "2018-06-20 17:06:43.850174",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index a633cc3..c58b185 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -12,12 +12,15 @@
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, get_company_defaults
from frappe.integrations.utils import get_payment_gateway_controller
from frappe.utils.background_jobs import enqueue
+from erpnext.erpnext_integrations.stripe_integration import create_stripe_subscription
+from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
class PaymentRequest(Document):
def validate(self):
self.validate_reference_document()
self.validate_payment_request()
self.validate_currency()
+ self.validate_subscription_details()
def validate_reference_document(self):
if not self.reference_doctype or not self.reference_name:
@@ -33,6 +36,21 @@
if self.payment_account and ref_doc.currency != frappe.db.get_value("Account", self.payment_account, "account_currency"):
frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
+ def validate_subscription_details(self):
+ if self.is_a_subscription:
+ amount = 0
+ for subscription_plan in self.subscription_plans:
+ payment_gateway = frappe.db.get_value("Subscription Plan", subscription_plan.plan, "payment_gateway")
+ if payment_gateway != self.payment_gateway_account:
+ frappe.throw(_('The payment gateway account in plan {0} is different from the payment gateway account in this payment request'.format(subscription_plan.name)))
+
+ rate = get_plan_rate(subscription_plan.plan, quantity=subscription_plan.qty)
+
+ amount += rate
+
+ if amount != self.grand_total:
+ frappe.msgprint(_("The amount of {0} set in this payment request is different from the calculated amount of all payment plans: {1}. Make sure this is correct before submitting the document.".format(self.grand_total, amount)))
+
def on_submit(self):
send_mail = self.payment_gateway_validation()
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
@@ -235,6 +253,10 @@
return redirect_to
+ def create_subscription(self, payment_provider, gateway_controller, data):
+ if payment_provider == "stripe":
+ return create_stripe_subscription(gateway_controller, data)
+
@frappe.whitelist(allow_guest=True)
def make_payment_request(**args):
"""Make payment request"""
@@ -375,3 +397,14 @@
<p>{{ _("Thank you for your business!") }}</p>
""", dict(doc=doc, payment_url = '{{ payment_url }}'))
+
+@frappe.whitelist()
+def get_subscription_details(reference_doctype, reference_name):
+ if reference_doctype == "Sales Invoice":
+ subscriptions = frappe.db.sql("""SELECT parent as sub_name FROM `tabSubscription Invoice` WHERE invoice=%s""",reference_name, as_dict=1)
+ subscription_plans = []
+ for subscription in subscriptions:
+ plans = frappe.get_doc("Subscription", subscription.sub_name).plans
+ for plan in plans:
+ subscription_plans.append(plan)
+ return subscription_plans
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/consultation/test_consultation.js b/erpnext/accounts/doctype/payment_request/test_payment_request.js
similarity index 70%
copy from erpnext/healthcare/doctype/consultation/test_consultation.js
copy to erpnext/accounts/doctype/payment_request/test_payment_request.js
index 803e73c..070b595 100644
--- a/erpnext/healthcare/doctype/consultation/test_consultation.js
+++ b/erpnext/accounts/doctype/payment_request/test_payment_request.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Consultation", function (assert) {
+QUnit.test("test: Payment Request", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
- // insert a new Consultation
- () => frappe.tests.make('Consultation', [
+ // insert a new Payment Request
+ () => frappe.tests.make('Payment Request', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 0d40b21..4db56f3 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -4493,7 +4493,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2018-07-06 02:38:40.310899",
+ "modified": "2018-07-17 02:38:40.310899",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 43a0d01..b67b61c 100755
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -573,5 +573,6 @@
name_list.append(name)
except Exception:
frappe.log_error(frappe.get_traceback())
+ frappe.db.rollback()
return name_list
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index d3efb70..ca6b47b 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -36,7 +36,6 @@
},
refresh: function(doc, dt, dn) {
- console.log("triggered the SalesInvoiceController");
this._super();
if(cur_frm.msgbox && cur_frm.msgbox.$wrapper.is(":visible")) {
// hide new msgbox
@@ -389,7 +388,6 @@
},
loyalty_amount: function(){
- console.log("triggered the loyalty amount");
this.calculate_outstanding_amount();
this.frm.refresh_field("outstanding_amount");
this.frm.refresh_field("paid_amount");
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 7a9e7d0..f01caad 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -681,6 +681,66 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_21",
+ "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,
+ "depends_on": "eval: doc.is_return && doc.return_against",
+ "fieldname": "update_billed_amount_in_sales_order",
+ "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": "Update Billed Amount in Sales 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_in_quick_entry": 0,
"allow_on_submit": 0,
@@ -2476,7 +2536,7 @@
"in_standard_filter": 0,
"label": "Loyalty Points",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -2509,7 +2569,7 @@
"in_standard_filter": 0,
"label": "Loyalty Amount",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -2541,7 +2601,7 @@
"in_standard_filter": 0,
"label": "Redeem Loyalty Points",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -2606,7 +2666,7 @@
"in_standard_filter": 0,
"label": "Loyalty Program",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Loyalty Program",
"permlevel": 0,
"precision": "",
@@ -2640,7 +2700,7 @@
"in_standard_filter": 0,
"label": "Redemption Account",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Account",
"permlevel": 0,
"precision": "",
@@ -2674,7 +2734,7 @@
"in_standard_filter": 0,
"label": "Redemption Cost Center",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Cost Center",
"permlevel": 0,
"precision": "",
@@ -2735,8 +2795,8 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Apply Additional Discount On",
@@ -5382,7 +5442,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2018-07-10 19:28:04.351108",
+ "modified": "2018-07-18 13:16:20.918322",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index f645983..2c4125f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -95,6 +95,10 @@
if self._action != 'submit' and self.update_stock and not self.is_return:
set_batch_nos(self, 'warehouse', True)
+ if self.redeem_loyalty_points:
+ lp = frappe.get_doc('Loyalty Program', self.loyalty_program)
+ self.loyalty_redemption_account = lp.expense_account if not self.loyalty_redemption_account else self.loyalty_redemption_account
+ self.loyalty_redemption_cost_center = lp.cost_center if not self.loyalty_redemption_cost_center else self.loyalty_redemption_cost_center
self.set_against_income_account()
self.validate_c_form()
@@ -124,7 +128,7 @@
self.check_prev_docstatus()
- if self.is_return:
+ if self.is_return and not self.update_billed_amount_in_sales_order:
# NOTE status updating bypassed for is_return
self.status_updater = []
@@ -181,7 +185,7 @@
if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'):
unlink_ref_doc_from_payment_entries(self)
- if self.is_return:
+ if self.is_return and not self.update_billed_amount_in_sales_order:
# NOTE status updating bypassed for is_return
self.status_updater = []
@@ -1015,7 +1019,7 @@
from `tabSales Invoice`
where docstatus=1 and is_return=1 and ifnull(return_against, '')=%s
""", self.name)
- return flt(returned_amount[0][0]) if returned_amount else 0
+ return abs(flt(returned_amount[0][0])) if returned_amount else 0
# redeem the loyalty points.
def apply_loyalty_points(self):
@@ -1026,7 +1030,7 @@
points_to_redeem = self.loyalty_points
for lp_entry in loyalty_point_entries:
- available_points = lp_entry.loyalty_points - redemption_details.get(lp_entry.name)
+ available_points = lp_entry.loyalty_points - flt(redemption_details.get(lp_entry.name))
if available_points > points_to_redeem:
redeemed_points = points_to_redeem
else:
diff --git a/erpnext/accounts/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json
index 5d64d9a..a58ac3e 100644
--- a/erpnext/accounts/doctype/subscription/subscription.json
+++ b/erpnext/accounts/doctype/subscription/subscription.json
@@ -118,39 +118,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "1",
- "fieldname": "quantity",
- "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": "Quantity",
- "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,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "subscription_period",
"fieldtype": "Section Break",
"hidden": 0,
@@ -847,7 +814,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-07-11 19:34:44.582203",
+ "modified": "2018-07-13 15:18:49.016010",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription",
diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py
index 72f86f2..fe39161 100644
--- a/erpnext/accounts/doctype/subscription/subscription.py
+++ b/erpnext/accounts/doctype/subscription/subscription.py
@@ -8,6 +8,7 @@
from frappe import _
from frappe.model.document import Document
from frappe.utils.data import nowdate, getdate, cint, add_days, date_diff, get_last_day, add_to_date, flt
+from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
class Subscription(Document):
@@ -244,7 +245,6 @@
# for that reason
items_list = self.get_items_from_plans(self.plans, prorate)
for item in items_list:
- item['qty'] = self.quantity
invoice.append('items', item)
# Taxes
@@ -272,6 +272,10 @@
discount_on = self.apply_additional_discount
invoice.apply_additional_discount = discount_on if discount_on else 'Grand Total'
+ # Subscription period
+ invoice.from_date = self.current_invoice_start
+ invoice.to_date = self.current_invoice_end
+
invoice.flags.ignore_mandatory = True
invoice.save()
invoice.submit()
@@ -283,28 +287,25 @@
"""
Returns the `Customer` linked to the `Subscriber`
"""
- return frappe.get_value('Subscriber', subscriber_name, 'customer')
+ return frappe.db.get_value('Subscriber', subscriber_name, 'customer')
def get_items_from_plans(self, plans, prorate=0):
"""
Returns the `Item`s linked to `Subscription Plan`
"""
- plan_items = [plan.plan for plan in plans]
- item_details = None
+ if prorate:
+ prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start)
- if plan_items:
- item_details = frappe.db.sql(
- 'select item as item_code, cost as rate from `tabSubscription Plan` where name in %s',
- (plan_items,), as_dict=1
- )
+ items = []
+ customer = self.get_customer(self.subscriber)
+ for plan in plans:
+ item_code = frappe.db.get_value("Subscription Plan", plan.plan, "item")
+ if not prorate:
+ items.append({'item_code': item_code, 'qty': plan.qty, 'rate': get_plan_rate(plan.plan, plan.qty, customer)})
+ else:
+ items.append({'item_code': item_code, 'qty': plan.qty, 'rate': (get_plan_rate(plan.plan, plan.qty, customer) * prorate_factor)})
- if prorate:
- prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start)
-
- for item in item_details:
- item['rate'] = item['rate'] * prorate_factor
-
- return item_details
+ return items
def process(self):
"""
@@ -329,7 +330,7 @@
2. Change the `Subscription` status to 'Past Due Date'
3. Change the `Subscription` status to 'Cancelled'
"""
- if getdate(nowdate()) > getdate(self.current_invoice_end) and not self.has_outstanding_invoice():
+ if getdate(nowdate()) > getdate(self.current_invoice_end) or (getdate(nowdate()) >= getdate(self.current_invoice_end) and getdate(self.current_invoice_end) == getdate(self.current_invoice_start)) and not self.has_outstanding_invoice():
self.generate_invoice()
if self.current_invoice_is_past_due():
self.status = 'Past Due Date'
@@ -363,7 +364,7 @@
else:
if self.is_not_outstanding(current_invoice):
self.status = 'Active'
- self.update_subscription_period(nowdate())
+ self.update_subscription_period(add_days(self.current_invoice_end, 1))
else:
self.set_status_grace_period()
diff --git a/erpnext/accounts/doctype/subscription/test_subscription.py b/erpnext/accounts/doctype/subscription/test_subscription.py
index 47efa45..c42b8e8 100644
--- a/erpnext/accounts/doctype/subscription/test_subscription.py
+++ b/erpnext/accounts/doctype/subscription/test_subscription.py
@@ -15,6 +15,7 @@
plan = frappe.new_doc('Subscription Plan')
plan.plan_name = '_Test Plan Name'
plan.item = '_Test Non Stock Item'
+ plan.price_determination = "Fixed rate"
plan.cost = 900
plan.billing_interval = 'Month'
plan.billing_interval_count = 1
@@ -24,6 +25,7 @@
plan = frappe.new_doc('Subscription Plan')
plan.plan_name = '_Test Plan Name 2'
plan.item = '_Test Non Stock Item'
+ plan.price_determination = "Fixed rate"
plan.cost = 1999
plan.billing_interval = 'Month'
plan.billing_interval_count = 1
@@ -33,6 +35,7 @@
plan = frappe.new_doc('Subscription Plan')
plan.plan_name = '_Test Plan Name 3'
plan.item = '_Test Non Stock Item'
+ plan.price_determination = "Fixed rate"
plan.cost = 1999
plan.billing_interval = 'Day'
plan.billing_interval_count = 14
@@ -58,7 +61,7 @@
subscription.subscriber = '_Test Customer'
subscription.trial_period_start = nowdate()
subscription.trial_period_end = add_days(nowdate(), 30)
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
self.assertEqual(subscription.trial_period_start, nowdate())
@@ -73,7 +76,7 @@
def test_create_subscription_without_trial_with_correct_period(self):
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
self.assertEqual(subscription.trial_period_start, None)
@@ -91,7 +94,7 @@
subscription.subscriber = '_Test Customer'
subscription.trial_period_end = nowdate()
subscription.trial_period_start = add_days(nowdate(), 30)
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
self.assertRaises(frappe.ValidationError, subscription.save)
subscription.delete()
@@ -101,8 +104,8 @@
subscription.subscriber = '_Test Customer'
subscription.trial_period_end = nowdate()
subscription.trial_period_start = add_days(nowdate(), 30)
- subscription.append('plans', {'plan': '_Test Plan Name'})
- subscription.append('plans', {'plan': '_Test Plan Name 3'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
+ subscription.append('plans', {'plan': '_Test Plan Name 3', 'qty': 1})
self.assertRaises(frappe.ValidationError, subscription.save)
subscription.delete()
@@ -111,7 +114,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
subscription.start = '2018-01-01'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.insert()
self.assertEqual(subscription.status, 'Active')
@@ -127,7 +130,7 @@
def test_status_goes_back_to_active_after_invoice_is_paid(self):
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.start = '2018-01-01'
subscription.insert()
subscription.process() # generate first invoice
@@ -144,7 +147,7 @@
subscription.process()
self.assertEqual(subscription.status, 'Active')
- self.assertEqual(subscription.current_invoice_start, nowdate())
+ self.assertEqual(subscription.current_invoice_start, add_months(subscription.start, 1))
self.assertEqual(len(subscription.invoices), 1)
subscription.delete()
@@ -157,7 +160,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.start = '2018-01-01'
subscription.insert()
subscription.process() # generate first invoice
@@ -180,7 +183,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.start = '2018-01-01'
subscription.insert()
subscription.process() # generate first invoice
@@ -198,7 +201,7 @@
def test_subscription_invoice_days_until_due(self):
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.days_until_due = 10
subscription.start = add_months(nowdate(), -1)
subscription.insert()
@@ -216,7 +219,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.start = '2018-01-01'
subscription.insert()
subscription.process() # generate first invoice
@@ -240,7 +243,7 @@
def test_subscription_remains_active_during_invoice_period(self):
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
subscription.process() # no changes expected
@@ -266,7 +269,7 @@
def test_subscription_cancelation(self):
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
subscription.cancel_subscription()
@@ -282,7 +285,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
self.assertEqual(subscription.status, 'Active')
@@ -317,7 +320,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
subscription.cancel_subscription()
invoice = subscription.get_current_invoice()
@@ -337,7 +340,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
subscription.cancel_subscription()
@@ -361,7 +364,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.start = '2018-01-01'
subscription.insert()
subscription.process() # generate first invoice
@@ -395,7 +398,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.start = '2018-01-01'
subscription.insert()
subscription.process() # generate first invoice
@@ -432,7 +435,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.start = '2018-01-01'
subscription.insert()
subscription.process() # generate first invoice
@@ -450,8 +453,9 @@
subscription.process()
self.assertEqual(subscription.status, 'Active')
+ # A new invoice is generated
subscription.process()
- self.assertEqual(subscription.status, 'Active')
+ self.assertEqual(subscription.status, 'Past Due Date')
settings.cancel_after_grace = default_grace_period_action
settings.save()
@@ -460,7 +464,7 @@
def test_restart_active_subscription(self):
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
self.assertRaises(frappe.ValidationError, subscription.restart_subscription)
@@ -471,7 +475,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
subscription.additional_discount_percentage = 10
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
subscription.cancel_subscription()
@@ -486,7 +490,7 @@
subscription = frappe.new_doc('Subscription')
subscription.subscriber = '_Test Customer'
subscription.additional_discount_amount = 11
- subscription.append('plans', {'plan': '_Test Plan Name'})
+ subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
subscription.save()
subscription.cancel_subscription()
diff --git a/erpnext/accounts/doctype/subscription_plan/subscription_plan.js b/erpnext/accounts/doctype/subscription_plan/subscription_plan.js
index f5ea804..aaa32cf 100644
--- a/erpnext/accounts/doctype/subscription_plan/subscription_plan.js
+++ b/erpnext/accounts/doctype/subscription_plan/subscription_plan.js
@@ -1,2 +1,9 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
+
+frappe.ui.form.on('Subscription Plan', {
+ price_determination: function(frm) {
+ frm.toggle_reqd("cost", frm.doc.price_determination === 'Fixed rate');
+ frm.toggle_reqd("price_list", frm.doc.price_determination === 'Based on price list');
+ }
+});
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/subscription_plan/subscription_plan.json b/erpnext/accounts/doctype/subscription_plan/subscription_plan.json
index ab58e7c..453521d 100644
--- a/erpnext/accounts/doctype/subscription_plan/subscription_plan.json
+++ b/erpnext/accounts/doctype/subscription_plan/subscription_plan.json
@@ -15,6 +15,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -42,42 +43,11 @@
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
- "unique": 0
+ "unique": 1
},
{
"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,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -110,10 +80,172 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "price_determination",
+ "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": "Price Determination",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nFixed rate\nBased on price list",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_7",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.price_determination==\"Fixed rate\"",
"fieldname": "cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -133,7 +265,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -141,6 +273,72 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.price_determination==\"Based on price list\"",
+ "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",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Price List",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_11",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -174,6 +372,38 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_13",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -204,6 +434,134 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "payment_plan_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": "Payment Plan",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "payment_plan_id",
+ "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": "Payment Plan",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_16",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "payment_gateway",
+ "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": "Payment Gateway",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Payment Gateway Account",
+ "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,
+ "translatable": 0,
+ "unique": 0
}
],
"has_web_view": 0,
@@ -216,7 +574,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-02-27 09:12:58.330140",
+ "modified": "2018-06-20 16:59:54.082358",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription Plan",
@@ -225,7 +583,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -244,7 +601,7 @@
"write": 1
}
],
- "quick_entry": 1,
+ "quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
diff --git a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
index 4b8c8fc..d3fef60 100644
--- a/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
+++ b/erpnext/accounts/doctype/subscription_plan/subscription_plan.py
@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
+from erpnext.utilities.product import get_price
class SubscriptionPlan(Document):
def validate(self):
@@ -13,3 +14,21 @@
def validate_interval_count(self):
if self.billing_interval_count < 1:
frappe.throw('Billing Interval Count cannot be less than 1')
+
+@frappe.whitelist()
+def get_plan_rate(plan, quantity=1, customer=None):
+ plan = frappe.get_doc("Subscription Plan", plan)
+ if plan.price_determination == "Fixed rate":
+ return plan.cost
+
+ elif plan.price_determination == "Based on price list":
+ if customer:
+ customer_group = frappe.db.get_value("Customer", customer, "customer_group")
+ else:
+ customer_group = None
+
+ price = get_price(item_code=plan.item, price_list=plan.price_list, customer_group=customer_group, company=None, qty=quantity)
+ if not price:
+ return 0
+ else:
+ return price.price_list_rate
diff --git a/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.json b/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.json
index c112923..ca54a16 100644
--- a/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.json
+++ b/erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.json
@@ -14,6 +14,39 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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": "Quantity",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -55,7 +88,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-02-25 07:35:07.736146",
+ "modified": "2018-06-20 15:35:13.514699",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Subscription Plan Detail",
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 164bbd5..ce1f34b 100755
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -288,6 +288,9 @@
if (callback) {
callback();
}
+ },
+ error: () => {
+ setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
}
})
},
@@ -1187,7 +1190,7 @@
message: __('Discount amount cannot be greater than 100%')
});
me.update_discount(item_code, discount);
- }else{
+ }else{
me.update_discount(item_code, discount);
me.update_value();
}
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 2cfca24..d7fe123 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -21,18 +21,18 @@
class DuplicatePartyAccountError(frappe.ValidationError): pass
@frappe.whitelist()
-def get_party_details(party=None, account=None, party_type="Customer", company=None,
- posting_date=None, bill_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
+def get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
+ bill_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
if not party:
return {}
if not frappe.db.exists(party_type, party):
frappe.throw(_("{0}: {1} does not exists").format(party_type, party))
return _get_party_details(party, account, party_type,
- company, posting_date, bill_date, price_list, currency, doctype, ignore_permissions)
+ company, posting_date, bill_date, price_list, currency, doctype, ignore_permissions, fetch_payment_terms_template)
-def _get_party_details(party=None, account=None, party_type="Customer", company=None,
- posting_date=None, bill_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
+def _get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
+ bill_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, bill_date, doctype))
party = out[party_type.lower()]
@@ -50,6 +50,11 @@
set_other_values(out, party, party_type)
set_price_list(out, party, party_type, price_list)
+ out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)
+
+ if fetch_payment_terms_template:
+ out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
+
if not out.get("currency"):
out["currency"] = currency
@@ -282,6 +287,7 @@
if (bill_date or posting_date) and party:
due_date = bill_date or posting_date
template_name = get_pyt_term_template(party, party_type, company)
+
if template_name:
due_date = get_due_date_from_template(template_name, posting_date, bill_date).strftime("%Y-%m-%d")
else:
@@ -315,11 +321,14 @@
due_date = max(due_date, add_months(get_last_day(due_date), term.credit_months))
return due_date
-def validate_due_date(posting_date, due_date, party_type, party, company=None, bill_date=None):
+def validate_due_date(posting_date, due_date, party_type, party, company=None, bill_date=None, template_name=None):
if getdate(due_date) < getdate(posting_date):
frappe.throw(_("Due Date cannot be before Posting Date"))
else:
- default_due_date = get_due_date(posting_date, party_type, party, company, bill_date)
+ if not template_name: return
+
+ default_due_date = get_due_date_from_template(template_name, posting_date, bill_date).strftime("%Y-%m-%d")
+
if not default_due_date:
return
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 1066a3e..d859d59 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -22,9 +22,9 @@
"fieldtype": "Link",
"options": "Supplier",
on_change: () => {
- var supplier = frappe.query_report_filters_by_name.supplier.get_value();
+ var supplier = frappe.query_report.get_filter_value('supplier');
frappe.db.get_value('Supplier', supplier, "tax_id", function(value) {
- frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
+ frappe.query_report.set_filter_value('tax_id', value["tax_id"]);
});
}
},
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index d421b6e..fda4960 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -22,10 +22,10 @@
"fieldtype": "Link",
"options": "Customer",
on_change: () => {
- var customer = frappe.query_report_filters_by_name.customer.get_value();
+ var customer = frappe.query_report.get_filter_value('customer');
frappe.db.get_value('Customer', customer, ["tax_id", "customer_name"], function(value) {
- frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
- frappe.query_report_filters_by_name.customer_name.set_value(value["customer_name"]);
+ frappe.query_report.set_filter_value('tax_id', value["tax_id"]);
+ frappe.query_report.set_filter_value('customer_name', value["customer_name"]);
});
}
},
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py
index c71ecf4..204eceb 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.py
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py
@@ -11,6 +11,8 @@
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
filters.periodicity, company=filters.company)
+ currency = filters.presentation_currency or frappe.db.get_value("Company", filters.company, "default_currency")
+
asset = get_data(filters.company, "Asset", "Debit", period_list,
only_current_fiscal_year=False, filters=filters,
accumulated_values=filters.accumulated_values)
@@ -24,7 +26,7 @@
accumulated_values=filters.accumulated_values)
provisional_profit_loss, total_credit = get_provisional_profit_loss(asset, liability, equity,
- period_list, filters.company)
+ period_list, filters.company, currency)
message, opening_balance = check_opening_balance(asset, liability, equity)
@@ -37,7 +39,7 @@
"account_name": "'" + _("Unclosed Fiscal Years Profit / Loss (Credit)") + "'",
"account": "'" + _("Unclosed Fiscal Years Profit / Loss (Credit)") + "'",
"warn_if_negative": True,
- "currency": frappe.db.get_value("Company", filters.company, "default_currency")
+ "currency": currency
}
for period in period_list:
unclosed[period.key] = opening_balance
@@ -58,12 +60,12 @@
return columns, data, message, chart
-def get_provisional_profit_loss(asset, liability, equity, period_list, company, consolidated=False):
+def get_provisional_profit_loss(asset, liability, equity, period_list, company, currency=None, consolidated=False):
provisional_profit_loss = {}
total_row = {}
if asset and (liability or equity):
total = total_row_total=0
- currency = frappe.db.get_value("Company", company, "default_currency")
+ currency = currency or frappe.db.get_value("Company", company, "default_currency")
total_row = {
"account_name": "'" + _("Total (Credit)") + "'",
"account": "'" + _("Total (Credit)") + "'",
diff --git a/erpnext/accounts/report/financial_statements.html b/erpnext/accounts/report/financial_statements.html
index 38fa3ce..e475a1c 100644
--- a/erpnext/accounts/report/financial_statements.html
+++ b/erpnext/accounts/report/financial_statements.html
@@ -1,5 +1,7 @@
{%
- if (report.columns.length > 8) {
+ var report_columns = report.get_columns_for_print();
+
+ if (report_columns.length > 8) {
frappe.throw(__("Too many columns. Export the report and print it using a spreadsheet application."));
}
%}
@@ -30,9 +32,9 @@
<table class="table table-bordered">
<thead>
<tr>
- <th style="width: {%= 100 - (report.columns.length - 2) * 13 %}%"></th>
- {% for(var i=2, l=report.columns.length; i<l; i++) { %}
- <th class="text-right">{%= report.columns[i].label %}</th>
+ <th style="width: {%= 100 - (report_columns.length - 2) * 13 %}%"></th>
+ {% for(var i=2, l=report_columns.length; i<l; i++) { %}
+ <th class="text-right">{%= report_columns[i].label %}</th>
{% } %}
</tr>
</thead>
@@ -47,9 +49,9 @@
<td>
<span style="padding-left: {%= cint(data[j].indent) * 2 %}em">{%= row.account_name %}</span>
</td>
- {% for(var i=2, l=report.columns.length; i<l; i++) { %}
+ {% for(var i=2, l=report_columns.length; i<l; i++) { %}
<td class="text-right">
- {% var fieldname = report.columns[i].field || report.columns[i].fieldname; %}
+ {% var fieldname = report_columns[i].field || report_columns[i].fieldname; %}
{% if (!is_null(row[fieldname])) { %}
{%= format_currency(row[fieldname], filters.presentation_currency) %}
{% } %}
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index e3d6151..5ba0bde 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -39,7 +39,7 @@
"fieldtype": "Link",
"options": "Account",
"get_query": function() {
- var company = frappe.query_report_filters_by_name.company.get_value();
+ var company = frappe.query_report.get_filter_value('company');
return {
"doctype": "Account",
"filters": {
@@ -53,7 +53,7 @@
"label": __("Voucher No"),
"fieldtype": "Data",
on_change: function() {
- frappe.query_report_filters_by_name.group_by.set_value("");
+ frappe.query_report.set_filter_value('group_by', "");
}
},
{
@@ -72,7 +72,7 @@
"options": "Party Type",
"default": "",
on_change: function() {
- frappe.query_report_filters_by_name.party.set_value("");
+ frappe.query_report.set_filter_value('party', "");
}
},
{
@@ -80,10 +80,9 @@
"label": __("Party"),
"fieldtype": "MultiSelect",
get_data: function() {
- if(!frappe.query_report_filters_by_name) return;
-
- var party_type = frappe.query_report_filters_by_name.party_type.get_value();
- var parties = frappe.query_report_filters_by_name.party.get_value();
+ if (!frappe.query_report.filters) return;
+ var party_type = frappe.query_report.get_filter_value('party_type');
+ var parties = frappe.query_report.get_filter_value('party');
if(!party_type) return;
const values = parties.split(/\s*,\s*/).filter(d => d);
@@ -96,7 +95,7 @@
async: false,
no_spinner: true,
args: {
- doctype: frappe.query_report_filters_by_name.party_type.get_value(),
+ doctype: frappe.query_report.get_filter_value('party_type'),
txt: txt,
filters: {
"name": ["not in", values]
@@ -109,25 +108,24 @@
return data;
},
on_change: function() {
- var party_type = frappe.query_report_filters_by_name.party_type.get_value();
- var parties = frappe.query_report_filters_by_name.party.get_value();
+ var party_type = frappe.query_report.get_filter_value('party_type');
+ var parties = frappe.query_report.get_filter_value('party');
const values = parties.split(/\s*,\s*/).filter(d => d);
if(!party_type || !parties || values.length>1) {
- frappe.query_report_filters_by_name.party_name.set_value("");
- frappe.query_report_filters_by_name.tax_id.set_value("");
+ frappe.query_report.set_filter_value('party_name', "");
+ frappe.query_report.set_filter_value('tax_id', "");
return;
} else {
var party = values[0];
- frappe.query_report_filters_by_name.show_name = true;
var fieldname = erpnext.utils.get_party_name(party_type) || "name";
frappe.db.get_value(party_type, party, fieldname, function(value) {
- frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]);
+ frappe.query_report.set_filter_value('party_name', value[fieldname]);
});
if (party_type === "Customer" || party_type === "Supplier") {
frappe.db.get_value(party_type, party, "tax_id", function(value) {
- frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
+ frappe.query_report.set_filter_value('tax_id', value["tax_id"]);
});
}
}
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 60252ea..2b0d5e7 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -169,7 +169,7 @@
row.qty += returned_item_row.qty
row.base_amount += returned_item_row.base_amount
row.buying_amount = row.qty * row.buying_rate
- if row.qty:
+ if row.qty or row.base_amount:
row = self.set_average_rate(row)
self.grouped_data.append(row)
diff --git a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js
index 9d4a352..ca24394 100644
--- a/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js
+++ b/erpnext/accounts/report/payment_period_based_on_invoice_date/payment_period_based_on_invoice_date.js
@@ -46,8 +46,8 @@
"label": __("Party"),
"fieldtype": "Dynamic Link",
"get_options": function() {
- var party_type = frappe.query_report_filters_by_name.party_type.get_value();
- var party = frappe.query_report_filters_by_name.party.get_value();
+ var party_type = frappe.query_report.get_filter_value('party_type');
+ var party = frappe.query_report.get_filter_value('party');
if(party && !party_type) {
frappe.throw(__("Please select Party Type first"));
}
diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
index a25fa56..80b50b9 100644
--- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
+++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
@@ -34,9 +34,10 @@
}
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
- frappe.query_report_filters_by_name.from_date.set_input(fy.year_start_date);
- frappe.query_report_filters_by_name.to_date.set_input(fy.year_end_date);
- query_report.trigger_refresh();
+ frappe.query_report.set_filter_value({
+ from_date: fy.year_start_date,
+ to_date: fy.year_end_date
+ });
});
}
},
@@ -58,20 +59,21 @@
"fieldtype": "Check"
}
],
- "formatter": function(row, cell, value, columnDef, dataContext, default_formatter) {
- if (columnDef.df.fieldname=="account") {
- value = dataContext.account_name;
+ "formatter": function(value, row, column, data, default_formatter) {
+ if (column.fieldname=="account") {
+ value = data.account_name;
- columnDef.df.link_onclick =
- "frappe.query_reports['Profitability Analysis'].open_profit_and_loss_statement(" + JSON.stringify(dataContext) + ")";
- columnDef.df.is_tree = true;
+ column.link_onclick =
+ "frappe.query_reports['Profitability Analysis'].open_profit_and_loss_statement(" + JSON.stringify(data) + ")";
+ column.is_tree = true;
}
- value = default_formatter(row, cell, value, columnDef, dataContext);
+ value = default_formatter(value, row, column, data);
- if (!dataContext.parent_account && dataContext.based_on != 'project') {
+ if (!data.parent_account && data.based_on != 'project') {
+ value = $(`<span>${value}</span>`);
var $value = $(value).css("font-weight", "bold");
- if (dataContext.warn_if_negative && dataContext[columnDef.df.fieldname] < 0) {
+ if (data.warn_if_negative && data[column.fieldname] < 0) {
$value.addClass("text-danger");
}
@@ -84,7 +86,7 @@
if (!data.account) return;
frappe.route_options = {
- "company": frappe.query_report_filters_by_name.company.get_value(),
+ "company": frappe.query_report.get_filter_value('company'),
"from_fiscal_year": data.fiscal_year,
"to_fiscal_year": data.fiscal_year
};
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.js b/erpnext/accounts/report/trial_balance/trial_balance.js
index ff198e9..8e95d8c 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.js
+++ b/erpnext/accounts/report/trial_balance/trial_balance.js
@@ -26,9 +26,10 @@
}
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
- frappe.query_report_filters_by_name.from_date.set_input(fy.year_start_date);
- frappe.query_report_filters_by_name.to_date.set_input(fy.year_end_date);
- query_report.trigger_refresh();
+ frappe.query_report.set_filter_value({
+ from_date: fy.year_start_date,
+ to_date: fy.year_end_date
+ });
});
}
},
diff --git a/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.js b/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.js
index 29f798e..873c65e 100644
--- a/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.js
+++ b/erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.js
@@ -25,9 +25,10 @@
}
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
- frappe.query_report_filters_by_name.from_date.set_input(fy.year_start_date);
- frappe.query_report_filters_by_name.to_date.set_input(fy.year_end_date);
- query_report.trigger_refresh();
+ frappe.query_report.set_filter_value({
+ from_date: fy.year_start_date,
+ to_date: fy.year_end_date
+ });
});
}
},
@@ -56,8 +57,8 @@
"label": __("Party"),
"fieldtype": "Dynamic Link",
"get_options": function() {
- var party_type = frappe.query_report_filters_by_name.party_type.get_value();
- var party = frappe.query_report_filters_by_name.party.get_value();
+ var party_type = frappe.query_report.get_filter_value('party_type');
+ var party = frappe.query_report.get_filter_value('party');
if(party && !party_type) {
frappe.throw(__("Please select Party Type first"));
}
diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py
index 4490398..d1995d2 100644
--- a/erpnext/accounts/report/utils.py
+++ b/erpnext/accounts/report/utils.py
@@ -1,7 +1,8 @@
import frappe
from erpnext import get_company_currency, get_default_company
from erpnext.setup.utils import get_exchange_rate
-from frappe.utils import cint
+from erpnext.accounts.doctype.fiscal_year.fiscal_year import get_from_and_to_date
+from frappe.utils import cint, get_datetime_str, formatdate
__exchange_rates = {}
P_OR_L_ACCOUNTS = list(
@@ -26,7 +27,12 @@
company = get_appropriate_company(filters)
company_currency = get_company_currency(company)
presentation_currency = filters['presentation_currency'] if filters.get('presentation_currency') else company_currency
- report_date = filters.get('to_date') or filters.get('to_fiscal_year')
+
+ report_date = filters.get('to_date')
+
+ if not report_date:
+ fiscal_year_to_date = get_from_and_to_date(filters.get('to_fiscal_year'))["to_date"]
+ report_date = formatdate(get_datetime_str(fiscal_year_to_date), "dd-MM-yyyy")
currency_map = dict(company=company, company_currency=company_currency, presentation_currency=presentation_currency, report_date=report_date)
@@ -58,6 +64,7 @@
:param to_currency: Quote currency
:return: Retrieved exchange rate
"""
+
rate = __exchange_rates.get('{0}-{1}@{2}'.format(from_currency, to_currency, date))
if not rate:
rate = get_exchange_rate(from_currency, to_currency, date) or 1
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 2021ddd..58b96ff 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -31,6 +31,14 @@
}
};
});
+
+ frm.set_query("cost_center", function() {
+ return {
+ "filters": {
+ "company": frm.doc.company,
+ }
+ };
+ });
},
refresh: function(frm) {
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index 1da8760..6b6518d 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -483,6 +483,37 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "cost_center",
+ "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": "Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Cost Center",
+ "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": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -1848,7 +1879,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-06-18 19:20:27.668745",
+ "modified": "2018-07-17 06:30:25.506194",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 985d13e..e475a5e 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -115,7 +115,7 @@
from_date = self.available_for_use_date
if number_of_pending_depreciations:
- next_depr_date = getdate(add_months(self.available_for_use_date,
+ next_depr_date = getdate(add_months(self.available_for_use_date,
number_of_pending_depreciations * 12))
if (cint(frappe.db.get_value("Asset Settings", None, "schedule_based_on_fiscal_year")) == 1
and getdate(d.depreciation_start_date) < next_depr_date):
@@ -315,14 +315,14 @@
elif self.docstatus == 1:
status = "Submitted"
- idx = self.get_default_finance_book_idx() or 0
-
- expected_value_after_useful_life = self.finance_books[idx].expected_value_after_useful_life
- value_after_depreciation = self.finance_books[idx].value_after_depreciation
-
if self.journal_entry_for_scrap:
status = "Scrapped"
elif self.finance_books:
+ idx = self.get_default_finance_book_idx() or 0
+
+ expected_value_after_useful_life = self.finance_books[idx].expected_value_after_useful_life
+ value_after_depreciation = self.finance_books[idx].value_after_depreciation
+
if flt(value_after_depreciation) <= expected_value_after_useful_life:
status = "Fully Depreciated"
elif flt(value_after_depreciation) < flt(self.gross_purchase_amount):
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 8111dae..446066c 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -38,6 +38,8 @@
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
+ depreciation_cost_center = asset.cost_center or depreciation_cost_center
+
for d in asset.get("schedules"):
if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
je = frappe.new_doc("Journal Entry")
@@ -156,6 +158,7 @@
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
+ depreciation_cost_center = asset.cost_center or depreciation_cost_center
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py
index dcb7009..22d25b5 100644
--- a/erpnext/assets/doctype/location/test_location.py
+++ b/erpnext/assets/doctype/location/test_location.py
@@ -27,6 +27,7 @@
formatted_location_string = str(formatted_locations)
test_location = frappe.get_doc('Location', 'Test Location Area')
+ test_location.save()
self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
self.assertEqual(area, test_location.get('area'))
diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json
index add0fd5..45b22d9 100644
--- a/erpnext/buying/doctype/buying_settings/buying_settings.json
+++ b/erpnext/buying/doctype/buying_settings/buying_settings.json
@@ -265,41 +265,7 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "description": "If enabled, last purchase details of items will not be fetched from previous purchase order or purchase receipt",
- "fieldname": "disable_fetch_last_purchase_rate",
- "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": "Disable Fetching Last Purchase Details in Purchase 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,
- "translatable": 0,
- "unique": 0
- },
+ },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -378,7 +344,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-06-12 03:41:41.739193",
+ "modified": "2018-07-18 07:52:38.062488",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying Settings",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index bc5472f..ea5c6f7 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -53,12 +53,7 @@
erpnext.queries.setup_queries(frm, "Warehouse", function() {
return erpnext.queries.warehouse(frm.doc);
});
-
- if (frm.doc.__onload) {
- frm.toggle_display('get_last_purchase_rate',
- frm.doc.__onload.disable_fetch_last_purchase_rate);
- }
- },
+ }
});
frappe.ui.form.on("Purchase Order Item", {
@@ -339,6 +334,73 @@
})
}, __("Add items from"));
+ this.frm.add_custom_button(__('Update rate as per last purchase'),
+ function() {
+ frappe.call({
+ "method": "get_last_purchase_rate",
+ "doc": me.frm.doc,
+ callback: function(r, rt) {
+ me.frm.dirty();
+ me.frm.cscript.calculate_taxes_and_totals();
+ }
+ })
+ }, __("Tools"));
+
+ this.frm.add_custom_button(__('Link to Material Request'),
+ function() {
+ var my_items = [];
+ for (var i in me.frm.doc.items) {
+ if(!me.frm.doc.items[i].material_request){
+ my_items.push(me.frm.doc.items[i].item_code);
+ }
+ }
+ frappe.call({
+ method: "erpnext.buying.utils.get_linked_material_requests",
+ args:{
+ items: my_items
+ },
+ callback: function(r) {
+ if(r.exc) return;
+
+ var i = 0;
+ var item_length = me.frm.doc.items.length;
+ while (i < item_length) {
+ var qty = me.frm.doc.items[i].qty;
+ (r.message[0] || []).forEach(function(d) {
+ if (d.qty > 0 && qty > 0 && me.frm.doc.items[i].item_code == d.item_code && !me.frm.doc.items[i].material_request_item)
+ {
+ me.frm.doc.items[i].material_request = d.mr_name;
+ me.frm.doc.items[i].material_request_item = d.mr_item;
+ var my_qty = Math.min(qty, d.qty);
+ qty = qty - my_qty;
+ d.qty = d.qty - my_qty;
+ me.frm.doc.items[i].stock_qty = my_qty * me.frm.doc.items[i].conversion_factor;
+ me.frm.doc.items[i].qty = my_qty;
+
+ frappe.msgprint("Assigning " + d.mr_name + " to " + d.item_code + " (row " + me.frm.doc.items[i].idx + ")");
+ if (qty > 0) {
+ frappe.msgprint("Splitting " + qty + " units of " + d.item_code);
+ var new_row = frappe.model.add_child(me.frm.doc, me.frm.doc.items[i].doctype, "items");
+ item_length++;
+
+ for (var key in me.frm.doc.items[i]) {
+ new_row[key] = me.frm.doc.items[i][key];
+ }
+
+ new_row.idx = item_length;
+ new_row["stock_qty"] = new_row.conversion_factor * qty;
+ new_row["qty"] = qty;
+ new_row["material_request"] = "";
+ new_row["material_request_item"] = "";
+ }
+ }
+ });
+ i++;
+ }
+ refresh_field("items");
+ }
+ });
+ }, __("Tools"));
},
tc_name: function() {
@@ -367,17 +429,6 @@
cur_frm.cscript.update_status('Deliver', 'Delivered')
},
- get_last_purchase_rate: function() {
- frappe.call({
- "method": "get_last_purchase_rate",
- "doc": cur_frm.doc,
- callback: function(r, rt) {
- cur_frm.dirty();
- cur_frm.cscript.calculate_taxes_and_totals();
- }
- })
- },
-
items_on_form_rendered: function() {
set_schedule_date(this.frm);
},
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 9f39cbf..8286885 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -1426,72 +1426,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
- "fieldname": "get_last_purchase_rate",
- "fieldtype": "Button",
- "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": "Get last purchase 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,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
- "fieldname": "link_to_mrs",
- "fieldtype": "Button",
- "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": "Link to material requests",
- "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,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "sb_last_purchase",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3737,7 +3671,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-07-06 11:00:05.037716",
+ "modified": "2018-07-18 07:49:53.131408",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 5af3078..b63c256 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -15,6 +15,7 @@
from erpnext.stock.utils import get_bin
from six import string_types
from erpnext.stock.doctype.item.item import get_item_defaults
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@@ -35,12 +36,6 @@
'percent_join_field': 'material_request'
}]
- def onload(self):
- super(PurchaseOrder, self).onload()
-
- self.set_onload('disable_fetch_last_purchase_rate',
- cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")))
-
def validate(self):
super(PurchaseOrder, self).validate()
@@ -124,7 +119,6 @@
def get_last_purchase_rate(self):
"""get last purchase rates for all items"""
- if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
conversion_rate = flt(self.get('conversion_rate')) or 1.0
for d in self.get("items"):
@@ -302,7 +296,6 @@
def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0):
"""get last purchase rate for an item"""
- if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
conversion_rate = flt(conversion_rate) or 1.0
@@ -390,9 +383,10 @@
target.qty = target.amount / flt(obj.rate) if (flt(obj.rate) and flt(obj.billed_amt)) else flt(obj.qty)
item = get_item_defaults(target.item_code, source_parent.company)
+ item_group = get_item_group_defaults(target.item_code, source_parent.company)
target.cost_center = frappe.db.get_value("Project", obj.project, "cost_center") \
or item.get("buying_cost_center") \
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or item_group.get("buying_cost_center")
doc = get_mapped_doc("Purchase Order", source_name, {
"Purchase Order": {
diff --git a/erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_last_purchase_rate.js b/erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_last_purchase_rate.js
deleted file mode 100644
index 8ccf1b6..0000000
--- a/erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_last_purchase_rate.js
+++ /dev/null
@@ -1,156 +0,0 @@
-QUnit.module('Buying');
-
-QUnit.test("test: purchase order with last purchase rate", function(assert) {
- assert.expect(9);
- let done = assert.async();
-
- frappe.run_serially([
- () => {
- return frappe.tests.make('Purchase Order', [
- {supplier: 'Test Supplier'},
- {is_subcontracted: 'No'},
- {currency: 'INR'},
- {items: [
- [
- {"item_code": 'Test Product 4'},
- {"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
- {"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
- {"qty": 1},
- {"rate": 800},
- {"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
- ],
- [
- {"item_code": 'Test Product 1'},
- {"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
- {"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
- {"qty": 1},
- {"rate": 400},
- {"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
- ]
- ]}
- ]);
- },
-
- () => {
- // Get item details
- assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item 1 name correct");
- assert.ok(cur_frm.doc.items[1].item_name == 'Test Product 1', "Item 2 name correct");
- },
-
- () => frappe.timeout(1),
-
- () => frappe.tests.click_button('Submit'),
- () => frappe.tests.click_button('Yes'),
- () => frappe.timeout(3),
-
- () => frappe.tests.click_button('Close'),
- () => frappe.timeout(1),
-
- () => {
- return frappe.tests.make('Purchase Order', [
- {supplier: 'Test Supplier'},
- {is_subcontracted: 'No'},
- {currency: 'INR'},
- {items: [
- [
- {"item_code": 'Test Product 4'},
- {"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
- {"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
- {"qty": 1},
- {"rate": 600},
- {"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
- ],
- [
- {"item_code": 'Test Product 1'},
- {"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
- {"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
- {"qty": 1},
- {"rate": 200},
- {"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
- ]
- ]}
- ]);
- },
-
- () => frappe.timeout(2),
-
- // Get the last purchase rate of items
- () => {
- assert.ok(cur_frm.doc.items[0].last_purchase_rate == 800, "Last purchase rate of item 1 correct");
- assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
- },
- () => {
- assert.ok(cur_frm.doc.items[1].last_purchase_rate == 400, "Last purchase rate of item 2 correct");
- assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
- },
-
- () => frappe.tests.click_button('Submit'),
- () => frappe.tests.click_button('Yes'),
- () => frappe.timeout(3),
-
- () => frappe.tests.click_button('Close'),
-
- () => frappe.timeout(1),
-
- () => {
- assert.ok(cur_frm.doc.status == 'To Receive and Bill', "Submitted successfully");
- },
-
- // enable allow_last_purchase_rate
- () => {
- return frappe.tests.make('Buying Settings', [
- // values to be set
- {"disable_fetch_last_purchase_rate": 1}
- ]);
- },
-
- () => {
- return frappe.tests.make('Purchase Order', [
- {supplier: 'Test Supplier'},
- {is_subcontracted: 'No'},
- {currency: 'INR'},
- {items: [
- [
- {"item_code": 'Test Product 4'},
- {"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
- {"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
- {"qty": 1},
- {"rate": 800},
- {"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
- ],
- [
- {"item_code": 'Test Product 1'},
- {"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
- {"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
- {"qty": 1},
- {"rate": 400},
- {"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
- ]
- ]}
- ]);
- },
-
- () => {
- // Get item details
- assert.ok(cur_frm.doc.items[0].last_purchase_rate == 0);
- assert.ok(cur_frm.doc.items[1].last_purchase_rate == 0);
- },
-
- () => frappe.timeout(1),
-
- () => frappe.tests.click_button('Submit'),
- () => frappe.tests.click_button('Yes'),
- () => frappe.timeout(3),
-
- () => frappe.tests.click_button('Close'),
- () => frappe.timeout(1),
-
- // enable allow_last_purchase_rate
- () => frappe.tests.make('Buying Settings', [
- // values to be set
- {"disable_fetch_last_purchase_rate": 0}
- ]),
-
- () => done()
- ]);
-});
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index e49f6c4..2623078 100755
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -723,7 +723,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -2309,7 +2309,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-06-15 13:05:44.702506",
+ "modified": "2018-07-18 07:53:54.677844",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
index b7e1e33..8f7bb2b 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
@@ -2779,7 +2779,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2018-07-06 02:45:48.616334",
+ "modified": "2018-07-17 02:45:48.616334",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",
diff --git a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js
index 41d9ef3..3d05612 100644
--- a/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js
+++ b/erpnext/buying/report/quoted_item_comparison/quoted_item_comparison.js
@@ -21,7 +21,7 @@
fieldname: "item",
fieldtype: "Link",
get_query: () => {
- let quote = frappe.query_report_filters_by_name.supplier_quotation.get_value();
+ let quote = frappe.query_report.get_filter_value('supplier_quotation');
if (quote != "") {
return {
query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query",
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index f987316..117b4c3 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -304,13 +304,13 @@
"hidden": 1
},
{
- "module_name": "Consultation",
+ "module_name": "Patient Encounter",
"color": "#2ecc71",
"icon": "fa fa-stethoscope",
- "doctype": "Consultation",
+ "doctype": "Patient Encounter",
"type": "link",
- "link": "List/Consultation",
- "label": _("Consultation"),
+ "link": "List/Patient Encounter",
+ "label": _("Patient Encounter"),
"hidden": 1
},
{
diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py
index f1339a7..e55f736 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -15,8 +15,8 @@
},
{
"type": "doctype",
- "name": "Consultation",
- "label": _("Consultation"),
+ "name": "Patient Encounter",
+ "label": _("Patient Encounter"),
},
{
"type": "doctype",
@@ -38,6 +38,11 @@
"type": "doctype",
"name": "Clinical Procedure",
"label": _("Clinical Procedure"),
+ },
+ {
+ "type": "doctype",
+ "name": "Inpatient Record",
+ "label": _("Inpatient Record"),
}
]
},
@@ -74,13 +79,13 @@
},
{
"type": "doctype",
- "name": "Physician",
- "label": _("Physician"),
+ "name": "Healthcare Practitioner",
+ "label": _("Healthcare Practitioner"),
},
{
"type": "doctype",
- "name": "Physician Schedule",
- "label": _("Physician Schedule"),
+ "name": "Practitioner Schedule",
+ "label": _("Practitioner Schedule"),
},
{
"type": "doctype",
@@ -167,6 +172,11 @@
"type": "doctype",
"name": "Clinical Procedure Template",
"label": _("Clinical Procedure Template"),
+ },
+ {
+ "type": "doctype",
+ "name": "Healthcare Service Unit Type",
+ "label": _("Healthcare Service Unit Type")
}
]
}
diff --git a/erpnext/config/hr.py b/erpnext/config/hr.py
index b87f4bc..0c7b122 100644
--- a/erpnext/config/hr.py
+++ b/erpnext/config/hr.py
@@ -43,6 +43,16 @@
},
{
"type": "doctype",
+ "name": "Job Opening",
+ "description": _("Opening for a Job."),
+ },
+ {
+ "type": "doctype",
+ "name": "Job Applicant",
+ "description": _("Applicant for a Job."),
+ },
+ {
+ "type": "doctype",
"name": "Leave Application",
},
{
diff --git a/erpnext/config/erpnext_integrations.py b/erpnext/config/integrations.py
similarity index 100%
rename from erpnext/config/erpnext_integrations.py
rename to erpnext/config/integrations.py
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index fe8e34e..b8fa0ec 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -165,9 +165,11 @@
if not self.due_date:
frappe.throw(_("Due Date is mandatory"))
- validate_due_date(self.posting_date, self.due_date, "Customer", self.customer, self.company)
+ validate_due_date(self.posting_date, self.due_date,
+ "Customer", self.customer, self.company, self.payment_terms_template)
elif self.doctype == "Purchase Invoice":
- validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier, self.company, self.bill_date)
+ validate_due_date(self.posting_date, self.due_date,
+ "Supplier", self.supplier, self.company, self.bill_date, self.payment_terms_template)
def set_price_list_currency(self, buying_or_selling):
if self.meta.get_field("posting_date"):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index a22a9ec..70a0773 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -79,6 +79,12 @@
{"parent": d.item_code, "company": self.company}, "default_supplier")
if supplier:
self.supplier = supplier
+ else:
+ item_group = frappe.db.get_value("Item", d.item_code, "item_group")
+ supplier = frappe.db.get_value("Item Default",
+ {"parent": item_group, "company": self.company}, "default_supplier")
+ if supplier:
+ self.supplier = supplier
break
def validate_stock_or_nonstock_items(self):
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 3451c62..a1e2919 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -52,9 +52,15 @@
def set_missing_lead_customer_details(self):
if getattr(self, "customer", None):
from erpnext.accounts.party import _get_party_details
+ fetch_payment_terms_template = False
+ if (self.get("__islocal") or
+ self.company != frappe.db.get_value(self.doctype, self.name, 'company')):
+ fetch_payment_terms_template = True
+
party_details = _get_party_details(self.customer,
ignore_permissions=self.flags.ignore_permissions,
- doctype=self.doctype, company=self.company)
+ doctype=self.doctype, company=self.company,
+ fetch_payment_terms_template=fetch_payment_terms_template)
if not self.meta.get_field("sales_team"):
party_details.pop("sales_team")
diff --git a/erpnext/demo/data/physician.json b/erpnext/demo/data/practitioner.json
similarity index 62%
rename from erpnext/demo/data/physician.json
rename to erpnext/demo/data/practitioner.json
index 3afea99..39c960f 100644
--- a/erpnext/demo/data/physician.json
+++ b/erpnext/demo/data/practitioner.json
@@ -1,16 +1,16 @@
[
{
- "doctype": "Physician",
+ "doctype": "Healthcare Practitioner",
"first_name": "Eddie Jessup",
"department": "Pathology"
},
{
- "doctype": "Physician",
+ "doctype": "Healthcare Practitioner",
"first_name": "Deepshi Garg",
"department": "ENT"
},
{
- "doctype": "Physician",
+ "doctype": "Healthcare Practitioner",
"first_name": "Amit Jain",
"department": "Microbiology"
}
diff --git a/erpnext/demo/setup/healthcare.py b/erpnext/demo/setup/healthcare.py
index b48e0bc..3ddb2ae 100644
--- a/erpnext/demo/setup/healthcare.py
+++ b/erpnext/demo/setup/healthcare.py
@@ -16,12 +16,12 @@
make_consulation()
make_appointment()
consulation_on_appointment()
- lab_test_on_consultation()
+ lab_test_on_encounter()
frappe.db.commit()
frappe.clear_cache()
def make_masters():
- import_json("Physician")
+ import_json("Healthcare Practitioner")
import_drug()
frappe.db.commit()
@@ -46,8 +46,8 @@
def make_appointment():
i = 1
while i <= 4:
- physician = get_random("Physician")
- department = frappe.get_value("Physician", physician, "department")
+ practitioner = get_random("Healthcare Practitioner")
+ department = frappe.get_value("Healthcare Practitioner", practitioner, "department")
patient = get_random("Patient")
patient_sex = frappe.get_value("Patient", patient, "sex")
appointment = frappe.new_doc("Patient Appointment")
@@ -59,92 +59,92 @@
appointment.appointment_date = appointment_datetime
appointment.patient = patient
appointment.patient_sex = patient_sex
- appointment.physician = physician
+ appointment.practitioner = practitioner
appointment.department = department
appointment.save(ignore_permissions = True)
i += 1
def make_consulation():
for i in range(3):
- physician = get_random("Physician")
- department = frappe.get_value("Physician", physician, "department")
+ practitioner = get_random("Healthcare Practitioner")
+ department = frappe.get_value("Healthcare Practitioner", practitioner, "department")
patient = get_random("Patient")
patient_sex = frappe.get_value("Patient", patient, "sex")
- consultation = set_consultation(patient, patient_sex, physician, department, getdate(), i)
- consultation.save(ignore_permissions=True)
+ encounter = set_encounter(patient, patient_sex, practitioner, department, getdate(), i)
+ encounter.save(ignore_permissions=True)
def consulation_on_appointment():
for i in range(3):
appointment = get_random("Patient Appointment")
appointment = frappe.get_doc("Patient Appointment",appointment)
- consultation = set_consultation(appointment.patient, appointment.patient_sex, appointment.physician, appointment.department, appointment.appointment_date, i)
- consultation.appointment = appointment.name
- consultation.save(ignore_permissions=True)
+ encounter = set_encounter(appointment.patient, appointment.patient_sex, appointment.practitioner, appointment.department, appointment.appointment_date, i)
+ encounter.appointment = appointment.name
+ encounter.save(ignore_permissions=True)
-def set_consultation(patient, patient_sex, physician, department, consultation_date, i):
- consultation = frappe.new_doc("Consultation")
- consultation.patient = patient
- consultation.patient_sex = patient_sex
- consultation.physician = physician
- consultation.visit_department = department
- consultation.consultation_date = consultation_date
+def set_encounter(patient, patient_sex, practitioner, department, encounter_date, i):
+ encounter = frappe.new_doc("Patient Encounter")
+ encounter.patient = patient
+ encounter.patient_sex = patient_sex
+ encounter.practitioner = practitioner
+ encounter.visit_department = department
+ encounter.encounter_date = encounter_date
if i > 2 and patient_sex=='Female':
- consultation.symptoms = "Having chest pains for the last week."
- consultation.diagnosis = """This patient's description of dull, aching,
+ encounter.symptoms = "Having chest pains for the last week."
+ encounter.diagnosis = """This patient's description of dull, aching,
exertion related substernal chest pain is suggestive of ischemic
cardiac origin. Her findings of a FH of early ASCVD, hypertension,
and early surgical menopause are pertinent risk factors for development
of coronary artery disease. """
else:
- consultation = append_drug_rx(consultation)
- consultation = append_test_rx(consultation)
- return consultation
+ encounter = append_drug_rx(encounter)
+ encounter = append_test_rx(encounter)
+ return encounter
def make_lab_test():
- physician = get_random("Physician")
+ practitioner = get_random("Healthcare Practitioner")
patient = get_random("Patient")
patient_sex = frappe.get_value("Patient", patient, "sex")
template = get_random("Lab Test Template")
- set_lab_test(patient, patient_sex, physician, template)
+ set_lab_test(patient, patient_sex, practitioner, template)
-def lab_test_on_consultation():
+def lab_test_on_encounter():
i = 1
while i <= 2:
test_rx = get_random("Lab Prescription", filters={'test_created': 0})
test_rx = frappe.get_doc("Lab Prescription", test_rx)
- consultation = frappe.get_doc("Consultation", test_rx.parent)
- set_lab_test(consultation.patient, consultation.patient_sex, consultation.physician, test_rx.test_code, test_rx.name)
+ encounter = frappe.get_doc("Patient Encounter", test_rx.parent)
+ set_lab_test(encounter.patient, encounter.patient_sex, encounter.practitioner, test_rx.test_code, test_rx.name)
i += 1
-def set_lab_test(patient, patient_sex, physician, template, rx=None):
+def set_lab_test(patient, patient_sex, practitioner, template, rx=None):
lab_test = frappe.new_doc("Lab Test")
- lab_test.physician = physician
+ lab_test.practitioner = practitioner
lab_test.patient = patient
lab_test.patient_sex = patient_sex
lab_test.template = template
lab_test.prescription = rx
create_test_from_template(lab_test)
-def append_test_rx(consultation):
+def append_test_rx(encounter):
i = 1
while i <= 2:
- test_rx = consultation.append("test_prescription")
+ test_rx = encounter.append("test_prescription")
test_rx.test_code = get_random("Lab Test Template")
i += 1
- return consultation
+ return encounter
-def append_drug_rx(consultation):
+def append_drug_rx(encounter):
i = 1
while i <= 3:
drug = get_random("Item", filters={"item_group":"Drug"})
drug = frappe.get_doc("Item", drug)
- drug_rx = consultation.append("drug_prescription")
+ drug_rx = encounter.append("drug_prescription")
drug_rx.drug_code = drug.item_code
drug_rx.drug_name = drug.item_name
drug_rx.dosage = get_random("Prescription Dosage")
drug_rx.period = get_random("Prescription Duration")
i += 1
- return consultation
+ return encounter
def random_date(start,l):
current = start
diff --git a/erpnext/domains/healthcare.py b/erpnext/domains/healthcare.py
index 3c54b01..5a54cf6 100644
--- a/erpnext/domains/healthcare.py
+++ b/erpnext/domains/healthcare.py
@@ -2,7 +2,7 @@
'desktop_icons': [
'Patient',
'Patient Appointment',
- 'Consultation',
+ 'Patient Encounter',
'Lab Test',
'Healthcare',
'Accounts',
@@ -26,4 +26,4 @@
insert_after='customer')
},
'on_setup': 'erpnext.healthcare.setup.setup_healthcare'
-}
\ No newline at end of file
+}
diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html
index e46a5e7..e2df273 100644
--- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html
+++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.html
@@ -1,5 +1,8 @@
-{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) || frappe.defaults.get_default("letter_head"); %}
-{% if(letterhead) { %}
+{%
+ var letterhead = filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) || frappe.defaults.get_default("letter_head");
+ var report_columns = report.get_columns_for_print();
+%}
+{% if(letterhead) { %}
<div style="margin-bottom: 7px;" class="text-center">
{%= frappe.boot.letter_heads[letterhead].header %}
</div>
@@ -20,8 +23,8 @@
<table class="table table-bordered">
<thead>
<tr>
- {% for(var i=1, l=report.columns.length; i<l; i++) { %}
- <th style="text-transform: uppercase; max-width: 100px">{%= report.columns[i].label %}</th>
+ {% for(var i=1, l=report_columns.length; i<l; i++) { %}
+ <th style="text-transform: uppercase; max-width: 100px">{%= report_columns[i].label %}</th>
{% } %}
</tr>
</thead>
@@ -31,9 +34,9 @@
var row = data[j];
%}
<tr>
- {% for(var i=1, l=report.columns.length; i<l; i++) { %}
+ {% for(var i=1, l=report_columns.length; i<l; i++) { %}
<td class="text-center">
- {% var fieldname = report.columns[i].field; %}
+ {% var fieldname = report_columns[i].field; %}
{% if (!is_null(row[fieldname])) { %}
{%= row[fieldname] %}
{% } %}
diff --git a/erpnext/education/report/final_assessment_grades/final_assessment_grades.js b/erpnext/education/report/final_assessment_grades/final_assessment_grades.js
index ba0a42f..ddff8a8 100644
--- a/erpnext/education/report/final_assessment_grades/final_assessment_grades.js
+++ b/erpnext/education/report/final_assessment_grades/final_assessment_grades.js
@@ -21,7 +21,7 @@
return{
filters: {
"group_based_on": "Batch",
- "academic_year": frappe.query_report_filters_by_name.academic_year.value
+ "academic_year": frappe.query_report.get_filter_value('academic_year')
}
};
}
diff --git a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js b/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js
index 402bb02..104d3ec 100644
--- a/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js
+++ b/erpnext/education/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js
@@ -31,7 +31,7 @@
return frappe.call({
method: "erpnext.education.report.student_monthly_attendance_sheet.student_monthly_attendance_sheet.get_attendance_years",
callback: function(r) {
- var year_filter = frappe.query_report_filters_by_name.year;
+ var year_filter = frappe.query_report.get_filter('year');
year_filter.df.options = r.message;
year_filter.df.default = r.message.split("\n")[0];
year_filter.refresh();
diff --git a/erpnext/erpnext_integrations/stripe_integration.py b/erpnext/erpnext_integrations/stripe_integration.py
new file mode 100644
index 0000000..a35ca28
--- /dev/null
+++ b/erpnext/erpnext_integrations/stripe_integration.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, 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.integrations.utils import create_request_log
+import stripe
+
+def create_stripe_subscription(gateway_controller, data):
+ stripe_settings = frappe.get_doc("Stripe Settings", gateway_controller)
+ stripe_settings.data = frappe._dict(data)
+
+ stripe.api_key = stripe_settings.get_password(fieldname="secret_key", raise_exception=False)
+ stripe.default_http_client = stripe.http_client.RequestsClient()
+
+ try:
+ stripe_settings.integration_request = create_request_log(stripe_settings.data, "Host", "Stripe")
+ stripe_settings.payment_plans = frappe.get_doc("Payment Request", stripe_settings.data.reference_docname).subscription_plans
+ return create_subscription_on_stripe(stripe_settings)
+
+ except Exception:
+ frappe.log_error(frappe.get_traceback())
+ return{
+ "redirect_to": frappe.redirect_to_message(_('Server Error'), _("It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account.")),
+ "status": 401
+ }
+
+
+def create_subscription_on_stripe(stripe_settings):
+ items = []
+ for payment_plan in stripe_settings.payment_plans:
+ plan = frappe.db.get_value("Subscription Plan", payment_plan.plan, "payment_plan_id")
+ items.append({"plan": plan, "quantity": payment_plan.qty})
+
+ try:
+ customer = stripe.Customer.create(description=stripe_settings.data.payer_name, email=stripe_settings.data.payer_email, source=stripe_settings.data.stripe_token_id)
+ subscription = stripe.Subscription.create(customer=customer, items=items)
+
+ if subscription.status == "active":
+ stripe_settings.integration_request.db_set('status', 'Completed', update_modified=False)
+ stripe_settings.flags.status_changed_to = "Completed"
+
+ else:
+ stripe_settings.integration_request.db_set('status', 'Failed', update_modified=False)
+ frappe.log_error('Subscription N°: ' + subscription.id, 'Stripe Payment not completed')
+
+ except Exception:
+ stripe_settings.integration_request.db_set('status', 'Failed', update_modified=False)
+ frappe.log_error(frappe.get_traceback())
+
+ return stripe_settings.finalize_request()
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
index c687393..c316ba7 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
@@ -15,6 +15,41 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "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": "Inpatient Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Record",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -47,6 +82,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -79,10 +115,12 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -111,6 +149,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -142,6 +181,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -173,6 +213,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -205,6 +246,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -237,6 +279,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -267,6 +310,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -299,6 +343,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -331,6 +376,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -363,6 +409,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -394,6 +441,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -426,6 +474,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -457,6 +506,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -488,6 +538,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -520,6 +571,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -553,6 +605,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -585,6 +638,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -617,6 +671,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -659,7 +714,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-04 11:23:32.884076",
+ "modified": "2018-07-12 19:18:30.400534",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedure",
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
index aac4224..35c0ff5 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
@@ -725,7 +725,7 @@
"print": 1,
"read": 1,
"report": 1,
- "role": "Medical Administrator",
+ "role": "Healthcare Administrator",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
@@ -781,4 +781,4 @@
"title_field": "template",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/consultation/consultation_list.js b/erpnext/healthcare/doctype/consultation/consultation_list.js
deleted file mode 100755
index ea3906d..0000000
--- a/erpnext/healthcare/doctype/consultation/consultation_list.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
-(c) ESS 2015-16
-*/
-frappe.listview_settings['Consultation'] = {
- filters:[["docstatus","!=","1"]]
-};
-
diff --git a/erpnext/healthcare/doctype/consultation/test_consultation.py b/erpnext/healthcare/doctype/consultation/test_consultation.py
deleted file mode 100644
index 24dc011..0000000
--- a/erpnext/healthcare/doctype/consultation/test_consultation.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-import unittest
-
-# test_records = frappe.get_test_records('Consultation')
-
-class TestConsultation(unittest.TestCase):
- pass
diff --git a/erpnext/healthcare/doctype/fee_validity/fee_validity.json b/erpnext/healthcare/doctype/fee_validity/fee_validity.json
index 595539c..802f04a 100644
--- a/erpnext/healthcare/doctype/fee_validity/fee_validity.json
+++ b/erpnext/healthcare/doctype/fee_validity/fee_validity.json
@@ -14,11 +14,12 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -27,10 +28,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Physician",
+ "label": "Healthcare Practitioner",
"length": 0,
"no_copy": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -41,10 +42,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -72,10 +75,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -102,10 +107,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -132,10 +139,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -162,10 +171,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -193,6 +204,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -206,7 +218,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-10-05 11:26:35.292841",
+ "modified": "2018-07-16 12:43:45.635230",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Fee Validity",
@@ -215,7 +227,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -238,11 +249,11 @@
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
- "search_fields": "physician,patient",
+ "search_fields": "practitioner, patient",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
- "title_field": "physician",
+ "title_field": "practitioner",
"track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
index ed852f1..64222ad 100644
--- a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
+++ b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.py
@@ -13,7 +13,7 @@
class TestFeeValidity(unittest.TestCase):
def test_fee_validity(self):
patient = get_random("Patient")
- physician = get_random("Physician")
+ practitioner = get_random("Healthcare Practitioner")
department = get_random("Medical Department")
if not patient:
@@ -29,36 +29,36 @@
medical_department.save(ignore_permissions=True)
department = medical_department.name
- if not physician:
- physician = frappe.new_doc("Physician")
- physician.first_name = "Amit Jain"
- physician.department = department
- physician.save(ignore_permissions=True)
- physician = physician.name
+ if not practitioner:
+ practitioner = frappe.new_doc("Healthcare Practitioner")
+ practitioner.first_name = "Amit Jain"
+ practitioner.department = department
+ practitioner.save(ignore_permissions=True)
+ practitioner = practitioner.name
frappe.db.set_value("Healthcare Settings", None, "max_visit", 2)
frappe.db.set_value("Healthcare Settings", None, "valid_days", 7)
- appointment = create_appointment(patient, physician, nowdate(), department)
+ appointment = create_appointment(patient, practitioner, nowdate(), department)
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
self.assertEqual(invoice, None)
invoice_appointment(appointment)
- appointment = create_appointment(patient, physician, add_days(nowdate(), 4), department)
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 4), department)
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
self.assertTrue(invoice)
- appointment = create_appointment(patient, physician, add_days(nowdate(), 5), department)
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 5), department)
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
self.assertEqual(invoice, None)
- appointment = create_appointment(patient, physician, add_days(nowdate(), 10), department)
+ appointment = create_appointment(patient, practitioner, add_days(nowdate(), 10), department)
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
self.assertEqual(invoice, None)
-def create_appointment(patient, physician, appointment_date, department):
+def create_appointment(patient, practitioner, appointment_date, department):
appointment = frappe.new_doc("Patient Appointment")
appointment.patient = patient
- appointment.physician = physician
+ appointment.practitioner = practitioner
appointment.department = department
appointment.appointment_date = appointment_date
appointment.company = "_Test Company"
diff --git a/erpnext/healthcare/doctype/consultation/__init__.py b/erpnext/healthcare/doctype/healthcare_practitioner/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/consultation/__init__.py
copy to erpnext/healthcare/doctype/healthcare_practitioner/__init__.py
diff --git a/erpnext/healthcare/doctype/physician/physician.js b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
old mode 100755
new mode 100644
similarity index 90%
rename from erpnext/healthcare/doctype/physician/physician.js
rename to erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
index 0b1a077..f2dc849
--- a/erpnext/healthcare/doctype/physician/physician.js
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.js
@@ -1,7 +1,7 @@
// Copyright (c) 2016, ESS LLP and contributors
// For license information, please see license.txt
-frappe.ui.form.on('Physician', {
+frappe.ui.form.on('Healthcare Practitioner', {
setup: function(frm) {
frm.set_query('account', 'accounts', function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
@@ -15,11 +15,11 @@
});
},
refresh: function(frm) {
- frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Physician'};
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Healthcare Practitioner'};
if(!frm.is_new()) {
frappe.contacts.render_address_and_contact(frm);
}
- frm.set_query("service_unit", "physician_schedules", function(){
+ frm.set_query("service_unit", "practitioner_schedules", function(){
return {
filters: {
"is_group": false,
@@ -30,7 +30,7 @@
}
});
-frappe.ui.form.on("Physician", "user_id",function(frm) {
+frappe.ui.form.on("Healthcare Practitioner", "user_id",function(frm) {
if(frm.doc.user_id){
frappe.call({
"method": "frappe.client.get",
@@ -64,7 +64,7 @@
}
});
-frappe.ui.form.on("Physician", "employee", function(frm) {
+frappe.ui.form.on("Healthcare Practitioner", "employee", function(frm) {
if(frm.doc.employee){
frappe.call({
"method": "frappe.client.get",
diff --git a/erpnext/healthcare/doctype/physician/physician.json b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
similarity index 94%
rename from erpnext/healthcare/doctype/physician/physician.json
rename to erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
index 7fb1a56..e7c575d 100644
--- a/erpnext/healthcare/doctype/physician/physician.json
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.json
@@ -14,6 +14,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -45,6 +46,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -76,6 +78,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -107,6 +110,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -138,6 +142,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -170,6 +175,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -202,6 +208,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -234,6 +241,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -266,6 +274,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -296,6 +305,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -327,6 +337,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -358,6 +369,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -389,6 +401,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -420,6 +433,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -451,11 +465,12 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "physician_schedules",
+ "fieldname": "practitioner_schedules",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -464,10 +479,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Physician Schedules",
+ "label": "Practitioner Schedules",
"length": 0,
"no_copy": 0,
- "options": "Physician Service Unit Schedule",
+ "options": "Practitioner Service Unit Schedule",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -483,6 +498,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -514,6 +530,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -546,6 +563,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -577,6 +595,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -608,6 +627,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -638,6 +658,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -669,6 +690,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -700,6 +722,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -732,6 +755,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -774,16 +798,15 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-03-09 15:25:43.166877",
+ "modified": "2018-07-10 11:18:58.760297",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Physician",
+ "name": "Healthcare Practitioner",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
@@ -803,7 +826,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -823,7 +845,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
diff --git a/erpnext/healthcare/doctype/physician/physician.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
similarity index 62%
rename from erpnext/healthcare/doctype/physician/physician.py
rename to erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
index eb03083..753ecd1 100644
--- a/erpnext/healthcare/doctype/physician/physician.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
@@ -10,12 +10,12 @@
from erpnext.accounts.party import validate_party_accounts
from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
-class Physician(Document):
+class HealthcarePractitioner(Document):
def onload(self):
load_address_and_contact(self)
def autoname(self):
- # physician first_name and last_name
+ # practitioner first_name and last_name
self.name = " ".join(filter(None,
[cstr(self.get(f)).strip() for f in ["first_name","middle_name","last_name"]]))
@@ -25,20 +25,20 @@
if self.user_id:
self.validate_for_enabled_user_id()
self.validate_duplicate_user_id()
- existing_user_id = frappe.db.get_value("Physician", self.name, "user_id")
+ existing_user_id = frappe.db.get_value("Healthcare Practitioner", self.name, "user_id")
if self.user_id != existing_user_id:
frappe.permissions.remove_user_permission(
- "Physician", self.name, existing_user_id)
+ "Healthcare Practitioner", self.name, existing_user_id)
else:
- existing_user_id = frappe.db.get_value("Physician", self.name, "user_id")
+ existing_user_id = frappe.db.get_value("Healthcare Practitioner", self.name, "user_id")
if existing_user_id:
frappe.permissions.remove_user_permission(
- "Physician", self.name, existing_user_id)
+ "Healthcare Practitioner", self.name, existing_user_id)
def on_update(self):
if self.user_id:
- frappe.permissions.add_user_permission("Physician", self.name, self.user_id)
+ frappe.permissions.add_user_permission("Healthcare Practitioner", self.name, self.user_id)
def validate_for_enabled_user_id(self):
@@ -49,11 +49,11 @@
frappe.throw(_("User {0} is disabled").format(self.user_id))
def validate_duplicate_user_id(self):
- physician = frappe.db.sql_list("""select name from `tabPhysician` where
+ practitioner = frappe.db.sql_list("""select name from `tabHealthcare Practitioner` where
user_id=%s and name!=%s""", (self.user_id, self.name))
- if physician:
- throw(_("User {0} is already assigned to Physician {1}").format(
- self.user_id, physician[0]), frappe.DuplicateEntryError)
+ if practitioner:
+ throw(_("User {0} is already assigned to Healthcare Practitioner {1}").format(
+ self.user_id, practitioner[0]), frappe.DuplicateEntryError)
def on_trash(self):
- delete_contact_and_address('Physician', self.name)
+ delete_contact_and_address('Healthcare Practitioner', self.name)
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
new file mode 100644
index 0000000..3c01ab0
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner_dashboard.py
@@ -0,0 +1,18 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'heatmap': True,
+ 'heatmap_message': _('This is based on transactions against this Healthcare Practitioner.'),
+ 'fieldname': 'practitioner',
+ 'transactions': [
+ {
+ 'label': _('Appointments and Patient Encounters'),
+ 'items': ['Patient Appointment', 'Patient Encounter']
+ },
+ {
+ 'label': _('Lab Tests'),
+ 'items': ['Lab Test']
+ }
+ ]
+ }
diff --git a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js b/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.js
similarity index 67%
copy from erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
copy to erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.js
index c397f18..75aa208 100644
--- a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Physician Schedule", function (assert) {
+QUnit.test("test: Healthcare Practitioner", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
- // insert a new Physician Schedule
- () => frappe.tests.make('Physician Schedule', [
+ // insert a new Healthcare Practitioner
+ () => frappe.tests.make('Healthcare Practitioner', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.py
new file mode 100644
index 0000000..de8201b
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+import unittest
+
+class TestHealthcarePractitioner(unittest.TestCase):
+ pass
diff --git a/erpnext/healthcare/doctype/physician_schedule_time_slot/__init__.py b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/physician_schedule_time_slot/__init__.py
rename to erpnext/healthcare/doctype/healthcare_schedule_time_slot/__init__.py
diff --git a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.json b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
similarity index 94%
rename from erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.json
rename to erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
index 8aece2b..9faa5b2 100644
--- a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.json
+++ b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.json
@@ -41,6 +41,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -71,6 +72,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -101,6 +103,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -114,10 +117,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-07-12 14:28:01.985998",
+ "modified": "2018-05-08 13:45:57.226530",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Physician Schedule Time Slot",
+ "name": "Healthcare Schedule Time Slot",
"name_case": "",
"owner": "rmehta@gmail.com",
"permissions": [],
diff --git a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.py b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.py
similarity index 61%
rename from erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.py
rename to erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.py
index abdce51..e58ea53 100644
--- a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.py
+++ b/erpnext/healthcare/doctype/healthcare_schedule_time_slot/healthcare_schedule_time_slot.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.model.document import Document
-class PhysicianScheduleTimeSlot(Document):
+class HealthcareScheduleTimeSlot(Document):
pass
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
index e966515..8480a52 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
@@ -17,6 +17,7 @@
},
refresh: function(frm) {
frm.trigger("set_root_readonly");
+ frm.set_df_property("service_unit_type", "reqd", 1);
frm.add_custom_button(__("Healthcare Service Unit Tree"), function() {
frappe.set_route("Tree", "Healthcare Service Unit");
});
@@ -35,8 +36,12 @@
}
},
is_group: function(frm) {
- if(frm.doc.is_group){
+ if(frm.doc.is_group == 1){
frm.set_value("allow_appointments", false);
+ frm.set_df_property("service_unit_type", "reqd", 0);
+ }
+ else{
+ frm.set_df_property("service_unit_type", "reqd", 1);
}
}
});
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
index d11ecdc..945817c 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
@@ -15,6 +15,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -46,6 +47,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -78,10 +80,13 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.inpatient_occupancy != 1 && doc.allow_appointments != 1",
"fieldname": "is_group",
"fieldtype": "Check",
"hidden": 0,
@@ -109,11 +114,48 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.is_group != 1",
+ "fieldname": "service_unit_type",
+ "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": "Service Unit Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Healthcare Service Unit 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": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.is_group != 1",
+ "default": "0",
+ "depends_on": "eval:doc.is_group != 1 && doc.inpatient_occupancy != 1",
+ "fetch_from": "service_unit_type.allow_appointments",
"fieldname": "allow_appointments",
"fieldtype": "Check",
"hidden": 0,
@@ -125,12 +167,12 @@
"in_standard_filter": 0,
"label": "Allow Appointments",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -141,11 +183,14 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
- "bold": 1,
+ "bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.is_group != 1 && doc.allow_appointments == 1",
+ "default": "0",
+ "depends_on": "eval:doc.is_group != 1 && doc.allow_appointments == 1 && doc.inpatient_occupany != 1",
+ "fetch_from": "service_unit_type.overlap_appointments",
"fieldname": "overlap_appointments",
"fieldtype": "Check",
"hidden": 0,
@@ -157,12 +202,12 @@
"in_standard_filter": 0,
"label": "Allow Overlap",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -173,6 +218,76 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.allow_appointments != 1 && doc.is_group != 1",
+ "fetch_from": "service_unit_type.inpatient_occupancy",
+ "fieldname": "inpatient_occupancy",
+ "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": "Inpatient Occupancy",
+ "length": 0,
+ "no_copy": 1,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.inpatient_occupancy == 1",
+ "fieldname": "occupied",
+ "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": "Occupied",
+ "length": 0,
+ "no_copy": 1,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -189,7 +304,7 @@
"in_standard_filter": 0,
"label": "Warehouse",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Warehouse",
"permlevel": 0,
"precision": "",
@@ -206,6 +321,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -238,6 +354,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -269,6 +386,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -300,6 +418,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -341,7 +460,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-04 11:20:16.942603",
+ "modified": "2018-07-17 17:40:18.867327",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare Service Unit",
@@ -380,7 +499,7 @@
"print": 1,
"read": 1,
"report": 1,
- "role": "Medical Administrator",
+ "role": "Healthcare Administrator",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
index 21b0e6e..89adbf8 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
@@ -14,8 +14,9 @@
self.validate_one_root()
def validate(self):
- if self.is_group:
- self.allow_appointments = False
- self.overlap_appointments = False
- elif not self.allow_appointments:
- self.overlap_appointments = False
+ if self.is_group == 1:
+ self.allow_appointments = 0
+ self.overlap_appointments = 0
+ self.inpatient_occupancy = 0
+ elif self.allow_appointments != 1:
+ self.overlap_appointments = 0
diff --git a/erpnext/healthcare/doctype/consultation/__init__.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/consultation/__init__.py
copy to erpnext/healthcare/doctype/healthcare_service_unit_type/__init__.py
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
new file mode 100644
index 0000000..84255b29
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
@@ -0,0 +1,119 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Healthcare Service Unit Type', {
+ service_unit_type: function(frm) {
+ set_item_details(frm);
+ if(!frm.doc.__islocal){
+ frm.doc.change_in_item = 1;
+ }
+ },
+ is_billable: function(frm) {
+ set_item_details(frm);
+ },
+ refresh: function(frm) {
+ frm.set_df_property("item_code", "read_only", frm.doc.__islocal ? 0 : 1);
+ if(!frm.doc.__islocal) {
+ frm.add_custom_button(__('Change Item Code'), function() {
+ change_item_code(cur_frm,frm.doc);
+ } );
+ if(frm.doc.disabled == 1){
+ frm.add_custom_button(__('Enable'), function() {
+ enable(cur_frm);
+ } );
+ }
+ else{
+ frm.add_custom_button(__('Disable'), function() {
+ disable(cur_frm);
+ } );
+ }
+ }
+ },
+ rate: function(frm) {
+ if(!frm.doc.__islocal){
+ frm.doc.change_in_item = 1;
+ }
+ },
+ item_group: function(frm) {
+ if(!frm.doc.__islocal){
+ frm.doc.change_in_item = 1;
+ }
+ },
+ description: function(frm) {
+ if(!frm.doc.__islocal){
+ frm.doc.change_in_item = 1;
+ }
+ }
+});
+
+var disable = function(frm){
+ var doc = frm.doc;
+ frappe.call({
+ method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
+ args: {status: 1, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
+ callback: function(){
+ cur_frm.reload_doc();
+ }
+ });
+};
+
+var enable = function(frm){
+ var doc = frm.doc;
+ frappe.call({
+ method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
+ args: {status: 0, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
+ callback: function(){
+ cur_frm.reload_doc();
+ }
+ });
+};
+
+var change_item_code = function(frm, doc){
+ var d = new frappe.ui.Dialog({
+ title:__("Change Item Code"),
+ fields:[
+ {
+ "fieldtype": "Data",
+ "label": "Item Code",
+ "fieldname": "Item Code",
+ reqd:1
+ },
+ {
+ "fieldtype": "Button",
+ "label": __("Change Code"),
+ click: function() {
+ var values = d.get_values();
+ if(!values)
+ return;
+ change_item_code_from_unit_type(values["Item Code"], doc);
+ d.hide();
+ }
+ }
+ ]
+ });
+ d.show();
+ d.set_values({
+ 'Item Code': frm.doc.item_code
+ });
+
+ var change_item_code_from_unit_type = function(item_code, doc){
+ frappe.call({
+ "method": "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.change_item_code",
+ "args": {item: doc.item, item_code: item_code, doc_name: doc.name},
+ callback: function () {
+ frm.reload_doc();
+ }
+ });
+ };
+};
+
+var set_item_details = function(frm) {
+ if(frm.doc.service_unit_type && frm.doc.is_billable == 1){
+ if(!frm.doc.item_code)
+ frm.set_value("item_code", frm.doc.service_unit_type);
+ if(!frm.doc.description)
+ frm.set_value("description", frm.doc.service_unit_type);
+ if(!frm.doc.item_group)
+ frm.set_value("item_group", 'Services');
+ }
+};
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
new file mode 100644
index 0000000..6394ce7
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.json
@@ -0,0 +1,554 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:service_unit_type",
+ "beta": 0,
+ "creation": "2018-07-11 16:47:51.414675",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "service_unit_type",
+ "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": "Service Unit Type",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.inpatient_occupancy != 1",
+ "fieldname": "allow_appointments",
+ "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": "Allow Appointments",
+ "length": 0,
+ "no_copy": 1,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.allow_appointments == 1 && doc.inpatient_occupany != 1",
+ "fieldname": "overlap_appointments",
+ "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": "Allow Overlap",
+ "length": 0,
+ "no_copy": 1,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.allow_appointments != 1",
+ "fieldname": "inpatient_occupancy",
+ "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": "Inpatient Occupancy",
+ "length": 0,
+ "no_copy": 1,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.inpatient_occupancy == 1 && doc.allow_appointments != 1",
+ "fieldname": "is_billable",
+ "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": "Is 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "is_billable",
+ "fieldname": "item_details",
+ "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": "Item Details",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item_code",
+ "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": "Item Code",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item_group",
+ "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 Group",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item Group",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "uom",
+ "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": "UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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": 0,
+ "in_standard_filter": 0,
+ "label": "Rate / UOM",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_11",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fieldname": "disabled",
+ "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": "Disabled",
+ "length": 0,
+ "no_copy": 1,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "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": "Description",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "change_in_item",
+ "fieldtype": "Check",
+ "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": "Change in Item",
+ "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,
+ "translatable": 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": "2018-07-13 16:54:59.131606",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Healthcare Service Unit Type",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 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": "Healthcare Administrator",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "service_unit_type",
+ "track_changes": 0,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
new file mode 100644
index 0000000..e0d380b
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, 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.model.document import Document
+
+class HealthcareServiceUnitType(Document):
+ def after_insert(self):
+ if self.inpatient_occupancy and self.is_billable:
+ create_item(self)
+
+ def on_trash(self):
+ if(self.item):
+ try:
+ frappe.delete_doc("Item",self.item)
+ except Exception:
+ frappe.throw(_("""Not permitted. Please disable the Service Unit Type"""))
+
+ def on_update(self):
+ if(self.change_in_item and self.is_billable == 1 and self.item):
+ updating_item(self)
+ if not item_price_exist(self):
+ if(self.test_rate != 0.0):
+ price_list_name = frappe.db.get_value("Price List", {"selling": 1})
+ if(self.test_rate):
+ make_item_price(self.test_code, price_list_name, self.test_rate)
+ else:
+ make_item_price(self.test_code, price_list_name, 0.0)
+
+ frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
+ elif(self.is_billable == 0 and self.item):
+ frappe.db.set_value("Item",self.item,"disabled",1)
+ self.reload()
+
+def item_price_exist(doc):
+ item_price = frappe.db.exists({
+ "doctype": "Item Price",
+ "item_code": doc.item_code})
+ if(item_price):
+ return True
+ else:
+ return False
+
+def updating_item(doc):
+ frappe.db.sql("""update `tabItem` set item_name=%s, item_group=%s, disabled=0, standard_rate=%s,
+ description=%s, modified=NOW() where item_code=%s""",
+ (doc.service_unit_type, doc.item_group , doc.rate, doc.description, doc.item))
+
+def create_item(doc):
+ #insert item
+ item = frappe.get_doc({
+ "doctype": "Item",
+ "item_code": doc.item_code,
+ "item_name":doc.service_unit_type,
+ "item_group": doc.item_group,
+ "description":doc.description,
+ "is_sales_item": 1,
+ "is_service_item": 1,
+ "is_purchase_item": 0,
+ "is_stock_item": 0,
+ "show_in_website": 0,
+ "is_pro_applicable": 0,
+ "disabled": 0,
+ "stock_uom": doc.uom
+ }).insert(ignore_permissions=True)
+
+ #insert item price
+ #get item price list to insert item price
+ if(doc.rate != 0.0):
+ price_list_name = frappe.db.get_value("Price List", {"selling": 1})
+ if(doc.rate):
+ make_item_price(item.name, price_list_name, doc.rate)
+ item.standard_rate = doc.rate
+ else:
+ make_item_price(item.name, price_list_name, 0.0)
+ item.standard_rate = 0.0
+ item.save(ignore_permissions = True)
+ #Set item to the Doc
+ frappe.db.set_value("Healthcare Service Unit Type", doc.name, "item", item.name)
+
+ doc.reload() #refresh the doc after insert.
+
+def make_item_price(item, price_list_name, item_price):
+ frappe.get_doc({
+ "doctype": "Item Price",
+ "price_list": price_list_name,
+ "item_code": item,
+ "price_list_rate": item_price
+ }).insert(ignore_permissions=True)
+
+@frappe.whitelist()
+def change_item_code(item, item_code, doc_name):
+ item_exist = frappe.db.exists({
+ "doctype": "Item",
+ "item_code": item_code})
+ if(item_exist):
+ frappe.throw(_("Code {0} already exist").format(item_code))
+ else:
+ frappe.rename_doc("Item", item, item_code, ignore_permissions = True)
+ frappe.db.set_value("Healthcare Service Unit Type", doc_name, "item_code", item_code)
+
+@frappe.whitelist()
+def disable_enable(status, doc_name, item, is_billable):
+ frappe.db.set_value("Healthcare Service Unit Type", doc_name, "disabled", status)
+ if(is_billable == 1):
+ frappe.db.set_value("Item", item, "disabled", status)
diff --git a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js
similarity index 65%
copy from erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
copy to erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js
index c397f18..6db8f9e 100644
--- a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Physician Schedule", function (assert) {
+QUnit.test("test: Healthcare Service Unit Type", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
- // insert a new Physician Schedule
- () => frappe.tests.make('Physician Schedule', [
+ // insert a new Healthcare Service Unit Type
+ () => frappe.tests.make('Healthcare Service Unit Type', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py
new file mode 100644
index 0000000..3c5b64f
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+import unittest
+
+class TestHealthcareServiceUnitType(unittest.TestCase):
+ pass
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
index 7d9f2c7..0bd8534 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json
@@ -14,6 +14,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -40,10 +41,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -71,10 +74,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -103,10 +108,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -134,10 +141,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -163,10 +172,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -193,10 +204,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -225,10 +238,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -242,7 +257,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Consultations in valid days",
+ "label": "Patient Encounters in valid days",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -255,10 +270,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -285,10 +302,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -315,10 +334,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -345,10 +366,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -377,10 +400,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -407,15 +432,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "Hello {{doc.patient}}, You have scheduled an appointment with {{doc.physician}} by {{doc.start_dt}} at {{doc.company}}.\nThank you, Good day!",
+ "default": "Hello {{doc.patient}}, You have scheduled an appointment with {{doc.practitioner}} by {{doc.start_dt}} at {{doc.company}}.\nThank you, Good day!",
"depends_on": "app_con",
"fieldname": "app_con_msg",
"fieldtype": "Small Text",
@@ -439,10 +466,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -471,10 +500,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -500,10 +531,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -530,15 +563,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "Hello {{doc.patient}}, You have an appointment with {{doc.physician}} by {{doc.appointment_time}} at {{doc.company}}.\nThank you, Good day!\n",
+ "default": "Hello {{doc.patient}}, You have an appointment with {{doc.practitioner}} by {{doc.appointment_time}} at {{doc.company}}.\nThank you, Good day!\n",
"depends_on": "app_rem",
"fieldname": "app_rem_msg",
"fieldtype": "Small Text",
@@ -562,10 +597,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -593,15 +630,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
- "description": "Default income accounts to be used if not set in Physician to book Consultation charges.",
+ "description": "Default income accounts to be used if not set in Healthcare Practitioner to book Appointment charges.",
"fieldname": "sb_in_ac",
"fieldtype": "Section Break",
"hidden": 0,
@@ -624,10 +663,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -655,15 +696,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
- "description": "Default receivable accounts to be used if not set in Patient to book Consultation charges.",
+ "description": "Default receivable accounts to be used if not set in Patient to book Appointment charges.",
"fieldname": "sb_r_ac",
"fieldtype": "Section Break",
"hidden": 0,
@@ -686,10 +729,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -717,10 +762,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -747,10 +794,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -778,10 +827,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -808,10 +859,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -837,10 +890,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -868,10 +923,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -899,10 +956,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -929,10 +988,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -960,10 +1021,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -989,10 +1052,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1020,6 +1085,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -1033,7 +1099,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-10-05 11:36:44.087182",
+ "modified": "2018-07-16 14:00:04.171717",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare Settings",
@@ -1042,7 +1108,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
index ae7c4c5..3a142f5 100644
--- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
+++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.py
@@ -50,9 +50,9 @@
return receivable_account
return frappe.db.get_value("Company", company, "default_receivable_account")
-def get_income_account(physician, company):
- if(physician):
- income_account = get_account("Physician", None, physician, company)
+def get_income_account(practitioner, company):
+ if(practitioner):
+ income_account = get_account("Healthcare Practitioner", None, practitioner, company)
if income_account:
return income_account
income_account = get_account(None, "income_account", "Healthcare Settings", company)
diff --git a/erpnext/healthcare/doctype/consultation/__init__.py b/erpnext/healthcare/doctype/inpatient_occupancy/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/consultation/__init__.py
copy to erpnext/healthcare/doctype/inpatient_occupancy/__init__.py
diff --git a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.json b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
similarity index 61%
copy from erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.json
copy to erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
index 8aece2b..2ac498d 100644
--- a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.json
+++ b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
@@ -3,8 +3,8 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
- "beta": 1,
- "creation": "2017-05-03 17:27:07.466088",
+ "beta": 0,
+ "creation": "2018-07-12 12:07:36.932333",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
@@ -14,12 +14,13 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "day",
- "fieldtype": "Select",
+ "fieldname": "service_unit",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -27,30 +28,32 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Day",
+ "label": "Healthcare Service Unit",
"length": 0,
"no_copy": 0,
- "options": "Sunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday",
+ "options": "Healthcare Service Unit",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "from_time",
- "fieldtype": "Time",
+ "fieldname": "check_in",
+ "fieldtype": "Datetime",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -58,49 +61,84 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "From Time",
+ "label": "Check In",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "to_time",
- "fieldtype": "Time",
+ "fieldname": "left",
+ "fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
- "in_list_view": 1,
+ "in_list_view": 0,
"in_standard_filter": 0,
- "label": "To Time",
+ "label": "Left",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "check_out",
+ "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": "Check Out",
+ "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,
+ "translatable": 0,
"unique": 0
}
],
@@ -114,17 +152,16 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-07-12 14:28:01.985998",
+ "modified": "2018-07-17 18:26:46.009878",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Physician Schedule Time Slot",
+ "name": "Inpatient Occupancy",
"name_case": "",
- "owner": "rmehta@gmail.com",
+ "owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
diff --git a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.py b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py
similarity index 60%
copy from erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.py
copy to erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py
index abdce51..52de25b 100644
--- a/erpnext/healthcare/doctype/physician_schedule_time_slot/physician_schedule_time_slot.py
+++ b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.model.document import Document
-class PhysicianScheduleTimeSlot(Document):
+class InpatientOccupancy(Document):
pass
diff --git a/erpnext/healthcare/doctype/consultation/__init__.py b/erpnext/healthcare/doctype/inpatient_record/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/consultation/__init__.py
rename to erpnext/healthcare/doctype/inpatient_record/__init__.py
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
new file mode 100644
index 0000000..936c682
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.js
@@ -0,0 +1,185 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Inpatient Record', {
+ refresh: function(frm) {
+ if(!frm.doc.__islocal && frm.doc.status == "Admission Scheduled"){
+ frm.add_custom_button(__('Admit'), function() {
+ admit_patient_dialog(frm);
+ } );
+ frm.set_df_property("btn_transfer", "hidden", 1);
+ }
+ if(!frm.doc.__islocal && frm.doc.status == "Discharge Scheduled"){
+ frm.add_custom_button(__('Discharge'), function() {
+ discharge_patient(frm);
+ } );
+ frm.set_df_property("btn_transfer", "hidden", 0);
+ }
+ if(!frm.doc.__islocal && (frm.doc.status == "Discharged" || frm.doc.status == "Discharge Scheduled")){
+ frm.disable_save();
+ frm.set_df_property("btn_transfer", "hidden", 1);
+ }
+ },
+ btn_transfer: function(frm) {
+ transfer_patient_dialog(frm);
+ }
+});
+
+var discharge_patient = function(frm) {
+ frappe.call({
+ doc: frm.doc,
+ method: "discharge",
+ callback: function(data) {
+ if(!data.exc){
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: "Process Discharge"
+ });
+};
+
+var admit_patient_dialog = function(frm){
+ var dialog = new frappe.ui.Dialog({
+ title: 'Admit Patient',
+ width: 100,
+ fields: [
+ {fieldtype: "Link", label: "Service Unit Type", fieldname: "service_unit_type", options: "Healthcare Service Unit Type"},
+ {fieldtype: "Link", label: "Service Unit", fieldname: "service_unit", options: "Healthcare Service Unit", reqd: 1},
+ {fieldtype: "Datetime", label: "Admission Datetime", fieldname: "check_in", reqd: 1},
+ {fieldtype: "Date", label: "Expected Discharge", fieldname: "expected_discharge"}
+ ],
+ primary_action_label: __("Admit"),
+ primary_action : function(){
+ var service_unit = dialog.get_value('service_unit');
+ var check_in = dialog.get_value('check_in');
+ var expected_discharge = null;
+ if(dialog.get_value('expected_discharge')){
+ expected_discharge = dialog.get_value('expected_discharge');
+ }
+ if(!service_unit && !check_in){
+ return;
+ }
+ frappe.call({
+ doc: frm.doc,
+ method: 'admit',
+ args:{
+ 'service_unit': service_unit,
+ 'check_in': check_in,
+ 'expected_discharge': expected_discharge
+ },
+ callback: function(data) {
+ if(!data.exc){
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: "Process Admission"
+ });
+ frm.refresh_fields();
+ dialog.hide();
+ }
+ });
+
+ dialog.fields_dict["service_unit_type"].get_query = function(){
+ return {
+ filters: {
+ "inpatient_occupancy": 1,
+ "allow_appointments": 0
+ }
+ };
+ };
+ dialog.fields_dict["service_unit"].get_query = function(){
+ return {
+ filters: {
+ "is_group": 0,
+ "service_unit_type": dialog.get_value("service_unit_type"),
+ "occupied" : 0
+ }
+ };
+ };
+
+ dialog.show();
+};
+
+var transfer_patient_dialog = function(frm){
+ var dialog = new frappe.ui.Dialog({
+ title: 'Transfer Patient',
+ width: 100,
+ fields: [
+ {fieldtype: "Link", label: "Leave From", fieldname: "leave_from", options: "Healthcare Service Unit", reqd: 1, read_only:1},
+ {fieldtype: "Link", label: "Service Unit Type", fieldname: "service_unit_type", options: "Healthcare Service Unit Type"},
+ {fieldtype: "Link", label: "Transfer To", fieldname: "service_unit", options: "Healthcare Service Unit", reqd: 1},
+ {fieldtype: "Datetime", label: "Check In", fieldname: "check_in", reqd: 1}
+ ],
+ primary_action_label: __("Transfer"),
+ primary_action : function(){
+ var service_unit = null;
+ var check_in = dialog.get_value('check_in');
+ var leave_from = null;
+ if(dialog.get_value('leave_from')){
+ leave_from = dialog.get_value('leave_from');
+ }
+ if(dialog.get_value('service_unit')){
+ service_unit = dialog.get_value('service_unit');
+ }
+ if(!check_in){
+ return;
+ }
+ frappe.call({
+ doc: frm.doc,
+ method: 'transfer',
+ args:{
+ 'service_unit': service_unit,
+ 'check_in': check_in,
+ 'leave_from': leave_from
+ },
+ callback: function(data) {
+ if(!data.exc){
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: "Process Transfer"
+ });
+ frm.refresh_fields();
+ dialog.hide();
+ }
+ });
+
+ dialog.fields_dict["leave_from"].get_query = function(){
+ return {
+ query : "erpnext.healthcare.doctype.inpatient_record.inpatient_record.get_leave_from",
+ filters: {docname:frm.doc.name}
+ };
+ };
+ dialog.fields_dict["service_unit_type"].get_query = function(){
+ return {
+ filters: {
+ "inpatient_occupancy": 1,
+ "allow_appointments": 0
+ }
+ };
+ };
+ dialog.fields_dict["service_unit"].get_query = function(){
+ return {
+ filters: {
+ "is_group": 0,
+ "service_unit_type": dialog.get_value("service_unit_type"),
+ "occupied" : 0
+ }
+ };
+ };
+
+ dialog.show();
+
+ var not_left_service_unit = null;
+ for(let inpatient_occupancy in frm.doc.inpatient_occupancies){
+ if(frm.doc.inpatient_occupancies[inpatient_occupancy].left != 1){
+ not_left_service_unit = frm.doc.inpatient_occupancies[inpatient_occupancy].service_unit;
+ }
+ }
+ dialog.set_values({
+ 'leave_from': not_left_service_unit
+ });
+};
diff --git a/erpnext/healthcare/doctype/consultation/consultation.json b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
similarity index 73%
copy from erpnext/healthcare/doctype/consultation/consultation.json
copy to erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
index 2f6de0c..2f9f1f1 100644
--- a/erpnext/healthcare/doctype/consultation/consultation.json
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
@@ -1,20 +1,21 @@
{
- "allow_copy": 1,
+ "allow_copy": 0,
"allow_guest_to_view": 0,
- "allow_import": 1,
+ "allow_import": 0,
"allow_rename": 0,
"autoname": "naming_series:",
- "beta": 1,
- "creation": "2016-04-21 10:53:44.637684",
+ "beta": 0,
+ "creation": "2018-07-11 17:48:51.404139",
"custom": 0,
- "default_print_format": "",
"docstatus": 0,
"doctype": "DocType",
- "document_type": "Document",
+ "document_type": "",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -40,10 +41,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -60,39 +63,7 @@
"label": "Series",
"length": 0,
"no_copy": 0,
- "options": "C-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "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": "",
- "fieldname": "appointment",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Appointment",
- "length": 0,
- "no_copy": 0,
- "options": "Patient Appointment",
+ "options": "IP-",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -101,43 +72,14 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "type",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Type",
- "length": 0,
- "no_copy": 1,
- "options": "Appointment Type",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -145,12 +87,12 @@
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
- "ignore_user_permissions": 1,
+ "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 1,
+ "in_standard_filter": 0,
"label": "Patient",
"length": 0,
"no_copy": 0,
@@ -163,50 +105,55 @@
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
- "search_index": 1,
+ "search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "patient_age",
+ "fetch_from": "patient.patient_name",
+ "fieldname": "patient_name",
"fieldtype": "Data",
- "hidden": 1,
+ "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": "Age",
+ "label": "Patient Name",
"length": 0,
"no_copy": 0,
- "options": "",
"permlevel": 0,
"precision": "",
- "print_hide": 1,
+ "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
- "report_hide": 1,
+ "report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "patient_sex",
- "fieldtype": "Select",
- "hidden": 1,
+ "fetch_from": "patient.sex",
+ "fieldname": "gender",
+ "fieldtype": "Link",
+ "hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
@@ -216,38 +163,7 @@
"label": "Gender",
"length": 0,
"no_copy": 0,
- "options": "\nMale\nFemale\nOther",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "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": "physician",
- "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": 1,
- "label": "Doctor",
- "length": 0,
- "no_copy": 0,
- "options": "Physician",
+ "options": "Gender",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -255,30 +171,33 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 1,
+ "fetch_from": "patient.blood_group",
+ "fieldname": "blood_group",
+ "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": "Company",
+ "label": "Blood Group",
"length": 0,
"no_copy": 0,
- "options": "Company",
+ "options": "\nA Positive\nA Negative\nAB Positive\nAB Negative\nB Positive\nB Negative\nO Positive\nO Negative",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -289,15 +208,149 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "column_break_6",
+ "fieldname": "dob",
+ "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": "Date of birth",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "patient.mobile",
+ "fieldname": "mobile",
+ "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": "Mobile",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "patient.email",
+ "fieldname": "email",
+ "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": "Email",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Email",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "patient.phone",
+ "fieldname": "phone",
+ "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": "Phone",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_8",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -318,47 +371,51 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "visit_department",
- "fieldtype": "Link",
+ "fieldname": "status",
+ "fieldtype": "Select",
"hidden": 0,
- "ignore_user_permissions": 1,
+ "ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Department",
+ "in_standard_filter": 0,
+ "label": "Status",
"length": 0,
"no_copy": 0,
- "options": "Medical Department",
+ "options": "Admission Scheduled\nAdmitted\nDischarge Scheduled\nDischarged",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
- "search_index": 1,
+ "search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
- "fieldname": "consultation_date",
+ "fieldname": "scheduled_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -367,7 +424,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Consultation Date",
+ "label": "Admission Schedule Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -380,25 +437,27 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "",
- "fieldname": "consultation_time",
- "fieldtype": "Time",
+ "default": "Today",
+ "fieldname": "admitted_datetime",
+ "fieldtype": "Datetime",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
- "in_list_view": 0,
+ "in_list_view": 1,
"in_standard_filter": 0,
- "label": "Consultation Time",
+ "label": "Admitted Datetime",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -408,49 +467,84 @@
"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",
- "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": "Invoice",
- "length": 0,
- "no_copy": 1,
- "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,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expected_discharge",
+ "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": "Expected Discharge",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "discharge_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": "Discharge 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": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
- "fieldname": "sb_symptoms",
+ "fieldname": "references",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -459,7 +553,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Encounter Impression",
+ "label": "References",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -472,107 +566,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "symptoms_select",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Complaints",
- "length": 0,
- "no_copy": 1,
- "options": "Complaint",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "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": "symptoms",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 1,
- "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,
- "default": "0",
- "fieldname": "symptoms_in_print",
- "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": "In print",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "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": "physical_examination",
+ "fieldname": "cb_admission",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -581,7 +585,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "",
+ "label": "Admission",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -594,384 +598,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "",
- "fieldname": "diagnosis_select",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Diagnosis",
- "length": 0,
- "no_copy": 1,
- "options": "Diagnosis",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "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": "",
- "fieldname": "diagnosis",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 1,
- "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,
- "default": "1",
- "depends_on": "",
- "fieldname": "diagnosis_in_print",
- "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": "In print",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "codification",
- "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": "Medical Coding",
- "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": "codification_table",
- "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": "Medical Coding",
- "length": 0,
- "no_copy": 0,
- "options": "Codification 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,
- "fieldname": "sb_drug_prescription",
- "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": "Medication",
- "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": "drug_prescription",
- "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": "Medication",
- "length": 0,
- "no_copy": 0,
- "options": "Drug Prescription",
- "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": "sb_test_prescription",
- "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": "Investigations",
- "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": "test_prescription",
- "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": "Investigations",
- "length": 0,
- "no_copy": 0,
- "options": "Lab Prescription",
- "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": "sb_procedures",
- "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": "Procedures",
- "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": "procedure_prescription",
- "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": "Procedures",
- "length": 0,
- "no_copy": 1,
- "options": "Procedure Prescription",
- "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": "consultation_comment",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 1,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Review Details",
- "length": 0,
- "no_copy": 1,
- "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",
+ "fieldname": "admission_practitioner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -980,12 +617,13 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Amended From",
+ "label": "Healthcare Practitioner",
"length": 0,
- "no_copy": 1,
- "options": "Consultation",
+ "no_copy": 0,
+ "options": "Healthcare Practitioner",
"permlevel": 0,
- "print_hide": 1,
+ "precision": "",
+ "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
@@ -993,6 +631,299 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "admission_encounter",
+ "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": "Patient Encounter",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Patient Encounter",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb_discharge",
+ "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,
+ "label": "Discharge",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "discharge_practitioner",
+ "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": "Healthcare Practitioner",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Healthcare Practitioner",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "discharge_encounter",
+ "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": "Patient Encounter",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Patient Encounter",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sb_inpatient_occupancy",
+ "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": "Inpatient Occupancy",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "inpatient_occupancies",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Occupancy",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "btn_transfer",
+ "fieldtype": "Button",
+ "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": "Transfer",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.status != \"Admission Scheduled\"",
+ "fieldname": "sb_discharge_note",
+ "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": "Discharge Note",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "discharge_note",
+ "fieldtype": "Text Editor",
+ "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": "",
+ "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,
+ "translatable": 0,
"unique": 0
}
],
@@ -1002,21 +933,20 @@
"idx": 0,
"image_view": 0,
"in_create": 0,
- "is_submittable": 1,
+ "is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-03-19 11:35:13.826577",
+ "modified": "2018-07-18 14:10:30.245833",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Consultation",
+ "name": "Inpatient Record",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "apply_user_permissions": 0,
- "cancel": 1,
+ "amend": 0,
+ "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
@@ -1027,22 +957,21 @@
"print": 1,
"read": 1,
"report": 1,
- "role": "Physician",
+ "role": "Healthcare Administrator",
"set_user_permissions": 0,
"share": 1,
- "submit": 1,
+ "submit": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient, physician, visit_department, consultation_date, consultation_time",
- "show_name_in_global_search": 1,
+ "search_fields": "patient",
+ "show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "patient",
"track_changes": 1,
- "track_seen": 1
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
new file mode 100644
index 0000000..07cd9e4
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, 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 today, now_datetime
+from frappe.model.document import Document
+from frappe.desk.reportview import get_match_cond
+
+class InpatientRecord(Document):
+ def after_insert(self):
+ frappe.db.set_value("Patient", self.patient, "inpatient_status", "Admission Scheduled")
+ frappe.db.set_value("Patient", self.patient, "inpatient_record", self.name)
+
+ def validate(self):
+ self.validate_already_scheduled_or_admitted()
+ if self.status == "Discharged":
+ frappe.db.set_value("Patient", self.patient, "inpatient_status", None)
+ frappe.db.set_value("Patient", self.patient, "inpatient_record", None)
+
+ def validate_already_scheduled_or_admitted(self):
+ query = """
+ select name, status
+ from `tabInpatient Record`
+ where (status = 'Admitted' or status = 'Admission Scheduled')
+ and name != %(name)s and patient = %(patient)s
+ """
+
+ ip_record = frappe.db.sql(query,{
+ "name": self.name,
+ "patient": self.patient
+ }, as_dict = 1)
+
+ if ip_record:
+ msg = _(("Already {0} Patient {1} with Inpatient Record ").format(ip_record[0].status, self.patient) \
+ + """ <b><a href="#Form/Inpatient Record/{0}">{0}</a></b>""".format(ip_record[0].name))
+ frappe.throw(msg)
+
+ def admit(self, service_unit, check_in, expected_discharge=None):
+ admit_patient(self, service_unit, check_in, expected_discharge)
+
+ def discharge(self):
+ discharge_patient(self)
+
+ def transfer(self, service_unit, check_in, leave_from):
+ if leave_from:
+ patient_leave_service_unit(self, check_in, leave_from)
+ if service_unit:
+ transfer_patient(self, service_unit, check_in)
+
+@frappe.whitelist()
+def schedule_inpatient(patient, encounter_id, practitioner):
+ patient_obj = frappe.get_doc('Patient', patient)
+ inpatient_record = frappe.new_doc('Inpatient Record')
+ inpatient_record.patient = patient
+ inpatient_record.patient_name = patient_obj.patient_name
+ inpatient_record.gender = patient_obj.sex
+ inpatient_record.blood_group = patient_obj.blood_group
+ inpatient_record.dob = patient_obj.dob
+ inpatient_record.mobile = patient_obj.mobile
+ inpatient_record.email = patient_obj.email
+ inpatient_record.phone = patient_obj.phone
+ inpatient_record.status = "Admission Scheduled"
+ inpatient_record.scheduled_date = today()
+ inpatient_record.admission_practitioner = practitioner
+ inpatient_record.admission_encounter = encounter_id
+ inpatient_record.save(ignore_permissions = True)
+
+@frappe.whitelist()
+def schedule_discharge(patient, encounter_id, practitioner):
+ inpatient_record_id = frappe.db.get_value('Patient', patient, 'inpatient_record')
+ if inpatient_record_id:
+ inpatient_record = frappe.get_doc("Inpatient Record", inpatient_record_id)
+ inpatient_record.discharge_practitioner = practitioner
+ inpatient_record.discharge_encounter = encounter_id
+ inpatient_record.status = "Discharge Scheduled"
+ inpatient_record.save(ignore_permissions = True)
+ frappe.db.set_value("Patient", patient, "inpatient_status", "Discharge Scheduled")
+
+def discharge_patient(inpatient_record):
+ if inpatient_record.inpatient_occupancies:
+ for inpatient_occupancy in inpatient_record.inpatient_occupancies:
+ if inpatient_occupancy.left != 1:
+ inpatient_occupancy.left = True
+ inpatient_occupancy.check_out = now_datetime()
+ frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupied", False)
+
+ inpatient_record.discharge_date = today()
+ inpatient_record.status = "Discharged"
+
+ inpatient_record.save(ignore_permissions = True)
+
+def admit_patient(inpatient_record, service_unit, check_in, expected_discharge=None):
+ inpatient_record.admitted_datetime = check_in
+ inpatient_record.status = "Admitted"
+ inpatient_record.expected_discharge = expected_discharge
+
+ inpatient_record.set('inpatient_occupancies', [])
+ transfer_patient(inpatient_record, service_unit, check_in)
+
+ frappe.db.set_value("Patient", inpatient_record.patient, "inpatient_status", "Admitted")
+ frappe.db.set_value("Patient", inpatient_record.patient, "inpatient_record", inpatient_record.name)
+
+def transfer_patient(inpatient_record, service_unit, check_in):
+ item_line = inpatient_record.append('inpatient_occupancies', {})
+ item_line.service_unit = service_unit
+ item_line.check_in = check_in
+
+ inpatient_record.save(ignore_permissions = True)
+
+ frappe.db.set_value("Healthcare Service Unit", service_unit, "occupied", True)
+
+def patient_leave_service_unit(inpatient_record, check_out, leave_from):
+ if inpatient_record.inpatient_occupancies:
+ for inpatient_occupancy in inpatient_record.inpatient_occupancies:
+ if inpatient_occupancy.left != 1 and inpatient_occupancy.service_unit == leave_from:
+ inpatient_occupancy.left = True
+ inpatient_occupancy.check_out = check_out
+ frappe.db.set_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "occupied", False)
+ inpatient_record.save(ignore_permissions = True)
+
+@frappe.whitelist()
+def get_leave_from(doctype, txt, searchfield, start, page_len, filters):
+ docname = filters['docname']
+
+ query = '''select io.service_unit
+ from `tabInpatient Occupancy` io, `tabInpatient Record` ir
+ where io.parent = '{docname}' and io.parentfield = 'inpatient_occupancies'
+ and io.left!=1 and io.parent = ir.name'''
+
+ return frappe.db.sql(query.format(**{
+ "docname": docname,
+ "searchfield": searchfield,
+ "mcond": get_match_cond(doctype)
+ }), {
+ 'txt': "%%%s%%" % txt,
+ '_txt': txt.replace("%", ""),
+ 'start': start,
+ 'page_len': page_len
+ })
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record_dashboard.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record_dashboard.py
new file mode 100644
index 0000000..0dc8970
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record_dashboard.py
@@ -0,0 +1,16 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'inpatient_record',
+ 'transactions': [
+ {
+ 'label': _('Appointments and Encounters'),
+ 'items': ['Patient Appointment', 'Patient Encounter']
+ },
+ {
+ 'label': _('Lab Tests and Vital Signs'),
+ 'items': ['Lab Test', 'Clinical Procedure', 'Sample Collection', 'Vital Signs']
+ }
+ ]
+ }
diff --git a/erpnext/healthcare/doctype/consultation/test_consultation.js b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js
similarity index 70%
rename from erpnext/healthcare/doctype/consultation/test_consultation.js
rename to erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js
index 803e73c..1ce9afa 100644
--- a/erpnext/healthcare/doctype/consultation/test_consultation.js
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Consultation", function (assert) {
+QUnit.test("test: Inpatient Record", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
- // insert a new Consultation
- () => frappe.tests.make('Consultation', [
+ // insert a new Inpatient Record
+ () => frappe.tests.make('Inpatient Record', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
new file mode 100644
index 0000000..91cc417
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from frappe.utils import now_datetime, today
+from frappe.utils.make_random import get_random
+from erpnext.healthcare.doctype.inpatient_record.inpatient_record import admit_patient, discharge_patient
+
+class TestInpatientRecord(unittest.TestCase):
+ def test_admit_and_discharge(self):
+ patient = get_patient()
+ # Schedule Admission
+ ip_record = create_inpatient(patient)
+ ip_record.save(ignore_permissions = True)
+ self.assertEqual(ip_record.name, frappe.db.get_value("Patient", patient, "inpatient_record"))
+ self.assertEqual(ip_record.status, frappe.db.get_value("Patient", patient, "inpatient_status"))
+
+ # Admit
+ service_unit = get_healthcare_service_unit()
+ admit_patient(ip_record, service_unit, now_datetime())
+ self.assertEqual("Admitted", frappe.db.get_value("Patient", patient, "inpatient_status"))
+ self.assertEqual(1, frappe.db.get_value("Healthcare Service Unit", service_unit, "occupied"))
+
+ # Discharge
+ discharge_patient(ip_record)
+ self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_record"))
+ self.assertEqual(None, frappe.db.get_value("Patient", patient, "inpatient_status"))
+ self.assertEqual(0, frappe.db.get_value("Healthcare Service Unit", service_unit, "occupied"))
+
+ def test_validate_overlap_admission(self):
+ patient = get_patient()
+
+ ip_record = create_inpatient(patient)
+ ip_record.save(ignore_permissions = True)
+ ip_record_new = create_inpatient(patient)
+ self.assertRaises(frappe.ValidationError, ip_record_new.save)
+
+ service_unit = get_healthcare_service_unit()
+ admit_patient(ip_record, service_unit, now_datetime())
+ ip_record_new = create_inpatient(patient)
+ self.assertRaises(frappe.ValidationError, ip_record_new.save)
+
+def create_inpatient(patient):
+ patient_obj = frappe.get_doc('Patient', patient)
+ inpatient_record = frappe.new_doc('Inpatient Record')
+ inpatient_record.patient = patient
+ inpatient_record.patient_name = patient_obj.patient_name
+ inpatient_record.gender = patient_obj.sex
+ inpatient_record.blood_group = patient_obj.blood_group
+ inpatient_record.dob = patient_obj.dob
+ inpatient_record.mobile = patient_obj.mobile
+ inpatient_record.email = patient_obj.email
+ inpatient_record.phone = patient_obj.phone
+ inpatient_record.inpatient = "Scheduled"
+ inpatient_record.scheduled_date = today()
+ return inpatient_record
+
+def get_patient():
+ patient = get_random("Patient")
+ if not patient:
+ patient = frappe.new_doc("Patient")
+ patient.patient_name = "Test Patient"
+ patient.sex = "Male"
+ patient.save(ignore_permissions=True)
+ return patient.name
+ return patient
+
+
+def get_healthcare_service_unit():
+ service_unit = get_random("Healthcare Service Unit", filters={"inpatient_occupancy": 1})
+ if not service_unit:
+ service_unit = frappe.new_doc("Healthcare Service Unit")
+ service_unit.healthcare_service_unit_name = "Test Service Unit Ip Occupancy"
+ service_unit.service_unit_type = get_service_unit_type()
+ service_unit.inpatient_occupancy = 1
+ service_unit.occupied = 0
+ service_unit.save(ignore_permissions = True)
+ return service_unit.name
+ return service_unit
+
+def get_service_unit_type():
+ service_unit_type = get_random("Healthcare Service Unit Type", filters={"inpatient_occupancy": 1})
+
+ if not service_unit_type:
+ service_unit_type = frappe.new_doc("Healthcare Service Unit Type")
+ service_unit_type.service_unit_type = "Test Service Unit Type Ip Occupancy"
+ service_unit_type.inpatient_occupancy = 1
+ service_unit_type.save(ignore_permissions = True)
+ return service_unit_type.name
+ return service_unit_type
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.js b/erpnext/healthcare/doctype/lab_test/lab_test.js
index 02aa001..c3b069d 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.js
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.js
@@ -30,7 +30,7 @@
});
}
if(frm.doc.__islocal){
- frm.add_custom_button(__('Get from Consultation'), function () {
+ frm.add_custom_button(__('Get from Patient Encounter'), function () {
get_lab_test_prescribed(frm);
});
}
@@ -60,7 +60,7 @@
},
onload: function (frm) {
- frm.add_fetch("physician", "department", "department");
+ frm.add_fetch("practitioner", "department", "department");
if(frm.doc.employee){
frappe.call({
method: "frappe.client.get",
@@ -160,21 +160,21 @@
$.each(result, function(x, y){
var row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
<div class="col-xs-2"> %(lab_test)s </div>\
- <div class="col-xs-2"> %(consultation)s </div>\
- <div class="col-xs-3"> %(physician)s </div>\
+ <div class="col-xs-2"> %(encounter)s </div>\
+ <div class="col-xs-3"> %(practitioner)s </div>\
<div class="col-xs-3"> %(date)s </div>\
<div class="col-xs-1">\
<a data-name="%(name)s" data-lab-test="%(lab_test)s"\
- data-consultation="%(consultation)s" data-physician="%(physician)s"\
+ data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
data-invoice="%(invoice)s" href="#"><button class="btn btn-default btn-xs">Get Lab Test\
- </button></a></div></div>', {name:y[0], lab_test: y[1], consultation:y[2], invoice:y[3], physician:y[4], date:y[5]})).appendTo(html_field);
+ </button></a></div></div>', {name:y[0], lab_test: y[1], encounter:y[2], invoice:y[3], practitioner:y[4], date:y[5]})).appendTo(html_field);
row.find("a").click(function() {
frm.doc.template = $(this).attr("data-lab-test");
frm.doc.prescription = $(this).attr("data-name");
- frm.doc.physician = $(this).attr("data-physician");
+ frm.doc.practitioner = $(this).attr("data-practitioner");
frm.set_df_property("template", "read_only", 1);
frm.set_df_property("patient", "read_only", 1);
- frm.set_df_property("physician", "read_only", 1);
+ frm.set_df_property("practitioner", "read_only", 1);
if($(this).attr("data-invoice") != 'null'){
frm.doc.invoice = $(this).attr("data-invoice");
refresh_field("invoice");
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
index a64c13c..0132c98 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.json
@@ -15,6 +15,41 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "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": "Inpatient Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Record",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -42,11 +77,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -74,15 +110,17 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -106,16 +144,17 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "patient.patient_name",
+ "fetch_from": "patient.patient_name",
"fieldname": "patient_name",
"fieldtype": "Data",
"hidden": 0,
@@ -139,11 +178,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -170,11 +210,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -202,16 +243,17 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
@@ -220,10 +262,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Doctor",
+ "label": "Healthcare Practitioner",
"length": 0,
"no_copy": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -234,11 +276,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -265,11 +308,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -296,11 +340,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -328,11 +373,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -358,11 +404,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -390,11 +437,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -422,11 +470,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -453,11 +502,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -484,11 +534,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -516,11 +567,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -548,11 +600,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -581,16 +634,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "employee.employee_name",
+ "fetch_from": "employee.employee_name",
"fieldname": "employee_name",
"fieldtype": "Data",
"hidden": 0,
@@ -614,16 +668,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "employee.designation",
+ "fetch_from": "employee.designation",
"fieldname": "employee_designation",
"fieldtype": "Data",
"hidden": 0,
@@ -647,11 +702,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -679,11 +735,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -710,11 +767,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -740,11 +798,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -771,11 +830,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -801,11 +861,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -833,11 +894,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -865,11 +927,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -895,11 +958,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -926,11 +990,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -956,11 +1021,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -987,11 +1053,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1017,11 +1084,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1048,11 +1116,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1078,11 +1147,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1109,11 +1179,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1140,11 +1211,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1171,11 +1243,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1202,11 +1275,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1234,11 +1308,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1265,11 +1340,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1296,11 +1372,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1327,11 +1404,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1358,11 +1436,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1389,11 +1468,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1421,7 +1501,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -1436,7 +1516,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-16 22:43:40.341869",
+ "modified": "2018-07-17 12:47:01.425117",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Lab Test",
@@ -1505,11 +1585,11 @@
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
- "search_fields": "patient,invoice,physician,test_name,sample",
+ "search_fields": "patient,invoice,practitioner,test_name,sample",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py
index 4e07ed6..767581f 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.py
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.py
@@ -60,13 +60,13 @@
def update_lab_test_print_sms_email_status(print_sms_email, name):
frappe.db.set_value("Lab Test",name,print_sms_email,1)
-def create_lab_test_doc(invoice, consultation, patient, template):
+def create_lab_test_doc(invoice, encounter, patient, template):
#create Test Result for template, copy vals from Invoice
lab_test = frappe.new_doc("Lab Test")
if(invoice):
lab_test.invoice = invoice
- if(consultation):
- lab_test.physician = consultation.physician
+ if(encounter):
+ lab_test.practitioner = encounter.practitioner
lab_test.patient = patient.name
lab_test.patient_age = patient.get_age()
lab_test.patient_sex = patient.sex
@@ -159,9 +159,9 @@
if not (template):
return
patient = frappe.get_doc("Patient", patient)
- consultation_id = frappe.get_value("Lab Prescription", prescription, "parent")
- consultation = frappe.get_doc("Consultation", consultation_id)
- lab_test = create_lab_test(patient, template, prescription, consultation, invoice)
+ encounter_id = frappe.get_value("Lab Prescription", prescription, "parent")
+ encounter = frappe.get_doc("Patient Encounter", encounter_id)
+ lab_test = create_lab_test(patient, template, prescription, encounter, invoice)
return lab_test.name
def create_sample_collection(lab_test, template, patient, invoice):
@@ -215,8 +215,8 @@
lab_test.save(ignore_permissions=True) # insert the result
return lab_test
-def create_lab_test(patient, template, prescription, consultation, invoice):
- lab_test = create_lab_test_doc(invoice, consultation, patient, template)
+def create_lab_test(patient, template, prescription, encounter, invoice):
+ lab_test = create_lab_test_doc(invoice, encounter, patient, template)
lab_test = create_sample_collection(lab_test, template, patient, invoice)
lab_test = load_result_format(lab_test, template, prescription, invoice)
return lab_test
@@ -292,5 +292,5 @@
@frappe.whitelist()
def get_lab_test_prescribed(patient):
- return frappe.db.sql("""select cp.name, cp.test_code, cp.parent, cp.invoice, ct.physician, ct.consultation_date from tabConsultation ct,
+ return frappe.db.sql("""select cp.name, cp.test_code, cp.parent, cp.invoice, ct.practitioner, ct.encounter_date from `tabPatient Encounter` ct,
`tabLab Prescription` cp where ct.patient=%s and cp.parent=ct.name and cp.test_created=0""", (patient))
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
index 3e3878a..35620e9 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json
@@ -14,6 +14,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -40,11 +41,12 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -72,11 +74,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -103,11 +106,12 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -136,11 +140,12 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -168,11 +173,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -198,11 +204,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -232,11 +239,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -266,11 +274,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -299,11 +308,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -332,11 +342,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -364,11 +375,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -395,11 +407,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -425,11 +438,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -458,11 +472,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -489,11 +504,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -521,11 +537,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -553,11 +570,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -584,11 +602,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -616,11 +635,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -648,11 +668,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -678,11 +699,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -709,11 +731,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -740,11 +763,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -772,16 +796,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "sample.sample_uom",
+ "fetch_from": "sample.sample_uom",
"fieldname": "sample_uom",
"fieldtype": "Data",
"hidden": 0,
@@ -805,11 +830,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -837,11 +863,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -868,11 +895,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -900,11 +928,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -918,7 +947,7 @@
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
+ "in_standard_filter": 1,
"label": "disabled",
"length": 0,
"no_copy": 0,
@@ -932,7 +961,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -946,7 +975,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-16 22:43:26.086857",
+ "modified": "2018-07-02 11:58:00.266070",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Lab Test Template",
diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js
index b40f78d..d0ab94c 100644
--- a/erpnext/healthcare/doctype/patient/patient.js
+++ b/erpnext/healthcare/doctype/patient/patient.js
@@ -33,8 +33,8 @@
frm.add_custom_button(__('Medical Record'), function () {
create_medical_record(frm);
}, "Create");
- frm.add_custom_button(__('Consultation'), function () {
- btn_create_consultation(frm);
+ frm.add_custom_button(__('Patient Encounter'), function () {
+ btn_create_encounter(frm);
}, "Create");
}
},
@@ -94,14 +94,14 @@
frappe.new_doc("Vital Signs");
};
-var btn_create_consultation = function (frm) {
+var btn_create_encounter = function (frm) {
if (!frm.doc.name) {
frappe.throw(__("Please save the patient first"));
}
frappe.route_options = {
"patient": frm.doc.name,
};
- frappe.new_doc("Consultation");
+ frappe.new_doc("Patient Encounter");
};
var btn_invoice_registration = function (frm) {
diff --git a/erpnext/healthcare/doctype/patient/patient.json b/erpnext/healthcare/doctype/patient/patient.json
index 10cc11ab..b442a19 100644
--- a/erpnext/healthcare/doctype/patient/patient.json
+++ b/erpnext/healthcare/doctype/patient/patient.json
@@ -16,6 +16,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -49,6 +50,73 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "inpatient_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": "Inpatient Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nAdmission Scheduled\nAdmitted\nDischarge Scheduled",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "inpatient_record",
+ "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": "Inpatient Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Record",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -81,6 +149,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -113,6 +182,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -145,6 +215,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -177,6 +248,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -208,6 +280,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -239,6 +312,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -272,6 +346,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -304,6 +379,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -334,6 +410,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -366,6 +443,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -398,6 +476,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -429,6 +508,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -461,6 +541,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -492,6 +573,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -524,6 +606,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -555,6 +638,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -587,6 +671,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -618,6 +703,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -649,6 +735,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -680,6 +767,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -710,6 +798,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -741,6 +830,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -772,6 +862,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -803,6 +894,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -834,6 +926,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -864,6 +957,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -896,6 +990,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -927,6 +1022,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -958,6 +1054,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -989,6 +1086,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1020,6 +1118,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1051,6 +1150,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1081,6 +1181,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1112,6 +1213,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1143,6 +1245,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1177,6 +1280,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1209,6 +1313,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1240,6 +1345,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1283,7 +1389,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 50,
- "modified": "2018-03-13 11:20:31.338415",
+ "modified": "2018-07-18 13:36:05.308926",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient",
@@ -1292,7 +1398,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
@@ -1312,7 +1417,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
@@ -1332,7 +1436,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py
index d0332d8..bff24f7 100644
--- a/erpnext/healthcare/doctype/patient/patient.py
+++ b/erpnext/healthcare/doctype/patient/patient.py
@@ -81,7 +81,7 @@
territory = "Rest Of The World"
frappe.msgprint(_("Please set default customer group and territory in Selling Settings"), alert=True)
customer = frappe.get_doc({"doctype": "Customer",
- "customer_name": doc.name,
+ "customer_name": doc.patient_name,
"customer_group": customer_group,
"territory" : territory,
"customer_type": "Individual"
diff --git a/erpnext/healthcare/doctype/patient/patient_dashboard.py b/erpnext/healthcare/doctype/patient/patient_dashboard.py
index 628e91b..098497c 100644
--- a/erpnext/healthcare/doctype/patient/patient_dashboard.py
+++ b/erpnext/healthcare/doctype/patient/patient_dashboard.py
@@ -7,8 +7,8 @@
'fieldname': 'patient',
'transactions': [
{
- 'label': _('Appointments and Consultations'),
- 'items': ['Patient Appointment', 'Consultation']
+ 'label': _('Appointments and Patient Encounters'),
+ 'items': ['Patient Appointment', 'Patient Encounter']
},
{
'label': _('Lab Tests and Vital Signs'),
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 7d5ed8d..23ec85d 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -6,7 +6,7 @@
frm.custom_make_buttons = {
'Sales Invoice': 'Invoice',
'Vital Signs': 'Vital Signs',
- 'Consultation': 'Consultation'
+ 'Patient Encounter': 'Patient Encounter'
};
},
refresh: function(frm) {
@@ -15,7 +15,7 @@
filters: {"disabled": 0}
};
});
- frm.set_query("physician", function() {
+ frm.set_query("practitioner", function() {
return {
filters: {
'department': frm.doc.department
@@ -47,8 +47,8 @@
},"Create");
}
else{
- frm.add_custom_button(__("Consultation"),function(){
- btn_create_consultation(frm);
+ frm.add_custom_button(__("Patient Encounter"),function(){
+ btn_create_encounter(frm);
},"Create");
}
@@ -67,8 +67,8 @@
},"Create");
}
else{
- frm.add_custom_button(__("Consultation"),function(){
- btn_create_consultation(frm);
+ frm.add_custom_button(__("Patient Encounter"),function(){
+ btn_create_encounter(frm);
},"Create");
}
@@ -93,22 +93,23 @@
}
else if(frm.doc.status != "Cancelled" && frappe.user.has_role("Accounts User")){
frm.add_custom_button(__('Invoice'), function() {
- btn_invoice_consultation(frm);
+ btn_invoice_encounter(frm);
},__("Create"));
}
}
+ frm.set_df_property("get_procedure_from_encounter", "read_only", frm.doc.__islocal ? 0 : 1);
},
check_availability: function(frm) {
- var { physician, appointment_date } = frm.doc;
- if(!(physician && appointment_date)) {
- frappe.throw(__("Please select Physician and Date"));
+ var { practitioner, appointment_date } = frm.doc;
+ if(!(practitioner && appointment_date)) {
+ frappe.throw(__("Please select Healthcare Practitioner and Date"));
}
// show booking modal
frm.call({
method: 'get_availability_data',
args: {
- physician: physician,
+ practitioner: practitioner,
date: appointment_date
},
callback: (r) => {
@@ -124,7 +125,7 @@
function show_empty_state() {
frappe.msgprint({
title: __('Not Available'),
- message: __("Physician {0} not available on {1}", [physician.bold(), appointment_date.bold()]),
+ message: __("Healthcare Practitioner {0} not available on {1}", [practitioner.bold(), appointment_date.bold()]),
indicator: 'red'
});
}
@@ -216,7 +217,7 @@
frm.disable_save();
}
},
- get_procedure_from_consultation: function(frm) {
+ get_procedure_from_encounter: function(frm) {
get_procedure_prescribed(frm);
}
});
@@ -249,26 +250,26 @@
html_field.empty();
$.each(result, function(x, y){
var row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
- <div class="col-xs-5"> %(consultation)s <br> %(consulting_physician)s <br> %(consultation_date)s </div>\
- <div class="col-xs-5"> %(procedure_template)s <br>%(physician)s <br> %(date)s</div>\
+ <div class="col-xs-5"> %(encounter)s <br> %(consulting_practitioner)s <br> %(encounter_date)s </div>\
+ <div class="col-xs-5"> %(procedure_template)s <br>%(practitioner)s <br> %(date)s</div>\
<div class="col-xs-2">\
<a data-name="%(name)s" data-procedure-template="%(procedure_template)s"\
- data-consultation="%(consultation)s" data-physician="%(physician)s"\
+ data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
data-date="%(date)s" data-department="%(department)s">\
<button class="btn btn-default btn-xs">Add\
</button></a></div></div><div class="col-xs-12"><hr/><div/>', {name:y[0], procedure_template: y[1],
- consultation:y[2], consulting_physician:y[3], consultation_date:y[4],
- physician:y[5]? y[5]:'', date: y[6]? y[6]:'', department: y[7]? y[7]:''})).appendTo(html_field);
+ encounter:y[2], consulting_practitioner:y[3], encounter_date:y[4],
+ practitioner:y[5]? y[5]:'', date: y[6]? y[6]:'', department: y[7]? y[7]:''})).appendTo(html_field);
row.find("a").click(function() {
frm.doc.procedure_template = $(this).attr("data-procedure-template");
frm.doc.procedure_prescription = $(this).attr("data-name");
- frm.doc.physician = $(this).attr("data-physician");
+ frm.doc.practitioner = $(this).attr("data-practitioner");
frm.doc.appointment_date = $(this).attr("data-date");
frm.doc.department = $(this).attr("data-department");
refresh_field("procedure_template");
refresh_field("procedure_prescription");
refresh_field("appointment_date");
- refresh_field("physician");
+ refresh_field("practitioner");
refresh_field("department");
d.hide();
return false;
@@ -295,10 +296,10 @@
});
};
-var btn_create_consultation = function(frm){
+var btn_create_encounter = function(frm){
var doc = frm.doc;
frappe.call({
- method:"erpnext.healthcare.doctype.patient_appointment.patient_appointment.create_consultation",
+ method:"erpnext.healthcare.doctype.patient_appointment.patient_appointment.create_encounter",
args: {appointment: doc.name},
callback: function(data){
if(!data.exc){
@@ -338,7 +339,7 @@
);
};
-var btn_invoice_consultation = function(frm){
+var btn_invoice_encounter = function(frm){
frappe.call({
doc: frm.doc,
method:"create_invoice",
@@ -353,13 +354,13 @@
});
};
-frappe.ui.form.on("Patient Appointment", "physician", function(frm) {
- if(frm.doc.physician){
+frappe.ui.form.on("Patient Appointment", "practitioner", function(frm) {
+ if(frm.doc.practitioner){
frappe.call({
"method": "frappe.client.get",
args: {
- doctype: "Physician",
- name: frm.doc.physician
+ doctype: "Healthcare Practitioner",
+ name: frm.doc.practitioner
},
callback: function (data) {
frappe.model.set_value(frm.doctype,frm.docname, "department",data.message.department);
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index 3c087ea..b19e48e 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -15,10 +15,46 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "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": "Inpatient Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Record",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -42,11 +78,12 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -74,16 +111,17 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
@@ -92,10 +130,10 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
- "label": "Physician",
+ "label": "Healthcare Practitioner",
"length": 0,
"no_copy": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -106,16 +144,17 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "get_procedure_from_consultation",
+ "fieldname": "get_procedure_from_encounter",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -137,11 +176,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -169,11 +209,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -201,11 +242,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -232,11 +274,12 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -263,11 +306,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -295,11 +339,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -327,11 +372,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -359,11 +405,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -391,17 +438,18 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
- "fetch_from": "patient.patient_name",
+ "fetch_from": "patient.patient_name",
"fieldname": "patient_name",
"fieldtype": "Data",
"hidden": 0,
@@ -425,16 +473,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "patient.sex",
+ "fetch_from": "patient.sex",
"fieldname": "patient_sex",
"fieldtype": "Data",
"hidden": 0,
@@ -458,11 +507,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -490,11 +540,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -523,11 +574,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -555,11 +607,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -586,11 +639,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -617,11 +671,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -647,11 +702,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -679,11 +735,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -711,11 +768,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -742,11 +800,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -773,16 +832,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "referring_physician",
+ "fieldname": "referring_practitioner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
@@ -791,10 +851,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Referring Physician",
+ "label": "Referring Practitioner",
"length": 0,
"no_copy": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -805,11 +865,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -837,7 +898,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -851,7 +912,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-16 22:43:39.359254",
+ "modified": "2018-07-17 12:48:28.394133",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Appointment",
@@ -920,11 +981,11 @@
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
- "search_fields": "patient, physician, department, appointment_date, appointment_time",
+ "search_fields": "patient, practitioner, department, appointment_date, appointment_time",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index a9561a0..d535bec 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -28,7 +28,7 @@
frappe.db.set_value("Procedure Prescription", self.procedure_prescription, "appointment_booked", True)
# Check fee validity exists
appointment = self
- validity_exist = validity_exists(appointment.physician, appointment.patient)
+ validity_exist = validity_exists(appointment.practitioner, appointment.patient)
if validity_exist:
fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
@@ -64,11 +64,11 @@
@frappe.whitelist()
-def get_availability_data(date, physician):
+def get_availability_data(date, practitioner):
"""
- Get availability data of 'physician' on 'date'
+ Get availability data of 'practitioner' on 'date'
:param date: Date to check in schedule
- :param physician: Name of the physician
+ :param practitioner: Name of the practitioner
:return: dict containing a list of available slots, list of appointments and time of appointments
"""
@@ -77,21 +77,21 @@
available_slots = []
slot_details = []
- physician_schedule = None
+ practitioner_schedule = None
employee = None
- physician_obj = frappe.get_doc("Physician", physician)
+ practitioner_obj = frappe.get_doc("Healthcare Practitioner", practitioner)
- # Get Physician employee relation
- if physician_obj.employee:
- employee = physician_obj.employee
- elif physician_obj.user_id:
+ # Get practitioner employee relation
+ if practitioner_obj.employee:
+ employee = practitioner_obj.employee
+ elif practitioner_obj.user_id:
if frappe.db.exists({
"doctype": "Employee",
- "user_id": physician_obj.user_id
+ "user_id": practitioner_obj.user_id
}):
- employee = frappe.get_doc("Employee", {"user_id": physician_obj.user_id}).name
+ employee = frappe.get_doc("Employee", {"user_id": practitioner_obj.user_id}).name
if employee:
# Check if it is Holiday
@@ -104,21 +104,21 @@
and docstatus = 1""", (employee, date), as_dict=True)
if leave_record:
if leave_record[0].half_day:
- frappe.throw(_("Dr {0} on Half day Leave on {1}").format(physician, date))
+ frappe.throw(_("{0} on Half day Leave on {1}").format(practitioner, date))
else:
- frappe.throw(_("Dr {0} on Leave on {1}").format(physician, date))
+ frappe.throw(_("{0} on Leave on {1}").format(practitioner, date))
- # get physicians schedule
- if physician_obj.physician_schedules:
- for schedule in physician_obj.physician_schedules:
+ # get practitioners schedule
+ if practitioner_obj.practitioner_schedules:
+ for schedule in practitioner_obj.practitioner_schedules:
if schedule.schedule:
- physician_schedule = frappe.get_doc("Physician Schedule", schedule.schedule)
+ practitioner_schedule = frappe.get_doc("Practitioner Schedule", schedule.schedule)
else:
- frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician)))
+ frappe.throw(_("{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master".format(practitioner)))
- if physician_schedule:
+ if practitioner_schedule:
available_slots = []
- for t in physician_schedule.time_slots:
+ for t in practitioner_schedule.time_slots:
if weekday == t.day:
available_slots.append(t)
@@ -129,10 +129,10 @@
slot_name = schedule.schedule+" - "+schedule.service_unit
allow_overlap = frappe.get_value('Healthcare Service Unit', schedule.service_unit, 'overlap_appointments')
if allow_overlap:
- # fetch all appointments to physician by service unit
+ # fetch all appointments to practitioner by service unit
appointments = frappe.get_all(
"Patient Appointment",
- filters={"physician": physician, "service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]},
+ filters={"practitioner": practitioner, "service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]},
fields=["name", "appointment_time", "duration", "status"])
else:
# fetch all appointments to service unit
@@ -142,21 +142,21 @@
fields=["name", "appointment_time", "duration", "status"])
else:
slot_name = schedule.schedule
- # fetch all appointments to physician without service unit
+ # fetch all appointments to practitioner without service unit
appointments = frappe.get_all(
"Patient Appointment",
- filters={"physician": physician, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]},
+ filters={"practitioner": practitioner, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]},
fields=["name", "appointment_time", "duration", "status"])
slot_details.append({"slot_name":slot_name, "service_unit":schedule.service_unit,
"avail_slot":available_slots, 'appointments': appointments})
else:
- frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician)))
+ frappe.throw(_("{0} does not have a Healthcare Practitioner Schedule. Add it in Healthcare Practitioner master".format(practitioner)))
if not available_slots and not slot_details:
# TODO: return available slots in nearby dates
- frappe.throw(_("Physician not available on {0}").format(weekday))
+ frappe.throw(_("Healthcare Practitioner not available on {0}").format(weekday))
return {
"slot_details": slot_details
@@ -210,37 +210,37 @@
sales_invoice.company = appointment_doc.company
sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
- fee_validity = get_fee_validity(appointment_doc.physician, appointment_doc.patient, appointment_doc.appointment_date)
+ fee_validity = get_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date)
procedure_template = False
if appointment_doc.procedure_template:
procedure_template = appointment_doc.procedure_template
- create_invoice_items(appointment_doc.physician, appointment_doc.company, sales_invoice, procedure_template)
+ create_invoice_items(appointment_doc.practitioner, appointment_doc.company, sales_invoice, procedure_template)
sales_invoice.save(ignore_permissions=True)
frappe.db.sql("""update `tabPatient Appointment` set sales_invoice=%s where name=%s""", (sales_invoice.name, appointment_doc.name))
frappe.db.set_value("Fee Validity", fee_validity.name, "ref_invoice", sales_invoice.name)
- consultation = frappe.db.exists({
- "doctype": "Consultation",
+ encounter = frappe.db.exists({
+ "doctype": "Patient Encounter",
"appointment": appointment_doc.name})
- if consultation:
- frappe.db.set_value("Consultation", consultation[0][0], "invoice", sales_invoice.name)
+ if encounter:
+ frappe.db.set_value("Patient Encounter", encounter[0][0], "invoice", sales_invoice.name)
return sales_invoice.name
-def get_fee_validity(physician, patient, date):
- validity_exist = validity_exists(physician, patient)
+def get_fee_validity(practitioner, patient, date):
+ validity_exist = validity_exists(practitioner, patient)
if validity_exist:
fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
fee_validity = update_fee_validity(fee_validity, date)
else:
- fee_validity = create_fee_validity(physician, patient, date)
+ fee_validity = create_fee_validity(practitioner, patient, date)
return fee_validity
-def validity_exists(physician, patient):
+def validity_exists(practitioner, patient):
return frappe.db.exists({
"doctype": "Fee Validity",
- "physician": physician,
+ "practitioner": practitioner,
"patient": patient})
@@ -260,15 +260,15 @@
return fee_validity
-def create_fee_validity(physician, patient, date):
+def create_fee_validity(practitioner, patient, date):
fee_validity = frappe.new_doc("Fee Validity")
- fee_validity.physician = physician
+ fee_validity.practitioner = practitioner
fee_validity.patient = patient
fee_validity = update_fee_validity(fee_validity, date)
return fee_validity
-def create_invoice_items(physician, company, invoice, procedure_template):
+def create_invoice_items(practitioner, company, invoice, procedure_template):
item_line = invoice.append("items")
if procedure_template:
procedure_template_obj = frappe.get_doc("Clinical Procedure Template", procedure_template)
@@ -277,11 +277,11 @@
item_line.description = procedure_template_obj.description
else:
item_line.item_name = "Consulting Charges"
- item_line.description = "Consulting Charges: " + physician
+ item_line.description = "Consulting Charges: " + practitioner
item_line.uom = "Nos"
item_line.conversion_factor = 1
- item_line.income_account = get_income_account(physician, company)
- op_consulting_charge = frappe.db.get_value("Physician", physician, "op_consulting_charge")
+ item_line.income_account = get_income_account(practitioner, company)
+ op_consulting_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
if op_consulting_charge:
item_line.rate = op_consulting_charge
item_line.amount = op_consulting_charge
@@ -292,18 +292,18 @@
@frappe.whitelist()
-def create_consultation(appointment):
+def create_encounter(appointment):
appointment = frappe.get_doc("Patient Appointment", appointment)
- consultation = frappe.new_doc("Consultation")
- consultation.appointment = appointment.name
- consultation.patient = appointment.patient
- consultation.physician = appointment.physician
- consultation.visit_department = appointment.department
- consultation.patient_sex = appointment.patient_sex
- consultation.consultation_date = appointment.appointment_date
+ encounter = frappe.new_doc("Patient Encounter")
+ encounter.appointment = appointment.name
+ encounter.patient = appointment.patient
+ encounter.practitioner = appointment.practitioner
+ encounter.visit_department = appointment.department
+ encounter.patient_sex = appointment.patient_sex
+ encounter.encounter_date = appointment.appointment_date
if appointment.sales_invoice:
- consultation.invoice = appointment.sales_invoice
- return consultation.as_dict()
+ encounter.invoice = appointment.sales_invoice
+ return encounter.as_dict()
def remind_appointment():
@@ -347,7 +347,7 @@
"""
from frappe.desk.calendar import get_event_conditions
conditions = get_event_conditions("Patient Appointment", filters)
- data = frappe.db.sql("""select `tabPatient Appointment`.name, patient, physician, status,
+ data = frappe.db.sql("""select `tabPatient Appointment`.name, patient, practitioner, status,
duration, timestamp(appointment_date, appointment_time) as 'start', type.color as 'color'
from `tabPatient Appointment`
left join `tabAppointment Type` as type on `tabPatient Appointment`.appointment_type=type.name
@@ -360,8 +360,8 @@
return data
@frappe.whitelist()
def get_procedure_prescribed(patient):
- return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.physician,
- ct.consultation_date, pp.physician, pp.date, pp.department
- from tabConsultation ct, `tabProcedure Prescription` pp
+ return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
+ ct.encounter_date, pp.practitioner, pp.date, pp.department
+ from `tabPatient Encounter` ct, `tabProcedure Prescription` pp
where ct.patient='{0}' and pp.parent=ct.name and pp.appointment_booked=0
order by ct.creation desc""".format(patient))
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_calendar.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_calendar.js
index dfff5a4..fc674a8 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_calendar.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_calendar.js
@@ -14,9 +14,9 @@
filters: [
{
'fieldtype': 'Link',
- 'fieldname': 'physician',
- 'options': 'Physician',
- 'label': __('Physician')
+ 'fieldname': 'practitioner',
+ 'options': 'Healthcare Practitioner',
+ 'label': __('Healthcare Practitioner')
},
{
'fieldtype': 'Link',
@@ -43,4 +43,4 @@
'label': __('Status')
}
]
-};
\ No newline at end of file
+};
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
index 1862915..f9ef1cb 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment_dashboard.py
@@ -9,7 +9,7 @@
'transactions': [
{
'label': _('Consultations'),
- 'items': ['Consultation', 'Vital Signs', 'Patient Medical Record']
+ 'items': ['Patient Encounter', 'Vital Signs', 'Patient Medical Record']
},
{
'label': _('Billing'),
diff --git a/erpnext/healthcare/doctype/physician/__init__.py b/erpnext/healthcare/doctype/patient_encounter/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/physician/__init__.py
rename to erpnext/healthcare/doctype/patient_encounter/__init__.py
diff --git a/erpnext/healthcare/doctype/consultation/consultation.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
similarity index 73%
rename from erpnext/healthcare/doctype/consultation/consultation.js
rename to erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 727d175..47c9cad 100644
--- a/erpnext/healthcare/doctype/consultation/consultation.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -1,7 +1,7 @@
// Copyright (c) 2016, ESS LLP and contributors
// For license information, please see license.txt
-frappe.ui.form.on('Consultation', {
+frappe.ui.form.on('Patient Encounter', {
setup: function(frm) {
frm.get_field('drug_prescription').grid.editable_fields = [
{fieldname: 'drug_code', columns: 2},
@@ -19,7 +19,28 @@
refresh: function(frm) {
refresh_field('drug_prescription');
refresh_field('test_prescription');
-
+ if (!frm.doc.__islocal){
+ frappe.call({
+ method: 'frappe.client.get_value',
+ args: {
+ doctype: 'Patient',
+ fieldname: 'inpatient_status',
+ filters: {name: frm.doc.patient}
+ },
+ callback: function(data) {
+ if(data.message && data.message.inpatient_status == "Admission Scheduled" || data.message.inpatient_status == "Admitted"){
+ frm.add_custom_button(__('Schedule Discharge'), function() {
+ schedule_discharge(frm);
+ });
+ }
+ else if(data.message.inpatient_status != "Discharge Scheduled"){
+ frm.add_custom_button(__('Schedule Admission'), function() {
+ schedule_inpatient(frm);
+ });
+ }
+ }
+ });
+ }
frm.add_custom_button(__('Medical Record'), function() {
if (frm.doc.patient) {
frappe.route_options = {"patient": frm.doc.patient};
@@ -75,7 +96,7 @@
});
if(!frm.doc.__islocal && !frm.doc.invoice && (frappe.user.has_role("Accounts User"))){
frm.add_custom_button(__('Invoice'), function() {
- btn_invoice_consultation(frm);
+ btn_invoice_encounter(frm);
},__("Create"));
}
frm.set_df_property("appointment", "read_only", frm.doc.__islocal ? 0:1);
@@ -83,19 +104,47 @@
frm.set_df_property("patient_age", "read_only", frm.doc.__islocal ? 0:1);
frm.set_df_property("patient_sex", "read_only", frm.doc.__islocal ? 0:1);
frm.set_df_property("type", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("physician", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("practitioner", "read_only", frm.doc.__islocal ? 0:1);
frm.set_df_property("visit_department", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("consultation_date", "read_only", frm.doc.__islocal ? 0:1);
- frm.set_df_property("consultation_time", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("encounter_date", "read_only", frm.doc.__islocal ? 0:1);
+ frm.set_df_property("encounter_time", "read_only", frm.doc.__islocal ? 0:1);
}
});
-var btn_invoice_consultation = function(frm){
+var schedule_inpatient = function(frm) {
+ frappe.call({
+ method: "erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_inpatient",
+ args: {patient: frm.doc.patient, encounter_id: frm.doc.name, practitioner: frm.doc.practitioner},
+ callback: function(data) {
+ if(!data.exc){
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: "Process Inpatient Scheduling"
+ });
+};
+
+var schedule_discharge = function(frm) {
+ frappe.call({
+ method: "erpnext.healthcare.doctype.inpatient_record.inpatient_record.schedule_discharge",
+ args: {patient: frm.doc.patient, encounter_id: frm.doc.name, practitioner: frm.doc.practitioner},
+ callback: function(data) {
+ if(!data.exc){
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: "Process Discharge"
+ });
+};
+
+var btn_invoice_encounter = function(frm){
var doc = frm.doc;
frappe.call({
method:
- "erpnext.healthcare.doctype.consultation.consultation.create_invoice",
- args: {company: doc.company, patient: doc.patient, physician: doc.physician, consultation_id: doc.name },
+ "erpnext.healthcare.doctype.encounter.encounter.create_invoice",
+ args: {company: doc.company, patient: doc.patient, practitioner: doc.practitioner, encounter_id: doc.name },
callback: function(data){
if(!data.exc){
if(data.message){
@@ -142,7 +191,7 @@
frappe.new_doc("Clinical Procedure");
};
-frappe.ui.form.on("Consultation", "appointment", function(frm){
+frappe.ui.form.on("Patient Encounter", "appointment", function(frm){
if(frm.doc.appointment){
frappe.call({
"method": "frappe.client.get",
@@ -153,20 +202,20 @@
callback: function (data) {
frappe.model.set_value(frm.doctype,frm.docname, "patient", data.message.patient);
frappe.model.set_value(frm.doctype,frm.docname, "type", data.message.appointment_type);
- frappe.model.set_value(frm.doctype,frm.docname, "physician", data.message.physician);
+ frappe.model.set_value(frm.doctype,frm.docname, "practitioner", data.message.practitioner);
frappe.model.set_value(frm.doctype,frm.docname, "invoice", data.message.sales_invoice);
}
});
}
});
-frappe.ui.form.on("Consultation", "physician", function(frm) {
- if(frm.doc.physician){
+frappe.ui.form.on("Patient Encounter", "practitioner", function(frm) {
+ if(frm.doc.practitioner){
frappe.call({
"method": "frappe.client.get",
args: {
- doctype: "Physician",
- name: frm.doc.physician
+ doctype: "Healthcare Practitioner",
+ name: frm.doc.practitioner
},
callback: function (data) {
frappe.model.set_value(frm.doctype,frm.docname, "visit_department",data.message.department);
@@ -175,7 +224,7 @@
}
});
-frappe.ui.form.on("Consultation", "symptoms_select", function(frm) {
+frappe.ui.form.on("Patient Encounter", "symptoms_select", function(frm) {
if(frm.doc.symptoms_select){
var symptoms = null;
if(frm.doc.symptoms)
@@ -186,7 +235,7 @@
frappe.model.set_value(frm.doctype,frm.docname, "symptoms_select", null);
}
});
-frappe.ui.form.on("Consultation", "diagnosis_select", function(frm) {
+frappe.ui.form.on("Patient Encounter", "diagnosis_select", function(frm) {
if(frm.doc.diagnosis_select){
var diagnosis = null;
if(frm.doc.diagnosis)
@@ -198,7 +247,7 @@
}
});
-frappe.ui.form.on("Consultation", "patient", function(frm) {
+frappe.ui.form.on("Patient Encounter", "patient", function(frm) {
if(frm.doc.patient){
frappe.call({
"method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
diff --git a/erpnext/healthcare/doctype/consultation/consultation.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
similarity index 87%
rename from erpnext/healthcare/doctype/consultation/consultation.json
rename to erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index 2f6de0c..292c900 100644
--- a/erpnext/healthcare/doctype/consultation/consultation.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -15,6 +15,41 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "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": "Inpatient Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Record",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -40,10 +75,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -71,10 +108,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -103,10 +142,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -134,14 +175,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -165,10 +209,12 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -196,10 +242,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -227,15 +275,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -244,10 +294,10 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
- "label": "Doctor",
+ "label": "Healthcare Practitioner",
"length": 0,
"no_copy": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -258,10 +308,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -289,10 +341,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -318,10 +372,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -349,16 +405,18 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
- "fieldname": "consultation_date",
+ "fieldname": "encounter_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -367,7 +425,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Consultation Date",
+ "label": "Encounter Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -380,16 +438,18 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
- "fieldname": "consultation_time",
+ "fieldname": "encounter_time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -398,7 +458,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Consultation Time",
+ "label": "Encounter Time",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -411,10 +471,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -442,10 +504,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -472,10 +536,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -503,10 +569,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -533,10 +601,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -564,10 +634,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -594,10 +666,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -626,10 +700,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -657,10 +733,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -689,10 +767,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -719,10 +799,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -750,10 +832,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -780,10 +864,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -811,10 +897,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -841,10 +929,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -872,10 +962,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -902,10 +994,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -933,15 +1027,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "consultation_comment",
+ "fieldname": "encounter_comment",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -963,10 +1059,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -983,7 +1081,7 @@
"label": "Amended From",
"length": 0,
"no_copy": 1,
- "options": "Consultation",
+ "options": "Patient Encounter",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@@ -993,6 +1091,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -1006,16 +1105,15 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-03-19 11:35:13.826577",
+ "modified": "2018-07-17 12:51:13.487000",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Consultation",
+ "name": "Patient Encounter",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 1,
- "apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
@@ -1038,11 +1136,11 @@
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
- "search_fields": "patient, physician, visit_department, consultation_date, consultation_time",
+ "search_fields": "patient, practitioner, visit_department, encounter_date, encounter_time",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/consultation/consultation.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
old mode 100755
new mode 100644
similarity index 71%
rename from erpnext/healthcare/doctype/consultation/consultation.py
rename to erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index ace5ac0..3d8f952
--- a/erpnext/healthcare/doctype/consultation/consultation.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -9,14 +9,14 @@
import json
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
-class Consultation(Document):
+class PatientEncounter(Document):
def on_update(self):
if(self.appointment):
frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
- update_consultation_to_medical_record(self)
+ update_encounter_to_medical_record(self)
def after_insert(self):
- insert_consultation_to_medical_record(self)
+ insert_encounter_to_medical_record(self)
def on_cancel(self):
if(self.appointment):
@@ -62,8 +62,8 @@
return sales_invoice.as_dict()
@frappe.whitelist()
-def create_invoice(company, patient, physician, consultation_id):
- if not consultation_id:
+def create_invoice(company, patient, practitioner, encounter_id):
+ if not encounter_id:
return False
sales_invoice = frappe.new_doc("Sales Invoice")
sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
@@ -71,61 +71,61 @@
sales_invoice.is_pos = '0'
sales_invoice.debit_to = get_receivable_account(company)
- create_invoice_items(physician, sales_invoice, company)
+ create_invoice_items(practitioner, sales_invoice, company)
sales_invoice.save(ignore_permissions=True)
- frappe.db.sql("""update tabConsultation set invoice=%s where name=%s""", (sales_invoice.name, consultation_id))
- appointment = frappe.db.get_value("Consultation", consultation_id, "appointment")
+ frappe.db.sql("""update `tabPatient Encounter` set invoice=%s where name=%s""", (sales_invoice.name, encounter_id))
+ appointment = frappe.db.get_value("Patient Encounter", encounter_id, "appointment")
if appointment:
frappe.db.set_value("Patient Appointment", appointment, "sales_invoice", sales_invoice.name)
return sales_invoice.name
-def create_invoice_items(physician, invoice, company):
+def create_invoice_items(practitioner, invoice, company):
item_line = invoice.append("items")
item_line.item_name = "Consulting Charges"
- item_line.description = "Consulting Charges: " + physician
+ item_line.description = "Consulting Charges: " + practitioner
item_line.qty = 1
item_line.uom = "Nos"
item_line.conversion_factor = 1
- item_line.income_account = get_income_account(physician, company)
- op_consulting_charge = frappe.get_value("Physician", physician, "op_consulting_charge")
+ item_line.income_account = get_income_account(practitioner, company)
+ op_consulting_charge = frappe.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
if op_consulting_charge:
item_line.rate = op_consulting_charge
item_line.amount = op_consulting_charge
return invoice
-def insert_consultation_to_medical_record(doc):
+def insert_encounter_to_medical_record(doc):
subject = set_subject_field(doc)
medical_record = frappe.new_doc("Patient Medical Record")
medical_record.patient = doc.patient
medical_record.subject = subject
medical_record.status = "Open"
- medical_record.communication_date = doc.consultation_date
- medical_record.reference_doctype = "Consultation"
+ medical_record.communication_date = doc.encounter_date
+ medical_record.reference_doctype = "Patient Encounter"
medical_record.reference_name = doc.name
medical_record.reference_owner = doc.owner
medical_record.save(ignore_permissions=True)
-def update_consultation_to_medical_record(consultation):
- medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (consultation.name))
+def update_encounter_to_medical_record(encounter):
+ medical_record_id = frappe.db.sql("select name from `tabPatient Medical Record` where reference_name=%s", (encounter.name))
if medical_record_id and medical_record_id[0][0]:
- subject = set_subject_field(consultation)
+ subject = set_subject_field(encounter)
frappe.db.set_value("Patient Medical Record", medical_record_id[0][0], "subject", subject)
else:
- insert_consultation_to_medical_record(consultation)
+ insert_encounter_to_medical_record(encounter)
-def delete_medical_record(consultation):
- frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (consultation.name))
+def delete_medical_record(encounter):
+ frappe.db.sql("""delete from `tabPatient Medical Record` where reference_name = %s""", (encounter.name))
-def set_subject_field(consultation):
+def set_subject_field(encounter):
subject = "No Diagnosis "
- if(consultation.diagnosis):
- subject = "Diagnosis: \n"+ cstr(consultation.diagnosis)+". "
- if(consultation.drug_prescription):
+ if(encounter.diagnosis):
+ subject = "Diagnosis: \n"+ cstr(encounter.diagnosis)+". "
+ if(encounter.drug_prescription):
subject +="\nDrug(s) Prescribed. "
- if(consultation.test_prescription):
+ if(encounter.test_prescription):
subject += "\nTest(s) Prescribed."
- if(consultation.procedure_prescription):
+ if(encounter.procedure_prescription):
subject += "\nProcedure(s) Prescribed."
return subject
diff --git a/erpnext/healthcare/doctype/consultation/consultation_dashboard.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_dashboard.py
similarity index 88%
rename from erpnext/healthcare/doctype/consultation/consultation_dashboard.py
rename to erpnext/healthcare/doctype/patient_encounter/patient_encounter_dashboard.py
index 6170891..ec35211 100644
--- a/erpnext/healthcare/doctype/consultation/consultation_dashboard.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_dashboard.py
@@ -2,7 +2,7 @@
def get_data():
return {
- 'fieldname': 'consultation',
+ 'fieldname': 'encounter',
'non_standard_fieldnames': {
'Patient Medical Record': 'reference_name'
},
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js
new file mode 100644
index 0000000..93c02f6
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter_list.js
@@ -0,0 +1,6 @@
+/*
+(c) ESS 2015-16
+*/
+frappe.listview_settings['Patient Encounter'] = {
+ filters:[["docstatus","!=","1"]]
+};
diff --git a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.js
similarity index 69%
rename from erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
rename to erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.js
index c397f18..1baabf7 100644
--- a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
+++ b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Physician Schedule", function (assert) {
+QUnit.test("test: Patient Encounter", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
- // insert a new Physician Schedule
- () => frappe.tests.make('Physician Schedule', [
+ // insert a new Patient Encounter
+ () => frappe.tests.make('Patient Encounter', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py
new file mode 100644
index 0000000..f5df152
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+import unittest
+
+class TestPatientEncounter(unittest.TestCase):
+ pass
diff --git a/erpnext/healthcare/doctype/physician/physician_dashboard.py b/erpnext/healthcare/doctype/physician/physician_dashboard.py
deleted file mode 100644
index ee8f774..0000000
--- a/erpnext/healthcare/doctype/physician/physician_dashboard.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from frappe import _
-
-def get_data():
- return {
- 'heatmap': True,
- 'heatmap_message': _('This is based on transactions against this Physician.'),
- 'fieldname': 'physician',
- 'transactions': [
- {
- 'label': _('Appointments and Consultations'),
- 'items': ['Patient Appointment', 'Consultation']
- },
- {
- 'label': _('Lab Tests'),
- 'items': ['Lab Test']
- }
- ]
- }
diff --git a/erpnext/healthcare/doctype/physician/test_physician.py b/erpnext/healthcare/doctype/physician/test_physician.py
deleted file mode 100644
index 2fbf574..0000000
--- a/erpnext/healthcare/doctype/physician/test_physician.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and Contributors
-# See license.txt
-from __future__ import unicode_literals
-import unittest
-import frappe
-
-test_dependencies = ['Physician Schedule']
-
-
-class TestPhysician(unittest.TestCase):
- def tearDown(self):
- frappe.delete_doc_if_exists('Physician', '_Testdoctor2', force=1)
-
- def test_new_physician_without_schedule(self):
- physician = frappe.new_doc('Physician')
- physician.first_name = '_Testdoctor2'
-
- physician.insert()
- self.assertEqual(frappe.get_value('Physician', '_Testdoctor2', 'first_name'), '_Testdoctor2')
diff --git a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.py b/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.py
deleted file mode 100644
index ece3578..0000000
--- a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-import unittest
-
-class TestPhysicianSchedule(unittest.TestCase):
- pass
diff --git a/erpnext/healthcare/doctype/physician_schedule/test_records.json b/erpnext/healthcare/doctype/physician_schedule/test_records.json
deleted file mode 100644
index 1e6230d..0000000
--- a/erpnext/healthcare/doctype/physician_schedule/test_records.json
+++ /dev/null
@@ -1,8 +0,0 @@
-[
- {
- "schedule_name": "_Testdoctor1 Schedule"
- },
- {
- "schedule_name": "_Testdoctor2 Schedule"
- }
-]
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/physician_schedule/__init__.py b/erpnext/healthcare/doctype/practitioner_schedule/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/physician_schedule/__init__.py
rename to erpnext/healthcare/doctype/practitioner_schedule/__init__.py
diff --git a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
similarity index 96%
rename from erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
rename to erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
index c1b5581..f247856 100644
--- a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
+++ b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.js
@@ -1,7 +1,7 @@
-// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
-frappe.ui.form.on('Physician Schedule', {
+frappe.ui.form.on('Practitioner Schedule', {
refresh: function(frm) {
cur_frm.fields_dict["time_slots"].grid.wrapper.find('.grid-add-row').hide();
cur_frm.fields_dict["time_slots"].grid.add_custom_button(__('Add Time Slots'), () => {
diff --git a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.json b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
similarity index 91%
rename from erpnext/healthcare/doctype/physician_schedule/physician_schedule.json
rename to erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
index b1b3129..08a1b86 100644
--- a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.json
+++ b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json
@@ -15,6 +15,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -41,10 +42,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -61,7 +64,7 @@
"label": "Time Slots",
"length": 0,
"no_copy": 0,
- "options": "Physician Schedule Time Slot",
+ "options": "Healthcare Schedule Time Slot",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -72,10 +75,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -102,6 +107,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -115,16 +121,15 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-10-05 11:21:54.488194",
+ "modified": "2018-06-29 14:55:34.795995",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Physician Schedule",
+ "name": "Practitioner Schedule",
"name_case": "",
"owner": "rmehta@gmail.com",
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
diff --git a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.py b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.py
similarity index 67%
rename from erpnext/healthcare/doctype/physician_schedule/physician_schedule.py
rename to erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.py
index 167e9cd..8bd0937 100644
--- a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.py
+++ b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.py
@@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.model.document import Document
-
-class PhysicianSchedule(Document):
+class PractitionerSchedule(Document):
def autoname(self):
self.name = self.schedule_name
diff --git a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js b/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.js
similarity index 68%
copy from erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
copy to erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.js
index c397f18..32dac2c 100644
--- a/erpnext/healthcare/doctype/physician_schedule/test_physician_schedule.js
+++ b/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Physician Schedule", function (assert) {
+QUnit.test("test: Practitioner Schedule", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
- // insert a new Physician Schedule
- () => frappe.tests.make('Physician Schedule', [
+ // insert a new Practitioner Schedule
+ () => frappe.tests.make('Practitioner Schedule', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.py b/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.py
new file mode 100644
index 0000000..52638cb
--- /dev/null
+++ b/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+import unittest
+
+class TestPractitionerSchedule(unittest.TestCase):
+ pass
diff --git a/erpnext/healthcare/doctype/physician_service_unit_schedule/__init__.py b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/physician_service_unit_schedule/__init__.py
rename to erpnext/healthcare/doctype/practitioner_service_unit_schedule/__init__.py
diff --git a/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.json b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.json
similarity index 91%
rename from erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.json
rename to erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.json
index 7fff2be..f4a80ab 100644
--- a/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.json
+++ b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.json
@@ -14,6 +14,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -30,7 +31,7 @@
"label": "Schedule",
"length": 0,
"no_copy": 0,
- "options": "Physician Schedule",
+ "options": "Practitioner Schedule",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -46,6 +47,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -87,10 +89,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-05-02 03:38:09.935153",
+ "modified": "2018-06-29 15:14:18.647514",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Physician Service Unit Schedule",
+ "name": "Practitioner Service Unit Schedule",
"name_case": "",
"owner": "Administrator",
"permissions": [],
diff --git a/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.py b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.py
similarity index 60%
rename from erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.py
rename to erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.py
index 7aaec4d..c18a440 100644
--- a/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.py
+++ b/erpnext/healthcare/doctype/practitioner_service_unit_schedule/practitioner_service_unit_schedule.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.model.document import Document
-class PhysicianServiceUnitSchedule(Document):
+class PractitionerServiceUnitSchedule(Document):
pass
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
index 73bcf3f..b4c4532 100644
--- a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
+++ b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
@@ -14,6 +14,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -41,16 +42,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "procedure.template",
+ "fetch_from": "procedure.template",
"fieldname": "procedure_name",
"fieldtype": "Data",
"hidden": 0,
@@ -74,11 +76,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -106,16 +109,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -124,10 +128,10 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Physician",
+ "label": "Referral",
"length": 0,
"no_copy": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -138,11 +142,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -169,11 +174,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -200,11 +206,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -231,7 +238,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -245,7 +252,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-05-16 22:43:37.924984",
+ "modified": "2018-07-16 13:08:15.499491",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Procedure Prescription",
diff --git a/erpnext/healthcare/doctype/sample_collection/sample_collection.json b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
index 03d8d90..b5c4dbf 100644
--- a/erpnext/healthcare/doctype/sample_collection/sample_collection.json
+++ b/erpnext/healthcare/doctype/sample_collection/sample_collection.json
@@ -15,6 +15,41 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "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": "Inpatient Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Record",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -43,11 +78,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -75,15 +111,17 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -107,11 +145,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -137,11 +176,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -169,16 +209,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "patient.sex",
+ "fetch_from": "patient.sex",
"fieldname": "patient_sex",
"fieldtype": "Data",
"hidden": 0,
@@ -202,11 +243,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -234,11 +276,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -264,11 +307,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -296,16 +340,17 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "sample.sample_uom",
+ "fetch_from": "sample.sample_uom",
"fieldname": "sample_uom",
"fieldtype": "Data",
"hidden": 0,
@@ -329,11 +374,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -361,11 +407,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -391,11 +438,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -423,11 +471,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -454,11 +503,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -486,11 +536,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -517,11 +568,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -547,11 +599,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -578,7 +631,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -592,7 +645,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-16 22:43:35.762002",
+ "modified": "2018-07-12 19:19:00.573460",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Sample Collection",
diff --git a/erpnext/healthcare/doctype/vital_signs/vital_signs.json b/erpnext/healthcare/doctype/vital_signs/vital_signs.json
index 70a04fa..8354859 100644
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.json
+++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.json
@@ -14,10 +14,46 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "patient.inpatient_record",
+ "fieldname": "inpatient_record",
+ "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": "Inpatient Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Inpatient Record",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -41,16 +77,17 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "patient.patient_name",
+ "fetch_from": "patient.patient_name",
"fieldname": "patient_name",
"fieldtype": "Data",
"hidden": 0,
@@ -74,11 +111,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -106,16 +144,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "consultation",
+ "fieldname": "encounter",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -124,10 +163,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Consultation",
+ "label": "Patient Encounter",
"length": 0,
"no_copy": 1,
- "options": "Consultation",
+ "options": "Patient Encounter",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -138,11 +177,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -168,11 +208,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -200,11 +241,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -230,11 +272,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -262,11 +305,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -293,11 +337,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -325,11 +370,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -357,11 +403,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -389,11 +436,78 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "tongue",
+ "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": "Tongue",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nCoated\nVery Coated\nNormal\nFurry\nCuts",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "abdomen",
+ "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": "Abdomen",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nBloated\nFull\nFluid\nConstipated",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -419,11 +533,45 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "reflexes",
+ "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": "Reflexes",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nNormal\nHyper\nVery Hyper\nOne Sided",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -450,11 +598,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -482,11 +631,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -514,11 +664,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -545,11 +696,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -576,11 +728,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -607,11 +760,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -638,11 +792,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -670,11 +825,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -700,11 +856,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -731,11 +888,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -763,11 +921,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -794,7 +953,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -808,7 +967,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-16 22:42:54.580491",
+ "modified": "2018-07-17 14:04:09.604470",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Vital Signs",
@@ -865,4 +1024,4 @@
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js
index aeab4fc..9f2e552 100644
--- a/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js
+++ b/erpnext/healthcare/page/appointment_analytic/appointment_analytic.js
@@ -14,7 +14,7 @@
title: __("Appointment Analytics"),
parent: $(wrapper).find('.layout-main'),
page: wrapper.page,
- doctypes: ["Patient Appointment", "Physician", "Medical Department", "Appointment Type", "Patient"],
+ doctypes: ["Patient Appointment", "Healthcare Practitioner", "Medical Department", "Appointment Type", "Patient"],
tree_grid: { show: true }
});
@@ -22,16 +22,16 @@
"Medical Department": {
label: __("Department"),
show: true,
- item_key: "physician",
+ item_key: "practitioner",
parent_field: "department",
formatter: function(item) {
return item.name;
}
},
- "Physician": {
- label: __("Physician"),
+ "Healthcare Practitioner": {
+ label: __("Healthcare Practitioner"),
show: true,
- item_key: "physician",
+ item_key: "practitioner",
formatter: function(item) {
return item.name;
}
@@ -52,7 +52,7 @@
},
filters: [
{fieldtype:"Select", label: __("Tree Type"), fieldname: "tree_type",
- options:["Physician", "Medical Department"], filter: function(val, item, opts, me) {
+ options:["Healthcare Practitioner", "Medical Department"], filter: function(val, item, opts, me) {
return me.apply_zero_filter(val, item, opts, me);}},
{fieldtype:"Select", label: __("Status"), fieldname: "status",
options:[
@@ -64,10 +64,10 @@
{label: __("Cancelled"), value: "Cancelled"}]},
{fieldtype:"Select", label: __("Type"), link:"Appointment Type", fieldname: "type",
default_value: __("Select Type...")},
- {fieldtype:"Select", label: __("Physician"), link:"Physician", fieldname: "physician",
- default_value: __("Select Physician..."), filter: function(val, item, opts) {
+ {fieldtype:"Select", label: __("Healthcare Practitioner"), link:"Healthcare Practitioner", fieldname: "practitioner",
+ default_value: __("Select Healthcare Practitioner..."), filter: function(val, item, opts) {
return val == opts.default_value || item.name == val || item._show;
- }, link_formatter: {filter_input: "physician"}},
+ }, link_formatter: {filter_input: "practitioner"}},
{fieldtype:"Select", label: __("Department"), link:"Medical Department", fieldname: "department",
default_value: __("Select Department..."), filter: function(val, item, opts) {
return val == opts.default_value || item.department == val || item._show;
@@ -81,7 +81,7 @@
],
setup_filters: function() {
this._super();
- this.trigger_refresh_on_change(["tree_type", "physician", "department", "status", "type"]);
+ this.trigger_refresh_on_change(["tree_type", "practitioner", "department", "status", "type"]);
// this.show_zero_check()
},
@@ -96,10 +96,10 @@
}
if(!this.data || me.item_type != me.tree_type) {
var items = null;
- if(me.tree_type=='Physician') {
- items = frappe.report_dump.data["Physician"];
+ if(me.tree_type=='Healthcare Practitioner') {
+ items = frappe.report_dump.data["Healthcare Practitioner"];
} if(me.tree_type=='Medical Department') {
- items = this.prepare_tree("Physician", "Medical Department");
+ items = this.prepare_tree("Healthcare Practitioner", "Medical Department");
}
me.item_type = me.tree_type;
me.parent_map = {};
diff --git a/erpnext/healthcare/print_format/consultation_print/consultation_print.json b/erpnext/healthcare/print_format/consultation_print/consultation_print.json
deleted file mode 100644
index 05b8b43..0000000
--- a/erpnext/healthcare/print_format/consultation_print/consultation_print.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "align_labels_left": 0,
- "creation": "2017-04-10 14:05:53.355863",
- "custom_format": 1,
- "disabled": 0,
- "doc_type": "Consultation",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {% else %}\n <div align=\"right\">\n <h1>{{doc.name}}</h1>\n </div>\n {%- endif %}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n {% if doc.appointment %}\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t<label>Appointment</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t<strong>: </strong>{{doc.appointment}}\n\t\t\t</div>\n\t\t</div>\n\t\t{%- endif -%}\n\n <div class=\"row\">\n\t\t <div class=\"col-xs-4 text-left\">\n\t\t\t <label>Patient</label>\n\t\t </div>\n {% if doc.patient %}\n\t\t <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong>{{doc.patient}}\n\t\t </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong><em>Patient Name</em>\n\t\t </div>\n {%- endif -%}\n\t\t</div>\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Age</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_age}}\n\t\t\t</div>\n\t\t</div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Gender</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_sex}}\n\t\t\t</div>\n </div>\n\n </div>\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n\t <div class=\"col-xs-4 text-left\">\n\t\t <label>Doctor</label>\n\t </div>\n {% if doc.physician %}\n\t <div class=\"col-xs-7 text-left value\">\n\t\t\t<strong>: </strong>{{doc.physician}}\n\t </div>\n {%- endif -%}\n\t</div>\n\n {% if doc.consultation_date %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Date</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.consultation_date}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.consultation_time %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Time</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.consultation_time}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.visit_department %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Department</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.visit_department}}\n\t\t</div>\n </div>\n {%- endif -%}\n </div>\n\n </div>\n\n</div>\n<div>\n <hr>\n {% if doc.symptoms_in_print%}\n {% if doc.symptoms %}\n Complaints:\n <strong>{{doc.symptoms}}</strong>\n \t <br>\n {%- endif -%}\n {%- endif -%}\n\n {% if doc.diagnosis_in_print%}\n {% if doc.diagnosis %}\n \t Diagnosis:\n <strong>{{doc.diagnosis}}</strong>\n <br>\n {%- endif -%}\n {%- endif -%}\n\n</div>\n\n<div>\n {% if doc.drug_prescription %}\n <br>\n Rx,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Drug</th>\n <th class=\"text-left\">Dosage</th>\n <th class=\"text-left\">Period</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.drug_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.drug_name -%}<b>{{ row.drug_name }}</b>{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.dosage -%}{{ row.dosage }}{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.period -%}{{ row.period }}{%- endif -%}\n\t\t </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.comment -%}{{ row.comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n\n\n<div>\n {% if doc.test_prescription %}\n Investigations,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Test</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.test_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.test_name -%}<b>{{ row.test_name }}</b>{%- endif -%}\n </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.test_comment -%}{{ row.test_comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n<div>\n {% if doc.consultation_comment %}\n <br>\n {{doc.consultation_comment}}\n {%- endif -%}\n</div>\n",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2017-05-15 16:36:06.034909",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Consultation Print",
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Server",
- "show_section_headings": 0,
- "standard": "Yes"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/consultation_print/__init__.py b/erpnext/healthcare/print_format/encounter_print/__init__.py
similarity index 100%
rename from erpnext/healthcare/print_format/consultation_print/__init__.py
rename to erpnext/healthcare/print_format/encounter_print/__init__.py
diff --git a/erpnext/healthcare/print_format/encounter_print/encounter_print.json b/erpnext/healthcare/print_format/encounter_print/encounter_print.json
new file mode 100644
index 0000000..b33c777
--- /dev/null
+++ b/erpnext/healthcare/print_format/encounter_print/encounter_print.json
@@ -0,0 +1,22 @@
+{
+ "align_labels_right": 0,
+ "creation": "2017-04-10 14:05:53.355863",
+ "custom_format": 1,
+ "disabled": 0,
+ "doc_type": "Patient Encounter",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "font": "Default",
+ "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {% else %}\n <div align=\"right\">\n <h1>{{doc.name}}</h1>\n </div>\n {%- endif %}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n {% if doc.appointment %}\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t<label>Appointment</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t<strong>: </strong>{{doc.appointment}}\n\t\t\t</div>\n\t\t</div>\n\t\t{%- endif -%}\n\n <div class=\"row\">\n\t\t <div class=\"col-xs-4 text-left\">\n\t\t\t <label>Patient</label>\n\t\t </div>\n {% if doc.patient %}\n\t\t <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong>{{doc.patient}}\n\t\t </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong><em>Patient Name</em>\n\t\t </div>\n {%- endif -%}\n\t\t</div>\n\t <div class=\"row\">\n\t\t\t<div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Age</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_age}}\n\t\t\t</div>\n\t\t</div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n\t\t\t\t<label>Gender</label>\n\t\t\t</div>\n\t\t\t<div class=\"col-xs-7 value\">\n\t\t\t <strong>: </strong> {{doc.patient_sex}}\n\t\t\t</div>\n </div>\n\n </div>\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n\t <div class=\"col-xs-4 text-left\">\n\t\t <label>Healthcare Practitioner</label>\n\t </div>\n {% if doc.practitioner %}\n\t <div class=\"col-xs-7 text-left value\">\n\t\t\t<strong>: </strong>{{doc.practitioner}}\n\t </div>\n {%- endif -%}\n\t</div>\n\n {% if doc.encounter_date %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Date</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_date}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.encounter_time %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Time</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.encounter_time}}\n\t\t</div>\n </div>\n\t {%- endif -%}\n {% if doc.visit_department %}\n\t <div class=\"row\">\n\t\t<div class=\"col-xs-4 text-left\">\n\t\t<label>Department</label>\n\t\t</div>\n\t\t<div class=\"col-xs-7 text-left value\">\n\t\t<strong>: </strong>{{doc.visit_department}}\n\t\t</div>\n </div>\n {%- endif -%}\n </div>\n\n </div>\n\n</div>\n<div>\n <hr>\n {% if doc.symptoms_in_print%}\n {% if doc.symptoms %}\n Complaints:\n <strong>{{doc.symptoms}}</strong>\n \t <br>\n {%- endif -%}\n {%- endif -%}\n\n {% if doc.diagnosis_in_print%}\n {% if doc.diagnosis %}\n \t Diagnosis:\n <strong>{{doc.diagnosis}}</strong>\n <br>\n {%- endif -%}\n {%- endif -%}\n\n</div>\n\n<div>\n {% if doc.drug_prescription %}\n <br>\n Rx,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Drug</th>\n <th class=\"text-left\">Dosage</th>\n <th class=\"text-left\">Period</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.drug_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.drug_name -%}<b>{{ row.drug_name }}</b>{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.dosage -%}{{ row.dosage }}{%- endif -%}\n </td>\n \t<td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.period -%}{{ row.period }}{%- endif -%}\n\t\t </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.comment -%}{{ row.comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n\n\n<div>\n {% if doc.test_prescription %}\n Investigations,\n <table class=\"table\">\n <tbody>\n <!--<tr>\n <th>Test</th>\n <th>Remark</th>\n </tr>-->\n\n {%- for row in doc.test_prescription -%}\n <tr>\n <td style=\"width: 30%;border:none;\">\n {%- if row.test_name -%}<b>{{ row.test_name }}</b>{%- endif -%}\n </td>\n <td style=\"width: 30%;text-align: left;border:none;\">\n\t\t\t <div style=\"border: 0px;\">\n {%- if row.test_comment -%}{{ row.test_comment }}{%- endif -%}\n </div>\n\t\t </td>\n </tr>\n\n\t {%- endfor -%}\n </tbody>\n </table>\n\n\n {%- endif -%}\n</div>\n<div>\n {% if doc.encounter_comment %}\n <br>\n {{doc.encounter_comment}}\n {%- endif -%}\n</div>\n",
+ "idx": 0,
+ "line_breaks": 0,
+ "modified": "2018-07-10 18:52:10.970448",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Encounter Print",
+ "owner": "Administrator",
+ "print_format_builder": 0,
+ "print_format_type": "Server",
+ "show_section_headings": 0,
+ "standard": "Yes"
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
index e3e21a7..2f85ff6 100644
--- a/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
+++ b/erpnext/healthcare/print_format/lab_test_print/lab_test_print.json
@@ -1,22 +1,22 @@
{
- "align_labels_left": 0,
- "creation": "2017-04-24 15:38:45.332473",
- "custom_format": 1,
- "disabled": 0,
- "doc_type": "Lab Test",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {%- endif %}\n\n {% if (doc.docstatus != 1) %}\n <b>Lab Tests have to be Submitted for Print .. !</b>\n {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.approval_status != \"Approved\") %}\n <b>Lab Tests have to be Approved for Print .. !</b>\n {%- else -%}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n {% if doc.invoice %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Order No.</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong>{{doc.invoice}}\n </div>\n </div>\n {%- endif -%}\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Patient</label>\n </div>\n {% if doc.patient %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong>{{doc.patient}}\n </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong><em>Patient Name</em>\n </div>\n {%- endif -%}\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Age</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_age}}\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Gender</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_sex}}\n </div>\n </div>\n\n </div>\n\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Doctor</label>\n </div>\n {% if doc.physician %}\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.physician}}\n </div>\n {%- endif -%}\n </div>\n\n {% if doc.sample_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Sample Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.sample_date}}\n </div>\n </div>\n {%- endif -%}\n\n {% if doc.result_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Result Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.result_date}}\n </div>\n </div>\n {%- endif -%}\n\n </div>\n\n </div>\n\n <div align=\"center\">\n <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n </div>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.normal_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n <th class=\"text-right\">Normal Range</th>\n </tr>\n\n {%- if doc.normal_test_items|length > 1 %}\n <tr><td style=\"width: 40%;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n {%- endif -%}\n\n {%- for row in doc.normal_test_items -%}\n <tr>\n <td style=\"width: 40%;border:none;\">\n {%- if doc.normal_test_items|length > 1 %}  {%- endif -%}\n {%- if row.test_name -%}<b>{{ row.test_name }}</b>\n {%- else -%}   {%- endif -%}\n {%- if row.test_event -%}   {{ row.test_event }}{%- endif -%}\n </td>\n\n <td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%} \n {%- if row.test_uom -%}{{ row.test_uom }}{%- endif -%}\n </td>\n\n <td style=\"width: 30%;text-align: right;border:none;\">\n <div style=\"border: 0px;\">\n {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n </div>\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n </tbody>\n </table>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.special_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n </tr>\n <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n {%- for row in doc.special_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\">   {{ row.test_particulars }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n {%- if doc.sensitivity_test_items -%}\n <tr>\n <th>Antibiotic</th>\n <th class=\"text-left\">Sensitivity</th>\n </tr>\n {%- for row in doc.sensitivity_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n </tbody>\n </table>\n {%- endif -%}\n\n <div align=\"right\">\n {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n {%- else -%}\n <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n {%- endif -%}\n </div>\n</div>\n",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2017-04-27 12:11:58.342145",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "Lab Test Print",
- "owner": "Administrator",
- "print_format_builder": 0,
- "print_format_type": "Server",
- "show_section_headings": 0,
+ "align_labels_right": 0,
+ "creation": "2017-04-24 15:38:45.332473",
+ "custom_format": 1,
+ "disabled": 0,
+ "doc_type": "Lab Test",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "font": "Default",
+ "html": "<div >\n {% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n <hr>\n {%- endif %}\n\n {% if (doc.docstatus != 1) %}\n <b>Lab Tests have to be Submitted for Print .. !</b>\n {% elif (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"require_test_result_approval\") == '1' and doc.approval_status != \"Approved\") %}\n <b>Lab Tests have to be Approved for Print .. !</b>\n {%- else -%}\n <div class=\"row section-break\">\n <div class=\"col-xs-6 column-break\">\n {% if doc.invoice %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Order No.</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong>{{doc.invoice}}\n </div>\n </div>\n {%- endif -%}\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Patient</label>\n </div>\n {% if doc.patient %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong>{{doc.patient}}\n </div>\n {% else %}\n <div class=\"col-xs-7 value\">\n <strong>: </strong><em>Patient Name</em>\n </div>\n {%- endif -%}\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Age</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_age}}\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Gender</label>\n </div>\n <div class=\"col-xs-7 value\">\n <strong>: </strong> {{doc.patient_sex}}\n </div>\n </div>\n\n </div>\n\n <div class=\"col-xs-6 column-break\">\n\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Healthcare Practitioner</label>\n </div>\n {% if doc.practitioner %}\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.practitioner}}\n </div>\n {%- endif -%}\n </div>\n\n {% if doc.sample_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Sample Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.sample_date}}\n </div>\n </div>\n {%- endif -%}\n\n {% if doc.result_date %}\n <div class=\"row\">\n <div class=\"col-xs-4 text-left\">\n <label>Result Date</label>\n </div>\n <div class=\"col-xs-7 text-left value\">\n <strong>: </strong>{{doc.result_date}}\n </div>\n </div>\n {%- endif -%}\n\n </div>\n\n </div>\n\n <div align=\"center\">\n <hr><h4 class=\"text-uppercase\"><b><u>Department of {{doc.department}}</u></b></h4>\n </div>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.normal_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n <th class=\"text-right\">Normal Range</th>\n </tr>\n\n {%- if doc.normal_test_items|length > 1 %}\n <tr><td style=\"width: 40%;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n {%- endif -%}\n\n {%- for row in doc.normal_test_items -%}\n <tr>\n <td style=\"width: 40%;border:none;\">\n {%- if doc.normal_test_items|length > 1 %}  {%- endif -%}\n {%- if row.test_name -%}<b>{{ row.test_name }}</b>\n {%- else -%}   {%- endif -%}\n {%- if row.test_event -%}   {{ row.test_event }}{%- endif -%}\n </td>\n\n <td style=\"width: 20%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%} \n {%- if row.test_uom -%}{{ row.test_uom }}{%- endif -%}\n </td>\n\n <td style=\"width: 30%;text-align: right;border:none;\">\n <div style=\"border: 0px;\">\n {%- if row.normal_range -%}{{ row.normal_range }}{%- endif -%}\n </div>\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n </tbody>\n </table>\n\n <table class=\"table\">\n <tbody>\n {%- if doc.special_test_items -%}\n <tr>\n <th>Name of Test</th>\n <th class=\"text-left\">Result</th>\n </tr>\n <tr><td style=\"width: 30%;border:none;\"> <b>{{ doc.test_name }}</b> </td><td></td></tr>\n {%- for row in doc.special_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\">   {{ row.test_particulars }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">\n {%- if row.result_value -%}{{ row.result_value }}{%- endif -%}\n </td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n {%- if doc.sensitivity_test_items -%}\n <tr>\n <th>Antibiotic</th>\n <th class=\"text-left\">Sensitivity</th>\n </tr>\n {%- for row in doc.sensitivity_test_items -%}\n <tr>\n <td style=\"width: 30%;border:none;\"> {{ row.antibiotic }} </td>\n <td style=\"width: 70%;text-align: left;border:none;\">{{ row.antibiotic_sensitivity }}</td>\n </tr>\n\n {%- endfor -%}\n {%- endif -%}\n\n </tbody>\n </table>\n {%- endif -%}\n\n <div align=\"right\">\n {%- if (frappe.db.get_value(\"Healthcare Settings\", \"None\", \"employee_name_and_designation_in_print\") == '1') -%}\n <h6 class=\"text-uppercase\"><b>{{doc.employee_name}}</b></h6>\n <h6 class=\"text-uppercase\"><b>{{doc.employee_designation}}</b></h6>\n {%- else -%}\n <h6 ><b>{{frappe.db.get_value(\"Healthcare Settings\", \"None\", \"custom_signature_in_print\") }}</b></h6>\n {%- endif -%}\n </div>\n</div>\n",
+ "idx": 0,
+ "line_breaks": 0,
+ "modified": "2018-07-10 11:29:24.167265",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Lab Test Print",
+ "owner": "Administrator",
+ "print_format_builder": 0,
+ "print_format_type": "Server",
+ "show_section_headings": 0,
"standard": "Yes"
-}
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/report/lab_test_report/lab_test_report.py b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
index 61769f8..e4771c5 100644
--- a/erpnext/healthcare/report/lab_test_report/lab_test_report.py
+++ b/erpnext/healthcare/report/lab_test_report/lab_test_report.py
@@ -17,7 +17,7 @@
data = []
for lab_test in lab_test_list:
- row = [ lab_test.test_name, lab_test.patient, lab_test.physician, lab_test.invoice, lab_test.status, lab_test.result_date, lab_test.department]
+ row = [ lab_test.test_name, lab_test.patient, lab_test.practitioner, lab_test.invoice, lab_test.status, lab_test.result_date, lab_test.department]
data.append(row)
return columns, data
@@ -27,7 +27,7 @@
columns = [
_("Test") + ":Data:120",
_("Patient") + ":Link/Patient:180",
- _("Doctor") + ":Link/Physician:120",
+ _("Healthcare Practitioner") + ":Link/Healthcare Practitioner:120",
_("Invoice") + ":Link/Sales Invoice:120",
_("Status") + ":Data:120",
_("Result Date") + ":Date:120",
@@ -52,7 +52,7 @@
def get_lab_test(filters):
conditions = get_conditions(filters)
- return frappe.db.sql("""select name, patient, test_name, patient_name, status, result_date, physician, invoice, department
+ return frappe.db.sql("""select name, patient, test_name, patient_name, status, result_date, practitioner, invoice, department
from `tabLab Test`
where docstatus<2 %s order by submitted_date desc, name desc""" %
conditions, filters, as_dict=1)
diff --git a/erpnext/healthcare/setup.py b/erpnext/healthcare/setup.py
index f30f42c..c00b637 100644
--- a/erpnext/healthcare/setup.py
+++ b/erpnext/healthcare/setup.py
@@ -14,8 +14,6 @@
create_duration()
create_dosage()
create_healthcare_item_groups()
- create_lab_test_items()
- create_lab_test_template()
create_sensitivity()
add_healthcare_service_unit_tree_root()
@@ -184,73 +182,6 @@
]
insert_record(records)
-def create_lab_test_items():
- records = [
- {"doctype": "Item", "item_code": "MCH", "item_name": "MCH", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
- {"doctype": "Item", "item_code": "LDL", "item_name": "LDL", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
- {"doctype": "Item", "item_code": "GTT", "item_name": "GTT", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
- {"doctype": "Item", "item_code": "HDL", "item_name": "HDL", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
- {"doctype": "Item", "item_code": "BILT", "item_name": "BILT", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
- {"doctype": "Item", "item_code": "BILD", "item_name": "BILD", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
- {"doctype": "Item", "item_code": "BP", "item_name": "BP", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1},
- {"doctype": "Item", "item_code": "BS", "item_name": "BS", "item_group": _("Laboratory"),
- "stock_uom": _("Unit"), "is_stock_item": 0, "is_purchase_item": 0, "is_sales_item": 1}
- ]
- insert_record(records)
-
-def create_lab_test_template():
- records = [
- {"doctype": "Lab Test Template", "name": "MCH","test_name": "MCH","test_code": "MCH",
- "test_group": _("Laboratory"),"department": _("Haematology"),"item": "MCH",
- "test_template_type": "Single","is_billable": 1,"test_rate": 0.0,"test_uom": "Microgram",
- "test_normal_range": "27 - 32 Microgram",
- "sensitivity": 0,"test_description": "Mean Corpuscular Hemoglobin"},
- {"doctype": "Lab Test Template", "name": "LDL","test_name": "LDL (Serum)","test_code": "LDL",
- "test_group": _("Laboratory"),"department": _("Biochemistry"),
- "item": "LDL","test_template_type": "Single",
- "is_billable": 1,"test_rate": 0.0,"test_uom": "mg / dl","test_normal_range": "70 - 160 mg/dlLow-density Lipoprotein (LDL)",
- "sensitivity": 0,"test_description": "Low-density Lipoprotein (LDL)"},
- {"doctype": "Lab Test Template", "name": "GTT","test_name": "GTT","test_code": "GTT",
- "test_group": _("Laboratory"),"department": _("Haematology"),
- "item": "GTT","test_template_type": "Single",
- "is_billable": 1,"test_rate": 0.0,"test_uom": "mg / dl","test_normal_range": "Less than 85 mg/dl",
- "sensitivity": 0,"test_description": "Glucose Tolerance Test"},
- {"doctype": "Lab Test Template", "name": "HDL","test_name": "HDL (Serum)","test_code": "HDL",
- "test_group": _("Laboratory"),"department": _("Biochemistry"),
- "item": "HDL","test_template_type": "Single",
- "is_billable": 1,"test_rate": 0.0,"test_uom": "mg / dl","test_normal_range": "35 - 65 mg/dl",
- "sensitivity": 0,"test_description": "High-density Lipoprotein (HDL)"},
- {"doctype": "Lab Test Template", "name": "BILT","test_name": "Bilirubin Total","test_code": "BILT",
- "test_group": _("Laboratory"),"department": _("Biochemistry"),
- "item": "BILT","test_template_type": "Single",
- "is_billable": 1,"test_rate": 0.0,"test_uom": "mg / dl","test_normal_range": "0.2 - 1.2 mg / dl",
- "sensitivity": 0,"test_description": "Bilirubin Total"},
- {"doctype": "Lab Test Template", "name": "BILD","test_name": "Bilirubin Direct","test_code": "BILD",
- "test_group": _("Laboratory"),"department": _("Biochemistry"),
- "item": "BILD","test_template_type": "Single",
- "is_billable": 1,"test_rate": 0.0,"test_uom": "mg / dl","test_normal_range": "0.4 mg / dl",
- "sensitivity": 0,"test_description": "Bilirubin Direct"},
-
- {"doctype": "Lab Test Template", "name": "BP","test_name": "Bile Pigment","test_code": "BP",
- "test_group": _("Laboratory"),"department": _("Pathology"),
- "item": "BP","test_template_type": "Single",
- "is_billable": 1,"test_rate": 0.0,"test_uom": "","test_normal_range": "",
- "sensitivity": 0,"test_description": "Bile Pigment"},
- {"doctype": "Lab Test Template", "name": "BS","test_name": "Bile Salt","test_code": "BS",
- "test_group": _("Laboratory"),"department": _("Pathology"),
- "item": "BS","test_template_type": "Single",
- "is_billable": 1,"test_rate": 0.0,"test_uom": "","test_normal_range": "",
- "sensitivity": 0,"test_description": "Bile Salt"}
- ]
- insert_record(records)
-
def create_sensitivity():
records = [
{"doctype": "Sensitivity", "sensitivity": _("Low Sensitivity")},
@@ -266,7 +197,7 @@
record = [
{
"doctype": "Healthcare Service Unit",
- "healthcare_service_unit_name": "All Healthcare Service Unit",
+ "healthcare_service_unit_name": "All Healthcare Service Units",
"is_group": 1
}
]
diff --git a/erpnext/healthcare/web_form/lab_test/lab_test.json b/erpnext/healthcare/web_form/lab_test/lab_test.json
index fec34b6..89029fa 100644
--- a/erpnext/healthcare/web_form/lab_test/lab_test.json
+++ b/erpnext/healthcare/web_form/lab_test/lab_test.json
@@ -18,7 +18,7 @@
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
- "modified": "2017-06-07 16:03:06.781364",
+ "modified": "2018-07-16 13:10:47.940128",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "lab-test",
@@ -77,13 +77,13 @@
"reqd": 0
},
{
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
- "label": "Doctor",
+ "label": "Healthcare Practitioner",
"max_length": 0,
"max_value": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"read_only": 0,
"reqd": 0
},
diff --git a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.json b/erpnext/healthcare/web_form/patient_appointments/patient_appointments.json
index 613e367..e9cf7a8 100644
--- a/erpnext/healthcare/web_form/patient_appointments/patient_appointments.json
+++ b/erpnext/healthcare/web_form/patient_appointments/patient_appointments.json
@@ -18,7 +18,7 @@
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
- "modified": "2017-06-07 15:57:27.196428",
+ "modified": "2018-07-16 13:11:08.626316",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "patient-appointments",
@@ -43,13 +43,13 @@
"reqd": 1
},
{
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
- "label": "Physician",
+ "label": "Healthcare Practitioner",
"max_length": 0,
"max_value": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"read_only": 0,
"reqd": 1
},
diff --git a/erpnext/healthcare/doctype/consultation/__init__.py b/erpnext/healthcare/web_form/personal_details/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/consultation/__init__.py
copy to erpnext/healthcare/web_form/personal_details/__init__.py
diff --git a/erpnext/healthcare/web_form/personal_details/personal_details.js b/erpnext/healthcare/web_form/personal_details/personal_details.js
new file mode 100644
index 0000000..f09e540
--- /dev/null
+++ b/erpnext/healthcare/web_form/personal_details/personal_details.js
@@ -0,0 +1,3 @@
+frappe.ready(function() {
+ // bind events here
+});
diff --git a/erpnext/healthcare/web_form/personal_details/personal_details.json b/erpnext/healthcare/web_form/personal_details/personal_details.json
new file mode 100644
index 0000000..aad987a
--- /dev/null
+++ b/erpnext/healthcare/web_form/personal_details/personal_details.json
@@ -0,0 +1,87 @@
+{
+ "accept_payment": 0,
+ "allow_comments": 0,
+ "allow_delete": 0,
+ "allow_edit": 1,
+ "allow_incomplete": 0,
+ "allow_multiple": 0,
+ "allow_print": 0,
+ "amount": 0.0,
+ "amount_based_on_field": 0,
+ "creation": "2018-07-03 19:33:23.332661",
+ "currency": "INR",
+ "doc_type": "Patient",
+ "docstatus": 0,
+ "doctype": "Web Form",
+ "idx": 0,
+ "introduction_text": "",
+ "is_standard": 1,
+ "login_required": 1,
+ "max_attachment_size": 0,
+ "modified": "2018-07-04 17:22:28.936442",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "personal-details",
+ "owner": "Administrator",
+ "payment_button_label": "Buy Now",
+ "published": 1,
+ "route": "personal-details",
+ "show_sidebar": 1,
+ "sidebar_items": [],
+ "success_url": "/personal-details",
+ "title": "Personal Details",
+ "web_form_fields": [
+ {
+ "fieldname": "patient_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Full Name",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "sex",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "label": "Gender",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "\nMale\nFemale\nOther",
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "dob",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "label": "Date of birth",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "mobile",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Mobile",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "email",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Email",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "Email",
+ "read_only": 1,
+ "reqd": 0
+ }
+ ]
+}
diff --git a/erpnext/healthcare/web_form/personal_details/personal_details.py b/erpnext/healthcare/web_form/personal_details/personal_details.py
new file mode 100644
index 0000000..aa68c42
--- /dev/null
+++ b/erpnext/healthcare/web_form/personal_details/personal_details.py
@@ -0,0 +1,28 @@
+from __future__ import unicode_literals
+
+import frappe
+from frappe import _
+
+no_cache = 1
+no_sitemap = 1
+
+def get_context(context):
+ if frappe.session.user=='Guest':
+ frappe.throw(_("You need to be logged in to access this page"), frappe.PermissionError)
+
+ context.show_sidebar=True
+
+ if frappe.db.exists("Patient", {'email': frappe.session.user}):
+ patient = frappe.get_doc("Patient", {'email': frappe.session.user})
+ context.doc = patient
+ frappe.form_dict.new = 0
+ frappe.form_dict.name = patient.name
+
+def get_patient():
+ return frappe.get_value("Patient",{"email": frappe.session.user}, "name")
+
+def has_website_permission(doc, ptype, user, verbose=False):
+ if doc.name == get_patient():
+ return True
+ else:
+ return False
diff --git a/erpnext/healthcare/web_form/prescription/prescription.json b/erpnext/healthcare/web_form/prescription/prescription.json
index 5f251a3..a2aabd1 100644
--- a/erpnext/healthcare/web_form/prescription/prescription.json
+++ b/erpnext/healthcare/web_form/prescription/prescription.json
@@ -10,7 +10,7 @@
"amount_based_on_field": 0,
"creation": "2017-06-06 17:13:19.101374",
"currency": "INR",
- "doc_type": "Consultation",
+ "doc_type": "Patient Encounter",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
@@ -18,13 +18,13 @@
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
- "modified": "2017-06-20 11:56:05.132154",
+ "modified": "2018-07-16 13:11:28.057697",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "prescription",
"owner": "Administrator",
"payment_button_label": "Buy Now",
- "print_format": "Consultation Print",
+ "print_format": "Encounter Print",
"published": 1,
"route": "prescription",
"show_sidebar": 1,
@@ -33,13 +33,13 @@
"title": "Prescription",
"web_form_fields": [
{
- "fieldname": "physician",
+ "fieldname": "practitioner",
"fieldtype": "Link",
"hidden": 0,
- "label": "Doctor",
+ "label": "Healthcare Practitioner",
"max_length": 0,
"max_value": 0,
- "options": "Physician",
+ "options": "Healthcare Practitioner",
"read_only": 0,
"reqd": 1
},
@@ -56,10 +56,10 @@
},
{
"default": "Today",
- "fieldname": "consultation_date",
+ "fieldname": "encounter_date",
"fieldtype": "Date",
"hidden": 0,
- "label": "Consultation Date",
+ "label": "Encounter Date",
"max_length": 0,
"max_value": 0,
"read_only": 0,
@@ -67,10 +67,10 @@
},
{
"default": "",
- "fieldname": "consultation_time",
+ "fieldname": "encounter_time",
"fieldtype": "Data",
"hidden": 0,
- "label": "Consultation Time",
+ "label": "Encounter Time",
"max_length": 0,
"max_value": 0,
"read_only": 0,
@@ -99,7 +99,7 @@
"reqd": 0
},
{
- "fieldname": "consultation_comment",
+ "fieldname": "encounter_comment",
"fieldtype": "Small Text",
"hidden": 0,
"label": "Review Details",
diff --git a/erpnext/healthcare/web_form/prescription/prescription.py b/erpnext/healthcare/web_form/prescription/prescription.py
index 73b0350..efdeaa9 100644
--- a/erpnext/healthcare/web_form/prescription/prescription.py
+++ b/erpnext/healthcare/web_form/prescription/prescription.py
@@ -7,13 +7,13 @@
def get_list_context(context):
context.row_template = "erpnext/templates/includes/healthcare/prescription_row_template.html"
- context.get_list = get_consultation_list
+ context.get_list = get_encounter_list
-def get_consultation_list(doctype, txt, filters, limit_start, limit_page_length = 20, order_by='modified desc'):
+def get_encounter_list(doctype, txt, filters, limit_start, limit_page_length = 20, order_by='modified desc'):
patient = get_patient()
- consultations = frappe.db.sql("""select * from `tabConsultation`
+ encounters = frappe.db.sql("""select * from `tabPatient Encounter`
where patient = %s order by creation desc""", patient, as_dict = True)
- return consultations
+ return encounters
def get_patient():
return frappe.get_value("Patient",{"email": frappe.session.user}, "name")
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index be73b3a..999ece9 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -12,7 +12,7 @@
source_link = "https://github.com/frappe/erpnext"
develop_version = '11.x.x-develop'
-staging_version = '11.x.x'
+staging_version = '11.0.0-beta'
error_report_email = "support@erpnext.com"
@@ -133,6 +133,7 @@
]
standard_portal_menu_items = [
+ {"title": _("Personal Details"), "route": "/personal-details", "reference_doctype": "Patient", "role": "Patient"},
{"title": _("Projects"), "route": "/project", "reference_doctype": "Project"},
{"title": _("Request for Quotations"), "route": "/rfq", "reference_doctype": "Request for Quotation", "role": "Supplier"},
{"title": _("Supplier Quotation"), "route": "/supplier-quotations", "reference_doctype": "Supplier Quotation", "role": "Supplier"},
@@ -145,7 +146,7 @@
{"title": _("Timesheets"), "route": "/timesheets", "reference_doctype": "Timesheet", "role":"Customer"},
{"title": _("Timesheets"), "route": "/timesheets", "reference_doctype": "Timesheet", "role":"Customer"},
{"title": _("Lab Test"), "route": "/lab-test", "reference_doctype": "Lab Test", "role":"Patient"},
- {"title": _("Prescription"), "route": "/prescription", "reference_doctype": "Consultation", "role":"Patient"},
+ {"title": _("Prescription"), "route": "/prescription", "reference_doctype": "Patient Encounter", "role":"Patient"},
{"title": _("Patient Appointment"), "route": "/patient-appointments", "reference_doctype": "Patient Appointment", "role":"Patient"},
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"},
{"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"},
@@ -168,8 +169,9 @@
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission",
"Timesheet": "erpnext.controllers.website_list_for_contact.has_website_permission",
"Lab Test": "erpnext.healthcare.web_form.lab_test.lab_test.has_website_permission",
- "Consultation": "erpnext.healthcare.web_form.prescription.prescription.has_website_permission",
- "Patient Appointment": "erpnext.healthcare.web_form.patient_appointments.patient_appointments.has_website_permission"
+ "Patient Encounter": "erpnext.healthcare.web_form.prescription.prescription.has_website_permission",
+ "Patient Appointment": "erpnext.healthcare.web_form.patient_appointments.patient_appointments.has_website_permission",
+ "Patient": "erpnext.healthcare.web_form.personal_details.personal_details.has_website_permission"
}
dump_report_map = "erpnext.startup.report_data_map.data_map"
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.py b/erpnext/hr/doctype/additional_salary/additional_salary.py
index 90f6c0b..e758227 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.py
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.py
@@ -55,11 +55,18 @@
if additional_components:
additional_components_array = []
for additional_component in additional_components:
- struct_row = {}
- additional_components_dict = {}
additional_component_obj = frappe.get_doc("Additional Salary", additional_component[0])
amount = additional_component_obj.get_amount(start_date, end_date)
salary_component = frappe.get_doc("Salary Component", additional_component_obj.salary_component)
+ added = False
+ for added_component in additional_components_array:
+ if added_component["struct_row"]["salary_component"] == salary_component.name:
+ added_component["amount"] += amount
+ added = True
+ if added:
+ continue
+ struct_row = {}
+ additional_components_dict = {}
struct_row['depends_on_lwp'] = salary_component.depends_on_lwp
struct_row['salary_component'] = salary_component.name
struct_row['abbr'] = salary_component.salary_component_abbr
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
index a117997..9b6dba5 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
@@ -200,7 +200,7 @@
# TODO: Check if there is benefit claim for employee then pro-rata divide the rest of amount (Late Benefit Application)
else:
component_max = frappe.db.get_value("Salary Component", struct_row.salary_component, "max_benefit_amount")
- if component_max > 0:
+ if component_max:
benefit_amount = get_benefit_pro_rata_ratio_amount(sal_struct, component_max)
return get_amount(period_factor, benefit_amount, period_length)
return False
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py b/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
index 64138e5..beaddd9 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
@@ -3,9 +3,9 @@
# See license.txt
from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
import unittest
-from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
+from erpnext.hr.doctype.employee.test_employee import make_employee
class TestEmployeeTaxExemptionDeclaration(unittest.TestCase):
def setUp(self):
@@ -39,7 +39,7 @@
declaration = frappe.get_doc({
"doctype": "Employee Tax Exemption Declaration",
"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
- "company": "_Test Company",
+ "company": erpnext.get_default_company(),
"payroll_period": "_Test Payroll Period",
"declarations": [dict(exemption_sub_category = "_Test Sub Category",
exemption_category = "_Test Category",
@@ -55,7 +55,7 @@
declaration = frappe.get_doc({
"doctype": "Employee Tax Exemption Declaration",
"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
- "company": "_Test Company",
+ "company": erpnext.get_default_company(),
"payroll_period": "_Test Payroll Period",
"declarations": [dict(exemption_sub_category = "_Test Sub Category",
exemption_category = "_Test Category",
@@ -70,7 +70,7 @@
duplicate_declaration = frappe.get_doc({
"doctype": "Employee Tax Exemption Declaration",
"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
- "company": "_Test Company",
+ "company": erpnext.get_default_company(),
"payroll_period": "_Test Payroll Period",
"declarations": [dict(exemption_sub_category = "_Test Sub Category",
exemption_category = "_Test Category",
@@ -87,10 +87,13 @@
payroll_period = frappe.get_doc(dict(
doctype = 'Payroll Period',
name = "_Test Payroll Period",
- company = "_Test Company",
+ company = erpnext.get_default_company(),
start_date = date(date.today().year, 1, 1),
end_date = date(date.today().year, 12, 31)
)).insert()
+ return payroll_period
+ else:
+ return frappe.get_doc("Payroll Period", "_Test Payroll Period")
def create_exemption_category():
if not frappe.db.exists("Employee Tax Exemption Category", "_Test Category"):
diff --git a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py b/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py
index 7ff5a45..b3df2dc 100644
--- a/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py
+++ b/erpnext/hr/doctype/payroll_entry/test_payroll_entry.py
@@ -18,8 +18,8 @@
for dt in ["Salary Slip", "Salary Component", "Salary Component Account", "Payroll Entry", "Loan"]:
frappe.db.sql("delete from `tab%s`" % dt)
- make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA", "Leave Encashment"])
- make_deduction_salary_component(["Professional Tax", "TDS"])
+ make_earning_salary_component(setup=True)
+ make_deduction_salary_component(setup=True)
def test_payroll_entry(self): # pylint: disable=no-self-use
company = erpnext.get_default_company()
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index b856487..f4dbec7 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -6,18 +6,19 @@
import frappe
import erpnext
import calendar
+import random
from erpnext.accounts.utils import get_fiscal_year
from frappe.utils.make_random import get_random
-from frappe.utils import getdate, nowdate, add_days, add_months, flt
+from frappe.utils import getdate, nowdate, add_days, add_months, flt, get_first_day, get_last_day
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
from erpnext.hr.doctype.payroll_entry.payroll_entry import get_month_details
from erpnext.hr.doctype.employee.test_employee import make_employee
-
+from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import create_payroll_period, create_exemption_category
class TestSalarySlip(unittest.TestCase):
def setUp(self):
- make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
- make_deduction_salary_component(["Professional Tax", "TDS"])
+ make_earning_salary_component(setup=True)
+ make_deduction_salary_component(setup=True)
for dt in ["Leave Application", "Leave Allocation", "Salary Slip"]:
frappe.db.sql("delete from `tab%s`" % dt)
@@ -164,6 +165,61 @@
elif payroll_frequncy == "Daily":
self.assertEqual(ss.end_date, nowdate())
+ def test_tax_for_payroll_period(self):
+ data = {}
+ # test the impact of tax exemption declaration, tax exemption proof submission and deduct check boxes in annual tax calculation
+ # as per assigned salary structure 40500 in monthly salary so 236000*5/100/12
+ frappe.db.sql("""delete from `tabPayroll Period`""")
+ frappe.db.sql("""delete from `tabSalary Component`""")
+ payroll_period = create_payroll_period()
+ create_tax_slab(payroll_period)
+ employee = make_employee("test_tax@salary.slip")
+ frappe.db.sql("""delete from `tabSalary Slip` where employee=%s""", (employee))
+ frappe.db.sql("""delete from `tabEmployee Tax Exemption Declaration` where employee=%s""", (employee))
+ frappe.db.sql("""delete from `tabEmployee Tax Exemption Proof Submission` where employee=%s""", (employee))
+ from erpnext.hr.doctype.salary_structure.test_salary_structure import make_salary_structure, create_salary_structure_assignment
+ salary_structure = make_salary_structure("Stucture to test tax", "Monthly", test_tax=True)
+ create_salary_structure_assignment(employee, salary_structure.name, payroll_period.start_date)
+
+ # create salary slip for whole period deducting tax only on last period to find the total tax amount paid
+ create_salary_slips_for_payroll_period(employee, salary_structure.name, payroll_period)
+ tax_paid_amount = frappe.db.sql("""select sum(sd.amount) from `tabSalary Detail` sd join `tabSalary Slip` ss where
+ ss.name=sd.parent and ss.employee=%s and ss.docstatus=1 and sd.salary_component='TDS'""", (employee))
+
+ # total taxable income 236000, at 5% tax slab
+ annual_tax = 11800
+ self.assertEqual(tax_paid_amount[0][0], annual_tax)
+ frappe.db.sql("""delete from `tabSalary Slip` where employee=%s""", (employee))
+
+ # create exemption declaration so the tax amount varies
+ create_exemption_declaration(employee, payroll_period.name)
+
+ # create for payroll deducting in random months
+ data["deducted_dates"] = create_salary_slips_for_payroll_period(employee, salary_structure.name, payroll_period, deduct_random=True)
+ tax_paid_amount = frappe.db.sql("""select sum(sd.amount) from `tabSalary Detail` sd join `tabSalary Slip` ss where
+ ss.name=sd.parent and ss.employee=%s and ss.docstatus=1 and sd.salary_component='TDS'""", (employee))
+
+ # No proof sumitted, total tax paid, should not change
+ try:
+ self.assertEqual(tax_paid_amount[0][0], annual_tax)
+ except AssertionError:
+ print("\nTax calculation failed on following case\n", data, "\n")
+ raise
+
+ # Submit proof for total 86000
+ data["proof"] = [create_proof_submission(employee, payroll_period, 50000), 50000]
+ data["proof1"] = [create_proof_submission(employee, payroll_period, 36000), 36000]
+ frappe.db.sql("""delete from `tabSalary Slip` where employee=%s""", (employee))
+ data["deducted_dates"] = create_salary_slips_for_payroll_period(employee, salary_structure.name, payroll_period, deduct_random=True)
+ tax_paid_amount = frappe.db.sql("""select sum(sd.amount) from `tabSalary Detail` sd join `tabSalary Slip` ss where
+ ss.name=sd.parent and ss.employee=%s and ss.docstatus=1 and sd.salary_component='TDS'""", (employee))
+ # total taxable income 150000, at 5% tax slab
+ try:
+ self.assertEqual(tax_paid_amount[0][0], 7500)
+ except AssertionError:
+ print("\nTax calculation failed on following case\n", data, "\n")
+ raise
+
def make_holiday_list(self):
fiscal_year = get_fiscal_year(nowdate(), company=erpnext.get_default_company())
if not frappe.db.get_value("Holiday List", "Salary Slip Test Holiday List"):
@@ -212,28 +268,22 @@
return salary_slip
-
-def make_earning_salary_component(salary_components):
+def make_salary_component(salary_components, test_tax):
for salary_component in salary_components:
- if not frappe.db.exists('Salary Component', salary_component):
- sal_comp = frappe.get_doc({
- "doctype": "Salary Component",
- "salary_component": salary_component,
- "type": "Earning"
- })
- sal_comp.insert()
- get_salary_component_account(salary_component)
-
-def make_deduction_salary_component(salary_components):
- for salary_component in salary_components:
- if not frappe.db.exists('Salary Component', salary_component):
- sal_comp = frappe.get_doc({
- "doctype": "Salary Component",
- "salary_component": salary_component,
- "type": "Deduction"
- })
- sal_comp.insert()
- get_salary_component_account(salary_component)
+ if not frappe.db.exists('Salary Component', salary_component["salary_component"]):
+ if test_tax:
+ if salary_component["type"] == "Earning":
+ salary_component["is_tax_applicable"] = 1
+ elif salary_component["salary_component"] == "TDS":
+ salary_component["variable_based_on_taxable_salary"] = 1
+ salary_component["amount_based_on_formula"] = 0
+ salary_component["amount"] = 0
+ salary_component["formula"] = ""
+ salary_component["condition"] = ""
+ salary_component["doctype"] = "Salary Component"
+ salary_component["salary_component_abbr"] = salary_component["abbr"]
+ frappe.get_doc(salary_component).insert()
+ get_salary_component_account(salary_component["salary_component"])
def get_salary_component_account(sal_comp):
company = erpnext.get_default_company()
@@ -244,7 +294,6 @@
})
sal_comp.save()
-
def create_account(company):
salary_account = frappe.db.get_value("Account", "Salary - " + frappe.db.get_value('Company', company, 'abbr'))
if not salary_account:
@@ -256,64 +305,138 @@
}).insert()
return salary_account
-
-def get_earnings_component(setup=False):
- if setup:
- make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
-
- return [
- {
- "salary_component": 'Basic Salary',
- "abbr":'BS',
- "condition": 'base > 10000',
- "formula": 'base*.5',
- "idx": 1
- },
- {
+def make_earning_salary_component(setup=False, test_tax=False):
+ data = [
+ {
+ "salary_component": 'Basic Salary',
+ "abbr":'BS',
+ "condition": 'base > 10000',
+ "formula": 'base*.5',
+ "type": "Earning"
+ },
+ {
+ "salary_component": 'HRA',
+ "abbr":'H',
+ "amount": 3000,
+ "type": "Earning"
+ },
+ {
+ "salary_component": 'Special Allowance',
+ "abbr":'SA',
+ "condition": 'H < 10000',
+ "formula": 'BS*.5',
+ "type": "Earning"
+ },
+ {
+ "salary_component": "Leave Encashment",
+ "abbr": 'LE',
+ "is_additional_component": 1,
+ "type": "Earning"
+ }
+ ]
+ if setup or test_tax:
+ make_salary_component(data, test_tax)
+ data.append({
"salary_component": 'Basic Salary',
"abbr":'BS',
"condition": 'base < 10000',
"formula": 'base*.2',
- "idx": 2
- },
- {
- "salary_component": 'HRA',
- "abbr":'H',
- "amount": 3000,
- "idx": 3
- },
- {
- "salary_component": 'Special Allowance',
- "abbr":'SA',
- "condition": 'H < 10000',
- "formula": 'BS*.5',
- "idx": 4
- },
- ]
+ "type": "Earning"
+ })
+ return data
-def get_deductions_component(setup=False):
- if setup:
- make_deduction_salary_component(["Professional Tax", "TDS"])
-
- return [
+def make_deduction_salary_component(setup=False, test_tax=False):
+ data = [
{
"salary_component": 'Professional Tax',
"abbr":'PT',
"condition": 'base > 10000',
"formula": 'base*.1',
- "idx": 1
+ "type": "Deduction"
},
{
"salary_component": 'TDS',
"abbr":'T',
"formula": 'base*.1',
- "idx": 2
- },
- {
- "salary_component": 'TDS',
- "abbr":'T',
- "condition": 'employment_type=="Intern"',
- "formula": 'base*.1',
- "idx": 3
+ "type": "Deduction"
}
]
+ if not test_tax:
+ data.append({
+ "salary_component": 'TDS',
+ "abbr":'T',
+ "condition": 'employment_type=="Intern"',
+ "formula": 'base*.1',
+ "type": "Deduction"
+ })
+ if setup or test_tax:
+ make_salary_component(data, test_tax)
+
+ return data
+
+def create_exemption_declaration(employee, payroll_period):
+ create_exemption_category()
+ declaration = frappe.get_doc({"doctype": "Employee Tax Exemption Declaration",
+ "employee": employee,
+ "payroll_period": payroll_period,
+ "company": erpnext.get_default_company()})
+ declaration.append("declarations", {"exemption_sub_category": "_Test Sub Category",
+ "exemption_category": "_Test Category",
+ "amount": 100000})
+ declaration.submit()
+
+def create_proof_submission(employee, payroll_period, amount):
+ submission_date = add_months(payroll_period.start_date, random.randint(0, 11))
+ proof_submission = frappe.get_doc({"doctype": "Employee Tax Exemption Proof Submission",
+ "employee": employee,
+ "payroll_period": payroll_period.name,
+ "submission_date": submission_date})
+ proof_submission.append("tax_exemption_proofs", {"exemption_sub_category": "_Test Sub Category",
+ "exemption_category": "_Test Category", "type_of_proof": "Test",
+ "amount": amount})
+ proof_submission.submit()
+ return submission_date
+
+def create_tax_slab(payroll_period):
+ data = [{
+ "from_amount": 250000,
+ "to_amount": 500000,
+ "percent_deduction": 5
+ },
+ {
+ "from_amount": 500000,
+ "to_amount": 1000000,
+ "percent_deduction": 20
+ },
+ {
+ "from_amount": 1000000,
+ "percent_deduction": 30
+ }]
+ payroll_period.taxable_salary_slabs = []
+ for item in data:
+ payroll_period.append("taxable_salary_slabs", item)
+ payroll_period.save()
+
+def create_salary_slips_for_payroll_period(employee, salary_structure, payroll_period, deduct_random=False):
+ deducted_dates = []
+ i = 0
+ while i < 12:
+ slip = frappe.get_doc({"doctype": "Salary Slip", "employee": employee,
+ "salary_structure": salary_structure, "frequency": "Monthly"})
+ if i == 0:
+ posting_date = add_days(payroll_period.start_date, 25)
+ else:
+ posting_date = add_months(posting_date, 1)
+ if i == 11:
+ slip.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
+ slip.deduct_tax_for_unclaimed_employee_benefits = 1
+ if deduct_random and not random.randint(0, 2):
+ slip.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
+ deducted_dates.append(posting_date)
+ slip.posting_date = posting_date
+ slip.start_date = get_first_day(posting_date)
+ slip.end_date = get_last_day(posting_date)
+ doc = make_salary_slip(salary_structure, slip, employee)
+ doc.submit()
+ i += 1
+ return deducted_dates
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.py b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
index 78b16f2..1a16db7 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.py
@@ -8,8 +8,8 @@
from frappe.utils.make_random import get_random
from frappe.utils import nowdate, add_days, add_years, getdate, add_months
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
-from erpnext.hr.doctype.salary_slip.test_salary_slip import get_earnings_component,\
- get_deductions_component, make_employee_salary_slip
+from erpnext.hr.doctype.salary_slip.test_salary_slip import make_earning_salary_component,\
+ make_deduction_salary_component, make_employee_salary_slip
from erpnext.hr.doctype.employee.test_employee import make_employee
@@ -34,7 +34,7 @@
"from_date": nowdate(),
"to_date": add_years(nowdate(), 1),
"weekly_off": "Sunday"
- }).insert()
+ }).insert()
holiday_list.get_weekly_off_dates()
holiday_list.save()
@@ -72,14 +72,16 @@
self.assertFalse(("\n" in row.formula) or ("\n" in row.condition))
-def make_salary_structure(salary_structure, payroll_frequency, employee=None, dont_submit=False, other_details=None):
+def make_salary_structure(salary_structure, payroll_frequency, employee=None, dont_submit=False, other_details=None, test_tax=False):
+ if test_tax:
+ frappe.db.sql("""delete from `tabSalary Structure` where name=%s""",(salary_structure))
if not frappe.db.exists('Salary Structure', salary_structure):
details = {
"doctype": "Salary Structure",
"name": salary_structure,
"company": erpnext.get_default_company(),
- "earnings": get_earnings_component(),
- "deductions": get_deductions_component(),
+ "earnings": make_earning_salary_component(test_tax=test_tax),
+ "deductions": make_deduction_salary_component(test_tax=test_tax),
"payroll_frequency": payroll_frequency,
"payment_account": get_random("Account")
}
@@ -97,14 +99,16 @@
return salary_structure_doc
-def create_salary_structure_assignment(employee, salary_structure):
+def create_salary_structure_assignment(employee, salary_structure, from_date=None):
+ if frappe.db.exists("Salary Structure Assignment", {"employee": employee}):
+ frappe.db.sql("""delete from `tabSalary Structure Assignment` where employee=%s""",(employee))
salary_structure_assignment = frappe.new_doc("Salary Structure Assignment")
salary_structure_assignment.employee = employee
salary_structure_assignment.base = 50000
salary_structure_assignment.variable = 5000
- salary_structure_assignment.from_date = add_months(nowdate(), -1)
+ salary_structure_assignment.from_date = from_date or add_months(nowdate(), -1)
salary_structure_assignment.salary_structure = salary_structure
salary_structure_assignment.company = erpnext.get_default_company()
salary_structure_assignment.save(ignore_permissions=True)
salary_structure_assignment.submit()
- return salary_structure_assignment
\ No newline at end of file
+ return salary_structure_assignment
diff --git a/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.py b/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.py
index 210f75d..cf09066 100644
--- a/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.py
+++ b/erpnext/hr/doctype/salary_structure_assignment/salary_structure_assignment.py
@@ -38,7 +38,7 @@
select salary_structure from `tabSalary Structure Assignment`
where employee=%(employee)s
and docstatus = 1
- and %(on_date)s > from_date order by from_date desc limit 1""", {
+ and %(on_date)s >= from_date order by from_date desc limit 1""", {
'employee': employee,
'on_date': on_date,
})
diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
index 7d80817..ed44d63 100644
--- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
+++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
@@ -24,6 +24,7 @@
]
for leave_type in leave_types:
+ columns.append(_(leave_type) + " " + _("Opening") + ":Float:160")
columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
@@ -32,6 +33,7 @@
def get_data(filters, leave_types):
user = frappe.session.user
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
+ allocation_records_based_on_from_date = get_leave_allocation_records(filters.from_date)
active_employees = frappe.get_all("Employee",
filters = { "status": "Active", "company": filters.company},
@@ -47,12 +49,16 @@
# leaves taken
leaves_taken = get_approved_leaves_for_period(employee.name, leave_type,
filters.from_date, filters.to_date)
-
+
+ # opening balance
+ opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
+ allocation_records_based_on_from_date.get(employee.name, frappe._dict()))
+
# closing balance
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
- row += [leaves_taken, closing]
+ row += [opening, leaves_taken, closing]
data.append(row)
diff --git a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.js b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.js
index b1678db..348c5e7 100644
--- a/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.js
+++ b/erpnext/hr/report/monthly_attendance_sheet/monthly_attendance_sheet.js
@@ -38,7 +38,7 @@
return frappe.call({
method: "erpnext.hr.report.monthly_attendance_sheet.monthly_attendance_sheet.get_attendance_years",
callback: function(r) {
- var year_filter = frappe.query_report_filters_by_name.year;
+ var year_filter = frappe.query_report.get_filter('year');
year_filter.df.options = r.message;
year_filter.df.default = r.message.split("\n")[0];
year_filter.refresh();
diff --git a/erpnext/hr/report/salary_register/salary_register.html b/erpnext/hr/report/salary_register/salary_register.html
index 74ecff9..a322bd4 100644
--- a/erpnext/hr/report/salary_register/salary_register.html
+++ b/erpnext/hr/report/salary_register/salary_register.html
@@ -1,3 +1,6 @@
+{%
+ var report_columns = report.get_columns_for_print();
+%}
<div style="margin-bottom: 7px;" class="text-center">
{%= frappe.boot.letter_heads[filters.letter_head || frappe.defaults.get_default("letter_head")] %}
</div>
@@ -7,8 +10,8 @@
<table class="table table-bordered">
<thead>
<tr>
- {% for(var i=1, l=report.columns.length; i<l; i++) { %}
- <th class="text-right">{%= report.columns[i].label %}</th>
+ {% for(var i=1, l=report_columns.length; i<l; i++) { %}
+ <th class="text-right">{%= report_columns[i].label %}</th>
{% } %}
</tr>
</thead>
@@ -18,10 +21,10 @@
var row = data[j];
%}
<tr>
- {% for(var i=1, l=report.columns.length; i<l; i++) { %}
+ {% for(var i=1, l=report_columns.length; i<l; i++) { %}
<td class="text-right">
- {% var fieldname = report.columns[i].field; %}
- {% if (report.columns[i].fieldtype=='Currency' && !isNaN(row[fieldname])) { %}
+ {% var fieldname = report_columns[i].field; %}
+ {% if (report_columns[i].fieldtype=='Currency' && !isNaN(row[fieldname])) { %}
{%= format_currency(row[fieldname]) %}
{% } else { %}
{% if (!is_null(row[fieldname])) { %}
diff --git a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.js b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.js
index 486d259..b66bebb 100644
--- a/erpnext/hr/report/vehicle_expenses/vehicle_expenses.js
+++ b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.js
@@ -17,9 +17,11 @@
}
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
- frappe.query_report_filters_by_name.from_date.set_input(fy.year_start_date);
- frappe.query_report_filters_by_name.to_date.set_input(fy.year_end_date);
- query_report.trigger_refresh();
+
+ frappe.query_report.set_filter({
+ from_date: fy.year_start_date,
+ to_date: fy.year_end_date
+ });
});
}
}
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index 29e0048..1214191 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -14,6 +14,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -45,6 +46,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -77,6 +79,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -112,6 +115,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -145,6 +149,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -180,6 +185,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -212,6 +218,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -243,6 +250,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -274,6 +282,41 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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,
+ "oldfieldname": "company",
+ "oldfieldtype": "Link",
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 1,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -307,6 +350,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -341,6 +385,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -376,7 +421,8 @@
},
{
"allow_bulk_edit": 0,
- "allow_on_submit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@@ -408,6 +454,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -441,6 +488,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -473,6 +521,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -504,6 +553,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -535,6 +585,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -568,6 +619,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -597,6 +649,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -629,6 +682,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -660,6 +714,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -692,6 +747,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -724,7 +780,8 @@
},
{
"allow_bulk_edit": 0,
- "allow_on_submit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@@ -756,6 +813,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -787,6 +845,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -817,6 +876,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -848,6 +908,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -879,7 +940,8 @@
},
{
"allow_bulk_edit": 0,
- "allow_on_submit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
@@ -910,6 +972,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -943,6 +1006,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -976,6 +1040,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1009,6 +1074,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1041,6 +1107,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1073,6 +1140,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1105,6 +1173,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1135,6 +1204,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1167,6 +1237,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1198,6 +1269,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1228,6 +1300,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1262,39 +1335,7 @@
},
{
"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,
- "oldfieldname": "company",
- "oldfieldtype": "Link",
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 1,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1325,6 +1366,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1358,6 +1400,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1389,6 +1432,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1420,6 +1464,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1452,6 +1497,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1483,6 +1529,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1515,6 +1562,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1558,7 +1606,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-04-30 12:49:21.211740",
+ "modified": "2018-07-19 11:08:32.198681",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order",
@@ -1610,5 +1658,6 @@
"sort_order": "ASC",
"title_field": "production_item",
"track_changes": 1,
- "track_seen": 1
+ "track_seen": 1,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.js b/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.js
index 97ba7b9..c6ecaef 100644
--- a/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.js
+++ b/erpnext/manufacturing/report/bom_variance_report/bom_variance_report.js
@@ -16,7 +16,7 @@
"fieldtype": "Link",
"options": "Work Order",
"get_query": function() {
- var bom_no = frappe.query_report_filters_by_name.bom_no.get_value();
+ var bom_no = frappe.query_report.get_filter_value('bom_no');
return{
query: "erpnext.manufacturing.report.bom_variance_report.bom_variance_report.get_work_orders",
filters: {
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index a7fc349..20def27 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -267,7 +267,6 @@
erpnext.patches.v6_27.fix_recurring_order_status
erpnext.patches.v6_20x.update_product_bundle_description
erpnext.patches.v7_0.update_party_status #2016-09-22
-erpnext.patches.v7_0.update_item_projected
erpnext.patches.v7_0.remove_features_setup
erpnext.patches.v7_0.update_home_page
execute:frappe.delete_doc_if_exists("Page", "financial-analytics")
@@ -525,7 +524,6 @@
erpnext.patches.v10_0.taxes_issue_with_pos
erpnext.patches.v11_0.update_account_type_in_party_type
erpnext.patches.v10_1.transfer_subscription_to_auto_repeat
-erpnext.patches.v10_1.drop_old_subscription_records
erpnext.patches.v11_0.update_brand_in_item_price
erpnext.patches.v11_0.create_default_success_action
erpnext.patches.v11_0.add_healthcare_service_unit_tree_root
@@ -555,4 +553,9 @@
erpnext.patches.v11_0.set_salary_component_properties
erpnext.patches.v11_0.set_user_permissions_for_department
erpnext.patches.v11_0.hr_ux_cleanups
-erpnext.patches.v11_0.update_allow_transfer_for_manufacture
\ No newline at end of file
+erpnext.patches.v11_0.skip_user_permission_check_for_department
+erpnext.patches.v11_0.set_department_for_doctypes
+erpnext.patches.v11_0.update_allow_transfer_for_manufacture
+erpnext.patches.v11_0.rename_healthcare_doctype_and_fields
+erpnext.patches.v11_0.add_item_group_defaults
+erpnext.patches.v10_0.update_address_template_for_india
diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field.py b/erpnext/patches/v10_0/added_extra_gst_custom_field.py
index a1512ed..98b1820 100644
--- a/erpnext/patches/v10_0/added_extra_gst_custom_field.py
+++ b/erpnext/patches/v10_0/added_extra_gst_custom_field.py
@@ -6,4 +6,4 @@
if not company:
return
- make_custom_fields()
\ No newline at end of file
+ make_custom_fields(update=False)
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py b/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py
index 7b65a65..12aa5fd 100644
--- a/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py
+++ b/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py
@@ -10,12 +10,12 @@
frappe.db.sql("""delete from `tabCustom Field` where dt = %s
and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""", doctype)
- make_custom_fields()
+ make_custom_fields(update=False)
frappe.db.sql("""
update `tabCustom Field`
set reqd = 0, `default` = ''
where fieldname = 'reason_for_issuing_document'
""")
-
-
+
+
diff --git a/erpnext/patches/v10_0/update_address_template_for_india.py b/erpnext/patches/v10_0/update_address_template_for_india.py
new file mode 100644
index 0000000..5897b43
--- /dev/null
+++ b/erpnext/patches/v10_0/update_address_template_for_india.py
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from erpnext.regional.india.setup import update_address_template
+
+def execute():
+ if frappe.db.get_value('Company', {'country': 'India'}, 'name'):
+ address_template = frappe.db.get_value('Address Template', 'India', 'template')
+ if not address_template or "gstin" not in address_template:
+ update_address_template()
diff --git a/erpnext/patches/v10_1/drop_old_subscription_records.py b/erpnext/patches/v10_1/drop_old_subscription_records.py
deleted file mode 100644
index 7573f15..0000000
--- a/erpnext/patches/v10_1/drop_old_subscription_records.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-
-
-def execute():
- frappe.db.sql('DELETE from `tabSubscription`')
diff --git a/erpnext/patches/v10_1/transfer_subscription_to_auto_repeat.py b/erpnext/patches/v10_1/transfer_subscription_to_auto_repeat.py
index a9078e3..5c18985 100644
--- a/erpnext/patches/v10_1/transfer_subscription_to_auto_repeat.py
+++ b/erpnext/patches/v10_1/transfer_subscription_to_auto_repeat.py
@@ -4,25 +4,21 @@
def execute():
- to_rename = ['Purchase Order', 'Journal Entry', 'Sales Invoice', 'Payment Entry',
- 'Delivery Note', 'Purchase Invoice', 'Quotation', 'Sales Order',
- 'Purchase Receipt', 'Supplier Quotation']
-
- frappe.reload_doc('accounts', 'doctype', 'sales_invoice')
- frappe.reload_doc('accounts', 'doctype', 'purchase_invoice')
- frappe.reload_doc('accounts', 'doctype', 'payment_entry')
- frappe.reload_doc('accounts', 'doctype', 'journal_entry')
- frappe.reload_doc('buying', 'doctype', 'purchase_order')
- frappe.reload_doc('buying', 'doctype', 'supplier_quotation')
frappe.reload_doc('desk', 'doctype', 'auto_repeat')
- frappe.reload_doc('selling', 'doctype', 'quotation')
- frappe.reload_doc('selling', 'doctype', 'sales_order')
- frappe.reload_doc('stock', 'doctype', 'purchase_receipt')
- frappe.reload_doc('stock', 'doctype', 'delivery_note')
- for doctype in to_rename:
- if frappe.db.has_column(doctype, 'subscription'):
- rename_field(doctype, 'subscription', 'auto_repeat')
+ doctypes_to_rename = {
+ 'accounts': ['Journal Entry', 'Payment Entry', 'Purchase Invoice', 'Sales Invoice'],
+ 'buying': ['Purchase Order', 'Supplier Quotation'],
+ 'selling': ['Quotation', 'Sales Order'],
+ 'stock': ['Delivery Note', 'Purchase Receipt']
+ }
+
+ for module, doctypes in doctypes_to_rename.items():
+ for doctype in doctypes:
+ frappe.reload_doc(module, 'doctype', frappe.scrub(doctype))
+
+ if frappe.db.has_column(doctype, 'subscription'):
+ rename_field(doctype, 'subscription', 'auto_repeat')
subscriptions = frappe.db.sql('select * from `tabSubscription`', as_dict=1)
@@ -30,3 +26,19 @@
doc['doctype'] = 'Auto Repeat'
auto_repeat = frappe.get_doc(doc)
auto_repeat.db_insert()
+
+ frappe.db.sql('delete from `tabSubscription`')
+ frappe.db.commit()
+ drop_columns_from_subscription()
+
+def drop_columns_from_subscription():
+ fields_to_drop = {'Subscription': []}
+ for field in ['naming_series', 'reference_doctype', 'reference_document', 'start_date',
+ 'end_date', 'submit_on_creation', 'disabled', 'frequency', 'repeat_on_day',
+ 'next_schedule_date', 'notify_by_email', 'subject', 'recipients', 'print_format',
+ 'message', 'status', 'amended_from']:
+
+ if field in frappe.db.get_table_columns("Subscription"):
+ fields_to_drop['Subscription'].append(field)
+
+ frappe.model.delete_fields(fields_to_drop, delete=1)
\ No newline at end of file
diff --git a/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py b/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py
index 17368bf..0c4209a 100644
--- a/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py
+++ b/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py
@@ -4,10 +4,11 @@
def execute():
""" assign lft and rgt appropriately """
frappe.reload_doc("healthcare", "doctype", "healthcare_service_unit")
+ frappe.reload_doc("healthcare", "doctype", "healthcare_service_unit_type")
- if not frappe.db.exists("Healthcare Service Unit", _('All Healthcare Service Unit')):
+ if not frappe.db.exists("Healthcare Service Unit", _('All Healthcare Service Units')):
frappe.get_doc({
'doctype': 'Healthcare Service Unit',
- 'healthcare_service_unit_name': _('All Healthcare Service Unit'),
+ 'healthcare_service_unit_name': _('All Healthcare Service Units'),
'is_group': 1
}).insert(ignore_permissions=True)
diff --git a/erpnext/patches/v11_0/add_item_group_defaults.py b/erpnext/patches/v11_0/add_item_group_defaults.py
new file mode 100644
index 0000000..2a15ad1
--- /dev/null
+++ b/erpnext/patches/v11_0/add_item_group_defaults.py
@@ -0,0 +1,73 @@
+# Copyright (c) 2018, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ '''
+
+ Fields to move from item group to item defaults child table
+ [ default_cost_center, default_expense_account, default_income_account ]
+
+ '''
+
+ frappe.reload_doc('stock', 'doctype', 'item_default')
+ frappe.reload_doc('setup', 'doctype', 'item_group')
+
+ companies = frappe.get_all("Company")
+ item_groups = frappe.db.sql("""select name, default_income_account, default_expense_account,\
+ default_cost_center from `tabItem Group`""", as_dict=True)
+
+ if len(companies) == 1:
+ for item_group in item_groups:
+ doc = frappe.get_doc("Item Group", item_group.get("name"))
+ item_group_defaults = []
+ item_group_defaults.append({
+ "company": companies[0].name,
+ "income_account": item_group.get("default_income_account"),
+ "expense_account": item_group.get("default_expense_account"),
+ "buying_cost_center": item_group.get("default_cost_center"),
+ "selling_cost_center": item_group.get("default_cost_center")
+ })
+ doc.extend("item_group_defaults", item_group_defaults)
+ for child_doc in doc.item_group_defaults:
+ child_doc.db_insert()
+ else:
+ item_group_dict = {
+ "default_expense_account": ["expense_account"],
+ "default_income_account": ["income_account"],
+ "default_cost_center": ["buying_cost_center", "selling_cost_center"]
+ }
+ for item_group in item_groups:
+ item_group_defaults = []
+ def insert_into_item_defaults(doc_field_name, doc_field_value, company):
+ for d in item_group_defaults:
+ if d.get("company") == company:
+ d[doc_field_name[0]] = doc_field_value
+ if len(doc_field_name) > 1:
+ d[doc_field_name[1]] = doc_field_value
+ return
+
+ item_group_defaults.append({
+ "company": company,
+ doc_field_name[0]: doc_field_value
+ })
+
+ if(len(doc_field_name) > 1):
+ item_group_defaults[len(item_group_defaults)-1][doc_field_name[1]] = doc_field_value
+
+ for d in [
+ ["default_expense_account", "Account"], ["default_income_account", "Account"],
+ ["default_cost_center", "Cost Center"]
+ ]:
+ if item_group.get(d[0]):
+ company = frappe.get_value(d[1], item_group.get(d[0]), "company", cache=True)
+ doc_field_name = item_group_dict.get(d[0])
+
+ insert_into_item_defaults(doc_field_name, item_group.get(d[0]), company)
+
+ doc = frappe.get_doc("Item Group", item_group.get("name"))
+ doc.extend("item_group_defaults", item_group_defaults)
+ for child_doc in doc.item_group_defaults:
+ child_doc.db_insert()
diff --git a/erpnext/patches/v11_0/rename_healthcare_doctype_and_fields.py b/erpnext/patches/v11_0/rename_healthcare_doctype_and_fields.py
new file mode 100644
index 0000000..3a77f10
--- /dev/null
+++ b/erpnext/patches/v11_0/rename_healthcare_doctype_and_fields.py
@@ -0,0 +1,56 @@
+import frappe
+from frappe.model.rename_doc import rename_doc
+from frappe.model.utils.rename_field import rename_field
+from frappe.modules import scrub, get_doctype_module
+
+field_rename_map = {
+ "Patient Encounter": [
+ ["consultation_time", "encounter_time"],
+ ["consultation_date", "encounter_date"],
+ ["consultation_comment", "encounter_comment"],
+ ["physician", "practitioner"]
+ ],
+ "Fee Validity": [
+ ["physician", "practitioner"]
+ ],
+ "Lab Test": [
+ ["physician", "practitioner"]
+ ],
+ "Patient Appointment": [
+ ["physician", "practitioner"],
+ ["referring_physician", "referring_practitioner"]
+ ],
+ "Procedure Prescription": [
+ ["physician", "practitioner"]
+ ]
+}
+
+doc_rename_map = {
+ "Physician Schedule Time Slot": "Healthcare Schedule Time Slot",
+ "Physician Schedule": "Practitioner Schedule",
+ "Physician Service Unit Schedule": "Practitioner Service Unit Schedule",
+ "Consultation": "Patient Encounter",
+ "Physician": "Healthcare Practitioner"
+}
+
+def execute():
+ for dt in doc_rename_map:
+ if frappe.db.exists('DocType', dt):
+ rename_doc('DocType', dt, doc_rename_map[dt], force=True)
+
+ for dn in field_rename_map:
+ if frappe.db.exists('DocType', dn):
+ frappe.reload_doc(get_doctype_module(dn), "doctype", scrub(dn))
+
+ for dt, field_list in field_rename_map.items():
+ if frappe.db.exists('DocType', dt):
+ for field in field_list:
+ if frappe.db.has_column(dt, field[0]):
+ rename_field(dt, field[0], field[1])
+
+ if frappe.db.exists('DocType', 'Practitioner Service Unit Schedule'):
+ if frappe.db.has_column('Practitioner Service Unit Schedule', 'parentfield'):
+ frappe.db.sql("""
+ update `tabPractitioner Service Unit Schedule` set parentfield = 'practitioner_schedules'
+ where parentfield = 'physician_schedules' and parenttype = 'Healthcare Practitioner'
+ """)
diff --git a/erpnext/patches/v11_0/set_department_for_doctypes.py b/erpnext/patches/v11_0/set_department_for_doctypes.py
new file mode 100644
index 0000000..b1098ab
--- /dev/null
+++ b/erpnext/patches/v11_0/set_department_for_doctypes.py
@@ -0,0 +1,23 @@
+import frappe
+
+# Set department value based on employee value
+
+def execute():
+
+ doctypes_to_update = {
+ 'hr': ['Appraisal', 'Leave Allocation', 'Expense Claim', 'Salary Slip',
+ 'Attendance', 'Training Feedback', 'Training Result Employee','Leave Application',
+ 'Employee Advance', 'Training Event Employee', 'Payroll Employee Detail'],
+ 'education': ['Instructor'],
+ 'projects': ['Activity Cost', 'Timesheet'],
+ 'setup': ['Sales Person']
+ }
+
+ for module, doctypes in doctypes_to_update.items():
+ for doctype in doctypes:
+ if frappe.db.table_exists(doctype):
+ frappe.reload_doc(module, 'doctype', frappe.scrub(doctype))
+ frappe.db.sql("""
+ update `tab%s` dt
+ set department=(select department from `tabEmployee` where name=dt.employee)
+ """ % doctype)
diff --git a/erpnext/patches/v11_0/skip_user_permission_check_for_department.py b/erpnext/patches/v11_0/skip_user_permission_check_for_department.py
new file mode 100644
index 0000000..123eed5
--- /dev/null
+++ b/erpnext/patches/v11_0/skip_user_permission_check_for_department.py
@@ -0,0 +1,28 @@
+import frappe
+
+# Skips user permission check for doctypes where department link field was recently added
+# https://github.com/frappe/erpnext/pull/14121
+
+def execute():
+ user_permissions = frappe.get_all("User Permission",
+ filters=[['allow', '=', 'Department']],
+ fields=['name', 'skip_for_doctype'])
+
+ doctypes_to_skip = []
+
+ for doctype in ['Appraisal', 'Leave Allocation', 'Expense Claim', 'Instructor', 'Salary Slip',
+ 'Attendance', 'Training Feedback', 'Training Result Employee',
+ 'Leave Application', 'Employee Advance', 'Activity Cost', 'Training Event Employee',
+ 'Timesheet', 'Sales Person', 'Payroll Employee Detail']:
+ if frappe.db.exists('Custom Field', { 'dt': doctype, 'fieldname': 'department'}): continue
+ doctypes_to_skip.append(doctype)
+
+ for perm in user_permissions:
+ skip_for_doctype = perm.get('skip_for_doctype')
+
+ skip_for_doctype = skip_for_doctype.split('\n') + doctypes_to_skip
+ skip_for_doctype = set(skip_for_doctype) # to remove duplicates
+ skip_for_doctype = '\n'.join(skip_for_doctype) # convert back to string
+
+ frappe.set_value('User Permission', perm.name, 'skip_for_doctype', skip_for_doctype)
+
diff --git a/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py b/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py
index 5d76304..a5cf22c 100644
--- a/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py
+++ b/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py
@@ -9,7 +9,7 @@
def repost_bin_qty():
for bin in frappe.db.sql(""" select name from `tabBin`
- where (actual_qty + ordered_qty + indented_qty + planned_qty- reserved_qty - reserved_qty_for_production) != projected_qty """, as_dict=1):
+ where (actual_qty + ordered_qty + indented_qty + planned_qty - reserved_qty - reserved_qty_for_production - reserved_qty_for_sub_contract) != projected_qty """, as_dict=1):
bin_doc = frappe.get_doc('Bin', bin.name)
bin_doc.set_projected_qty()
bin_doc.db_set("projected_qty", bin_doc.projected_qty, update_modified = False)
diff --git a/erpnext/patches/v7_0/update_item_projected.py b/erpnext/patches/v7_0/update_item_projected.py
deleted file mode 100644
index 71b54af..0000000
--- a/erpnext/patches/v7_0/update_item_projected.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import frappe
-
-def execute():
- frappe.reload_doctype("Item")
- from erpnext.stock.doctype.bin.bin import update_item_projected_qty
- for item in frappe.get_all("Item", filters={"is_stock_item": 1}):
- update_item_projected_qty(item.name)
\ No newline at end of file
diff --git a/erpnext/patches/v8_7/add_more_gst_fields.py b/erpnext/patches/v8_7/add_more_gst_fields.py
index a1512ed..fc76a06 100644
--- a/erpnext/patches/v8_7/add_more_gst_fields.py
+++ b/erpnext/patches/v8_7/add_more_gst_fields.py
@@ -6,4 +6,6 @@
if not company:
return
+ frappe.reload_doc('hr', 'doctype', 'Employee Tax Exemption Declaration')
+ frappe.reload_doc('hr', 'doctype', 'Employee Tax Exemption Proof Submission')
make_custom_fields()
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index 1f274db..9f1c586 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -19,10 +19,10 @@
def setUp(self):
for dt in ["Salary Slip", "Salary Structure", "Salary Structure Assignment", "Timesheet"]:
frappe.db.sql("delete from `tab%s`" % dt)
-
- from erpnext.hr.doctype.salary_slip.test_salary_slip import make_earning_salary_component
- make_earning_salary_component(["Timesheet Component"])
-
+
+ if not frappe.db.exists("Salary Component", "Timesheet Component"):
+ frappe.get_doc({"doctype": "Salary Component", "salary_component": "Timesheet Component"}).insert()
+
def test_timesheet_billing_amount(self):
make_salary_structure_for_timesheet("_T-Employee-00001")
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 08f8d43..0997ef3 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -11,7 +11,7 @@
href="https://discuss.erpnext.com">Feedback</a></p>'
- $('.navbar-home').html('<img class="erpnext-icon" src="'+
+ $('.navbar-home').prepend('<img class="erpnext-icon" src="'+
frappe.urllib.get_base_url()+'/assets/erpnext/images/erp-icon.svg" />');
$('[data-link="docs"]').attr("href", "https://frappe.github.io/erpnext/")
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index a80ffa8..e420a48 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -226,62 +226,6 @@
tc_name: function() {
this.get_terms();
},
- link_to_mrs: function() {
- var my_items = [];
- for (var i in cur_frm.doc.items) {
- if(!cur_frm.doc.items[i].material_request){
- my_items.push(cur_frm.doc.items[i].item_code);
- }
- }
- frappe.call({
- method: "erpnext.buying.utils.get_linked_material_requests",
- args:{
- items: my_items
- },
- callback: function(r) {
- if(r.exc || !r.message) return;
-
- var i = 0;
- var item_length = cur_frm.doc.items.length;
- while (i < item_length) {
- var qty = cur_frm.doc.items[i].qty;
- (r.message[0] || []).forEach(function(d) {
- if (d.qty > 0 && qty > 0 && cur_frm.doc.items[i].item_code == d.item_code && !cur_frm.doc.items[i].material_request_item)
- {
- cur_frm.doc.items[i].material_request = d.mr_name;
- cur_frm.doc.items[i].material_request_item = d.mr_item;
- var my_qty = Math.min(qty, d.qty);
- qty = qty - my_qty;
- d.qty = d.qty - my_qty;
- cur_frm.doc.items[i].stock_qty = my_qty*cur_frm.doc.items[i].conversion_factor;
- cur_frm.doc.items[i].qty = my_qty;
-
- frappe.msgprint(__("Assigning {0} to {1} (row {2})",
- [d.mr_name, d.item_code, cur_frm.doc.items[i].idx]));
-
- if (qty > 0) {
- frappe.msgprint(__("Splitting {0} units of {1}", [qty, d.item_code]));
- var newrow = frappe.model.add_child(cur_frm.doc, cur_frm.doc.items[i].doctype, "items");
- item_length++;
-
- for (var key in cur_frm.doc.items[i]) {
- newrow[key] = cur_frm.doc.items[i][key];
- }
-
- newrow.idx = item_length;
- newrow["stock_qty"] = newrow.conversion_factor*qty;
- newrow["qty"] = qty;
- newrow["material_request"] = "";
- newrow["material_request_item"] = "";
- }
- }
- });
- i++;
- }
- refresh_field("items");
- }
- });
- },
update_auto_repeat_reference: function(doc) {
if (doc.auto_repeat) {
diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js
index cf1f1e9..1b8e079 100644
--- a/erpnext/public/js/controllers/stock_controller.js
+++ b/erpnext/public/js/controllers/stock_controller.js
@@ -73,7 +73,7 @@
from_date: me.frm.doc.posting_date,
to_date: me.frm.doc.posting_date,
company: me.frm.doc.company,
- group_by_voucher: false
+ group_by: ""
};
frappe.set_route("query-report", "General Ledger");
}, __("View"));
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 7e31c57..2fcdbb4 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -2,20 +2,22 @@
erpnext.financial_statements = {
"filters": get_filters(),
- "formatter": function(row, cell, value, columnDef, dataContext, default_formatter) {
- if (columnDef.df.fieldname=="account") {
- value = dataContext.account_name;
+ "formatter": function(value, row, column, data, default_formatter) {
+ if (column.fieldname=="account") {
+ value = data.account_name;
- columnDef.df.link_onclick =
- "erpnext.financial_statements.open_general_ledger(" + JSON.stringify(dataContext) + ")";
- columnDef.df.is_tree = true;
+ column.link_onclick =
+ "erpnext.financial_statements.open_general_ledger(" + JSON.stringify(data) + ")";
+ column.is_tree = true;
}
- value = default_formatter(row, cell, value, columnDef, dataContext);
+ value = default_formatter(value, row, column, data);
- if (!dataContext.parent_account) {
+ if (!data.parent_account) {
+ value = $(`<span>${value}</span>`);
+
var $value = $(value).css("font-weight", "bold");
- if (dataContext.warn_if_negative && dataContext[columnDef.df.fieldname] < 0) {
+ if (data.warn_if_negative && data[column.fieldname] < 0) {
$value.addClass("text-danger");
}
@@ -30,7 +32,7 @@
frappe.route_options = {
"account": data.account,
- "company": frappe.query_report_filters_by_name.company.get_value(),
+ "company": frappe.query_report.get_filter_value('company'),
"from_date": data.from_date || data.year_start_date,
"to_date": data.to_date || data.year_end_date,
"project": (project && project.length > 0) ? project[0].$input.val() : ""
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 630e029..c95d0cf 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -81,7 +81,7 @@
frappe.db.sql(""" update `tabPrint Format` set disabled = 0 where
name in('GST POS Invoice', 'GST Tax Invoice') """)
-def make_custom_fields():
+def make_custom_fields(update=True):
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description',
allow_on_submit=1, print_hide=1)
@@ -241,7 +241,7 @@
]
}
- create_custom_fields(custom_fields, ignore_validate = frappe.flags.in_patch)
+ create_custom_fields(custom_fields, ignore_validate = frappe.flags.in_patch, update=update)
def make_fixtures(company=None):
docs = []
@@ -271,7 +271,7 @@
def set_tax_withholding_category(docs, company):
accounts = []
- tds_account = frappe.db.get_value("Account", filter={"account_type": "Payable",
+ tds_account = frappe.db.get_value("Account", filters={"account_type": "Payable",
"account_name": "TDS", "company": company})
if company and tds_account:
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 6c007cd..2912ab9 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -142,6 +142,7 @@
hra_amt = earning.amount
if basic_amt and hra_amt:
return basic_amt, hra_amt
+ return basic_amt, hra_amt
def calculate_hra_exemption(salary_structure, basic, monthly_hra, monthly_house_rent, rented_in_metro_city):
# TODO make this configurable
diff --git a/erpnext/regional/report/gstr_1/gstr_1.js b/erpnext/regional/report/gstr_1/gstr_1.js
index b2c8aed..9246aa6 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.js
+++ b/erpnext/regional/report/gstr_1/gstr_1.js
@@ -17,7 +17,7 @@
"fieldtype": "Link",
"options": "Address",
"get_query": function() {
- var company = frappe.query_report_filters_by_name.company.get_value();
+ var company = frappe.query_report.get_filter_value('company');
if (company) {
return {
"query": 'frappe.contacts.doctype.address.address.address_query',
diff --git a/erpnext/regional/report/gstr_2/gstr_2.py b/erpnext/regional/report/gstr_2/gstr_2.py
index 0a2e968..0605695 100644
--- a/erpnext/regional/report/gstr_2/gstr_2.py
+++ b/erpnext/regional/report/gstr_2/gstr_2.py
@@ -71,8 +71,6 @@
is_igst = True if d[1] in self.gst_accounts.igst_account else False
if is_igst and d[0] not in self.igst_invoices:
self.igst_invoices.append(d[0])
- if is_igst:
- break
def get_conditions(self):
conditions = ""
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 5499ab0..fe3bedf 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -77,6 +77,12 @@
}
},
+ loyalty_program: function(frm) {
+ if(frm.doc.loyalty_program) {
+ frm.set_value('loyalty_program_tier', null);
+ }
+ },
+
refresh: function(frm) {
if(frappe.defaults.get_default("cust_master_name")!="Naming Series") {
frm.toggle_display("naming_series", false);
diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json
index 5215854..b0a63df 100644
--- a/erpnext/selling/doctype/customer/customer.json
+++ b/erpnext/selling/doctype/customer/customer.json
@@ -1493,10 +1493,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1512,7 +1514,7 @@
"in_standard_filter": 0,
"label": "Loyalty Program",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"options": "Loyalty Program",
"permlevel": 0,
"precision": "",
@@ -1524,16 +1526,18 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "loyalty_program_tier",
- "fieldtype": "Read Only",
+ "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -1543,21 +1547,23 @@
"in_standard_filter": 0,
"label": "Loyalty Program Tier",
"length": 0,
- "no_copy": 0,
+ "no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1768,7 +1774,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-06-27 12:12:30.677834",
+ "modified": "2018-07-12 13:20:13.203294",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer",
@@ -1955,5 +1961,6 @@
"sort_order": "ASC",
"title_field": "customer_name",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 595180b..2c22543 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -62,6 +62,12 @@
self.set_loyalty_program()
self.check_customer_group_change()
+ # set loyalty program tier
+ if frappe.db.exists('Customer', self.name):
+ customer = frappe.get_doc('Customer', self.name)
+ if self.loyalty_program == customer.loyalty_program and not self.loyalty_program_tier:
+ self.loyalty_program_tier = customer.loyalty_program_tier
+
def check_customer_group_change(self):
frappe.flags.customer_group_changed = False
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index ccbb942..d3ca4f8 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -3163,7 +3163,7 @@
"istable": 0,
"max_attachments": 1,
"menu_index": 0,
- "modified": "2018-07-06 03:23:15.354674",
+ "modified": "2018-07-17 03:23:15.354674",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index ee6b1c7..3ec4a23 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -16,7 +16,7 @@
from frappe.desk.doctype.auto_repeat.auto_repeat import get_next_schedule_date
from erpnext.selling.doctype.customer.customer import check_credit_limit
from erpnext.stock.doctype.item.item import get_item_defaults
-
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@@ -377,16 +377,26 @@
return items
def on_recurring(self, reference_doc, auto_repeat_doc):
- self.set("delivery_date", get_next_schedule_date(reference_doc.delivery_date,
- auto_repeat_doc.frequency, cint(auto_repeat_doc.repeat_on_day)))
+
+ def _get_delivery_date(ref_doc_delivery_date, red_doc_transaction_date, transaction_date):
+ delivery_date = get_next_schedule_date(ref_doc_delivery_date,
+ auto_repeat_doc.frequency, cint(auto_repeat_doc.repeat_on_day))
+
+ if delivery_date <= transaction_date:
+ delivery_date_diff = frappe.utils.date_diff(ref_doc_delivery_date, red_doc_transaction_date)
+ delivery_date = frappe.utils.add_days(transaction_date, delivery_date_diff)
+
+ return delivery_date
+
+ self.set("delivery_date", _get_delivery_date(reference_doc.delivery_date,
+ reference_doc.transaction_date, self.transaction_date ))
for d in self.get("items"):
reference_delivery_date = frappe.db.get_value("Sales Order Item",
{"parent": reference_doc.name, "item_code": d.item_code, "idx": d.idx}, "delivery_date")
- d.set("delivery_date", get_next_schedule_date(reference_delivery_date,
- auto_repeat_doc.frequency, cint(auto_repeat_doc.repeat_on_day)))
-
+ d.set("delivery_date", _get_delivery_date(reference_delivery_date,
+ reference_doc.transaction_date, self.transaction_date))
def get_list_context(context=None):
from erpnext.controllers.website_list_for_contact import get_list_context
@@ -503,11 +513,12 @@
target.qty = flt(source.qty) - flt(source.delivered_qty)
item = get_item_defaults(target.item_code, source_parent.company)
+ item_group = get_item_group_defaults(target.item_code, source_parent.company)
if item:
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
or item.get("selling_cost_center") \
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or item_group.get("selling_cost_center")
target_doc = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
@@ -571,8 +582,9 @@
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center")
if not target.cost_center and target.item_code:
item = get_item_defaults(target.item_code, target.company)
+ item_group = get_item_group_defaults(target.item_code, target.company)
target.cost_center = item.get("selling_cost_center") \
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or item_group.get("selling_cost_center")
doclist = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index a3993b8..f2919fb 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -56,6 +56,21 @@
si1 = make_sales_invoice(so.name)
self.assertEqual(len(si1.get("items")), 0)
+ def test_so_billed_amount_against_return_entry(self):
+ from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_sales_return
+ so = make_sales_order(do_not_submit=True)
+ so.submit()
+
+ si = make_sales_invoice(so.name)
+ si.insert()
+ si.submit()
+
+ si1 = make_sales_return(si.name)
+ si1.update_billed_amount_in_sales_order = 1
+ si1.submit()
+ so.load_from_db()
+ self.assertEquals(so.per_billed, 0)
+
def test_make_sales_invoice_with_terms(self):
so = make_sales_order(do_not_submit=True)
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index d75bf61..da72dc5 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -511,6 +511,7 @@
if(!r.exc) {
if (!this.frm.doc.pos_profile) {
frappe.dom.unfreeze();
+ setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
frappe.throw(__("POS Profile is required to use Point-of-Sale"));
}
this.frm.script_manager.trigger("update_stock");
diff --git a/erpnext/selling/report/address_and_contacts/address_and_contacts.js b/erpnext/selling/report/address_and_contacts/address_and_contacts.js
index 383f18b..ef87586 100644
--- a/erpnext/selling/report/address_and_contacts/address_and_contacts.js
+++ b/erpnext/selling/report/address_and_contacts/address_and_contacts.js
@@ -23,7 +23,7 @@
"label": __("Party Name"),
"fieldtype": "Dynamic Link",
"get_options": function() {
- let party_type = frappe.query_report_filters_by_name.party_type.get_value();
+ let party_type = frappe.query_report.get_filter_value('party_type');
if(!party_type) {
frappe.throw(__("Please select Party Type first"));
}
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 430617f..85b10dd 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -374,7 +374,7 @@
path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(company_doc.country))
if os.path.exists(path.encode("utf-8")):
frappe.get_attr("erpnext.regional.{0}.setup.setup"
- .format(frappe.scrub(company_doc.country)))(company_doc)
+ .format(frappe.scrub(company_doc.country)))(company_doc, False)
def update_company_current_month_sales(company):
current_month_year = formatdate(today(), "MM-yyyy")
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index c55c7cb..df22231 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -14,6 +14,40 @@
]
}
}
+ frm.fields_dict["item_group_defaults"].grid.get_field("expense_account").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ query: "erpnext.controllers.queries.get_expense_account",
+ filters: { company: row.company }
+ }
+ }
+ frm.fields_dict["item_group_defaults"].grid.get_field("income_account").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ query: "erpnext.controllers.queries.get_income_account",
+ filters: { company: row.company }
+ }
+ }
+
+ frm.fields_dict["item_group_defaults"].grid.get_field("buying_cost_center").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ filters: {
+ "is_group": 0,
+ "company": row.company
+ }
+ }
+ }
+
+ frm.fields_dict["item_group_defaults"].grid.get_field("selling_cost_center").get_query = function(doc, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ return {
+ filters: {
+ "is_group": 0,
+ "company": row.company
+ }
+ }
+ }
},
refresh: function(frm) {
diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json
index 29486b2..0a16a29 100644
--- a/erpnext/setup/doctype/item_group/item_group.json
+++ b/erpnext/setup/doctype/item_group/item_group.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:item_group_name",
@@ -13,6 +14,8 @@
"editable_grid": 0,
"fields": [
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -38,9 +41,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -68,9 +74,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "unique": 0
+ "translatable": 0,
+ "unique": 1
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -100,9 +109,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -132,9 +144,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -159,15 +174,18 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "default_income_account",
- "fieldtype": "Link",
+ "fieldname": "defaults",
+ "fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -175,11 +193,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Default Income Account",
+ "label": "Defaults",
"length": 0,
"no_copy": 0,
- "options": "Account",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -188,15 +206,18 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "default_expense_account",
- "fieldtype": "Link",
+ "fieldname": "item_group_defaults",
+ "fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -204,11 +225,12 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Default Expense Account",
+ "label": "Item Group Defaults",
"length": 0,
"no_copy": 0,
- "options": "Account",
+ "options": "Item Default",
"permlevel": 0,
+ "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -217,38 +239,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_cost_center",
- "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 Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "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_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -274,9 +270,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -303,9 +302,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -333,9 +335,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 1
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -364,9 +369,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -394,9 +402,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -424,9 +435,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -454,9 +468,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -484,9 +501,12 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -516,21 +536,22 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
+ "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-sitemap",
"idx": 1,
"image_view": 0,
"in_create": 0,
-
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 3,
- "modified": "2017-02-20 13:24:59.364873",
+ "modified": "2018-07-11 16:07:56.050363",
"modified_by": "Administrator",
"module": "Setup",
"name": "Item Group",
@@ -539,7 +560,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -559,7 +579,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -579,7 +598,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -599,7 +617,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -619,7 +636,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -639,7 +655,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -665,5 +680,6 @@
"show_name_in_global_search": 1,
"sort_order": "DESC",
"track_changes": 0,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 230b740..d4f16be 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -173,3 +173,19 @@
item_group_name = frappe.db.get_value("Item Group", d.get('name'))
if item_group_name:
clear_cache(frappe.db.get_value('Item Group', item_group_name, 'route'))
+
+def get_item_group_defaults(item, company):
+ item_group = frappe.db.get_value("Item", item, "item_group")
+ item_group_defaults = frappe.db.sql('''
+ select
+ expense_account, income_account, buying_cost_center, default_warehouse,
+ selling_cost_center, default_supplier
+ from
+ `tabItem Default` where company = %s and parent = %s and parenttype = 'Item Group'
+ ''', (company, item_group), as_dict=1)
+
+ if item_group_defaults:
+ return item_group_defaults[0]
+ else:
+ return frappe.db.get_value("Item", item, ["name", "item_name", "description", "stock_uom",
+ "is_stock_item", "item_code", "item_group"], as_dict=1)
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/physician/test_physician.js b/erpnext/setup/doctype/item_group/test_item_group.js
similarity index 73%
rename from erpnext/healthcare/doctype/physician/test_physician.js
rename to erpnext/setup/doctype/item_group/test_item_group.js
index 43750ac..ea322e2 100644
--- a/erpnext/healthcare/doctype/physician/test_physician.js
+++ b/erpnext/setup/doctype/item_group/test_item_group.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Physician", function (assert) {
+QUnit.test("test: Item Group", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
- // insert a new Physician
- () => frappe.tests.make('Physician', [
+ // insert a new Item Group
+ () => frappe.tests.make('Item Group', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/setup/doctype/item_group/test_records.json b/erpnext/setup/doctype/item_group/test_records.json
index 74f4641..436535e 100644
--- a/erpnext/setup/doctype/item_group/test_records.json
+++ b/erpnext/setup/doctype/item_group/test_records.json
@@ -4,7 +4,11 @@
"is_group": 0,
"item_group_name": "_Test Item Group",
"parent_item_group": "All Item Groups",
- "default_cost_center": "_Test Cost Center 2 - _TC"
+ "item_group_defaults": [{
+ "company": "_Test Company",
+ "buying_cost_center": "_Test Cost Center 2 - _TC",
+ "selling_cost_center": "_Test Cost Center 2 - _TC"
+ }]
},
{
"doctype": "Item Group",
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 2d2a18b..54c5d17 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -34,7 +34,14 @@
if options:
prefixes = prefixes + "\n" + options
prefixes.replace("\n\n", "\n")
- prefixes = "\n".join(sorted(prefixes.split("\n")))
+ prefixes = prefixes.split("\n")
+
+ custom_prefixes = frappe.get_all('DocType', fields=["autoname"],
+ filters={"name": ('not in', doctypes), "autoname":('like', '%.#%'), 'module': ('not in', ['Core'])})
+ if custom_prefixes:
+ prefixes = prefixes + [d.autoname.rsplit('.', 1)[0] for d in custom_prefixes]
+
+ prefixes = "\n".join(sorted(prefixes))
return {
"transactions": "\n".join([''] + sorted(doctypes)),
diff --git a/erpnext/setup/doctype/sales_partner/test_sales_partner.py b/erpnext/setup/doctype/sales_partner/test_sales_partner.py
index a4ae807..4548a4e 100644
--- a/erpnext/setup/doctype/sales_partner/test_sales_partner.py
+++ b/erpnext/setup/doctype/sales_partner/test_sales_partner.py
@@ -4,4 +4,6 @@
import frappe
-test_records = frappe.get_test_records('Sales Partner')
\ No newline at end of file
+test_records = frappe.get_test_records('Sales Partner')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/setup/doctype/sales_person/test_sales_person.py b/erpnext/setup/doctype/sales_person/test_sales_person.py
index 10b5f7c..8313cb4 100644
--- a/erpnext/setup/doctype/sales_person/test_sales_person.py
+++ b/erpnext/setup/doctype/sales_person/test_sales_person.py
@@ -5,4 +5,6 @@
test_dependencies = ["Employee"]
import frappe
-test_records = frappe.get_test_records('Sales Person')
\ No newline at end of file
+test_records = frappe.get_test_records('Sales Person')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/setup/doctype/territory/test_territory.py b/erpnext/setup/doctype/territory/test_territory.py
index 5ec8e4a..efe00c5 100644
--- a/erpnext/setup/doctype/territory/test_territory.py
+++ b/erpnext/setup/doctype/territory/test_territory.py
@@ -4,4 +4,6 @@
import frappe
-test_records = frappe.get_test_records('Territory')
\ No newline at end of file
+test_records = frappe.get_test_records('Territory')
+
+test_ignore = ["Item Group"]
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index 250d377..d86ac5e 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -115,7 +115,7 @@
if not value:
import requests
- api_url = "https://exchangeratesapi.io/api/{0}".format(transaction_date)
+ api_url = "https://frankfurter.erpnext.org/{0}".format(transaction_date)
response = requests.get(api_url, params={
"base": from_currency,
"symbols": to_currency
diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py
index 49b770b..8e880dc 100644
--- a/erpnext/startup/notifications.py
+++ b/erpnext/startup/notifications.py
@@ -60,7 +60,7 @@
"Lab Test": {"docstatus": 0},
"Sample Collection": {"docstatus": 0},
"Patient Appointment": {"status": "Open"},
- "Consultation": {"docstatus": 0}
+ "Patient Encounter": {"docstatus": 0}
},
"targets": {
diff --git a/erpnext/startup/report_data_map.py b/erpnext/startup/report_data_map.py
index 5de7998..fec2dea 100644
--- a/erpnext/startup/report_data_map.py
+++ b/erpnext/startup/report_data_map.py
@@ -298,14 +298,14 @@
}
},
"Patient Appointment": {
- "columns": ["name", "appointment_type", "patient", "physician", "appointment_date", "department", "status", "company"],
+ "columns": ["name", "appointment_type", "patient", "practitioner", "appointment_date", "department", "status", "company"],
"order_by": "name",
"links": {
- "physician": ["Physician", "name"],
+ "practitioner": ["Healthcare Practitioner", "name"],
"appointment_type": ["Appointment Type", "name"]
}
},
- "Physician": {
+ "Healthcare Practitioner": {
"columns": ["name", "department"],
"order_by": "name",
"links": {
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 9d13657..8be489d 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -251,8 +251,8 @@
def get_batches(item_code, warehouse, qty=1, throw=False):
batches = frappe.db.sql(
- 'select batch_id, sum(actual_qty) as qty from `tabBatch` join `tabStock Ledger Entry` '
- 'on `tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no '
+ 'select batch_id, sum(actual_qty) as qty from `tabBatch` join `tabStock Ledger Entry` ignore index (item_code, warehouse) '
+ 'on `(tabBatch`.batch_id = `tabStock Ledger Entry`.batch_no )'
'where `tabStock Ledger Entry`.item_code = %s and `tabStock Ledger Entry`.warehouse = %s '
'and (`tabBatch`.expiry_date >= CURDATE() or `tabBatch`.expiry_date IS NULL)'
'group by batch_id '
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index ffcda03..5572baf 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -3881,7 +3881,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2018-07-06 03:03:35.035396",
+ "modified": "2018-07-17 03:03:35.035396",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 3941cd9..37800fc 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -1830,7 +1830,7 @@
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 1,
+ "collapsible": 0,
"columns": 0,
"fieldname": "defaults",
"fieldtype": "Section Break",
@@ -3951,7 +3951,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 1,
- "modified": "2018-07-12 17:16:50.567598",
+ "modified": "2018-07-17 14:18:09.334205",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 5c35bec..7ef4f8c 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -17,7 +17,7 @@
from six import iteritems
test_ignore = ["BOM"]
-test_dependencies = ["Warehouse"]
+test_dependencies = ["Warehouse", "Item Group"]
def make_item(item_code, properties=None):
if frappe.db.exists("Item", item_code):
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 1f47317..51ccfcd 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -3436,7 +3436,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2018-07-06 02:59:59.609643",
+ "modified": "2018-07-17 02:59:59.609643",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 011df70..89f90bf 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -9,6 +9,7 @@
from erpnext.stock.utils import get_incoming_rate
from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError, get_valuation_rate
from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos, get_batch_qty
from erpnext.stock.doctype.item.item import get_item_defaults
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, add_additional_cost
@@ -579,7 +580,7 @@
pro_doc.run_method("update_planned_qty")
def get_item_details(self, args=None, for_update=False):
- item = frappe.db.sql("""select i.stock_uom, i.description, i.image, i.item_name, i.item_group,
+ item = frappe.db.sql("""select i.name, i.stock_uom, i.description, i.image, i.item_name, i.item_group,
i.has_batch_no, i.sample_quantity, i.has_serial_no,
id.expense_account, id.buying_cost_center
from `tabItem` i LEFT JOIN `tabItem Default` id ON i.name=id.parent and id.company=%s
@@ -592,6 +593,7 @@
frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get("item_code")))
item = item[0]
+ item_group_defaults = get_item_group_defaults(item.name, self.company)
ret = frappe._dict({
'uom' : item.stock_uom,
@@ -600,7 +602,7 @@
'image' : item.image,
'item_name' : item.item_name,
'expense_account' : args.get("expense_account"),
- 'cost_center' : get_default_cost_center(args, item),
+ 'cost_center' : get_default_cost_center(args, item, item_group_defaults),
'qty' : 0,
'transfer_qty' : 0,
'conversion_factor' : 1,
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 085e87f..3c60896 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -131,3 +131,5 @@
add index posting_sort_index(posting_date, posting_time, name)""")
frappe.db.add_index("Stock Ledger Entry", ["voucher_no", "voucher_type"])
+ frappe.db.add_index("Stock Ledger Entry", ["batch_no", "item_code", "warehouse"])
+
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 77f5f41..bd3577f 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -58,7 +58,7 @@
item.current_valuation_rate = rate
self.difference_amount += (flt(item.qty, item.precision("qty")) * \
flt(item.valuation_rate or rate, item.precision("valuation_rate")) \
- - flt(qty) * flt(rate))
+ - flt(qty, item.precision("qty")) * flt(rate, item.precision("valuation_rate")))
return True
items = filter(lambda d: _changed(d), self.items)
@@ -246,7 +246,9 @@
def set_total_qty_and_amount(self):
for d in self.get("items"):
d.amount = flt(d.qty, d.precision("qty")) * flt(d.valuation_rate, d.precision("valuation_rate"))
- d.current_amount = flt(d.current_qty) * flt(d.current_valuation_rate)
+ d.current_amount = (flt(d.current_qty,
+ d.precision("current_qty")) * flt(d.current_valuation_rate, d.precision("current_valuation_rate")))
+
d.quantity_difference = flt(d.qty) - flt(d.current_qty)
d.amount_difference = flt(d.amount) - flt(d.current_amount)
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 6d89187..f1afd1c 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -12,7 +12,7 @@
from erpnext.stock.doctype.batch.batch import get_batch_no
from erpnext import get_company_currency
from erpnext.stock.doctype.item.item import get_item_defaults
-
+from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from six import string_types, iteritems
@@ -208,7 +208,10 @@
if len(user_default_warehouse_list) == 1 else ""
item_defaults = get_item_defaults(item.name, args.company)
- warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or args.warehouse
+ item_group_defaults = get_item_group_defaults(item.name, args.company)
+
+ warehouse = user_default_warehouse or item_defaults.get("default_warehouse") or\
+ item_group_defaults.get("default_warehouse") or args.warehouse
material_request_type = ''
if args.get('doctype') == "Material Request" and not args.get('material_request_type'):
@@ -231,9 +234,9 @@
"description": cstr(item.description).strip(),
"image": cstr(item.image).strip(),
"warehouse": warehouse,
- "income_account": get_default_income_account(args, item_defaults),
- "expense_account": get_default_expense_account(args, item_defaults),
- "cost_center": get_default_cost_center(args, item_defaults),
+ "income_account": get_default_income_account(args, item_defaults, item_group_defaults),
+ "expense_account": get_default_expense_account(args, item_defaults, item_group_defaults),
+ "cost_center": get_default_cost_center(args, item_defaults, item_group_defaults),
'has_serial_no': item.has_serial_no,
'has_batch_no': item.has_batch_no,
"batch_no": None,
@@ -252,7 +255,7 @@
"net_rate": 0.0,
"net_amount": 0.0,
"discount_percentage": 0.0,
- "supplier": item_defaults.get("default_supplier"),
+ "supplier": get_default_supplier(args, item_defaults, item_group_defaults),
"update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
"delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
"is_fixed_asset": item.is_fixed_asset,
@@ -299,15 +302,15 @@
return out
-def get_default_income_account(args, item):
+def get_default_income_account(args, item, item_group):
return (item.get("income_account")
- or args.income_account
- or frappe.db.get_value("Item Group", item.item_group, "default_income_account"))
+ or item_group.get("income_account")
+ or args.income_account)
-def get_default_expense_account(args, item):
+def get_default_expense_account(args, item, item_group):
return (item.get("expense_account")
- or args.expense_account
- or frappe.db.get_value("Item Group", item.item_group, "default_expense_account"))
+ or item_group.get("expense_account")
+ or args.expense_account)
def get_default_deferred_revenue_account(args, item):
if item.enable_deferred_revenue:
@@ -317,12 +320,16 @@
else:
return None
-def get_default_cost_center(args, item):
+def get_default_cost_center(args, item, item_group):
return (frappe.db.get_value("Project", args.get("project"), "cost_center")
or (item.get("selling_cost_center") if args.get("customer") else item.get("buying_cost_center"))
- or frappe.db.get_value("Item Group", item.item_group, "default_cost_center")
+ or (item_group.get("selling_cost_center") if args.get("customer") else item_group.get("buying_cost_center"))
or args.get("cost_center"))
+def get_default_supplier(args, item, item_group):
+ return (item.get("default_supplier")
+ or item_group.get("default_supplier"))
+
def get_price_list_rate(args, item_doc, out):
meta = frappe.get_meta(args.parenttype or args.doctype)
@@ -686,10 +693,11 @@
def get_valuation_rate(item_code, company, warehouse=None):
item = get_item_defaults(item_code, company)
+ item_group = get_item_group_defaults(item_code, company)
# item = frappe.get_doc("Item", item_code)
if item.get("is_stock_item"):
if not warehouse:
- warehouse = item.get("default_warehouse")
+ warehouse = item.get("default_warehouse") or item_group.get("default_warehouse")
return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
["valuation_rate"], as_dict=True) or {"valuation_rate": 0}
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index 69abeeb..774803f 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -23,32 +23,33 @@
data = []
for (company, item, warehouse) in sorted(iwb_map):
- qty_dict = iwb_map[(company, item, warehouse)]
- item_reorder_level = 0
- item_reorder_qty = 0
- if item + warehouse in item_reorder_detail_map:
- item_reorder_level = item_reorder_detail_map[item + warehouse]["warehouse_reorder_level"]
- item_reorder_qty = item_reorder_detail_map[item + warehouse]["warehouse_reorder_qty"]
+ if item_map.get(item):
+ qty_dict = iwb_map[(company, item, warehouse)]
+ item_reorder_level = 0
+ item_reorder_qty = 0
+ if item + warehouse in item_reorder_detail_map:
+ item_reorder_level = item_reorder_detail_map[item + warehouse]["warehouse_reorder_level"]
+ item_reorder_qty = item_reorder_detail_map[item + warehouse]["warehouse_reorder_qty"]
- report_data = [item, item_map[item]["item_name"],
- item_map[item]["item_group"],
- item_map[item]["brand"],
- item_map[item]["description"], warehouse,
- item_map[item]["stock_uom"], qty_dict.opening_qty,
- qty_dict.opening_val, qty_dict.in_qty,
- qty_dict.in_val, qty_dict.out_qty,
- qty_dict.out_val, qty_dict.bal_qty,
- qty_dict.bal_val, qty_dict.val_rate,
- item_reorder_level,
- item_reorder_qty,
- company
- ]
+ report_data = [item, item_map[item]["item_name"],
+ item_map[item]["item_group"],
+ item_map[item]["brand"],
+ item_map[item]["description"], warehouse,
+ item_map[item]["stock_uom"], qty_dict.opening_qty,
+ qty_dict.opening_val, qty_dict.in_qty,
+ qty_dict.in_val, qty_dict.out_qty,
+ qty_dict.out_val, qty_dict.bal_qty,
+ qty_dict.bal_val, qty_dict.val_rate,
+ item_reorder_level,
+ item_reorder_qty,
+ company
+ ]
- if filters.get('show_variant_attributes', 0) == 1:
- variants_attributes = get_variants_attributes()
- report_data += [item_map[item].get(i) for i in variants_attributes]
+ if filters.get('show_variant_attributes', 0) == 1:
+ variants_attributes = get_variants_attributes()
+ report_data += [item_map[item].get(i) for i in variants_attributes]
- data.append(report_data)
+ data.append(report_data)
if filters.get('show_variant_attributes', 0) == 1:
columns += ["{}:Data:100".format(i) for i in get_variants_attributes()]
@@ -202,12 +203,12 @@
item_details = {}
if not items:
items = list(set([d.item_code for d in sle]))
-
+
if items:
for item in frappe.db.sql("""
select name, item_name, description, item_group, brand, stock_uom
from `tabItem`
- where name in ({0})
+ where name in ({0}) and ifnull(disabled, 0) = 0
""".format(', '.join(['"' + frappe.db.escape(i, percent=False) + '"' for i in items])), as_dict=1):
item_details.setdefault(item.name, item)
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 4eec3e0..153a4c1 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -110,10 +110,16 @@
def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20, order_by=None):
from frappe.www.list import get_list
user = frappe.session.user
+ contact = frappe.db.get_value('Contact', {'user': user}, 'name')
+ customer = None
+ if contact:
+ contact_doc = frappe.get_doc('Contact', contact)
+ customer = contact_doc.get_link_for('Customer')
+
ignore_permissions = False
if is_website_user():
if not filters: filters = []
- filters.append(("Issue", "raised_by", "=", user))
+ filters.append(("Issue", "customer", "=", customer)) if customer else filters.append(("Issue", "raised_by", "=", user))
ignore_permissions = True
return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=ignore_permissions)
@@ -145,7 +151,10 @@
set_status(name, status)
def has_website_permission(doc, ptype, user, verbose=False):
- return doc.raised_by==user
+ from erpnext.controllers.website_list_for_contact import has_website_permission
+ permission_based_on_customer = has_website_permission(doc, ptype, user, verbose)
+
+ return permission_based_on_customer or doc.raised_by==user
def update_issue(contact, method):
diff --git a/erpnext/support/web_form/issues/issues.json b/erpnext/support/web_form/issues/issues.json
index a8c7ab9..6d89d11 100644
--- a/erpnext/support/web_form/issues/issues.json
+++ b/erpnext/support/web_form/issues/issues.json
@@ -18,7 +18,7 @@
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
- "modified": "2018-05-07 05:54:22.213127",
+ "modified": "2018-07-20 13:08:43.797886",
"modified_by": "Administrator",
"module": "Support",
"name": "issues",
@@ -85,6 +85,18 @@
"reqd": 0
},
{
+ "default": "Medium",
+ "fieldname": "priority",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "label": "Priority",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "Low\nMedium\nHigh",
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
"default": "1",
"fieldname": "via_customer_portal",
"fieldtype": "Check",
diff --git a/erpnext/templates/includes/healthcare/appointment_row_template.html b/erpnext/templates/includes/healthcare/appointment_row_template.html
index 53be5e6..b369c2a 100644
--- a/erpnext/templates/includes/healthcare/appointment_row_template.html
+++ b/erpnext/templates/includes/healthcare/appointment_row_template.html
@@ -7,7 +7,7 @@
</span>
</div>
<div class="col-xs-3">
- {{ doc.physician }}
+ {{ doc.practitioner }}
</div>
<div class="col-xs-2">
{% if doc.department %}{{ doc.department }}{% endif %}
diff --git a/erpnext/templates/includes/healthcare/lab_test_row_template.html b/erpnext/templates/includes/healthcare/lab_test_row_template.html
index d6c9b54..b67f2bd 100644
--- a/erpnext/templates/includes/healthcare/lab_test_row_template.html
+++ b/erpnext/templates/includes/healthcare/lab_test_row_template.html
@@ -10,7 +10,7 @@
{{ doc.test_name }}
</div>
<div class="col-xs-3">
- {{ doc.physician }}
+ {{ doc.practitioner }}
</div>
<div class="col-xs-3 text-right small text-muted">
{{ frappe.format_date(doc.result_date) }}
diff --git a/erpnext/templates/includes/healthcare/prescription_row_template.html b/erpnext/templates/includes/healthcare/prescription_row_template.html
index 13ce3bc..22ef6e4 100644
--- a/erpnext/templates/includes/healthcare/prescription_row_template.html
+++ b/erpnext/templates/includes/healthcare/prescription_row_template.html
@@ -5,10 +5,10 @@
{{ doc.name }}
</div>
<div class="col-xs-4">
- {{ doc.physician }}
+ {{ doc.practitioner }}
</div>
<div class="col-xs-4 text-right small text-muted">
- {{ frappe.format_date(doc.consultation_date) }}
+ {{ frappe.format_date(doc.encounter_date) }}
</div>
</div>
</a>
diff --git a/erpnext/templates/includes/issue_row.html b/erpnext/templates/includes/issue_row.html
index eb5c0a4..637fde2 100644
--- a/erpnext/templates/includes/issue_row.html
+++ b/erpnext/templates/includes/issue_row.html
@@ -5,12 +5,29 @@
<span class="indicator {{ "red" if doc.status=="Open" else "darkgrey" }}">
{{ doc.name }}</span>
</div>
- <div class="col-xs-6 items-preview ellipsis ellipsis-width">
- {{ doc.subject }}</div>
-
+ <div class="col-xs-5 items-preview ellipsis ellipsis-width">
+ {{ doc.subject }}</div>
+ <div class="col-xs-2 text-muted">
+ <span class="indicator
+ {% if doc.status == "Open" %}
+ {% if doc.priority == "Medium" %}
+ orange"> Medium
+ {% elif doc.priority == "Low" %}
+ yellow"> Low
+ {% else %}
+ red"> High
+ {% endif %}
+ {% elif doc.status == "Closed" %}
+ green"> Closed
+ {% else %}
+ darkgrey"> {{ doc.status }}
+ {% endif %}
+ </span>
+ </div>
<div class="col-xs-3 text-right small text-muted">
{{ frappe.format_date(doc.modified) }}
</div>
</div>
</a>
</div>
+
\ No newline at end of file
diff --git a/erpnext/templates/pages/integrations/gocardless_checkout.html b/erpnext/templates/pages/integrations/gocardless_checkout.html
index eb124ca..bbe5640 100644
--- a/erpnext/templates/pages/integrations/gocardless_checkout.html
+++ b/erpnext/templates/pages/integrations/gocardless_checkout.html
@@ -13,4 +13,4 @@
<span class='gocardless-loading'>{{ _("Loading Payment System") }}</span>
</p>
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/integrations/gocardless_checkout.py b/erpnext/templates/pages/integrations/gocardless_checkout.py
index 3c2466e..2ba7001 100644
--- a/erpnext/templates/pages/integrations/gocardless_checkout.py
+++ b/erpnext/templates/pages/integrations/gocardless_checkout.py
@@ -73,4 +73,4 @@
except Exception as e:
frappe.log_error(e, "GoCardless Payment Error")
- return {"redirect_to": '/integrations/payment-failed'}
+ return {"redirect_to": '/integrations/payment-failed'}
\ No newline at end of file
diff --git a/erpnext/templates/pages/integrations/gocardless_confirmation.html b/erpnext/templates/pages/integrations/gocardless_confirmation.html
index 1baf23b..1567487 100644
--- a/erpnext/templates/pages/integrations/gocardless_confirmation.html
+++ b/erpnext/templates/pages/integrations/gocardless_confirmation.html
@@ -13,4 +13,4 @@
<span class='gocardless-loading'>{{ _("Payment Confirmation") }}</span>
</p>
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/integrations/gocardless_confirmation.py b/erpnext/templates/pages/integrations/gocardless_confirmation.py
index fc564c3..069d900 100644
--- a/erpnext/templates/pages/integrations/gocardless_confirmation.py
+++ b/erpnext/templates/pages/integrations/gocardless_confirmation.py
@@ -82,4 +82,4 @@
}).insert(ignore_permissions=True)
except Exception:
- frappe.log_error(frappe.get_traceback())
+ frappe.log_error(frappe.get_traceback())
\ No newline at end of file