Merge branch 'develop' of https://github.com/frappe/erpnext into stock_ageing_fix
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
index aea6080..40a97ae 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js
@@ -78,7 +78,6 @@
var create_import_button = function(frm) {
frm.page.set_primary_action(__("Start Import"), function () {
- setup_progress_bar(frm);
frappe.call({
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
args: {
@@ -86,11 +85,11 @@
company: frm.doc.company
},
freeze: true,
+ freeze_message: __("Creating Accounts..."),
callback: function(r) {
if(!r.exc) {
clearInterval(frm.page["interval"]);
frm.page.set_indicator(__('Import Successfull'), 'blue');
- frappe.hide_progress();
create_reset_button(frm);
}
}
@@ -126,13 +125,3 @@
}
});
};
-
-var setup_progress_bar = function(frm) {
- frm.page["seconds_elapsed"] = 0;
- frm.page["execution_time"] = (frm.page["total_accounts"] > 100) ? 100 : frm.page["total_accounts"];
-
- frm.page["interval"] = setInterval(function() {
- frm.page["seconds_elapsed"] += 1;
- frappe.show_progress(__('Creating Accounts'), frm.page["seconds_elapsed"], frm.page["execution_time"]);
- }, 250);
-};
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index 76efa48..4683c7a 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -33,6 +33,9 @@
def generate_data_from_csv(file_name, as_dict=False):
''' read csv file and return the generated nested tree '''
+ if not file_name.endswith('.csv'):
+ frappe.throw("Only CSV files can be used to for importing data. Please check the file format you are trying to upload")
+
file_doc = frappe.get_doc('File', {"file_url": file_name})
file_path = file_doc.get_full_path()
@@ -96,15 +99,27 @@
return [child] + return_parent(data, parent_account)
charts_map, paths = {}, []
+
+ line_no = 3
+ error_messages = []
+
for i in data:
account_name, _, account_number, is_group, account_type, root_type = i
+
+ if not account_name:
+ error_messages.append("Row {0}: Please enter Account Name".format(line_no))
+
charts_map[account_name] = {}
- if is_group: charts_map[account_name]["is_group"] = is_group
+ if is_group == 1: charts_map[account_name]["is_group"] = is_group
if account_type: charts_map[account_name]["account_type"] = account_type
if root_type: charts_map[account_name]["root_type"] = root_type
if account_number: charts_map[account_name]["account_number"] = account_number
path = return_parent(data, account_name)[::-1]
paths.append(path) # List of path is created
+ line_no += 1
+
+ if error_messages:
+ frappe.throw("<br>".join(error_messages))
out = {}
for path in paths:
@@ -150,22 +165,27 @@
if len(roots) < 4:
return _("Number of root accounts cannot be less than 4")
+ error_messages = []
+
for account in roots:
- if not account.get("root_type"):
- return _("Please enter Root Type for - {0}").format(account.get("account_name"))
- elif account.get("root_type") not in ("Asset", "Liability", "Expense", "Income", "Equity"):
- return _('Root Type for "{0}" must be one of the Asset, Liability, Income, Expense and Equity').format(account.get("account_name"))
+ if not account.get("root_type") and account.get("account_name"):
+ error_messages.append("Please enter Root Type for account- {0}".format(account.get("account_name")))
+ elif account.get("root_type") not in ("Asset", "Liability", "Expense", "Income", "Equity") and account.get("account_name"):
+ error_messages.append("Root Type for {0} must be one of the Asset, Liability, Income, Expense and Equity".format(account.get("account_name")))
+
+ if error_messages:
+ return "<br>".join(error_messages)
def validate_account_types(accounts):
account_types_for_ledger = ["Cost of Goods Sold", "Depreciation", "Fixed Asset", "Payable", "Receivable", "Stock Adjustment"]
- account_types = [accounts[d]["account_type"] for d in accounts if not accounts[d]['is_group']]
+ account_types = [accounts[d]["account_type"] for d in accounts if not accounts[d]['is_group'] == 1]
missing = list(set(account_types_for_ledger) - set(account_types))
if missing:
return _("Please identify/create Account (Ledger) for type - {0}").format(' , '.join(missing))
account_types_for_group = ["Bank", "Cash", "Stock"]
- account_groups = [accounts[d]["account_type"] for d in accounts if accounts[d]['is_group']]
+ account_groups = [accounts[d]["account_type"] for d in accounts if accounts[d]['is_group'] not in ('', 1)]
missing = list(set(account_types_for_group) - set(account_groups))
if missing:
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
index dad75b4..0d5456e 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
@@ -21,9 +21,29 @@
refresh: function(frm) {
if(frm.doc.docstatus==1) {
- frm.add_custom_button(__('Create Journal Entry'), function() {
- return frm.events.make_jv(frm);
- });
+ frappe.db.get_value("Journal Entry Account", {
+ 'reference_type': 'Exchange Rate Revaluation',
+ 'reference_name': frm.doc.name,
+ 'docstatus': 1
+ }, "sum(debit) as sum", (r) =>{
+ let total_amt = 0;
+ frm.doc.accounts.forEach(d=> {
+ total_amt = total_amt + d['new_balance_in_base_currency'];
+ });
+ if(total_amt === r.sum) {
+ frm.add_custom_button(__("Journal Entry"), function(){
+ frappe.route_options = {
+ 'reference_type': 'Exchange Rate Revaluation',
+ 'reference_name': frm.doc.name
+ };
+ frappe.set_route("List", "Journal Entry");
+ }, __("View"));
+ } else {
+ frm.add_custom_button(__('Create Journal Entry'), function() {
+ return frm.events.make_jv(frm);
+ });
+ }
+ }, 'Journal Entry');
}
},
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 07494a2..c3c3e26 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -187,9 +187,13 @@
method: "erpnext.selling.doctype.quotation.quotation.make_sales_invoice",
source_doctype: "Quotation",
target: me.frm,
- setters: {
- customer: me.frm.doc.customer || undefined,
- },
+ setters: [{
+ fieldtype: 'Link',
+ label: __('Customer'),
+ options: 'Customer',
+ fieldname: 'party_name',
+ default: me.frm.doc.customer,
+ }],
get_query_filters: {
docstatus: 1,
status: ["!=", "Lost"],
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js
index 0422111..03940f4 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.js
+++ b/erpnext/accounts/report/cash_flow/cash_flow.js
@@ -8,17 +8,19 @@
// The last item in the array is the definition for Presentation Currency
// filter. It won't be used in cash flow for now so we pop it. Please take
// of this if you are working here.
- frappe.query_reports["Cash Flow"]["filters"].pop();
- frappe.query_reports["Cash Flow"]["filters"].push({
- "fieldname": "accumulated_values",
- "label": __("Accumulated Values"),
- "fieldtype": "Check"
- });
+ frappe.query_reports["Cash Flow"]["filters"].splice(5, 1);
- frappe.query_reports["Cash Flow"]["filters"].push({
- "fieldname": "include_default_book_entries",
- "label": __("Include Default Book Entries"),
- "fieldtype": "Check"
- });
+ frappe.query_reports["Cash Flow"]["filters"].push(
+ {
+ "fieldname": "accumulated_values",
+ "label": __("Accumulated Values"),
+ "fieldtype": "Check"
+ },
+ {
+ "fieldname": "include_default_book_entries",
+ "label": __("Include Default Book Entries"),
+ "fieldtype": "Check"
+ }
+ );
});
\ No newline at end of file
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index 75d99e7..cd3d8dc 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -69,7 +69,9 @@
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency)
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
- return columns, data
+ chart = get_chart_data(columns, data)
+
+ return columns, data, None, chart
def get_cash_flow_accounts():
operation_accounts = {
@@ -171,4 +173,21 @@
total_row["total"] += row["total"]
out.append(total_row)
- out.append({})
\ No newline at end of file
+ out.append({})
+
+def get_chart_data(columns, data):
+ labels = [d.get("label") for d in columns[2:]]
+ datasets = [{'name':account.get('account').replace("'", ""), 'values': [account.get('total')]} for account in data if account.get('parent_account') == None and account.get('currency')]
+ datasets = datasets[:-1]
+
+ chart = {
+ "data": {
+ 'labels': labels,
+ 'datasets': datasets
+ },
+ "type": "bar"
+ }
+
+ chart["fieldtype"] = "Currency"
+
+ return chart
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
index 48d7361..ac11868 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
@@ -93,4 +93,6 @@
else:
chart["type"] = "line"
+ chart["fieldtype"] = "Currency"
+
return chart
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index dead1f0..5dce349 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -66,10 +66,11 @@
"net_total",
"total_net_weight",
"taxes_section",
- "taxes_and_charges",
+ "tax_category",
"column_break_50",
"shipping_rule",
"section_break_52",
+ "taxes_and_charges",
"taxes",
"sec_tax_breakup",
"other_charges_calculation",
@@ -569,7 +570,7 @@
{
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
- "label": "Taxes and Charges",
+ "label": "Purchase Taxes and Charges Template",
"oldfieldname": "purchase_other_charges",
"oldfieldtype": "Link",
"options": "Purchase Taxes and Charges Template",
@@ -1032,12 +1033,18 @@
"fieldname": "update_auto_repeat_reference",
"fieldtype": "Button",
"label": "Update Auto Repeat Reference"
+ },
+ {
+ "fieldname": "tax_category",
+ "fieldtype": "Link",
+ "label": "Tax Category",
+ "options": "Tax Category"
}
],
"icon": "fa fa-file-text",
"idx": 105,
"is_submittable": 1,
- "modified": "2019-06-24 21:22:05.483429",
+ "modified": "2019-07-11 18:25:49.509343",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py
index 1311111..756d22e 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -26,8 +26,8 @@
},
{
"type": "page",
- "name": "medical_record",
- "label": _("Patient Medical Record"),
+ "name": "patient_history",
+ "label": _("Patient History"),
},
{
"type": "page",
diff --git a/erpnext/config/stock.py b/erpnext/config/stock.py
index 84aa847..f5e48b3 100644
--- a/erpnext/config/stock.py
+++ b/erpnext/config/stock.py
@@ -281,9 +281,9 @@
},
{
"type": "report",
+ "is_query_report": True,
"name": "Item Shortage Report",
- "route": "#Report/Bin/Item Shortage Report",
- "doctype": "Purchase Receipt"
+ "doctype": "Bin"
},
{
"type": "report",
diff --git a/erpnext/config/support.py b/erpnext/config/support.py
index 0301bb3..151c4f7 100644
--- a/erpnext/config/support.py
+++ b/erpnext/config/support.py
@@ -21,13 +21,7 @@
"type": "doctype",
"name": "Issue Priority",
"description": _("Issue Priority."),
- },
- {
- "type": "doctype",
- "name": "Communication",
- "description": _("Communication log."),
- "onboard": 1,
- },
+ }
]
},
{
@@ -97,4 +91,15 @@
},
]
},
+ {
+ "label": _("Settings"),
+ "icon": "fa fa-list",
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Support Settings",
+ "label": _("Support Settings"),
+ },
+ ]
+ },
]
\ No newline at end of file
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index ebbe3d9..8e1510a 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -15,6 +15,9 @@
self.calculate()
def calculate(self):
+ if not len(self.doc.get("items")):
+ return
+
self.discount_amount_applied = False
self._calculate()
diff --git a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
index 29a1a2b..96a533e 100644
--- a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
+++ b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py
@@ -7,7 +7,9 @@
from frappe import _
from frappe.model.document import Document
from requests_oauthlib import OAuth2Session
-import json, requests
+import json
+import requests
+import traceback
from erpnext import encode_company_abbr
# QuickBooks requires a redirect URL, User will be redirect to this URL
@@ -32,7 +34,6 @@
class QuickBooksMigrator(Document):
def __init__(self, *args, **kwargs):
super(QuickBooksMigrator, self).__init__(*args, **kwargs)
- from pprint import pprint
self.oauth = OAuth2Session(
client_id=self.client_id,
redirect_uri=self.redirect_url,
@@ -46,7 +47,9 @@
if self.company:
# We need a Cost Center corresponding to the selected erpnext Company
self.default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
- self.default_warehouse = frappe.get_all('Warehouse', filters={"company": self.company, "is_group": 0})[0]["name"]
+ company_warehouses = frappe.get_all('Warehouse', filters={"company": self.company, "is_group": 0})
+ if company_warehouses:
+ self.default_warehouse = company_warehouses[0].name
if self.authorization_endpoint:
self.authorization_url = self.oauth.authorization_url(self.authorization_endpoint)[0]
@@ -218,7 +221,7 @@
def _fetch_general_ledger(self):
try:
- query_uri = "{}/company/{}/reports/GeneralLedger".format(self.api_endpoint ,self.quickbooks_company_id)
+ query_uri = "{}/company/{}/reports/GeneralLedger".format(self.api_endpoint, self.quickbooks_company_id)
response = self._get(query_uri,
params={
"columns": ",".join(["tx_date", "txn_type", "credit_amt", "debt_amt"]),
@@ -493,17 +496,17 @@
"account_currency": customer["CurrencyRef"]["value"],
"company": self.company,
})[0]["name"]
- except Exception as e:
+ except Exception:
receivable_account = None
erpcustomer = frappe.get_doc({
"doctype": "Customer",
"quickbooks_id": customer["Id"],
- "customer_name" : encode_company_abbr(customer["DisplayName"], self.company),
- "customer_type" : "Individual",
- "customer_group" : "Commercial",
+ "customer_name": encode_company_abbr(customer["DisplayName"], self.company),
+ "customer_type": "Individual",
+ "customer_group": "Commercial",
"default_currency": customer["CurrencyRef"]["value"],
"accounts": [{"company": self.company, "account": receivable_account}],
- "territory" : "All Territories",
+ "territory": "All Territories",
"company": self.company,
}).insert()
if "BillAddr" in customer:
@@ -521,7 +524,7 @@
item_dict = {
"doctype": "Item",
"quickbooks_id": item["Id"],
- "item_code" : encode_company_abbr(item["Name"], self.company),
+ "item_code": encode_company_abbr(item["Name"], self.company),
"stock_uom": "Unit",
"is_stock_item": 0,
"item_group": "All Item Groups",
@@ -549,14 +552,14 @@
erpsupplier = frappe.get_doc({
"doctype": "Supplier",
"quickbooks_id": vendor["Id"],
- "supplier_name" : encode_company_abbr(vendor["DisplayName"], self.company),
- "supplier_group" : "All Supplier Groups",
+ "supplier_name": encode_company_abbr(vendor["DisplayName"], self.company),
+ "supplier_group": "All Supplier Groups",
"company": self.company,
}).insert()
if "BillAddr" in vendor:
self._create_address(erpsupplier, "Supplier", vendor["BillAddr"], "Billing")
if "ShipAddr" in vendor:
- self._create_address(erpsupplier, "Supplier",vendor["ShipAddr"], "Shipping")
+ self._create_address(erpsupplier, "Supplier", vendor["ShipAddr"], "Shipping")
except Exception as e:
self._log_error(e)
@@ -829,7 +832,7 @@
"currency": invoice["CurrencyRef"]["value"],
"conversion_rate": invoice.get("ExchangeRate", 1),
"posting_date": invoice["TxnDate"],
- "due_date": invoice.get("DueDate", invoice["TxnDate"]),
+ "due_date": invoice.get("DueDate", invoice["TxnDate"]),
"credit_to": credit_to_account,
"supplier": frappe.get_all("Supplier",
filters={
@@ -1200,7 +1203,7 @@
def _create_address(self, entity, doctype, address, address_type):
- try :
+ try:
if not frappe.db.exists({"doctype": "Address", "quickbooks_id": address["Id"]}):
frappe.get_doc({
"doctype": "Address",
@@ -1252,8 +1255,6 @@
def _log_error(self, execption, data=""):
- import json, traceback
- traceback.print_exc()
frappe.log_error(title="QuickBooks Migration Error",
message="\n".join([
"Data",
diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js
index 1692814..1a34fe8 100644
--- a/erpnext/healthcare/doctype/patient/patient.js
+++ b/erpnext/healthcare/doctype/patient/patient.js
@@ -21,9 +21,9 @@
});
}
if (frm.doc.patient_name && frappe.user.has_role("Physician")) {
- frm.add_custom_button(__('Medical Record'), function () {
+ frm.add_custom_button(__('Patient History'), function () {
frappe.route_options = { "patient": frm.doc.name };
- frappe.set_route("medical_record");
+ frappe.set_route("patient_history");
},"View");
}
if (!frm.doc.__islocal && (frappe.user.has_role("Nursing User") || frappe.user.has_role("Physician"))) {
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index b3cbd1f..858145e 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -30,9 +30,9 @@
};
});
if(frm.doc.patient){
- frm.add_custom_button(__('Medical Record'), function() {
+ frm.add_custom_button(__('Patient History'), function() {
frappe.route_options = {"patient": frm.doc.patient};
- frappe.set_route("medical_record");
+ frappe.set_route("patient_history");
},__("View"));
}
if(frm.doc.status == "Open"){
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 7ea4568..088bc81 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -41,10 +41,10 @@
}
});
}
- frm.add_custom_button(__('Medical Record'), function() {
+ frm.add_custom_button(__('Patient History'), function() {
if (frm.doc.patient) {
frappe.route_options = {"patient": frm.doc.patient};
- frappe.set_route("medical_record");
+ frappe.set_route("patient_history");
} else {
frappe.msgprint(__("Please select Patient"));
}
diff --git a/erpnext/healthcare/page/medical_record/__init__.py b/erpnext/healthcare/page/medical_record/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/healthcare/page/medical_record/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/healthcare/page/medical_record/medical_record.js b/erpnext/healthcare/page/medical_record/medical_record.js
deleted file mode 100644
index df19d8f..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record.js
+++ /dev/null
@@ -1,182 +0,0 @@
-frappe.provide("frappe.medical_record");
-frappe.pages['medical_record'].on_page_load = function(wrapper) {
- var me = this;
- var page = frappe.ui.make_app_page({
- parent: wrapper,
- title: 'Medical Record',
- });
-
- frappe.breadcrumbs.add("Medical");
-
- page.main.html(frappe.render_template("patient_select", {}));
- var patient = frappe.ui.form.make_control({
- parent: page.main.find(".patient"),
- df: {
- fieldtype: "Link",
- options: "Patient",
- fieldname: "patient",
- change: function(){
- page.main.find(".frappe-list").html("");
- draw_page(patient.get_value(), me);
- }
- },
- only_input: true,
- });
- patient.refresh();
-
-
- this.page.main.on("click", ".medical_record-message", function() {
- var doctype = $(this).attr("data-doctype"),
- docname = $(this).attr("data-docname");
-
- if (doctype && docname) {
- frappe.route_options = {
- scroll_to: { "doctype": doctype, "name": docname }
- };
- frappe.set_route(["Form", doctype, docname]);
- }
- });
-
- this.page.sidebar.on("click", ".edit-details", function() {
- patient = patient.get_value();
- if (patient) {
- frappe.set_route(["Form", "Patient", patient]);
- }
- });
-
-};
-
-frappe.pages['medical_record'].refresh = function() {
- var me = this;
-
- if(frappe.route_options) {
- if(frappe.route_options.patient){
- me.page.main.find(".frappe-list").html("");
- var patient = frappe.route_options.patient;
- draw_page(patient,me);
- me.page.main.find("[data-fieldname='patient']").val(patient);
- frappe.route_options = null;
- }
- }
-};
-var show_patient_info = function(patient, me){
- frappe.call({
- "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
- args: {
- patient: patient
- },
- callback: function (r) {
- var data = r.message;
- var details = "";
- if(data.email) details += "<br><b>Email :</b> " + data.email;
- if(data.mobile) details += "<br><b>Mobile :</b> " + data.mobile;
- if(data.occupation) details += "<br><b>Occupation :</b> " + data.occupation;
- if(data.blood_group) details += "<br><b>Blood group : </b> " + data.blood_group;
- if(data.allergies) details += "<br><br><b>Allergies : </b> "+ data.allergies;
- if(data.medication) details += "<br><b>Medication : </b> "+ data.medication;
- if(data.alcohol_current_use) details += "<br><br><b>Alcohol use : </b> "+ data.alcohol_current_use;
- if(data.alcohol_past_use) details += "<br><b>Alcohol past use : </b> "+ data.alcohol_past_use;
- if(data.tobacco_current_use) details += "<br><b>Tobacco use : </b> "+ data.tobacco_current_use;
- if(data.tobacco_past_use) details += "<br><b>Tobacco past use : </b> "+ data.tobacco_past_use;
- if(data.medical_history) details += "<br><br><b>Medical history : </b> "+ data.medical_history;
- if(data.surgical_history) details += "<br><b>Surgical history : </b> "+ data.surgical_history;
- if(data.surrounding_factors) details += "<br><br><b>Occupational hazards : </b> "+ data.surrounding_factors;
- if(data.other_risk_factors) details += "<br><b>Other risk factors : </b> " + data.other_risk_factors;
- if(data.patient_details) details += "<br><br><b>More info : </b> " + data.patient_details;
-
- if(details){
- details = "<div style='padding-left:10px; font-size:13px;' align='center'></br><b class='text-muted'>Patient Details</b>" + details + "</div>";
- }
-
- var vitals = "";
- if(data.temperature) vitals += "<br><b>Temperature :</b> " + data.temperature;
- if(data.pulse) vitals += "<br><b>Pulse :</b> " + data.pulse;
- if(data.respiratory_rate) vitals += "<br><b>Respiratory Rate :</b> " + data.respiratory_rate;
- if(data.bp) vitals += "<br><b>BP :</b> " + data.bp;
- if(data.bmi) vitals += "<br><b>BMI :</b> " + data.bmi;
- if(data.height) vitals += "<br><b>Height :</b> " + data.height;
- if(data.weight) vitals += "<br><b>Weight :</b> " + data.weight;
- if(data.signs_date) vitals += "<br><b>Date :</b> " + data.signs_date;
-
- if(vitals){
- vitals = "<div style='padding-left:10px; font-size:13px;' align='center'></br><b class='text-muted'>Vital Signs</b>" + vitals + "<br></div>";
- details = vitals + details;
- }
- if(details) details += "<div align='center'><br><a class='btn btn-default btn-sm edit-details'>Edit Details</a></b> </div>";
-
- me.page.sidebar.addClass("col-sm-3");
- me.page.sidebar.html(details);
- me.page.wrapper.find(".layout-main-section-wrapper").addClass("col-sm-9");
- }
- });
-};
-var draw_page = function(patient, me){
- frappe.model.with_doctype("Patient Medical Record", function() {
- me.page.list = new frappe.ui.BaseList({
- hide_refresh: true,
- page: me.page,
- method: 'erpnext.healthcare.page.medical_record.medical_record.get_feed',
- args: {name: patient},
- parent: $("<div></div>").appendTo(me.page.main),
- render_view: function(values) {
- var me = this;
- var wrapper = me.page.main.find(".result-list").get(0);
- values.map(function (value) {
- var row = $('<div class="list-row">').data("data", value).appendTo($(wrapper)).get(0);
- new frappe.medical_record.Feed(row, value);
- });
- },
- show_filters: true,
- doctype: "Patient Medical Record",
- });
- show_patient_info(patient, me);
- me.page.list.run();
- });
-};
-
-frappe.medical_record.last_feed_date = false;
-frappe.medical_record.Feed = Class.extend({
- init: function(row, data) {
- this.scrub_data(data);
- this.add_date_separator(row, data);
- if(!data.add_class)
- data.add_class = "label-default";
-
- data.link = "";
- if (data.reference_doctype && data.reference_name) {
- data.link = frappe.format(data.reference_name, {fieldtype: "Link", options: data.reference_doctype},
- {label: __(data.reference_doctype)});
- }
-
- $(row)
- .append(frappe.render_template("medical_record_row", data))
- .find("a").addClass("grey");
- },
- scrub_data: function(data) {
- data.by = frappe.user.full_name(data.owner);
- data.imgsrc = frappe.utils.get_file_link(frappe.user_info(data.owner).image);
-
- data.icon = "icon-flag";
- },
- add_date_separator: function(row, data) {
- var date = frappe.datetime.str_to_obj(data.creation);
- var last = frappe.medical_record.last_feed_date;
-
- if((last && frappe.datetime.obj_to_str(last) != frappe.datetime.obj_to_str(date)) || (!last)) {
- var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date));
- if(diff < 1) {
- var pdate = 'Today';
- } else if(diff < 2) {
- pdate = 'Yesterday';
- } else {
- pdate = frappe.datetime.global_date_format(date);
- }
- data.date_sep = pdate;
- data.date_class = pdate=='Today' ? "date-indicator blue" : "date-indicator";
- } else {
- data.date_sep = null;
- data.date_class = "";
- }
- frappe.medical_record.last_feed_date = date;
- }
-});
diff --git a/erpnext/healthcare/page/medical_record/medical_record.json b/erpnext/healthcare/page/medical_record/medical_record.json
deleted file mode 100644
index ca30c3b..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "content": null,
- "creation": "2016-06-09 11:33:14.025787",
- "docstatus": 0,
- "doctype": "Page",
- "icon": "icon-play",
- "idx": 0,
- "modified": "2018-08-06 11:40:39.705660",
- "modified_by": "Administrator",
- "module": "Healthcare",
- "name": "medical_record",
- "owner": "Administrator",
- "page_name": "medical_record",
- "restrict_to_domain": "Healthcare",
- "roles": [
- {
- "role": "Physician"
- }
- ],
- "script": null,
- "standard": "Yes",
- "style": null,
- "system_page": 0,
- "title": "Medical Record"
-}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/medical_record/medical_record.py b/erpnext/healthcare/page/medical_record/medical_record.py
deleted file mode 100644
index 22c5852..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, ESS LLP and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.utils import cint
-
-@frappe.whitelist()
-def get_feed(start, page_length, name):
- """get feed"""
- result = frappe.db.sql("""select name, owner, modified, creation,
- reference_doctype, reference_name, subject
- from `tabPatient Medical Record`
- where patient=%(patient)s
- order by creation desc
- limit %(start)s, %(page_length)s""",
- {
- "start": cint(start),
- "page_length": cint(page_length),
- "patient": name
- }, as_dict=True)
-
- return result
diff --git a/erpnext/healthcare/page/medical_record/medical_record_row.html b/erpnext/healthcare/page/medical_record/medical_record_row.html
deleted file mode 100644
index 9a670c9..0000000
--- a/erpnext/healthcare/page/medical_record/medical_record_row.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<div class="row medical_record-row" data-creation="{%= creation.split(" ")[0] + " 00:00:00" %}">
- <div class="col-xs-3 text-right medical_record-date"><span class="{%= date_class %}">
- {%= date_sep || "" %}</span>
- </div>
- <div class="col-xs-9 medical_record-message"
- data-doctype="{%= reference_doctype %}"
- data-docname="{%= reference_name %}"
- title="{%= by %} / {%= frappe.datetime.str_to_user(creation) %}">
- <span class="avatar avatar-small">
- <div class="avatar-frame" style="background-image: url({{ imgsrc }});"></div>
- <!-- <img src="{%= imgsrc %}"> -->
- </span>
- <span class="small">
- {% if (reference_doctype && reference_name) { %}
- {%= __("{0}: {1}", [link, "<strong>" + subject + "</strong>"]) %}
- {% } else { %}
- {%= subject %}
- {% } %}
- </span>
- </div>
-</div>
diff --git a/erpnext/healthcare/page/medical_record/patient_select.html b/erpnext/healthcare/page/medical_record/patient_select.html
deleted file mode 100644
index 321baf7..0000000
--- a/erpnext/healthcare/page/medical_record/patient_select.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div class="text-center col-sm-9" style="padding: 40px;">
-
- <p>{%= __("Select Patient") %}</p>
- <p class="patient" style="margin: auto; max-width: 300px; margin-bottom: 20px;"></p>
-</div>
diff --git a/erpnext/healthcare/page/patient_history/__init__.py b/erpnext/healthcare/page/patient_history/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/__init__.py
diff --git a/erpnext/healthcare/page/medical_record/medical_record.css b/erpnext/healthcare/page/patient_history/patient_history.css
similarity index 62%
rename from erpnext/healthcare/page/medical_record/medical_record.css
rename to erpnext/healthcare/page/patient_history/patient_history.css
index 977625b..865d6ab 100644
--- a/erpnext/healthcare/page/medical_record/medical_record.css
+++ b/erpnext/healthcare/page/patient_history/patient_history.css
@@ -14,6 +14,10 @@
margin-bottom: -4px;
}
+.medical_record-row > * {
+ z-index: -999;
+}
+
.date-indicator {
background:none;
font-size:12px;
@@ -35,6 +39,61 @@
color: #5e64ff;
}
+.div-bg-color {
+ background: #fafbfc;
+}
+
+.bg-color-white {
+ background: #FFFFFF;
+}
+
+.d-flex {
+ display: flex;
+}
+
+.width-full {
+ width: 100%;
+}
+
+.p-3 {
+ padding: 16px;
+}
+
+.mt-2 {
+ margin-top: 8px;
+}
+
+.mr-3 {
+ margin-right: 16px;
+}
+
+.Box {
+ background-color: #fff;
+ border: 1px solid #d1d5da;
+ border-radius: 3px;
+}
+
+.flex-column {
+ flex-direction: column;
+}
+
+.avatar {
+ display: inline-block;
+ overflow: hidden;
+ line-height: 1;
+ vertical-align: middle;
+ border-radius: 3px;
+}
+
+.py-3 {
+ padding-top: 16px;
+ padding-bottom: 16px;
+}
+
+.border-bottom {
+ border-bottom: 1px #e1e4e8 solid;
+}
+
.date-indicator.blue::after {
background: #5e64ff;
}
@@ -65,8 +124,3 @@
#page-medical_record .list-filters {
display: none ;
}
-
-#page-medical_record .octicon-heart {
- color: #ff5858;
- margin: 0px 5px;
-}
diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html
new file mode 100644
index 0000000..7a9446d
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.html
@@ -0,0 +1,20 @@
+<div class="col-sm-12">
+ <div class="col-sm-3">
+ <p class="text-center">{%= __("Select Patient") %}</p>
+ <p class="patient" style="margin: auto; max-width: 300px; margin-bottom: 20px;"></p>
+ <div class="patient_details" style="z-index=0"></div>
+ </div>
+ <div class="col-sm-9 patient_documents">
+ <div class="col-sm-12">
+ <div class="col-sm-12 show_chart_btns" align="center">
+ </div>
+ <div id="chart" class="col-sm-12 patient_vital_charts">
+ </div>
+ </div>
+ <div class="col-sm-12 patient_documents_list">
+ </div>
+ <div class="col-sm-12 text-center py-3">
+ <a class="btn btn-sm btn-default btn-get-records" style="display:none">More..</a>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js
new file mode 100644
index 0000000..87fe7ed
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.js
@@ -0,0 +1,300 @@
+frappe.provide("frappe.patient_history");
+frappe.pages['patient_history'].on_page_load = function(wrapper) {
+ var me = this;
+ var page = frappe.ui.make_app_page({
+ parent: wrapper,
+ title: 'Patient History',
+ single_column: true
+ });
+
+ frappe.breadcrumbs.add("Healthcare");
+ let pid = '';
+ page.main.html(frappe.render_template("patient_history", {}));
+ var patient = frappe.ui.form.make_control({
+ parent: page.main.find(".patient"),
+ df: {
+ fieldtype: "Link",
+ options: "Patient",
+ fieldname: "patient",
+ change: function(){
+ if(pid != patient.get_value() && patient.get_value()){
+ me.start = 0;
+ me.page.main.find(".patient_documents_list").html("");
+ get_documents(patient.get_value(), me);
+ show_patient_info(patient.get_value(), me);
+ show_patient_vital_charts(patient.get_value(), me, "bp", "mmHg", "Blood Pressure");
+ }
+ pid = patient.get_value();
+ }
+ },
+ only_input: true,
+ });
+ patient.refresh();
+
+ if (frappe.route_options){
+ patient.set_value(frappe.route_options.patient);
+ }
+
+ this.page.main.on("click", ".btn-show-chart", function() {
+ var btn_show_id = $(this).attr("data-show-chart-id"), pts = $(this).attr("data-pts");
+ var title = $(this).attr("data-title");
+ show_patient_vital_charts(patient.get_value(), me, btn_show_id, pts, title);
+ });
+
+ this.page.main.on("click", ".btn-more", function() {
+ var doctype = $(this).attr("data-doctype"), docname = $(this).attr("data-docname");
+ if(me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched') == "1"){
+ me.page.main.find("."+docname).hide();
+ me.page.main.find("."+docname).parent().find('.document-html').show();
+ }else{
+ if(doctype && docname){
+ let exclude = ["patient", "patient_name", 'patient_sex', "encounter_date"];
+ frappe.call({
+ method: "erpnext.healthcare.utils.render_doc_as_html",
+ args:{
+ doctype: doctype,
+ docname: docname,
+ exclude_fields: exclude
+ },
+ callback: function(r) {
+ if (r.message){
+ me.page.main.find("."+docname).hide();
+ me.page.main.find("."+docname).parent().find('.document-html').html(r.message.html+"\
+ <div align='center'><a class='btn octicon octicon-chevron-up btn-default btn-xs\
+ btn-less' data-doctype='"+doctype+"' data-docname='"+docname+"'></a></div>");
+ me.page.main.find("."+docname).parent().find('.document-html').show();
+ me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched', "1");
+ }
+ },
+ freeze: true
+ });
+ }
+ }
+ });
+
+ this.page.main.on("click", ".btn-less", function() {
+ var docname = $(this).attr("data-docname");
+ me.page.main.find("."+docname).parent().find('.document-id').show();
+ me.page.main.find("."+docname).parent().find('.document-html').hide();
+ });
+ me.start = 0;
+ me.page.main.on("click", ".btn-get-records", function(){
+ get_documents(patient.get_value(), me);
+ });
+};
+
+var get_documents = function(patient, me){
+ frappe.call({
+ "method": "erpnext.healthcare.page.patient_history.patient_history.get_feed",
+ args: {
+ name: patient,
+ start: me.start,
+ page_length: 20
+ },
+ callback: function (r) {
+ var data = r.message;
+ if(data.length){
+ add_to_records(me, data);
+ }else{
+ me.page.main.find(".patient_documents_list").append("<div class='text-muted' align='center'><br><br>No more records..<br><br></div>");
+ me.page.main.find(".btn-get-records").hide();
+ }
+ }
+ });
+};
+
+var add_to_records = function(me, data){
+ var details = "<ul class='nav nav-pills nav-stacked'>";
+ var i;
+ for(i=0; i<data.length; i++){
+ if(data[i].reference_doctype){
+ let label = '';
+ if(data[i].subject){
+ label += "<br/>"+data[i].subject;
+ }
+ data[i] = add_date_separator(data[i]);
+ if(frappe.user_info(data[i].owner).image){
+ data[i].imgsrc = frappe.utils.get_file_link(frappe.user_info(data[i].owner).image);
+ }
+ else{
+ data[i].imgsrc = false;
+ }
+ var time_line_heading = data[i].practitioner ? `${data[i].practitioner} ` : ``;
+ time_line_heading += data[i].reference_doctype + " - "+ data[i].reference_name;
+ details += `<li data-toggle='pill' class='patient_doc_menu'
+ data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
+ <div class='col-sm-12 d-flex border-bottom py-3'>`;
+ if (data[i].imgsrc){
+ details += `<span class='mr-3'>
+ <img class='avtar' src='${data[i].imgsrc}' width='32' height='32'>
+ </img>
+ </span>`;
+ }else{
+ details += `<span class='mr-3 avatar avatar-small' style='width:32px; height:32px;'><div align='center' class='standard-image'
+ style='background-color: #fafbfc;'>${data[i].practitioner ? data[i].practitioner.charAt(0) : "U"}</div></span>`;
+ }
+ details += `<div class='d-flex flex-column width-full'>
+ <div>
+ `+time_line_heading+` on
+ <span>
+ ${data[i].date_sep}
+ </span>
+ </div>
+ <div class='Box p-3 mt-2'>
+ <span class='${data[i].reference_name} document-id'>${label}
+ <div align='center'>
+ <a class='btn octicon octicon-chevron-down btn-default btn-xs btn-more'
+ data-doctype='${data[i].reference_doctype}' data-docname='${data[i].reference_name}'>
+ </a>
+ </div>
+ </span>
+ <span class='document-html' hidden data-fetched="0">
+ </span>
+ </div>
+ </div>
+ </div>
+ </li>`;
+ }
+ }
+ details += "</ul>";
+ me.page.main.find(".patient_documents_list").append(details);
+ me.start += data.length;
+ if(data.length===20){
+ me.page.main.find(".btn-get-records").show();
+ }else{
+ me.page.main.find(".btn-get-records").hide();
+ me.page.main.find(".patient_documents_list").append("<div class='text-muted' align='center'><br><br>No more records..<br><br></div>");
+ }
+};
+
+var add_date_separator = function(data) {
+ var date = frappe.datetime.str_to_obj(data.creation);
+
+ var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date));
+ if(diff < 1) {
+ var pdate = 'Today';
+ } else if(diff < 2) {
+ pdate = 'Yesterday';
+ } else {
+ pdate = frappe.datetime.global_date_format(date);
+ }
+ data.date_sep = pdate;
+ return data;
+};
+
+var show_patient_info = function(patient, me){
+ frappe.call({
+ "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
+ args: {
+ patient: patient
+ },
+ callback: function (r) {
+ var data = r.message;
+ var details = "";
+ if(data.image){
+ details += "<div><img class='thumbnail' width=75% src='"+data.image+"'></div>";
+ }
+ details += "<b>" + data.patient_name +"</b><br>" + data.sex;
+ if(data.email) details += "<br>" + data.email;
+ if(data.mobile) details += "<br>" + data.mobile;
+ if(data.occupation) details += "<br><br><b>Occupation :</b> " + data.occupation;
+ if(data.blood_group) details += "<br><b>Blood group : </b> " + data.blood_group;
+ if(data.allergies) details += "<br><br><b>Allergies : </b> "+ data.allergies.replace("\n", "<br>");
+ if(data.medication) details += "<br><b>Medication : </b> "+ data.medication.replace("\n", "<br>");
+ if(data.alcohol_current_use) details += "<br><br><b>Alcohol use : </b> "+ data.alcohol_current_use;
+ if(data.alcohol_past_use) details += "<br><b>Alcohol past use : </b> "+ data.alcohol_past_use;
+ if(data.tobacco_current_use) details += "<br><b>Tobacco use : </b> "+ data.tobacco_current_use;
+ if(data.tobacco_past_use) details += "<br><b>Tobacco past use : </b> "+ data.tobacco_past_use;
+ if(data.medical_history) details += "<br><br><b>Medical history : </b> "+ data.medical_history.replace("\n", "<br>");
+ if(data.surgical_history) details += "<br><b>Surgical history : </b> "+ data.surgical_history.replace("\n", "<br>");
+ if(data.surrounding_factors) details += "<br><br><b>Occupational hazards : </b> "+ data.surrounding_factors.replace("\n", "<br>");
+ if(data.other_risk_factors) details += "<br><b>Other risk factors : </b> " + data.other_risk_factors.replace("\n", "<br>");
+ if(data.patient_details) details += "<br><br><b>More info : </b> " + data.patient_details.replace("\n", "<br>");
+
+ if(details){
+ details = "<div style='padding-left:10px; font-size:13px;' align='center'>" + details + "</div>";
+ }
+ me.page.main.find(".patient_details").html(details);
+ }
+ });
+};
+
+var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) {
+ frappe.call({
+ method: "erpnext.healthcare.utils.get_patient_vitals",
+ args:{
+ patient: patient
+ },
+ callback: function(r) {
+ if (r.message){
+ var show_chart_btns_html = "<div style='padding-top:5px;'><a class='btn btn-default btn-xs btn-show-chart' \
+ data-show-chart-id='bp' data-pts='mmHg' data-title='Blood Pressure'>Blood Pressure</a>\
+ <a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='pulse_rate' \
+ data-pts='per Minutes' data-title='Respiratory/Pulse Rate'>Respiratory/Pulse Rate</a>\
+ <a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='temperature' \
+ data-pts='°C or °F' data-title='Temperature'>Temperature</a>\
+ <a class='btn btn-default btn-xs btn-show-chart' data-show-chart-id='bmi' \
+ data-pts='bmi' data-title='BMI'>BMI</a></div>";
+ me.page.main.find(".show_chart_btns").html(show_chart_btns_html);
+ var data = r.message;
+ let labels = [], datasets = [];
+ let bp_systolic = [], bp_diastolic = [], temperature = [];
+ let pulse = [], respiratory_rate = [], bmi = [], height = [], weight = [];
+ for(var i=0; i<data.length; i++){
+ labels.push(data[i].signs_date+"||"+data[i].signs_time);
+ if(btn_show_id=="bp"){
+ bp_systolic.push(data[i].bp_systolic);
+ bp_diastolic.push(data[i].bp_diastolic);
+ }
+ if(btn_show_id=="temperature"){
+ temperature.push(data[i].temperature);
+ }
+ if(btn_show_id=="pulse_rate"){
+ pulse.push(data[i].pulse);
+ respiratory_rate.push(data[i].respiratory_rate);
+ }
+ if(btn_show_id=="bmi"){
+ bmi.push(data[i].bmi);
+ height.push(data[i].height);
+ weight.push(data[i].weight);
+ }
+ }
+ if(btn_show_id=="temperature"){
+ datasets.push({name: "Temperature", values: temperature, chartType:'line'});
+ }
+ if(btn_show_id=="bmi"){
+ datasets.push({name: "BMI", values: bmi, chartType:'line'});
+ datasets.push({name: "Height", values: height, chartType:'line'});
+ datasets.push({name: "Weight", values: weight, chartType:'line'});
+ }
+ if(btn_show_id=="bp"){
+ datasets.push({name: "BP Systolic", values: bp_systolic, chartType:'line'});
+ datasets.push({name: "BP Diastolic", values: bp_diastolic, chartType:'line'});
+ }
+ if(btn_show_id=="pulse_rate"){
+ datasets.push({name: "Heart Rate / Pulse", values: pulse, chartType:'line'});
+ datasets.push({name: "Respiratory Rate", values: respiratory_rate, chartType:'line'});
+ }
+ new Chart( ".patient_vital_charts", {
+ data: {
+ labels: labels,
+ datasets: datasets
+ },
+
+ title: title,
+ type: 'axis-mixed', // 'axis-mixed', 'bar', 'line', 'pie', 'percentage'
+ height: 150,
+ colors: ['purple', '#ffa3ef', 'light-blue'],
+
+ tooltipOptions: {
+ formatTooltipX: d => (d + '').toUpperCase(),
+ formatTooltipY: d => d + ' ' + pts,
+ }
+ });
+ }else{
+ me.page.main.find(".patient_vital_charts").html("");
+ me.page.main.find(".show_chart_btns").html("");
+ }
+ }
+ });
+};
diff --git a/erpnext/healthcare/page/patient_history/patient_history.json b/erpnext/healthcare/page/patient_history/patient_history.json
new file mode 100644
index 0000000..b3892a4
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.json
@@ -0,0 +1,28 @@
+{
+ "content": null,
+ "creation": "2018-08-08 17:09:13.816199",
+ "docstatus": 0,
+ "doctype": "Page",
+ "icon": "",
+ "idx": 0,
+ "modified": "2018-08-08 17:09:55.969424",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "patient_history",
+ "owner": "Administrator",
+ "page_name": "patient_history",
+ "restrict_to_domain": "Healthcare",
+ "roles": [
+ {
+ "role": "Healthcare Administrator"
+ },
+ {
+ "role": "Physician"
+ }
+ ],
+ "script": null,
+ "standard": "Yes",
+ "style": null,
+ "system_page": 0,
+ "title": "Patient History"
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py
new file mode 100644
index 0000000..772aa4e
--- /dev/null
+++ b/erpnext/healthcare/page/patient_history/patient_history.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, ESS LLP and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import cint
+from erpnext.healthcare.utils import render_docs_as_html
+
+@frappe.whitelist()
+def get_feed(name, start=0, page_length=20):
+ """get feed"""
+ result = frappe.db.sql("""select name, owner, creation,
+ reference_doctype, reference_name, subject
+ from `tabPatient Medical Record`
+ where patient=%(patient)s
+ order by creation desc
+ limit %(start)s, %(page_length)s""",
+ {
+ "patient": name,
+ "start": cint(start),
+ "page_length": cint(page_length)
+ }, as_dict=True)
+ return result
+
+@frappe.whitelist()
+def get_feed_for_dt(doctype, docname):
+ """get feed"""
+ result = frappe.db.sql("""select name, owner, modified, creation,
+ reference_doctype, reference_name, subject
+ from `tabPatient Medical Record`
+ where reference_name=%(docname)s and reference_doctype=%(doctype)s
+ order by creation desc""",
+ {
+ "docname": docname,
+ "doctype": doctype
+ }, as_dict=True)
+
+ return result
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 6a226d9..97bb98f 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -429,3 +429,116 @@
occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total)
each["occupied_out_of_vacant"] = occupancy_msg
return hc_service_units
+
+@frappe.whitelist()
+def get_patient_vitals(patient, from_date=None, to_date=None):
+ if not patient: return
+ vitals = frappe.db.sql("""select * from `tabVital Signs` where \
+ docstatus=1 and patient=%s order by signs_date, signs_time""", \
+ (patient), as_dict=1)
+ if vitals and vitals[0]:
+ return vitals
+ else:
+ return False
+
+@frappe.whitelist()
+def render_docs_as_html(docs):
+ # docs key value pair {doctype: docname}
+ docs_html = "<div class='col-md-12 col-sm-12 text-muted'>"
+ for doc in docs:
+ docs_html += render_doc_as_html(doc['doctype'], doc['docname'])['html'] + "<br/>"
+ return {'html': docs_html}
+
+@frappe.whitelist()
+def render_doc_as_html(doctype, docname, exclude_fields = []):
+ #render document as html, three column layout will break
+ doc = frappe.get_doc(doctype, docname)
+ meta = frappe.get_meta(doctype)
+ doc_html = "<div class='col-md-12 col-sm-12'>"
+ section_html = ""
+ section_label = ""
+ html = ""
+ sec_on = False
+ col_on = 0
+ has_data = False
+ for df in meta.fields:
+ #on section break append append previous section and html to doc html
+ if df.fieldtype == "Section Break":
+ if has_data and col_on and sec_on:
+ doc_html += section_html + html + "</div>"
+ elif has_data and not col_on and sec_on:
+ doc_html += "<div class='col-md-12 col-sm-12'\
+ ><div class='col-md-12 col-sm-12'>" \
+ + section_html + html +"</div></div>"
+ while col_on:
+ doc_html += "</div>"
+ col_on -= 1
+ sec_on = True
+ has_data= False
+ col_on = 0
+ section_html = ""
+ html = ""
+ if df.label:
+ section_label = df.label
+ continue
+ #on column break append html to section html or doc html
+ if df.fieldtype == "Column Break":
+ if sec_on and has_data:
+ section_html += "<div class='col-md-12 col-sm-12'\
+ ><div class='col-md-6 col\
+ -sm-6'><b>" + section_label + "</b>" + html + "</div><div \
+ class='col-md-6 col-sm-6'>"
+ elif has_data:
+ doc_html += "<div class='col-md-12 col-sm-12'><div class='col-m\
+ d-6 col-sm-6'>" + html + "</div><div class='col-md-6 col-sm-6'>"
+ elif sec_on and not col_on:
+ section_html += "<div class='col-md-6 col-sm-6'>"
+ html = ""
+ col_on += 1
+ if df.label:
+ html += '<br>' + df.label
+ continue
+ #on table iterate in items and create table based on in_list_view, append to section html or doc html
+ if df.fieldtype == "Table":
+ items = doc.get(df.fieldname)
+ if not items: continue
+ child_meta = frappe.get_meta(df.options)
+ if not has_data : has_data = True
+ table_head = ""
+ table_row = ""
+ create_head = True
+ for item in items:
+ table_row += '<tr>'
+ for cdf in child_meta.fields:
+ if cdf.in_list_view:
+ if create_head:
+ table_head += '<th>' + cdf.label + '</th>'
+ if item.get(cdf.fieldname):
+ table_row += '<td>' + str(item.get(cdf.fieldname)) \
+ + '</td>'
+ else:
+ table_row += '<td></td>'
+ create_head = False
+ table_row += '</tr>'
+ if sec_on:
+ section_html += '<table class="table table-condensed \
+ bordered">' + table_head + table_row + '</table>'
+ else:
+ html += '<table class="table table-condensed table-bordered">' \
+ + table_head + table_row + '</table>'
+ continue
+ #on other field types add label and value to html
+ if not df.hidden and not df.print_hide and doc.get(df.fieldname) and df.fieldname not in exclude_fields:
+ html += "<br>{0} : {1}".format(df.label or df.fieldname, \
+ doc.get(df.fieldname))
+ if not has_data : has_data = True
+ if sec_on and col_on and has_data:
+ doc_html += section_html + html + "</div></div>"
+ elif sec_on and not col_on and has_data:
+ doc_html += "<div class='col-md-12 col-sm-12'\
+ ><div class='col-md-12 col-sm-12'>" \
+ + section_html + html +"</div></div>"
+ if doc_html:
+ doc_html = "<div class='small'><div class='col-md-12 text-right'><a class='btn btn-default btn-xs' href='#Form/%s/%s'></a></div>" %(doctype, docname) + doc_html + "</div>"
+
+ return {'html': doc_html}
diff --git a/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py b/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py
deleted file mode 100644
index b6c6502..0000000
--- a/erpnext/hr/doctype/employee_loan_application/employee_loan_application.py
+++ /dev/null
@@ -1,69 +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, math
-from frappe import _
-from frappe.utils import flt, rounded
-from frappe.model.mapper import get_mapped_doc
-from frappe.model.document import Document
-
-from erpnext.hr.doctype.employee_loan.employee_loan import get_monthly_repayment_amount, check_repayment_method
-
-class EmployeeLoanApplication(Document):
- def validate(self):
- check_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
- self.validate_loan_amount()
- self.get_repayment_details()
-
- def validate_loan_amount(self):
- maximum_loan_limit = frappe.db.get_value('Loan Type', self.loan_type, 'maximum_loan_amount')
- if maximum_loan_limit and self.loan_amount > maximum_loan_limit:
- frappe.throw(_("Loan Amount cannot exceed Maximum Loan Amount of {0}").format(maximum_loan_limit))
-
- def get_repayment_details(self):
- if self.repayment_method == "Repay Over Number of Periods":
- self.repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
-
- if self.repayment_method == "Repay Fixed Amount per Period":
- monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
- if monthly_interest_rate:
- monthly_interest_amount = self.loan_amount * monthly_interest_rate
- if monthly_interest_amount >= self.repayment_amount:
- frappe.throw(_("Repayment amount {} should be greater than monthly interest amount {}").
- format(self.repayment_amount, monthly_interest_amount))
-
- self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
- math.log(self.repayment_amount - (monthly_interest_amount))) /
- (math.log(1 + monthly_interest_rate)))
- else:
- self.repayment_periods = self.loan_amount / self.repayment_amount
-
- self.calculate_payable_amount()
-
- def calculate_payable_amount(self):
- balance_amount = self.loan_amount
- self.total_payable_amount = 0
- self.total_payable_interest = 0
-
- while(balance_amount > 0):
- interest_amount = rounded(balance_amount * flt(self.rate_of_interest) / (12*100))
- balance_amount = rounded(balance_amount + interest_amount - self.repayment_amount)
-
- self.total_payable_interest += interest_amount
-
- self.total_payable_amount = self.loan_amount + self.total_payable_interest
-
-@frappe.whitelist()
-def make_employee_loan(source_name, target_doc = None):
- doclist = get_mapped_doc("Employee Loan Application", source_name, {
- "Employee Loan Application": {
- "doctype": "Employee Loan",
- "validation": {
- "docstatus": ["=", 1]
- }
- }
- }, target_doc)
-
- return doclist
\ No newline at end of file
diff --git a/erpnext/hr/doctype/loan/loan.js b/erpnext/hr/doctype/loan/loan.js
index e1b4178..3f5c30c 100644
--- a/erpnext/hr/doctype/loan/loan.js
+++ b/erpnext/hr/doctype/loan/loan.js
@@ -39,31 +39,19 @@
},
refresh: function (frm) {
- if (frm.doc.docstatus == 1 && frm.doc.status == "Sanctioned") {
- frm.add_custom_button(__('Create Disbursement Entry'), function() {
- frm.trigger("make_jv");
- })
- }
- if (frm.doc.repayment_schedule) {
- let total_amount_paid = 0;
- $.each(frm.doc.repayment_schedule || [], function(i, row) {
- if (row.paid) {
- total_amount_paid += row.total_payment;
- }
- });
- frm.set_value("total_amount_paid", total_amount_paid);
-; }
- if (frm.doc.docstatus == 1 && frm.doc.repayment_start_date && (frm.doc.applicant_type == 'Member' || frm.doc.repay_from_salary == 0)) {
- frm.add_custom_button(__('Create Repayment Entry'), function() {
- frm.trigger("make_repayment_entry");
- })
+ if (frm.doc.docstatus == 1) {
+ if (frm.doc.status == "Sanctioned") {
+ frm.add_custom_button(__('Create Disbursement Entry'), function() {
+ frm.trigger("make_jv");
+ }).addClass("btn-primary");
+ } else if (frm.doc.status == "Disbursed" && frm.doc.repayment_start_date && (frm.doc.applicant_type == 'Member' || frm.doc.repay_from_salary == 0)) {
+ frm.add_custom_button(__('Create Repayment Entry'), function() {
+ frm.trigger("make_repayment_entry");
+ }).addClass("btn-primary");
+ }
}
frm.trigger("toggle_fields");
},
- status: function (frm) {
- frm.toggle_reqd("disbursement_date", frm.doc.status == 'Disbursed')
- frm.toggle_reqd("repayment_start_date", frm.doc.status == 'Disbursed')
- },
make_jv: function (frm) {
frappe.call({
diff --git a/erpnext/hr/doctype/loan/loan.json b/erpnext/hr/doctype/loan/loan.json
index 587b301..505b601 100644
--- a/erpnext/hr/doctype/loan/loan.json
+++ b/erpnext/hr/doctype/loan/loan.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
@@ -20,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "applicant_type",
"fieldtype": "Select",
"hidden": 0,
@@ -53,6 +55,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "applicant",
"fieldtype": "Dynamic Link",
"hidden": 0,
@@ -86,6 +89,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "applicant_name",
"fieldtype": "Data",
"hidden": 0,
@@ -118,6 +122,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "loan_application",
"fieldtype": "Link",
"hidden": 0,
@@ -151,6 +156,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "loan_type",
"fieldtype": "Link",
"hidden": 0,
@@ -184,6 +190,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -215,7 +222,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "",
+ "default": "Today",
+ "fetch_if_empty": 0,
"fieldname": "posting_date",
"fieldtype": "Date",
"hidden": 0,
@@ -248,6 +256,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -282,6 +291,7 @@
"collapsible": 0,
"columns": 0,
"default": "Sanctioned",
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -299,7 +309,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -316,6 +326,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.applicant_type==\"Employee\"",
+ "fetch_if_empty": 0,
"fieldname": "repay_from_salary",
"fieldtype": "Check",
"hidden": 0,
@@ -348,6 +359,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
@@ -380,6 +392,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "loan_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -415,6 +428,7 @@
"columns": 0,
"default": "",
"fetch_from": "loan_type.rate_of_interest",
+ "fetch_if_empty": 0,
"fieldname": "rate_of_interest",
"fieldtype": "Percent",
"hidden": 0,
@@ -448,6 +462,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "depends_on": "eval:doc.status==\"Disbursed\"",
+ "fetch_if_empty": 0,
"fieldname": "disbursement_date",
"fieldtype": "Date",
"hidden": 0,
@@ -480,6 +496,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "repayment_start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -499,7 +516,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -512,6 +529,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
@@ -544,6 +562,7 @@
"collapsible": 0,
"columns": 0,
"default": "Repay Over Number of Periods",
+ "fetch_if_empty": 0,
"fieldname": "repayment_method",
"fieldtype": "Select",
"hidden": 0,
@@ -579,6 +598,7 @@
"columns": 0,
"default": "",
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "repayment_periods",
"fieldtype": "Int",
"hidden": 0,
@@ -613,6 +633,7 @@
"columns": 0,
"default": "",
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "monthly_repayment_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -646,6 +667,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "account_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -678,6 +700,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"hidden": 0,
@@ -711,6 +734,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_account",
"fieldtype": "Link",
"hidden": 0,
@@ -744,6 +768,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"hidden": 0,
@@ -775,6 +800,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "loan_account",
"fieldtype": "Link",
"hidden": 0,
@@ -808,6 +834,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "interest_income_account",
"fieldtype": "Link",
"hidden": 0,
@@ -841,6 +868,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_15",
"fieldtype": "Section Break",
"hidden": 0,
@@ -873,6 +901,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "repayment_schedule",
"fieldtype": "Table",
"hidden": 0,
@@ -906,6 +935,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_17",
"fieldtype": "Section Break",
"hidden": 0,
@@ -939,6 +969,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
+ "fetch_if_empty": 0,
"fieldname": "total_payment",
"fieldtype": "Currency",
"hidden": 0,
@@ -972,6 +1003,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1004,6 +1036,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
+ "fetch_if_empty": 0,
"fieldname": "total_interest_payable",
"fieldtype": "Currency",
"hidden": 0,
@@ -1037,6 +1070,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_amount_paid",
"fieldtype": "Currency",
"hidden": 0,
@@ -1070,6 +1104,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -1106,7 +1141,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-21 16:15:53.267145",
+ "modified": "2019-07-10 13:04:20.953694",
"modified_by": "Administrator",
"module": "HR",
"name": "Loan",
@@ -1149,7 +1184,6 @@
"set_user_permissions": 0,
"share": 0,
"submit": 0,
- "user_permission_doctypes": "[\"Employee\"]",
"write": 0
}
],
diff --git a/erpnext/hr/doctype/loan/loan.py b/erpnext/hr/doctype/loan/loan.py
index 58c9b8f..a803863 100644
--- a/erpnext/hr/doctype/loan/loan.py
+++ b/erpnext/hr/doctype/loan/loan.py
@@ -6,29 +6,33 @@
import frappe, math, json
import erpnext
from frappe import _
-from frappe.utils import flt, rounded, add_months, nowdate
+from frappe.utils import flt, rounded, add_months, nowdate, getdate
from erpnext.controllers.accounts_controller import AccountsController
class Loan(AccountsController):
def validate(self):
- check_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods)
+ validate_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods)
+ self.set_missing_fields()
+ self.make_repayment_schedule()
+ self.set_repayment_period()
+ self.calculate_totals()
+
+ def set_missing_fields(self):
if not self.company:
self.company = erpnext.get_default_company()
+
if not self.posting_date:
self.posting_date = nowdate()
+
if self.loan_type and not self.rate_of_interest:
self.rate_of_interest = frappe.db.get_value("Loan Type", self.loan_type, "rate_of_interest")
+
if self.repayment_method == "Repay Over Number of Periods":
self.monthly_repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
+
if self.status == "Repaid/Closed":
self.total_amount_paid = self.total_payment
- if self.status == 'Disbursed' and self.repayment_start_date < self.disbursement_date:
- frappe.throw(_("Repayment Start Date cannot be before Disbursement Date."))
- if self.status == "Disbursed":
- self.make_repayment_schedule()
- self.set_repayment_period()
- self.calculate_totals()
def make_jv_entry(self):
self.check_permission('write')
@@ -105,20 +109,31 @@
frappe.db.set_value("Loan", doc.name, "total_amount_paid", total_amount_paid)
def update_disbursement_status(doc):
- disbursement = frappe.db.sql("""select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
- from `tabGL Entry` where account = %s and against_voucher_type = 'Loan' and against_voucher = %s""",
- (doc.payment_account, doc.name), as_dict=1)[0]
- if disbursement.disbursed_amount == doc.loan_amount:
- frappe.db.set_value("Loan", doc.name , "status", "Disbursed")
- if disbursement.disbursed_amount == 0:
- frappe.db.set_value("Loan", doc.name , "status", "Sanctioned")
- if disbursement.disbursed_amount > doc.loan_amount:
- frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(doc.loan_amount))
- if disbursement.disbursed_amount > 0:
- frappe.db.set_value("Loan", doc.name , "disbursement_date", disbursement.posting_date)
- frappe.db.set_value("Loan", doc.name , "repayment_start_date", disbursement.posting_date)
+ disbursement = frappe.db.sql("""
+ select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
+ from `tabGL Entry`
+ where account = %s and against_voucher_type = 'Loan' and against_voucher = %s
+ """, (doc.payment_account, doc.name), as_dict=1)[0]
-def check_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
+ disbursement_date = None
+ if not disbursement or disbursement.disbursed_amount == 0:
+ status = "Sanctioned"
+ elif disbursement.disbursed_amount == doc.loan_amount:
+ disbursement_date = disbursement.posting_date
+ status = "Disbursed"
+ elif disbursement.disbursed_amount > doc.loan_amount:
+ frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(doc.loan_amount))
+
+ if status == 'Disbursed' and getdate(disbursement_date) > getdate(frappe.db.get_value("Loan", doc.name, "repayment_start_date")):
+ frappe.throw(_("Disbursement Date cannot be after Loan Repayment Start Date"))
+
+ frappe.db.sql("""
+ update `tabLoan`
+ set status = %s, disbursement_date = %s
+ where name = %s
+ """, (status, disbursement_date, doc.name))
+
+def validate_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
if repayment_method == "Repay Over Number of Periods" and not repayment_periods:
frappe.throw(_("Please enter Repayment Periods"))
@@ -222,4 +237,4 @@
"reference_name": loan,
})
journal_entry.set("accounts", account_amt_list)
- return journal_entry.as_dict()
\ No newline at end of file
+ return journal_entry.as_dict()
diff --git a/erpnext/hr/doctype/loan_application/loan_application.js b/erpnext/hr/doctype/loan_application/loan_application.js
index febcbd8..a73b62a 100644
--- a/erpnext/hr/doctype/loan_application/loan_application.js
+++ b/erpnext/hr/doctype/loan_application/loan_application.js
@@ -23,9 +23,8 @@
},
add_toolbar_buttons: function(frm) {
if (frm.doc.status == "Approved") {
- frm.add_custom_button(__('Loan'), function() {
+ frm.add_custom_button(__('Create Loan'), function() {
frappe.call({
- type: "GET",
method: "erpnext.hr.doctype.loan_application.loan_application.make_loan",
args: {
"source_name": frm.doc.name
@@ -37,7 +36,7 @@
}
}
});
- })
+ }).addClass("btn-primary");
}
}
});
diff --git a/erpnext/hr/doctype/loan_application/loan_application.py b/erpnext/hr/doctype/loan_application/loan_application.py
index 706c964..5dbcf15 100644
--- a/erpnext/hr/doctype/loan_application/loan_application.py
+++ b/erpnext/hr/doctype/loan_application/loan_application.py
@@ -9,11 +9,11 @@
from frappe.model.mapper import get_mapped_doc
from frappe.model.document import Document
-from erpnext.hr.doctype.loan.loan import get_monthly_repayment_amount, check_repayment_method
+from erpnext.hr.doctype.loan.loan import get_monthly_repayment_amount, validate_repayment_method
class LoanApplication(Document):
def validate(self):
- check_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
+ validate_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
self.validate_loan_amount()
self.get_repayment_details()
@@ -29,14 +29,14 @@
if self.repayment_method == "Repay Fixed Amount per Period":
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
if monthly_interest_rate:
- self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
+ self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
math.log(self.repayment_amount - (self.loan_amount*monthly_interest_rate))) /
(math.log(1 + monthly_interest_rate)))
else:
self.repayment_periods = self.loan_amount / self.repayment_amount
self.calculate_payable_amount()
-
+
def calculate_payable_amount(self):
balance_amount = self.loan_amount
self.total_payable_amount = 0
@@ -47,9 +47,9 @@
balance_amount = rounded(balance_amount + interest_amount - self.repayment_amount)
self.total_payable_interest += interest_amount
-
+
self.total_payable_amount = self.loan_amount + self.total_payable_interest
-
+
@frappe.whitelist()
def make_loan(source_name, target_doc = None):
doclist = get_mapped_doc("Loan Application", source_name, {
diff --git a/erpnext/hr/doctype/shift_type/shift_type.py b/erpnext/hr/doctype/shift_type/shift_type.py
index eaf6b1e..b98f445 100644
--- a/erpnext/hr/doctype/shift_type/shift_type.py
+++ b/erpnext/hr/doctype/shift_type/shift_type.py
@@ -22,7 +22,7 @@
'skip_auto_attendance':'0',
'attendance':('is', 'not set'),
'time':('>=', self.process_attendance_after),
- 'shift_actual_start': ('<', self.last_sync_of_checkin),
+ 'shift_actual_end': ('<', self.last_sync_of_checkin),
'shift': self.name
}
logs = frappe.db.get_list('Employee Checkin', fields="*", filters=filters, order_by="employee,time")
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 75eb794..766f675 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -594,6 +594,7 @@
sum(bom_item.{qty_field}/ifnull(bom.quantity, 1)) * %(qty)s as qty,
item.description,
item.image,
+ bom.project,
item.stock_uom,
item.allow_alternative_item,
item_default.default_warehouse,
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 571c2dc..a293785 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -605,6 +605,7 @@
erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019
execute:frappe.delete_doc_if_exists("Page", "support-analytics")
erpnext.patches.v12_0.make_item_manufacturer
+erpnext.patches.v12_0.remove_patient_medical_record_page
erpnext.patches.v11_1.move_customer_lead_to_dynamic_column
erpnext.patches.v11_1.set_default_action_for_quality_inspection
erpnext.patches.v11_1.delete_bom_browser
diff --git a/erpnext/patches/v12_0/remove_patient_medical_record_page.py b/erpnext/patches/v12_0/remove_patient_medical_record_page.py
new file mode 100644
index 0000000..904bfe4
--- /dev/null
+++ b/erpnext/patches/v12_0/remove_patient_medical_record_page.py
@@ -0,0 +1,7 @@
+# Copyright (c) 2019
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.delete_doc("Page", "medical_record")
diff --git a/erpnext/patches/v12_0/set_priority_for_support.py b/erpnext/patches/v12_0/set_priority_for_support.py
index cc29039..5096ed4 100644
--- a/erpnext/patches/v12_0/set_priority_for_support.py
+++ b/erpnext/patches/v12_0/set_priority_for_support.py
@@ -33,19 +33,23 @@
service_level_priorities = frappe.get_list("Service Level", fields=["name", "priority", "response_time", "response_time_period", "resolution_time", "resolution_time_period"])
frappe.reload_doc("support", "doctype", "service_level")
+ frappe.reload_doc("support", "doctype", "support_settings")
+ frappe.db.set_value('Support Settings', None, 'track_service_level_agreement', 1)
for service_level in service_level_priorities:
if service_level:
doc = frappe.get_doc("Service Level", service_level.name)
- doc.append("priorities", {
- "priority": service_level.priority,
- "default_priority": 1,
- "response_time": service_level.response_time,
- "response_time_period": service_level.response_time_period,
- "resolution_time": service_level.resolution_time,
- "resolution_time_period": service_level.resolution_time_period
- })
- doc.save(ignore_permissions=True)
+ if not doc.priorities:
+ doc.append("priorities", {
+ "priority": service_level.priority,
+ "default_priority": 1,
+ "response_time": service_level.response_time,
+ "response_time_period": service_level.response_time_period,
+ "resolution_time": service_level.resolution_time,
+ "resolution_time_period": service_level.resolution_time_period
+ })
+ doc.flags.ignore_validate = True
+ doc.save(ignore_permissions=True)
except frappe.db.TableMissingError:
frappe.reload_doc("support", "doctype", "service_level")
@@ -73,6 +77,7 @@
"resolution_time": service_level_agreement.resolution_time,
"resolution_time_period": service_level_agreement.resolution_time_period
})
+ doc.flags.ignore_validate = True
doc.save(ignore_permissions=True)
except frappe.db.TableMissingError:
frappe.reload_doc("support", "doctype", "service_level_agreement")
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/update_due_date_in_gle.py b/erpnext/patches/v12_0/update_due_date_in_gle.py
index 4c47a82..3484872 100644
--- a/erpnext/patches/v12_0/update_due_date_in_gle.py
+++ b/erpnext/patches/v12_0/update_due_date_in_gle.py
@@ -13,5 +13,5 @@
WHERE
`tabGL Entry`.voucher_no = `tab{doctype}`.name and `tabGL Entry`.party is not null
and `tabGL Entry`.voucher_type in ('Sales Invoice', 'Purchase Invoice', 'Journal Entry')
- and account in (select name from `tabAccount` where account_type in ('Receivable', 'Payable') )""" #nosec
+ and `tabGL Entry`.account in (select name from `tabAccount` where account_type in ('Receivable', 'Payable'))""" #nosec
.format(doctype=doctype))
diff --git a/erpnext/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js
index 91dfe80..89657a1 100644
--- a/erpnext/public/js/call_popup/call_popup.js
+++ b/erpnext/public/js/call_popup/call_popup.js
@@ -109,7 +109,7 @@
});
wrapper.append(`
<div class="caller-info flex">
- ${frappe.avatar(null, 'avatar-xl', contact.name, contact.image)}
+ ${frappe.avatar(null, 'avatar-xl', contact.name, contact.image || '')}
<div>
<h5>${contact_name}</h5>
<div>${contact.mobile_no || ''}</div>
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index ec71df3..095e744 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -52,3 +52,13 @@
"Sales Partner": "Selling",
"Brand": "Selling"
});
+
+$.extend(frappe.breadcrumbs.module_map, {
+ 'ERPNext Integrations': 'Integrations',
+ 'Geo': 'Settings',
+ 'Accounts': 'Accounting',
+ 'Portal': 'Website',
+ 'Utilities': 'Settings',
+ 'Shopping Cart': 'Website',
+ 'Contacts': 'CRM'
+});
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 824b8d9..750900e 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -141,6 +141,7 @@
price_list_rate: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
+
frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]);
let item_rate = item.price_list_rate;
@@ -154,6 +155,8 @@
if (item.discount_amount) {
item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item));
+ } else {
+ item.rate = item_rate;
}
this.calculate_taxes_and_totals();
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index cf48be4..0cd648e 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -573,7 +573,6 @@
if(!r.exc) {
var doc = frappe.model.sync(r.message);
cur_frm.dirty();
- erpnext.utils.clear_duplicates();
cur_frm.refresh();
}
}
@@ -604,28 +603,6 @@
}
}
-erpnext.utils.clear_duplicates = function() {
- if(!cur_frm.doc.items) return;
- const unique_items = new Map();
- /*
- Create a Map of items with
- item_code => [qty, warehouse, batch_no]
- */
- let items = [];
-
- for (let item of cur_frm.doc.items) {
- if (!(unique_items.has(item.item_code) && unique_items.get(item.item_code)[0] === item.qty &&
- unique_items.get(item.item_code)[1] === item.warehouse && unique_items.get(item.item_code)[2] === item.batch_no &&
- unique_items.get(item.item_code)[3] === item.delivery_date && unique_items.get(item.item_code)[4] === item.required_date &&
- unique_items.get(item.item_code)[5] === item.rate)) {
-
- unique_items.set(item.item_code, [item.qty, item.warehouse, item.batch_no, item.delivery_date, item.required_date, item.rate]);
- items.push(item);
- }
- }
- cur_frm.doc.items = items;
-}
-
frappe.form.link_formatters['Item'] = function(value, doc) {
if(doc && doc.item_name && doc.item_name !== value) {
return value? value + ': ' + doc.item_name: doc.item_name;
diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py
index 87ca6a7..8e790bf 100644
--- a/erpnext/selling/doctype/customer/customer_dashboard.py
+++ b/erpnext/selling/doctype/customer/customer_dashboard.py
@@ -26,10 +26,6 @@
'items': ['Sales Order', 'Delivery Note', 'Sales Invoice']
},
{
- 'label': _('Service Level Agreement'),
- 'items': ['Service Level Agreement']
- },
- {
'label': _('Payments'),
'items': ['Payment Entry']
},
diff --git a/erpnext/selling/doctype/installation_note/installation_note.js b/erpnext/selling/doctype/installation_note/installation_note.js
index a8d9ae8..7fd0877 100644
--- a/erpnext/selling/doctype/installation_note/installation_note.js
+++ b/erpnext/selling/doctype/installation_note/installation_note.js
@@ -3,7 +3,7 @@
frappe.ui.form.on('Installation Note', {
setup: function(frm) {
- frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'customer', doctype: 'Customer'}
frm.set_query('customer_address', erpnext.queries.address_query);
frm.set_query('contact_person', erpnext.queries.contact_query);
frm.set_query('customer', erpnext.queries.customer);
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 26ca7c6..39dda92 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -107,7 +107,7 @@
refresh: function(doc, dt, dn) {
var me = this;
this._super();
- var allow_delivery = false;
+ let allow_delivery = false;
if(doc.docstatus==1) {
if(this.frm.has_perm("submit")) {
@@ -132,6 +132,8 @@
if(doc.status !== 'Closed') {
if(doc.status !== 'On Hold') {
+ allow_delivery = this.frm.doc.items.some(item => item.delivered_by_supplier === 0 && item.qty > flt(item.delivered_qty))
+
if (this.frm.has_perm("submit")) {
if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
// hold
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 6c0b02d..e9b310e 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -492,13 +492,27 @@
frappe.local.message_log = []
+def get_requested_item_qty(sales_order):
+ return frappe._dict(frappe.db.sql("""
+ select sales_order_item, sum(stock_qty)
+ from `tabMaterial Request Item`
+ where docstatus = 1
+ and sales_order = %s
+ group by sales_order_item
+ """, sales_order))
+
@frappe.whitelist()
def make_material_request(source_name, target_doc=None):
+ requested_item_qty = get_requested_item_qty(source_name)
+
def postprocess(source, doc):
doc.material_request_type = "Purchase"
def update_item(source, target, source_parent):
target.project = source_parent.project
+ target.qty = source.stock_qty - requested_item_qty.get(source.name, 0)
+ target.conversion_factor = 1
+ target.stock_qty = source.stock_qty - requested_item_qty.get(source.name, 0)
doc = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
@@ -523,7 +537,7 @@
"stock_uom": "uom",
"stock_qty": "qty"
},
- "condition": lambda doc: not frappe.db.exists('Product Bundle', doc.item_code),
+ "condition": lambda doc: not frappe.db.exists('Product Bundle', doc.item_code) and doc.stock_qty > requested_item_qty.get(doc.name, 0),
"postprocess": update_item
}
}, target_doc, postprocess)
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.js b/erpnext/selling/report/sales_analytics/sales_analytics.js
index fbe045b..149c923 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.js
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.js
@@ -8,7 +8,7 @@
fieldname: "tree_type",
label: __("Tree Type"),
fieldtype: "Select",
- options: ["Customer Group","Customer","Item Group","Item","Territory"],
+ options: ["Customer Group","Customer","Item Group","Item","Territory","Order Type"],
default: "Customer",
reqd: 1
},
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py
index 3239fc6..8a5e50a 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.py
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.py
@@ -23,15 +23,15 @@
self.get_columns()
self.get_data()
self.get_chart_data()
- return self.columns, self.data , None, self.chart
+ return self.columns, self.data, None, self.chart
def get_columns(self):
- self.columns =[{
+ self.columns = [{
"label": _(self.filters.tree_type + " ID"),
- "options": self.filters.tree_type,
+ "options": self.filters.tree_type if self.filters.tree_type != "Order Type" else "",
"fieldname": "entity",
- "fieldtype": "Link",
- "width": 140
+ "fieldtype": "Link" if self.filters.tree_type != "Order Type" else "Data",
+ "width": 140 if self.filters.tree_type != "Order Type" else 200
}]
if self.filters.tree_type in ["Customer", "Supplier", "Item"]:
self.columns.append({
@@ -73,6 +73,28 @@
self.get_sales_transactions_based_on_item_group()
self.get_rows_by_group()
+ elif self.filters.tree_type == "Order Type":
+ if self.filters.doc_type != "Sales Order":
+ self.data = []
+ return
+ self.get_sales_transactions_based_on_order_type()
+ self.get_rows_by_group()
+
+ def get_sales_transactions_based_on_order_type(self):
+ if self.filters["value_quantity"] == 'Value':
+ value_field = "base_net_total"
+ else:
+ value_field = "total_qty"
+
+ self.entries = frappe.db.sql(""" select s.order_type as entity, s.{value_field} as value_field, s.{date_field}
+ from `tab{doctype}` s where s.docstatus = 1 and s.company = %s and s.{date_field} between %s and %s
+ and ifnull(s.order_type, '') != '' order by s.order_type
+ """
+ .format(date_field=self.date_field, value_field=value_field, doctype=self.filters.doc_type),
+ (self.filters.company, self.filters.from_date, self.filters.to_date), as_dict=1)
+
+ self.get_teams()
+
def get_sales_transactions_based_on_customers_or_suppliers(self):
if self.filters["value_quantity"] == 'Value':
value_field = "base_net_total as value_field"
@@ -88,7 +110,7 @@
self.entries = frappe.get_all(self.filters.doc_type,
fields=[entity, entity_name, value_field, self.date_field],
- filters = {
+ filters={
"docstatus": 1,
"company": self.filters.company,
self.date_field: ('between', [self.filters.from_date, self.filters.to_date])
@@ -112,7 +134,7 @@
where s.name = i.parent and i.docstatus = 1 and s.company = %s
and s.{date_field} between %s and %s
"""
- .format(date_field=self.date_field, value_field = value_field, doctype=self.filters.doc_type),
+ .format(date_field=self.date_field, value_field=value_field, doctype=self.filters.doc_type),
(self.filters.company, self.filters.from_date, self.filters.to_date), as_dict=1)
self.entity_names = {}
@@ -135,7 +157,7 @@
self.entries = frappe.get_all(self.filters.doc_type,
fields=[entity_field, value_field, self.date_field],
- filters = {
+ filters={
"docstatus": 1,
"company": self.filters.company,
self.date_field: ('between', [self.filters.from_date, self.filters.to_date])
@@ -154,13 +176,13 @@
from `tab{doctype} Item` i , `tab{doctype}` s
where s.name = i.parent and i.docstatus = 1 and s.company = %s
and s.{date_field} between %s and %s
- """.format(date_field=self.date_field, value_field = value_field, doctype=self.filters.doc_type),
+ """.format(date_field=self.date_field, value_field=value_field, doctype=self.filters.doc_type),
(self.filters.company, self.filters.from_date, self.filters.to_date), as_dict=1)
self.get_groups()
def get_rows(self):
- self.data=[]
+ self.data = []
self.get_periodic_data()
for entity, period_data in iteritems(self.entity_periodic_data):
@@ -192,7 +214,7 @@
period = self.get_period(end_date)
amount = flt(self.entity_periodic_data.get(d.name, {}).get(period, 0.0))
row[scrub(period)] = amount
- if d.parent:
+ if d.parent and (self.filters.tree_type != "Order Type" or d.parent == "Order Types"):
self.entity_periodic_data.setdefault(d.parent, frappe._dict()).setdefault(period, 0.0)
self.entity_periodic_data[d.parent][period] += amount
total += amount
@@ -216,7 +238,7 @@
elif self.filters.range == 'Monthly':
period = str(self.months[posting_date.month - 1]) + " " + str(posting_date.year)
elif self.filters.range == 'Quarterly':
- period = "Quarter " + str(((posting_date.month-1)//3)+1) +" " + str(posting_date.year)
+ period = "Quarter " + str(((posting_date.month - 1) // 3) + 1) + " " + str(posting_date.year)
else:
year = get_fiscal_year(posting_date, company=self.filters.company)
period = str(year[0])
@@ -234,7 +256,7 @@
}.get(self.filters.range, 1)
if self.filters.range in ['Monthly', 'Quarterly']:
- from_date = from_date.replace(day = 1)
+ from_date = from_date.replace(day=1)
elif self.filters.range == "Yearly":
from_date = get_fiscal_year(from_date)[1]
else:
@@ -270,7 +292,22 @@
self.group_entries = frappe.db.sql("""select name, lft, rgt , {parent} as parent
from `tab{tree}` order by lft"""
- .format(tree=self.filters.tree_type, parent=parent), as_dict=1)
+ .format(tree=self.filters.tree_type, parent=parent), as_dict=1)
+
+ for d in self.group_entries:
+ if d.parent:
+ self.depth_map.setdefault(d.name, self.depth_map.get(d.parent) + 1)
+ else:
+ self.depth_map.setdefault(d.name, 0)
+
+ def get_teams(self):
+ self.depth_map = frappe._dict()
+
+ self.group_entries = frappe.db.sql(""" select * from (select "Order Types" as name, 0 as lft,
+ 2 as rgt, '' as parent union select distinct order_type as name, 1 as lft, 1 as rgt, "Order Types" as parent
+ from `tab{doctype}` where ifnull(order_type, '') != '') as b order by lft, name
+ """
+ .format(doctype=self.filters.doc_type), as_dict=1)
for d in self.group_entries:
if d.parent:
@@ -285,13 +322,13 @@
length = len(self.columns)
if self.filters.tree_type in ["Customer", "Supplier", "Item"]:
- labels = [d.get("label") for d in self.columns[2:length-1]]
+ labels = [d.get("label") for d in self.columns[2:length - 1]]
else:
- labels = [d.get("label") for d in self.columns[1:length-1]]
+ labels = [d.get("label") for d in self.columns[1:length - 1]]
self.chart = {
"data": {
'labels': labels,
- 'datasets':[]
+ 'datasets': []
},
"type": "line"
- }
\ No newline at end of file
+ }
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 4019e07..62bde42 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -61,7 +61,7 @@
quotation.flags.ignore_permissions = True
quotation.submit()
- if quotation.lead:
+ if quotation.quotation_to == 'Lead' and quotation.party_name:
# company used to create customer accounts
frappe.defaults.set_user_default("company", quotation.company)
diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py
index d182290..30675b5 100644
--- a/erpnext/stock/doctype/item_price/item_price.py
+++ b/erpnext/stock/doctype/item_price/item_price.py
@@ -31,13 +31,16 @@
frappe.throw(_("Valid From Date must be lesser than Valid Upto Date."))
def update_price_list_details(self):
- self.buying, self.selling, self.currency = \
- frappe.db.get_value("Price List",
- {"name": self.price_list, "enabled": 1},
- ["buying", "selling", "currency"])
+ if self.price_list:
+ self.buying, self.selling, self.currency = \
+ frappe.db.get_value("Price List",
+ {"name": self.price_list, "enabled": 1},
+ ["buying", "selling", "currency"])
def update_item_details(self):
- self.item_name, self.item_description = frappe.db.get_value("Item",self.item_code,["item_name", "description"])
+ if self.item_code:
+ self.item_name, self.item_description = frappe.db.get_value("Item",
+ self.item_code,["item_name", "description"])
def check_duplicates(self):
conditions = "where item_code=%(item_code)s and price_list=%(price_list)s and name != %(name)s"
diff --git a/erpnext/stock/doctype/manufacturer/manufacturer.js b/erpnext/stock/doctype/manufacturer/manufacturer.js
index 67df1bf..bb7e314 100644
--- a/erpnext/stock/doctype/manufacturer/manufacturer.js
+++ b/erpnext/stock/doctype/manufacturer/manufacturer.js
@@ -3,6 +3,14 @@
frappe.ui.form.on('Manufacturer', {
refresh: function(frm) {
-
+ frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Manufacturer' };
+ if (frm.doc.__islocal) {
+ hide_field(['address_html','contact_html']);
+ frappe.contacts.clear_address_and_contact(frm);
+ }
+ else {
+ unhide_field(['address_html','contact_html']);
+ frappe.contacts.render_address_and_contact(frm);
+ }
}
});
diff --git a/erpnext/stock/doctype/manufacturer/manufacturer.json b/erpnext/stock/doctype/manufacturer/manufacturer.json
index 5025917..3a64fbe 100644
--- a/erpnext/stock/doctype/manufacturer/manufacturer.json
+++ b/erpnext/stock/doctype/manufacturer/manufacturer.json
@@ -1,268 +1,120 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:short_name",
- "beta": 0,
- "creation": "2016-01-17 11:04:52.761731",
- "custom": 0,
- "description": "Manufacturers used in Items",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:short_name",
+ "creation": "2016-01-17 11:04:52.761731",
+ "description": "Manufacturers used in Items",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "engine": "InnoDB",
+ "field_order": [
+ "short_name",
+ "full_name",
+ "website",
+ "country",
+ "logo",
+ "address_contacts",
+ "address_html",
+ "column_break_8",
+ "contact_html",
+ "section_break_10",
+ "notes"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Limited to 12 characters",
- "fieldname": "short_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": "Short Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "description": "Limited to 12 characters",
+ "fieldname": "short_name",
+ "fieldtype": "Data",
+ "label": "Short Name",
+ "reqd": 1,
+ "unique": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "full_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Full 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,
- "unique": 0
- },
+ "fieldname": "full_name",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Full Name"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "website",
- "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": "Website",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "website",
+ "fieldtype": "Data",
+ "label": "Website"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "country",
- "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": "Country",
- "length": 0,
- "no_copy": 0,
- "options": "Country",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "country",
+ "fieldtype": "Link",
+ "label": "Country",
+ "options": "Country"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "logo",
- "fieldtype": "Attach Image",
- "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": "Logo",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "logo",
+ "fieldtype": "Attach Image",
+ "label": "Logo"
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "notes",
- "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": "Notes",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
+ "fieldname": "notes",
+ "fieldtype": "Small Text",
+ "label": "Notes"
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "address_contacts",
+ "fieldtype": "Section Break",
+ "label": "Address and Contacts",
+ "options": "fa fa-map-marker"
+ },
+ {
+ "fieldname": "address_html",
+ "fieldtype": "HTML",
+ "label": "Address HTML",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_8",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "contact_html",
+ "fieldtype": "HTML",
+ "label": "Contact HTML",
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-certificate",
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2017-08-03 06:27:57.182666",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Manufacturer",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "icon": "fa fa-certificate",
+ "modified": "2019-07-06 13:06:47.237014",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Manufacturer",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Stock Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Stock Manager",
+ "share": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Stock User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 0
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Stock User",
+ "share": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "short_name, full_name",
- "show_name_in_global_search": 1,
- "sort_field": "",
- "sort_order": "DESC",
- "title_field": "short_name",
- "track_changes": 0,
- "track_seen": 0
+ ],
+ "search_fields": "short_name, full_name",
+ "show_name_in_global_search": 1,
+ "sort_order": "DESC",
+ "title_field": "short_name"
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/manufacturer/manufacturer.py b/erpnext/stock/doctype/manufacturer/manufacturer.py
index 7b85b05..b624f73 100644
--- a/erpnext/stock/doctype/manufacturer/manufacturer.py
+++ b/erpnext/stock/doctype/manufacturer/manufacturer.py
@@ -4,7 +4,10 @@
from __future__ import unicode_literals
import frappe
+from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
from frappe.model.document import Document
class Manufacturer(Document):
- pass
+ def onload(self):
+ """Load address and contacts in `__onload`"""
+ load_address_and_contact(self)
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 5351f32..96e31ff 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -211,6 +211,7 @@
d.stock_uom = item.stock_uom;
d.conversion_factor = 1;
d.qty = item.qty;
+ d.project = item.project;
});
}
d.hide();
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 2b079e7..f2fe448 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -450,7 +450,7 @@
"field_map": {
"name": "material_request_item",
"parent": "material_request",
- "uom": "stock_uom",
+ "uom": "stock_uom"
},
"postprocess": update_item,
"condition": lambda doc: doc.ordered_qty < doc.stock_qty
diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.json b/erpnext/stock/doctype/quality_inspection/quality_inspection.json
index 94d4794..a9f3cd0 100644
--- a/erpnext/stock/doctype/quality_inspection/quality_inspection.json
+++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.json
@@ -1,857 +1,260 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2013-04-30 13:13:03",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "autoname": "naming_series:",
+ "creation": "2013-04-30 13:13:03",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "naming_series",
+ "report_date",
+ "column_break_4",
+ "inspection_type",
+ "reference_type",
+ "reference_name",
+ "section_break_7",
+ "item_code",
+ "item_serial_no",
+ "batch_no",
+ "sample_size",
+ "column_break1",
+ "item_name",
+ "description",
+ "status",
+ "section_break_14",
+ "inspected_by",
+ "verified_by",
+ "bom_no",
+ "column_break_17",
+ "remarks",
+ "amended_from",
+ "specification_details",
+ "quality_inspection_template",
+ "readings"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "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": "Series",
- "length": 0,
- "no_copy": 1,
- "options": "MAT-QA-.YYYY.-",
- "permlevel": 0,
- "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": 1,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "no_copy": 1,
+ "options": "MAT-QA-.YYYY.-",
+ "reqd": 1,
+ "set_only_once": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "report_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": "Report Date",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "report_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "default": "Today",
+ "fieldname": "report_date",
+ "fieldtype": "Date",
+ "in_list_view": 1,
+ "label": "Report Date",
+ "oldfieldname": "report_date",
+ "oldfieldtype": "Date",
+ "reqd": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_4",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "inspection_type",
- "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": 1,
- "label": "Inspection Type",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "inspection_type",
- "oldfieldtype": "Select",
- "options": "\nIncoming\nOutgoing\nIn Process",
- "permlevel": 0,
- "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
- },
+ "fieldname": "inspection_type",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Inspection Type",
+ "oldfieldname": "inspection_type",
+ "oldfieldtype": "Select",
+ "options": "\nIncoming\nOutgoing\nIn Process",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference_type",
- "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": "Reference Type",
- "length": 0,
- "no_copy": 0,
- "options": "\nPurchase Receipt\nPurchase Invoice\nDelivery Note\nSales Invoice\nStock Entry",
- "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
- },
+ "fieldname": "reference_type",
+ "fieldtype": "Select",
+ "label": "Reference Type",
+ "options": "\nPurchase Receipt\nPurchase Invoice\nDelivery Note\nSales Invoice\nStock Entry"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "reference_name",
- "fieldtype": "Dynamic 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": 1,
- "label": "Reference Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "purchase_receipt_no",
- "oldfieldtype": "Link",
- "options": "reference_type",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Reference Name",
+ "oldfieldname": "purchase_receipt_no",
+ "oldfieldtype": "Link",
+ "options": "reference_type"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_7",
- "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
- },
+ "fieldname": "section_break_7",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_code",
- "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": 1,
- "label": "Item Code",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "item_code",
- "oldfieldtype": "Link",
- "options": "Item",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Item Code",
+ "oldfieldname": "item_code",
+ "oldfieldtype": "Link",
+ "options": "Item",
+ "reqd": 1,
+ "search_index": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_serial_no",
- "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 Serial No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "item_serial_no",
- "oldfieldtype": "Link",
- "options": "Serial No",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "item_serial_no",
+ "fieldtype": "Link",
+ "label": "Item Serial No",
+ "oldfieldname": "item_serial_no",
+ "oldfieldtype": "Link",
+ "options": "Serial No"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "batch_no",
- "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": "Batch No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "batch_no",
- "oldfieldtype": "Link",
- "options": "Batch",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "batch_no",
+ "fieldtype": "Link",
+ "label": "Batch No",
+ "oldfieldname": "batch_no",
+ "oldfieldtype": "Link",
+ "options": "Batch"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sample_size",
- "fieldtype": "Float",
- "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": "Sample Size",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "sample_size",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "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
- },
+ "fieldname": "sample_size",
+ "fieldtype": "Float",
+ "label": "Sample Size",
+ "oldfieldname": "sample_size",
+ "oldfieldtype": "Currency",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break1",
- "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,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "oldfieldtype": "Column Break",
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_name",
- "fieldtype": "Data",
- "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": "Item Name",
- "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
- },
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "label": "Item Name",
+ "read_only": 1
+ },
{
- "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,
- "oldfieldname": "description",
- "oldfieldtype": "Small Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description",
+ "oldfieldname": "description",
+ "oldfieldtype": "Small Text",
"width": "300px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_14",
- "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
- },
+ "fieldname": "section_break_14",
+ "fieldtype": "Section Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "user",
- "fieldname": "inspected_by",
- "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": "Inspected By",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "inspected_by",
- "oldfieldtype": "Data",
- "options": "User",
- "permlevel": 0,
- "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
- },
+ "default": "user",
+ "fieldname": "inspected_by",
+ "fieldtype": "Link",
+ "label": "Inspected By",
+ "oldfieldname": "inspected_by",
+ "oldfieldtype": "Data",
+ "options": "User",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "verified_by",
- "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": "Verified By",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "verified_by",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "verified_by",
+ "fieldtype": "Data",
+ "label": "Verified By",
+ "oldfieldname": "verified_by",
+ "oldfieldtype": "Data"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "bom_no",
- "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": "BOM No",
- "length": 0,
- "no_copy": 0,
- "options": "BOM",
- "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
- },
+ "fieldname": "bom_no",
+ "fieldtype": "Link",
+ "label": "BOM No",
+ "options": "BOM",
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_17",
- "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
- },
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "remarks",
- "fieldtype": "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": "Remarks",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "remarks",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "remarks",
+ "fieldtype": "Text",
+ "label": "Remarks",
+ "no_copy": 1,
+ "oldfieldname": "remarks",
+ "oldfieldtype": "Text"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amended_from",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Amended From",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "amended_from",
- "oldfieldtype": "Data",
- "options": "Quality Inspection",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Amended From",
+ "no_copy": 1,
+ "oldfieldname": "amended_from",
+ "oldfieldtype": "Data",
+ "options": "Quality Inspection",
+ "print_hide": 1,
+ "read_only": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "specification_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": "",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Section Break",
- "options": "Simple",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "specification_details",
+ "fieldtype": "Section Break",
+ "oldfieldtype": "Section Break",
+ "options": "Simple"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "quality_inspection_template",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Quality Inspection Template",
- "length": 0,
- "no_copy": 0,
- "options": "Quality Inspection Template",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
+ "fieldname": "quality_inspection_template",
+ "fieldtype": "Link",
+ "label": "Quality Inspection Template",
+ "options": "Quality Inspection Template"
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "readings",
- "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": "Readings",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "qa_specification_details",
- "oldfieldtype": "Table",
- "options": "Quality Inspection Reading",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "fieldname": "readings",
+ "fieldtype": "Table",
+ "label": "Readings",
+ "oldfieldname": "qa_specification_details",
+ "oldfieldtype": "Table",
+ "options": "Quality Inspection Reading"
+ },
+ {
+ "default": "Accepted",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "label": "Status",
+ "options": "\nAccepted\nRejected",
+ "reqd": 1
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-search",
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-21 14:44:45.996446",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Quality Inspection",
- "owner": "Administrator",
+ ],
+ "icon": "fa fa-search",
+ "idx": 1,
+ "is_submittable": 1,
+ "modified": "2019-07-12 12:07:23.153698",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Quality Inspection",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Quality Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Quality Manager",
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "item_code, report_date, reference_name",
- "show_name_in_global_search": 1,
- "sort_order": "ASC",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "search_fields": "item_code, report_date, reference_name",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "ASC"
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json
index 94aecfe..f9f8a71 100644
--- a/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json
+++ b/erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json
@@ -1,413 +1,138 @@
{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "hash",
- "beta": 0,
- "creation": "2013-02-22 01:27:43",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "editable_grid": 1,
+ "autoname": "hash",
+ "creation": "2013-02-22 01:27:43",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "field_order": [
+ "specification",
+ "value",
+ "reading_1",
+ "reading_2",
+ "reading_3",
+ "reading_4",
+ "reading_5",
+ "reading_6",
+ "reading_7",
+ "reading_8",
+ "reading_9",
+ "reading_10",
+ "status"
+ ],
"fields": [
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "specification",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Parameter",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "specification",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 3,
+ "fieldname": "specification",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Parameter",
+ "oldfieldname": "specification",
+ "oldfieldtype": "Data",
+ "reqd": 1
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "value",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Acceptance Criteria",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "value",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "value",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Acceptance Criteria",
+ "oldfieldname": "value",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_1",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Reading 1",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_1",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 1,
+ "fieldname": "reading_1",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Reading 1",
+ "oldfieldname": "reading_1",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_2",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Reading 2",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_2",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 1,
+ "fieldname": "reading_2",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Reading 2",
+ "oldfieldname": "reading_2",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_3",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Reading 3",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_3",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 1,
+ "fieldname": "reading_3",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Reading 3",
+ "oldfieldname": "reading_3",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_4",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Reading 4",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_4",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "reading_4",
+ "fieldtype": "Data",
+ "label": "Reading 4",
+ "oldfieldname": "reading_4",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_5",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reading 5",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_5",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "reading_5",
+ "fieldtype": "Data",
+ "label": "Reading 5",
+ "oldfieldname": "reading_5",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_6",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reading 6",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_6",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "reading_6",
+ "fieldtype": "Data",
+ "label": "Reading 6",
+ "oldfieldname": "reading_6",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_7",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reading 7",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_7",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "reading_7",
+ "fieldtype": "Data",
+ "label": "Reading 7",
+ "oldfieldname": "reading_7",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_8",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reading 8",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_8",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "reading_8",
+ "fieldtype": "Data",
+ "label": "Reading 8",
+ "oldfieldname": "reading_8",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_9",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reading 9",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_9",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "reading_9",
+ "fieldtype": "Data",
+ "label": "Reading 9",
+ "oldfieldname": "reading_9",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reading_10",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Reading 10",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "reading_10",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "fieldname": "reading_10",
+ "fieldtype": "Data",
+ "label": "Reading 10",
+ "oldfieldname": "reading_10",
+ "oldfieldtype": "Data"
+ },
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Accepted",
- "fieldname": "status",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Status",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "status",
- "oldfieldtype": "Select",
- "options": "Accepted\nRejected",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
+ "columns": 2,
+ "default": "Accepted",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "Status",
+ "oldfieldname": "status",
+ "oldfieldtype": "Select",
+ "options": "Accepted\nRejected"
}
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
-
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2016-11-16 03:55:50.046712",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Quality Inspection Reading",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "track_seen": 0
+ ],
+ "idx": 1,
+ "istable": 1,
+ "modified": "2019-07-11 18:48:12.667404",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Quality Inspection Reading",
+ "owner": "Administrator",
+ "permissions": [],
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
index 5933700..912a465 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
@@ -61,7 +61,8 @@
"ste_detail",
"column_break_51",
"transferred_qty",
- "reference_purchase_receipt"
+ "reference_purchase_receipt",
+ "project"
],
"fields": [
{
@@ -472,11 +473,18 @@
"label": "Reference Purchase Receipt",
"options": "Purchase Receipt",
"read_only": 1
+ },
+ {
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "label": "Project",
+ "options": "Project",
+ "read_only": 1
}
],
"idx": 1,
"istable": 1,
- "modified": "2019-06-14 11:58:41.958144",
+ "modified": "2019-07-12 11:34:53.190749",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Entry Detail",
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 1a272d1..aec9db9 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -2,6 +2,12 @@
onload: function(frm) {
frm.email_field = "raised_by";
+ frappe.db.get_value("Support Settings", {name: "Support Settings"}, "allow_resetting_service_level_agreement", (r) => {
+ if (!r.allow_resetting_service_level_agreement) {
+ frm.set_df_property("reset_service_level_agreement", "hidden", 1) ;
+ }
+ });
+
if (frm.doc.service_level_agreement) {
frappe.call({
method: "erpnext.support.doctype.service_level_agreement.service_level_agreement.get_service_level_agreement_filters",
@@ -73,6 +79,42 @@
}
},
+ reset_service_level_agreement: function(frm) {
+ let reset_sla = new frappe.ui.Dialog({
+ title: __("Reset Service Level Agreement"),
+ fields: [
+ {
+ fieldtype: "Data",
+ fieldname: "reason",
+ label: __("Reason"),
+ reqd: 1
+ }
+ ],
+ primary_action_label: __("Reset"),
+ primary_action: (values) => {
+ reset_sla.disable_primary_action();
+ reset_sla.hide();
+ reset_sla.clear();
+
+ frappe.show_alert({
+ indicator: 'green',
+ message: __('Resetting Service Level Agreement.')
+ });
+
+ frm.call("reset_service_level_agreement", {
+ reason: values.reason,
+ user: frappe.session.user_email
+ }, () => {
+ reset_sla.enable_primary_action();
+ frm.refresh();
+ frappe.msgprint(__("Service Level Agreement Reset."));
+ });
+ }
+ });
+
+ reset_sla.show();
+ },
+
timeline_refresh: function(frm) {
// create button for "Help Article"
if(frappe.model.can_create('Help Article')) {
@@ -129,8 +171,15 @@
function set_time_to_resolve_and_response(frm) {
frm.dashboard.clear_headline();
- var time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_fulfilled);
- var time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_fulfilled);
+ var time_to_respond = get_status(frm.doc.response_by_variance);
+ if (!frm.doc.first_responded_on && frm.doc.agreement_fulfilled === "Ongoing") {
+ time_to_respond = get_time_left(frm.doc.response_by, frm.doc.agreement_fulfilled);
+ }
+
+ var time_to_resolve = get_status(frm.doc.resolution_by_variance);
+ if (!frm.doc.resolution_date && frm.doc.agreement_fulfilled === "Ongoing") {
+ time_to_resolve = get_time_left(frm.doc.resolution_by, frm.doc.agreement_fulfilled);
+ }
frm.dashboard.set_headline_alert(
'<div class="row">' +
@@ -146,7 +195,15 @@
function get_time_left(timestamp, agreement_fulfilled) {
const diff = moment(timestamp).diff(moment());
- const diff_display = diff >= 44500 ? moment.duration(diff).humanize() : moment(0, 'seconds').format('HH:mm');
- let indicator = (diff_display == '00:00' && agreement_fulfilled != "Fulfilled") ? "red" : "green";
+ const diff_display = diff >= 44500 ? moment.duration(diff).humanize() : "Failed";
+ let indicator = (diff_display == 'Failed' && agreement_fulfilled != "Fulfilled") ? "red" : "green";
return {"diff_display": diff_display, "indicator": indicator};
}
+
+function get_status(variance) {
+ if (variance > 0) {
+ return {"diff_display": "Fulfilled", "indicator": "green"};
+ } else {
+ return {"diff_display": "Failed", "indicator": "red"};
+ }
+}
\ No newline at end of file
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index b7c4166..1e5d5f9 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -1,365 +1,384 @@
{
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "naming_series:",
- "creation": "2013-02-01 10:36:25",
- "doctype": "DocType",
- "document_type": "Setup",
- "engine": "InnoDB",
- "field_order": [
- "subject_section",
- "naming_series",
- "subject",
- "customer",
- "raised_by",
- "cb00",
- "status",
- "priority",
- "issue_type",
- "sb_details",
- "description",
- "service_level_section",
- "service_level_agreement",
- "response_by",
- "response_by_variance",
- "cb",
- "agreement_fulfilled",
- "resolution_by",
- "resolution_by_variance",
- "response",
- "mins_to_first_response",
- "first_responded_on",
- "additional_info",
- "lead",
- "contact",
- "email_account",
- "column_break_16",
- "customer_name",
- "project",
- "company",
- "section_break_19",
- "resolution_details",
- "column_break1",
- "opening_date",
- "opening_time",
- "resolution_date",
- "content_type",
- "attachment",
- "via_customer_portal"
- ],
- "fields": [
- {
- "fieldname": "subject_section",
- "fieldtype": "Section Break",
- "label": "Subject",
- "options": "fa fa-flag"
- },
- {
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "label": "Series",
- "no_copy": 1,
- "options": "ISS-.YYYY.-",
- "print_hide": 1,
- "set_only_once": 1
- },
- {
- "bold": 1,
- "fieldname": "subject",
- "fieldtype": "Data",
- "in_global_search": 1,
- "label": "Subject",
- "reqd": 1,
- "in_standard_filter": 1
- },
- {
- "fieldname": "customer",
- "fieldtype": "Link",
- "in_global_search": 1,
- "label": "Customer",
- "oldfieldname": "customer",
- "oldfieldtype": "Link",
- "options": "Customer",
- "print_hide": 1,
- "search_index": 1
- },
- {
- "bold": 1,
- "depends_on": "eval:doc.__islocal",
- "fieldname": "raised_by",
- "fieldtype": "Data",
- "in_global_search": 1,
- "in_list_view": 1,
- "label": "Raised By (Email)",
- "oldfieldname": "raised_by",
- "oldfieldtype": "Data",
- "options": "Email"
- },
- {
- "fieldname": "cb00",
- "fieldtype": "Column Break"
- },
- {
- "default": "Open",
- "fieldname": "status",
- "fieldtype": "Select",
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Status",
- "no_copy": 1,
- "oldfieldname": "status",
- "oldfieldtype": "Select",
- "options": "Open\nReplied\nHold\nClosed",
- "search_index": 1
- },
- {
- "fieldname": "priority",
- "fieldtype": "Link",
- "in_standard_filter": 1,
- "label": "Priority",
- "options": "Issue Priority"
- },
- {
- "fieldname": "issue_type",
- "fieldtype": "Link",
- "label": "Issue Type",
- "options": "Issue Type"
- },
- {
- "collapsible": 1,
- "collapsible_depends_on": "eval:doc.status!=\"Closed\"",
- "fieldname": "sb_details",
- "fieldtype": "Section Break",
- "label": "Details"
- },
- {
- "bold": 1,
- "fieldname": "description",
- "fieldtype": "Text Editor",
- "in_global_search": 1,
- "label": "Description",
- "oldfieldname": "problem_description",
- "oldfieldtype": "Text"
- },
- {
- "collapsible": 1,
- "depends_on": "eval: doc.service_level_agreement",
- "fieldname": "service_level_section",
- "fieldtype": "Section Break",
- "label": "Service Level"
- },
- {
- "fieldname": "service_level_agreement",
- "fieldtype": "Link",
- "label": "Service Level Agreement",
- "options": "Service Level Agreement"
- },
- {
- "fieldname": "response_by",
- "fieldtype": "Datetime",
- "label": "Response By",
- "read_only": 1
- },
- {
- "collapsible": 1,
- "fieldname": "cb",
- "fieldtype": "Column Break",
- "options": "fa fa-pushpin",
- "read_only": 1
- },
- {
- "fieldname": "resolution_by",
- "fieldtype": "Datetime",
- "label": "Resolution By",
- "read_only": 1
- },
- {
- "collapsible": 1,
- "fieldname": "response",
- "fieldtype": "Section Break",
- "label": "Response"
- },
- {
- "bold": 1,
- "fieldname": "mins_to_first_response",
- "fieldtype": "Float",
- "label": "Mins to First Response",
- "read_only": 1
- },
- {
- "fieldname": "first_responded_on",
- "fieldtype": "Datetime",
- "label": "First Responded On"
- },
- {
- "collapsible": 1,
- "fieldname": "additional_info",
- "fieldtype": "Section Break",
- "label": "Reference",
- "options": "fa fa-pushpin",
- "read_only": 1
- },
- {
- "fieldname": "lead",
- "fieldtype": "Link",
- "label": "Lead",
- "options": "Lead"
- },
- {
- "fieldname": "contact",
- "fieldtype": "Link",
- "label": "Contact",
- "options": "Contact"
- },
- {
- "fieldname": "email_account",
- "fieldtype": "Link",
- "label": "Email Account",
- "options": "Email Account"
- },
- {
- "fieldname": "column_break_16",
- "fieldtype": "Column Break"
- },
- {
- "bold": 1,
- "fieldname": "customer_name",
- "fieldtype": "Data",
- "label": "Customer Name",
- "oldfieldname": "customer_name",
- "oldfieldtype": "Data",
- "read_only": 1
- },
- {
- "fieldname": "project",
- "fieldtype": "Link",
- "label": "Project",
- "options": "Project"
- },
- {
- "fieldname": "company",
- "fieldtype": "Link",
- "label": "Company",
- "options": "Company",
- "print_hide": 1
- },
- {
- "collapsible": 1,
- "fieldname": "section_break_19",
- "fieldtype": "Section Break",
- "label": "Resolution"
- },
- {
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "resolution_details",
- "fieldtype": "Text Editor",
- "label": "Resolution Details",
- "no_copy": 1,
- "oldfieldname": "resolution_details",
- "oldfieldtype": "Text"
- },
- {
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "column_break1",
- "fieldtype": "Column Break",
- "oldfieldtype": "Column Break",
- "read_only": 1
- },
- {
- "default": "Today",
- "fieldname": "opening_date",
- "fieldtype": "Date",
- "label": "Opening Date",
- "no_copy": 1,
- "oldfieldname": "opening_date",
- "oldfieldtype": "Date",
- "read_only": 1
- },
- {
- "fieldname": "opening_time",
- "fieldtype": "Time",
- "label": "Opening Time",
- "no_copy": 1,
- "oldfieldname": "opening_time",
- "oldfieldtype": "Time",
- "read_only": 1
- },
- {
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "resolution_date",
- "fieldtype": "Datetime",
- "label": "Resolution Date",
- "no_copy": 1,
- "oldfieldname": "resolution_date",
- "oldfieldtype": "Date",
- "read_only": 1
- },
- {
- "fieldname": "content_type",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Content Type"
- },
- {
- "fieldname": "attachment",
- "fieldtype": "Attach",
- "hidden": 1,
- "label": "Attachment"
- },
- {
- "default": "0",
- "fieldname": "via_customer_portal",
- "fieldtype": "Check",
- "label": "Via Customer Portal"
- },
- {
- "default": "Ongoing",
- "fieldname": "agreement_fulfilled",
- "fieldtype": "Select",
- "label": "Service Level Agreement Fulfilled",
- "options": "Ongoing\nFulfilled\nFailed",
- "read_only": 1
- },
- {
- "description": "in hours",
- "fieldname": "response_by_variance",
- "fieldtype": "Float",
- "label": "Response By Variance",
- "read_only": 1
- },
- {
- "description": "in hours",
- "fieldname": "resolution_by_variance",
- "fieldtype": "Float",
- "label": "Resolution By Variance",
- "read_only": 1
- }
- ],
- "icon": "fa fa-ticket",
- "idx": 7,
- "modified": "2019-06-27 15:19:00.771333",
- "modified_by": "Administrator",
- "module": "Support",
- "name": "Issue",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "delete": 1,
- "email": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Support Team",
- "share": 1,
- "write": 1
- }
- ],
- "quick_entry": 1,
- "search_fields": "status,customer,subject,raised_by",
- "sort_field": "modified",
- "sort_order": "ASC",
- "timeline_field": "customer",
- "title_field": "subject",
- "track_seen": 1
-}
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "naming_series:",
+ "creation": "2013-02-01 10:36:25",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "engine": "InnoDB",
+ "field_order": [
+ "subject_section",
+ "naming_series",
+ "subject",
+ "customer",
+ "raised_by",
+ "cb00",
+ "status",
+ "priority",
+ "issue_type",
+ "sb_details",
+ "description",
+ "service_level_section",
+ "service_level_agreement",
+ "response_by",
+ "response_by_variance",
+ "reset_service_level_agreement",
+ "cb",
+ "agreement_fulfilled",
+ "resolution_by",
+ "resolution_by_variance",
+ "service_level_agreement_creation",
+ "response",
+ "mins_to_first_response",
+ "first_responded_on",
+ "additional_info",
+ "lead",
+ "contact",
+ "email_account",
+ "column_break_16",
+ "customer_name",
+ "project",
+ "company",
+ "section_break_19",
+ "resolution_details",
+ "column_break1",
+ "opening_date",
+ "opening_time",
+ "resolution_date",
+ "content_type",
+ "attachment",
+ "via_customer_portal"
+ ],
+ "fields": [
+ {
+ "fieldname": "subject_section",
+ "fieldtype": "Section Break",
+ "label": "Subject",
+ "options": "fa fa-flag"
+ },
+ {
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "label": "Series",
+ "no_copy": 1,
+ "options": "ISS-.YYYY.-",
+ "print_hide": 1,
+ "set_only_once": 1
+ },
+ {
+ "bold": 1,
+ "fieldname": "subject",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "in_standard_filter": 1,
+ "label": "Subject",
+ "reqd": 1
+ },
+ {
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "in_global_search": 1,
+ "label": "Customer",
+ "oldfieldname": "customer",
+ "oldfieldtype": "Link",
+ "options": "Customer",
+ "print_hide": 1,
+ "search_index": 1
+ },
+ {
+ "bold": 1,
+ "depends_on": "eval:doc.__islocal",
+ "fieldname": "raised_by",
+ "fieldtype": "Data",
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "label": "Raised By (Email)",
+ "oldfieldname": "raised_by",
+ "oldfieldtype": "Data",
+ "options": "Email"
+ },
+ {
+ "fieldname": "cb00",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "Open",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Status",
+ "no_copy": 1,
+ "oldfieldname": "status",
+ "oldfieldtype": "Select",
+ "options": "Open\nReplied\nHold\nClosed",
+ "search_index": 1
+ },
+ {
+ "default": "Medium",
+ "fieldname": "priority",
+ "fieldtype": "Link",
+ "in_standard_filter": 1,
+ "label": "Priority",
+ "options": "Issue Priority"
+ },
+ {
+ "fieldname": "issue_type",
+ "fieldtype": "Link",
+ "label": "Issue Type",
+ "options": "Issue Type"
+ },
+ {
+ "collapsible": 1,
+ "collapsible_depends_on": "eval:doc.status!=\"Closed\"",
+ "fieldname": "sb_details",
+ "fieldtype": "Section Break",
+ "label": "Details"
+ },
+ {
+ "bold": 1,
+ "fieldname": "description",
+ "fieldtype": "Text Editor",
+ "in_global_search": 1,
+ "label": "Description",
+ "oldfieldname": "problem_description",
+ "oldfieldtype": "Text"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "service_level_section",
+ "fieldtype": "Section Break",
+ "label": "Service Level"
+ },
+ {
+ "fieldname": "service_level_agreement",
+ "fieldtype": "Link",
+ "label": "Service Level Agreement",
+ "options": "Service Level Agreement"
+ },
+ {
+ "fieldname": "response_by",
+ "fieldtype": "Datetime",
+ "label": "Response By",
+ "read_only": 1
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "cb",
+ "fieldtype": "Column Break",
+ "options": "fa fa-pushpin",
+ "read_only": 1
+ },
+ {
+ "fieldname": "resolution_by",
+ "fieldtype": "Datetime",
+ "label": "Resolution By",
+ "read_only": 1
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "response",
+ "fieldtype": "Section Break",
+ "label": "Response"
+ },
+ {
+ "bold": 1,
+ "fieldname": "mins_to_first_response",
+ "fieldtype": "Float",
+ "label": "Mins to First Response",
+ "read_only": 1
+ },
+ {
+ "fieldname": "first_responded_on",
+ "fieldtype": "Datetime",
+ "label": "First Responded On"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "additional_info",
+ "fieldtype": "Section Break",
+ "label": "Reference",
+ "options": "fa fa-pushpin",
+ "read_only": 1
+ },
+ {
+ "fieldname": "lead",
+ "fieldtype": "Link",
+ "label": "Lead",
+ "options": "Lead"
+ },
+ {
+ "fieldname": "contact",
+ "fieldtype": "Link",
+ "label": "Contact",
+ "options": "Contact"
+ },
+ {
+ "fieldname": "email_account",
+ "fieldtype": "Link",
+ "label": "Email Account",
+ "options": "Email Account"
+ },
+ {
+ "fieldname": "column_break_16",
+ "fieldtype": "Column Break"
+ },
+ {
+ "bold": 1,
+ "fieldname": "customer_name",
+ "fieldtype": "Data",
+ "label": "Customer Name",
+ "oldfieldname": "customer_name",
+ "oldfieldtype": "Data",
+ "read_only": 1
+ },
+ {
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "label": "Project",
+ "options": "Project"
+ },
+ {
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "label": "Company",
+ "options": "Company",
+ "print_hide": 1
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "section_break_19",
+ "fieldtype": "Section Break",
+ "label": "Resolution"
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "resolution_details",
+ "fieldtype": "Text Editor",
+ "label": "Resolution Details",
+ "no_copy": 1,
+ "oldfieldname": "resolution_details",
+ "oldfieldtype": "Text"
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "oldfieldtype": "Column Break",
+ "read_only": 1
+ },
+ {
+ "default": "Today",
+ "fieldname": "opening_date",
+ "fieldtype": "Date",
+ "label": "Opening Date",
+ "no_copy": 1,
+ "oldfieldname": "opening_date",
+ "oldfieldtype": "Date",
+ "read_only": 1
+ },
+ {
+ "fieldname": "opening_time",
+ "fieldtype": "Time",
+ "label": "Opening Time",
+ "no_copy": 1,
+ "oldfieldname": "opening_time",
+ "oldfieldtype": "Time",
+ "read_only": 1
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "resolution_date",
+ "fieldtype": "Datetime",
+ "label": "Resolution Date",
+ "no_copy": 1,
+ "oldfieldname": "resolution_date",
+ "oldfieldtype": "Date",
+ "read_only": 1
+ },
+ {
+ "fieldname": "content_type",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Content Type"
+ },
+ {
+ "fieldname": "attachment",
+ "fieldtype": "Attach",
+ "hidden": 1,
+ "label": "Attachment"
+ },
+ {
+ "default": "0",
+ "fieldname": "via_customer_portal",
+ "fieldtype": "Check",
+ "label": "Via Customer Portal"
+ },
+ {
+ "default": "Ongoing",
+ "depends_on": "eval: doc.service_level_agreement",
+ "fieldname": "agreement_fulfilled",
+ "fieldtype": "Select",
+ "label": "Service Level Agreement Fulfilled",
+ "options": "Ongoing\nFulfilled\nFailed",
+ "read_only": 1
+ },
+ {
+ "depends_on": "eval: doc.service_level_agreement",
+ "description": "in hours",
+ "fieldname": "response_by_variance",
+ "fieldtype": "Float",
+ "label": "Response By Variance",
+ "read_only": 1
+ },
+ {
+ "depends_on": "eval: doc.service_level_agreement",
+ "description": "in hours",
+ "fieldname": "resolution_by_variance",
+ "fieldtype": "Float",
+ "label": "Resolution By Variance",
+ "read_only": 1
+ },
+ {
+ "fieldname": "service_level_agreement_creation",
+ "fieldtype": "Datetime",
+ "hidden": 1,
+ "label": "Service Level Agreement Creation",
+ "read_only": 1
+ },
+ {
+ "depends_on": "eval: doc.service_level_agreement",
+ "fieldname": "reset_service_level_agreement",
+ "fieldtype": "Button",
+ "label": "Reset Service Level Agreement"
+ }
+ ],
+ "icon": "fa fa-ticket",
+ "idx": 7,
+ "modified": "2019-07-11 23:57:22.015881",
+ "modified_by": "Administrator",
+ "module": "Support",
+ "name": "Issue",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Support Team",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "search_fields": "status,customer,subject,raised_by",
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "timeline_field": "customer",
+ "title_field": "subject",
+ "track_changes": 1,
+ "track_seen": 1
+ }
\ No newline at end of file
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index ad1c263..ce9fb12 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -92,7 +92,6 @@
self.resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_datetime()), 2)
self.agreement_fulfilled = "Fulfilled" if self.response_by_variance > 0 and self.resolution_by_variance > 0 else "Failed"
- self.save(ignore_permissions=True)
def create_communication(self):
communication = frappe.new_doc("Communication")
@@ -118,6 +117,18 @@
replicated_issue = deepcopy(self)
replicated_issue.subject = subject
+ replicated_issue.creation = now_datetime()
+
+ # Reset SLA
+ if replicated_issue.service_level_agreement:
+ replicated_issue.service_level_agreement_creation = now_datetime()
+ replicated_issue.service_level_agreement = None
+ replicated_issue.agreement_fulfilled = "Ongoing"
+ replicated_issue.response_by = None
+ replicated_issue.response_by_variance = None
+ replicated_issue.resolution_by = None
+ replicated_issue.resolution_by_variance = None
+
frappe.get_doc(replicated_issue).insert()
# Replicate linked Communications
@@ -136,7 +147,8 @@
return replicated_issue.name
def before_insert(self):
- self.set_response_and_resolution_time()
+ if frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
+ self.set_response_and_resolution_time()
def set_response_and_resolution_time(self, priority=None, service_level_agreement=None):
service_level_agreement = get_active_service_level_agreement_for(priority=priority,
@@ -162,8 +174,9 @@
if not self.creation:
self.creation = now_datetime()
+ self.service_level_agreement_creation = now_datetime()
- start_date_time = get_datetime(self.creation)
+ start_date_time = get_datetime(self.service_level_agreement_creation)
self.response_by = get_expected_time_for(parameter='response', service_level=priority, start_date_time=start_date_time)
self.resolution_by = get_expected_time_for(parameter='resolution', service_level=priority, start_date_time=start_date_time)
@@ -171,13 +184,33 @@
self.resolution_by_variance = round(time_diff_in_hours(self.resolution_by, now_datetime()))
def change_service_level_agreement_and_priority(self):
- if not self.priority == frappe.db.get_value("Issue", self.name, "priority"):
- self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
- frappe.msgprint("Priority has been updated.")
+ if self.service_level_agreement and frappe.db.exists("Issue", self.name) and \
+ frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
- if not self.service_level_agreement == frappe.db.get_value("Issue", self.name, "service_level_agreement"):
- self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
- frappe.msgprint("Service Level Agreement has been updated.")
+ if not self.priority == frappe.db.get_value("Issue", self.name, "priority"):
+ self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
+ frappe.msgprint(_("Priority has been changed to {0}.").format(self.priority))
+
+ if not self.service_level_agreement == frappe.db.get_value("Issue", self.name, "service_level_agreement"):
+ self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
+ frappe.msgprint(_("Service Level Agreement has been changed to {0}.").format(self.service_level_agreement))
+
+ def reset_service_level_agreement(self, reason, user):
+ if not frappe.db.get_single_value("Support Settings", "allow_resetting_service_level_agreement"):
+ frappe.throw(_("Allow Resetting Service Level Agreement from Support Settings."))
+
+ frappe.get_doc({
+ "doctype": "Comment",
+ "comment_type": "Info",
+ "reference_doctype": self.doctype,
+ "reference_name": self.name,
+ "comment_email": user,
+ "content": " resetted Service Level Agreement - {0}".format(_(reason)),
+ }).insert(ignore_permissions=True)
+
+ self.service_level_agreement_creation = now_datetime()
+ self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement)
+ self.save()
def get_expected_time_for(parameter, service_level, start_date_time):
current_date_time = start_date_time
diff --git a/erpnext/support/doctype/issue/issue_list.js b/erpnext/support/doctype/issue/issue_list.js
index e87c464..6d702f6 100644
--- a/erpnext/support/doctype/issue/issue_list.js
+++ b/erpnext/support/doctype/issue/issue_list.js
@@ -23,8 +23,8 @@
'Low': 'yellow',
'Medium': 'orange',
'High': 'red'
- }
- return [__(doc.status), color[doc.priority] || 'Red', `status,=,Open`];
+ };
+ return [__(doc.status), color[doc.priority] || 'red', `status,=,Open`];
} else if (doc.status === 'Closed') {
return [__(doc.status), "green", "status,=," + doc.status];
} else {
diff --git a/erpnext/support/doctype/issue/test_issue.py b/erpnext/support/doctype/issue/test_issue.py
index 75d70b1..7a5e3e3 100644
--- a/erpnext/support/doctype/issue/test_issue.py
+++ b/erpnext/support/doctype/issue/test_issue.py
@@ -11,6 +11,7 @@
class TestIssue(unittest.TestCase):
def test_response_time_and_resolution_time_based_on_different_sla(self):
+ frappe.db.set_value("Support Settings", None, "track_service_level_agreement", 1)
create_service_level_agreements_for_issues()
creation = datetime.datetime(2019, 3, 4, 12, 0)
@@ -79,7 +80,8 @@
"customer": customer,
"raised_by": "test@example.com",
"description": "Service Level Agreement Issue",
- "creation": creation
+ "creation": creation,
+ "service_level_agreement_creation": creation
}).insert(ignore_permissions=True)
return issue
diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json
index f91a80c..9a83ca7 100644
--- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.json
+++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.json
@@ -5,6 +5,7 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
+ "enable",
"service_level",
"default_service_level_agreement",
"holiday_list",
@@ -149,9 +150,15 @@
"in_standard_filter": 1,
"label": "Entity Type",
"options": "\nCustomer\nCustomer Group\nTerritory"
+ },
+ {
+ "default": "1",
+ "fieldname": "enable",
+ "fieldtype": "Check",
+ "label": "Enable"
}
],
- "modified": "2019-06-20 18:04:14.293378",
+ "modified": "2019-07-09 17:22:16.402939",
"modified_by": "Administrator",
"module": "Support",
"name": "Service Level Agreement",
diff --git a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
index 82c0ffb..a399c58 100644
--- a/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/service_level_agreement.py
@@ -6,19 +6,23 @@
import frappe
from frappe.model.document import Document
from frappe import _
+from frappe.utils import getdate
class ServiceLevelAgreement(Document):
def validate(self):
+ if not frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
+ frappe.throw(_("Service Level Agreement tracking is not enabled."))
+
if self.default_service_level_agreement:
if frappe.db.exists("Service Level Agreement", {"default_service_level_agreement": "1", "name": ["!=", self.name]}):
frappe.throw(_("A Default Service Level Agreement already exists."))
else:
if self.start_date and self.end_date:
- if self.start_date >= self.end_date:
+ if getdate(self.start_date) >= getdate(self.end_date):
frappe.throw(_("Start Date of Agreement can't be greater than or equal to End Date."))
- if self.end_date < frappe.utils.getdate():
+ if getdate(self.end_date) < getdate(frappe.utils.getdate()):
frappe.throw(_("End Date of Agreement can't be less than today."))
if self.entity_type and self.entity:
@@ -44,12 +48,16 @@
for service_level_agreement in service_level_agreements:
doc = frappe.get_doc("Service Level Agreement", service_level_agreement.name)
- if doc.end_date and doc.end_date < frappe.utils.getdate():
+ if doc.end_date and getdate(doc.end_date) < getdate(frappe.utils.getdate()):
frappe.db.set_value("Service Level Agreement", service_level_agreement.name, "active", 0)
def get_active_service_level_agreement_for(priority, customer=None, service_level_agreement=None):
+ if not frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
+ return
+
filters = [
["Service Level Agreement", "active", "=", 1],
+ ["Service Level Agreement", "enable", "=", 1]
]
if priority:
@@ -80,6 +88,14 @@
@frappe.whitelist()
def get_service_level_agreement_filters(name, customer=None):
+ if not frappe.db.get_single_value("Support Settings", "track_service_level_agreement"):
+ return
+
+ filters = [
+ ["Service Level Agreement", "active", "=", 1],
+ ["Service Level Agreement", "enable", "=", 1]
+ ]
+
if not customer:
or_filters = [
["Service Level Agreement", "default_service_level_agreement", "=", 1]
@@ -93,5 +109,5 @@
return {
"priority": [priority.priority for priority in frappe.get_list("Service Level Priority", filters={"parent": name}, fields=["priority"])],
- "service_level_agreements": [d.name for d in frappe.get_list("Service Level Agreement", or_filters=or_filters)]
+ "service_level_agreements": [d.name for d in frappe.get_list("Service Level Agreement", filters=filters, or_filters=or_filters)]
}
\ No newline at end of file
diff --git a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
index 6aa5394..4a741ea 100644
--- a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
@@ -10,6 +10,8 @@
class TestServiceLevelAgreement(unittest.TestCase):
def test_service_level_agreement(self):
+ frappe.db.set_value("Support Settings", None, "track_service_level_agreement", 1)
+
create_service_level_for_sla()
# Default Service Level Agreement
@@ -74,6 +76,7 @@
service_level_agreement = frappe.get_doc({
"doctype": "Service Level Agreement",
+ "enable": 1,
"default_service_level_agreement": default_service_level_agreement,
"service_level": service_level,
"holiday_list": holiday_list,
diff --git a/erpnext/support/doctype/support_settings/support_settings.json b/erpnext/support/doctype/support_settings/support_settings.json
index 2b79107..be9e064 100644
--- a/erpnext/support/doctype/support_settings/support_settings.json
+++ b/erpnext/support/doctype/support_settings/support_settings.json
@@ -1,560 +1,152 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
"creation": "2017-02-17 13:07:35.686409",
- "custom": 0,
- "docstatus": 0,
"doctype": "DocType",
- "document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
+ "field_order": [
+ "sb_00",
+ "track_service_level_agreement",
+ "allow_resetting_service_level_agreement",
+ "issues_sb",
+ "close_issue_after_days",
+ "portal_sb",
+ "get_started_sections",
+ "show_latest_forum_posts",
+ "forum_sb",
+ "forum_url",
+ "get_latest_query",
+ "response_key_list",
+ "column_break_10",
+ "post_title_key",
+ "post_description_key",
+ "post_route_key",
+ "post_route_string",
+ "search_apis_sb",
+ "search_apis"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "issues_sb",
"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": "Issues",
- "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
+ "label": "Issues"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"default": "7",
"description": "Auto close Issue after 7 days",
"fieldname": "close_issue_after_days",
"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": "Close Issue After Days",
- "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
+ "label": "Close Issue After Days"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "portal_sb",
"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": "Support Portal",
- "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
+ "label": "Support Portal"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "get_started_sections",
"fieldtype": "Code",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Get Started Sections",
- "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
+ "label": "Get Started Sections"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "default": "0",
"fieldname": "show_latest_forum_posts",
"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": "Show Latest Forum Posts",
- "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
+ "label": "Show Latest Forum Posts"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "show_latest_forum_posts",
"fieldname": "forum_sb",
"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": "Forum Posts",
- "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
+ "label": "Forum Posts"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "forum_url",
"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": "Forum URL",
- "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
+ "label": "Forum URL"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "get_latest_query",
"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": "Get Latest Query",
- "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
+ "label": "Get Latest Query"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "response_key_list",
"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": "Response Key List",
- "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
+ "label": "Response Key List"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_10",
- "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
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "post_title_key",
"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": "Post Title Key",
- "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
+ "label": "Post Title Key"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "post_description_key",
"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": "Post Description Key",
- "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
+ "label": "Post Description Key"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "post_route_key",
"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": "Post Route Key",
- "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
+ "label": "Post Route Key"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "post_route_string",
"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": "Post Route String",
- "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
+ "label": "Post Route String"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "search_apis_sb",
"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": "Search APIs",
- "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
+ "label": "Search APIs"
},
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "search_apis",
"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": "Search APIs",
- "length": 0,
- "no_copy": 0,
- "options": "Support Search Source",
- "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
+ "options": "Support Search Source"
+ },
+ {
+ "fieldname": "sb_00",
+ "fieldtype": "Section Break",
+ "label": "Service Level Agreements"
+ },
+ {
+ "default": "0",
+ "fieldname": "track_service_level_agreement",
+ "fieldtype": "Check",
+ "label": "Track Service Level Agreement"
+ },
+ {
+ "default": "0",
+ "fieldname": "allow_resetting_service_level_agreement",
+ "fieldtype": "Check",
+ "label": "Allow Resetting Service Level Agreement"
}
],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
"issingle": 1,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-05-17 02:11:33.462444",
+ "modified": "2019-07-10 22:52:39.663873",
"modified_by": "Administrator",
"module": "Support",
"name": "Support Settings",
- "name_case": "",
"owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
- "report": 0,
"role": "System Manager",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
}
],
"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
+ "track_changes": 1
}
\ No newline at end of file