fix merge conflict
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/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..e7371bd 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)
@@ -226,15 +244,19 @@
success_url = shopping_cart_settings.payment_success_url
if success_url:
redirect_to = ({
- "Orders": "orders",
- "Invoices": "invoices",
- "My Account": "me"
- }).get(success_url, "me")
+ "Orders": "/orders",
+ "Invoices": "/invoices",
+ "My Account": "/me"
+ }).get(success_url, "/me")
else:
redirect_to = get_url("/orders/{0}".format(self.reference_name))
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/accounts/doctype/payment_request/test_payment_request.js b/erpnext/accounts/doctype/payment_request/test_payment_request.js
new file mode 100644
index 0000000..070b595
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_request/test_payment_request.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Payment Request", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Payment Request
+ () => frappe.tests.make('Payment Request', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
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/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/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 0663228..5ba0bde 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -80,6 +80,7 @@
"label": __("Party"),
"fieldtype": "MultiSelect",
get_data: function() {
+ 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;
diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
index 33a2948..80b50b9 100644
--- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
+++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js
@@ -59,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");
}
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/config/healthcare.py b/erpnext/config/healthcare.py
index ae36f9c..e55f736 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -38,6 +38,11 @@
"type": "doctype",
"name": "Clinical Procedure",
"label": _("Clinical Procedure"),
+ },
+ {
+ "type": "doctype",
+ "name": "Inpatient Record",
+ "label": _("Inpatient Record"),
}
]
},
@@ -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/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/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py b/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py
index af15cf5..c65e3ce 100644
--- a/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py
+++ b/erpnext/erpnext_integrations/doctype/gocardless_settings/gocardless_settings.py
@@ -145,11 +145,11 @@
if self.flags.status_changed_to == "Completed":
status = 'Completed'
- if self.data.reference_doctype and self.data.reference_docname:
+ if 'reference_doctype' in self.data and 'reference_docname' in self.data:
custom_redirect_to = None
try:
- custom_redirect_to = frappe.get_doc(self.data.reference_doctype,
- self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to)
+ custom_redirect_to = frappe.get_doc(self.data.get('reference_doctype'),
+ self.data.get('reference_docname')).run_method("on_payment_authorized", self.flags.status_changed_to)
except Exception:
frappe.log_error(frappe.get_traceback())
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/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 dbb5b20..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",
@@ -417,4 +536,4 @@
"title_field": "healthcare_service_unit_name",
"track_changes": 1,
"track_seen": 0
-}
+}
\ No newline at end of file
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/hr/doctype/salary_structure_employee/__init__.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/__init__.py
similarity index 100%
copy from erpnext/hr/doctype/salary_structure_employee/__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/healthcare_service_unit_type/test_healthcare_service_unit_type.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js
new file mode 100644
index 0000000..6db8f9e
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Healthcare Service Unit Type", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Healthcare Service Unit Type
+ () => frappe.tests.make('Healthcare Service Unit Type', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
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/hr/doctype/salary_structure_employee/__init__.py b/erpnext/healthcare/doctype/inpatient_occupancy/__init__.py
similarity index 100%
rename from erpnext/hr/doctype/salary_structure_employee/__init__.py
rename to erpnext/healthcare/doctype/inpatient_occupancy/__init__.py
diff --git a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
new file mode 100644
index 0000000..2ac498d
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.json
@@ -0,0 +1,170 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-07-12 12:07:36.932333",
+ "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",
+ "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": "Healthcare Service Unit",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Healthcare Service Unit",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 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": "check_in",
+ "fieldtype": "Datetime",
+ "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": "Check In",
+ "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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "left",
+ "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": "Left",
+ "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
+ },
+ {
+ "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
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-07-17 18:26:46.009878",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Inpatient Occupancy",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py
new file mode 100644
index 0000000..52de25b
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_occupancy/inpatient_occupancy.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# 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 InpatientOccupancy(Document):
+ pass
diff --git a/erpnext/hr/doctype/salary_structure_employee/__init__.py b/erpnext/healthcare/doctype/inpatient_record/__init__.py
similarity index 100%
copy from erpnext/hr/doctype/salary_structure_employee/__init__.py
copy 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/inpatient_record/inpatient_record.json b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
new file mode 100644
index 0000000..2f9f1f1
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.json
@@ -0,0 +1,977 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "naming_series:",
+ "beta": 0,
+ "creation": "2018-07-11 17:48:51.404139",
+ "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": "section_break_1",
+ "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,
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "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": "Series",
+ "length": 0,
+ "no_copy": 0,
+ "options": "IP-",
+ "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": "patient",
+ "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": "Patient",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Patient",
+ "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,
+ "fetch_from": "patient.patient_name",
+ "fieldname": "patient_name",
+ "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": "Patient Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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.sex",
+ "fieldname": "gender",
+ "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": "Gender",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Gender",
+ "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.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": "Blood Group",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nA Positive\nA Negative\nAB Positive\nAB Negative\nB Positive\nB Negative\nO Positive\nO Negative",
+ "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": "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,
+ "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": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Admission Scheduled\nAdmitted\nDischarge Scheduled\nDischarged",
+ "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": "Today",
+ "fieldname": "scheduled_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": "Admission Schedule Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "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": "admitted_datetime",
+ "fieldtype": "Datetime",
+ "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": "Admitted Datetime",
+ "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": "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": "references",
+ "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": "References",
+ "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": "cb_admission",
+ "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": "Admission",
+ "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": "admission_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": "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
+ }
+ ],
+ "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-18 14:10:30.245833",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Inpatient Record",
+ "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,
+ "search_fields": "patient",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 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/inpatient_record/test_inpatient_record.js b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js
new file mode 100644
index 0000000..1ce9afa
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Inpatient Record", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Inpatient Record
+ () => frappe.tests.make('Inpatient Record', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
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..b192064
--- /dev/null
+++ b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.py
@@ -0,0 +1,107 @@
+# -*- 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):
+ frappe.db.sql("""delete from `tabInpatient Record`""")
+ 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)
+ frappe.db.sql("""delete from `tabInpatient Record`""")
+
+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.is_group = 0
+ service_unit_parent_name = frappe.db.exists({
+ "doctype": "Healthcare Service Unit",
+ "healthcare_service_unit_name": "All Healthcare Service Units",
+ "is_group": 1
+ })
+ if not service_unit_parent_name:
+ parent_service_unit = frappe.new_doc("Healthcare Service Unit")
+ parent_service_unit.healthcare_service_unit_name = "All Healthcare Service Units"
+ parent_service_unit.is_group = 1
+ parent_service_unit.save(ignore_permissions = True)
+ service_unit.parent_healthcare_service_unit = "All Healthcare Service Units"
+ 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.json b/erpnext/healthcare/doctype/lab_test/lab_test.json
index ae66325..0132c98 100644
--- a/erpnext/healthcare/doctype/lab_test/lab_test.json
+++ b/erpnext/healthcare/doctype/lab_test/lab_test.json
@@ -20,6 +20,40 @@
"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,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -86,6 +120,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -1481,7 +1516,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-07-16 12:47:01.425117",
+ "modified": "2018-07-17 12:47:01.425117",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Lab Test",
@@ -1557,4 +1592,4 @@
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
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_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index f5e59f2..23ec85d 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -97,6 +97,7 @@
},__("Create"));
}
}
+ frm.set_df_property("get_procedure_from_encounter", "read_only", frm.doc.__islocal ? 0 : 1);
},
check_availability: function(frm) {
var { practitioner, appointment_date } = frm.doc;
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index f88a1e0..b19e48e 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -20,6 +20,41 @@
"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,
@@ -877,7 +912,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-07-16 12:48:28.394133",
+ "modified": "2018-07-17 12:48:28.394133",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Appointment",
@@ -953,4 +988,4 @@
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index a9b45ac..47c9cad 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -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};
@@ -90,6 +111,34 @@
}
});
+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({
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index 1373503..292c900 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -20,6 +20,40 @@
"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,
"fieldname": "section_break_1",
"fieldtype": "Section Break",
"hidden": 0,
@@ -151,6 +185,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "inpatient_record.patient",
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
@@ -1070,7 +1105,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-07-16 12:51:13.487000",
+ "modified": "2018-07-17 12:51:13.487000",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Encounter",
@@ -1108,4 +1143,4 @@
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
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 761ae6d..8354859 100644
--- a/erpnext/healthcare/doctype/vital_signs/vital_signs.json
+++ b/erpnext/healthcare/doctype/vital_signs/vital_signs.json
@@ -19,6 +19,41 @@
"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,
@@ -932,7 +967,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-07-16 14:04:09.604470",
+ "modified": "2018-07-17 14:04:09.604470",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Vital Signs",
@@ -989,4 +1024,4 @@
"title_field": "patient",
"track_changes": 1,
"track_seen": 1
-}
\ No newline at end of file
+}
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/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/attendance/attendance.py b/erpnext/hr/doctype/attendance/attendance.py
index ad162c6..9f8cea8 100644
--- a/erpnext/hr/doctype/attendance/attendance.py
+++ b/erpnext/hr/doctype/attendance/attendance.py
@@ -32,7 +32,7 @@
else:
self.status = 'On Leave'
self.leave_type = d.leave_type
- frappe.msgprint(_("Employee {0} on Leave on {1}").format(self.employee, self.attendance_date))
+ frappe.msgprint(_("Employee {0} is on Leave on {1}").format(self.employee, self.attendance_date))
if self.status == "On Leave" and not leave_record:
frappe.throw(_("No leave record found for employee {0} for {1}").format(self.employee, self.attendance_date))
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/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index bc6ffc1..1f49310 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -131,24 +131,15 @@
elif getdate(self.to_date) <= getdate(nowdate()):
for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
date = dt.strftime("%Y-%m-%d")
- if not date == self.half_day_date:
- doc = frappe.new_doc("Attendance")
- doc.employee = self.employee
- doc.attendance_date = date
- doc.company = self.company
- doc.status = "On Leave"
- doc.leave_type = self.leave_type
- doc.insert(ignore_permissions=True)
- doc.submit()
- else:
- doc = frappe.new_doc("Attendance")
- doc.employee = self.employee
- doc.attendance_date = date
- doc.company = self.company
- doc.status = "Half Day"
- doc.leave_type = self.leave_type
- doc.insert(ignore_permissions=True)
- doc.submit()
+ doc = frappe.new_doc("Attendance")
+ doc.employee = self.employee
+ doc.attendance_date = date
+ doc.company = self.company
+ doc.leave_type = self.leave_type
+ doc.status = "Half Day" if date == self.half_day_date else "On Leave"
+ doc.flags.ignore_validate = True
+ doc.insert(ignore_permissions=True)
+ doc.submit()
def cancel_attendance(self):
if self.docstatus == 2:
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 23528af..5a91796 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -130,7 +130,6 @@
for d in self.get(key):
if d.salary_component == struct_row.salary_component:
component_row = d
-
if not component_row:
self.append(key, {
'amount': amount,
@@ -147,6 +146,7 @@
'tax_on_additional_salary': additional_tax
})
else:
+ component_row.default_amount = amount
component_row.amount = amount
component_row.tax_on_flexible_benefit = benefit_tax
component_row.tax_on_additional_salary = additional_tax
@@ -429,7 +429,7 @@
def calculate_net_pay(self):
if self.salary_structure:
self.calculate_component_amounts()
-
+
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
self.total_deduction = 0
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js
index 6b195a8..4a111e7 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -19,8 +19,7 @@
frm.set_query("salary_component", "earnings", function() {
return {
filters: {
- type: "earning",
- is_additional_component: 0
+ type: "earning"
}
}
});
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.json b/erpnext/hr/doctype/salary_structure/salary_structure.json
index 5480c0e..ce8b64e 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.json
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.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,
@@ -107,6 +110,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -141,6 +145,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -175,6 +180,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -208,6 +214,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -239,6 +246,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -271,6 +279,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -301,6 +310,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -335,6 +345,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -368,6 +379,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -399,6 +411,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -430,6 +443,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -465,6 +479,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -498,6 +513,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -532,6 +548,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -565,6 +582,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -598,6 +616,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -629,6 +648,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -659,6 +679,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -692,6 +713,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -725,6 +747,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -756,6 +779,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -787,6 +811,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -819,6 +844,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -849,6 +875,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -873,7 +900,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,
@@ -881,6 +908,7 @@
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -922,7 +950,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-04-14 16:05:11.002259",
+ "modified": "2018-07-24 18:36:25.169098",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Structure",
@@ -976,5 +1004,6 @@
"timeline_field": "",
"title_field": "",
"track_changes": 0,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py
index 48d67fc..9d972bd 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.py
@@ -8,13 +8,24 @@
from frappe import _
from frappe.model.mapper import get_mapped_doc
from frappe.model.document import Document
+from six import iteritems
class SalaryStructure(Document):
def validate(self):
+ self.set_missing_values()
self.validate_amount()
self.strip_condition_and_formula_fields()
self.validate_max_benefits_with_flexi()
+ def set_missing_values(self):
+ fields = ["depends_on_lwp", "variable_based_on_taxable_salary", "is_tax_applicable", "is_flexible_benefit"]
+ for table in ["earnings", "deductions"]:
+ for d in self.get(table):
+ component_default_value = frappe.db.get_value("Salary Component", str(d.salary_component), fields, as_dict=1)
+ for fieldname, value in iteritems(component_default_value):
+ if d.get(fieldname) != value:
+ d[fieldname] = value
+
def validate_amount(self):
if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet:
frappe.throw(_("Net pay cannot be negative"))
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/doctype/salary_structure_employee/salary_structure_employee.json b/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.json
deleted file mode 100644
index f2295ff..0000000
--- a/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.json
+++ /dev/null
@@ -1,233 +0,0 @@
-{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "employee",
- "beta": 0,
- "creation": "2016-07-26 11:53:43.621605",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
- "fields": [
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "employee",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Employee",
- "length": 0,
- "no_copy": 0,
- "options": "Employee",
- "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_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "employee.employee_name",
- "fieldname": "employee_name",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Employee Name",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "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_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "from_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "From Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "to_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "To Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "base",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Base",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "variable",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Variable",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "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": 1,
- "max_attachments": 0,
- "modified": "2018-05-16 22:43:05.329951",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Salary Structure Employee",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.py b/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.py
deleted file mode 100644
index dfcac3f..0000000
--- a/erpnext/hr/doctype/salary_structure_employee/salary_structure_employee.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.model.document import Document
-
-class SalaryStructureEmployee(Document):
- pass
diff --git a/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json b/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
index cb4003a..9f299df 100644
--- a/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
+++ b/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
@@ -1,4 +1,5 @@
{
+ "align_labels_right": 0,
"creation": "2016-07-07 11:45:14.872204",
"custom_format": 0,
"disabled": 0,
@@ -6,13 +7,16 @@
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
- "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \" <h3 style=\\\"text-align: right;\\\"><span style=\\\"line-height: 1.42857;\\\">{{doc.name}}</span></h3>\\n<div>\\n <hr style=\\\"text-align: center;\\\">\\n</div> \"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_days\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]",
+ "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \" <h3 style=\\\"text-align: right;\\\"><span style=\\\"line-height: 1.42857;\\\">{{doc.name}}</span></h3>\\n<div>\\n <hr style=\\\"text-align: center;\\\">\\n</div> \"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\", \"label\": \"Employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\", \"label\": \"Employee Name\"}, {\"print_hide\": 0, \"fieldname\": \"department\", \"label\": \"Department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\", \"label\": \"Designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\", \"label\": \"Branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\", \"label\": \"Start Date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\", \"label\": \"End Date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_days\", \"label\": \"Working Days\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\", \"label\": \"Leave Without Pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\", \"label\": \"Payment Days\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\", \"label\": \"Earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\", \"label\": \"Deductions\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\", \"label\": \"Gross Pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\", \"label\": \"Total Deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\", \"label\": \"Net Pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\", \"label\": \"Total in words\"}]",
"idx": 0,
- "modified": "2016-08-22 00:21:42.600548",
+ "line_breaks": 0,
+ "modified": "2018-07-24 19:31:39.040701",
"modified_by": "Administrator",
+ "module": "HR",
"name": "Salary Slip Standard",
"owner": "Administrator",
"print_format_builder": 1,
"print_format_type": "Server",
+ "show_section_headings": 0,
"standard": "Yes"
}
\ 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/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index d289b82..6acad06 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -133,8 +133,8 @@
task.flags.ignore_recursion_check = True
task.save()
- def has_webform_permission(doc):
- project_user = frappe.db.get_value("Project User", {"parent": doc.project, "user":frappe.session.user} , "user")
+ def has_webform_permission(self):
+ project_user = frappe.db.get_value("Project User", {"parent": self.project, "user":frappe.session.user} , "user")
if project_user:
return True
diff --git a/erpnext/projects/web_form/tasks/tasks.json b/erpnext/projects/web_form/tasks/tasks.json
index 98a2055..c646210 100644
--- a/erpnext/projects/web_form/tasks/tasks.json
+++ b/erpnext/projects/web_form/tasks/tasks.json
@@ -1,23 +1,33 @@
{
+ "accept_payment": 0,
"allow_comments": 1,
"allow_delete": 1,
"allow_edit": 1,
+ "allow_incomplete": 0,
"allow_multiple": 1,
+ "allow_print": 0,
+ "amount": 0.0,
+ "amount_based_on_field": 0,
"breadcrumbs": "[{\"title\":\"Tasks\", \"name\":\"tasks\"}]",
"creation": "2016-06-24 15:50:33.091287",
"doc_type": "Task",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
+ "introduction_text": "",
"is_standard": 1,
"login_required": 1,
- "modified": "2016-08-06 11:59:21.494549",
+ "max_attachment_size": 0,
+ "modified": "2018-07-24 11:32:07.805956",
"modified_by": "Administrator",
"module": "Projects",
"name": "tasks",
"owner": "Administrator",
+ "payment_button_label": "Buy Now",
"published": 1,
"route": "tasks",
+ "show_sidebar": 1,
+ "sidebar_items": [],
"success_url": "",
"title": "Task",
"web_form_fields": [
@@ -26,6 +36,8 @@
"fieldtype": "Link",
"hidden": 0,
"label": "Project",
+ "max_length": 0,
+ "max_value": 0,
"options": "Project",
"read_only": 1,
"reqd": 1
@@ -35,6 +47,8 @@
"fieldtype": "Data",
"hidden": 0,
"label": "Subject",
+ "max_length": 0,
+ "max_value": 0,
"read_only": 0,
"reqd": 1
},
@@ -43,15 +57,19 @@
"fieldtype": "Select",
"hidden": 0,
"label": "Status",
- "options": "Open\nClosed\nCancelled",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "Open\nWorking\nPending Review\nOverdue\nClosed\nCancelled",
"read_only": 0,
"reqd": 0
},
{
"fieldname": "description",
- "fieldtype": "Text",
+ "fieldtype": "Text Editor",
"hidden": 0,
"label": "Details",
+ "max_length": 0,
+ "max_value": 0,
"read_only": 0,
"reqd": 0
},
@@ -60,6 +78,8 @@
"fieldtype": "Select",
"hidden": 0,
"label": "Priority",
+ "max_length": 0,
+ "max_value": 0,
"options": "Low\nMedium\nHigh\nUrgent",
"read_only": 0,
"reqd": 0
@@ -69,6 +89,8 @@
"fieldtype": "Date",
"hidden": 0,
"label": "Expected Start Date",
+ "max_length": 0,
+ "max_value": 0,
"read_only": 0,
"reqd": 0
},
@@ -77,6 +99,8 @@
"fieldtype": "Date",
"hidden": 0,
"label": "Expected End Date",
+ "max_length": 0,
+ "max_value": 0,
"read_only": 0,
"reqd": 0
}
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index b7bb77e..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");
}
diff --git a/erpnext/public/js/hub/hub_factory.js b/erpnext/public/js/hub/hub_factory.js
index 21f3e8d..f933600 100644
--- a/erpnext/public/js/hub/hub_factory.js
+++ b/erpnext/public/js/hub/hub_factory.js
@@ -29,4 +29,4 @@
<a href="#marketplace/home">${__('Marketplace')}
</li>
`)
-})
\ No newline at end of file
+})
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index cd0bc9a..7bb09e9 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -249,7 +249,6 @@
set_salary_components(docs)
set_tds_account(docs, company)
- set_tax_withholding_category(docs, company)
for d in docs:
try:
@@ -259,6 +258,9 @@
except frappe.NameError:
pass
+ # create tds fixtures
+ set_tax_withholding_category(company)
+
def set_salary_components(docs):
docs.extend([
{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'type': 'Deduction'},
@@ -269,31 +271,33 @@
{'doctype': 'Salary Component', 'salary_component': 'Leave Encashment', 'description': 'Leave Encashment', 'type': 'Earning'}
])
-def set_tax_withholding_category(docs, company):
+def set_tax_withholding_category(company):
accounts = []
- tds_account = frappe.db.get_value("Account", filter={"account_type": "Payable",
- "account_name": "TDS", "company": company})
+ abbr = frappe.get_value("Company", company, "abbr")
+ tds_account = frappe.get_value("Account", 'TDS Payable - {0}'.format(abbr), 'name')
if company and tds_account:
- accounts = [
- {
- 'company': company,
- 'account': tds_account
- }
- ]
+ accounts = [dict(company=company, account=tds_account)]
- docs.extend([
- {
- 'doctype': 'Tax Withholding Category', '__newname': 'TDS',
- 'percent_of_tax_withheld': 10,'threshold': 150000, 'book_on_invoice': 1,
- 'withhold_cumulative_tax_amount': 0, 'accounts': accounts
- }
- ])
+ tds = frappe.get_doc({
+ 'doctype': 'Tax Withholding Category', 'name': 'TDS',
+ 'percent_of_tax_withheld': 10,'threshold': 150000, 'book_on_invoice': 1,
+ 'withhold_cumulative_tax_amount': 0, 'accounts': accounts
+ })
+
+ try:
+ tds.flags.ignore_permissions = True
+ tds.insert()
+ except frappe.DuplicateEntryError:
+ tds = frappe.get_doc("Tax Withholding Category", tds.get("name"))
+ tds.append("accounts", accounts[0])
+ tds.save()
def set_tds_account(docs, company):
+ abbr = frappe.get_value("Company", company, "abbr")
docs.extend([
{
- 'doctype': 'Account', 'account_name': 'TDS', 'account_type': 'Tax',
- 'parent_account': 'Duties and Taxes', 'company': company
+ "doctype": "Account", "account_name": "TDS Payable", "account_type": "Tax",
+ "parent_account": "Duties and Taxes - {0}".format(abbr), "company": company
}
])
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/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index 9d13657..ef0a317 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/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/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 77c59f4..72a226e 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -1,9 +1,9 @@
frappe.ui.form.on("Issue", {
- "onload": function(frm) {
+ onload: function(frm) {
frm.email_field = "raised_by";
},
- "refresh": function(frm) {
+ refresh: function(frm) {
if(frm.doc.status!=="Closed") {
frm.add_custom_button(__("Close"), function() {
frm.set_value("status", "Closed");
@@ -33,5 +33,39 @@
frappe.set_route('Form', 'Help Article', doc.name);
});
}
+
+ if (!frm.timeline.wrapper.find('.btn-split-issue').length) {
+ let split_issue = __("Split Issue")
+ $(`<button class="btn btn-xs btn-link btn-add-to-kb text-muted hidden-xs btn-split-issue pull-right" style="display:inline-block; margin-right: 5px">
+ ${split_issue}
+ </button>`)
+ .appendTo(frm.timeline.wrapper.find('.comment-header .asset-details:not([data-communication-type="Comment"])'))
+ if (!frm.timeline.wrapper.data("split-issue-event-attached")){
+ frm.timeline.wrapper.on('click', '.btn-split-issue', (e) => {
+ var dialog = new frappe.ui.Dialog({
+ title: __("Split Issue"),
+ fields: [
+ {fieldname: 'subject', fieldtype: 'Data', reqd:1, label: __('Subject'), description: __('All communications including and above this shall be moved into the new Issue')}
+ ],
+ primary_action_label: __("Split"),
+ primary_action: function() {
+ frm.call("split_issue", {
+ subject: dialog.fields_dict.subject.value,
+ communication_id: e.currentTarget.closest(".timeline-item").getAttribute("data-name")
+ }, (r) => {
+ let url = window.location.href
+ let arr = url.split("/");
+ let result = arr[0] + "//" + arr[2]
+ frappe.msgprint(`New issue created: <a href="${result}/desk#Form/Issue/${r.message}">${r.message}</a>`)
+ frm.reload_doc();
+ dialog.hide();
+ });
+ }
+ });
+ dialog.show()
+ })
+ frm.timeline.wrapper.data("split-issue-event-attached", true)
+ }
+ }
}
});
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index c7b5e06..153a4c1 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -81,6 +81,22 @@
self.db_set("description", "")
+ def split_issue(self, subject, communication_id):
+ # Bug: Pressing enter doesn't send subject
+ from copy import deepcopy
+ replicated_issue = deepcopy(self)
+ replicated_issue.subject = subject
+ frappe.get_doc(replicated_issue).insert()
+ # Replicate linked Communications
+ # todo get all communications in timeline before this, and modify them to append them to new doc
+ comm_to_split_from = frappe.get_doc("Communication", communication_id)
+ communications = frappe.get_all("Communication", filters={"reference_name": 'ISS-00001', "reference_doctype": "Issue", "creation": ('>=', comm_to_split_from.creation)})
+ for communication in communications:
+ doc = frappe.get_doc("Communication", communication.name)
+ doc.reference_name = replicated_issue.name
+ doc.save()
+ return replicated_issue.name
+
def get_list_context(context=None):
return {
"title": _("Issues"),
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/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..7193d75 100644
--- a/erpnext/templates/pages/integrations/gocardless_checkout.html
+++ b/erpnext/templates/pages/integrations/gocardless_checkout.html
@@ -9,8 +9,8 @@
{% endblock %}
{%- block page_content -%}
-<p class='lead text-center centered'>
+<p class='lead text-center'>
<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..6ba154a 100644
--- a/erpnext/templates/pages/integrations/gocardless_confirmation.html
+++ b/erpnext/templates/pages/integrations/gocardless_confirmation.html
@@ -9,8 +9,8 @@
{% endblock %}
{%- block page_content -%}
-<p class='lead text-center centered'>
+<p class='lead text-center'>
<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..697ed3c 100644
--- a/erpnext/templates/pages/integrations/gocardless_confirmation.py
+++ b/erpnext/templates/pages/integrations/gocardless_confirmation.py
@@ -36,10 +36,15 @@
"session_token": frappe.session.user
})
+ confirmation_url = redirect_flow.confirmation_url
+ gocardless_success_page = frappe.get_hooks('gocardless_success_page')
+ if gocardless_success_page:
+ confirmation_url = frappe.get_attr(gocardless_success_page[-1])(reference_doctype, reference_docname)
+
data = {
"mandate": redirect_flow.links.mandate,
"customer": redirect_flow.links.customer,
- "redirect_to": redirect_flow.confirmation_url,
+ "redirect_to": confirmation_url,
"redirect_message": "Mandate successfully created",
"reference_doctype": reference_doctype,
"reference_docname": reference_docname
@@ -53,7 +58,7 @@
gateway_controller = get_gateway_controller(reference_docname)
frappe.get_doc("GoCardless Settings", gateway_controller).create_payment_request(data)
- return {"redirect_to": redirect_flow.confirmation_url}
+ return {"redirect_to": confirmation_url}
except Exception as e:
frappe.log_error(e, "GoCardless Payment Error")
@@ -82,4 +87,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